deps: upgrade openssl sources to openssl-3.5.1

PR-URL: https://github.com/nodejs/node/pull/59234
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Richard Lau <richard.lau@ibm.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
This commit is contained in:
Node.js GitHub Bot 2025-07-27 00:43:44 +00:00
parent 34cfc5a44a
commit 3eadca6ada
1607 changed files with 250027 additions and 33149 deletions

View file

@ -0,0 +1,11 @@
#
# 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
#
# Allow ctags to load configuration file under the sub directories.
--optlib-dir=+./.ctags.d

View file

@ -0,0 +1,13 @@
#
# 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
#
# List file names or patterns you want ctags to ignore.
--exclude=.ctags.d
--exclude=test
--exclude=check-format-test-positives.c

View file

@ -0,0 +1,18 @@
#
# 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
#
# This file is only for extracting macro definitions.
--langmap=C:+.h
-o -
--sort=no
--languages=C
-R
--fields-C=+{macrodef}
--fields=+{signature}

View file

@ -0,0 +1,9 @@
#
# 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
#
--param-CPreProcessor._expand=1

View file

@ -1,5 +1,5 @@
Acknowlegements
===============
Acknowledgements
================
Please see our [Thanks!][] page for the current acknowledgements.

View file

@ -12,6 +12,7 @@ Groups
* OpenSSL Software Services, Inc.
* OpenSSL Software Foundation, Inc.
* Google LLC
Individuals
-----------
@ -48,4 +49,5 @@ Individuals
* Tim Hudson
* Tomáš Mráz
* Ulf Möller
* Valerii Krygin
* Viktor Dukhovni

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,6 @@
Code of Conduct
===============
The OpenSSL [Code of Conduct] is published on the project's website.
[Code of Conduct]: https://www.openssl.org/community/conduct.html

View file

@ -100,13 +100,5 @@ guidelines:
with a specific release without having to sift through the higher
noise ratio in git-log.
8. For larger or more important user visible changes, as well as
security fixes, please add a line in [NEWS.md](NEWS.md).
On exception, it might be worth adding a multi-line entry (such as
the entry that announces all the types that became opaque with
OpenSSL 1.1.0).
This file helps users get a very quick summary of what comes with a
specific release, to see if an upgrade is worth the effort.
9. Guidelines how to integrate error output of new crypto library modules
8. Guidelines on how to integrate error output of new crypto library modules
can be found in [crypto/err/README.md](crypto/err/README.md).

View file

@ -48,15 +48,25 @@ my %targets=(
defines =>
sub {
my @defs = ( 'OPENSSL_BUILDING_OPENSSL' );
push @defs, "BROTLI" unless $disabled{brotli};
push @defs, "BROTLI_SHARED" unless $disabled{"brotli-dynamic"};
push @defs, "ZLIB" unless $disabled{zlib};
push @defs, "ZLIB_SHARED" unless $disabled{"zlib-dynamic"};
push @defs, "ZSTD" unless $disabled{zstd};
push @defs, "ZSTD_SHARED" unless $disabled{"zstd-dynamic"};
return [ @defs ];
},
includes =>
sub {
my @incs = ();
push @incs, $withargs{jitter_include}
if !$disabled{jitter} && $withargs{jitter_include};
push @incs, $withargs{brotli_include}
if !$disabled{brotli} && $withargs{brotli_include};
push @incs, $withargs{zlib_include}
if !$disabled{zlib} && $withargs{zlib_include};
push @incs, $withargs{zstd_include}
if !$disabled{zstd} && $withargs{zstd_include};
return [ @incs ];
},
},
@ -68,12 +78,46 @@ my %targets=(
AR => "ar",
ARFLAGS => "qc",
CC => "cc",
OBJCOPY => "objcopy",
bin_cflags =>
sub {
my @flags = ();
if (!defined($disabled{pie})) {
push(@flags, "-fPIE");
}
return join(" ", @flags);
},
bin_lflags =>
sub {
my @flags = ();
if (!defined($disabled{pie})) {
push(@flags, "-pie");
}
return join(" ", @flags);
},
lflags =>
sub { $withargs{zlib_lib} ? "-L".$withargs{zlib_lib} : () },
sub {
my @libs = ();
push(@libs, "-L".$withargs{jitter_lib}) if $withargs{jitter_lib};
push(@libs, "-L".$withargs{zlib_lib}) if $withargs{zlib_lib};
push(@libs, "-L".$withargs{brotli_lib}) if $withargs{brotli_lib};
push(@libs, "-L".$withargs{zstd_lib}) if $withargs{zstd_lib};
return join(" ", @libs);
},
ex_libs =>
sub { !defined($disabled{zlib})
&& defined($disabled{"zlib-dynamic"})
? "-lz" : () },
sub {
my @libs = ();
push(@libs, "-l:libjitterentropy.a") if !defined($disabled{jitter});
push(@libs, "-lz") if !defined($disabled{zlib}) && defined($disabled{"zlib-dynamic"});
if (!defined($disabled{brotli}) && defined($disabled{"brotli-dynamic"})) {
push(@libs, "-lbrotlienc");
push(@libs, "-lbrotlidec");
push(@libs, "-lbrotlicommon");
push(@libs, "-lm");
}
push(@libs, "-lzstd") if !defined($disabled{zstd}) && defined($disabled{"zstd-dynamic"});
return join(" ", @libs);
},
HASHBANGPERL => "/usr/bin/env perl", # Only Unix actually cares
RANLIB => sub { which("$config{cross_compile_prefix}ranlib")
? "ranlib" : "" },
@ -100,12 +144,29 @@ my %targets=(
},
ex_libs =>
sub {
my @libs = ();
unless ($disabled{zlib}) {
if (defined($disabled{"zlib-dynamic"})) {
return $withargs{zlib_lib} // "ZLIB1";
push(@libs, $withargs{zlib_lib} // "ZLIB1");
}
}
return ();
unless ($disabled{zstd}) {
if (defined($disabled{"zstd-dynamic"})) {
push(@libs, $withargs{zstd_lib} // "libzstd");
}
}
unless ($disabled{brotli}) {
if (defined($disabled{"brotli-dynamic"})) {
my $path = "";
if (defined($withargs{brotli_lib})) {
$path = $withargs{brotli_lib} . "\\";
}
push(@libs, $path . "brotlicommon.lib");
push(@libs, $path . "brotlidec.lib");
push(@libs, $path . "brotlienc.lib");
}
}
return join(" ", @libs);
},
MT => "mt",

View file

@ -242,9 +242,7 @@ my %targets = (
CFLAGS => add_before(picker(default => "-Wall",
debug => "-O0 -g",
release => "-O3 -fomit-frame-pointer")),
cflags => add(threads("-pthread")),
lib_cppflags => add("-DL_ENDIAN"),
ex_libs => add(threads("-pthread")),
bn_ops => "BN_LLONG",
shared_cflag => "-fPIC",
shared_ldflag => add_before("-shared -static-libgcc"),
@ -265,9 +263,8 @@ my %targets = (
CFLAGS => add_before(picker(default => "-Wall",
debug => "-O0 -g",
release => "-O3")),
cflags => add_before("-m64", threads("-pthread")),
cflags => add("-m64"),
lib_cppflags => add("-DL_ENDIAN"),
ex_libs => add(threads("-pthread")),
bn_ops => "SIXTY_FOUR_BIT_LONG",
asm_arch => 'x86_64',
perlasm_scheme => "elf",
@ -299,7 +296,6 @@ my %targets = (
lib_cppflags => add("-DL_ENDIAN"),
thread_scheme => "pthreads",
lflags => add(threads("-mt")),
ex_libs => add(threads("-lpthread")),
bn_ops => "SIXTY_FOUR_BIT_LONG",
asm_arch => 'x86_64',
perlasm_scheme => "elf",
@ -315,12 +311,10 @@ my %targets = (
CFLAGS => add_before(picker(default => "-Wall",
debug => "-O0 -g",
release => "-O3")),
cflags => add(threads("-pthread")),
lib_cppflags => add("-DB_ENDIAN -DBN_DIV2W"),
ex_libs => add(threads("-pthread")),
bn_ops => "BN_LLONG RC4_CHAR",
shared_cflag => "-fPIC",
shared_ldflag => add_before("-shared"),
shared_ldflag => add_before("-shared -static-libgcc"),
},
"solaris-sparcv8-gcc" => {
inherit_from => [ "solaris-sparcv7-gcc" ],
@ -356,7 +350,6 @@ my %targets = (
cppflags => add(threads("-D_REENTRANT")),
lib_cppflags => add("-DB_ENDIAN -DBN_DIV2W"),
lflags => add(threads("-mt")),
ex_libs => add(threads("-lpthread")),
bn_ops => "BN_LLONG RC4_CHAR",
shared_cflag => "-KPIC",
shared_ldflag => add_before("-G -dy -z text"),
@ -821,11 +814,18 @@ my %targets = (
multilib => "64",
},
# riscv64 below refers to contemporary RISCV Architecture
# riscv below refers to contemporary RISCV Architecture
# specifications,
"linux64-riscv64" => {
inherit_from => [ "linux-generic64"],
perlasm_scheme => "linux64",
asm_arch => 'riscv64',
},
"linux32-riscv32" => {
inherit_from => [ "linux-latomic" ],
perlasm_scheme => "linux32",
asm_arch => 'riscv32',
},
# loongarch64 below refers to contemporary LoongArch Architecture
@ -833,6 +833,8 @@ my %targets = (
"linux64-loongarch64" => {
inherit_from => [ "linux-generic64"],
perlasm_scheme => "linux64",
asm_arch => 'loongarch64',
lib_cppflags => add("-DL_ENDIAN"),
},
#### IA-32 targets...
@ -870,6 +872,10 @@ my %targets = (
asm_arch => 'x86',
perlasm_scheme => "elf",
},
"linux-x86-latomic" => {
inherit_from => [ "linux-x86" ],
ex_libs => add(threads("-latomic")),
},
"linux-x86-clang" => {
inherit_from => [ "linux-x86" ],
CC => "clang",
@ -1087,11 +1093,80 @@ my %targets = (
perlasm_scheme => "linux64",
},
# riscv64 below refers to contemporary RISCV Architecture
"BSD-ppc" => {
inherit_from => [ "BSD-generic32" ],
asm_arch => 'ppc32',
perlasm_scheme => "linux32",
lib_cppflags => add("-DB_ENDIAN"),
},
"BSD-ppc64" => {
inherit_from => [ "BSD-generic64" ],
cflags => add("-m64"),
cxxflags => add("-m64"),
lib_cppflags => add("-DB_ENDIAN"),
asm_arch => 'ppc64',
perlasm_scheme => "linux64",
},
"BSD-ppc64le" => {
inherit_from => [ "BSD-generic64" ],
cflags => add("-m64"),
cxxflags => add("-m64"),
lib_cppflags => add("-DL_ENDIAN"),
asm_arch => 'ppc64',
perlasm_scheme => "linux64le",
},
# riscv below refers to contemporary RISCV Architecture
# specifications,
"BSD-riscv64" => {
inherit_from => [ "BSD-generic64"],
perlasm_scheme => "linux64",
asm_arch => 'riscv64',
},
"BSD-riscv32" => {
inherit_from => [ "BSD-generic32"],
perlasm_scheme => "linux32",
asm_arch => 'riscv32',
},
"BSD-armv4" => {
################################################################
# Note that -march is not among compiler options in linux-armv4
# target description. Not specifying one is intentional to give
# you choice to:
#
# a) rely on your compiler default by not specifying one;
# b) specify your target platform explicitly for optimal
# performance, e.g. -march=armv6 or -march=armv7-a;
# c) build "universal" binary that targets *range* of platforms
# by specifying minimum and maximum supported architecture;
#
# As for c) option. It actually makes no sense to specify
# maximum to be less than ARMv7, because it's the least
# requirement for run-time switch between platform-specific
# code paths. And without run-time switch performance would be
# equivalent to one for minimum. Secondly, there are some
# natural limitations that you'd have to accept and respect.
# Most notably you can *not* build "universal" binary for
# big-endian platform. This is because ARMv7 processor always
# picks instructions in little-endian order. Another similar
# limitation is that -mthumb can't "cross" -march=armv6t2
# boundary, because that's where it became Thumb-2. Well, this
# limitation is a bit artificial, because it's not really
# impossible, but it's deemed too tricky to support. And of
# course you have to be sure that your binutils are actually
# up to the task of handling maximum target platform. With all
# this in mind here is an example of how to configure
# "universal" build:
#
# ./Configure BSD-armv4 -march=armv6 -D__ARM_MAX_ARCH__=8
#
inherit_from => [ "BSD-generic32" ],
asm_arch => 'armv4',
perlasm_scheme => "linux32",
},
"bsdi-elf-gcc" => {
@ -1108,6 +1183,81 @@ my %targets = (
shared_target => "bsd-gcc-shared",
shared_cflag => "-fPIC",
},
#### *BSD-nodef
"BSD-nodef-generic32" => {
# As for thread cflag. Idea is to maintain "collective" set of
# flags, which would cover all BSD flavors. -pthread applies
# to them all, but is treated differently. OpenBSD expands is
# as -D_POSIX_THREAD -lc_r, which is sufficient. FreeBSD 4.x
# expands it as -lc_r, which has to be accompanied by explicit
# -D_THREAD_SAFE and sometimes -D_REENTRANT. FreeBSD 5.x
# expands it as -lc_r, which seems to be sufficient?
inherit_from => [ "BASE_unix" ],
CC => "cc",
CFLAGS => picker(default => "-Wall",
debug => "-O0 -g",
release => "-O3"),
cflags => threads("-pthread"),
cppflags => threads("-D_THREAD_SAFE -D_REENTRANT"),
ex_libs => add(threads("-pthread")),
enable => add("devcryptoeng"),
bn_ops => "BN_LLONG",
thread_scheme => "pthreads",
dso_scheme => "dlfcn",
shared_target => "bsd-gcc-nodef-shared",
shared_cflag => "-fPIC",
},
"BSD-nodef-generic64" => {
inherit_from => [ "BSD-nodef-generic32" ],
bn_ops => "SIXTY_FOUR_BIT_LONG",
},
"BSD-nodef-x86" => {
inherit_from => [ "BSD-nodef-generic32" ],
CFLAGS => add(picker(release => "-fomit-frame-pointer")),
lib_cppflags => add("-DL_ENDIAN"),
bn_ops => "BN_LLONG",
asm_arch => 'x86',
perlasm_scheme => "a.out",
},
"BSD-nodef-x86-elf" => {
inherit_from => [ "BSD-nodef-x86" ],
perlasm_scheme => "elf",
},
"BSD-nodef-sparcv8" => {
inherit_from => [ "BSD-nodef-generic32" ],
cflags => add("-mcpu=v8"),
lib_cppflags => add("-DB_ENDIAN"),
asm_arch => 'sparcv8',
perlasm_scheme => 'void',
},
"BSD-nodef-sparc64" => {
# -DMD32_REG_T=int doesn't actually belong in sparc64 target, it
# simply *happens* to work around a compiler bug in gcc 3.3.3,
# triggered by RIPEMD160 code.
inherit_from => [ "BSD-nodef-generic64" ],
lib_cppflags => add("-DB_ENDIAN -DMD32_REG_T=int"),
bn_ops => "BN_LLONG",
asm_arch => 'sparcv9',
perlasm_scheme => 'void',
},
"BSD-nodef-ia64" => {
inherit_from => [ "BSD-nodef-generic64" ],
lib_cppflags => add("-DL_ENDIAN"),
bn_ops => "SIXTY_FOUR_BIT_LONG",
asm_arch => 'ia64',
perlasm_scheme => 'void',
},
"BSD-nodef-x86_64" => {
inherit_from => [ "BSD-nodef-generic64" ],
lib_cppflags => add("-DL_ENDIAN"),
bn_ops => "SIXTY_FOUR_BIT_LONG",
asm_arch => 'x86_64',
perlasm_scheme => "elf",
},
#### SCO/Caldera targets.
#
@ -1283,6 +1433,19 @@ my %targets = (
AR => add("-X32"),
RANLIB => add("-X32"),
},
# shared_target of "aix-solib" builds shared libraries packaged
# without archives. This improves the behavior of inter-library
# references (libssl depending on libcrypto) when building with
# shlib_variant.
# You'll get: libxxx.so (import library, used when linking applications)
# libxxx.so.ver (shared object)
# libxxx.a (static library archive)
# and for runtime, you only need libxxx.so.ver. libxxx.so and libxxx.a
# can be installed along with include files to make an SDK
"aix-cc-solib" => {
inherit_from => [ "aix-cc" ],
shared_target => "aix-solib",
},
"aix64-cc" => {
inherit_from => [ "aix-common" ],
CC => "cc",
@ -1318,6 +1481,10 @@ my %targets = (
AR => add("-X64"),
RANLIB => add("-X64"),
},
"aix64-cc-solib" => {
inherit_from => [ "aix64-cc" ],
shared_target => "aix-solib",
},
# SIEMENS BS2000/OSD: an EBCDIC-based mainframe
"BS2000-OSD" => {
@ -1618,6 +1785,7 @@ my %targets = (
CFLAGS => picker(default => "-Wall",
debug => "-g -O0",
release => "-O3"),
ex_libs => add("-lcrypt32"),
lib_cppflags => "-DTERMIOS -DL_ENDIAN",
sys_id => "CYGWIN",
thread_scheme => "pthread",
@ -1731,20 +1899,53 @@ my %targets = (
},
##### GNU Hurd
"hurd-x86" => {
"hurd-generic32" => {
inherit_from => [ "BASE_unix" ],
CC => "gcc",
CFLAGS => "-O3 -fomit-frame-pointer -Wall",
CXX => "g++",
CFLAGS => picker(default => "-Wall",
debug => "-O0 -g",
release => "-O3"),
CXXFLAGS => picker(default => "-Wall",
debug => "-O0 -g",
release => "-O3"),
cflags => threads("-pthread"),
lib_cppflags => "-DL_ENDIAN",
cxxflags => combine("-std=c++11", threads("-pthread")),
ex_libs => add("-ldl", threads("-pthread")),
bn_ops => "BN_LLONG",
asm_arch => 'x86',
perlasm_scheme => 'elf',
bn_ops => "BN_LLONG RC4_CHAR",
thread_scheme => "pthreads",
dso_scheme => "dlfcn",
shared_target => "linux-shared",
shared_cflag => "-fPIC",
shared_ldflag => sub { $disabled{pinshared} ? () : "-Wl,-znodelete" },
},
"hurd-generic64" => {
inherit_from => [ "hurd-generic32" ],
bn_ops => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
},
#### X86 / X86_64 targets
"hurd-x86" => {
inherit_from => [ "hurd-generic32" ],
CFLAGS => add(picker(release => "-fomit-frame-pointer")),
cflags => add("-m32"),
cxxflags => add("-m32"),
lib_cppflags => add("-DL_ENDIAN"),
bn_ops => "BN_LLONG",
asm_arch => 'x86',
perlasm_scheme => 'elf',
},
"hurd-x86_64" => {
inherit_from => [ "hurd-generic64" ],
cflags => add("-m64"),
cxxflags => add("-m64"),
lib_cppflags => add("-DL_ENDIAN"),
bn_ops => "SIXTY_FOUR_BIT_LONG",
asm_arch => 'x86_64',
perlasm_scheme => 'elf',
multilib => "64",
},
##### VxWorks for various targets
@ -1897,6 +2098,7 @@ my %targets = (
cflag_incfirst => '/FIRST_INCLUDE=',
lib_defines =>
add("OPENSSL_USE_NODELETE",
"_XOPEN_SOURCE", "_XOPEN_SOURCE_EXTENDED=1",
sub {
return vms_info()->{def_zlib}
? "LIBZ=\"\"\"".vms_info()->{def_zlib}."\"\"\"" : ();

View file

@ -12,6 +12,7 @@
arm64 => "aarch64-linux-android",
mips => "mipsel-linux-android",
mips64 => "mips64el-linux-android",
riscv64 => "riscv64-linux-android",
x86 => "i686-linux-android",
x86_64 => "x86_64-linux-android",
);
@ -270,6 +271,12 @@ my %targets = (
perlasm_scheme => "elf",
},
"android-riscv64" => {
inherit_from => [ "android" ],
asm_arch => 'riscv64',
perlasm_scheme => "linux64",
},
####################################################################
# Backward compatible targets, (might) require $CROSS_SYSROOT
#

View file

@ -1,9 +1,10 @@
#### iPhoneOS/iOS
#
# It takes recent enough Xcode to use following two targets. It shouldn't
# be a problem by now, but if they don't work, original targets below
# that depend on manual definition of environment variables should still
# work...
# `xcrun` targets require an Xcode that can determine the correct C compiler via
# `xcrun -sdk iphoneos`. This has been standard in Xcode for a while now - any recent
# Xcode should do. If the Xcode on the build machine doesn't support this then use
# the legacy targets at the end of this file. These require manual definition of
# environment variables.
#
my %targets = (
"ios-common" => {
@ -18,14 +19,14 @@ my %targets = (
# thus targeting iPhone pre-3GS, but it's assumed to be irrelevant
# at this point.
CC => "xcrun -sdk iphoneos cc",
cflags => add("-arch armv7 -mios-version-min=6.0.0 -fno-common"),
cflags => add("-arch armv7 -fno-common"),
asm_arch => 'armv4',
perlasm_scheme => "ios32",
},
"ios64-xcrun" => {
inherit_from => [ "ios-common" ],
CC => "xcrun -sdk iphoneos cc",
cflags => add("-arch arm64 -mios-version-min=7.0.0 -fno-common"),
cflags => add("-arch arm64 -fno-common"),
bn_ops => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
asm_arch => 'aarch64',
perlasm_scheme => "ios64",
@ -34,6 +35,30 @@ my %targets = (
inherit_from => [ "ios-common" ],
CC => "xcrun -sdk iphonesimulator cc",
},
"iossimulator-arm64-xcrun" => {
inherit_from => [ "ios-common" ],
CC => "xcrun -sdk iphonesimulator cc",
cflags => add("-arch arm64 -fno-common"),
bn_ops => "SIXTY_FOUR_BIT_LONG",
asm_arch => 'aarch64',
perlasm_scheme => "ios64",
},
"iossimulator-i386-xcrun" => {
inherit_from => [ "ios-common" ],
CC => "xcrun -sdk iphonesimulator cc",
cflags => add("-arch i386 -fno-common"),
bn_ops => "BN_LLONG",
asm_arch => 'x86',
perlasm_scheme => "macosx",
},
"iossimulator-x86_64-xcrun" => {
inherit_from => [ "ios-common" ],
CC => "xcrun -sdk iphonesimulator cc",
cflags => add("-arch x86_64 -fno-common"),
bn_ops => "SIXTY_FOUR_BIT_LONG",
asm_arch => 'x86_64',
perlasm_scheme => "macosx",
},
# It takes three prior-set environment variables to make it work:
#
# CROSS_COMPILE=/where/toolchain/is/usr/bin/ [note ending slash]

View file

@ -58,5 +58,64 @@ my %targets = (
shared_defflag => '',
perl_platform => 'Windows::cppbuilder',
uplink_arch => 'common',
},
"BC-64" => {
inherit_from => [ "BASE_Windows" ],
sys_id => "WIN64",
bn_ops => "BN_LLONG",
thread_scheme => "winthreads",
cc => "bcc64",
CPP => "cpp64 -oCON -Sc -Sr",
defines => add("WIN32_LEAN_AND_MEAN", "OPENSSL_SYS_WIN64",
"L_ENDIAN", "DSO_WIN32", "_stricmp=stricmp",
"_strnicmp=strnicmp", "_setmode=setmode"),
cflags => picker(default => add("-q -c",
threads("-tM"),
shared("-tR")),
debug => "-Od -v -vi- -D_DEBUG",
release => "-O2"),
bin_cflags => "-tWC",
lib_cflags => shared("-tWD -D_WINDLL -D_DLL"),
coutflag => "-o",
# -Sx isn't documented, but 'cpp64 -H -S' explains it:
#
# -Sx Omit preprocessed text in output
makedepcmd => "cpp64 -oCON -Sx -Hp",
makedep_scheme => "embarcadero",
LD => "ilink64",
LDFLAGS => picker(default => "-x -Gn -q -w-dup",
debug => '-j"$(BDS)\lib\win64\debug" ' .
'-L"$(BDS)\lib\win64\debug" -v',
release => '-j"$(BDS)\lib\win64\release" ' .
'-L"$(BDS)\lib\win64\release"'),
bin_lflags => "-ap -Tpe c0x64.o wildargs.o",
ldoutflag => ",",
ldpostoutflag => ",,",
ld_resp_delim => " +\n",
ex_libs => add(sub {
my @ex_libs = ("import64.a",
($disabled{shared}
? ($disabled{threads} ? "cw64.a" : "cw64mt.a")
: ($disabled{threads} ? "cw64i.a" : "cw64mti.a")));
push @ex_libs, "ws2_32.a" unless $disabled{sock};
return join(" ", @ex_libs);
}),
AR => "tlib",
ARFLAGS => "/P256 /N /u",
ar_resp_delim => " &\n",
RC => "brcc32",
RCFLAGS => '-i"$(BDS)\include\windows\sdk"',
rcoutflag => "-fo",
shared_target => "win-shared",
shared_ldflag => "-aa -Tpd c0d64.o",
lddefflag => ",",
ldresflag => ",",
ld_implib_rule => 'implib -a $< $**',
dso_scheme => "win64",
shared_defflag => '',
perl_platform => 'Windows::cppbuilder',
uplink_arch => 'common',
}
);

View file

@ -14,12 +14,15 @@
'_XOPEN_SOURCE',
'_XOPEN_SOURCE_EXTENDED=1',
'_TANDEM_SOURCE',
'__NSK_OPTIONAL_TYPES__',
'B_ENDIAN'),
perl => '/usr/bin/perl',
shared_target => 'nonstop-shared',
shared_extension => ".so",
ex_libs => add('-lrld'),
enable => ['egd'],
# Not currently inherited
disable => ['atexit'],
dso_scheme => 'DLFCN',
sys_id => 'TANDEM',
},
@ -58,7 +61,7 @@
# Itanium + guardian:
'nonstop-archenv-itanium-guardian' => {
template => 1,
defines => ['NO_GETPID', '_TANDEM_ARCH=2'],
defines => ['NO_GETPID'],
cflags => '-Wtarget=tns/e -Wsystype=guardian',
lflags => '-Weld="-set systype guardian"',
shared_ldflag => '-Wshared -Weld="-soname $(@:lib%.so=%)"',
@ -69,7 +72,7 @@
# x86 + guardian:
'nonstop-archenv-x86_64-guardian' => {
template => 1,
defines => ['NO_GETPID', '_TANDEM_ARCH=3'],
defines => ['NO_GETPID'],
cflags => '-Wtarget=tns/x -Wsystype=guardian',
lflags => '-Wxld="-set systype guardian"',
shared_ldflag => '-Wshared -Wxld="-soname $(@:lib%.so=%)"',
@ -89,7 +92,6 @@
# Itanium + oss:
'nonstop-archenv-itanium-oss' => {
template => 1,
defines => ['_TANDEM_ARCH=2'],
cflags => '-Wtarget=tns/e -Wsystype=oss',
lflags => '-Weld="-set systype oss"',
shared_ldflag => '-Wshared',
@ -99,7 +101,6 @@
# x86_64 + oss:
'nonstop-archenv-x86_64-oss' => {
template => 1,
defines => ['_TANDEM_ARCH=3'],
cflags => '-Wtarget=tns/x -Wsystype=oss',
lflags => '-Wxld="-set systype oss"',
shared_ldflag => '-Wshared',
@ -171,21 +172,14 @@
'_REENTRANT', '_THREAD_SUPPORT_FUNCTIONS'],
ex_libs => '-lput',
},
'nonstop-model-spt' => {
template => 1,
defines => ['_SPT_MODEL_',
'_REENTRANT', '_ENABLE_FLOSS_THREADS'],
ex_libs => '-lspt',
},
# Additional floss model that can be combined with any of the other models.
# If used without any of the other models, the entry that does so must
# disable threads.
'nonstop-model-floss' => {
######################################################################
# Build models
'nonstop-model-klt' => {
template => 1,
defines => ['OPENSSL_TANDEM_FLOSS'],
includes => ['/usr/local/include'],
ex_libs => '-lfloss',
defines => ['_KLT_MODEL_',
'_REENTRANT', '_THREAD_SUPPORT_FUNCTIONS'],
ex_libs => '-lklt',
},
######################################################################
@ -195,7 +189,7 @@
'nonstop-archenv-x86_64-oss',
'nonstop-ilp32',
'nonstop-efloat-x86_64' ],
disable => ['threads'],
disable => ['threads','atexit'],
},
'nonstop-nsx_put' => {
inherit_from => [ 'nonstop-common',
@ -204,6 +198,8 @@
'nonstop-efloat-x86_64',
'nonstop-model-put' ],
multilib => '-put',
multibin => '-put',
disable => ['atexit'],
},
'nonstop-nsx_64' => {
inherit_from => [ 'nonstop-common',
@ -211,7 +207,8 @@
'nonstop-lp64-x86_64',
'nonstop-efloat-x86_64' ],
multilib => '64',
disable => ['threads'],
multibin => '64',
disable => ['threads','atexit'],
},
'nonstop-nsx_64_put' => {
inherit_from => [ 'nonstop-common',
@ -220,35 +217,30 @@
'nonstop-efloat-x86_64',
'nonstop-model-put' ],
multilib => '64-put',
multibin => '64-put',
disable => ['atexit'],
},
'nonstop-nsx_spt' => {
'nonstop-nsx_64_klt' => {
inherit_from => [ 'nonstop-common',
'nonstop-archenv-x86_64-oss',
'nonstop-ilp32',
'nonstop-lp64-x86_64',
'nonstop-efloat-x86_64',
'nonstop-model-spt' ],
multilib => '-spt',
},
'nonstop-nsx_spt_floss' => {
inherit_from => [ 'nonstop-common',
'nonstop-archenv-x86_64-oss',
'nonstop-ilp32',
'nonstop-efloat-x86_64',
'nonstop-model-floss',
'nonstop-model-spt'],
multilib => '-spt',
'nonstop-model-klt' ],
multilib => '64-klt',
multibin => '64-klt',
disable => ['atexit'],
},
'nonstop-nsx_g' => {
inherit_from => [ 'nonstop-common',
'nonstop-archenv-x86_64-guardian',
'nonstop-ilp32', 'nonstop-nfloat-x86_64' ],
disable => ['threads'],
disable => ['threads','atexit'],
},
'nonstop-nsx_g_tandem' => {
inherit_from => [ 'nonstop-common',
'nonstop-archenv-x86_64-guardian',
'nonstop-ilp32', 'nonstop-tfloat-x86_64' ],
disable => ['threads'],
disable => ['threads','atexit'],
},
'nonstop-nsv' => {
inherit_from => [ 'nonstop-nsx' ],
@ -258,7 +250,7 @@
'nonstop-archenv-itanium-oss',
'nonstop-ilp32',
'nonstop-efloat-itanium' ],
disable => ['threads'],
disable => ['threads','atexit'],
},
'nonstop-nse_put' => {
inherit_from => [ 'nonstop-common',
@ -267,6 +259,8 @@
'nonstop-efloat-itanium',
'nonstop-model-put' ],
multilib => '-put',
multibin => '-put',
disable => ['atexit'],
},
'nonstop-nse_64' => {
inherit_from => [ 'nonstop-common',
@ -274,7 +268,8 @@
'nonstop-lp64-itanium',
'nonstop-efloat-itanium' ],
multilib => '64',
disable => ['threads'],
multibin => '64',
disable => ['threads','atexit'],
},
'nonstop-nse_64_put' => {
inherit_from => [ 'nonstop-common',
@ -283,33 +278,6 @@
'nonstop-efloat-itanium',
'nonstop-model-put' ],
multilib => '64-put',
},
'nonstop-nse_spt' => {
inherit_from => [ 'nonstop-common',
'nonstop-archenv-itanium-oss',
'nonstop-ilp32',
'nonstop-efloat-itanium',
'nonstop-model-spt' ],
multilib => '-spt',
},
'nonstop-nse_spt_floss' => {
inherit_from => [ 'nonstop-common',
'nonstop-archenv-itanium-oss',
'nonstop-ilp32',
'nonstop-efloat-itanium',
'nonstop-model-floss', 'nonstop-model-spt' ],
multilib => '-spt',
},
'nonstop-nse_g' => {
inherit_from => [ 'nonstop-common',
'nonstop-archenv-itanium-guardian',
'nonstop-ilp32', 'nonstop-nfloat-itanium' ],
disable => ['threads'],
},
'nonstop-nse_g_tandem' => {
inherit_from => [ 'nonstop-common',
'nonstop-archenv-itanium-guardian',
'nonstop-ilp32', 'nonstop-tfloat-itanium' ],
disable => ['threads'],
multibin => '64-put',
disable => ['atexit'],
},

View file

@ -0,0 +1,36 @@
## -*- mode: perl; -*-
# Windows on Arm clang-cl targets.
#
my %targets = (
"VC-WIN64-CLANGASM-ARM" => {
inherit_from => [ "VC-noCE-common" ],
defines => add("_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE",
"OPENSSL_SYS_WIN_CORE"),
bn_ops => "SIXTY_FOUR_BIT RC4_CHAR",
multilib => "-arm64",
asm_arch => "aarch64",
AS => "clang-cl.exe",
ASFLAGS => "/nologo /Zi --target=arm64-pc-windows-msvc",
asflags => "/c",
asoutflag => "/Fo",
perlasm_scheme => "win64",
uplink_arch => 'armv8',
},
"VC-CLANG-WIN64-CLANGASM-ARM" => {
CC => "clang-cl",
inherit_from => [ "VC-noCE-common" ],
defines => add("_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE",
"OPENSSL_SYS_WIN_CORE"),
bn_ops => "SIXTY_FOUR_BIT RC4_CHAR",
multilib => "-arm64",
asm_arch => "aarch64",
CFLAGS => add("--target=arm64-pc-windows-msvc"),
AS => "clang-cl.exe",
ASFLAGS => "/nologo /Zi --target=arm64-pc-windows-msvc",
asflags => "/c",
asoutflag => "/Fo",
perlasm_scheme => "win64",
uplink_arch => 'armv8',
},
);

View file

@ -0,0 +1,37 @@
## -*- mode: perl; -*-
# Windows HybridCRT targets.
#
# https://github.com/microsoft/WindowsAppSDK/blob/77761e244289fda6b3d5f14c7bded189fed4fb89/docs/Coding-Guidelines/HybridCRT.md
# Link statically against the runtime and STL, but link dynamically against the CRT by ignoring the static CRT
# lib and instead linking against the Universal CRT DLL import library. This "Hybrid" linking mechanism is
# supported according to the CRT maintainer. Dynamic linking against the CRT makes the binaries a bit smaller
# than they would otherwise be if the CRT, runtime, and STL were all statically linked in.
sub remove_from_flags {
my ($toRemove, $flags) = @_;
$flags =~ s/$toRemove//;
return $flags;
}
my %targets = (
"VC-WIN32-HYBRIDCRT" => {
inherit_from => [ "VC-WIN32" ],
cflags => sub {
remove_from_flags(qr/\/MDd?\s/, add(picker(debug => "/MTd",
release => "/MT"))->(@_))
},
lflags => add(picker(debug => "/NODEFAULTLIB:libucrtd.lib /DEFAULTLIB:ucrtd.lib",
release => "/NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib")),
},
"VC-WIN64A-HYBRIDCRT" => {
inherit_from => [ "VC-WIN64A" ],
cflags => sub {
remove_from_flags(qr/\/MDd?\s/, add(picker(debug => "/MTd",
release => "/MT"))->(@_))
},
lflags => add(picker(debug => "/NODEFAULTLIB:libucrtd.lib /DEFAULTLIB:ucrtd.lib",
release => "/NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib")),
},
);

View file

@ -36,14 +36,13 @@ my %targets = (
# /NODEFAULTLIB:kernel32.lib is needed, because MSVCRT.LIB has
# hidden reference to kernel32.lib, but we don't actually want
# it in "onecore" build.
# /APPCONTAINER is needed for Universal Windows Platform compat
lflags => add("/NODEFAULTLIB:kernel32.lib /APPCONTAINER"),
lflags => add("/NODEFAULTLIB:kernel32.lib"),
defines => add("OPENSSL_SYS_WIN_CORE"),
ex_libs => "onecore.lib",
},
"VC-WIN64A-ONECORE" => {
inherit_from => [ "VC-WIN64A" ],
lflags => add("/NODEFAULTLIB:kernel32.lib /APPCONTAINER"),
lflags => add("/NODEFAULTLIB:kernel32.lib"),
defines => add("OPENSSL_SYS_WIN_CORE"),
ex_libs => "onecore.lib",
},
@ -69,7 +68,7 @@ my %targets = (
defines => add("_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE",
"OPENSSL_SYS_WIN_CORE"),
bn_ops => "BN_LLONG RC4_CHAR",
lflags => add("/NODEFAULTLIB:kernel32.lib /APPCONTAINER"),
lflags => add("/NODEFAULTLIB:kernel32.lib"),
ex_libs => "onecore.lib",
multilib => "-arm",
},
@ -78,7 +77,7 @@ my %targets = (
defines => add("_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE",
"OPENSSL_SYS_WIN_CORE"),
bn_ops => "SIXTY_FOUR_BIT RC4_CHAR",
lflags => add("/NODEFAULTLIB:kernel32.lib /APPCONTAINER"),
lflags => add("/NODEFAULTLIB:kernel32.lib"),
ex_libs => "onecore.lib",
multilib => "-arm64",
},

View file

@ -203,6 +203,13 @@ In each table entry, the following keys are significant:
to have the different variants in different
directories.
multibin => On systems that support having multiple
implementations of a library and binaries
(typically a 32-bit and a 64-bit variant),
this is used to have the different variants
in different binary directories. This setting
works in conjunction with multilib.
bn_ops => Building options (was just bignum options in
the earlier history of this option, hence the
name). This is a string of words that describe
@ -584,7 +591,7 @@ They are all expected to return a string with the lines they produce.
objs => [ "PATH/TO/objectfile", ... ],
deps => [ "PATH/TO/otherlibfile", ... ]);
'lib' has the base (static) library ffile name
'lib' has the base (static) library filename
*without* extension. This is useful in case
supporting files are needed (such as import
libraries on Windows).

View file

@ -205,13 +205,16 @@
@cnf_ldflags, '$(LDFLAGS)');
our $bin_ex_libs = join('', @cnf_ex_libs, '$(EX_LIBS)');
# This is a horrible hack, but is needed because recursive inclusion of files
# in different directories does not work well with VMS C. We try to help by
# specifying extra relative directories. They must always be in Unix format,
# relative to the directory where the .c file is located. The logic is that
# any inclusion, merged with one of these relative directories, will find the
# requested inclusion file.
foreach (grep /\[\.crypto\.async\.arch\].*\.o$/, keys %{$unified_info{sources}}) {
# These are horrible hacks, but are needed because recursive inclusion of
# files in different directories does not work well with VMS C. We try to
# help by specifying extra relative directories. They must always be in Unix
# format, relative to the directory where the .c file is located. The logic
# is that any inclusion, merged with one of these relative directories, will
# find the requested inclusion file.
# In the regexps, it's advisable to always start the file name with .*?, as
# the C source to OBJ file translation adds stuff at the beginning of the,
# name, such as [.ssl]bio_ssl.c -> [.ssl]libssl-shlib-bio_ssl.OBJ
foreach (grep /\[\.crypto\.async\.arch\].*?\.o$/, keys %{$unified_info{sources}}) {
my $obj = platform->obj($_);
push @{$unified_info{includes_extra}->{$obj}}, qw(../);
}
@ -223,7 +226,20 @@
my $obj = platform->obj($_);
push @{$unified_info{includes_extra}->{$obj}}, qw(../);
}
foreach (grep /\[\.ssl\.(?:record|statem)\].*?\.o$/, keys %{$unified_info{sources}}) {
foreach (grep /\[\.ssl\].*?\.o$/, keys %{$unified_info{sources}}) {
my $obj = platform->obj($_);
# Most of the files in [.ssl] include "ssl_local.h" which includes things
# like "record/record.h". Adding "./" as an inclusion directory helps
# making this sort of header from these directories.
push @{$unified_info{includes_extra}->{$obj}}, qw(./);
# Additionally, an increasing amount of files in [.ssl] include
# "quic/quic_local.h", which in turn includes "../ssl_local.h". Adding
# "./quic" as an inclusion directory helps making this sort of header
# from these directories.
push @{$unified_info{includes_extra}->{$obj}}, qw(./quic);
}
foreach (grep /\[\.ssl\.(?:quic|record|statem|rio)\].*?\.o$/, keys %{$unified_info{sources}}) {
my $obj = platform->obj($_);
# Most of the files in [.ssl.record] and [.ssl.statem] include
# "../ssl_local.h", which includes things like "record/record.h".
@ -232,13 +248,35 @@
push @{$unified_info{includes_extra}->{$obj}}, qw(../);
}
foreach (grep /\[\.ssl\.record\.methods\].*?\.o$/, keys %{$unified_info{sources}}) {
my $obj = platform->obj($_);
# Most of the files in [.ssl.record.methods] include "../../ssl_local.h"
# which includes things like "record/record.h". Adding "../../" as an
# inclusion directory helps making this sort of header from these
# directories. But this gets worse; through a series of inclusions,
# all of them based on the relative directory of the object file, there's
# a need to deal with an inclusion of "../ssl_local.h" as well.
push @{$unified_info{includes_extra}->{$obj}}, qw(../../), qw(../);
}
foreach (grep /\[\.test\].*?\.o$/, keys %{$unified_info{sources}}) {
my $obj = platform->obj($_);
push @{$unified_info{includes_extra}->{$obj}}, qw(../ssl ./helpers);
# Some of the sources in [.test] also include headers like
# "../ssl/record/methods/recmethod_local.h", which in turn might include
# "../../ssl_local.h", so these object files need yet another hack.
# We could make this specific to just the object files that are affected
# directly, but that would end up with more whack-a-mole of this sort, so
# nah, we do it broadly.
push @{$unified_info{includes_extra}->{$obj}}, qw(../ssl/record/methods);
# Similarly, some include "../ssl/ssl_local.h", and somewhere down the
# line, "quic/quic_local.h" gets included, which includes "../ssl_local.h"
# The problem is fixed by adding ../ssl/quic too.
push @{$unified_info{includes_extra}->{$obj}}, qw(../ssl/quic);
}
foreach (grep /\[\.test\.helpers\].*?\.o$/, keys %{$unified_info{sources}}) {
my $obj = platform->obj($_);
push @{$unified_info{includes_extra}->{$obj}}, qw(../../ssl);
push @{$unified_info{includes_extra}->{$obj}},
qw(../../ssl ../../ssl/quic);
}
# This makes sure things get built in the order they need
@ -436,7 +474,7 @@ NODEBUG=@
$(NODEBUG) ! Set up logical names for the libraries, so LINK and
$(NODEBUG) ! running programs can use them.
$(NODEBUG) !
$(NODEBUG) {- join("\n\t\$(NODEBUG) ", map { "DEFINE ".uc($_)." 'F\$ENV(\"DEFAULT\")'".uc($_)."\$(SHLIB_EXT)" } @shlibs) || "!" -}
$(NODEBUG) {- join("\n\t\$(NODEBUG) ", map { "DEFINE ".uc($_)." 'F\$ENV(\"DEFAULT\")'".uc($_).".EXE" } @shlibs) || "!" -}
.LAST :
$(NODEBUG) {- join("\n\t\$(NODEBUG) ", map { "DEASSIGN ".uc($_) } @shlibs) || "!" -}
@ -1030,16 +1068,48 @@ EOF
my $dofile = abs2rel(rel2abs(catfile($config{sourcedir},
"util", "dofile.pl")),
rel2abs($config{builddir}));
my @perlmodules = ( 'configdata.pm',
grep { $_ =~ m|\.pm$| } @{$args{deps}} );
my %perlmoduleincs = map { '"-I'.dirname($_).'"' => 1 } @perlmodules;
my @perlmodules = ();
my %perlmoduleincs = ();
my %perlmoduledeps = ();
foreach my $x (('configdata.pm', @{$args{deps}})) {
# Compute (i)nclusion directory, (m)odule name and (d)ependency
my $i, $m, $d;
if ($x =~ /\|/) {
$i = $`;
$d = $';
# Massage the module part to become a real perl module spec
$m = $d;
$m =~ s|\.pm$||;
# Directory specs are :: in perl package names
$m =~ s|/|::|g;
# Full file name of the dependency
$d = catfile($i, $d) if $i;
} elsif ($x =~ /\.pm$/) {
$i = dirname($x);
$m = basename($x, '.pm');
$d = $x;
} else {
# All other dependencies are simply collected
$d = $x;
}
push @perlmodules, '"-M'.$m.'"' if $m;
$perlmoduledeps{$d} = 1;
$perlmoduleincs{'"-I'.$i.'"'} = 1 if $i;
}
my @decc_include_data
= make_decc_include_files(dirname($args{src}), dirname($gen0));
my $decc_include_scripture = pop @decc_include_data;
$deps = join(' ', $deps, @decc_include_data,
compute_platform_depends(@perlmodules));
@perlmodules = map { '"-M'.basename($_, '.pm').'"' } @perlmodules;
my $perlmodules = join(' ', '', sort keys %perlmoduleincs, @perlmodules);
# Because of the special treatment of dependencies, we need to
# recompute $deps completely
my $deps
= join(" ", @decc_include_data,
compute_platform_depends(@{$args{generator_deps}},
sort keys %perlmoduledeps));
my $perlmodules = join(' ', '', ( sort keys %perlmoduleincs ), @perlmodules);
return <<"EOF";
$args{src} : $gen0 $deps
@ -1241,16 +1311,28 @@ EOF
# previous line's file spec as default, so if no directory spec
# is present in the current line and the previous line has one that
# doesn't apply, you're in for a surprise.
# Furthermore, we collect all object files and static libraries in
# an explicit cluster, to make it clear to the linker that these files
# shall be processed before shareable images.
# The shareable images are used with /SELECTIVE, to avoid warnings of
# multiply defined symbols when the module object files override some
# symbols that are present in the shareable image.
my $write_opt1 =
join(",-\"\n\t", map { my $x = $_ =~ /\[/ ? $_ : "[]".$_;
"WRITE OPT_FILE \"$x" } @objs).
"\"";
join(",-\"\n\t",
"\@ WRITE OPT_FILE \"CLUSTER=_,,",
(map { my $x = $_ =~ /\[/ ? $_ : "[]".$_;
"\@ WRITE OPT_FILE \"$x" } @objs),
(map { my $x = ($_->{lib} =~ /\[/) ? $_->{lib} : "[]".$_->{lib};
"\@ WRITE OPT_FILE \"$x/LIB" }
grep { $_->{lib} =~ m|\.OLB$| }
@deps))
."\"";
my $write_opt2 =
join("\n\t", map { my $x = $_->{lib} =~ /\[/
? $_->{lib} : "[]".$_->{lib};
$x =~ s|(\.EXE)|$1/SHARE|;
$x =~ s|(\.OLB)|$1/LIB|;
"WRITE OPT_FILE \"$x\"" } @deps)
join("\n\t",
(map { my $x = ($_->{lib} =~ /\[/) ? $_->{lib} : "[]".$_->{lib};
"\@ WRITE OPT_FILE \"$x/SHARE/SELECTIVE\"" }
grep { $_->{lib} =~ m|\.EXE$| }
@deps))
|| "\@ !";
return <<"EOF"
$dso : $deps
@ -1305,30 +1387,30 @@ EOF
# is present in the current line and the previous line has one that
# doesn't apply, you're in for a surprise.
my $write_opt1 =
join(",-\"\n\t", map { my $x = $_ =~ /\[/ ? $_ : "[]".$_;
"\@ WRITE OPT_FILE \"$x" } @objs).
"\"";
"\@ WRITE OPT_FILE \"CASE_SENSITIVE=YES\"\n\t"
.join(",-\"\n\t",
"\@ WRITE OPT_FILE \"CLUSTER=_,,",
(map { my $x = $_ =~ /\[/ ? $_ : "[]".$_;
"\@ WRITE OPT_FILE \"$x" } @objs),
(map { my $x = ($_->{lib} =~ /\[/) ? $_->{lib} : "[]".$_->{lib};
# Special hack to include the MAIN object module
# explicitly, if it's known that there is one.
# |incmain| is defined in the rule generation further
# down, with the necessary /INCLUDE=main option unless
# the program has been determined to have a main function
# already.
$_->{attrs}->{has_main}
? "\@ WRITE OPT_FILE \"$x/LIB''incmain'"
: "\@ WRITE OPT_FILE \"$x/LIB" }
grep { $_->{lib} =~ m|\.OLB$| }
@deps))
."\"";
my $write_opt2 =
join("\n\t", "WRITE OPT_FILE \"CASE_SENSITIVE=YES\"",
map { my @lines = ();
use Data::Dumper;
my $x = $_->{lib} =~ /\[/
? $_->{lib} : "[]".$_->{lib};
if ($x =~ m|\.EXE$|) {
push @lines, "\@ WRITE OPT_FILE \"$x/SHARE\"";
} elsif ($x =~ m|\.OLB$|) {
# Special hack to include the MAIN object
# module explicitly. This will only be done
# if there isn't a 'main' in the program's
# object modules already.
my $main = $_->{attrs}->{has_main}
? '/INCLUDE=main' : '';
push @lines,
"\@ IF nomain THEN WRITE OPT_FILE \"$x/LIB$main\"",
"\@ IF .NOT. nomain THEN WRITE OPT_FILE \"$x/LIB\""
}
@lines
} @deps)
join("\n\t",
(map { my $x = $_->{lib} =~ /\[/ ? $_->{lib} : "[]".$_->{lib};
"\@ WRITE OPT_FILE \"$x/SHARE/SELECTIVE\"" }
grep { $_->{lib} =~ m|\.EXE$| }
@deps))
|| "\@ !";
# The linking commands looks a bit complex, but it's for good reason.
# When you link, say, foo.obj, bar.obj and libsomething.exe/share, and
@ -1351,6 +1433,8 @@ EOF
return <<"EOF"
$bin : $deps
$analyse_objs
@ incmain = "/INCLUDE=main"
@ IF .NOT. nomain THEN incmain = ""
@ OPEN/WRITE/SHARE=READ OPT_FILE $binname.OPT
$write_opt1
$write_opt2

View file

@ -13,12 +13,16 @@ require platform::Unix;
use configdata;
sub dsoext { '.so' }
sub shlibextsimple { '.a' }
sub shlibextsimple { return '.so' if $target{shared_target} eq "aix-solib";
'.a'}
# In shared mode, the default static library names clashes with the final
# "simple" full shared library name, so we add '_a' to the basename of the
# static libraries in that case.
# static libraries in that case, unless in solib mode (using only .so
# files for shared libraries, and not packaging them inside archives)
sub staticname {
return platform::Unix->staticname($_[1]) if $target{shared_target} eq "aix-solib";
# Non-installed libraries are *always* static, and their names remain
# the same, except for the mandatory extension
my $in_libname = platform::BASE->staticname($_[1]);
@ -27,3 +31,17 @@ sub staticname {
return platform::BASE->staticname($_[1]) . ($disabled{shared} ? '' : '_a');
}
# In solib mode, we do not install the simple symlink (we install the import
# library). In regular mode, we install the symlink.
sub sharedlib_simple {
return undef if $target{shared_target} eq "aix-solib";
return platform::Unix->sharedlib_simple($_[1], $_[0]->shlibextsimple());
}
# In solib mode, we install the import library. In regular mode, we have
# no import library.
sub sharedlib_import {
return platform::Unix->sharedlib_simple($_[1]) if $target{shared_target} eq "aix-solib";
return undef;
}

View file

@ -73,7 +73,9 @@ sub sharedlib_simple {
my $name = $_[0]->sharedname($_[1]);
my $simplename = $_[0]->sharedname_simple($_[1]);
my $ext = $_[0]->shlibext();
my $simpleext = $_[0]->shlibextsimple();
# Allow override of the extension passed in as parameter
my $simpleext = $_[2];
$simpleext = $_[0]->shlibextsimple() unless defined $simpleext;
return undef unless defined $simplename && defined $name;
return undef if ($name eq $simplename && $ext eq $simpleext);

View file

@ -1,6 +1,6 @@
#! /usr/bin/env perl
# -*- mode: perl; -*-
# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
# 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
@ -40,6 +40,12 @@ my %shared_info;
};
},
'bsd-gcc-shared' => sub { return $shared_info{'linux-shared'}; },
'bsd-gcc-nodef-shared' => sub {
return {
%{$shared_info{'gnu-shared'}},
shared_defflags => '-Wl,--version-script=',
};
},
'darwin-shared' => {
module_ldflags => '-bundle',
shared_ldflag => '-dynamiclib -current_version $(SHLIB_VERSION_NUMBER) -compatibility_version $(SHLIB_VERSION_NUMBER)',

View file

@ -11,8 +11,13 @@
sub windowsdll { $config{target} =~ /^(?:Cygwin|mingw)/ }
# Shared AIX support is special. We put libcrypto[64].so.ver into
# libcrypto.a and use libcrypto_a.a as static one.
sub sharedaix { !$disabled{shared} && $config{target} =~ /^aix/ }
# libcrypto.a and use libcrypto_a.a as static one, unless using
# shared_target style aix-solib. In that mode, create
# libcrypto.so as a link-import library that inserts runtime
# dependencies on libcrypto.so.ver, and the static library is
# named libcrypto.a.
sub sharedaix { !$disabled{shared} && $target{shared_target} =~ /^aix(?!-solib$)/ }
sub sharedaix_solib { !$disabled{shared} && $target{shared_target} =~ /^aix-solib$/ }
our $sover_dirname = platform->shlib_version_as_filename();
@ -20,8 +25,9 @@
# to. You're welcome.
sub dependmagic {
my $target = shift;
my $help = shift;
return "$target: build_generated\n\t\"\$(MAKE)\" depend && \"\$(MAKE)\" _$target\n_$target";
return "$target: build_generated ## $help\n\t\"\$(MAKE)\" depend && \"\$(MAKE)\" _$target\n_$target";
}
our $COLUMNS = $ENV{COLUMNS};
@ -198,6 +204,18 @@ INSTALL_PROGRAMS={-
grep { !$unified_info{attributes}->{programs}->{$_}->{noinst} }
@{$unified_info{programs}}))
-}
INSTALL_EXPORTERS_PKGCONFIG={-
join(" \\\n" . ' ' x 28,
fill_lines(" ", $COLUMNS - 28,
grep { $unified_info{attributes}->{generate}->{$_}->{exporter} eq 'pkg-config'}
sort keys %{$unified_info{generate}}))
-}
INSTALL_EXPORTERS_CMAKE={-
join(" \\\n" . ' ' x 24,
fill_lines(" ", $COLUMNS - 24,
grep { $unified_info{attributes}->{generate}->{$_}->{exporter} eq 'cmake'}
sort keys %{$unified_info{generate}}))
-}
BIN_SCRIPTS={-
join(" \\\n" . ' ' x 12,
fill_lines(" ", $COLUMNS - 12,
@ -311,6 +329,17 @@ MODULESDIR=$(libdir)/ossl-modules
# libraries and applications
LIBRPATH=$(libdir)
BINDIR={- our $bindir = $config{bindir};
unless ($bindir) {
$bindir = "bin$target{multibin}";
}
file_name_is_absolute($bindir) ? "" : $bindir -}
bindir={- file_name_is_absolute($bindir)
? $bindir : '$(INSTALLTOP)/$(BINDIR)' -}
PKGCONFIGDIR=$(libdir)/pkgconfig
CMAKECONFIGDIR=$(libdir)/cmake/OpenSSL
MANDIR=$(INSTALLTOP)/share/man
DOCDIR=$(INSTALLTOP)/share/doc/$(BASENAME)
HTMLDIR=$(DOCDIR)/html
@ -344,6 +373,7 @@ CFLAGS={- join(' ', @{$config{CFLAGS}}) -}
CXXFLAGS={- join(' ', @{$config{CXXFLAGS}}) -}
LDFLAGS= {- join(' ', @{$config{LDFLAGS}}) -}
EX_LIBS= {- join(' ', @{$config{LDLIBS}}) -}
OBJCOPY={- $config{OBJCOPY} -}
MAKEDEPEND={- $config{makedepcmd} -}
@ -496,18 +526,28 @@ LANG=C
# The main targets ###################################################
{- dependmagic('build_sw'); -}: build_libs_nodep build_modules_nodep build_programs_nodep link-utils
{- dependmagic('build_libs'); -}: build_libs_nodep
{- dependmagic('build_modules'); -}: build_modules_nodep
{- dependmagic('build_programs'); -}: build_programs_nodep
##@ Software
{- dependmagic('build_sw', 'Build all the software (default target)'); -}: build_libs_nodep build_modules_nodep build_programs_nodep link-utils
{- dependmagic('build_libs', 'Build the libraries libssl and libcrypto'); -}: build_libs_nodep
{- dependmagic('build_modules', 'Build the modules (i.e. providers and engines)'); -}: build_modules_nodep
{- dependmagic('build_programs', 'Build the openssl executables and scripts'); -}: build_programs_nodep
all: build_sw {- "build_docs" if !$disabled{docs}; -} ## Build software and documentation
debuginfo: $(SHLIBS)
@set -e; for i in $(SHLIBS); do \
$(OBJCOPY) --only-keep-debug $$i $$i.debug; \
$(OBJCOPY) --strip-debug --add-gnu-debuglink=$$i.debug $$i; \
done;
##@ Documentation
build_generated_pods: $(GENERATED_PODS)
build_docs: build_man_docs build_html_docs
build_man_docs: $(MANDOCS1) $(MANDOCS3) $(MANDOCS5) $(MANDOCS7)
build_html_docs: $(HTMLDOCS1) $(HTMLDOCS3) $(HTMLDOCS5) $(HTMLDOCS7)
build_docs: build_man_docs build_html_docs ## Create documentation
build_man_docs: $(MANDOCS1) $(MANDOCS3) $(MANDOCS5) $(MANDOCS7) ## Create manpages
build_html_docs: $(HTMLDOCS1) $(HTMLDOCS3) $(HTMLDOCS5) $(HTMLDOCS7) ## Create HTML documentation
build_generated: $(GENERATED_MANDATORY)
build_libs_nodep: libcrypto.pc libssl.pc openssl.pc
build_libs_nodep: $(LIBS) {- join(" ",map { platform->sharedlib_simple($_) // platform->sharedlib_import($_) // platform->sharedlib($_) // () } @{$unified_info{libraries}}) -}
build_modules_nodep: $(MODULES)
build_programs_nodep: $(PROGRAMS) $(SCRIPTS)
@ -523,10 +563,14 @@ build_all_generated: $(GENERATED_MANDATORY) $(GENERATED) build_docs
@echo " then make will fail..."
@ : {- output_on() if $disabled{makedepend}; "" -}
all: build_sw build_docs
##@ Help
.PHONY: help
help: ## Show this help screen
@$(PERL) $(SRCDIR)/util/help.pl $(BLDDIR)/Makefile
test: tests
{- dependmagic('tests'); -}: build_programs_nodep build_modules_nodep link-utils
##@ Testing
test: tests ## Run tests (alias of "tests")
{- dependmagic('tests', 'Run tests'); -}: build_programs_nodep build_modules_nodep link-utils
"$(MAKE)" run_tests
run_tests: FORCE
@ : {- output_off() if $disabled{tests}; "" -}
@ -540,16 +584,14 @@ run_tests: FORCE
@echo "Tests are not supported with your chosen Configure options"
@ : {- output_on() if !$disabled{tests}; "" -}
list-tests:
list-tests: ## List available tests that can be invoked via "make test TESTS=<name>"
@ : {- output_off() if $disabled{tests}; "" -}
"$(MAKE)" run_tests TESTS=list
@ : {- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -}
@echo "Tests are not supported with your chosen Configure options"
@ : {- output_on() if !$disabled{tests}; "" -}
install: install_sw install_ssldirs install_docs {- $disabled{fips} ? "" : "install_fips" -}
uninstall: uninstall_docs uninstall_sw {- $disabled{fips} ? "" : "uninstall_fips" -}
##@ Workspace cleaning
libclean:
@set -e; for s in $(SHLIB_INFO); do \
@ -574,7 +616,7 @@ libclean:
$(RM) $(LIBS)
$(RM) *{- platform->defext() -}
clean: libclean
clean: libclean ## Clean the workspace, keep the configuration
$(RM) $(HTMLDOCS1)
$(RM) $(HTMLDOCS3)
$(RM) $(HTMLDOCS5)
@ -591,10 +633,9 @@ clean: libclean
$(RM) tags TAGS doc-nits md-nits
$(RM) -r test/test-runs
$(RM) providers/fips*.new
$(RM) openssl.pc libcrypto.pc libssl.pc
-find . -type l \! -name '.*' -exec $(RM) {} \;
distclean: clean
distclean: clean ## Clean and remove the configuration
$(RM) include/openssl/configuration.h
$(RM) configdata.pm
$(RM) Makefile
@ -607,14 +648,19 @@ depend: Makefile
@: {- output_on() if $disabled{makedepend}; "" -}
# Install helper targets #############################################
##@ Installation
install_sw: install_dev install_engines install_modules install_runtime
install: install_sw install_ssldirs {- "install_docs" if !$disabled{docs}; -} {- $disabled{fips} ? "" : "install_fips" -} ## Install software and documentation, create OpenSSL directories
uninstall_sw: uninstall_runtime uninstall_modules uninstall_engines uninstall_dev
uninstall: {- "uninstall_docs" if !$disabled{docs}; -} uninstall_sw {- $disabled{fips} ? "" : "uninstall_fips" -} ## Uninstall software and documentation
install_docs: install_man_docs install_html_docs
install_sw: install_dev install_engines install_modules install_runtime ## Install just the software and libraries
uninstall_docs: uninstall_man_docs uninstall_html_docs
uninstall_sw: uninstall_runtime uninstall_modules uninstall_engines uninstall_dev ## Uninstall the software and libraries
install_docs: install_man_docs install_html_docs ## Install manpages and HTML documentation
uninstall_docs: uninstall_man_docs uninstall_html_docs ## Uninstall manpages and HTML documentation
$(RM) -r "$(DESTDIR)$(DOCDIR)"
{- output_off() if $disabled{fips}; "" -}
@ -725,12 +771,12 @@ install_dev: install_runtime_libs
fn1=`basename "$$s1"`; \
fn2=`basename "$$s2"`; \
fn3=`basename "$$s3"`; \
: {- output_off(); output_on() unless windowsdll() or sharedaix(); "" -}; \
: {- output_off(); output_on() unless windowsdll() or sharedaix() or sharedaix_solib(); "" -}; \
if [ "$$fn2" != "" ]; then \
$(ECHO) "link $(DESTDIR)$(libdir)/$$fn2 -> $(DESTDIR)$(libdir)/$$fn1"; \
ln -sf $$fn1 "$(DESTDIR)$(libdir)/$$fn2"; \
fi; \
: {- output_off() unless windowsdll() or sharedaix(); output_on() if windowsdll(); "" -}; \
: {- output_off() unless windowsdll() or sharedaix() or sharedaix_solib(); output_on() if windowsdll() or sharedaix_solib(); "" -}; \
if [ "$$fn3" != "" ]; then \
$(ECHO) "install $$s3 -> $(DESTDIR)$(libdir)/$$fn3"; \
cp $$s3 "$(DESTDIR)$(libdir)/$$fn3.new"; \
@ -738,7 +784,7 @@ install_dev: install_runtime_libs
mv -f "$(DESTDIR)$(libdir)/$$fn3.new" \
"$(DESTDIR)$(libdir)/$$fn3"; \
fi; \
: {- output_off() if windowsdll(); output_on() if sharedaix(); "" -}; \
: {- output_off() if windowsdll() or sharedaix_solib(); output_on() if sharedaix(); "" -}; \
a="$(DESTDIR)$(libdir)/$$fn2"; \
$(ECHO) "install $$s1 -> $$a"; \
if [ -f $$a ]; then ( trap "rm -rf /tmp/ar.$$$$" INT 0; \
@ -756,16 +802,20 @@ install_dev: install_runtime_libs
: {- output_off() if sharedaix(); output_on(); "" -}; \
done
@ : {- output_on() if $disabled{shared}; "" -}
@$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(libdir)/pkgconfig"
@$(ECHO) "install libcrypto.pc -> $(DESTDIR)$(libdir)/pkgconfig/libcrypto.pc"
@cp libcrypto.pc "$(DESTDIR)$(libdir)/pkgconfig"
@chmod 644 "$(DESTDIR)$(libdir)/pkgconfig/libcrypto.pc"
@$(ECHO) "install libssl.pc -> $(DESTDIR)$(libdir)/pkgconfig/libssl.pc"
@cp libssl.pc "$(DESTDIR)$(libdir)/pkgconfig"
@chmod 644 "$(DESTDIR)$(libdir)/pkgconfig/libssl.pc"
@$(ECHO) "install openssl.pc -> $(DESTDIR)$(libdir)/pkgconfig/openssl.pc"
@cp openssl.pc "$(DESTDIR)$(libdir)/pkgconfig"
@chmod 644 "$(DESTDIR)$(libdir)/pkgconfig/openssl.pc"
@$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(PKGCONFIGDIR)"
@for e in $(INSTALL_EXPORTERS_PKGCONFIG); do \
fn=`basename $$e`; \
$(ECHO) "install $$e -> $(DESTDIR)$(PKGCONFIGDIR)/$$fn"; \
cp $$e "$(DESTDIR)$(PKGCONFIGDIR)/$$fn"; \
chmod 644 "$(DESTDIR)$(PKGCONFIGDIR)/$$fn"; \
done
@$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(CMAKECONFIGDIR)"
@for e in $(INSTALL_EXPORTERS_CMAKE); do \
fn=`basename $$e`; \
$(ECHO) "install $$e -> $(DESTDIR)$(CMAKECONFIGDIR)/$$fn"; \
cp $$e "$(DESTDIR)$(CMAKECONFIGDIR)/$$fn"; \
chmod 644 "$(DESTDIR)$(CMAKECONFIGDIR)/$$fn"; \
done
uninstall_dev: uninstall_runtime_libs
@$(ECHO) "*** Uninstalling development files"
@ -809,10 +859,16 @@ uninstall_dev: uninstall_runtime_libs
: {- output_on() unless windowsdll(); "" -}; \
done
@ : {- output_on() if $disabled{shared}; "" -}
$(RM) "$(DESTDIR)$(libdir)/pkgconfig/libcrypto.pc"
$(RM) "$(DESTDIR)$(libdir)/pkgconfig/libssl.pc"
$(RM) "$(DESTDIR)$(libdir)/pkgconfig/openssl.pc"
-$(RMDIR) "$(DESTDIR)$(libdir)/pkgconfig"
@for e in $(INSTALL_EXPORTERS_PKGCONFIG); do \
fn=`basename "$$e"`; \
$(RM) "$(DESTDIR)$(PKGCONFIGDIR)/$$fn"; \
done
@for e in $(INSTALL_EXPORTERS_CMAKE); do \
fn=`basename "$$e"`; \
$(RM) "$(DESTDIR)$(CMAKECONFIGDIR)/$$fn"; \
done
-$(RMDIR) "$(DESTDIR)$(PKGCONFIGDIR)"
-$(RMDIR) "$(DESTDIR)$(CMAKECONFIGDIR)"
-$(RMDIR) "$(DESTDIR)$(libdir)"
_install_modules_deps: install_runtime_libs build_modules
@ -872,18 +928,18 @@ install_runtime_libs: build_libs
@ : {- output_off() if windowsdll(); "" -}
@$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(libdir)"
@ : {- output_on() if windowsdll(); output_off() unless windowsdll(); "" -}
@$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(INSTALLTOP)/bin"
@$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(bindir)/"
@ : {- output_on() unless windowsdll(); "" -}
@$(ECHO) "*** Installing runtime libraries"
@set -e; for s in dummy $(INSTALL_SHLIBS); do \
if [ "$$s" = "dummy" ]; then continue; fi; \
fn=`basename $$s`; \
: {- output_off() unless windowsdll(); "" -}; \
$(ECHO) "install $$s -> $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
cp $$s "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new"; \
chmod 755 "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new"; \
mv -f "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new" \
"$(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
$(ECHO) "install $$s -> $(DESTDIR)$(bindir)/$$fn"; \
cp $$s "$(DESTDIR)$(bindir)/$$fn.new"; \
chmod 755 "$(DESTDIR)$(bindir)/$$fn.new"; \
mv -f "$(DESTDIR)$(bindir)/$$fn.new" \
"$(DESTDIR)$(bindir)/$$fn"; \
: {- output_on() unless windowsdll(); "" -}{- output_off() if windowsdll(); "" -}; \
$(ECHO) "install $$s -> $(DESTDIR)$(libdir)/$$fn"; \
cp $$s "$(DESTDIR)$(libdir)/$$fn.new"; \
@ -895,25 +951,25 @@ install_runtime_libs: build_libs
install_programs: install_runtime_libs build_programs
@[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1)
@$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(INSTALLTOP)/bin"
@$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(bindir)"
@$(ECHO) "*** Installing runtime programs"
@set -e; for x in dummy $(INSTALL_PROGRAMS); do \
if [ "$$x" = "dummy" ]; then continue; fi; \
fn=`basename $$x`; \
$(ECHO) "install $$x -> $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
cp $$x "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new"; \
chmod 755 "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new"; \
mv -f "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new" \
"$(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
$(ECHO) "install $$x -> $(DESTDIR)$(bindir)/$$fn"; \
cp $$x "$(DESTDIR)$(bindir)/$$fn.new"; \
chmod 755 "$(DESTDIR)$(bindir)/$$fn.new"; \
mv -f "$(DESTDIR)$(bindir)/$$fn.new" \
"$(DESTDIR)$(bindir)/$$fn"; \
done
@set -e; for x in dummy $(BIN_SCRIPTS); do \
if [ "$$x" = "dummy" ]; then continue; fi; \
fn=`basename $$x`; \
$(ECHO) "install $$x -> $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
cp $$x "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new"; \
chmod 755 "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new"; \
mv -f "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new" \
"$(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
$(ECHO) "install $$x -> $(DESTDIR)$(bindir)/$$fn"; \
cp $$x "$(DESTDIR)$(bindir)/$$fn.new"; \
chmod 755 "$(DESTDIR)$(bindir)/$$fn.new"; \
mv -f "$(DESTDIR)$(bindir)/$$fn.new" \
"$(DESTDIR)$(bindir)/$$fn"; \
done
uninstall_runtime: uninstall_programs uninstall_runtime_libs
@ -924,17 +980,17 @@ uninstall_programs:
do \
if [ "$$x" = "dummy" ]; then continue; fi; \
fn=`basename $$x`; \
$(ECHO) "$(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
$(RM) "$(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
$(ECHO) "$(RM) $(DESTDIR)$(bindir)/$$fn"; \
$(RM) "$(DESTDIR)$(bindir)/$$fn"; \
done;
@set -e; for x in dummy $(BIN_SCRIPTS); \
do \
if [ "$$x" = "dummy" ]; then continue; fi; \
fn=`basename $$x`; \
$(ECHO) "$(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
$(RM) "$(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
$(ECHO) "$(RM) $(DESTDIR)$(bindir)/$$fn"; \
$(RM) "$(DESTDIR)$(bindir)/$$fn"; \
done
-$(RMDIR) "$(DESTDIR)$(INSTALLTOP)/bin"
-$(RMDIR) "$(DESTDIR)$(bindir)"
uninstall_runtime_libs:
@$(ECHO) "*** Uninstalling runtime libraries"
@ -942,8 +998,8 @@ uninstall_runtime_libs:
@set -e; for s in dummy $(INSTALL_SHLIBS); do \
if [ "$$s" = "dummy" ]; then continue; fi; \
fn=`basename $$s`; \
$(ECHO) "$(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
$(RM) "$(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
$(ECHO) "$(RM) $(DESTDIR)$(bindir)/$$fn"; \
$(RM) "$(DESTDIR)$(bindir)/$$fn"; \
done
@ : {- output_on() unless windowsdll(); "" -}
@ -1101,19 +1157,23 @@ uninstall_image_docs:
done
# Developer targets (note: these are only available on Unix) #########
##@ Code maintenance
# It's important that generate_buildinfo comes after ordinals, as ordinals
# is sensitive to build.info changes.
update: generate errors ordinals generate_buildinfo
update: generate errors ordinals generate_buildinfo ## Update errors, ordinals and build info
.PHONY: generate generate_apps generate_crypto_bn generate_crypto_objects \
generate_crypto_conf generate_crypto_asn1 generate_fuzz_oids
generate: generate_apps generate_crypto_bn generate_crypto_objects \
generate_crypto_conf generate_crypto_asn1 generate_fuzz_oids
.PHONY: generate_buildinfo generate_doc_buildinfo
generate_buildinfo: generate_doc_buildinfo
.PHONY: doc-nits md-nits
doc-nits: build_generated_pods
$(PERL) $(SRCDIR)/util/find-doc-nits -c -n -l -e
doc-nits: build_generated_pods ## Evaluate OpenSSL documentation
$(PERL) $(SRCDIR)/util/find-doc-nits -c -n -l -e -i
# This uses "mdl", the markdownlint application, which is written in ruby.
# The source is at https://github.com/markdownlint/markdownlint
@ -1121,15 +1181,23 @@ doc-nits: build_generated_pods
# Another option is at https://snapcraft.io/install/mdl/debian
# Finally, there's a Node.js version, which we haven't tried, that
# can be found at https://github.com/DavidAnson/markdownlint
md-nits:
mdl -s util/markdownlint.rb .
md-nits: ## Evaluate markdown files via "mdl"
mdl -s $(SRCDIR)/util/markdownlint.rb .
# Test coverage is a good idea for the future
#coverage: $(PROGRAMS) $(TESTPROGRAMS)
# ...
lint:
lint -DLINT $(INCLUDES) $(SRCS)
.PHONY: lint
lint: ## Evaluate C code via "splint"
@( cd $(SRCDIR); \
echo splint -DLINT -posixlib -preproc -D__gnuc_va_list=void \
-I. -Iinclude -Iapps/include $(CRYPTOHEADERS) $(SSLHEADERS) $(SRCS) )
.PHONY: check-format
check-format: ## Evaluate C code according to OpenSSL coding standards
( cd $(SRCDIR); $(PERL) util/check-format.pl \
$(SRCS) \$(CRYPTOHEADERS) $(SSLHEADERS) )
generate_apps:
( cd $(SRCDIR); $(PERL) VMS/VMSify-conf.pl \
@ -1232,7 +1300,7 @@ providers/fips.module.sources.new: configdata.pm
crypto/*cap.c; do \
echo "$$x"; \
done \
) | sort | uniq > providers/fips.module.sources.new
) | grep -v sm2p256 | sort | uniq > providers/fips.module.sources.new
rm -rf sources-tmp
# Set to -force to force a rebuild
@ -1259,6 +1327,7 @@ errors:
include/openssl/tls1.h
include/openssl/dtls1.h
include/openssl/srtp.h
include/openssl/quic.h
include/openssl/sslerr_legacy.h );
my @cryptoheaders_tmpl =
qw( include/internal/dso.h
@ -1304,6 +1373,14 @@ errors:
}
"";
-}
SRCS={-
sub uniq { my %seen; grep !$seen{$_}++, @_; }
sub flat(@) { return map { ref eq 'ARRAY' ? @$_ : $_ } @_; }
join(" \\\n" . ' ' x 5, fill_lines(" ", $COLUMNS - 5,
uniq(grep /\.(c|cc|cpp)$/,
flat (map { $unified_info{sources}->{$_} }
(sort keys %{$unified_info{sources}})))))
-}
CRYPTOHEADERS={- join(" \\\n" . ' ' x 14,
fill_lines(" ", $COLUMNS - 14, sort keys %cryptoheaders)) -}
SSLHEADERS={- join(" \\\n" . ' ' x 11,
@ -1321,6 +1398,7 @@ renumber: build_generated
--renumber \
$(SSLHEADERS)
.PHONY: ordinals
ordinals: build_generated
$(PERL) $(SRCDIR)/util/mknum.pl --version $(VERSION_NUMBER) --no-warnings \
--ordinals $(SRCDIR)/util/libcrypto.num \
@ -1336,7 +1414,7 @@ test_ordinals:
tags TAGS: FORCE
rm -f TAGS tags
-ctags -R .
-( cd $(SRCDIR); util/ctags.sh )
-etags `find . -name '*.[ch]' -o -name '*.pm'`
providers/fips.checksum.new: providers/fips.module.sources.new
@ -1390,59 +1468,6 @@ FORCE:
# Building targets ###################################################
libcrypto.pc libssl.pc openssl.pc: Makefile $(LIBS) {- join(" ",map { platform->sharedlib_simple($_) // platform->sharedlib_import($_) // platform->sharedlib($_) // () } @{$unified_info{libraries}}) -}
libcrypto.pc:
@ ( echo 'prefix=$(INSTALLTOP)'; \
echo 'exec_prefix=$${prefix}'; \
if [ -n "$(LIBDIR)" ]; then \
echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
else \
echo 'libdir=$(libdir)'; \
fi; \
echo 'includedir=$${prefix}/include'; \
echo 'enginesdir=$${libdir}/engines-{- $sover_dirname -}'; \
echo 'modulesdir=$${libdir}/ossl-modules'; \
echo ''; \
echo 'Name: OpenSSL-libcrypto'; \
echo 'Description: OpenSSL cryptography library'; \
echo 'Version: '$(VERSION); \
echo 'Libs: -L$${libdir} -lcrypto'; \
echo 'Libs.private: $(LIB_EX_LIBS)'; \
echo 'Cflags: -I$${includedir}' ) > libcrypto.pc
libssl.pc:
@ ( echo 'prefix=$(INSTALLTOP)'; \
echo 'exec_prefix=$${prefix}'; \
if [ -n "$(LIBDIR)" ]; then \
echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
else \
echo 'libdir=$(libdir)'; \
fi; \
echo 'includedir=$${prefix}/include'; \
echo ''; \
echo 'Name: OpenSSL-libssl'; \
echo 'Description: Secure Sockets Layer and cryptography libraries'; \
echo 'Version: '$(VERSION); \
echo 'Requires.private: libcrypto'; \
echo 'Libs: -L$${libdir} -lssl'; \
echo 'Cflags: -I$${includedir}' ) > libssl.pc
openssl.pc:
@ ( echo 'prefix=$(INSTALLTOP)'; \
echo 'exec_prefix=$${prefix}'; \
if [ -n "$(LIBDIR)" ]; then \
echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
else \
echo 'libdir=$(libdir)'; \
fi; \
echo 'includedir=$${prefix}/include'; \
echo ''; \
echo 'Name: OpenSSL'; \
echo 'Description: Secure Sockets Layer and cryptography libraries and tools'; \
echo 'Version: '$(VERSION); \
echo 'Requires: libssl libcrypto' ) > openssl.pc
Makefile: configdata.pm \
{- join(" \\\n" . ' ' x 10,
fill_lines(" ", $COLUMNS - 10,
@ -1596,12 +1621,44 @@ EOF
my $dofile = abs2rel(rel2abs(catfile($config{sourcedir},
"util", "dofile.pl")),
rel2abs($config{builddir}));
my @perlmodules = ( 'configdata.pm',
grep { $_ =~ m|\.pm$| } @{$args{deps}} );
my %perlmoduleincs = map { '"-I'.dirname($_).'"' => 1 } @perlmodules;
$deps = join(' ', $deps, compute_platform_depends(@perlmodules));
@perlmodules = map { "-M".basename($_, '.pm') } @perlmodules;
my $perlmodules = join(' ', '', sort keys %perlmoduleincs, @perlmodules);
my @perlmodules = ();
my %perlmoduleincs = ();
my %perlmoduledeps = ();
foreach my $x (('configdata.pm', @{$args{deps}})) {
# Compute (i)nclusion directory, (m)odule name and (d)ependency
my $i, $m, $d;
if ($x =~ /\|/) {
$i = $`;
$d = $';
# Massage the module part to become a real perl module spec
$m = $d;
$m =~ s|\.pm$||;
# Directory specs are :: in perl package names
$m =~ s|/|::|g;
# Full file name of the dependency
$d = catfile($i, $d) if $i;
} elsif ($x =~ /\.pm$/) {
$i = dirname($x);
$m = basename($x, '.pm');
$d = $x;
} else {
# All other dependencies are simply collected
$d = $x;
}
push @perlmodules, '"-M'.$m.'"' if $m;
$perlmoduledeps{$d} = 1;
$perlmoduleincs{'"-I'.$i.'"'} = 1 if $i;
}
# Because of the special treatment of dependencies, we need to
# recompute $deps completely
my $deps
= join(" ", compute_platform_depends(@{$args{generator_deps}},
sort keys %perlmoduledeps));
my $perlmodules = join(' ', '', ( sort keys %perlmoduleincs ), @perlmodules);
return <<"EOF";
$args{src}: $gen0 $deps
\$(PERL)$perlmodules "$dofile" "-o$target{build_file}" $gen0$gen_args > \$@
@ -1743,6 +1800,8 @@ EOF
# libraries for DLLs are a thing. On platforms that have this mechanism,
# $import has the name of this import library. On platforms that don't
# have this mechanism, $import will be |undef|.
# It's also used on AIX in solib mode, which creates import libraries
# for the shared libraries.
my $import = platform->sharedlib_import($args{lib});
# $simple is for platforms where full shared library names include the
# shared library version, and there's a simpler name that doesn't include
@ -1803,10 +1862,19 @@ EOF
}
}
if (defined $import) {
if (sharedaix_solib()) {
$recipe .= <<"EOF";
$import: $full $defs[0]
rm -f $import && \\
echo \\#!$full > $import && \\
cat $defs[0] >>$import
EOF
} else {
$recipe .= <<"EOF";
$import: $full
EOF
}
}
$recipe .= <<"EOF";
$full: $fulldeps
\$(CC) \$(LIB_CFLAGS) $linkflags\$(LIB_LDFLAGS)$shared_soname$shared_imp \\

View file

@ -155,6 +155,11 @@ MISC_SCRIPTS={-
&& $unified_info{attributes}->{scripts}->{$_}->{misc} }
@{$unified_info{scripts}})
-}
INSTALL_EXPORTERS_CMAKE={-
join(" ", map { quotify1($_) }
grep { $unified_info{attributes}->{generate}->{$_}->{exporter} eq 'cmake'}
sort keys %{$unified_info{generate}})
-}
IMAGEDOCS1={- our @IMAGEDOCS1 = @{$unified_info{imagedocs}->{man1}};
join(" ", @IMAGEDOCS1) -}
IMAGEDOCS3={- our @IMAGEDOCS3 = @{$unified_info{imagedocs}->{man3}};
@ -249,6 +254,8 @@ MODULESDIR=$(MODULESDIR_dev)$(MODULESDIR_dir)
libdir={- file_name_is_absolute($libdir)
? $libdir : '$(INSTALLTOP)\$(LIBDIR)' -}
CMAKECONFIGDIR=$(libdir)\cmake\OpenSSL
##### User defined commands and flags ################################
CC="{- $config{CC} -}"
@ -436,7 +443,7 @@ build_all_generated: $(GENERATED_MANDATORY) $(GENERATED) build_docs
@$(ECHO) " then make will fail..."
@{- output_on() if $disabled{makedepend}; "\@rem" -}
all: build_sw build_docs
all: build_sw {- "build_docs" if !$disabled{docs}; -}
test: tests
{- dependmagic('tests'); -}: build_programs_nodep build_modules_nodep copy-utils
@ -455,9 +462,9 @@ list-tests:
@$(ECHO) "Tests are not supported with your chosen Configure options"
@{- output_on() if !$disabled{tests}; "\@rem" -}
install: install_sw install_ssldirs install_docs {- $disabled{fips} ? "" : "install_fips" -}
install: install_sw install_ssldirs {- "install_docs" if !$disabled{docs}; -} {- $disabled{fips} ? "" : "install_fips" -}
uninstall: uninstall_docs uninstall_sw {- $disabled{fips} ? "" : "uninstall_fips" -}
uninstall: {- "uninstall_docs" if !$disabled{docs}; -} uninstall_sw {- $disabled{fips} ? "" : "uninstall_fips" -}
libclean:
"$(PERL)" -e "map { m/(.*)\.dll$$/; unlink glob """{.,apps,test,fuzz}/$$1.*"""; } @ARGV" $(SHLIBS)
@ -559,6 +566,8 @@ install_dev: install_runtime_libs
@"$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_LIBS) "$(libdir)"
@if "$(SHLIBS)"=="" \
"$(PERL)" "$(SRCDIR)\util\copy.pl" ossl_static.pdb "$(libdir)"
@"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(CMAKECONFIGDIR)"
@"$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_EXPORTERS_CMAKE) "$(CMAKECONFIGDIR)"
uninstall_dev:
@ -782,7 +791,7 @@ EOF
}
return <<"EOF";
$target: "$gen0" $deps
\$(CPP) $incs $cppflags $defs "$gen0" > \$@.i
\$(CPP) /D__ASSEMBLER__ $incs $cppflags $defs "$gen0" > \$@.i
move /Y \$@.i \$@
EOF
} elsif ($gen0 =~ m|^.*\.in$|) {
@ -792,12 +801,44 @@ EOF
my $dofile = abs2rel(rel2abs(catfile($config{sourcedir},
"util", "dofile.pl")),
rel2abs($config{builddir}));
my @perlmodules = ( 'configdata.pm',
grep { $_ =~ m|\.pm$| } @{$args{deps}} );
my %perlmoduleincs = map { '"-I'.dirname($_).'"' => 1 } @perlmodules;
$deps = join(' ', $deps, compute_platform_depends(@perlmodules));
@perlmodules = map { "-M".basename($_, '.pm') } @perlmodules;
my $perlmodules = join(' ', '', sort keys %perlmoduleincs, @perlmodules);
my @perlmodules = ();
my %perlmoduleincs = ();
my %perlmoduledeps = ();
foreach my $x (('configdata.pm', @{$args{deps}})) {
# Compute (i)nclusion directory, (m)odule name and (d)ependency
my $i, $m, $d;
if ($x =~ /\|/) {
$i = $`;
$d = $';
# Massage the module part to become a real perl module spec
$m = $d;
$m =~ s|\.pm$||;
# Directory specs are :: in perl package names
$m =~ s|/|::|g;
# Full file name of the dependency
$d = catfile($i, $d) if $i;
} elsif ($x =~ /\.pm$/) {
$i = dirname($x);
$m = basename($x, '.pm');
$d = $x;
} else {
# All other dependencies are simply collected
$d = $x;
}
push @perlmodules, '"-M'.$m.'"' if $m;
$perlmoduledeps{$d} = 1;
$perlmoduleincs{'"-I'.$i.'"'} = 1 if $i;
}
# Because of the special treatment of dependencies, we need to
# recompute $deps completely
my $deps
= join(" ", compute_platform_depends(@{$args{generator_deps}},
sort keys %perlmoduledeps));
my $perlmodules = join(' ', '', ( sort keys %perlmoduleincs ), @perlmodules);
return <<"EOF";
$args{src}: "$gen0" $deps
"\$(PERL)"$perlmodules "$dofile" "-o$target{build_file}" "$gen0"$gen_args > \$@

View file

@ -27,7 +27,7 @@ use OpenSSL::config;
my $orig_death_handler = $SIG{__DIE__};
$SIG{__DIE__} = \&death_handler;
my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
my $usage="Usage: Configure [no-<feature> ...] [enable-<feature> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]thread-pool] [[no-]default-thread-pool] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
my $banner = <<"EOF";
@ -77,10 +77,23 @@ EOF
# Generic OpenSSL-style methods relating to this support
# are always compiled but return NULL if the hardware
# support isn't compiled.
#
# enable-demos Enable the building of the example code in the demos directory
# enable-h3demo Enable the http3 demo, which currently only links to the
# external nghttp3 library on unix platforms
#
# enable-hqinterop
# Enable the building of the hq-interop code for construction
# of the interop container
#
# no-hw do not compile support for any crypto hardware.
# [no-]threads [don't] try to create a library that is suitable for
# multithreaded applications (default is "threads" if we
# know how to do it)
# [no-]thread-pool
# [don't] allow thread pool functionality
# [no-]default-thread-pool
# [don't] allow default thread pool functionality
# [no-]shared [don't] try to create shared libraries when supported.
# [no-]pic [don't] try to build position independent code when supported.
# If disabled, it also disables shared and dynamic-engine.
@ -88,8 +101,9 @@ EOF
# no-egd do not compile support for the entropy-gathering daemon APIs
# [no-]zlib [don't] compile support for zlib compression.
# zlib-dynamic Like "zlib", but the zlib library is expected to be a shared
# library and will be loaded in run-time by the OpenSSL library.
# library and will be loaded at run-time by the OpenSSL library.
# sctp include SCTP support
# no-quic disable QUIC support
# no-uplink Don't build support for UPLINK interface.
# enable-weak-ssl-ciphers
# Enable weak ciphers that are disabled by default.
@ -162,7 +176,7 @@ my @gcc_devteam_warn = qw(
-Wsign-compare
-Wshadow
-Wformat
-Wtype-limits
-Wno-type-limits
-Wundef
-Werror
-Wmissing-prototypes
@ -182,6 +196,8 @@ my @clang_devteam_warn = qw(
-Wno-parentheses-equality
-Wno-language-extension-token
-Wno-extended-offsetof
-Wno-missing-braces
-Wno-tautological-constant-out-of-range-compare
-Wconditional-uninitialized
-Wincompatible-pointer-types-discards-qualifiers
-Wmissing-variable-declarations
@ -378,6 +394,12 @@ if (defined env($local_config_envname)) {
}
}
# Fail if no configuration is apparent
if (!%table) {
print "Failed to find any os/compiler configurations. Please make sure the Configurations directory is included.\n";
&usage;
}
# Save away perl command information
$config{perl_cmd} = $^X;
$config{perl_version} = $Config{version};
@ -401,6 +423,8 @@ my @dtls = qw(dtls1 dtls1_2);
my @disablables = (
"acvp-tests",
"afalgeng",
"apps",
"argon2",
"aria",
"asan",
"asm",
@ -411,11 +435,14 @@ my @disablables = (
"autoload-config",
"bf",
"blake2",
"brotli",
"brotli-dynamic",
"buildtest-c++",
"bulk",
"cached-fetch",
"camellia",
"capieng",
"winstore",
"cast",
"chacha",
"cmac",
@ -424,11 +451,16 @@ my @disablables = (
"comp",
"crypto-mdebug",
"ct",
"default-thread-pool",
"demos",
"h3demo",
"hqinterop",
"deprecated",
"des",
"devcryptoeng",
"dgram",
"dh",
"docs",
"dsa",
"dso",
"dtls",
@ -438,6 +470,7 @@ my @disablables = (
"ec_nistp_64_gcc_128",
"ecdh",
"ecdsa",
"ecx",
"egd",
"engine",
"err",
@ -445,10 +478,15 @@ my @disablables = (
"filenames",
"fips",
"fips-securitychecks",
"fips-post",
"fips-jitter",
"fuzz-afl",
"fuzz-libfuzzer",
"gost",
"http",
"idea",
"integrity-only-ciphers",
"jitter",
"ktls",
"legacy",
"loadereng",
@ -456,6 +494,8 @@ my @disablables = (
"md2",
"md4",
"mdc2",
"ml-dsa",
"ml-kem",
"module",
"msan",
"multiblock",
@ -464,10 +504,13 @@ my @disablables = (
"ocsp",
"padlockeng",
"pic",
"pie",
"pinshared",
"poly1305",
"posix-io",
"psk",
"quic",
"unstable-qlog",
"rc2",
"rc4",
"rc5",
@ -481,7 +524,9 @@ my @disablables = (
"shared",
"siphash",
"siv",
"slh-dsa",
"sm2",
"sm2-precomp",
"sm3",
"sm4",
"sock",
@ -492,9 +537,13 @@ my @disablables = (
"ssl-trace",
"static-engine",
"stdio",
"sslkeylog",
"tests",
"tfo",
"thread-pool",
"threads",
"tls",
"tls-deprecated-ec",
"trace",
"ts",
"ubsan",
@ -505,6 +554,8 @@ my @disablables = (
"whirlpool",
"zlib",
"zlib-dynamic",
"zstd",
"zstd-dynamic",
);
foreach my $proto ((@tls, @dtls))
{
@ -535,16 +586,24 @@ my %deprecated_disablables = (
our %disabled = ( # "what" => "comment"
"fips" => "default",
"fips-jitter" => "default",
"asan" => "default",
"brotli" => "default",
"brotli-dynamic" => "default",
"buildtest-c++" => "default",
"crypto-mdebug" => "default",
"crypto-mdebug-backtrace" => "default",
"demos" => "default",
"h3demo" => "default",
"hqinterop" => "default",
"devcryptoeng" => "default",
"ec_nistp_64_gcc_128" => "default",
"egd" => "default",
"external-tests" => "default",
"fuzz-afl" => "default",
"fuzz-libfuzzer" => "default",
"pie" => "default",
"jitter" => "default",
"ktls" => "default",
"md2" => "default",
"msan" => "default",
@ -552,31 +611,36 @@ our %disabled = ( # "what" => "comment"
"sctp" => "default",
"ssl3" => "default",
"ssl3-method" => "default",
"sslkeylog" => "default",
"tfo" => "default",
"trace" => "default",
"ubsan" => "default",
"unit-test" => "default",
"weak-ssl-ciphers" => "default",
"zlib" => "default",
"zlib-dynamic" => "default",
"zstd" => "default",
"zstd-dynamic" => "default",
);
# Note: => pair form used for aesthetics, not to truly make a hash table
my @disable_cascades = (
# "what" => [ "cascade", ... ]
"bulk" => [ "shared", "dso",
"aria", "async", "autoload-config",
"aria", "async", "atexit", "autoload-config",
"blake2", "bf", "camellia", "cast", "chacha",
"cmac", "cms", "cmp", "comp", "ct",
"des", "dgram", "dh", "dsa",
"ec", "engine",
"filenames",
"idea", "ktls",
"md4", "multiblock", "nextprotoneg",
"ocsp", "ocb", "poly1305", "psk",
"md4", "ml-dsa", "ml-kem", "multiblock",
"nextprotoneg", "ocsp", "ocb", "poly1305", "psk",
"rc2", "rc4", "rmd160",
"seed", "siphash", "siv",
"sm3", "sm4", "srp",
"srtp", "ssl3-method", "ssl-trace",
"tfo",
"ts", "ui-console", "whirlpool",
"fips-securitychecks" ],
sub { $config{processor} eq "386" }
@ -584,10 +648,13 @@ my @disable_cascades = (
"ssl" => [ "ssl3" ],
"ssl3-method" => [ "ssl3" ],
"zlib" => [ "zlib-dynamic" ],
"brotli" => [ "brotli-dynamic" ],
"zstd" => [ "zstd-dynamic" ],
"des" => [ "mdc2" ],
"ec" => [ "ec2m", "ecdsa", "ecdh", "sm2", "gost" ],
"dgram" => [ "dtls", "sctp" ],
"sock" => [ "dgram" ],
"deprecated" => [ "tls-deprecated-ec" ],
"ec" => [ qw(ec2m ecdsa ecdh sm2 gost ecx tls-deprecated-ec) ],
"dgram" => [ "dtls", "quic", "sctp" ],
"sock" => [ "dgram", "tfo" ],
"dtls" => [ @dtls ],
sub { 0 == scalar grep { !$disabled{$_} } @dtls }
=> [ "dtls" ],
@ -595,6 +662,8 @@ my @disable_cascades = (
"tls" => [ @tls ],
sub { 0 == scalar grep { !$disabled{$_} } @tls }
=> [ "tls" ],
"tls1_3" => [ "quic" ],
"quic" => [ "unstable-qlog" ],
"crypto-mdebug" => [ "crypto-mdebug-backtrace" ],
@ -603,7 +672,7 @@ my @disable_cascades = (
# Without shared libraries, dynamic engines aren't possible.
# This is due to them having to link with libcrypto and register features
# using the ENGINE functionality, and since that relies on global tables,
# those *have* to be exacty the same as the ones accessed from the app,
# those *have* to be exactly the same as the ones accessed from the app,
# which cannot be guaranteed if shared libraries aren't present.
# (note that even with shared libraries, both the app and dynamic engines
# must be linked with the same library)
@ -626,7 +695,7 @@ my @disable_cascades = (
"stdio" => [ "apps", "capieng", "egd" ],
"apps" => [ "tests" ],
"tests" => [ "external-tests" ],
"comp" => [ "zlib" ],
"comp" => [ "zlib", "brotli", "zstd" ],
"sm3" => [ "sm2" ],
sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
@ -637,9 +706,17 @@ my @disable_cascades = (
"cmp" => [ "crmf" ],
"fips" => [ "fips-securitychecks", "acvp-tests" ],
"fips" => [ "fips-securitychecks", "fips-post", "acvp-tests",
"fips-jitter" ],
"deprecated-3.0" => [ "engine", "srp" ]
"threads" => [ "thread-pool" ],
"thread-pool" => [ "default-thread-pool" ],
"blake2" => [ "argon2" ],
"deprecated-3.0" => [ "engine", "srp" ],
"http" => [ "ocsp" ]
);
# Avoid protocol support holes. Also disable all versions below N, if version
@ -699,6 +776,7 @@ my %user = (
RANLIB => env('RANLIB'),
RC => env('RC') || env('WINDRES'),
RCFLAGS => [ env('RCFLAGS') || () ],
OBJCOPY => undef,
RM => undef,
);
# Info about what "make variables" may be prefixed with the cross compiler
@ -708,6 +786,7 @@ my @user_crossable = qw ( AR AS CC CXX CPP LD MT RANLIB RC );
# input, as opposed to the VAR=string option that override the corresponding
# config target attributes
my %useradd = (
ASFLAGS => [],
CPPDEFINES => [],
CPPINCLUDES => [],
CPPFLAGS => [],
@ -758,7 +837,7 @@ my %cmdvars = (); # Stores FOO='blah' type arguments
my %unsupported_options = ();
my %deprecated_options = ();
# If you change this, update apps/version.c
my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom);
my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu);
my @seed_sources = ();
while (@argvcopy)
{
@ -884,6 +963,23 @@ while (@argvcopy)
{
delete $disabled{"zlib"};
}
elsif ($1 eq "brotli-dynamic")
{
delete $disabled{"brotli"};
}
elsif ($1 eq "pie")
{
delete $disabled{"pie"};
}
elsif ($1 eq "zstd-dynamic")
{
delete $disabled{"zstd"};
}
elsif ($1 eq "fips-jitter")
{
delete $disabled{"fips"};
delete $disabled{"jitter"};
}
my $algo = $1;
delete $disabled{$algo};
@ -950,6 +1046,14 @@ while (@argvcopy)
{
$config{openssldir}=$1;
}
elsif (/^--with-jitter-include=(.*)$/)
{
$withargs{jitter_include}=$1;
}
elsif (/^--with-jitter-lib=(.*)$/)
{
$withargs{jitter_lib}=$1;
}
elsif (/^--with-zlib-lib=(.*)$/)
{
$withargs{zlib_lib}=$1;
@ -958,6 +1062,22 @@ while (@argvcopy)
{
$withargs{zlib_include}=$1;
}
elsif (/^--with-brotli-lib=(.*)$/)
{
$withargs{brotli_lib}=$1;
}
elsif (/^--with-brotli-include=(.*)$/)
{
$withargs{brotli_include}=$1;
}
elsif (/^--with-zstd-lib=(.*)$/)
{
$withargs{zstd_lib}=$1;
}
elsif (/^--with-zstd-include=(.*)$/)
{
$withargs{zstd_include}=$1;
}
elsif (/^--with-fuzzer-lib=(.*)$/)
{
$withargs{fuzzer_lib}=$1;
@ -1226,11 +1346,15 @@ if (scalar(grep { $_ eq 'none' } @seed_sources) > 0) {
============================== WARNING ===============================
You have selected the --with-rand-seed=none option, which effectively
disables automatic reseeding of the OpenSSL random generator.
disables automatic reseeding of the OpenSSL SEED-SRC random generator.
All operations depending on the random generator such as creating keys
will not work unless the random generator is seeded manually by the
application.
Instead of manually seeding, a different random generator can be set
at runtime in openssl.cnf or configured at build time with
-DOPENSSL_DEFAULT_SEED_SRC.
Please read the 'Note on random number generation' section in the
INSTALL.md instructions and the RAND_DRBG(7) manual page for more
details.
@ -1242,6 +1366,11 @@ push @{$config{openssl_feature_defines}},
map { (my $x = $_) =~ tr|[\-a-z]|[_A-Z]|; "OPENSSL_RAND_SEED_$x" }
@seed_sources;
my $provider_string = $disabled{"fips-post"} ? "non-compliant FIPS Provider" : "FIPS Provider";
$config{FIPS_VENDOR} =
(defined $version{FIPS_VENDOR} ? "$version{FIPS_VENDOR} $provider_string for OpenSSL" : "OpenSSL $provider_string");
# Backward compatibility?
if ($target =~ m/^CygWin32(-.*)$/) {
$target = "Cygwin".$1;
@ -1484,6 +1613,10 @@ unless($disabled{threads}) {
push @{$config{openssl_feature_defines}}, "OPENSSL_THREADS";
}
if ($disabled{"unstable-qlog"}) {
$disabled{"qlog"} = 1;
}
my $no_shared_warn=0;
if (($target{shared_target} // '') eq "")
{
@ -1548,7 +1681,7 @@ my %predefined_CXX = $config{CXX}
unless ($disabled{asm}) {
# big endian systems can use ELFv2 ABI
if ($target eq "linux-ppc64") {
if ($target eq "linux-ppc64" || $target eq "BSD-ppc64") {
$target{perlasm_scheme} = "linux64v2" if ($predefined_C{_CALL_ELF} == 2);
}
}
@ -1679,20 +1812,7 @@ $config{CFLAGS} = [ map { $_ eq '--ossl-strict-warnings'
unless ($disabled{afalgeng}) {
$config{afalgeng}="";
if (grep { $_ eq 'afalgeng' } @{$target{enable}}) {
my $minver = 4*10000 + 1*100 + 0;
if ($config{CROSS_COMPILE} eq "") {
my $verstr = `uname -r`;
my ($ma, $mi1, $mi2) = split("\\.", $verstr);
($mi2) = $mi2 =~ /(\d+)/;
my $ver = $ma*10000 + $mi1*100 + $mi2;
if ($ver < $minver) {
disable('too-old-kernel', 'afalgeng');
} else {
push @{$config{engdirs}}, "afalg";
}
} else {
disable('cross-compiling', 'afalgeng');
}
} else {
disable('not-linux', 'afalgeng');
}
@ -1731,6 +1851,12 @@ unless ($disabled{ktls}) {
}
}
unless ($disabled{winstore}) {
unless ($target =~ /^(?:Cygwin|mingw|VC-|BC-)/) {
disable('not-windows', 'winstore');
}
}
push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls});
# Get the extra flags used when building shared libraries and modules. We
@ -1792,7 +1918,7 @@ my %skipdir = ();
my %disabled_info = (); # For configdata.pm
foreach my $what (sort keys %disabled) {
# There are deprecated disablables that translate to themselves.
# They cause disabling cascades, but should otherwise not regiter.
# They cause disabling cascades, but should otherwise not register.
next if $deprecated_disablables{$what};
# The generated $disabled{"deprecated-x.y"} entries are special
# and treated properly elsewhere
@ -1802,7 +1928,7 @@ foreach my $what (sort keys %disabled) {
if (!grep { $what eq $_ } ( 'buildtest-c++', 'fips', 'threads', 'shared',
'module', 'pic', 'dynamic-engine', 'makedepend',
'zlib-dynamic', 'zlib', 'sse2', 'legacy' )) {
'sse2', 'legacy' )) {
(my $WHAT = uc $what) =~ s|-|_|g;
my $skipdir = $what;
@ -1815,7 +1941,7 @@ foreach my $what (sort keys %disabled) {
$skipdir{engines} = $what if $what eq 'engine';
$skipdir{"crypto/$skipdir"} = $what
unless $what eq 'async' || $what eq 'err' || $what eq 'dso';
unless $what eq 'async' || $what eq 'err' || $what eq 'dso' || $what eq 'http';
}
}
@ -2393,17 +2519,40 @@ EOF
} elsif ($dest eq '') {
$ddest = '';
} else {
$ddest = cleanfile($sourced, $_, $blddir, 1);
$ddest = cleanfile($sourced, $dest, $blddir, 1);
# If the destination doesn't exist in source, it can only be
# a generated file in the build tree.
if ($ddest eq $src_configdata || ! -f $ddest) {
$ddest = cleanfile($buildd, $_, $blddir);
$ddest = cleanfile($buildd, $dest, $blddir);
}
}
foreach (@{$depends{$dest}}) {
my $d = cleanfile($sourced, $_, $blddir, 1);
my $d2 = cleanfile($buildd, $_, $blddir);
foreach my $f (@{$depends{$dest}}) {
# If the dependency destination is generated, dependencies
# may have an extra syntax to separate the intended inclusion
# directory from the module to be loaded: a | instead of a
# / as directory separator.
# Do note that this has to be handled in the build file
# template as well.
# $i = inclusion path in source directory
# $i2 = inclusion path in build directory
# $m = module path (within the inclusion path)
# $i = full module path in source directory
# $i2 = full module path in build directory
my $i; my $i2; my $m; my $d; my $d2;
if ($unified_info{generate}->{$ddest}
&& $f =~ m/^(.*?)\|(.*)$/) {
$i = $1;
$m = $2;
# We must be very careful to modify $i last
$d = cleanfile($sourced, "$i/$m", $blddir, 1);
$d2 = cleanfile($buildd, "$i/$m", $blddir);
$i2 = cleandir($buildd, $i, $blddir);
$i = cleandir($sourced, $i, $blddir, 1);
} else {
$d = cleanfile($sourced, $f, $blddir, 1);
$d2 = cleanfile($buildd, $f, $blddir);
}
# If we know it's generated, or assume it is because we can't
# find it in the source tree, we set file we depend on to be
@ -2413,13 +2562,20 @@ EOF
keys %{$unified_info{generate}})
|| ! -f $d) {
$d = $d2;
$i = $i2;
}
if ($i) {
# Put together the computed inclusion dir with the
# original module name. Do note that we conserve the
# Unixly path syntax for the module path.
$d = "$i|$m";
}
$unified_info{depends}->{$ddest}->{$d} = 1;
# Fix up associated attributes
$unified_info{attributes}->{depends}->{$ddest}->{$d} =
$attributes{depends}->{$dest}->{$_}
if defined $attributes{depends}->{$dest}->{$_};
$attributes{depends}->{$dest}->{$f}
if defined $attributes{depends}->{$dest}->{$f};
}
}
@ -2589,7 +2745,9 @@ EOF
next if $dest eq "";
foreach my $d (keys %{$unified_info{depends}->{$dest}}) {
next unless $d =~ /\.(h|pm)$/;
my $i = dirname($d);
# Take into account when a dependency uses the inclusion|module
# syntax
my $i = $d =~ m/\|/ ? $` : dirname($d);
my $spot =
$d eq "configdata.pm" || defined($unified_info{generate}->{$d})
? 'build' : 'source';

View file

@ -1,33 +1,80 @@
MODIFYING OPENSSL SOURCE
========================
This document describes the way to add custom modifications to OpenSSL sources.
This document describes the way to add custom modifications to OpenSSL
sources.
If you are adding new C source files
------------------------------------
Please update the `build.info` files in the directories where you placed the
C source files, to include a line like this for each new C source file:
- In `crypto/` or any of its subdirectories (intended for `libcrypto`):
SOURCE[../libcrypto]={name-of-C-source-file}
- In `ssl/` or any of its subdirectories (intended for `libssl`):
SOURCE[../libssl]={name-of-C-source-file}
Do note that the path given as the `SOURCE` attribute must be adapted
appropriately for the location of the `build.info` file, as it's a relative
path to where the library itself is built, for example:
- For `crypto/build.info`, the library path should be `../libcrypto`
- For `crypto/evp/build.info`, the library path should be
`../../libcrypto`
- For `ssl/build.info`, the library path should be `../libssl`
- For `ssl/quic/build.info`, the library path should be `../../libssl`
To know more about `build.info` files, please read [doc/internal/man7/build.info.pod].
For better viewing, consider converting it to HTML or PDF using `pod2html`
or `pod2pdf`.
Adding new public functions
---------------------------
If you are adding new public functions to the custom library build, you need to
either add a prototype in one of the existing OpenSSL header files;
or provide a new header file and edit
[Configurations/unix-Makefile.tmpl](Configurations/unix-Makefile.tmpl)
to pick up that file.
either add a prototype in one of the existing OpenSSL header files, or
provide a new header file and edit.
After that perform the following steps:
Only headers in the `include/openssl` subdirectory are considered for public
functions. If you're creating a new header file, it must be located in that
directory.
Functions declared in `include/openssl` header files are assumed to be part
of the `libcrypto` library unless specified otherwise. *If your new
functions are meant for the `libssl` library*, you will need to edit
[Configurations/unix-Makefile.tmpl] and add the header file name in the
array `my @sslheaders_tmpl`.
Updating OpenSSL's bookkeeping files
------------------------------------
OpenSSL has a few bookkeeping files to keep track of exposed functions, most
importantly `util/libcrypto.num` and `util/libssl.num`. Any time a new
public function - as defined above - is added, these files must be updated.
To make such an update, please do the following:
./Configure -Werror --strict-warnings [your-options]
make update
make
make test
`make update` ensures that your functions declarations are added to
`util/libcrypto.num` or `util/libssl.num`.
If you plan to submit the changes you made to OpenSSL
(see [CONTRIBUTING.md](CONTRIBUTING.md)), it's worth running:
If you plan to submit the changes you made to OpenSSL (see
[CONTRIBUTING.md]), it's also worth running the following after running
`make update`, to ensure that documentation has correct format.
make doc-nits
after running `make update` to ensure that documentation has correct format.
Do note that `make update` also generates files related to OIDs (in the
`crypto/objects/` folder) and errors messages.
`make update` also generates files related to OIDs (in the `crypto/objects/`
folder) and errors.
If a merge error occurs in one of these generated files then the
If a git merge error occurs in one of these generated files, then the
generated files need to be removed and regenerated using `make update`.
To aid in this process the generated files can be committed separately
so they can be removed easily.
To aid in this process, the generated files can be committed separately
so they can be removed easily by reverting that commit.
[doc/internal/man7/build.info.pod]: ./doc/internal/man7/build.info.pod
[Configurations/unix-Makefile.tmpl]: ./Configurations/unix-Makefile.tmpl
[CONTRIBUTING.md]: ./CONTRIBUTING.md

View file

@ -19,7 +19,7 @@ Table of Contents
- [Build Type](#build-type)
- [Directories](#directories)
- [Compiler Warnings](#compiler-warnings)
- [ZLib Flags](#zlib-flags)
- [Compression Algorithm Flags](#compression-algorithm-flags)
- [Seeding the Random Generator](#seeding-the-random-generator)
- [Setting the FIPS HMAC key](#setting-the-FIPS-HMAC-key)
- [Enable and Disable Features](#enable-and-disable-features)
@ -52,6 +52,8 @@ To install OpenSSL, you will need:
* Perl 5 with core modules (please read [NOTES-PERL.md](NOTES-PERL.md))
* The Perl module `Text::Template` (please read [NOTES-PERL.md](NOTES-PERL.md))
* an ANSI C compiler
* POSIX C library (at least POSIX.1-2008), or compatible types and
functionality.
* a development environment in the form of development libraries and C
header files
* a supported operating system
@ -64,6 +66,8 @@ issues and other details, please read one of these:
* [Notes for Windows platforms](NOTES-WINDOWS.md)
* [Notes for the DOS platform with DJGPP](NOTES-DJGPP.md)
* [Notes for the OpenVMS platform](NOTES-VMS.md)
* [Notes for the HPE NonStop platform](NOTES-NONSTOP.md)
* [Notes on POSIX](NOTES-POSIX.md)
* [Notes on Perl](NOTES-PERL.md)
* [Notes on Valgrind](NOTES-VALGRIND.md)
@ -120,21 +124,11 @@ represents one of the four commands
Arguments
---------
**Mandatory arguments** are enclosed in double curly braces.
A simple example would be
**Optional Arguments** are enclosed in square brackets.
$ type {{ filename }}
[option...]
which is to be understood to use the command `type` on some file name
determined by the user.
**Optional Arguments** are enclosed in double square brackets.
[[ options ]]
Note that the notation assumes spaces around `{`, `}`, `[`, `]`, `{{`, `}}` and
`[[`, `]]`. This is to differentiate from OpenVMS directory
specifications, which also use [ and ], but without spaces.
A trailing ellipsis means that more than one could be specified.
Quick Installation Guide
========================
@ -151,7 +145,7 @@ Use the following commands to configure, build and test OpenSSL.
The testing is optional, but recommended if you intend to install
OpenSSL for production use.
### Unix / Linux / macOS
### Unix / Linux / macOS / NonStop
$ ./Configure
$ make
@ -177,8 +171,9 @@ issue the following commands to build OpenSSL.
As mentioned in the [Choices](#choices) section, you need to pick one
of the four Configure targets in the first command.
Most likely you will be using the `VC-WIN64A` target for 64bit Windows
binaries (AMD64) or `VC-WIN32` for 32bit Windows binaries (X86).
Most likely you will be using the `VC-WIN64A`/`VC-WIN64A-HYBRIDCRT` target for
64bit Windows binaries (AMD64) or `VC-WIN32`/`VC-WIN32-HYBRIDCRT` for 32bit
Windows binaries (X86).
The other two options are `VC-WIN64I` (Intel IA64, Itanium) and
`VC-CE` (Windows CE) are rather uncommon nowadays.
@ -207,7 +202,7 @@ the global search path for system libraries.
Finally, if you plan on using the FIPS module, you need to read the
[Post-installation Notes](#post-installation-notes) further down.
### Unix / Linux / macOS
### Unix / Linux / macOS / NonStop
Depending on your distribution, you need to run the following command as
root user or prepend `sudo` to the command:
@ -391,8 +386,39 @@ for OpenSSL development. It only works when using gcc or clang as the compiler.
If you are developing a patch for OpenSSL then it is recommended that you use
this option where possible.
ZLib Flags
----------
Compression Algorithm Flags
---------------------------
### with-brotli-include
--with-brotli-include=DIR
The directory for the location of the brotli include files (i.e. the location
of the **brotli** include directory). This option is only necessary if
[enable-brotli](#enable-brotli) is used and the include files are not already
on the system include path.
### with-brotli-lib
--with-brotli-lib=LIB
**On Unix**: this is the directory containing the brotli libraries.
If not provided, the system library path will be used.
The names of the libraries are:
* libbrotlicommon.a or libbrotlicommon.so
* libbrotlidec.a or libbrotlidec.so
* libbrotlienc.a or libbrotlienc.so
**On Windows:** this is the directory containing the brotli libraries.
If not provided, the system library path will be used.
The names of the libraries are:
* brotlicommon.lib
* brotlidec.lib
* brotlienc.lib
### with-zlib-include
@ -418,6 +444,32 @@ then this flag is optional and defaults to `ZLIB1` if not provided.
This flag is optional and if not provided then `GNV$LIBZSHR`, `GNV$LIBZSHR32`
or `GNV$LIBZSHR64` is used by default depending on the pointer size chosen.
### with-zstd-include
--with-zstd-include=DIR
The directory for the location of the Zstd include file. This option is only
necessary if [enable-std](#enable-zstd) is used and the include file is not
already on the system include path.
OpenSSL requires Zstd 1.4 or greater. The Linux kernel source contains a
*zstd.h* file that is not compatible with the 1.4.x Zstd distribution, the
compilation will generate an error if the Linux *zstd.h* is included before
(or instead of) the Zstd distribution header.
### with-zstd-lib
--with-zstd-lib=LIB
**On Unix**: this is the directory containing the Zstd library.
If not provided the system library path will be used.
**On Windows:** this is the filename of the Zstd library (with or
without a path). This flag must be provided if the
[enable-zstd-dynamic](#enable-zstd-dynamic) option is not also used.
If `zstd-dynamic` is used then this flag is optional and defaults
to `LIBZSTD` if not provided.
Seeding the Random Generator
----------------------------
@ -455,12 +507,8 @@ This source is ignored by the FIPS provider.
### rdcpu
Use the `RDSEED` or `RDRAND` command if provided by the CPU.
### librandom
Use librandom (not implemented yet).
This source is ignored by the FIPS provider.
Use the `RDSEED` or `RDRAND` command on x86 or `RNDRRS` command on aarch64
if provided by the CPU.
### none
@ -473,6 +521,35 @@ at the end of this document.
[rng]: #notes-on-random-number-generation
### jitter
When configured with `enable-jitter`, a "JITTER" RNG is compiled that
can provide an alternative software seed source. It can be configured
by setting `seed` option in `openssl.cnf`. A minimal `openssl.cnf` is
shown below:
openssl_conf = openssl_init
[openssl_init]
random = random
[random]
seed=JITTER
It uses a statically linked [jitterentropy-library] as the seed source.
Additional configuration flags available:
--with-jitter-include=DIR
The directory for the location of the jitterentropy.h include file, if
it is outside the system include path.
--with-jitter-lib=DIR
This is the directory containing the static libjitterentropy.a
library, if it is outside the system library path.
Setting the FIPS HMAC key
-------------------------
@ -534,6 +611,11 @@ access to algorithm internals that are not normally accessible.
Additional information related to ACVP can be found at
<https://github.com/usnistgov/ACVP>.
### no-apps
Do not build apps, e.g. the openssl program. This is handy for minimization.
This option also disables tests.
### no-asm
Do not use assembler code.
@ -552,6 +634,7 @@ Do not use `atexit()` in libcrypto builds.
`atexit()` has varied semantics between platforms and can cause SIGSEGV in some
circumstances. This option disables the atexit registration of OPENSSL_cleanup.
By default, NonStop configurations use `no-atexit`.
### no-autoalginit
@ -571,6 +654,17 @@ Typically OpenSSL will automatically load human readable error strings. For a
statically linked application this may be undesirable if small executable size
is an objective.
### enable-brotli
Build with support for brotli compression/decompression.
### enable-brotli-dynamic
Like the enable-brotli option, but has OpenSSL load the brotli library dynamically
when needed.
This is only supported on systems where loading of shared libraries is supported.
### no-autoload-config
Don't automatically load the default `openssl.cnf` file.
@ -658,6 +752,10 @@ Don't build support for datagram based BIOs.
Selecting this option will also force the disabling of DTLS.
### no-docs
Don't build and install documentation, i.e. manual pages in various forms.
### no-dso
Don't build support for loading Dynamic Shared Objects (DSO)
@ -683,6 +781,12 @@ Don't build support for Elliptic Curves.
Don't build support for binary Elliptic Curves
### no-tls-deprecated-ec
Disable legacy TLS EC groups that were deprecated in RFC8422. These are the
Koblitz curves, B<secp160r1>, B<secp160r2>, B<secp192r1>, B<secp224r1>, and the
binary Elliptic curves that would also be disabled by C<no-ec2m>.
### enable-ec_nistp_64_gcc_128
Enable support for optimised implementations of some commonly used NIST
@ -736,6 +840,26 @@ Build (and install) the FIPS provider
Don't perform FIPS module run-time checks related to enforcement of security
parameters such as minimum security strength of keys.
### no-fips-post
Don't perform FIPS module Power On Self Tests.
This option MUST be used for debugging only as it makes the FIPS provider
non-compliant. It is useful when setting breakpoints in FIPS algorithms.
### enable-fips-jitter
Use the CPU Jitter library as a FIPS validated entropy source.
This option will only produce a compliant FIPS provider if you have:
1. independently performed the required [SP 800-90B] entropy assessments;
2. meet the minimum required entropy as specified by [jitterentropy-library];
3. obtain an [ESV] certificate for the [jitterentropy-library] and
4. have had the resulting FIPS provider certified by the [CMVP].
Failure to do all of these will produce a non-compliant FIPS provider.
### enable-fuzz-libfuzzer, enable-fuzz-afl
Build with support for fuzzing using either libfuzzer or AFL.
@ -753,6 +877,10 @@ Note that if this feature is enabled then GOST ciphersuites are only available
if the GOST algorithms are also available through loading an externally supplied
engine.
### no-http
Disable HTTP support.
### no-legacy
Don't build the legacy provider.
@ -763,6 +891,16 @@ Disabling this also disables the legacy algorithms: MD2 (already disabled by def
Don't generate dependencies.
### no-ml-dsa
Disable Module-Lattice-Based Digital Signature Standard (ML-DSA) support.
ML-DSA is based on CRYSTALS-DILITHIUM. See [FIPS 204].
### no-ml-kem
Disable Module-Lattice-Based Key-Encapsulation Mechanism Standard (ML-KEM)
support. ML-KEM is based on CRYSTALS-KYBER. See [FIPS 203].
### no-module
Don't build any dynamically loadable engines.
@ -795,6 +933,10 @@ As synonym for `no-padlockeng`. Deprecated and should not be used.
Don't build with support for Position Independent Code.
### enable-pie
Build with support for Position Independent Execution.
### no-pinshared
Don't pin the shared libraries.
@ -848,6 +990,15 @@ Do not create shared libraries, only static ones.
See [Notes on shared libraries](#notes-on-shared-libraries) below.
### no-slh-dsa
Disable Stateless Hash Based Digital Signature Standard support.
(SLH-DSA is based on SPHINCS+. See [FIPS 205])
### no-sm2-precomp
Disable using the SM2 precomputed table on aarch64 to make the library smaller.
### no-sock
Don't build support for socket BIOs.
@ -901,6 +1052,14 @@ tests also use the command line applications, the tests will also be skipped.
Don't build test programs or run any tests.
### enable-tfo
Build with support for TCP Fast Open (RFC7413). Supported on Linux, macOS and FreeBSD.
### no-quic
Don't build with QUIC support.
### no-threads
Don't build with support for multi-threaded applications.
@ -913,12 +1072,44 @@ will usually require additional system-dependent options!
See [Notes on multi-threading](#notes-on-multi-threading) below.
### no-thread-pool
Don't build with support for thread pool functionality.
### thread-pool
Build with thread pool functionality. If enabled, OpenSSL algorithms may
use the thread pool to perform parallel computation. This option in itself
does not enable OpenSSL to spawn new threads. Currently the only supported
thread pool mechanism is the default thread pool.
### no-default-thread-pool
Don't build with support for default thread pool functionality.
### default-thread-pool
Build with default thread pool functionality. If enabled, OpenSSL may create
and manage threads up to a maximum number of threads authorized by the
application. Supported on POSIX compliant platforms and Windows.
### enable-trace
Build with support for the integrated tracing api.
See manual pages OSSL_trace_set_channel(3) and OSSL_trace_enabled(3) for details.
### enable-sslkeylog
Build with support for the SSLKEYLOGFILE environment variable
When enabled, setting SSLKEYLOGFILE to a file path records the keys exchanged
during a TLS handshake for use in analysis tools like wireshark. Note that the
use of this mechanism allows for decryption of application payloads found in
captured packets using keys from the key log file and therefore has significant
security consequences. See Section 3 of
[the draft standard for SSLKEYLOGFILE](https://datatracker.ietf.org/doc/draft-ietf-tls-keylogfile/)
### no-ts
Don't build Time Stamping (TS) Authority support.
@ -965,6 +1156,25 @@ when needed.
This is only supported on systems where loading of shared libraries is supported.
### enable-zstd
Build with support for Zstd compression/decompression.
### enable-zstd-dynamic
Like the enable-zstd option, but has OpenSSL load the Zstd library dynamically
when needed.
This is only supported on systems where loading of shared libraries is supported.
### enable-unstable-qlog
Enables qlog output support for the QUIC protocol. This functionality is
unstable and implements a draft version of the qlog specification. The qlog
output from OpenSSL will change in incompatible ways in future, and is not
subject to any format stability or compatibility guarantees at this time. See
the manpage openssl-qlog(7) for details.
### 386
In 32-bit x86 builds, use the 80386 instruction set only in assembly modules
@ -986,6 +1196,10 @@ synonymous with `no-ssl3`. Note this only affects version negotiation.
OpenSSL will still provide the methods for applications to explicitly select
the individual protocol versions.
### no-integrity-only-ciphers
Don't build support for integrity only ciphers in tls.
### no-{protocol}-method
no-{ssl3|tls1|tls1_1|tls1_2|dtls1|dtls1_2}-method
@ -1007,9 +1221,9 @@ Build with support for the specified algorithm.
### no-{algorithm}
no-{aria|bf|blake2|camellia|cast|chacha|cmac|
des|dh|dsa|ecdh|ecdsa|idea|md4|mdc2|ocb|
poly1305|rc2|rc4|rmd160|scrypt|seed|
siphash|siv|sm2|sm3|sm4|whirlpool}
des|dh|dsa|ecdh|ecdsa|idea|md4|mdc2|ml-dsa|
ml-kem|ocb|poly1305|rc2|rc4|rmd160|scrypt|
seed|siphash|siv|sm2|sm3|sm4|whirlpool}
Build without support for the specified algorithm.
@ -1034,7 +1248,7 @@ below and how these flags interact with those variables.
Additional options that are not otherwise recognised are passed through as
they are to the compiler as well. Unix-style options beginning with a
`-` or `+` and Windows-style options beginning with a `/` are recognized.
`-` or `+` and Windows-style options beginning with a `/` are recognised.
Again, consult your compiler documentation.
If the option contains arguments separated by spaces, then the URL-style
@ -1169,15 +1383,15 @@ the same.
#### Unix / Linux / macOS
$ ./Configure [[ options ]]
$ ./Configure [options...]
#### OpenVMS
$ perl Configure [[ options ]]
$ perl Configure [options...]
#### Windows
$ perl Configure [[ options ]]
$ perl Configure [options...]
### Manual Configuration
@ -1199,12 +1413,13 @@ When you have identified your system (and if necessary compiler) use this
name as the argument to `Configure`. For example, a `linux-elf` user would
run:
$ ./Configure linux-elf [[ options ]]
$ ./Configure linux-elf [options...]
### Creating your own Configuration
If your system isn't listed, you will have to create a configuration
file named `Configurations/{{ something }}.conf` and add the correct
file named `Configurations/YOURFILENAME.conf` (replace `YOURFILENAME`
with a filename of your choosing) and add the correct
configuration for your system. See the available configs as examples
and read [Configurations/README.md](Configurations/README.md) and
[Configurations/README-design.md](Configurations/README-design.md)
@ -1236,21 +1451,21 @@ directory and invoking the configuration commands from there.
$ mkdir /var/tmp/openssl-build
$ cd /var/tmp/openssl-build
$ /PATH/TO/OPENSSL/SOURCE/Configure [[ options ]]
$ /PATH/TO/OPENSSL/SOURCE/Configure [options...]
#### OpenVMS example
$ set default sys$login:
$ create/dir [.tmp.openssl-build]
$ set default [.tmp.openssl-build]
$ perl D:[PATH.TO.OPENSSL.SOURCE]Configure [[ options ]]
$ perl D:[PATH.TO.OPENSSL.SOURCE]Configure [options...]
#### Windows example
$ C:
$ mkdir \temp-openssl
$ cd \temp-openssl
$ perl d:\PATH\TO\OPENSSL\SOURCE\Configure [[ options ]]
$ perl d:\PATH\TO\OPENSSL\SOURCE\Configure [options...]
Paths can be relative just as well as absolute. `Configure` will do its best
to translate them to relative paths whenever possible.
@ -1471,7 +1686,7 @@ over the build process. Typically these should be defined prior to running
PERL
The name of the Perl executable to use when building OpenSSL.
Only needed if builing should use a different Perl executable
Only needed if building should use a different Perl executable
than what is used to run the Configure script.
RANLIB
@ -1506,6 +1721,12 @@ described here. Examine the Makefiles themselves for the full list.
build_docs
Build all documentation components.
debuginfo
On unix platforms, this target can be used to create .debug
libraries, which separate the DWARF information in the
shared library ELF files into a separate file for use
in post-mortem (core dump) debugging
clean
Remove all build artefacts and return the directory to a "clean"
state.
@ -1627,7 +1848,7 @@ working incorrectly. If you think you encountered a bug, please
Along with a short description of the bug, please provide the complete
configure command line and the relevant output including the error message.
Note: To make the output readable, pleace add a 'code fence' (three backquotes
Note: To make the output readable, please add a 'code fence' (three backquotes
` ``` ` on a separate line) before and after your output:
```
@ -1830,3 +2051,24 @@ is used, as it is the version of the GNU assembler that will be checked.
[10-main.conf]:
Configurations/10-main.conf
[CMVP]:
<https://csrc.nist.gov/projects/cryptographic-module-validation-program>
[ESV]:
<https://csrc.nist.gov/Projects/cryptographic-module-validation-program/entropy-validations>
[FIPS 203]:
<https://csrc.nist.gov/pubs/fips/203/final>
[FIPS 204]:
<https://csrc.nist.gov/pubs/fips/204/final>
[SP 800-90B]:
<https://csrc.nist.gov/pubs/sp/800/90/b/final>
[jitterentropy-library]:
<https://github.com/smuellerDD/jitterentropy-library>
[FIPS 205]:
<https://csrc.nist.gov/pubs/fips/205/final>

View file

@ -7,6 +7,11 @@ release. For more details please read the CHANGES file.
OpenSSL Releases
----------------
- [OpenSSL 3.5](#openssl-35)
- [OpenSSL 3.4](#openssl-34)
- [OpenSSL 3.3](#openssl-33)
- [OpenSSL 3.2](#openssl-32)
- [OpenSSL 3.1](#openssl-31)
- [OpenSSL 3.0](#openssl-30)
- [OpenSSL 1.1.1](#openssl-111)
- [OpenSSL 1.1.0](#openssl-110)
@ -15,34 +20,166 @@ OpenSSL Releases
- [OpenSSL 1.0.0](#openssl-100)
- [OpenSSL 0.9.x](#openssl-09x)
OpenSSL 3.0
OpenSSL 3.5
-----------
### Major changes between OpenSSL 3.0.16 and OpenSSL 3.0.17 [1 Jul 2025]
### Major changes between OpenSSL 3.5.0 and OpenSSL 3.5.1 [1 Jul 2025]
OpenSSL 3.0.17 is a bug fix release.
This release incorporates the following bug fixes and mitigations:
* Miscellaneous minor bug fixes.
### Major changes between OpenSSL 3.0.15 and OpenSSL 3.0.16 [11 Feb 2025]
OpenSSL 3.0.16 is a security patch release. The most severe CVE fixed in this
OpenSSL 3.5.1 is a security patch release. The most severe CVE fixed in this
release is Low.
This release incorporates the following bug fixes and mitigations:
* Fix x509 application adds trusted use instead of rejected use.
([CVE-2025-4575])
### Major changes between OpenSSL 3.4 and OpenSSL 3.5.0 [8 Apr 2025]
OpenSSL 3.5.0 is a feature release adding significant new functionality to
OpenSSL.
This release incorporates the following potentially significant or incompatible
changes:
* Default encryption cipher for the `req`, `cms`, and `smime` applications
changed from `des-ede3-cbc` to `aes-256-cbc`.
* The default TLS supported groups list has been changed to include and
prefer hybrid PQC KEM groups. Some practically unused groups were removed
from the default list.
* The default TLS keyshares have been changed to offer X25519MLKEM768 and
and X25519.
* All `BIO_meth_get_*()` functions were deprecated.
This release adds the following new features:
* Support for server side QUIC (RFC 9000)
* Support for 3rd party QUIC stacks including 0-RTT support
* Support for PQC algorithms (ML-KEM, ML-DSA and SLH-DSA)
* A new configuration option `no-tls-deprecated-ec` to disable support for
TLS groups deprecated in RFC8422
* A new configuration option `enable-fips-jitter` to make the FIPS provider
to use the `JITTER` seed source
* Support for central key generation in CMP
* Support added for opaque symmetric key objects (EVP_SKEY)
* Support for multiple TLS keyshares and improved TLS key establishment group
configurability
* API support for pipelining in provided cipher algorithms
Known issues in 3.5.0
* <https://github.com/openssl/openssl/issues/27282>
Calling SSL_accept on objects returned from SSL_accept_connection
results in error. It is expected that making this call will advance
the SSL handshake for the passed connection, but currently it does not.
This can be handled by calling SSL_do_handshake instead. A fix is planned
for OpenSSL 3.5.1
OpenSSL 3.4
-----------
### Major changes between OpenSSL 3.4.0 and OpenSSL 3.4.1 [11 Feb 2025]
OpenSSL 3.4.1 is a security patch release. The most severe CVE fixed in this
release is High.
This release incorporates the following bug fixes and mitigations:
* Fixed RFC7250 handshakes with unauthenticated servers don't abort as expected.
([CVE-2024-12797])
* Fixed timing side-channel in ECDSA signature computation.
([CVE-2024-13176])
### Major changes between OpenSSL 3.3 and OpenSSL 3.4.0 [22 Oct 2024]
OpenSSL 3.4.0 is a feature release adding significant new functionality to
OpenSSL.
This release incorporates the following potentially significant or incompatible
changes:
* Deprecation of TS_VERIFY_CTX_set_* functions and addition of replacement
TS_VERIFY_CTX_set0_* functions with improved semantics
* Redesigned use of OPENSSLDIR/ENGINESDIR/MODULESDIR on Windows such that
what were formerly build time locations can now be defined at run time
with registry keys
* The X25519 and X448 key exchange implementation in the FIPS provider
is unapproved and has `fips=no` property.
* SHAKE-128 and SHAKE-256 implementations have no default digest length
anymore. That means these algorithms cannot be used with
EVP_DigestFinal/_ex() unless the `xoflen` param is set before.
* Setting `config_diagnostics=1` in the config file will cause errors to
be returned from SSL_CTX_new() and SSL_CTX_new_ex() if there is an error
in the ssl module configuration.
* An empty renegotiate extension will be used in TLS client hellos instead
of the empty renegotiation SCSV, for all connections with a minimum TLS
version > 1.0.
* Deprecation of SSL_SESSION_get_time(), SSL_SESSION_set_time() and
SSL_CTX_flush_sessions() functions in favor of their respective `_ex`
functions which are Y2038-safe on platforms with Y2038-safe `time_t`
This release adds the following new features:
* Support for directly fetched composite signature algorithms such as
RSA-SHA2-256 including new API functions
* FIPS indicators support in the FIPS provider and various updates of the FIPS
provider required for future FIPS 140-3 validations
* Implementation of RFC 9579 (PBMAC1) in PKCS#12
* An optional additional random seed source RNG `JITTER` using a statically
linked jitterentropy library
* New options `-not_before` and `-not_after` for explicit setting start and
end dates of certificates created with the `req` and `x509` apps
* Support for integrity-only cipher suites TLS_SHA256_SHA256 and
TLS_SHA384_SHA384 in TLS 1.3, as defined in RFC 9150
* Support for retrieving certificate request templates and CRLs in CMP
* Support for additional X.509v3 extensions related to Attribute Certificates
* Initial Attribute Certificate (RFC 5755) support
* Possibility to customize ECC groups initialization to use precomputed values
to save CPU time and use of this feature by the P-256 implementation
OpenSSL 3.3
-----------
### Major changes between OpenSSL 3.3.2 and OpenSSL 3.3.3 [under development]
OpenSSL 3.3.3 is a security patch release. The most severe CVE fixed in this
release is Low.
This release incorporates the following bug fixes and mitigations:
* Fixed possible OOB memory access with invalid low-level GF(2^m) elliptic
curve parameters.
([CVE-2024-9143])
### Major changes between OpenSSL 3.0.14 and OpenSSL 3.0.15 [3 Sep 2024]
### Major changes between OpenSSL 3.3.1 and OpenSSL 3.3.2 [3 Sep 2024]
OpenSSL 3.0.15 is a security patch release. The most severe CVE fixed in this
OpenSSL 3.3.2 is a security patch release. The most severe CVE fixed in this
release is Moderate.
This release incorporates the following bug fixes and mitigations:
@ -53,7 +190,12 @@ This release incorporates the following bug fixes and mitigations:
* Fixed possible buffer overread in SSL_select_next_proto()
([CVE-2024-5535])
### Major changes between OpenSSL 3.0.13 and OpenSSL 3.0.14 [4 Jun 2024]
### Major changes between OpenSSL 3.3.0 and OpenSSL 3.3.1 [4 Jun 2024]
OpenSSL 3.3.1 is a security patch release. The most severe CVE fixed in this
release is Low.
This release incorporates the following bug fixes and mitigations:
* Fixed potential use after free after SSL_free_buffers() is called
([CVE-2024-4741])
@ -62,38 +204,268 @@ This release incorporates the following bug fixes and mitigations:
be very slow
([CVE-2024-4603])
### Major changes between OpenSSL 3.2 and OpenSSL 3.3.0 [9 Apr 2024]
OpenSSL 3.3.0 is a feature release adding significant new functionality to
OpenSSL.
This release adds the following new features:
* Support for qlog for tracing QUIC connections has been added
* Added APIs to allow configuring the negotiated idle timeout for QUIC
connections, and to allow determining the number of additional streams
that can currently be created for a QUIC connection.
* Added APIs to allow disabling implicit QUIC event processing for QUIC SSL
objects
* Added APIs to allow querying the size and utilisation of a QUIC stream's
write buffer
* New API `SSL_write_ex2`, which can be used to send an end-of-stream (FIN)
condition in an optimised way when using QUIC.
* Limited support for polling of QUIC connection and stream objects in a
non-blocking manner.
* Added a new EVP_DigestSqueeze() API. This allows SHAKE to squeeze multiple
times with different output sizes.
* Added exporter for CMake on Unix and Windows, alongside the pkg-config
exporter.
* The BLAKE2s hash algorithm matches BLAKE2b's support for configurable
output length.
* The EVP_PKEY_fromdata function has been augmented to allow for the
derivation of CRT (Chinese Remainder Theorem) parameters when requested
* Added API functions SSL_SESSION_get_time_ex(), SSL_SESSION_set_time_ex()
using time_t which is Y2038 safe on 32 bit systems when 64 bit time
is enabled
* Unknown entries in TLS SignatureAlgorithms, ClientSignatureAlgorithms
config options and the respective calls to SSL[_CTX]_set1_sigalgs() and
SSL[_CTX]_set1_client_sigalgs() that start with `?` character are
ignored and the configuration will still be used.
* Added `-set_issuer` and `-set_subject` options to `openssl x509` to
override the Issuer and Subject when creating a certificate. The `-subj`
option now is an alias for `-set_subject`.
* Added several new features of CMPv3 defined in RFC 9480 and RFC 9483
* New option `SSL_OP_PREFER_NO_DHE_KEX`, which allows configuring a TLS1.3
server to prefer session resumption using PSK-only key exchange over PSK
with DHE, if both are available.
* New atexit configuration switch, which controls whether the OPENSSL_cleanup
is registered when libcrypto is unloaded.
* Added X509_STORE_get1_objects to avoid issues with the existing
X509_STORE_get0_objects API in multi-threaded applications.
* Support for using certificate profiles and extened delayed delivery in CMP
This release incorporates the following potentially significant or incompatible
changes:
* Applied AES-GCM unroll8 optimisation to Microsoft Azure Cobalt 100
* Optimized AES-CTR for ARM Neoverse V1 and V2
* Enable AES and SHA3 optimisations on Apple Silicon M3-based MacOS systems
similar to M1/M2.
* Various optimizations for cryptographic routines using RISC-V vector crypto
extensions
* Added assembly implementation for md5 on loongarch64
* Accept longer context for TLS 1.2 exporters
* The activate and soft_load configuration settings for providers in
openssl.cnf have been updated to require a value of [1|yes|true|on]
(in lower or UPPER case) to enable the setting. Conversely a value
of [0|no|false|off] will disable the setting.
* In `openssl speed`, changed the default hash function used with `hmac` from
`md5` to `sha256`.
* The `-verify` option to the `openssl crl` and `openssl req` will make the
program exit with 1 on failure.
* The d2i_ASN1_GENERALIZEDTIME(), d2i_ASN1_UTCTIME(), ASN1_TIME_check(), and
related functions have been augmented to check for a minimum length of
the input string, in accordance with ITU-T X.690 section 11.7 and 11.8.
* OPENSSL_sk_push() and sk_<TYPE>_push() functions now return 0 instead of -1
if called with a NULL stack argument.
* New limit on HTTP response headers is introduced to HTTP client. The
default limit is set to 256 header lines.
This release incorporates the following bug fixes and mitigations:
* The BIO_get_new_index() function can only be called 127 times before it
reaches its upper bound of BIO_TYPE_MASK and will now return -1 once its
exhausted.
A more detailed list of changes in this release can be found in the
[CHANGES.md] file.
Users interested in using the new QUIC functionality are encouraged to read the
[README file for QUIC][README-QUIC.md], which provides links to relevant
documentation and example code.
As always, bug reports and issues relating to OpenSSL can be [filed on our issue
tracker][issue tracker].
OpenSSL 3.2
-----------
### Major changes between OpenSSL 3.2.1 and OpenSSL 3.2.2 [under development]
OpenSSL 3.2.2 is a security patch release. The most severe CVE fixed in this
release is Low.
This release incorporates the following bug fixes and mitigations:
* Fixed unbounded memory growth with session handling in TLSv1.3
([CVE-2024-2511])
### Major changes between OpenSSL 3.0.12 and OpenSSL 3.0.13 [30 Jan 2024]
### Major changes between OpenSSL 3.2.0 and OpenSSL 3.2.1 [30 Jan 2024]
OpenSSL 3.2.1 is a security patch release. The most severe CVE fixed in this
release is Low.
This release incorporates the following bug fixes and mitigations:
* Fixed PKCS12 Decoding crashes
([CVE-2024-0727])
* Fixed Excessive time spent checking invalid RSA public keys
* Fixed excessive time spent checking invalid RSA public keys
([CVE-2023-6237])
* Fixed POLY1305 MAC implementation corrupting vector registers on PowerPC
CPUs which support PowerISA 2.07
([CVE-2023-6129])
* Fix excessive time spent in DH check / generation with large Q parameter
value ([CVE-2023-5678])
### Major changes between OpenSSL 3.0.11 and OpenSSL 3.0.12 [24 Oct 2023]
### Major changes between OpenSSL 3.1 and OpenSSL 3.2.0 [23 Nov 2023]
OpenSSL 3.2.0 is a feature release adding significant new functionality to
OpenSSL.
This release incorporates the following potentially significant or incompatible
changes:
* The default SSL/TLS security level has been changed from 1 to 2.
* The `x509`, `ca`, and `req` apps now always produce X.509v3 certificates.
* Subject or issuer names in X.509 objects are now displayed as UTF-8 strings
by default. Also spaces surrounding `=` in DN output are removed.
This release adds the following new features:
* Support for client side QUIC, including support for
multiple streams (RFC 9000)
* Support for Ed25519ctx, Ed25519ph and Ed448ph in addition
to existing support for Ed25519 and Ed448 (RFC 8032)
* Support for deterministic ECDSA signatures (RFC 6979)
* Support for AES-GCM-SIV, a nonce-misuse-resistant AEAD (RFC 8452)
* Support for the Argon2 KDF, along with supporting thread pool
functionality (RFC 9106)
* Support for Hybrid Public Key Encryption (HPKE) (RFC 9180)
* Support for SM4-XTS
* Support for Brainpool curves in TLS 1.3
* Support for TLS Raw Public Keys (RFC 7250)
* Support for TCP Fast Open on Linux, macOS and FreeBSD,
where enabled and supported (RFC 7413)
* Support for TLS certificate compression, including library
support for zlib, Brotli and zstd (RFC 8879)
* Support for provider-based pluggable signature algorithms
in TLS 1.3 with supporting CMS and X.509 functionality
With a suitable provider this enables the use of post-quantum/quantum-safe
cryptography.
* Support for using the Windows system certificate store as a source of
trusted root certificates
This is not yet enabled by default and must be activated using an
environment variable. This is likely to become enabled by default
in a future feature release.
* Support for using the IANA standard names in TLS ciphersuite configuration
* Multiple new features and improvements to CMP protocol support
The following known issues are present in this release and will be rectified
in a future release:
* Provider-based signature algorithms cannot be configured using the
SignatureAlgorithms configuration file parameter (#22761)
This release incorporates the following documentation enhancements:
* Added multiple tutorials on the OpenSSL library and in particular
on writing various clients (using TLS and QUIC protocols) with libssl
See [OpenSSL Guide].
This release incorporates the following bug fixes and mitigations:
* Fixed excessive time spent in DH check / generation with large Q parameter
value
([CVE-2023-5678])
A more detailed list of changes in this release can be found in the
[CHANGES.md] file.
Users interested in using the new QUIC functionality are encouraged to read the
[README file for QUIC][README-QUIC.md], which provides links to relevant
documentation and example code.
As always, bug reports and issues relating to OpenSSL can be [filed on our issue
tracker][issue tracker].
OpenSSL 3.1
-----------
### Major changes between OpenSSL 3.1.3 and OpenSSL 3.1.4 [24 Oct 2023]
* Mitigate incorrect resize handling for symmetric cipher keys and IVs.
([CVE-2023-5363])
### Major changes between OpenSSL 3.0.10 and OpenSSL 3.0.11 [19 Sep 2023]
### Major changes between OpenSSL 3.1.2 and OpenSSL 3.1.3 [19 Sep 2023]
* Fix POLY1305 MAC implementation corrupting XMM registers on Windows
([CVE-2023-4807])
### Major changes between OpenSSL 3.0.9 and OpenSSL 3.0.10 [1 Aug 2023]
### Major changes between OpenSSL 3.1.1 and OpenSSL 3.1.2 [1 Aug 2023]
* Fix excessive time spent checking DH q parameter value ([CVE-2023-3817])
* Fix DH_check() excessive time with over sized modulus ([CVE-2023-3446])
* Do not ignore empty associated data entries with AES-SIV ([CVE-2023-2975])
* When building with the `enable-fips` option and using the resulting
FIPS provider, TLS 1.2 will, by default, mandate the use of an
extended master secret and the Hash and HMAC DRBGs will not operate
with truncated digests.
### Major changes between OpenSSL 3.0.8 and OpenSSL 3.0.9 [30 May 2023]
### Major changes between OpenSSL 3.1.0 and OpenSSL 3.1.1 [30 May 2023]
* Mitigate for very slow `OBJ_obj2txt()` performance with gigantic OBJECT
IDENTIFIER sub-identities. ([CVE-2023-2650])
@ -104,6 +476,17 @@ This release incorporates the following bug fixes and mitigations:
([CVE-2023-0465])
* Limited the number of nodes created in a policy tree ([CVE-2023-0464])
### Major changes between OpenSSL 3.0 and OpenSSL 3.1.0 [14 Mar 2023]
* SSL 3, TLS 1.0, TLS 1.1, and DTLS 1.0 only work at security level 0.
* Performance enhancements and new platform support including new
assembler code algorithm implementations.
* Deprecated LHASH statistics functions.
* FIPS 140-3 compliance changes.
OpenSSL 3.0
-----------
### Major changes between OpenSSL 3.0.7 and OpenSSL 3.0.8 [7 Feb 2023]
* Fixed NULL dereference during PKCS7 data verification ([CVE-2023-0401])
@ -150,7 +533,7 @@ This release incorporates the following bug fixes and mitigations:
* Fixed a bug where the RC4-MD5 ciphersuite incorrectly used the
AAD data as the MAC key ([CVE-2022-1434])
* Fix a bug in the OPENSSL_LH_flush() function that breaks reuse of the memory
occuppied by the removed hash table entries ([CVE-2022-1473])
occupied by the removed hash table entries ([CVE-2022-1473])
### Major changes between OpenSSL 3.0.1 and OpenSSL 3.0.2 [15 Mar 2022]
@ -169,7 +552,7 @@ This release incorporates the following bug fixes and mitigations:
* Enhanced 'openssl list' with many new options.
* Added migration guide to man7.
* Implemented support for fully "pluggable" TLSv1.3 groups.
* Added suport for Kernel TLS (KTLS).
* Added support for Kernel TLS (KTLS).
* Changed the license to the Apache License v2.0.
* Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2,
RC4, RC5, and DES to the legacy provider.
@ -212,7 +595,7 @@ This release incorporates the following bug fixes and mitigations:
* Deprecated ERR_put_error(), ERR_get_error_line(), ERR_get_error_line_data(),
ERR_peek_error_line_data(), ERR_peek_last_error_line_data() and
ERR_func_error_string().
* Added OSSL_PROVIDER_available(), to check provider availibility.
* Added OSSL_PROVIDER_available(), to check provider availability.
* Added 'openssl mac' that uses the EVP_MAC API.
* Added 'openssl kdf' that uses the EVP_KDF API.
* Add OPENSSL_info() and 'openssl info' to get built-in data.
@ -1496,7 +1879,7 @@ OpenSSL 0.9.x
* Overhauled Win32 builds
* Cleanups and fixes to the Big Number (BN) library
* Support for ASN.1 GeneralizedTime
* Splitted ASN.1 SETs from SEQUENCEs
* Split ASN.1 SETs from SEQUENCEs
* ASN1 and PEM support for Netscape Certificate Sequences
* Overhauled Perl interface
* Lots of source tree cleanups.
@ -1516,7 +1899,7 @@ OpenSSL 0.9.x
* Support for various new platforms
<!-- Links -->
[CVE-2025-4575]: https://www.openssl.org/news/vulnerabilities.html#CVE-2025-4575
[CVE-2024-13176]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-13176
[CVE-2024-9143]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-9143
[CVE-2024-6119]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-6119
@ -1692,3 +2075,10 @@ OpenSSL 0.9.x
[CVE-2006-2940]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-2940
[CVE-2006-2937]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-2937
[CVE-2005-2969]: https://www.openssl.org/news/vulnerabilities.html#CVE-2005-2969
[OpenSSL Guide]: https://www.openssl.org/docs/manmaster/man7/ossl-guide-introduction.html
[CHANGES.md]: ./CHANGES.md
[README-QUIC.md]: ./README-QUIC.md
[issue tracker]: https://github.com/openssl/openssl/issues
[CMVP]: https://csrc.nist.gov/projects/cryptographic-module-validation-program
[ESV]: https://csrc.nist.gov/Projects/cryptographic-module-validation-program/entropy-validations
[jitterentropy-library]: https://github.com/smuellerDD/jitterentropy-library

View file

@ -4,7 +4,7 @@ Notes for Android platforms
Requirement details
-------------------
Beside basic tools like perl and make you'll need to download the Android
Beside basic tools like perl and make, you'll need to download the Android
NDK. It's available for Linux, macOS and Windows, but only Linux
version was actually tested. There is no reason to believe that macOS
wouldn't work. And as for Windows, it's unclear which "shell" would be
@ -17,8 +17,8 @@ Notes for Android platforms
Android is a cross-compiled target and you can't rely on `./Configure`
to find out the configuration target for you. You have to name your
target explicitly; there are `android-arm`, `android-arm64`, `android-mips`,
`android-mip64`, `android-x86` and `android-x86_64` (`*MIPS` targets are no
longer supported with NDK R20+).
`android-mip64`, `android-x86`, `android-x86_64` and `android-riscv64`
(`*MIPS` targets are no longer supported with NDK R20+).
Do not pass --cross-compile-prefix (as you might be tempted), as it
will be "calculated" automatically based on chosen platform. However,
@ -26,13 +26,13 @@ Notes for Android platforms
invoke `$(CROSS_COMPILE)clang` [`*gcc` on NDK 19 and lower] and company.
(`./Configure` will fail and give you a hint if you get it wrong.)
Apart from `PATH` adjustment you need to set `ANDROID_NDK_ROOT` environment
Apart from `PATH` adjustment, you need to set `ANDROID_NDK_ROOT` environment
to point at the `NDK` directory. If you're using a side-by-side NDK the path
will look something like `/some/where/android-sdk/ndk/<ver>`, and for a
standalone NDK the path will be something like `/some/where/android-ndk-<ver>`.
Both variables are significant at both configuration and compilation times.
The NDK customarily supports multiple Android API levels, e.g. `android-14`,
`android-21`, etc. By default latest API level is chosen. If you need to target
`android-21`, etc. By default, latest API level is chosen. If you need to target
an older platform pass the argument `-D__ANDROID_API__=N` to `Configure`,
with `N` being the numerical value of the target platform version. For example,
to compile for Android 10 arm64 with a side-by-side NDK r20.0.5594570
@ -59,7 +59,7 @@ Notes for Android platforms
conflict, and mixing the two is therefore not supported. Migration to
`CROSS_SYSROOT`-less setup is recommended.
One can engage clang by adjusting PATH to cover same NDK's clang. Just
One can engage clang by adjusting PATH to cover the same NDK's clang. Just
keep in mind that if you miss it, Configure will try to use gcc...
Also, PATH would need even further adjustment to cover unprefixed, yet
target-specific, ar and ranlib. It's possible that you don't need to
@ -67,7 +67,7 @@ Notes for Android platforms
Another option is to create so called "standalone toolchain" tailored
for single specific platform including Android API level, and assign its
location to `ANDROID_NDK_ROOT`. In such case you have to pass matching
location to `ANDROID_NDK_ROOT`. In such case, you have to pass matching
target name to Configure and shouldn't use `-D__ANDROID_API__=N`. `PATH`
adjustment becomes simpler, `$ANDROID_NDK_ROOT/bin:$PATH` suffices.

33
deps/openssl/openssl/NOTES-ANSI.md vendored Normal file
View file

@ -0,0 +1,33 @@
Notes on ANSI C
===============
When building for pure ANSI C (C89/C90), you must configure with at least
the following configuration settings:
- `no-asm`
There are cases of `asm()` calls in our C source, which isn't supported
in pure ANSI C.
- `no-secure-memory`
The secure memory calls aren't supported with ANSI C.
- `-D_XOPEN_SOURCE=1`
This macro enables the use of the following types, functions and global
variables:
- `timezone`
- `-D_POSIX_C_SOURCE=200809L`
This macro enables the use of the following types, functions and global
variables:
- `ssize_t`
- `strdup()`
It's arguable that with gcc and clang, all of these issues are removed when
defining the macro `_DEFAULT_SOURCE`. However, that effectively sets the C
language level to C99, which isn't ANSI C.

View file

@ -19,22 +19,31 @@ About c99 compiler
The c99 compiler is required for building OpenSSL from source. While c11
may work, it has not been broadly tested. c99 is the only compiler
prerequisite needed to build OpenSSL 3.0 on this platform. You should also
have the FLOSS package installed on your system. The ITUGLIB FLOSS package
is the only FLOSS variant that has been broadly tested.
prerequisite needed to build OpenSSL 3.0 on this platform.
Threading Models
----------------
OpenSSL can be built using unthreaded, POSIX User Threads (PUT), or Standard
POSIX Threads (SPT). Select the following build configuration for each on
the TNS/X (L-Series) platform:
OpenSSL can be built either using the POSIX User Threads (PUT) threading model,
or with threading support disabled. Select the following build configuration
for each on the TNS/X (L-Series) platform:
* `nonstop-nsx` or default will select an unthreaded build.
* `nonstop-nsx` or default will select an unthreaded 32-bit build.
* `nonstop-nsx_64` selects an unthreaded 64-bit memory and file length build.
* `nonstop-nsx_64_klt` selects the 64-bit memory and file length KLT build.
* `nonstop-nsx_put` selects the PUT build.
* `nonstop-nsx_64_put` selects the 64 bit file length PUT build.
* `nonstop-nsx_spt_floss` selects the SPT build with FLOSS. FLOSS is
required for SPT builds because of a known hang when using SPT on its own.
* `nonstop-nsx_64_put` selects the 64-bit memory and file length PUT build.
The KLT threading model is a newly released model on NonStop. It implements
kernel-level threading. KLT provides much closer threading to what OpenSSL
uses for Linux-like threading models. KLT continues to use the pthread library
API. There is no supported 32-bit or Guardian builds for KLT. Note: KLT is
not currently available but is planned for post-2024.
The SPT threading model is no longer supported as of OpenSSL 3.2.
The PUT model is incompatible with the QUIC capability. This capability should
be disabled when building with PUT.
### TNS/E Considerations
@ -56,10 +65,13 @@ relating to `atexit()` processing when a shared library is unloaded and when
the program terminates. This limitation applies to all OpenSSL shared library
components.
It is possible to configure the build with `no-atexit` to avoid the SIGSEGV.
Preferably, you can explicitly call `OPENSSL_cleanup()` from your application.
It is not mandatory as it just deallocates various global data structures
OpenSSL allocated.
A control has been added as of 3.3.x to disable calls to `atexit()` within the
`libcrypto` builds (specifically in `crypto/init.c`). This switch can be
controlled using `disable-atexit` or `enable-atexit`, and is disabled by default
for NonStop builds. If you need to have `atexit()` functionality, set
`enabled-atexit` when configuring OpenSSL to enable the `atexit()` call to
register `OPENSSL_cleanup()` automatically. Preferably, you can explicitly call
`OPENSSL_cleanup()` from your application.
About Prefix and OpenSSLDir
---------------------------
@ -145,9 +157,7 @@ update this list:
- nonstop-nsx_64_put
**Note:** Cross-compile builds for TNS/E have not been attempted, but should
follow the same considerations as for TNS/X above. SPT builds generally require
FLOSS, which is not available for workstation builds. As a result, SPT builds
of OpenSSL cannot be cross-compiled.
follow the same considerations as for TNS/X above.
Also see the NSDEE discussion below for more historical information.
@ -211,30 +221,21 @@ Example Configure Targets
-------------------------
For OSS targets, the main DLL names will be `libssl.so` and `libcrypto.so`.
For GUARDIAN targets, DLL names will be `ssl` and `crypto`. The following
assumes that your PWD is set according to your installation standards.
The following assumes that your PWD is set according to your installation
standards.
./Configure nonstop-nsx --prefix=${PWD} \
--openssldir=${PWD}/ssl no-threads \
--with-rand-seed=rdcpu ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS}
./Configure nonstop-nsx_g --prefix=${PWD} \
--openssldir=${PWD}/ssl no-threads \
--with-rand-seed=rdcpu ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS}
./Configure nonstop-nsx_put --prefix=${PWD} \
--openssldir=${PWD}/ssl threads "-D_REENTRANT" \
--with-rand-seed=rdcpu ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS}
./Configure nonstop-nsx_spt_floss --prefix=${PWD} \
--openssldir=${PWD}/ssl threads "-D_REENTRANT" \
--with-rand-seed=rdcpu ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS}
./Configure nonstop-nsx_64 --prefix=${PWD} \
--openssldir=${PWD}/ssl no-threads \
--with-rand-seed=rdcpu ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS}
./Configure nonstop-nsx_64_put --prefix=${PWD} \
--openssldir=${PWD}/ssl threads "-D_REENTRANT" \
--with-rand-seed=rdcpu ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS}
./Configure nonstop-nsx_g_tandem --prefix=${PWD} \
--openssldir=${PWD}/ssl no-threads \
--with-rand-seed=rdcpu ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS}
./Configure nonstop-nse --prefix=${PWD} \
--openssldir=${PWD}/ssl no-threads \
@ -245,15 +246,9 @@ assumes that your PWD is set according to your installation standards.
./Configure nonstop-nse_put --prefix=${PWD} \
--openssldir=${PWD}/ssl threads "-D_REENTRANT" \
--with-rand-seed=egd ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS}
./Configure nonstop-nse_spt_floss --prefix=${PWD} \
--openssldir=${PWD}/ssl threads "-D_REENTRANT" \
--with-rand-seed=egd ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS}
./Configure nonstop-nse_64 --prefix=${PWD} \
--openssldir=${PWD}/ssl no-threads \
--with-rand-seed=egd ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS}
./Configure nonstop-nse_64_put --prefix=${PWD} \
--openssldir=${PWD}/ssl threads "-D_REENTRANT"
--with-rand-seed=egd ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS}
./Configure nonstop-nse_g_tandem --prefix=${PWD} \
--openssldir=${PWD}/ssl no-threads \
--with-rand-seed=egd ${CIPHENABLES} ${DBGFLAG} ${SYSTEMLIBS}

View file

@ -38,7 +38,7 @@ MinGW and Cygwin. The key recommendation is to use a Perl installation
that matches the build environment. For example, if you will build
on Cygwin be sure to use the Cygwin package manager to install Perl.
For MSYS builds use the MSYS provided Perl.
For VC-* builds we recommend Strawberry Perl, from <http://strawberryperl.com>.
For VC-* builds, we recommend Strawberry Perl, from <http://strawberryperl.com>.
An alternative is ActiveState Perl, from <http://www.activestate.com/ActivePerl>
for which you may need to explicitly select the Perl module Win32/Console.pm
available via <https://platform.activestate.com/ActiveState>.

20
deps/openssl/openssl/NOTES-POSIX.md vendored Normal file
View file

@ -0,0 +1,20 @@
Notes on POSIX
==============
There are few instances where OpenSSL requires a POSIX C library, at least
version 1-2008, or compatible enough functionality.
There are exceptions, though, for platforms that do not have a POSIX
library, or where there are quirks that need working around. A notable
platform is Windows, where POSIX functionality may be available, but where
the function names are prefixed with an underscore, and where some POSIX
types are not present (such as `ssize_t`).
Platforms that do have a POSIX library may still not have them accessible
unless the following macros are defined:
_POSIX_C_SOURCE=200809L
_XOPEN_SOURCE=1
This is, for example, the case when building with gcc or clang and using the
flag `-ansi`.

View file

@ -101,14 +101,14 @@ Notes for UNIX-like platforms
shared library face exactly the same problem with non-default locations.
The OpenSSL config options mentioned above might or might not have bearing
on linking of the target application. "Might" means that under some
circumstances it would be sufficient to link with OpenSSL shared library
circumstances, it would be sufficient to link with OpenSSL shared library
"naturally", i.e. with `-L/whatever/path -lssl -lcrypto`. But there are
also cases when you'd have to explicitly specify runtime search path
when linking your application. Consult your system documentation and use
above section as inspiration...
Shared OpenSSL builds also install static libraries. Linking with the
latter is likely to require special care, because linkers usually look
latter is likely to require special care because linkers usually look
for shared libraries first and tend to remain "blind" to static OpenSSL
libraries. Referring to system documentation would suffice, if not for
a corner case. On AIX static libraries (in shared build) are named

View file

@ -1,9 +1,9 @@
Notes on Valgrind
=================
Valgrind is a test harness that includes many tools such as memcheck,
[Valgrind](https://valgrind.org/) is a test harness that includes many tools such as memcheck,
which is commonly used to check for memory leaks, etc. The default tool
run by Valgrind is memcheck. There are other tools available, but this
run by Valgrind is memcheck. There are [other tools available](https://valgrind.org/info/tools.html), but this
will focus on memcheck.
Valgrind runs programs in a virtual machine, this means OpenSSL unit
@ -13,11 +13,11 @@ Requirements
------------
1. Platform supported by Valgrind
See <http://valgrind.org/info/platforms.html>
- See [Valgrind Supported Platforms](http://valgrind.org/info/platforms.html)
2. Valgrind installed on the platform
See <http://valgrind.org/downloads/current.html>
- See [Valgrind Current Releases](http://valgrind.org/downloads/current.html)
3. OpenSSL compiled
See [INSTALL.md](INSTALL.md)
- See [INSTALL.md](INSTALL.md)
Running Tests
-------------
@ -32,7 +32,7 @@ to allow programs to find shared libraries. The variable can be modified
to specify a different executable environment.
EXE_SHELL=\
"`/bin/pwd`/util/wrap.pl valgrind --error-exitcode=1 --leak-check=full -q"
"$(/bin/pwd)/util/wrap.pl valgrind --error-exitcode=1 --leak-check=full -q"
This will start up Valgrind with the default checker (`memcheck`).
The `--error-exitcode=1` option specifies that Valgrind should exit with an
@ -62,11 +62,11 @@ file [test/README.md](test/README.md).
Example command line:
$ make test EXE_SHELL="`/bin/pwd`/util/wrap.pl valgrind --error-exitcode=1 \
$ make test EXE_SHELL="$(/bin/pwd)/util/wrap.pl valgrind --error-exitcode=1 \
--leak-check=full -q" OPENSSL_ia32cap=":0"
If an error occurs, you can then run the specific test via the `TESTS` variable
with the `VERBOSE` or `VF` or `VFP` options to gather additional information.
$ make test VERBOSE=1 TESTS=test_test EXE_SHELL="`/bin/pwd`/util/wrap.pl \
$ make test VERBOSE=1 TESTS=test_test EXE_SHELL="$(/bin/pwd)/util/wrap.pl \
valgrind --error-exitcode=1 --leak-check=full -q" OPENSSL_ia32cap=":0"

View file

@ -1,9 +1,9 @@
Notes for Windows platforms
===========================
- [Native builds using Visual C++](#native-builds-using-visual-c++)
- [Native builds using Visual C++](#native-builds-using-visual-c)
- [Native builds using Embarcadero C++Builder](
#native-builds-using-embarcadero-c++-builder)
#native-builds-using-embarcadero-cbuilder)
- [Native builds using MinGW](#native-builds-using-mingw)
- [Linking native applications](#linking-native-applications)
- [Hosted builds using Cygwin](#hosted-builds-using-cygwin)
@ -23,7 +23,7 @@ or
"Hosted" OpenSSL relies on an external POSIX compatibility layer
for building (using GNU/Unix shell, compiler, and tools) and at run time.
For this option you can use Cygwin.
For this option, you can use Cygwin.
Native builds using Visual C++
==============================
@ -77,6 +77,14 @@ Quick start
- `perl Configure VC-WIN64A` if you want 64-bit OpenSSL or
- `perl Configure VC-WIN64-ARM` if you want Windows on Arm (win-arm64)
OpenSSL or
- `perl Configure VC-WIN64-CLANGASM-ARM` if you want Windows on Arm (win-arm64)
OpenSSL with assembly support using clang-cl as assembler or
- `perl Configure VC-CLANG-WIN64-CLANGASM-ARM` if you want Windows on Arm (win-arm64)
OpenSSL using clang-cl as both compiler and assembler or
- `perl Configure VC-WIN32-HYBRIDCRT` if you want 32-bit OpenSSL dependent
on the Universal CRT or
- `perl Configure VC-WIN64A-HYBRIDCRT` if you want 64-bit OpenSSL dependent
on the Universal CRT or
- `perl Configure` to let Configure figure out the platform
a. If you don't plan to develop OpenSSL yourself and don't need to rebuild,
@ -96,31 +104,41 @@ check the INSTALL.md file.
Installation directories
------------------------
The default installation directories are derived from environment
variables.
On most Unix platforms installation directories are determined at build time via
constant defines. On Windows platforms however, installation directories are
determined via registry keys, as it is common practice to build OpenSSL and
install it to a variety of locations.
For VC-WIN32, the following defaults are use:
The following keys:
PREFIX: %ProgramFiles(x86)%\OpenSSL
OPENSSLDIR: %CommonProgramFiles(x86)%\SSL
`\\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\OpenSSL-<version>-<ctx>\OPENSSLDIR`
`\\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\OpenSSL-<version>-<ctx>\ENGINESDIR`
`\\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\OpenSSL-<version>-<ctx>\MODULESDIR`
For VC-WIN64, the following defaults are use:
Can be administratively set, and openssl will take the paths found there as the
values for OPENSSLDIR, ENGINESDIR and MODULESDIR respectively.
PREFIX: %ProgramW6432%\OpenSSL
OPENSSLDIR: %CommonProgramW6432%\SSL
To enable the reading of registry keys from windows builds, add
`-DOSSL_WINCTX=<string>`to the Configure command line. This define is used
at build-time to construct library build specific registry key paths of the
format:
`\\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432node\OpenSSL-<version>-<ctx>`
Should those environment variables not exist (on a pure Win32
installation for examples), these fallbacks are used:
Where `<version>` is the major.minor version of the library being
built, and `<ctx>` is the value specified by `-DOPENSSL_WINCTX`. This allows
for multiple openssl builds to be created and installed on a single system, in
which each library can use its own set of registry keys.
PREFIX: %ProgramFiles%\OpenSSL
OPENSSLDIR: %CommonProgramFiles%\SSL
Note the installer available at <https://github.com/openssl/installer> will set
these keys when the installer is run.
ALSO NOTE that those directories are usually write protected, even if
your account is in the Administrators group. To work around that,
start the command prompt by right-clicking on it and choosing "Run as
Administrator" before running `nmake install`. The other solution
is, of course, to choose a different set of directories by using
`--prefix` and `--openssldir` when configuring.
A summary table of behavior on Windows platforms
|`OSSL_WINCTX`|Registry key|OpenSSL Behavior |
|-------------|------------|------------------------------------------|
|Defined | Defined |OpenSSL Reads Paths from Registry |
|Defined | Undefined |OpenSSL returns errors on module/conf load|
|Undefined | N/A |OpenSSL uses build time defaults |
Special notes for Universal Windows Platform builds, aka `VC-*-UWP`
-------------------------------------------------------------------
@ -135,8 +153,8 @@ Native builds using Embarcadero C++Builder
=========================================
This toolchain (a descendant of Turbo/Borland C++) is an alternative to MSVC.
OpenSSL currently includes an experimental 32-bit configuration targeting the
Clang-based compiler (`bcc32c.exe`) in v10.3.3 Community Edition.
OpenSSL currently includes experimental 32-bit and 64-bit configurations targeting the
Clang-based compiler (`bcc32c.exe` and `bcc64.exe`) in v10.3.3 Community Edition.
<https://www.embarcadero.com/products/cbuilder/starter>
1. Install Perl.
@ -145,6 +163,8 @@ Clang-based compiler (`bcc32c.exe`) in v10.3.3 Community Edition.
3. Go to the root of the OpenSSL source directory and run:
`perl Configure BC-32 --prefix=%CD%`
for Win64 builds use:
`perl Configure BC-64 --prefix=%CD%`
4. `make -N`
@ -217,7 +237,7 @@ Linking native applications
This section applies to all native builds.
If you link with static OpenSSL libraries then you're expected to
If you link with static OpenSSL libraries, then you're expected to
additionally link your application with `WS2_32.LIB`, `GDI32.LIB`,
`ADVAPI32.LIB`, `CRYPT32.LIB` and `USER32.LIB`. Those developing
non-interactive service applications might feel concerned about
@ -225,7 +245,7 @@ linking with `GDI32.LIB` and `USER32.LIB`, as they are justly associated
with interactive desktop, which is not available to service
processes. The toolkit is designed to detect in which context it's
currently executed, GUI, console app or service, and act accordingly,
namely whether or not to actually make GUI calls. Additionally those
namely whether to actually make GUI calls. Additionally, those
who wish to `/DELAYLOAD:GDI32.DLL` and `/DELAYLOAD:USER32.DLL` and
actually keep them off service process should consider implementing
and exporting from .exe image in question own `_OPENSSL_isservice` not
@ -266,5 +286,5 @@ Apart from that, follow the Unix / Linux instructions in INSTALL.md.
NOTE: `make test` and normal file operations may fail in directories
mounted as text (i.e. `mount -t c:\somewhere /home`) due to Cygwin
stripping of carriage returns. To avoid this ensure that a binary
stripping of carriage returns. To avoid this, ensure that a binary
mount is used, e.g. `mount -b c:\somewhere /home`.

View file

@ -8,7 +8,7 @@ The ENGINE API was introduced in OpenSSL version 0.9.6 as a low level
interface for adding alternative implementations of cryptographic
primitives, most notably for integrating hardware crypto devices.
The ENGINE interface has its limitations and it has been superseeded
The ENGINE interface has its limitations and it has been superseded
by the [PROVIDER API](README-PROVIDERS.md), it is deprecated in OpenSSL
version 3.0. The following documentation is retained as an aid for
users who need to maintain or support existing ENGINE implementations.
@ -22,9 +22,9 @@ Built-in ENGINE implementations
There are currently built-in ENGINE implementations for the following
crypto devices:
* Microsoft CryptoAPI
* VIA Padlock
* nCipher CHIL
- Microsoft CryptoAPI
- VIA Padlock
- nCipher CHIL
In addition, dynamic binding to external ENGINE implementations is now
provided by a special ENGINE called "dynamic". See the "DYNAMIC ENGINE"
@ -94,10 +94,10 @@ implementation) then you should mail complete details to the relevant
OpenSSL mailing list. For a definition of "complete details", refer to
the OpenSSL "README" file. As for which list to send it to:
* openssl-users: if you are *using* the ENGINE abstraction, either in an
- openssl-users: if you are *using* the ENGINE abstraction, either in an
pre-compiled application or in your own application code.
* openssl-dev: if you are discussing problems with OpenSSL source code.
- openssl-dev: if you are discussing problems with OpenSSL source code.
USAGE
=====
@ -185,7 +185,7 @@ the shared-library ENGINE implementation. If this command succeeds, the
(copy of the) 'dynamic' ENGINE will magically morph into the ENGINE
that has been loaded from the shared-library. As such, any control
commands supported by the loaded ENGINE could then be executed as per
normal. Eg. if ENGINE "foo" is implemented in the shared-library
normal. For instance, if ENGINE "foo" is implemented in the shared-library
"libfoo.so" and it supports some special control command "CMD_FOO", the
following code would load and use it (NB: obviously this code has no
error checking);
@ -282,8 +282,9 @@ ENGINE.
3. Manually enter the same compilation line to compile the
"hw_atalla.c" file but with the following two changes;
* add "-DENGINE_DYNAMIC_SUPPORT" to the command line switches,
* change the output file from "hw_atalla.o" to something new,
- add "-DENGINE_DYNAMIC_SUPPORT" to the command line switches,
- change the output file from "hw_atalla.o" to something new,
eg. "tmp_atalla.o"
4. Link "tmp_atalla.o" into a shared-library using the top-level

View file

@ -34,7 +34,9 @@ Installing the FIPS provider
In order to be FIPS compliant you must only use FIPS validated source code.
Refer to <https://www.openssl.org/source/> for information related to
which versions are FIPS validated. The instructions given below build OpenSSL
just using the FIPS validated source code.
just using the FIPS validated source code. Any FIPS validated version may be
used with any other openssl library. Please see <https://www.openssl.org/source/>
To determine which FIPS validated library version may be appropriate for you.
If you want to use a validated FIPS provider, but also want to use the latest
OpenSSL release to build everything else, then refer to the next section.
@ -71,14 +73,14 @@ the installation by doing the following two things:
- Runs the FIPS module self tests
- Generates the so-called FIPS module configuration file containing information
about the module such as the module checksum (and for OpenSSL 3.0 the
about the module such as the module checksum (and for OpenSSL 3.1.2 the
self test status).
The FIPS module must have the self tests run, and the FIPS module config file
output generated on every machine that it is to be used on. For OpenSSL 3.0,
output generated on every machine that it is to be used on. For OpenSSL 3.1.2
you must not copy the FIPS module config file output data from one machine to another.
On Unix the `openssl fipsinstall` command will be invoked as follows by default:
On Unix, the `openssl fipsinstall` command will be invoked as follows by default:
$ openssl fipsinstall -out /usr/local/ssl/fipsmodule.cnf -module /usr/local/lib/ossl-modules/fips.so
@ -95,11 +97,11 @@ Download and build a validated FIPS provider
--------------------------------------------
Refer to <https://www.openssl.org/source/> for information related to
which versions are FIPS validated. For this example we use OpenSSL 3.0.0.
which versions are FIPS validated. For this example we use OpenSSL 3.1.2.
$ wget https://www.openssl.org/source/openssl-3.0.0.tar.gz
$ tar -xf openssl-3.0.0.tar.gz
$ cd openssl-3.0.0
$ wget https://www.openssl.org/source/openssl-3.1.2.tar.gz
$ tar -xf openssl-3.1.2.tar.gz
$ cd openssl-3.1.2
$ ./Configure enable-fips
$ make
$ cd ..
@ -107,44 +109,45 @@ which versions are FIPS validated. For this example we use OpenSSL 3.0.0.
Download and build the latest release of OpenSSL
------------------------------------------------
We use OpenSSL 3.1.0 here, (but you could also use the latest 3.0.X)
We use OpenSSL 3.5.0 here, (but you could also use the latest 3.5.X)
$ wget https://www.openssl.org/source/openssl-3.1.0.tar.gz
$ tar -xf openssl-3.1.0.tar.gz
$ cd openssl-3.1.0
$ wget https://www.openssl.org/source/openssl-3.5.0.tar.gz
$ tar -xf openssl-3.5.0.tar.gz
$ cd openssl-3.5.0
$ ./Configure enable-fips
$ make
Use the OpenSSL FIPS provider for testing
-----------------------------------------
We do this by replacing the artifact for the OpenSSL 3.1.0 FIPS provider.
Note that the OpenSSL 3.1.0 FIPS provider has not been validated
We do this by replacing the artifact for the OpenSSL 3.5.0 FIPS provider.
Note that the OpenSSL 3.5.0 FIPS provider has not been validated
so it must not be used for FIPS purposes.
$ cp ../openssl-3.0.0/providers/fips.so providers/.
$ cp ../openssl-3.0.0/providers/fipsmodule.cnf providers/.
// Note that for OpenSSL 3.0 that the `fipsmodule.cnf` file should not
$ cp ../openssl-3.1.2/providers/fips.so providers/.
$ cp ../openssl-3.1.2/providers/fipsmodule.cnf providers/.
// Note that for OpenSSL 3.1.2 that the `fipsmodule.cnf` file should not
// be copied across multiple machines if it contains an entry for
// `install-status`. (Otherwise the self tests would be skipped).
// Validate the output of the following to make sure we are using the
// OpenSSL 3.0.0 FIPS provider
// OpenSSL 3.1.2 FIPS provider
$ ./util/wrap.pl -fips apps/openssl list -provider-path providers \
-provider fips -providers
// Now run the current tests using the OpenSSL 3.0 FIPS provider.
// Now run the current tests using the OpenSSL 3.1.2 FIPS provider.
$ make tests
Copy the FIPS provider artifacts (`fips.so` & `fipsmodule.cnf`) to known locations
-------------------------------------------------------------------------------------
$ cd ../openssl-3.0.0
$ cd ../openssl-3.1.2
$ sudo make install_fips
Check that the correct FIPS provider is being used
--------------------------------------------------
$ cd ../openssl-3.5.0
$./util/wrap.pl -fips apps/openssl list -provider-path providers \
-provider fips -providers
@ -152,11 +155,11 @@ Check that the correct FIPS provider is being used
Providers:
base
name: OpenSSL Base Provider
version: 3.1.0
version: 3.5.0
status: active
fips
name: OpenSSL FIPS Provider
version: 3.0.0
version: 3.1.2
status: active
Using the FIPS Module in applications
@ -165,4 +168,34 @@ Using the FIPS Module in applications
Documentation about using the FIPS module is available on the [fips_module(7)]
manual page.
[fips_module(7)]: https://www.openssl.org/docs/man3.0/man7/fips_module.html
[fips_module(7)]: https://www.openssl.org/docs/manmaster/man7/fips_module.html
Entropy Source
==============
The FIPS provider typically relies on an external entropy source,
specified during OpenSSL build configuration (default: `os`). However, by
enabling the `enable-fips-jitter` option during configuration, an internal
jitter entropy source will be used instead. Note that this will cause
the FIPS provider to operate in a non-compliant mode unless an entropy
assessment [ESV] and validation through the [CMVP] are additionally conducted.
Note that the `enable-fips-jitter` option is only available in OpenSSL
versions 3.5 and later.
[CMVP]: https://csrc.nist.gov/projects/cryptographic-module-validation-program
[ESV]: https://csrc.nist.gov/Projects/cryptographic-module-validation-program/entropy-validations
3rd-Party Vendor Builds
=====================================
Some Vendors choose to patch/modify/build their own FIPS provider,
test it with a Security Laboratory and submit it under their own CMVP
certificate, instead of using OpenSSL Project submissions. When doing
so, FIPS provider should uniquely identify its own name and version
number. The build infrastructure allows to customize FIPS provider
build information via changes to strings in `VERSION.dat`.
Setting "PRE_RELEASE_TAG" (dashed suffix), "BUILD_METADATA" (plus
suffix), and "FIPS_VENDOR" allow to control reported FIPS provider
name and build version as required for CMVP submission.

View file

@ -15,12 +15,12 @@ Standard Providers
Providers are containers for algorithm implementations. Whenever a cryptographic
algorithm is used via the high level APIs a provider is selected. It is that
provider implementation that actually does the required work. There are five
providers distributed with OpenSSL. In the future we expect third parties to
providers distributed with OpenSSL. In the future, we expect third parties to
distribute their own providers which can be added to OpenSSL dynamically.
Documentation about writing providers is available on the [provider(7)]
manual page.
[provider(7)]: https://www.openssl.org/docs/man3.0/man7/provider.html
[provider(7)]: https://www.openssl.org/docs/manmaster/man7/provider.html
The Default Provider
--------------------
@ -31,10 +31,10 @@ explicitly (e.g. in the application or via config), then this is the provider
that will be used. It is loaded automatically the first time that we try to
get an algorithm from a provider if no other provider has been loaded yet.
If another provider has already been loaded then it won't be loaded
automatically. Therefore if you want to use it in conjunction with other
providers then you must load it explicitly.
automatically. Therefore, if you want to use it in conjunction with other
providers, then you must load it explicitly.
This is a "built-in" provider which means that it is compiled and linked
This is a "built-in" provider, which means that it is compiled and linked
into the libcrypto library and does not exist as a separate standalone module.
The Legacy Provider
@ -58,7 +58,7 @@ The FIPS provider contains a sub-set of the algorithm implementations available
from the default provider, consisting of algorithms conforming to FIPS standards.
It is intended that this provider will be FIPS140-2 validated.
In some cases there may be minor behavioural differences between algorithm
In some cases, there may be minor behavioural differences between algorithm
implementations in this provider compared to the equivalent algorithm in the
default provider. This is typically in order to conform to FIPS standards.
@ -88,7 +88,7 @@ Providers to be loaded can be specified in the OpenSSL config file.
See the [config(5)] manual page for information about how to configure
providers via the config file, and how to automatically activate them.
[config(5)]: https://www.openssl.org/docs/man3.0/man5/config.html
[config(5)]: https://www.openssl.org/docs/manmaster/man5/config.html
The following is a minimal config file example to load and activate both
the legacy and the default provider in the default library context.

108
deps/openssl/openssl/README-QUIC.md vendored Normal file
View file

@ -0,0 +1,108 @@
Using OpenSSL with QUIC
=======================
From OpenSSL 3.2, OpenSSL features support for making QUIC connections as a
client. Starting with OpenSSL 3.5, server-side QUIC support has also been added.
Users interested in using the new QUIC functionality are encouraged to look at
some of the following resources:
- The new [OpenSSL Guide], which provides introductory guides on the use of TLS,
QUIC, and other OpenSSL functionality.
- The [OpenSSL Guide] incorporates various code samples. The complete source
for these can be [found in the source tree under `demos/guide`](./demos/guide/).
- The [openssl-quic(7) manual page], which provides a basic reference overview
of QUIC functionality and how use of QUIC differs from use of TLS with regard
to our API.
- The [Demo-Driven Design (DDD)][DDD] demos, which demonstrate the use of QUIC
using simple examples. These can be [found in the source tree under
`doc/designs/ddd`].
- The [demo found in `demos/http3`], which provides an HTTP/3 client example
using the nghttp3 HTTP/3 library.
FAQ
---
### Why would I want to use QUIC, and what functionality does QUIC offer relative to TLS or DTLS?
QUIC is a state-of-the-art secure transport protocol carried over UDP. It can
serve many of the use cases of SSL/TLS as well as those of DTLS.
QUIC delivers a number of advantages such as support for multiple streams of
communication; it is the basis for HTTP/3 [RFC 9114]; fast connection
initiation; and connection migration (enabling a connection to survive IP
address changes). For a more complete description of what QUIC is and its
advantages see the [QUIC Introduction] in the [OpenSSL Guide].
For a comprehensive overview of OpenSSL's QUIC implementation, see the
[openssl-quic(7) manual page].
### How can I use HTTP/3 with OpenSSL?
There are many HTTP/3 implementations in C available. The use of one such HTTP/3
library with OpenSSL QUIC is demonstrated via the [demo found in `demos/http3`].
### How can I use OpenSSL QUIC in my own application for a different protocol?
The [OpenSSL Guide] provides introductory examples for how to make use of
OpenSSL QUIC.
The [openssl-quic(7) manual page] and the [Demo-Driven Design (DDD)][DDD] demos
may also be helpful to illustrate the changes needed if you are trying to adapt
an existing application.
### How can I test QUIC using `openssl s_client`?
There is basic support for single-stream QUIC using `openssl s_client`:
```shell
$ openssl s_client -quic -alpn myalpn -connect host:port
```
In the above example replace `host` with the hostname of the server (e.g.
`www.example.com`) and `port` with the port for the server (e.g. `443`). Replace
`myalpn` with the Application Layer Protocol to use (e.g.`h3` represents
HTTP/3). IANA maintains a standard list of [ALPN ids] that can be used.
This example connects to a QUIC server and opens a single bidirectional stream.
Data can be passed via stdin/stdout as usual. This allows test usage of QUIC
using simple TCP/TLS-like usage. Note that OpenSSL has no direct support for
HTTP/3 so connecting to an HTTP/3 server should be possible but sending an
HTTP/3 request or receiving any response data is not.
### How can I create a QUIC server with OpenSSL?
Starting with OpenSSL 3.5, you can create a QUIC server. OpenSSL provides a server
implementation example that you can use as a reference:
The example QUIC server implementation can be found in the source tree under
[`demos/quic/server`](./demos/quic/server/). This demonstrates how to implement a
basic QUIC server using the OpenSSL API.
To run the example QUIC server:
```shell
$ ./demos/quic/server/server <port-number> <certificate-file> <key-file>
```
For example:
```shell
$ ./demos/quic/server/server 4433 server.pem server.key
```
Replace `server.pem` and `server.key` with your certificate and private key files.
Note that the standard `openssl s_server` command does NOT support QUIC - you must
use this dedicated server example instead.
For more information about implementing QUIC servers with OpenSSL, refer to the
[OpenSSL Guide] and the [openssl-quic(7) manual page].
[openssl-quic(7) manual page]: https://www.openssl.org/docs/manmaster/man7/openssl-quic.html
[OpenSSL Guide]: https://www.openssl.org/docs/manmaster/man7/ossl-guide-introduction.html
[DDD]: https://github.com/openssl/openssl/tree/master/doc/designs/ddd
[found in the source tree under `doc/designs/ddd`]: ./doc/designs/ddd/
[demo found in `demos/http3`]: ./demos/http3/
[QUIC Introduction]: https://www.openssl.org/docs/manmaster/man7/ossl-guide-quic-introduction.html
[RFC 9114]: https://tools.ietf.org/html/rfc9114
[ALPN ids]: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids

View file

@ -4,13 +4,17 @@ Welcome to the OpenSSL Project
[![openssl logo]][www.openssl.org]
[![github actions ci badge]][github actions ci]
[![appveyor badge]][appveyor jobs]
![Nightly OS Zoo ci badge](https://github.com/openssl/openssl/actions/workflows/os-zoo.yml/badge.svg)
![Provider Compatibility](https://github.com/openssl/openssl/actions/workflows/provider-compatibility.yml/badge.svg)
![Quic Interop](https://github.com/openssl/openssl/actions/workflows/run_quic_interop.yml/badge.svg)
![Daily checks](https://github.com/openssl/openssl/actions/workflows/run-checker-daily.yml/badge.svg)
OpenSSL is a robust, commercial-grade, full-featured Open Source Toolkit
for the Transport Layer Security (TLS) protocol formerly known as the
Secure Sockets Layer (SSL) protocol. The protocol implementation is based
on a full-strength general purpose cryptographic library, which can also
be used stand-alone.
for the TLS (formerly SSL), DTLS and QUIC protocols.
The protocol implementations are based on a full-strength general purpose
cryptographic library, which can also be used stand-alone. Also included is a
cryptographic module validated to conform with FIPS standards.
OpenSSL is descended from the SSLeay library developed by Eric A. Young
and Tim J. Hudson.
@ -35,7 +39,9 @@ Overview
The OpenSSL toolkit includes:
- **libssl**
an implementation of all TLS protocol versions up to TLSv1.3 ([RFC 8446]).
an implementation of all TLS protocol versions up to TLSv1.3 ([RFC 8446]),
DTLS protocol versions up to DTLSv1.2 ([RFC 6347]) and
the QUIC version 1 protocol ([RFC 9000]).
- **libcrypto**
a full-strength general purpose cryptographic library. It constitutes the
@ -48,7 +54,8 @@ The OpenSSL toolkit includes:
- creation of X.509 certificates, CSRs and CRLs
- calculation of message digests
- encryption and decryption
- SSL/TLS client and server tests
- SSL/TLS/DTLS and client and server tests
- QUIC client tests
- handling of S/MIME signed or encrypted mail
- and more...
@ -63,10 +70,14 @@ Source code tarballs of the official releases can be downloaded from
The OpenSSL project does not distribute the toolkit in binary form.
However, for a large variety of operating systems precompiled versions
of the OpenSSL toolkit are available. In particular on Linux and other
Unix operating systems it is normally recommended to link against the
of the OpenSSL toolkit are available. In particular, on Linux and other
Unix operating systems, it is normally recommended to link against the
precompiled shared libraries provided by the distributor or vendor.
We also maintain a list of third parties that produce OpenSSL binaries for
various Operating Systems (including Windows) on the [Binaries] page on our
wiki.
For Testing and Development
---------------------------
@ -90,7 +101,7 @@ instead.
git clone https://github.com/yourname/openssl.git
This is necessary, because all development of OpenSSL nowadays is done via
This is necessary because all development of OpenSSL nowadays is done via
GitHub pull requests. For more details, see [Contributing](#contributing).
Build and Install
@ -109,12 +120,29 @@ document.
* [Notes on Perl](NOTES-PERL.md)
* [Notes on Valgrind](NOTES-VALGRIND.md)
Specific notes on upgrading to OpenSSL 3.0 from previous versions can be found
in the [migration_guide(7ossl)] manual page.
Specific notes on upgrading to OpenSSL 3.x from previous versions can be found
in the [ossl-guide-migration(7ossl)] manual page.
Documentation
=============
README Files
------------
There are some README.md files in the top level of the source distribution
containing additional information on specific topics.
* [Information about the OpenSSL QUIC protocol implementation](README-QUIC.md)
* [Information about the OpenSSL Provider architecture](README-PROVIDERS.md)
* [Information about using the OpenSSL FIPS validated module](README-FIPS.md)
* [Information about the legacy OpenSSL Engine architecture](README-ENGINES.md)
The OpenSSL Guide
-----------------
There are some tutorial and introductory pages on some important OpenSSL topics
within the [OpenSSL Guide].
Manual Pages
------------
@ -123,7 +151,14 @@ available online.
- [OpenSSL master](https://www.openssl.org/docs/manmaster)
- [OpenSSL 3.0](https://www.openssl.org/docs/man3.0)
- [OpenSSL 1.1.1](https://www.openssl.org/docs/man1.1.1)
- [OpenSSL 3.1](https://www.openssl.org/docs/man3.1)
- [OpenSSL 3.2](https://www.openssl.org/docs/man3.2)
Demos
-----
There are numerous source code demos for using various OpenSSL capabilities in the
[demos subfolder](./demos).
Wiki
----
@ -143,7 +178,7 @@ Support
=======
There are various ways to get in touch. The correct channel depends on
your requirement. see the [SUPPORT](SUPPORT.md) file for more details.
your requirement. See the [SUPPORT](SUPPORT.md) file for more details.
Contributing
============
@ -155,13 +190,13 @@ Legalities
==========
A number of nations restrict the use or export of cryptography. If you are
potentially subject to such restrictions you should seek legal advice before
potentially subject to such restrictions, you should seek legal advice before
attempting to develop or distribute cryptographic code.
Copyright
=========
Copyright (c) 1998-2025 The OpenSSL Project
Copyright (c) 1998-2025 The OpenSSL Project Authors
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
@ -181,13 +216,27 @@ All rights reserved.
<https://github.com/openssl/openssl/wiki>
"OpenSSL Wiki"
[migration_guide(7ossl)]:
<https://www.openssl.org/docs/man3.0/man7/migration_guide.html>
[ossl-guide-migration(7ossl)]:
<https://www.openssl.org/docs/manmaster/man7/ossl-guide-migration.html>
"OpenSSL Migration Guide"
[RFC 8446]:
<https://tools.ietf.org/html/rfc8446>
[RFC 6347]:
<https://tools.ietf.org/html/rfc6347>
[RFC 9000]:
<https://tools.ietf.org/html/rfc9000>
[Binaries]:
<https://github.com/openssl/openssl/wiki/Binaries>
"List of third party OpenSSL binaries"
[OpenSSL Guide]:
<https://www.openssl.org/docs/manmaster/man7/ossl-guide-introduction.html>
"An introduction to OpenSSL"
<!-- Logos and Badges -->
[openssl logo]:

View file

@ -1,6 +1,6 @@
MAJOR=3
MINOR=0
PATCH=17
MINOR=5
PATCH=1
PRE_RELEASE_TAG=
BUILD_METADATA=
RELEASE_DATE="1 Jul 2025"

View file

@ -32,7 +32,7 @@ const OPTIONS asn1parse_options[] = {
{"oid", OPT_OID, '<', "file of extra oid definitions"},
OPT_SECTION("I/O"),
{"inform", OPT_INFORM, 'F', "input format - one of DER PEM"},
{"inform", OPT_INFORM, 'A', "input format - one of DER PEM B64"},
{"in", OPT_IN, '<', "input file"},
{"out", OPT_OUT, '>', "output file (output format is always DER)"},
{"noout", OPT_NOOUT, 0, "do not produce any output"},
@ -44,7 +44,7 @@ const OPTIONS asn1parse_options[] = {
{OPT_MORE_STR, 0, 0, "into multiple ASN1 blob wrappings"},
{"genconf", OPT_GENCONF, 's', "file to generate ASN1 structure from"},
{"strictpem", OPT_STRICTPEM, 0,
"do not attempt base64 decode outside PEM markers"},
"equivalent to '-inform pem' (obsolete)"},
{"item", OPT_ITEM, 's', "item to parse and print"},
{OPT_MORE_STR, 0, 0, "(-inform will be ignored)"},
@ -69,7 +69,7 @@ int asn1parse_main(int argc, char **argv)
unsigned char *str = NULL;
char *name = NULL, *header = NULL, *prog;
const unsigned char *ctmpbuf;
int indent = 0, noout = 0, dump = 0, strictpem = 0, informat = FORMAT_PEM;
int indent = 0, noout = 0, dump = 0, informat = FORMAT_PEM;
int offset = 0, ret = 1, i, j;
long num, tmplen;
unsigned char *tmpbuf;
@ -96,7 +96,7 @@ int asn1parse_main(int argc, char **argv)
ret = 0;
goto end;
case OPT_INFORM:
if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
if (!opt_format(opt_arg(), OPT_FMT_ASN1, &informat))
goto opthelp;
break;
case OPT_IN:
@ -137,7 +137,7 @@ int asn1parse_main(int argc, char **argv)
genconf = opt_arg();
break;
case OPT_STRICTPEM:
strictpem = 1;
/* accepted for backward compatibility */
informat = FORMAT_PEM;
break;
case OPT_ITEM:
@ -160,8 +160,7 @@ int asn1parse_main(int argc, char **argv)
}
/* No extra args. */
argc = opt_num_rest();
if (argc != 0)
if (!opt_check_rest_arg(NULL))
goto opthelp;
if (oidfile != NULL) {
@ -180,7 +179,7 @@ int asn1parse_main(int argc, char **argv)
if ((buf = BUF_MEM_new()) == NULL)
goto end;
if (strictpem) {
if (genconf == NULL && genstr == NULL && informat == FORMAT_PEM) {
if (PEM_read_bio(in, &name, &header, &str, &num) != 1) {
BIO_printf(bio_err, "Error reading PEM file\n");
ERR_print_errors(bio_err);
@ -200,7 +199,7 @@ int asn1parse_main(int argc, char **argv)
}
} else {
if (informat == FORMAT_PEM) {
if (informat == FORMAT_BASE64) {
BIO *tmp;
if ((b64 = BIO_new(BIO_f_base64())) == NULL)
@ -218,6 +217,9 @@ int asn1parse_main(int argc, char **argv)
i = BIO_read(in, &(buf->data[num]), BUFSIZ);
if (i <= 0)
break;
/* make sure num doesn't overflow */
if (i > LONG_MAX - num)
goto end;
num += i;
}
}

View file

@ -16,7 +16,7 @@ $OPENSSLSRC=\
enc.c errstr.c \
genpkey.c kdf.c mac.c nseq.c passwd.c pkcs7.c \
pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c \
s_client.c s_server.c s_time.c sess_id.c smime.c speed.c \
s_client.c s_server.c s_time.c sess_id.c skeyutl.c smime.c speed.c \
spkac.c verify.c version.c x509.c rehash.c storeutl.c \
list.c info.c fipsinstall.c pkcs12.c
IF[{- !$disabled{'ec'} -}]

View file

@ -1,11 +1,13 @@
/*
* Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include "internal/e_os.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -129,7 +131,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
CONF *conf, unsigned long certopt, unsigned long nameopt,
int default_op, int ext_copy, int selfsign, unsigned long dateopt);
static int get_certificate_status(const char *ser_status, CA_DB *db);
static int do_updatedb(CA_DB *db);
static int check_time_format(const char *str);
static int do_revoke(X509 *x509, CA_DB *db, REVINFO_TYPE rev_type,
const char *extval);
@ -151,10 +152,10 @@ typedef enum OPTION_choice {
OPT_IN, OPT_INFORM, OPT_OUT, OPT_DATEOPT, OPT_OUTDIR, OPT_VFYOPT,
OPT_SIGOPT, OPT_NOTEXT, OPT_BATCH, OPT_PRESERVEDN, OPT_NOEMAILDN,
OPT_GENCRL, OPT_MSIE_HACK, OPT_CRL_LASTUPDATE, OPT_CRL_NEXTUPDATE,
OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC,
OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC, OPT_NOT_BEFORE, OPT_NOT_AFTER,
OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID,
OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS,
OPT_RAND_SERIAL,
OPT_RAND_SERIAL, OPT_QUIET,
OPT_R_ENUM, OPT_PROV_ENUM,
/* Do not change the order here; see related case statements below */
OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, OPT_CRL_CA_COMPROMISE
@ -166,9 +167,11 @@ const OPTIONS ca_options[] = {
OPT_SECTION("General"),
{"help", OPT_HELP, '-', "Display this summary"},
{"verbose", OPT_VERBOSE, '-', "Verbose output during processing"},
{"quiet", OPT_QUIET, '-', "Terse output during processing"},
{"outdir", OPT_OUTDIR, '/', "Where to put output cert"},
{"in", OPT_IN, '<', "The input cert request(s)"},
{"inform", OPT_INFORM, 'F', "CSR input format (DER or PEM); default PEM"},
{"inform", OPT_INFORM, 'F',
"CSR input format to use (PEM or DER; by default try PEM first)"},
{"infiles", OPT_INFILES, '-', "The last argument, requests to process"},
{"out", OPT_OUT, '>', "Where to put the output file(s)"},
{"dateopt", OPT_DATEOPT, 's', "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."},
@ -198,10 +201,13 @@ const OPTIONS ca_options[] = {
"Always create a random serial; do not store it"},
{"multivalue-rdn", OPT_MULTIVALUE_RDN, '-',
"Deprecated; multi-valued RDNs support is always on."},
{"startdate", OPT_STARTDATE, 's', "Cert notBefore, YYMMDDHHMMSSZ"},
{"startdate", OPT_STARTDATE, 's',
"[CC]YYMMDDHHMMSSZ value for notBefore certificate field"},
{"not_before", OPT_NOT_BEFORE, 's', "An alias for -startdate"},
{"enddate", OPT_ENDDATE, 's',
"YYMMDDHHMMSSZ cert notAfter (overrides -days)"},
{"days", OPT_DAYS, 'p', "Number of days to certify the cert for"},
"[CC]YYMMDDHHMMSSZ value for notAfter certificate field, overrides -days"},
{"not_after", OPT_NOT_AFTER, 's', "An alias for -enddate"},
{"days", OPT_DAYS, 'p', "Number of days from today to certify the cert for"},
{"extensions", OPT_EXTENSIONS, 's',
"Extension section (override value in config file)"},
{"extfile", OPT_EXTFILE, '<',
@ -332,6 +338,9 @@ opthelp:
case OPT_VERBOSE:
verbose = 1;
break;
case OPT_QUIET:
verbose = 0;
break;
case OPT_CONFIG:
configfile = opt_arg();
break;
@ -355,9 +364,11 @@ opthelp:
/* obsolete */
break;
case OPT_STARTDATE:
case OPT_NOT_BEFORE:
startdate = opt_arg();
break;
case OPT_ENDDATE:
case OPT_NOT_AFTER:
enddate = opt_arg();
break;
case OPT_DAYS:
@ -510,9 +521,7 @@ end_of_options:
&& (section = lookup_conf(conf, BASE_SECTION, ENV_DEFAULT_CA)) == NULL)
goto end;
p = NCONF_get_string(conf, NULL, "oid_file");
if (p == NULL)
ERR_clear_error();
p = app_conf_try_string(conf, NULL, "oid_file");
if (p != NULL) {
BIO *oid_bio = BIO_new_file(p, "r");
@ -530,29 +539,22 @@ end_of_options:
if (!app_RAND_load())
goto end;
f = NCONF_get_string(conf, section, STRING_MASK);
if (f == NULL)
ERR_clear_error();
f = app_conf_try_string(conf, section, STRING_MASK);
if (f != NULL && !ASN1_STRING_set_default_mask_asc(f)) {
BIO_printf(bio_err, "Invalid global string mask setting %s\n", f);
goto end;
}
if (chtype != MBSTRING_UTF8) {
f = NCONF_get_string(conf, section, UTF8_IN);
if (f == NULL)
ERR_clear_error();
else if (strcmp(f, "yes") == 0)
f = app_conf_try_string(conf, section, UTF8_IN);
if (f != NULL && strcmp(f, "yes") == 0)
chtype = MBSTRING_UTF8;
}
db_attr.unique_subject = 1;
p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT);
p = app_conf_try_string(conf, section, ENV_UNIQUE_SUBJECT);
if (p != NULL)
db_attr.unique_subject = parse_yesno(p, 1);
else
ERR_clear_error();
/*****************************************************************/
/* report status of cert with serial number given on command line */
@ -615,21 +617,14 @@ end_of_options:
if (!selfsign)
x509p = x509;
f = NCONF_get_string(conf, BASE_SECTION, ENV_PRESERVE);
if (f == NULL)
ERR_clear_error();
if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
f = app_conf_try_string(conf, BASE_SECTION, ENV_PRESERVE);
if (f != NULL && (*f == 'y' || *f == 'Y'))
preserve = 1;
f = NCONF_get_string(conf, BASE_SECTION, ENV_MSIE_HACK);
if (f == NULL)
ERR_clear_error();
if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
f = app_conf_try_string(conf, BASE_SECTION, ENV_MSIE_HACK);
if (f != NULL && (*f == 'y' || *f == 'Y'))
msie_hack = 1;
f = NCONF_get_string(conf, section, ENV_NAMEOPT);
if (f == NULL)
ERR_clear_error();
f = app_conf_try_string(conf, section, ENV_NAMEOPT);
if (f != NULL) {
if (!set_nameopt(f)) {
BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
@ -638,27 +633,21 @@ end_of_options:
default_op = 0;
}
f = NCONF_get_string(conf, section, ENV_CERTOPT);
f = app_conf_try_string(conf, section, ENV_CERTOPT);
if (f != NULL) {
if (!set_cert_ex(&certopt, f)) {
BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
goto end;
}
default_op = 0;
} else {
ERR_clear_error();
}
f = NCONF_get_string(conf, section, ENV_EXTCOPY);
f = app_conf_try_string(conf, section, ENV_EXTCOPY);
if (f != NULL) {
if (!set_ext_copy(&ext_copy, f)) {
BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
goto end;
}
} else {
ERR_clear_error();
}
/*****************************************************************/
@ -753,7 +742,7 @@ end_of_options:
if (verbose)
BIO_printf(bio_err, "Updating %s ...\n", dbfile);
i = do_updatedb(db);
i = do_updatedb(db, NULL);
if (i == -1) {
BIO_printf(bio_err, "Malloc failure\n");
goto end;
@ -786,13 +775,12 @@ end_of_options:
/* We can have sections in the ext file */
if (extensions == NULL) {
extensions = NCONF_get_string(extfile_conf, "default", "extensions");
if (extensions == NULL) {
ERR_clear_error();
extensions =
app_conf_try_string(extfile_conf, "default", "extensions");
if (extensions == NULL)
extensions = "default";
}
}
}
/*****************************************************************/
if (req || gencrl) {
@ -832,9 +820,8 @@ end_of_options:
if (email_dn == 1) {
char *tmp_email_dn = NULL;
tmp_email_dn = NCONF_get_string(conf, section, ENV_DEFAULT_EMAIL_DN);
if (tmp_email_dn == NULL)
ERR_clear_error();
tmp_email_dn =
app_conf_try_string(conf, section, ENV_DEFAULT_EMAIL_DN);
if (tmp_email_dn != NULL && strcmp(tmp_email_dn, "no") == 0)
email_dn = 0;
}
@ -847,10 +834,9 @@ end_of_options:
if (verbose)
BIO_printf(bio_err, "policy is %s\n", policy);
if (NCONF_get_string(conf, section, ENV_RAND_SERIAL) != NULL) {
if (app_conf_try_string(conf, section, ENV_RAND_SERIAL) != NULL) {
rand_ser = 1;
} else {
ERR_clear_error();
serialfile = lookup_conf(conf, section, ENV_SERIAL);
if (serialfile == NULL)
goto end;
@ -874,11 +860,8 @@ end_of_options:
* no '-extfile' option, so we look for extensions in the main
* configuration file
*/
if (extensions == NULL) {
extensions = NCONF_get_string(conf, section, ENV_EXTENSIONS);
if (extensions == NULL)
ERR_clear_error();
}
extensions = app_conf_try_string(conf, section, ENV_EXTENSIONS);
if (extensions != NULL) {
/* Check syntax of config file section */
X509V3_CTX ctx;
@ -895,40 +878,22 @@ end_of_options:
}
}
if (startdate == NULL) {
startdate = NCONF_get_string(conf, section, ENV_DEFAULT_STARTDATE);
if (startdate == NULL)
ERR_clear_error();
}
if (startdate != NULL && !ASN1_TIME_set_string_X509(NULL, startdate)) {
BIO_printf(bio_err,
"start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
goto end;
}
if (startdate == NULL)
startdate = "today";
if (enddate == NULL) {
enddate = NCONF_get_string(conf, section, ENV_DEFAULT_ENDDATE);
startdate =
app_conf_try_string(conf, section, ENV_DEFAULT_STARTDATE);
if (enddate == NULL)
ERR_clear_error();
}
if (enddate != NULL && !ASN1_TIME_set_string_X509(NULL, enddate)) {
BIO_printf(bio_err,
"end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
goto end;
}
enddate = app_conf_try_string(conf, section, ENV_DEFAULT_ENDDATE);
if (days == 0) {
if (!NCONF_get_number(conf, section, ENV_DEFAULT_DAYS, &days)) {
ERR_clear_error();
if (!app_conf_try_number(conf, section, ENV_DEFAULT_DAYS, &days))
days = 0;
}
}
if (enddate == NULL && days == 0) {
BIO_printf(bio_err, "cannot lookup how many days to certify for\n");
goto end;
}
if (days != 0 && enddate != NULL)
BIO_printf(bio_err,
"Warning: -enddate or -not_after option overriding -days option\n");
if (rand_ser) {
if ((serial = BN_new()) == NULL || !rand_serial(serial, NULL)) {
@ -1156,11 +1121,9 @@ end_of_options:
/*****************************************************************/
if (gencrl) {
int crl_v2 = 0;
if (crl_ext == NULL) {
crl_ext = NCONF_get_string(conf, section, ENV_CRLEXT);
if (crl_ext == NULL)
ERR_clear_error();
}
crl_ext = app_conf_try_string(conf, section, ENV_CRLEXT);
if (crl_ext != NULL) {
/* Check syntax of file */
X509V3_CTX ctx;
@ -1175,29 +1138,23 @@ end_of_options:
}
}
crlnumberfile = NCONF_get_string(conf, section, ENV_CRLNUMBER);
crlnumberfile = app_conf_try_string(conf, section, ENV_CRLNUMBER);
if (crlnumberfile != NULL) {
if ((crlnumber = load_serial(crlnumberfile, NULL, 0, NULL))
== NULL) {
BIO_printf(bio_err, "error while loading CRL number\n");
goto end;
}
} else {
ERR_clear_error();
}
if (!crldays && !crlhours && !crlsec) {
if (!NCONF_get_number(conf, section,
ENV_DEFAULT_CRL_DAYS, &crldays)) {
ERR_clear_error();
if (!app_conf_try_number(conf, section,
ENV_DEFAULT_CRL_DAYS, &crldays))
crldays = 0;
}
if (!NCONF_get_number(conf, section,
ENV_DEFAULT_CRL_HOURS, &crlhours)) {
ERR_clear_error();
if (!app_conf_try_number(conf, section,
ENV_DEFAULT_CRL_HOURS, &crlhours))
crlhours = 0;
}
}
if ((crl_nextupdate == NULL) &&
(crldays == 0) && (crlhours == 0) && (crlsec == 0)) {
BIO_printf(bio_err,
@ -1347,7 +1304,7 @@ end_of_options:
BIO_free_all(Sout);
BIO_free_all(out);
BIO_free_all(in);
sk_X509_pop_free(cert_sk, X509_free);
OSSL_STACK_OF_X509_free(cert_sk);
cleanse(passin);
if (free_passin)
@ -1391,7 +1348,7 @@ static int certify(X509 **xret, const char *infile, int informat,
EVP_PKEY *pktmp = NULL;
int ok = -1, i;
req = load_csr(infile, informat, "certificate request");
req = load_csr_autofmt(infile, informat, vfyopts, "certificate request");
if (req == NULL)
goto end;
if ((pktmp = X509_REQ_get0_pubkey(req)) == NULL) {
@ -1710,7 +1667,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
goto end;
}
if (!set_cert_times(ret, startdate, enddate, days))
if (!set_cert_times(ret, startdate, enddate, days, 0))
goto end;
if (enddate != NULL) {
@ -1731,7 +1688,16 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
/* Initialize the context structure */
X509V3_set_ctx(&ext_ctx, selfsign ? ret : x509,
ret, req, NULL, X509V3_CTX_REPLACE);
ret, NULL /* no need to give req, needed info is in ret */,
NULL, X509V3_CTX_REPLACE);
/* prepare fallback for AKID, but only if issuer cert equals subject cert */
if (selfsign) {
if (!X509V3_set_issuer_pkey(&ext_ctx, pkey))
goto end;
if (!cert_matches_key(ret, pkey))
BIO_printf(bio_err,
"Warning: Signature key and public key of cert do not match\n");
}
/* Lets add the extensions, if there are any */
if (ext_sect) {
@ -1868,7 +1834,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
p = "Valid";
else
p = "\ninvalid type, Database error\n";
BIO_printf(bio_err, "Type :%s\n", p);;
BIO_printf(bio_err, "Type :%s\n", p);
if (rrow[DB_type][0] == DB_TYPE_REV) {
p = rrow[DB_exp_date];
if (p == NULL)
@ -1933,7 +1899,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
!EVP_PKEY_missing_parameters(pkey))
EVP_PKEY_copy_parameters(pktmp, pkey);
if (!do_X509_sign(ret, pkey, dgst, sigopts, &ext_ctx))
if (!do_X509_sign(ret, 0, pkey, dgst, sigopts, &ext_ctx))
goto end;
/* We now just add it to the database as DB_TYPE_VAL('V') */
@ -2299,7 +2265,7 @@ static int get_certificate_status(const char *serial, CA_DB *db)
return ok;
}
static int do_updatedb(CA_DB *db)
int do_updatedb(CA_DB *db, time_t *now)
{
ASN1_TIME *a_tm = NULL;
int i, cnt = 0;
@ -2310,7 +2276,7 @@ static int do_updatedb(CA_DB *db)
return -1;
/* get actual time */
if (X509_gmtime_adj(a_tm, 0) == NULL) {
if (X509_time_adj(a_tm, 0, now) == NULL) {
ASN1_TIME_free(a_tm);
return -1;
}

View file

@ -174,10 +174,9 @@ int ciphers_main(int argc, char **argv)
/* Optional arg is cipher name. */
argv = opt_rest();
argc = opt_num_rest();
if (argc == 1)
if (opt_num_rest() == 1)
ciphers = argv[0];
else if (argc != 0)
else if (!opt_check_rest_arg(NULL))
goto opthelp;
if (convert != NULL) {

File diff suppressed because it is too large Load diff

View file

@ -66,10 +66,11 @@ typedef enum OPTION_choice {
OPT_DECRYPT, OPT_SIGN, OPT_CADES, OPT_SIGN_RECEIPT, OPT_RESIGN,
OPT_VERIFY, OPT_VERIFY_RETCODE, OPT_VERIFY_RECEIPT,
OPT_CMSOUT, OPT_DATA_OUT, OPT_DATA_CREATE, OPT_DIGEST_VERIFY,
OPT_DIGEST_CREATE, OPT_COMPRESS, OPT_UNCOMPRESS,
OPT_DIGEST, OPT_DIGEST_CREATE, OPT_COMPRESS, OPT_UNCOMPRESS,
OPT_ED_DECRYPT, OPT_ED_ENCRYPT, OPT_DEBUG_DECRYPT, OPT_TEXT,
OPT_ASCIICRLF, OPT_NOINTERN, OPT_NOVERIFY, OPT_NOCERTS,
OPT_NOATTR, OPT_NODETACH, OPT_NOSMIMECAP, OPT_BINARY, OPT_KEYID,
OPT_NOATTR, OPT_NODETACH, OPT_NOSMIMECAP, OPT_NO_SIGNING_TIME,
OPT_BINARY, OPT_KEYID,
OPT_NOSIGS, OPT_NO_CONTENT_VERIFY, OPT_NO_ATTR_VERIFY, OPT_INDEF,
OPT_NOINDEF, OPT_CRLFEOL, OPT_NOOUT, OPT_RR_PRINT,
OPT_RR_ALL, OPT_RR_FIRST, OPT_RCTFORM, OPT_CERTFILE, OPT_CAFILE,
@ -106,6 +107,7 @@ const OPTIONS cms_options[] = {
"Generate a signed receipt for a message"},
{"verify_receipt", OPT_VERIFY_RECEIPT, '<',
"Verify receipts; exit if receipt signatures do not verify"},
{"digest", OPT_DIGEST, 's', "Sign a pre-computed digest in hex notation"},
{"digest_create", OPT_DIGEST_CREATE, '-',
"Create a CMS \"DigestedData\" object"},
{"digest_verify", OPT_DIGEST_VERIFY, '-',
@ -174,7 +176,10 @@ const OPTIONS cms_options[] = {
OPT_SECTION("Signing"),
{"md", OPT_MD, 's', "Digest algorithm to use"},
{"signer", OPT_SIGNER, 's', "Signer certificate input file"},
{"certfile", OPT_CERTFILE, '<', "Other certificates file"},
{"certfile", OPT_CERTFILE, '<',
"Extra signer and intermediate CA certificates to include when signing"},
{OPT_MORE_STR, 0, 0,
"or to use as preferred signer certs and for chain building when verifying"},
{"cades", OPT_CADES, '-',
"Include signingCertificate attribute (CAdES-BES)"},
{"nodetach", OPT_NODETACH, '-', "Use opaque signing"},
@ -182,6 +187,8 @@ const OPTIONS cms_options[] = {
"Don't include signer's certificate when signing"},
{"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"},
{"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"},
{"no_signing_time", OPT_NO_SIGNING_TIME, '-',
"Omit the signing time attribute"},
{"receipt_request_all", OPT_RR_ALL, '-',
"When signing, create a receipt request for all recipients"},
{"receipt_request_first", OPT_RR_FIRST, '-',
@ -293,6 +300,9 @@ int cms_main(int argc, char **argv)
const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL;
char *certsoutfile = NULL, *digestname = NULL, *wrapname = NULL;
int noCAfile = 0, noCApath = 0, noCAstore = 0;
char *digesthex = NULL;
unsigned char *digestbin = NULL;
long digestlen = 0;
char *infile = NULL, *outfile = NULL, *rctfile = NULL;
char *passinarg = NULL, *passin = NULL, *signerfile = NULL;
char *originatorfile = NULL, *recipfile = NULL, *ciphername = NULL;
@ -314,6 +324,7 @@ int cms_main(int argc, char **argv)
if (encerts == NULL || vpm == NULL)
goto end;
opt_set_unknown_name("cipher");
prog = opt_init(argc, argv, cms_options);
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
@ -366,6 +377,9 @@ int cms_main(int argc, char **argv)
case OPT_DIGEST_CREATE:
operation = SMIME_DIGEST_CREATE;
break;
case OPT_DIGEST:
digesthex = opt_arg();
break;
case OPT_DIGEST_VERIFY:
operation = SMIME_DIGEST_VERIFY;
break;
@ -418,6 +432,9 @@ int cms_main(int argc, char **argv)
case OPT_NOSMIMECAP:
flags |= CMS_NOSMIMECAP;
break;
case OPT_NO_SIGNING_TIME:
flags |= CMS_NO_SIGNING_TIME;
break;
case OPT_BINARY:
flags |= CMS_BINARY;
break;
@ -705,17 +722,14 @@ int cms_main(int argc, char **argv)
if (!opt_md(digestname, &sign_md))
goto end;
}
if (ciphername != NULL) {
if (!opt_cipher_any(ciphername, &cipher))
goto end;
}
if (wrapname != NULL) {
if (!opt_cipher_any(wrapname, &wrap_cipher))
goto end;
}
/* Remaining args are files to process. */
argc = opt_num_rest();
argv = opt_rest();
if ((rr_allorfirst != -1 || rr_from != NULL) && rr_to == NULL) {
@ -822,15 +836,8 @@ int cms_main(int argc, char **argv)
}
if (operation == SMIME_ENCRYPT) {
if (!cipher) {
#ifndef OPENSSL_NO_DES
cipher = (EVP_CIPHER *)EVP_des_ede3_cbc();
#else
BIO_printf(bio_err, "No cipher selected\n");
goto end;
#endif
}
if (!cipher)
cipher = (EVP_CIPHER *)EVP_aes_256_cbc();
if (secret_key && !secret_keyid) {
BIO_printf(bio_err, "No secret key id\n");
goto end;
@ -894,10 +901,31 @@ int cms_main(int argc, char **argv)
goto end;
}
if (digesthex != NULL) {
if (operation != SMIME_SIGN) {
BIO_printf(bio_err,
"Cannot use -digest for non-signing operation\n");
goto end;
}
if (infile != NULL
|| (flags & CMS_DETACHED) == 0
|| (flags & CMS_STREAM) != 0) {
BIO_printf(bio_err,
"Cannot use -digest when -in, -nodetach or streaming is used\n");
goto end;
}
digestbin = OPENSSL_hexstr2buf(digesthex, &digestlen);
if (digestbin == NULL) {
BIO_printf(bio_err,
"Invalid hex value after -digest\n");
goto end;
}
} else {
in = bio_open_default(infile, 'r',
binary_files ? FORMAT_BINARY : informat);
if (in == NULL)
goto end;
}
if (operation & SMIME_IP) {
cms = load_content_info(informat, in, flags, &indata, "SMIME");
@ -919,7 +947,7 @@ int cms_main(int argc, char **argv)
ret = 5;
goto end;
}
sk_X509_pop_free(allcerts, X509_free);
OSSL_STACK_OF_X509_free(allcerts);
}
}
@ -998,7 +1026,8 @@ int cms_main(int argc, char **argv)
&& wrap_cipher != NULL) {
EVP_CIPHER_CTX *wctx;
wctx = CMS_RecipientInfo_kari_get0_ctx(ri);
EVP_EncryptInit_ex(wctx, wrap_cipher, NULL, NULL, NULL);
if (EVP_EncryptInit_ex(wctx, wrap_cipher, NULL, NULL, NULL) != 1)
goto end;
}
}
@ -1053,12 +1082,12 @@ int cms_main(int argc, char **argv)
} else if (operation & SMIME_SIGNERS) {
int i;
/*
* If detached data content we enable streaming if S/MIME output
* format.
* If detached data content and not signing pre-computed digest, we
* enable streaming if S/MIME output format.
*/
if (operation == SMIME_SIGN) {
if (flags & CMS_DETACHED) {
if ((flags & CMS_DETACHED) != 0 && digestbin == NULL) {
if (outformat == FORMAT_SMIME)
flags |= CMS_STREAM;
}
@ -1119,7 +1148,12 @@ int cms_main(int argc, char **argv)
key = NULL;
}
/* If not streaming or resigning finalize structure */
if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM)) {
if (operation == SMIME_SIGN && digestbin != NULL
&& (flags & CMS_STREAM) == 0) {
/* Use pre-computed digest instead of content */
if (!CMS_final_digest(cms, digestbin, digestlen, NULL, flags))
goto end;
} else if (operation == SMIME_SIGN && (flags & CMS_STREAM) == 0) {
if (!CMS_final(cms, in, NULL, flags))
goto end;
}
@ -1254,8 +1288,8 @@ int cms_main(int argc, char **argv)
end:
if (ret)
ERR_print_errors(bio_err);
sk_X509_pop_free(encerts, X509_free);
sk_X509_pop_free(other, X509_free);
OSSL_STACK_OF_X509_free(encerts);
OSSL_STACK_OF_X509_free(other);
X509_VERIFY_PARAM_free(vpm);
sk_OPENSSL_STRING_free(sksigners);
sk_OPENSSL_STRING_free(skkeys);
@ -1289,6 +1323,7 @@ int cms_main(int argc, char **argv)
BIO_free(in);
BIO_free(indata);
BIO_free_all(out);
OPENSSL_free(digestbin);
OPENSSL_free(passin);
NCONF_free(conf);
return ret;

View file

@ -1,5 +1,5 @@
/*
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -98,6 +98,7 @@ int crl_main(int argc, char **argv)
int hash_old = 0;
#endif
opt_set_unknown_name("digest");
prog = opt_init(argc, argv, crl_options);
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
@ -209,14 +210,11 @@ int crl_main(int argc, char **argv)
}
/* No remaining args. */
argc = opt_num_rest();
if (argc != 0)
if (!opt_check_rest_arg(NULL))
goto opthelp;
if (digestname != NULL) {
if (!opt_md(digestname, &digest))
goto opthelp;
}
x = load_crl(infile, informat, 1, "CRL");
if (x == NULL)
goto end;
@ -250,9 +248,10 @@ int crl_main(int argc, char **argv)
EVP_PKEY_free(pkey);
if (i < 0)
goto end;
if (i == 0)
if (i == 0) {
BIO_printf(bio_err, "verify failure\n");
else
goto end;
} else
BIO_printf(bio_err, "verify OK\n");
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -104,8 +104,7 @@ int crl2pkcs7_main(int argc, char **argv)
}
/* No remaining args. */
argc = opt_num_rest();
if (argc != 0)
if (!opt_check_rest_arg(NULL))
goto opthelp;
if (!nocrl) {
@ -139,7 +138,9 @@ int crl2pkcs7_main(int argc, char **argv)
if ((crl_stack = sk_X509_CRL_new_null()) == NULL)
goto end;
p7s->crl = crl_stack;
sk_X509_CRL_push(crl_stack, crl);
if (!sk_X509_CRL_push(crl_stack, crl))
goto end;
crl = NULL; /* now part of p7 for OPENSSL_freeing */
}
@ -217,7 +218,10 @@ static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile)
while (sk_X509_INFO_num(sk)) {
xi = sk_X509_INFO_shift(sk);
if (xi->x509 != NULL) {
sk_X509_push(stack, xi->x509);
if (!sk_X509_push(stack, xi->x509)) {
X509_INFO_free(xi);
goto end;
}
xi->x509 = NULL;
count++;
}

View file

@ -1,6 +1,6 @@
# This is a file that will be filled by the openssl srp routine.
# You can initialize the file with additional groups, these are
# records starting with a I followed by the g and N values and the id.
# records starting with an 'I' followed by the 'g' and 'N' values and the ID.
# The exact values ... you have to dig this out from the source of srp.c
# or srp_vfy.c
# The last value of an I is used as the default group for new users.
# The last value of an 'I' is used as the default group for new users.

View file

@ -1,5 +1,5 @@
/*
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -24,6 +24,9 @@
#undef BUFSIZE
#define BUFSIZE 1024*8
static int do_fp_oneshot_sign(BIO *out, EVP_MD_CTX *ctx, BIO *in, int sep, int binout,
EVP_PKEY *key, unsigned char *sigin, int siglen,
const char *sig_name, const char *file);
int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen,
EVP_PKEY *key, unsigned char *sigin, int siglen,
const char *sig_name, const char *md_name,
@ -93,7 +96,7 @@ const OPTIONS dgst_options[] = {
int dgst_main(int argc, char **argv)
{
BIO *in = NULL, *inp, *bmd = NULL, *out = NULL;
BIO *in = NULL, *inp = NULL, *bmd = NULL, *out = NULL;
ENGINE *e = NULL, *impl = NULL;
EVP_PKEY *sigkey = NULL;
STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL;
@ -111,12 +114,15 @@ int dgst_main(int argc, char **argv)
unsigned char *buf = NULL, *sigbuf = NULL;
int engine_impl = 0;
struct doall_dgst_digests dec;
EVP_MD_CTX *signctx = NULL;
int oneshot_sign = 0;
buf = app_malloc(BUFSIZE, "I/O buffer");
md = (EVP_MD *)EVP_get_digestbyname(argv[0]);
if (md != NULL)
digestname = argv[0];
opt_set_unknown_name("digest");
prog = opt_init(argc, argv, dgst_options);
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
@ -277,8 +283,6 @@ int dgst_main(int argc, char **argv)
}
if (keyfile != NULL) {
int type;
if (want_pub)
sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "public key");
else
@ -289,13 +293,15 @@ int dgst_main(int argc, char **argv)
*/
goto end;
}
type = EVP_PKEY_get_id(sigkey);
if (type == EVP_PKEY_ED25519 || type == EVP_PKEY_ED448) {
/*
* We implement PureEdDSA for these which doesn't have a separate
* digest, and only supports one shot.
*/
BIO_printf(bio_err, "Key type not supported for this operation\n");
{
char def_md[80];
if (EVP_PKEY_get_default_digest_name(sigkey, def_md,
sizeof(def_md)) == 2
&& strcmp(def_md, "UNDEF") == 0)
oneshot_sign = 1;
signctx = EVP_MD_CTX_new();
if (signctx == NULL)
goto end;
}
}
@ -341,7 +347,9 @@ int dgst_main(int argc, char **argv)
EVP_PKEY_CTX *pctx = NULL;
int res;
if (BIO_get_md_ctx(bmd, &mctx) <= 0) {
if (oneshot_sign) {
mctx = signctx;
} else if (BIO_get_md_ctx(bmd, &mctx) <= 0) {
BIO_printf(bio_err, "Error getting context\n");
goto end;
}
@ -378,6 +386,11 @@ int dgst_main(int argc, char **argv)
/* we use md as a filter, reading from 'in' */
else {
EVP_MD_CTX *mctx = NULL;
if (oneshot_sign) {
BIO_printf(bio_err, "Oneshot algorithms don't use a digest\n");
goto end;
}
if (BIO_get_md_ctx(bmd, &mctx) <= 0) {
BIO_printf(bio_err, "Error getting context\n");
goto end;
@ -406,6 +419,7 @@ int dgst_main(int argc, char **argv)
goto end;
}
}
if (!oneshot_sign) {
inp = BIO_push(bmd, in);
if (md == NULL) {
@ -416,9 +430,9 @@ int dgst_main(int argc, char **argv)
}
if (md != NULL)
md_name = EVP_MD_get0_name(md);
}
if (xoflen > 0) {
if (!(EVP_MD_get_flags(md) & EVP_MD_FLAG_XOF)) {
if (!EVP_MD_xof(md)) {
BIO_printf(bio_err, "Length can only be specified for XOF\n");
goto end;
}
@ -435,8 +449,12 @@ int dgst_main(int argc, char **argv)
if (argc == 0) {
BIO_set_fp(in, stdin, BIO_NOCLOSE);
ret = do_fp(out, buf, inp, separator, out_bin, xoflen, sigkey, sigbuf,
siglen, NULL, md_name, "stdin");
if (oneshot_sign)
ret = do_fp_oneshot_sign(out, signctx, in, separator, out_bin,
sigkey, sigbuf, siglen, NULL, "stdin");
else
ret = do_fp(out, buf, inp, separator, out_bin, xoflen,
sigkey, sigbuf, siglen, NULL, md_name, "stdin");
} else {
const char *sig_name = NULL;
@ -450,11 +468,18 @@ int dgst_main(int argc, char **argv)
perror(argv[i]);
ret = EXIT_FAILURE;
continue;
} else {
if (oneshot_sign) {
if (do_fp_oneshot_sign(out, signctx, in, separator, out_bin,
sigkey, sigbuf, siglen, sig_name,
argv[i]))
ret = EXIT_FAILURE;
} else {
if (do_fp(out, buf, inp, separator, out_bin, xoflen,
sigkey, sigbuf, siglen, sig_name, md_name, argv[i]))
ret = EXIT_FAILURE;
}
}
(void)BIO_reset(bmd);
}
}
@ -467,6 +492,7 @@ int dgst_main(int argc, char **argv)
BIO_free_all(out);
EVP_MD_free(md);
EVP_PKEY_free(sigkey);
EVP_MD_CTX_free(signctx);
sk_OPENSSL_STRING_free(sigopts);
sk_OPENSSL_STRING_free(macopts);
OPENSSL_free(sigbuf);
@ -543,6 +569,54 @@ static const char *newline_escape_filename(const char *file, int * backslash)
return (const char*)file_cpy;
}
static void print_out(BIO *out, unsigned char *buf, size_t len,
int sep, int binout,
const char *sig_name, const char *md_name, const char *file)
{
int i, backslash = 0;
if (binout) {
BIO_write(out, buf, len);
} else if (sep == 2) {
file = newline_escape_filename(file, &backslash);
if (backslash == 1)
BIO_puts(out, "\\");
for (i = 0; i < (int)len; i++)
BIO_printf(out, "%02x", buf[i]);
BIO_printf(out, " *%s\n", file);
OPENSSL_free((char *)file);
} else {
if (sig_name != NULL) {
BIO_puts(out, sig_name);
if (md_name != NULL)
BIO_printf(out, "-%s", md_name);
BIO_printf(out, "(%s)= ", file);
} else if (md_name != NULL) {
BIO_printf(out, "%s(%s)= ", md_name, file);
} else {
BIO_printf(out, "(%s)= ", file);
}
for (i = 0; i < (int)len; i++) {
if (sep && (i != 0))
BIO_printf(out, ":");
BIO_printf(out, "%02x", buf[i]);
}
BIO_printf(out, "\n");
}
}
static void print_verify_result(BIO *out, int i)
{
if (i > 0)
BIO_printf(out, "Verified OK\n");
else if (i == 0)
BIO_printf(out, "Verification failure\n");
else
BIO_printf(bio_err, "Error verifying data\n");
}
int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen,
EVP_PKEY *key, unsigned char *sigin, int siglen,
@ -550,7 +624,7 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen
const char *file)
{
size_t len = BUFSIZE;
int i, backslash = 0, ret = EXIT_FAILURE;
int i, ret = EXIT_FAILURE;
unsigned char *allocated_buf = NULL;
while (BIO_pending(bp) || !BIO_eof(bp)) {
@ -566,15 +640,8 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen
EVP_MD_CTX *ctx;
BIO_get_md_ctx(bp, &ctx);
i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen);
if (i > 0) {
BIO_printf(out, "Verified OK\n");
} else if (i == 0) {
BIO_printf(out, "Verification failure\n");
goto end;
} else {
BIO_printf(bio_err, "Error verifying data\n");
goto end;
}
print_verify_result(out, i);
if (i > 0)
ret = EXIT_SUCCESS;
goto end;
}
@ -616,39 +683,7 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen
if ((int)len < 0)
goto end;
}
if (binout) {
BIO_write(out, buf, len);
} else if (sep == 2) {
file = newline_escape_filename(file, &backslash);
if (backslash == 1)
BIO_puts(out, "\\");
for (i = 0; i < (int)len; i++)
BIO_printf(out, "%02x", buf[i]);
BIO_printf(out, " *%s\n", file);
OPENSSL_free((char *)file);
} else {
if (sig_name != NULL) {
BIO_puts(out, sig_name);
if (md_name != NULL)
BIO_printf(out, "-%s", md_name);
BIO_printf(out, "(%s)= ", file);
} else if (md_name != NULL) {
BIO_printf(out, "%s(%s)= ", md_name, file);
} else {
BIO_printf(out, "(%s)= ", file);
}
for (i = 0; i < (int)len; i++) {
if (sep && (i != 0))
BIO_printf(out, ":");
BIO_printf(out, "%02x", buf[i]);
}
BIO_printf(out, "\n");
}
print_out(out, buf, len, sep, binout, sig_name, md_name, file);
ret = EXIT_SUCCESS;
end:
if (allocated_buf != NULL)
@ -656,3 +691,55 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen
return ret;
}
/*
* Some new algorithms only support one shot operations.
* For these we need to buffer all input and then do the sign on the
* total buffered input. These algorithms set a NULL digest name which is
* then used inside EVP_DigestVerify() and EVP_DigestSign().
*/
static int do_fp_oneshot_sign(BIO *out, EVP_MD_CTX *ctx, BIO *in, int sep, int binout,
EVP_PKEY *key, unsigned char *sigin, int siglen,
const char *sig_name, const char *file)
{
int res, ret = EXIT_FAILURE;
size_t len = 0;
int buflen = 0;
int maxlen = 16 * 1024 * 1024;
uint8_t *buf = NULL, *sig = NULL;
buflen = bio_to_mem(&buf, maxlen, in);
if (buflen <= 0) {
BIO_printf(bio_err, "Read error in %s\n", file);
return ret;
}
if (sigin != NULL) {
res = EVP_DigestVerify(ctx, sigin, siglen, buf, buflen);
print_verify_result(out, res);
if (res > 0)
ret = EXIT_SUCCESS;
goto end;
}
if (key != NULL) {
if (EVP_DigestSign(ctx, NULL, &len, buf, buflen) != 1) {
BIO_printf(bio_err, "Error getting maximum length of signed data\n");
goto end;
}
sig = app_malloc(len, "Signature buffer");
if (EVP_DigestSign(ctx, sig, &len, buf, buflen) != 1) {
BIO_printf(bio_err, "Error signing data\n");
goto end;
}
print_out(out, sig, len, sep, binout, sig_name, NULL, file);
ret = EXIT_SUCCESS;
} else {
BIO_printf(bio_err, "key must be set for one-shot algorithms\n");
goto end;
}
end:
OPENSSL_free(sig);
OPENSSL_clear_free(buf, buflen);
return ret;
}

View file

@ -31,13 +31,14 @@
#define DEFBITS 2048
static EVP_PKEY *dsa_to_dh(EVP_PKEY *dh);
static int gendh_cb(EVP_PKEY_CTX *ctx);
static int verbose = 1;
typedef enum OPTION_choice {
OPT_COMMON,
OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT,
OPT_ENGINE, OPT_CHECK, OPT_TEXT, OPT_NOOUT,
OPT_DSAPARAM, OPT_2, OPT_3, OPT_5,
OPT_DSAPARAM, OPT_2, OPT_3, OPT_5, OPT_VERBOSE, OPT_QUIET,
OPT_R_ENUM, OPT_PROV_ENUM
} OPTION_CHOICE;
@ -67,6 +68,8 @@ const OPTIONS dhparam_options[] = {
{"2", OPT_2, '-', "Generate parameters using 2 as the generator value"},
{"3", OPT_3, '-', "Generate parameters using 3 as the generator value"},
{"5", OPT_5, '-', "Generate parameters using 5 as the generator value"},
{"verbose", OPT_VERBOSE, '-', "Verbose output"},
{"quiet", OPT_QUIET, '-', "Terse output"},
OPT_R_OPTIONS,
OPT_PROV_OPTIONS,
@ -138,6 +141,12 @@ int dhparam_main(int argc, char **argv)
case OPT_NOOUT:
noout = 1;
break;
case OPT_VERBOSE:
verbose = 1;
break;
case OPT_QUIET:
verbose = 0;
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
@ -155,7 +164,7 @@ int dhparam_main(int argc, char **argv)
if (argc == 1) {
if (!opt_int(argv[0], &num) || num <= 0)
goto opthelp;
} else if (argc != 0) {
} else if (!opt_check_rest_arg(NULL)) {
goto opthelp;
}
if (!app_RAND_load())
@ -170,10 +179,6 @@ int dhparam_main(int argc, char **argv)
goto end;
}
out = bio_open_default(outfile, 'w', outformat);
if (out == NULL)
goto end;
/* DH parameters */
if (num && !g)
g = 2;
@ -192,11 +197,13 @@ int dhparam_main(int argc, char **argv)
alg);
goto end;
}
EVP_PKEY_CTX_set_cb(ctx, gendh_cb);
EVP_PKEY_CTX_set_app_data(ctx, bio_err);
if (verbose) {
EVP_PKEY_CTX_set_cb(ctx, progress_cb);
BIO_printf(bio_err,
"Generating %s parameters, %d bit long %sprime\n",
alg, num, dsaparam ? "" : "safe ");
}
if (EVP_PKEY_paramgen_init(ctx) <= 0) {
BIO_printf(bio_err,
@ -274,7 +281,7 @@ int dhparam_main(int argc, char **argv)
* because, unlike PEM, there is no header to declare what
* the contents of the DER file are. The decoders just try
* and guess. Unfortunately with DHX key types they may guess
* wrong and think we have a DSA keytype. Therefore we try
* wrong and think we have a DSA keytype. Therefore, we try
* both DH and DHX sequentially.
*/
keytype = "DHX";
@ -311,6 +318,10 @@ int dhparam_main(int argc, char **argv)
}
}
out = bio_open_default(outfile, 'w', outformat);
if (out == NULL)
goto end;
if (text)
EVP_PKEY_print_params(out, pkey, 4, NULL);
@ -356,7 +367,7 @@ int dhparam_main(int argc, char **argv)
}
/*
* Historically we had the low level call DSA_dup_DH() to do this.
* Historically we had the low-level call DSA_dup_DH() to do this.
* That is now deprecated with no replacement. Since we still need to do this
* for backwards compatibility reasons, we do it "manually".
*/
@ -405,14 +416,3 @@ static EVP_PKEY *dsa_to_dh(EVP_PKEY *dh)
return pkey;
}
static int gendh_cb(EVP_PKEY_CTX *ctx)
{
int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
static const char symbols[] = ".+*\n";
char c = (p >= 0 && (size_t)p < sizeof(symbols) - 1) ? symbols[p] : '?';
BIO_write(b, &c, 1);
(void)BIO_flush(b);
return 1;
}

View file

@ -1,5 +1,5 @@
/*
* 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
@ -92,6 +92,7 @@ int dsa_main(int argc, char **argv)
int selection = 0;
OSSL_ENCODER_CTX *ectx = NULL;
opt_set_unknown_name("cipher");
prog = opt_init(argc, argv, dsa_options);
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
@ -161,17 +162,12 @@ int dsa_main(int argc, char **argv)
}
/* No extra args. */
argc = opt_num_rest();
if (argc != 0)
if (!opt_check_rest_arg(NULL))
goto opthelp;
if (ciphername != NULL) {
if (!opt_cipher(ciphername, &enc))
goto end;
}
private = pubin || pubout ? 0 : 1;
if (text && !pubin)
private = 1;
private = !pubin && (!pubout || text);
if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
BIO_printf(bio_err, "Error getting passwords\n");

View file

@ -11,7 +11,6 @@
#include <stdio.h>
#include <stdlib.h>
#include "apps.h"
#include <time.h>
#include <string.h>
#include "apps.h"
@ -25,17 +24,15 @@
static int verbose = 0;
static int gendsa_cb(EVP_PKEY_CTX *ctx);
typedef enum OPTION_choice {
OPT_COMMON,
OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT,
OPT_NOOUT, OPT_GENKEY, OPT_ENGINE, OPT_VERBOSE,
OPT_NOOUT, OPT_GENKEY, OPT_ENGINE, OPT_VERBOSE, OPT_QUIET,
OPT_R_ENUM, OPT_PROV_ENUM
} OPTION_CHOICE;
const OPTIONS dsaparam_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s [options] [numbits]\n"},
{OPT_HELP_STR, 1, '-', "Usage: %s [options] [numbits] [numqbits]\n"},
OPT_SECTION("General"),
{"help", OPT_HELP, '-', "Display this summary"},
@ -53,13 +50,15 @@ const OPTIONS dsaparam_options[] = {
{"text", OPT_TEXT, '-', "Print as text"},
{"noout", OPT_NOOUT, '-', "No output"},
{"verbose", OPT_VERBOSE, '-', "Verbose output"},
{"quiet", OPT_QUIET, '-', "Terse output"},
{"genkey", OPT_GENKEY, '-', "Generate a DSA key"},
OPT_R_OPTIONS,
OPT_PROV_OPTIONS,
OPT_PARAMETERS(),
{"numbits", 0, 0, "Number of bits if generating parameters (optional)"},
{"numbits", 0, 0, "Number of bits if generating parameters or key (optional)"},
{"numqbits", 0, 0, "Number of bits in the subprime parameter q if generating parameters or key (optional)"},
{NULL}
};
@ -69,7 +68,7 @@ int dsaparam_main(int argc, char **argv)
BIO *out = NULL;
EVP_PKEY *params = NULL, *pkey = NULL;
EVP_PKEY_CTX *ctx = NULL;
int numbits = -1, num = 0, genkey = 0;
int numbits = -1, numqbits = -1, num = 0, genkey = 0;
int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, noout = 0;
int ret = 1, i, text = 0, private = 0;
char *infile = NULL, *outfile = NULL, *prog;
@ -124,16 +123,24 @@ int dsaparam_main(int argc, char **argv)
case OPT_VERBOSE:
verbose = 1;
break;
case OPT_QUIET:
verbose = 0;
break;
}
}
/* Optional arg is bitsize. */
/* Optional args are bitsize and q bitsize. */
argc = opt_num_rest();
argv = opt_rest();
if (argc == 1) {
if (argc == 2) {
if (!opt_int(argv[0], &num) || num < 0)
goto opthelp;
} else if (argc != 0) {
if (!opt_int(argv[1], &numqbits) || numqbits < 0)
goto opthelp;
} else if (argc == 1) {
if (!opt_int(argv[0], &num) || num < 0)
goto opthelp;
} else if (!opt_check_rest_arg(NULL)) {
goto opthelp;
}
if (!app_RAND_load())
@ -143,10 +150,6 @@ int dsaparam_main(int argc, char **argv)
numbits = num;
private = genkey ? 1 : 0;
out = bio_open_owner(outfile, outformat, private);
if (out == NULL)
goto end;
ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(), "DSA", app_get0_propq());
if (ctx == NULL) {
BIO_printf(bio_err,
@ -160,9 +163,9 @@ int dsaparam_main(int argc, char **argv)
" Your key size is %d! Larger key size may behave not as expected.\n",
OPENSSL_DSA_MAX_MODULUS_BITS, numbits);
EVP_PKEY_CTX_set_cb(ctx, gendsa_cb);
EVP_PKEY_CTX_set_app_data(ctx, bio_err);
if (verbose) {
EVP_PKEY_CTX_set_cb(ctx, progress_cb);
BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n",
num);
BIO_printf(bio_err, "This could take some time\n");
@ -177,6 +180,13 @@ int dsaparam_main(int argc, char **argv)
"Error, DSA key generation setting bit length failed\n");
goto end;
}
if (numqbits > 0) {
if (EVP_PKEY_CTX_set_dsa_paramgen_q_bits(ctx, numqbits) <= 0) {
BIO_printf(bio_err,
"Error, DSA key generation setting subprime bit length failed\n");
goto end;
}
}
params = app_paramgen(ctx, "DSA");
} else {
params = load_keyparams(infile, informat, 1, "DSA", "DSA parameters");
@ -186,6 +196,10 @@ int dsaparam_main(int argc, char **argv)
goto end;
}
out = bio_open_owner(outfile, outformat, private);
if (out == NULL)
goto end;
if (text) {
EVP_PKEY_print_params(out, params, 0, NULL);
}
@ -237,22 +251,3 @@ int dsaparam_main(int argc, char **argv)
release_engine(e);
return ret;
}
static int gendsa_cb(EVP_PKEY_CTX *ctx)
{
static const char symbols[] = ".+*\n";
int p;
char c;
BIO *b;
if (!verbose)
return 1;
b = EVP_PKEY_CTX_get_app_data(ctx);
p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
c = (p >= 0 && (size_t)p < sizeof(symbols) - 1) ? symbols[p] : '?';
BIO_write(b, &c, 1);
(void)BIO_flush(b);
return 1;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2002-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
@ -80,6 +80,7 @@ int ec_main(int argc, char **argv)
char *point_format = NULL;
int no_public = 0;
opt_set_unknown_name("cipher");
prog = opt_init(argc, argv, ec_options);
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
@ -157,17 +158,12 @@ int ec_main(int argc, char **argv)
}
/* No extra arguments. */
argc = opt_num_rest();
if (argc != 0)
if (!opt_check_rest_arg(NULL))
goto opthelp;
if (ciphername != NULL) {
if (!opt_cipher(ciphername, &enc))
goto opthelp;
}
private = param_out || pubin || pubout ? 0 : 1;
if (text && !pubin)
private = 1;
private = !pubin && (text || (!param_out && !pubout));
if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
BIO_printf(bio_err, "Error getting passwords\n");

View file

@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2002-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@ -67,13 +67,11 @@ const OPTIONS ecparam_options[] = {
static int list_builtin_curves(BIO *out)
{
int ret = 0;
EC_builtin_curve *curves = NULL;
size_t n, crv_len = EC_get_builtin_curves(NULL, 0);
curves = app_malloc((int)sizeof(*curves) * crv_len, "list curves");
if (!EC_get_builtin_curves(curves, crv_len))
goto end;
EC_get_builtin_curves(curves, crv_len);
for (n = 0; n < crv_len; n++) {
const char *comment = curves[n].comment;
@ -87,10 +85,8 @@ static int list_builtin_curves(BIO *out)
BIO_printf(out, " %-10s: ", sname);
BIO_printf(out, "%s\n", comment);
}
ret = 1;
end:
OPENSSL_free(curves);
return ret;
return 1;
}
int ecparam_main(int argc, char **argv)
@ -186,25 +182,24 @@ int ecparam_main(int argc, char **argv)
}
/* No extra args. */
argc = opt_num_rest();
if (argc != 0)
if (!opt_check_rest_arg(NULL))
goto opthelp;
if (!app_RAND_load())
goto end;
private = genkey ? 1 : 0;
if (list_curves) {
out = bio_open_owner(outfile, outformat, private);
if (out == NULL)
goto end;
if (list_curves) {
if (list_builtin_curves(out))
ret = 0;
goto end;
}
private = genkey ? 1 : 0;
if (curve_name != NULL) {
OSSL_PARAM params[4];
OSSL_PARAM *p = params;
@ -243,9 +238,17 @@ int ecparam_main(int argc, char **argv)
goto end;
}
} else {
params_key = load_keyparams(infile, informat, 1, "EC", "EC parameters");
if (params_key == NULL || !EVP_PKEY_is_a(params_key, "EC"))
params_key = load_keyparams_suppress(infile, informat, 1, "EC",
"EC parameters", 1);
if (params_key == NULL)
params_key = load_keyparams_suppress(infile, informat, 1, "SM2",
"SM2 parameters", 1);
if (params_key == NULL) {
BIO_printf(bio_err, "Unable to load parameters from %s\n", infile);
goto end;
}
if (point_format
&& !EVP_PKEY_set_utf8_string_param(
params_key, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT,
@ -269,8 +272,12 @@ int ecparam_main(int argc, char **argv)
goto end;
}
out = bio_open_owner(outfile, outformat, private);
if (out == NULL)
goto end;
if (text
&& !EVP_PKEY_print_params(out, params_key, 0, NULL)) {
&& EVP_PKEY_print_params(out, params_key, 0, NULL) <= 0) {
BIO_printf(bio_err, "unable to print params\n");
goto end;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -49,7 +49,8 @@ typedef enum OPTION_choice {
OPT_NOPAD, OPT_SALT, OPT_NOSALT, OPT_DEBUG, OPT_UPPER_P, OPT_UPPER_A,
OPT_A, OPT_Z, OPT_BUFSIZE, OPT_K, OPT_KFILE, OPT_UPPER_K, OPT_NONE,
OPT_UPPER_S, OPT_IV, OPT_MD, OPT_ITER, OPT_PBKDF2, OPT_CIPHER,
OPT_R_ENUM, OPT_PROV_ENUM
OPT_SALTLEN, OPT_R_ENUM, OPT_PROV_ENUM,
OPT_SKEYOPT, OPT_SKEYMGMT
} OPTION_CHOICE;
const OPTIONS enc_options[] = {
@ -100,9 +101,13 @@ const OPTIONS enc_options[] = {
{OPT_MORE_STR, 0, 0,
"Use -iter to change the iteration count from " STR(PBKDF2_ITER_DEFAULT)},
{"none", OPT_NONE, '-', "Don't encrypt"},
#ifdef ZLIB
{"saltlen", OPT_SALTLEN, 'p', "Specify the PBKDF2 salt length (in bytes)"},
{OPT_MORE_STR, 0, 0, "Default: 16"},
#ifndef OPENSSL_NO_ZLIB
{"z", OPT_Z, '-', "Compress or decompress encrypted data using zlib"},
#endif
{"skeyopt", OPT_SKEYOPT, 's', "Key options as opt:value for opaque symmetric key handling"},
{"skeymgmt", OPT_SKEYMGMT, 's', "Symmetric key management name for opaque symmetric key handling"},
{"", OPT_CIPHER, '-', "Any supported cipher"},
OPT_R_OPTIONS,
@ -132,26 +137,47 @@ int enc_main(int argc, char **argv)
int base64 = 0, informat = FORMAT_BINARY, outformat = FORMAT_BINARY;
int ret = 1, inl, nopad = 0;
unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
unsigned char *buff = NULL, salt[PKCS5_SALT_LEN];
int rawkey_set = 0;
unsigned char *buff = NULL, salt[EVP_MAX_IV_LENGTH];
int saltlen = 0;
int pbkdf2 = 0;
int iter = 0;
long n;
int streamable = 1;
int wrap = 0;
struct doall_enc_ciphers dec;
#ifdef ZLIB
#ifndef OPENSSL_NO_ZLIB
int do_zlib = 0;
BIO *bzl = NULL;
#endif
int do_brotli = 0;
BIO *bbrot = NULL;
int do_zstd = 0;
BIO *bzstd = NULL;
STACK_OF(OPENSSL_STRING) *skeyopts = NULL;
const char *skeymgmt = NULL;
EVP_SKEY *skey = NULL;
EVP_SKEYMGMT *mgmt = NULL;
/* first check the command name */
if (strcmp(argv[0], "base64") == 0)
base64 = 1;
#ifdef ZLIB
#ifndef OPENSSL_NO_ZLIB
else if (strcmp(argv[0], "zlib") == 0)
do_zlib = 1;
#endif
#ifndef OPENSSL_NO_BROTLI
else if (strcmp(argv[0], "brotli") == 0)
do_brotli = 1;
#endif
#ifndef OPENSSL_NO_ZSTD
else if (strcmp(argv[0], "zstd") == 0)
do_zstd = 1;
#endif
else if (strcmp(argv[0], "enc") != 0)
ciphername = argv[0];
opt_set_unknown_name("cipher");
prog = opt_init(argc, argv, enc_options);
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
@ -219,7 +245,7 @@ int enc_main(int argc, char **argv)
base64 = 1;
break;
case OPT_Z:
#ifdef ZLIB
#ifndef OPENSSL_NO_ZLIB
do_zlib = 1;
#endif
break;
@ -278,6 +304,12 @@ int enc_main(int argc, char **argv)
iter = opt_int_arg();
pbkdf2 = 1;
break;
case OPT_SALTLEN:
if (!opt_int(opt_arg(), &saltlen))
goto opthelp;
if (saltlen > (int)sizeof(salt))
saltlen = (int)sizeof(salt);
break;
case OPT_PBKDF2:
pbkdf2 = 1;
if (iter == 0) /* do not overwrite a chosen value */
@ -286,6 +318,17 @@ int enc_main(int argc, char **argv)
case OPT_NONE:
cipher = NULL;
break;
case OPT_SKEYOPT:
if ((skeyopts == NULL &&
(skeyopts = sk_OPENSSL_STRING_new_null()) == NULL) ||
sk_OPENSSL_STRING_push(skeyopts, opt_arg()) == 0) {
BIO_printf(bio_err, "%s: out of memory\n", prog);
goto end;
}
break;
case OPT_SKEYMGMT:
skeymgmt = opt_arg();
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
@ -298,16 +341,19 @@ int enc_main(int argc, char **argv)
}
/* No extra arguments. */
argc = opt_num_rest();
if (argc != 0)
if (!opt_check_rest_arg(NULL))
goto opthelp;
if (!app_RAND_load())
goto end;
if (saltlen == 0 || pbkdf2 == 0)
saltlen = PKCS5_SALT_LEN;
/* Get the cipher name, either from progname (if set) or flag. */
if (ciphername != NULL) {
if (!opt_cipher(ciphername, &cipher))
goto opthelp;
if (cipher && (EVP_CIPHER_mode(cipher) == EVP_CIPH_WRAP_MODE)) {
wrap = 1;
streamable = 0;
}
if (digestname != NULL) {
if (!opt_md(digestname, &dgst))
@ -325,9 +371,15 @@ int enc_main(int argc, char **argv)
if (verbose)
BIO_printf(bio_err, "bufsize=%d\n", bsize);
#ifdef ZLIB
if (!do_zlib)
#ifndef OPENSSL_NO_ZLIB
if (do_zlib)
base64 = 0;
#endif
if (do_brotli)
base64 = 0;
if (do_zstd)
base64 = 0;
if (base64) {
if (enc)
outformat = FORMAT_BASE64;
@ -339,6 +391,10 @@ int enc_main(int argc, char **argv)
buff = app_malloc(EVP_ENCODE_LENGTH(bsize), "evp buffer");
if (infile == NULL) {
if (!streamable && printkey != 2) { /* if just print key and exit, it's ok */
BIO_printf(bio_err, "Unstreamable cipher mode\n");
goto end;
}
in = dup_bio_in(informat);
} else {
in = bio_open_default(infile, 'r', informat);
@ -354,7 +410,7 @@ int enc_main(int argc, char **argv)
str = pass;
}
if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) {
if ((str == NULL) && (cipher != NULL) && (hkey == NULL) && (skeyopts == NULL)) {
if (1) {
#ifndef OPENSSL_NO_UI_CONSOLE
for (;;) {
@ -399,7 +455,8 @@ int enc_main(int argc, char **argv)
rbio = in;
wbio = out;
#ifdef ZLIB
#ifndef OPENSSL_NO_COMP
# ifndef OPENSSL_NO_ZLIB
if (do_zlib) {
if ((bzl = BIO_new(BIO_f_zlib())) == NULL)
goto end;
@ -414,6 +471,33 @@ int enc_main(int argc, char **argv)
}
# endif
if (do_brotli) {
if ((bbrot = BIO_new(BIO_f_brotli())) == NULL)
goto end;
if (debug) {
BIO_set_callback_ex(bbrot, BIO_debug_callback_ex);
BIO_set_callback_arg(bbrot, (char *)bio_err);
}
if (enc)
wbio = BIO_push(bbrot, wbio);
else
rbio = BIO_push(bbrot, rbio);
}
if (do_zstd) {
if ((bzstd = BIO_new(BIO_f_zstd())) == NULL)
goto end;
if (debug) {
BIO_set_callback_ex(bzstd, BIO_debug_callback_ex);
BIO_set_callback_arg(bzstd, (char *)bio_err);
}
if (enc)
wbio = BIO_push(bzstd, wbio);
else
rbio = BIO_push(bzstd, rbio);
}
#endif
if (base64) {
if ((b64 = BIO_new(BIO_f_base64())) == NULL)
goto end;
@ -442,13 +526,13 @@ int enc_main(int argc, char **argv)
if (nosalt) {
sptr = NULL;
} else {
if (hsalt != NULL && !set_hex(hsalt, salt, sizeof(salt))) {
if (hsalt != NULL && !set_hex(hsalt, salt, saltlen)) {
BIO_printf(bio_err, "invalid hex salt value\n");
goto end;
}
if (enc) { /* encryption */
if (hsalt == NULL) {
if (RAND_bytes(salt, sizeof(salt)) <= 0) {
if (RAND_bytes(salt, saltlen) <= 0) {
BIO_printf(bio_err, "RAND_bytes failed\n");
goto end;
}
@ -461,7 +545,7 @@ int enc_main(int argc, char **argv)
sizeof(magic) - 1) != sizeof(magic) - 1
|| BIO_write(wbio,
(char *)salt,
sizeof(salt)) != sizeof(salt))) {
saltlen) != saltlen)) {
BIO_printf(bio_err, "error writing output file\n");
goto end;
}
@ -474,7 +558,7 @@ int enc_main(int argc, char **argv)
}
if (memcmp(mbuf, magic, sizeof(mbuf)) == 0) { /* file IS salted */
if (BIO_read(rbio, salt,
sizeof(salt)) != sizeof(salt)) {
saltlen) != saltlen) {
BIO_printf(bio_err, "error reading input file\n");
goto end;
}
@ -496,7 +580,8 @@ int enc_main(int argc, char **argv)
int iklen = EVP_CIPHER_get_key_length(cipher);
int ivlen = EVP_CIPHER_get_iv_length(cipher);
/* not needed if HASH_UPDATE() is fixed : */
int islen = (sptr != NULL ? sizeof(salt) : 0);
int islen = (sptr != NULL ? saltlen : 0);
if (!PKCS5_PBKDF2_HMAC(str, str_len, sptr, islen,
iter, dgst, iklen+ivlen, tmpkeyiv)) {
BIO_printf(bio_err, "PKCS5_PBKDF2_HMAC failed\n");
@ -505,6 +590,7 @@ int enc_main(int argc, char **argv)
/* split and move data back to global buffer */
memcpy(key, tmpkeyiv, iklen);
memcpy(iv, tmpkeyiv+iklen, ivlen);
rawkey_set = 1;
} else {
BIO_printf(bio_err, "*** WARNING : "
"deprecated key derivation used.\n"
@ -515,6 +601,7 @@ int enc_main(int argc, char **argv)
BIO_printf(bio_err, "EVP_BytesToKey failed\n");
goto end;
}
rawkey_set = 1;
}
/*
* zero the complete buffer or the string passed from the command
@ -527,6 +614,7 @@ int enc_main(int argc, char **argv)
}
if (hiv != NULL) {
int siz = EVP_CIPHER_get_iv_length(cipher);
if (siz == 0) {
BIO_printf(bio_err, "warning: iv not used by this cipher\n");
} else if (!set_hex(hiv, iv, siz)) {
@ -535,7 +623,8 @@ int enc_main(int argc, char **argv)
}
}
if ((hiv == NULL) && (str == NULL)
&& EVP_CIPHER_get_iv_length(cipher) != 0) {
&& EVP_CIPHER_get_iv_length(cipher) != 0
&& wrap == 0) {
/*
* No IV was explicitly set and no IV was generated.
* Hence the IV is undefined, making correct decryption impossible.
@ -550,6 +639,16 @@ int enc_main(int argc, char **argv)
}
/* wiping secret data as we no longer need it */
cleanse(hkey);
rawkey_set = 1;
}
/*
* At this moment we know whether we trying to use raw bytes as the key
* or an opaque symmetric key. We do not allow both options simultaneously.
*/
if (rawkey_set > 0 && skeyopts != NULL) {
BIO_printf(bio_err, "Either a raw key or the 'skeyopt' args must be used.\n");
goto end;
}
if ((benc = BIO_new(BIO_f_cipher())) == NULL)
@ -562,23 +661,54 @@ int enc_main(int argc, char **argv)
BIO_get_cipher_ctx(benc, &ctx);
if (!EVP_CipherInit_ex(ctx, cipher, e, NULL, NULL, enc)) {
if (wrap == 1)
EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
if (rawkey_set) {
if (!EVP_CipherInit_ex(ctx, cipher, e, key,
(hiv == NULL && wrap == 1 ? NULL : iv), enc)) {
BIO_printf(bio_err, "Error setting cipher %s\n",
EVP_CIPHER_get0_name(cipher));
ERR_print_errors(bio_err);
goto end;
}
} else {
OSSL_PARAM *params = NULL;
mgmt = EVP_SKEYMGMT_fetch(app_get0_libctx(),
skeymgmt != NULL ? skeymgmt : EVP_CIPHER_name(cipher),
app_get0_propq());
if (mgmt == NULL)
goto end;
params = app_params_new_from_opts(skeyopts,
EVP_SKEYMGMT_get0_imp_settable_params(mgmt));
if (params == NULL)
goto end;
skey = EVP_SKEY_import(app_get0_libctx(), EVP_SKEYMGMT_get0_name(mgmt),
app_get0_propq(), OSSL_SKEYMGMT_SELECT_ALL, params);
OSSL_PARAM_free(params);
if (skey == NULL) {
BIO_printf(bio_err, "Error creating opaque key object for skeymgmt %s\n",
skeymgmt ? skeymgmt : EVP_CIPHER_name(cipher));
ERR_print_errors(bio_err);
goto end;
}
if (!EVP_CipherInit_SKEY(ctx, cipher, skey,
(hiv == NULL && wrap == 1 ? NULL : iv),
EVP_CIPHER_get_iv_length(cipher), enc, NULL)) {
BIO_printf(bio_err, "Error setting an opaque key for cipher %s\n",
EVP_CIPHER_get0_name(cipher));
ERR_print_errors(bio_err);
goto end;
}
}
if (nopad)
EVP_CIPHER_CTX_set_padding(ctx, 0);
if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) {
BIO_printf(bio_err, "Error setting cipher %s\n",
EVP_CIPHER_get0_name(cipher));
ERR_print_errors(bio_err);
goto end;
}
if (debug) {
BIO_set_callback_ex(benc, BIO_debug_callback_ex);
BIO_set_callback_arg(benc, (char *)bio_err);
@ -587,7 +717,7 @@ int enc_main(int argc, char **argv)
if (printkey) {
if (!nosalt) {
printf("salt=");
for (i = 0; i < (int)sizeof(salt); i++)
for (i = 0; i < (int)saltlen; i++)
printf("%02X", salt[i]);
printf("\n");
}
@ -618,10 +748,16 @@ int enc_main(int argc, char **argv)
inl = BIO_read(rbio, (char *)buff, bsize);
if (inl <= 0)
break;
if (!streamable && !BIO_eof(rbio)) { /* do not output data */
BIO_printf(bio_err, "Unstreamable cipher mode\n");
goto end;
}
if (BIO_write(wbio, (char *)buff, inl) != inl) {
BIO_printf(bio_err, "error writing output file\n");
goto end;
}
if (!streamable)
break;
}
if (!BIO_flush(wbio)) {
if (enc)
@ -638,6 +774,9 @@ int enc_main(int argc, char **argv)
}
end:
ERR_print_errors(bio_err);
sk_OPENSSL_STRING_free(skeyopts);
EVP_SKEYMGMT_free(mgmt);
EVP_SKEY_free(skey);
OPENSSL_free(strbuf);
OPENSSL_free(buff);
BIO_free(in);
@ -646,9 +785,11 @@ int enc_main(int argc, char **argv)
BIO_free(b64);
EVP_MD_free(dgst);
EVP_CIPHER_free(cipher);
#ifdef ZLIB
#ifndef OPENSSL_NO_ZLIB
BIO_free(bzl);
#endif
BIO_free(bbrot);
BIO_free(bzstd);
release_engine(e);
OPENSSL_free(pass);
return ret;

View file

@ -251,7 +251,7 @@ static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds,
cmd = sk_OPENSSL_STRING_value(cmds, loop);
res = 1; /* assume success */
/* Check if this command has no ":arg" */
if ((arg = strstr(cmd, ":")) == NULL) {
if ((arg = strchr(cmd, ':')) == NULL) {
if (!ENGINE_ctrl_cmd_string(e, cmd, NULL, 0))
res = 0;
} else {
@ -316,7 +316,8 @@ int engine_main(int argc, char **argv)
* names, and then setup to parse the rest of the line as flags. */
prog = argv[0];
while ((argv1 = argv[1]) != NULL && *argv1 != '-') {
sk_OPENSSL_CSTRING_push(engines, argv1);
if (!sk_OPENSSL_CSTRING_push(engines, argv1))
goto end;
argc--;
argv++;
}
@ -347,7 +348,7 @@ int engine_main(int argc, char **argv)
break;
case OPT_TT:
test_avail_noise++;
/* fall thru */
/* fall through */
case OPT_T:
test_avail++;
break;
@ -372,12 +373,14 @@ int engine_main(int argc, char **argv)
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
goto end;
}
sk_OPENSSL_CSTRING_push(engines, *argv);
if (!sk_OPENSSL_CSTRING_push(engines, *argv))
goto end;
}
if (sk_OPENSSL_CSTRING_num(engines) == 0) {
for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) {
sk_OPENSSL_CSTRING_push(engines, ENGINE_get_id(e));
if (!sk_OPENSSL_CSTRING_push(engines, ENGINE_get_id(e)))
goto end;
}
}
@ -407,6 +410,9 @@ int engine_main(int argc, char **argv)
if (ENGINE_get_RSA(e) != NULL
&& !append_buf(&cap_buf, &cap_size, "RSA"))
goto end;
if (ENGINE_get_EC(e) != NULL
&& !append_buf(&cap_buf, &cap_size, "EC"))
goto end;
if (ENGINE_get_DSA(e) != NULL
&& !append_buf(&cap_buf, &cap_size, "DSA"))
goto end;

View file

@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -7,7 +7,6 @@
* https://www.openssl.org/source/license.html
*/
#include <string.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/provider.h>
@ -34,17 +33,42 @@ static int quiet = 0;
typedef enum OPTION_choice {
OPT_COMMON,
OPT_IN, OPT_OUT, OPT_MODULE,
OPT_IN, OPT_OUT, OPT_MODULE, OPT_PEDANTIC,
OPT_PROV_NAME, OPT_SECTION_NAME, OPT_MAC_NAME, OPT_MACOPT, OPT_VERIFY,
OPT_NO_LOG, OPT_CORRUPT_DESC, OPT_CORRUPT_TYPE, OPT_QUIET, OPT_CONFIG,
OPT_NO_CONDITIONAL_ERRORS,
OPT_NO_SECURITY_CHECKS,
OPT_SELF_TEST_ONLOAD
OPT_TLS_PRF_EMS_CHECK, OPT_NO_SHORT_MAC,
OPT_DISALLOW_PKCS15_PADDING, OPT_RSA_PSS_SALTLEN_CHECK,
OPT_DISALLOW_SIGNATURE_X931_PADDING,
OPT_HMAC_KEY_CHECK, OPT_KMAC_KEY_CHECK,
OPT_DISALLOW_DRGB_TRUNC_DIGEST,
OPT_SIGNATURE_DIGEST_CHECK,
OPT_HKDF_DIGEST_CHECK,
OPT_TLS13_KDF_DIGEST_CHECK,
OPT_TLS1_PRF_DIGEST_CHECK,
OPT_SSHKDF_DIGEST_CHECK,
OPT_SSKDF_DIGEST_CHECK,
OPT_X963KDF_DIGEST_CHECK,
OPT_DISALLOW_DSA_SIGN,
OPT_DISALLOW_TDES_ENCRYPT,
OPT_HKDF_KEY_CHECK,
OPT_KBKDF_KEY_CHECK,
OPT_TLS13_KDF_KEY_CHECK,
OPT_TLS1_PRF_KEY_CHECK,
OPT_SSHKDF_KEY_CHECK,
OPT_SSKDF_KEY_CHECK,
OPT_X963KDF_KEY_CHECK,
OPT_X942KDF_KEY_CHECK,
OPT_NO_PBKDF2_LOWER_BOUND_CHECK,
OPT_ECDH_COFACTOR_CHECK,
OPT_SELF_TEST_ONLOAD, OPT_SELF_TEST_ONINSTALL
} OPTION_CHOICE;
const OPTIONS fipsinstall_options[] = {
OPT_SECTION("General"),
{"help", OPT_HELP, '-', "Display this summary"},
{"pedantic", OPT_PEDANTIC, '-', "Set options for strict FIPS compliance"},
{"verify", OPT_VERIFY, '-',
"Verify a config file instead of generating one"},
{"module", OPT_MODULE, '<', "File name of the provider module"},
@ -58,14 +82,67 @@ const OPTIONS fipsinstall_options[] = {
"Disable the run-time FIPS security checks in the module"},
{"self_test_onload", OPT_SELF_TEST_ONLOAD, '-',
"Forces self tests to always run on module load"},
{"self_test_oninstall", OPT_SELF_TEST_ONINSTALL, '-',
"Forces self tests to run once on module installation"},
{"ems_check", OPT_TLS_PRF_EMS_CHECK, '-',
"Enable the run-time FIPS check for EMS during TLS1_PRF"},
{"no_short_mac", OPT_NO_SHORT_MAC, '-', "Disallow short MAC output"},
{"no_drbg_truncated_digests", OPT_DISALLOW_DRGB_TRUNC_DIGEST, '-',
"Disallow truncated digests with Hash and HMAC DRBGs"},
{"signature_digest_check", OPT_SIGNATURE_DIGEST_CHECK, '-',
"Enable checking for approved digests for signatures"},
{"hmac_key_check", OPT_HMAC_KEY_CHECK, '-', "Enable key check for HMAC"},
{"kmac_key_check", OPT_KMAC_KEY_CHECK, '-', "Enable key check for KMAC"},
{"hkdf_digest_check", OPT_HKDF_DIGEST_CHECK, '-',
"Enable digest check for HKDF"},
{"tls13_kdf_digest_check", OPT_TLS13_KDF_DIGEST_CHECK, '-',
"Enable digest check for TLS13-KDF"},
{"tls1_prf_digest_check", OPT_TLS1_PRF_DIGEST_CHECK, '-',
"Enable digest check for TLS1-PRF"},
{"sshkdf_digest_check", OPT_SSHKDF_DIGEST_CHECK, '-',
"Enable digest check for SSHKDF"},
{"sskdf_digest_check", OPT_SSKDF_DIGEST_CHECK, '-',
"Enable digest check for SSKDF"},
{"x963kdf_digest_check", OPT_X963KDF_DIGEST_CHECK, '-',
"Enable digest check for X963KDF"},
{"dsa_sign_disabled", OPT_DISALLOW_DSA_SIGN, '-',
"Disallow DSA signing"},
{"tdes_encrypt_disabled", OPT_DISALLOW_TDES_ENCRYPT, '-',
"Disallow Triple-DES encryption"},
{"rsa_pkcs15_padding_disabled", OPT_DISALLOW_PKCS15_PADDING, '-',
"Disallow PKCS#1 version 1.5 padding for RSA encryption"},
{"rsa_pss_saltlen_check", OPT_RSA_PSS_SALTLEN_CHECK, '-',
"Enable salt length check for RSA-PSS signature operations"},
{"rsa_sign_x931_disabled", OPT_DISALLOW_SIGNATURE_X931_PADDING, '-',
"Disallow X931 Padding for RSA signing"},
{"hkdf_key_check", OPT_HKDF_KEY_CHECK, '-',
"Enable key check for HKDF"},
{"kbkdf_key_check", OPT_KBKDF_KEY_CHECK, '-',
"Enable key check for KBKDF"},
{"tls13_kdf_key_check", OPT_TLS13_KDF_KEY_CHECK, '-',
"Enable key check for TLS13-KDF"},
{"tls1_prf_key_check", OPT_TLS1_PRF_KEY_CHECK, '-',
"Enable key check for TLS1-PRF"},
{"sshkdf_key_check", OPT_SSHKDF_KEY_CHECK, '-',
"Enable key check for SSHKDF"},
{"sskdf_key_check", OPT_SSKDF_KEY_CHECK, '-',
"Enable key check for SSKDF"},
{"x963kdf_key_check", OPT_X963KDF_KEY_CHECK, '-',
"Enable key check for X963KDF"},
{"x942kdf_key_check", OPT_X942KDF_KEY_CHECK, '-',
"Enable key check for X942KDF"},
{"no_pbkdf2_lower_bound_check", OPT_NO_PBKDF2_LOWER_BOUND_CHECK, '-',
"Disable lower bound check for PBKDF2"},
{"ecdh_cofactor_check", OPT_ECDH_COFACTOR_CHECK, '-',
"Enable Cofactor check for ECDH"},
OPT_SECTION("Input"),
{"in", OPT_IN, '<', "Input config file, used when verifying"},
OPT_SECTION("Output"),
{"out", OPT_OUT, '>', "Output config file, used when generating"},
{"mac_name", OPT_MAC_NAME, 's', "MAC name"},
{"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form. "
"See 'PARAMETER NAMES' in the EVP_MAC_ docs"},
{"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form."},
{OPT_MORE_STR, 0, 0, "See 'PARAMETER NAMES' in the EVP_MAC_ docs"},
{"noout", OPT_NO_LOG, '-', "Disable logging of self test events"},
{"corrupt_desc", OPT_CORRUPT_DESC, 's', "Corrupt a self test by description"},
{"corrupt_type", OPT_CORRUPT_TYPE, 's', "Corrupt a self test by type"},
@ -74,6 +151,116 @@ const OPTIONS fipsinstall_options[] = {
{NULL}
};
typedef struct {
unsigned int self_test_onload : 1;
unsigned int conditional_errors : 1;
unsigned int security_checks : 1;
unsigned int hmac_key_check : 1;
unsigned int kmac_key_check : 1;
unsigned int tls_prf_ems_check : 1;
unsigned int no_short_mac : 1;
unsigned int drgb_no_trunc_dgst : 1;
unsigned int signature_digest_check : 1;
unsigned int hkdf_digest_check : 1;
unsigned int tls13_kdf_digest_check : 1;
unsigned int tls1_prf_digest_check : 1;
unsigned int sshkdf_digest_check : 1;
unsigned int sskdf_digest_check : 1;
unsigned int x963kdf_digest_check : 1;
unsigned int dsa_sign_disabled : 1;
unsigned int tdes_encrypt_disabled : 1;
unsigned int rsa_pkcs15_padding_disabled : 1;
unsigned int rsa_pss_saltlen_check : 1;
unsigned int sign_x931_padding_disabled : 1;
unsigned int hkdf_key_check : 1;
unsigned int kbkdf_key_check : 1;
unsigned int tls13_kdf_key_check : 1;
unsigned int tls1_prf_key_check : 1;
unsigned int sshkdf_key_check : 1;
unsigned int sskdf_key_check : 1;
unsigned int x963kdf_key_check : 1;
unsigned int x942kdf_key_check : 1;
unsigned int pbkdf2_lower_bound_check : 1;
unsigned int ecdh_cofactor_check : 1;
} FIPS_OPTS;
/* Pedantic FIPS compliance */
static const FIPS_OPTS pedantic_opts = {
1, /* self_test_onload */
1, /* conditional_errors */
1, /* security_checks */
1, /* hmac_key_check */
1, /* kmac_key_check */
1, /* tls_prf_ems_check */
1, /* no_short_mac */
1, /* drgb_no_trunc_dgst */
1, /* signature_digest_check */
1, /* hkdf_digest_check */
1, /* tls13_kdf_digest_check */
1, /* tls1_prf_digest_check */
1, /* sshkdf_digest_check */
1, /* sskdf_digest_check */
1, /* x963kdf_digest_check */
1, /* dsa_sign_disabled */
1, /* tdes_encrypt_disabled */
1, /* rsa_pkcs15_padding_disabled */
1, /* rsa_pss_saltlen_check */
1, /* sign_x931_padding_disabled */
1, /* hkdf_key_check */
1, /* kbkdf_key_check */
1, /* tls13_kdf_key_check */
1, /* tls1_prf_key_check */
1, /* sshkdf_key_check */
1, /* sskdf_key_check */
1, /* x963kdf_key_check */
1, /* x942kdf_key_check */
1, /* pbkdf2_lower_bound_check */
1, /* ecdh_cofactor_check */
};
/* Default FIPS settings for backward compatibility */
static FIPS_OPTS fips_opts = {
1, /* self_test_onload */
1, /* conditional_errors */
1, /* security_checks */
0, /* hmac_key_check */
0, /* kmac_key_check */
0, /* tls_prf_ems_check */
0, /* no_short_mac */
0, /* drgb_no_trunc_dgst */
0, /* signature_digest_check */
0, /* hkdf_digest_check */
0, /* tls13_kdf_digest_check */
0, /* tls1_prf_digest_check */
0, /* sshkdf_digest_check */
0, /* sskdf_digest_check */
0, /* x963kdf_digest_check */
0, /* dsa_sign_disabled */
0, /* tdes_encrypt_disabled */
0, /* rsa_pkcs15_padding_disabled */
0, /* rsa_pss_saltlen_check */
0, /* sign_x931_padding_disabled */
0, /* hkdf_key_check */
0, /* kbkdf_key_check */
0, /* tls13_kdf_key_check */
0, /* tls1_prf_key_check */
0, /* sshkdf_key_check */
0, /* sskdf_key_check */
0, /* x963kdf_key_check */
0, /* x942kdf_key_check */
1, /* pbkdf2_lower_bound_check */
0, /* ecdh_cofactor_check */
};
static int check_non_pedantic_fips(int pedantic, const char *name)
{
if (pedantic) {
BIO_printf(bio_err, "Cannot specify -%s after -pedantic\n", name);
return 0;
}
return 1;
}
static int do_mac(EVP_MAC_CTX *ctx, unsigned char *tmp, BIO *in,
unsigned char *out, size_t *out_len)
{
@ -97,16 +284,47 @@ err:
return ret;
}
static int load_fips_prov_and_run_self_test(const char *prov_name)
static int load_fips_prov_and_run_self_test(const char *prov_name,
int *is_fips_140_2_prov)
{
int ret = 0;
OSSL_PROVIDER *prov = NULL;
OSSL_PARAM params[4], *p = params;
char *name = "", *vers = "", *build = "";
prov = OSSL_PROVIDER_load(NULL, prov_name);
if (prov == NULL) {
BIO_printf(bio_err, "Failed to load FIPS module\n");
goto end;
}
if (!quiet) {
*p++ = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_NAME,
&name, sizeof(name));
*p++ = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_VERSION,
&vers, sizeof(vers));
*p++ = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_BUILDINFO,
&build, sizeof(build));
*p = OSSL_PARAM_construct_end();
if (!OSSL_PROVIDER_get_params(prov, params)) {
BIO_printf(bio_err, "Failed to query FIPS module parameters\n");
goto end;
}
if (OSSL_PARAM_modified(params))
BIO_printf(bio_err, "\t%-10s\t%s\n", "name:", name);
if (OSSL_PARAM_modified(params + 1))
BIO_printf(bio_err, "\t%-10s\t%s\n", "version:", vers);
if (OSSL_PARAM_modified(params + 2))
BIO_printf(bio_err, "\t%-10s\t%s\n", "build:", build);
} else {
*p++ = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_VERSION,
&vers, sizeof(vers));
*p = OSSL_PARAM_construct_end();
if (!OSSL_PROVIDER_get_params(prov, params)) {
BIO_printf(bio_err, "Failed to query FIPS module parameters\n");
goto end;
}
}
*is_fips_140_2_prov = (strncmp("3.0.", vers, 4) == 0);
ret = 1;
end:
OSSL_PROVIDER_unload(prov);
@ -147,8 +365,7 @@ static int write_config_header(BIO *out, const char *prov_name,
static int write_config_fips_section(BIO *out, const char *section,
unsigned char *module_mac,
size_t module_mac_len,
int conditional_errors,
int security_checks,
const FIPS_OPTS *opts,
unsigned char *install_mac,
size_t install_mac_len)
{
@ -159,14 +376,79 @@ static int write_config_fips_section(BIO *out, const char *section,
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_VERSION,
VERSION_VAL) <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS,
conditional_errors ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS,
security_checks ? "1" : "0") <= 0
opts->conditional_errors ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_SECURITY_CHECKS,
opts->security_checks ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_HMAC_KEY_CHECK,
opts->hmac_key_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_KMAC_KEY_CHECK,
opts->kmac_key_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK,
opts->tls_prf_ems_check ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_NO_SHORT_MAC,
opts->no_short_mac ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_DRBG_TRUNC_DIGEST,
opts->drgb_no_trunc_dgst ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_SIGNATURE_DIGEST_CHECK,
opts->signature_digest_check ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_HKDF_DIGEST_CHECK,
opts->hkdf_digest_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n",
OSSL_PROV_PARAM_TLS13_KDF_DIGEST_CHECK,
opts->tls13_kdf_digest_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n",
OSSL_PROV_PARAM_TLS1_PRF_DIGEST_CHECK,
opts->tls1_prf_digest_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n",
OSSL_PROV_PARAM_SSHKDF_DIGEST_CHECK,
opts->sshkdf_digest_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_SSKDF_DIGEST_CHECK,
opts->sskdf_digest_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n",
OSSL_PROV_PARAM_X963KDF_DIGEST_CHECK,
opts->x963kdf_digest_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_DSA_SIGN_DISABLED,
opts->dsa_sign_disabled ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_TDES_ENCRYPT_DISABLED,
opts->tdes_encrypt_disabled ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n",
OSSL_PROV_PARAM_RSA_PKCS15_PAD_DISABLED,
opts->rsa_pkcs15_padding_disabled ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n",
OSSL_PROV_PARAM_RSA_PSS_SALTLEN_CHECK,
opts->rsa_pss_saltlen_check ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n",
OSSL_PROV_PARAM_RSA_SIGN_X931_PAD_DISABLED,
opts->sign_x931_padding_disabled ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_HKDF_KEY_CHECK,
opts->hkdf_key_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_KBKDF_KEY_CHECK,
opts->kbkdf_key_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n",
OSSL_PROV_PARAM_TLS13_KDF_KEY_CHECK,
opts->tls13_kdf_key_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_TLS1_PRF_KEY_CHECK,
opts->tls1_prf_key_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_SSHKDF_KEY_CHECK,
opts->sshkdf_key_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_SSKDF_KEY_CHECK,
opts->sskdf_key_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_X963KDF_KEY_CHECK,
opts->x963kdf_key_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_X942KDF_KEY_CHECK,
opts->x942kdf_key_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n",
OSSL_PROV_PARAM_PBKDF2_LOWER_BOUND_CHECK,
opts->pbkdf2_lower_bound_check ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_ECDH_COFACTOR_CHECK,
opts->ecdh_cofactor_check ? "1": "0") <= 0
|| !print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac,
module_mac_len))
goto end;
if (install_mac != NULL && install_mac_len > 0) {
if (install_mac != NULL
&& install_mac_len > 0
&& opts->self_test_onload == 0) {
if (!print_mac(out, OSSL_PROV_FIPS_PARAM_INSTALL_MAC, install_mac,
install_mac_len)
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_STATUS,
@ -182,8 +464,7 @@ static CONF *generate_config_and_load(const char *prov_name,
const char *section,
unsigned char *module_mac,
size_t module_mac_len,
int conditional_errors,
int security_checks)
const FIPS_OPTS *opts)
{
BIO *mem_bio = NULL;
CONF *conf = NULL;
@ -194,9 +475,7 @@ static CONF *generate_config_and_load(const char *prov_name,
if (!write_config_header(mem_bio, prov_name, section)
|| !write_config_fips_section(mem_bio, section,
module_mac, module_mac_len,
conditional_errors,
security_checks,
NULL, 0))
opts, NULL, 0))
goto end;
conf = app_load_config_bio(mem_bio, NULL);
@ -291,8 +570,8 @@ end:
int fipsinstall_main(int argc, char **argv)
{
int ret = 1, verify = 0, gotkey = 0, gotdigest = 0, self_test_onload = 0;
int enable_conditional_errors = 1, enable_security_checks = 1;
int ret = 1, verify = 0, gotkey = 0, gotdigest = 0, pedantic = 0;
int is_fips_140_2_prov = 0, set_selftest_onload_option = 0;
const char *section_name = "fips_sect";
const char *mac_name = "HMAC";
const char *prov_name = "fips";
@ -332,11 +611,102 @@ opthelp:
case OPT_OUT:
out_fname = opt_arg();
break;
case OPT_PEDANTIC:
fips_opts = pedantic_opts;
pedantic = 1;
break;
case OPT_NO_CONDITIONAL_ERRORS:
enable_conditional_errors = 0;
if (!check_non_pedantic_fips(pedantic, "no_conditional_errors"))
goto end;
fips_opts.conditional_errors = 0;
break;
case OPT_NO_SECURITY_CHECKS:
enable_security_checks = 0;
if (!check_non_pedantic_fips(pedantic, "no_security_checks"))
goto end;
fips_opts.security_checks = 0;
break;
case OPT_HMAC_KEY_CHECK:
fips_opts.hmac_key_check = 1;
break;
case OPT_KMAC_KEY_CHECK:
fips_opts.kmac_key_check = 1;
break;
case OPT_TLS_PRF_EMS_CHECK:
fips_opts.tls_prf_ems_check = 1;
break;
case OPT_NO_SHORT_MAC:
fips_opts.no_short_mac = 1;
break;
case OPT_DISALLOW_DRGB_TRUNC_DIGEST:
fips_opts.drgb_no_trunc_dgst = 1;
break;
case OPT_SIGNATURE_DIGEST_CHECK:
fips_opts.signature_digest_check = 1;
break;
case OPT_HKDF_DIGEST_CHECK:
fips_opts.hkdf_digest_check = 1;
break;
case OPT_TLS13_KDF_DIGEST_CHECK:
fips_opts.tls13_kdf_digest_check = 1;
break;
case OPT_TLS1_PRF_DIGEST_CHECK:
fips_opts.tls1_prf_digest_check = 1;
break;
case OPT_SSHKDF_DIGEST_CHECK:
fips_opts.sshkdf_digest_check = 1;
break;
case OPT_SSKDF_DIGEST_CHECK:
fips_opts.sskdf_digest_check = 1;
break;
case OPT_X963KDF_DIGEST_CHECK:
fips_opts.x963kdf_digest_check = 1;
break;
case OPT_DISALLOW_DSA_SIGN:
fips_opts.dsa_sign_disabled = 1;
break;
case OPT_DISALLOW_TDES_ENCRYPT:
fips_opts.tdes_encrypt_disabled = 1;
break;
case OPT_RSA_PSS_SALTLEN_CHECK:
fips_opts.rsa_pss_saltlen_check = 1;
break;
case OPT_DISALLOW_SIGNATURE_X931_PADDING:
fips_opts.sign_x931_padding_disabled = 1;
break;
case OPT_DISALLOW_PKCS15_PADDING:
fips_opts.rsa_pkcs15_padding_disabled = 1;
break;
case OPT_HKDF_KEY_CHECK:
fips_opts.hkdf_key_check = 1;
break;
case OPT_KBKDF_KEY_CHECK:
fips_opts.kbkdf_key_check = 1;
break;
case OPT_TLS13_KDF_KEY_CHECK:
fips_opts.tls13_kdf_key_check = 1;
break;
case OPT_TLS1_PRF_KEY_CHECK:
fips_opts.tls1_prf_key_check = 1;
break;
case OPT_SSHKDF_KEY_CHECK:
fips_opts.sshkdf_key_check = 1;
break;
case OPT_SSKDF_KEY_CHECK:
fips_opts.sskdf_key_check = 1;
break;
case OPT_X963KDF_KEY_CHECK:
fips_opts.x963kdf_key_check = 1;
break;
case OPT_X942KDF_KEY_CHECK:
fips_opts.x942kdf_key_check = 1;
break;
case OPT_NO_PBKDF2_LOWER_BOUND_CHECK:
if (!check_non_pedantic_fips(pedantic, "no_pbkdf2_lower_bound_check"))
goto end;
fips_opts.pbkdf2_lower_bound_check = 0;
break;
case OPT_ECDH_COFACTOR_CHECK:
fips_opts.ecdh_cofactor_check = 1;
break;
case OPT_QUIET:
quiet = 1;
@ -368,33 +738,44 @@ opthelp:
case OPT_MACOPT:
if (!sk_OPENSSL_STRING_push(opts, opt_arg()))
goto opthelp;
if (strncmp(opt_arg(), "hexkey:", 7) == 0)
if (HAS_PREFIX(opt_arg(), "hexkey:"))
gotkey = 1;
else if (strncmp(opt_arg(), "digest:", 7) == 0)
else if (HAS_PREFIX(opt_arg(), "digest:"))
gotdigest = 1;
break;
case OPT_VERIFY:
verify = 1;
break;
case OPT_SELF_TEST_ONLOAD:
self_test_onload = 1;
set_selftest_onload_option = 1;
fips_opts.self_test_onload = 1;
break;
case OPT_SELF_TEST_ONINSTALL:
if (!check_non_pedantic_fips(pedantic, "self_test_oninstall"))
goto end;
set_selftest_onload_option = 1;
fips_opts.self_test_onload = 0;
break;
}
}
/* No extra arguments. */
argc = opt_num_rest();
if (argc != 0 || (verify && in_fname == NULL))
if (!opt_check_rest_arg(NULL))
goto opthelp;
if (verify && in_fname == NULL) {
BIO_printf(bio_err, "Missing -in option for -verify\n");
goto opthelp;
}
if (parent_config != NULL) {
/* Test that a parent config can load the module */
if (verify_module_load(parent_config)) {
ret = OSSL_PROVIDER_available(NULL, prov_name) ? 0 : 1;
if (!quiet)
if (!quiet) {
BIO_printf(bio_err, "FIPS provider is %s\n",
ret == 0 ? "available" : "not available");
}
}
goto end;
}
if (module_fname == NULL)
@ -470,7 +851,7 @@ opthelp:
if (!do_mac(ctx, read_buffer, module_bio, module_mac, &module_mac_len))
goto end;
if (self_test_onload == 0) {
/* Calculate the MAC for the indicator status - it may not be used */
mem_bio = BIO_new_mem_buf((const void *)INSTALL_STATUS_VAL,
strlen(INSTALL_STATUS_VAL));
if (mem_bio == NULL) {
@ -479,27 +860,34 @@ opthelp:
}
if (!do_mac(ctx2, read_buffer, mem_bio, install_mac, &install_mac_len))
goto end;
} else {
install_mac_len = 0;
}
if (verify) {
if (fips_opts.self_test_onload == 1)
install_mac_len = 0;
if (!verify_config(in_fname, section_name, module_mac, module_mac_len,
install_mac, install_mac_len))
goto end;
if (!quiet)
BIO_printf(bio_err, "VERIFY PASSED\n");
} else {
conf = generate_config_and_load(prov_name, section_name, module_mac,
module_mac_len,
enable_conditional_errors,
enable_security_checks);
module_mac_len, &fips_opts);
if (conf == NULL)
goto end;
if (!load_fips_prov_and_run_self_test(prov_name))
if (!load_fips_prov_and_run_self_test(prov_name, &is_fips_140_2_prov))
goto end;
/*
* In OpenSSL 3.1 the code was changed so that the status indicator is
* not written out by default since this is a FIPS 140-3 requirement.
* For backwards compatibility - if the detected FIPS provider is 3.0.X
* (Which was a FIPS 140-2 validation), then the indicator status will
* be written to the config file unless 'self_test_onload' is set on the
* command line.
*/
if (set_selftest_onload_option == 0 && is_fips_140_2_prov)
fips_opts.self_test_onload = 0;
fout =
out_fname == NULL ? dup_bio_out(FORMAT_TEXT)
: bio_open_default(out_fname, 'w', FORMAT_TEXT);
@ -507,10 +895,9 @@ opthelp:
BIO_printf(bio_err, "Failed to open file\n");
goto end;
}
if (!write_config_fips_section(fout, section_name,
module_mac, module_mac_len,
enable_conditional_errors,
enable_security_checks,
module_mac, module_mac_len, &fips_opts,
install_mac, install_mac_len))
goto end;
if (!quiet)

View file

@ -24,7 +24,7 @@
typedef enum OPTION_choice {
OPT_COMMON,
OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_CIPHER, OPT_VERBOSE,
OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_CIPHER, OPT_VERBOSE, OPT_QUIET,
OPT_R_ENUM, OPT_PROV_ENUM
} OPTION_CHOICE;
@ -44,6 +44,7 @@ const OPTIONS gendsa_options[] = {
OPT_PROV_OPTIONS,
{"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"},
{"verbose", OPT_VERBOSE, '-', "Verbose output"},
{"quiet", OPT_QUIET, '-', "Terse output"},
OPT_PARAMETERS(),
{"dsaparam-file", 0, 0, "File containing DSA parameters"},
@ -62,6 +63,7 @@ int gendsa_main(int argc, char **argv)
OPTION_CHOICE o;
int ret = 1, private = 0, verbose = 0, nbits;
opt_set_unknown_name("cipher");
prog = opt_init(argc, argv, gendsa_options);
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
@ -97,23 +99,23 @@ int gendsa_main(int argc, char **argv)
case OPT_VERBOSE:
verbose = 1;
break;
case OPT_QUIET:
verbose = 0;
break;
}
}
/* One argument, the params file. */
argc = opt_num_rest();
argv = opt_rest();
if (argc != 1)
if (!opt_check_rest_arg("params file"))
goto opthelp;
argv = opt_rest();
dsaparams = argv[0];
if (!app_RAND_load())
goto end;
if (ciphername != NULL) {
if (!opt_cipher(ciphername, &enc))
goto end;
}
private = 1;
if (!app_passwd(NULL, passoutarg, NULL, &passout)) {

View file

@ -1,5 +1,5 @@
/*
* Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -15,18 +15,16 @@
#include <openssl/err.h>
#include <openssl/evp.h>
static int quiet;
static int verbose = 1;
static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e,
OSSL_LIB_CTX *libctx, const char *propq);
static int genpkey_cb(EVP_PKEY_CTX *ctx);
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_QUIET, OPT_CONFIG,
OPT_PROV_ENUM
OPT_VERBOSE, OPT_QUIET, OPT_CONFIG, OPT_OUTPUBKEY,
OPT_PROV_ENUM, OPT_R_ENUM
} OPTION_CHOICE;
const OPTIONS genpkey_options[] = {
@ -37,20 +35,23 @@ const OPTIONS genpkey_options[] = {
#endif
{"paramfile", OPT_PARAMFILE, '<', "Parameters file"},
{"algorithm", OPT_ALGORITHM, 's', "The public key algorithm"},
{"verbose", OPT_VERBOSE, '-', "Output status while generating keys"},
{"quiet", OPT_QUIET, '-', "Do not output status while generating keys"},
{"pkeyopt", OPT_PKEYOPT, 's',
"Set the public key algorithm option as opt:value"},
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,
OPT_R_OPTIONS,
/* This is deliberately last. */
{OPT_HELP_STR, 1, 1,
@ -58,14 +59,59 @@ const OPTIONS genpkey_options[] = {
{NULL}
};
static const char *param_datatype_2name(unsigned int type, int *ishex)
{
*ishex = 0;
switch (type) {
case OSSL_PARAM_INTEGER: return "int";
case OSSL_PARAM_UNSIGNED_INTEGER: return "uint";
case OSSL_PARAM_REAL: return "float";
case OSSL_PARAM_OCTET_STRING: *ishex = 1; return "string";
case OSSL_PARAM_UTF8_STRING: return "string";
default:
return NULL;
}
}
static void show_gen_pkeyopt(const char *algname, OSSL_LIB_CTX *libctx, const char *propq)
{
EVP_PKEY_CTX *ctx = NULL;
const OSSL_PARAM *params;
int i, ishex = 0;
if (algname == NULL)
return;
ctx = EVP_PKEY_CTX_new_from_name(libctx, algname, propq);
if (ctx == NULL)
return;
if (EVP_PKEY_keygen_init(ctx) <= 0)
goto cleanup;
params = EVP_PKEY_CTX_settable_params(ctx);
if (params == NULL)
goto cleanup;
BIO_printf(bio_err, "\nThe possible -pkeyopt arguments are:\n");
for (i = 0; params[i].key != NULL; ++i) {
const char *name = param_datatype_2name(params[i].data_type, &ishex);
if (name != NULL)
BIO_printf(bio_err, " %s%s:%s\n", ishex ? "hex" : "", params[i].key, name);
}
cleanup:
EVP_PKEY_CTX_free(ctx);
}
int genpkey_main(int argc, char **argv)
{
CONF *conf = NULL;
BIO *in = NULL, *out = NULL;
BIO *mem_out = NULL, *mem_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;
@ -74,6 +120,7 @@ int genpkey_main(int argc, char **argv)
OSSL_LIB_CTX *libctx = app_get0_libctx();
STACK_OF(OPENSSL_STRING) *keyopt = NULL;
opt_set_unknown_name("cipher");
prog = opt_init(argc, argv, genpkey_options);
keyopt = sk_OPENSSL_STRING_new_null();
if (keyopt == NULL)
@ -88,6 +135,7 @@ int genpkey_main(int argc, char **argv)
case OPT_HELP:
ret = 0;
opt_help(genpkey_options);
show_gen_pkeyopt(algname, libctx, app_get0_propq());
goto end;
case OPT_OUTFORM:
if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
@ -96,6 +144,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;
@ -115,7 +166,10 @@ int genpkey_main(int argc, char **argv)
goto end;
break;
case OPT_QUIET:
quiet = 1;
verbose = 0;
break;
case OPT_VERBOSE:
verbose = 1;
break;
case OPT_GENPARAM:
do_param = 1;
@ -135,14 +189,20 @@ int genpkey_main(int argc, char **argv)
if (!opt_provider(o))
goto end;
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
}
}
/* No extra arguments. */
argc = opt_num_rest();
if (argc != 0)
if (!opt_check_rest_arg(NULL))
goto opthelp;
if (!app_RAND_load())
goto end;
/* Fetch cipher, etc. */
if (paramfile != NULL) {
if (!init_keygen_file(&ctx, paramfile, e, libctx, app_get0_propq()))
@ -163,9 +223,12 @@ int genpkey_main(int argc, char **argv)
goto end;
}
}
if (ciphername != NULL)
if (!opt_cipher(ciphername, &cipher) || do_param == 1)
if (!opt_cipher(ciphername, &cipher))
goto opthelp;
if (ciphername != NULL && do_param == 1) {
BIO_printf(bio_err, "Cannot use cipher with -genparam option\n");
goto opthelp;
}
private = do_param ? 0 : 1;
@ -174,11 +237,20 @@ int genpkey_main(int argc, char **argv)
goto end;
}
out = bio_open_owner(outfile, outformat, private);
if (out == NULL)
mem_out = BIO_new(BIO_s_mem());
if (mem_out == NULL)
goto end;
BIO_set_mem_eof_return(mem_out, 0);
EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
if (outpubkeyfile != NULL) {
mem_outpubkey = BIO_new(BIO_s_mem());
if (mem_outpubkey == NULL)
goto end;
BIO_set_mem_eof_return(mem_outpubkey, 0);
}
if (verbose)
EVP_PKEY_CTX_set_cb(ctx, progress_cb);
EVP_PKEY_CTX_set_app_data(ctx, bio_err);
pkey = do_param ? app_paramgen(ctx, algname)
@ -187,13 +259,17 @@ int genpkey_main(int argc, char **argv)
goto end;
if (do_param) {
rv = PEM_write_bio_Parameters(out, pkey);
rv = PEM_write_bio_Parameters(mem_out, pkey);
} else if (outformat == FORMAT_PEM) {
assert(private);
rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, pass);
rv = PEM_write_bio_PrivateKey(mem_out, pkey, cipher, NULL, 0, NULL, pass);
if (rv > 0 && mem_outpubkey != NULL)
rv = PEM_write_bio_PUBKEY(mem_outpubkey, pkey);
} else if (outformat == FORMAT_ASN1) {
assert(private);
rv = i2d_PrivateKey_bio(out, pkey);
rv = i2d_PrivateKey_bio(mem_out, pkey);
if (rv > 0 && mem_outpubkey != NULL)
rv = i2d_PUBKEY_bio(mem_outpubkey, pkey);
} else {
BIO_printf(bio_err, "Bad format specified for key\n");
goto end;
@ -202,15 +278,15 @@ 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;
}
if (text) {
if (do_param)
rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
rv = EVP_PKEY_print_params(mem_out, pkey, 0, NULL);
else
rv = EVP_PKEY_print_private(out, pkey, 0, NULL);
rv = EVP_PKEY_print_private(mem_out, pkey, 0, NULL);
if (rv <= 0) {
BIO_puts(bio_err, "Error printing key\n");
@ -220,13 +296,27 @@ int genpkey_main(int argc, char **argv)
end:
sk_OPENSSL_STRING_free(keyopt);
if (ret != 0)
if (ret != 0) {
ERR_print_errors(bio_err);
} else {
if (mem_outpubkey != NULL) {
rv = mem_bio_to_file(mem_outpubkey, outpubkeyfile, outformat, private);
if (!rv)
BIO_printf(bio_err, "Error writing to outpubkey: '%s'. Error: %s\n",
outpubkeyfile, strerror(errno));
}
if (mem_out != NULL) {
rv = mem_bio_to_file(mem_out, outfile, outformat, private);
if (!rv)
BIO_printf(bio_err, "Error writing to outfile: '%s'. Error: %s\n",
outfile, strerror(errno));
}
}
EVP_PKEY_free(pkey);
EVP_PKEY_CTX_free(ctx);
EVP_CIPHER_free(cipher);
BIO_free_all(out);
BIO_free(in);
BIO_free_all(mem_out);
BIO_free_all(mem_outpubkey);
release_engine(e);
OPENSSL_free(pass);
NCONF_free(conf);
@ -318,27 +408,3 @@ int init_gen_str(EVP_PKEY_CTX **pctx,
}
static int genpkey_cb(EVP_PKEY_CTX *ctx)
{
char c = '*';
BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
if (quiet)
return 1;
switch (EVP_PKEY_CTX_get_keygen_info(ctx, 0)) {
case 0:
c = '.';
break;
case 1:
c = '+';
break;
case 3:
c = '\n';
break;
}
BIO_write(b, &c, 1);
(void)BIO_flush(b);
return 1;
}

View file

@ -29,15 +29,13 @@
static int verbose = 0;
static int genrsa_cb(EVP_PKEY_CTX *ctx);
typedef enum OPTION_choice {
OPT_COMMON,
#ifndef OPENSSL_NO_DEPRECATED_3_0
OPT_3,
#endif
OPT_F4, OPT_ENGINE,
OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES, OPT_VERBOSE,
OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES, OPT_VERBOSE, OPT_QUIET,
OPT_R_ENUM, OPT_PROV_ENUM, OPT_TRADITIONAL
} OPTION_CHOICE;
@ -62,6 +60,7 @@ const OPTIONS genrsa_options[] = {
{"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
{"primes", OPT_PRIMES, 'p', "Specify number of primes"},
{"verbose", OPT_VERBOSE, '-', "Verbose output"},
{"quiet", OPT_QUIET, '-', "Terse output"},
{"traditional", OPT_TRADITIONAL, '-',
"Use traditional format for private keys"},
{"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"},
@ -93,6 +92,7 @@ int genrsa_main(int argc, char **argv)
if (bn == NULL || cb == NULL)
goto end;
opt_set_unknown_name("cipher");
prog = opt_init(argc, argv, genrsa_options);
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
@ -139,6 +139,9 @@ opthelp:
case OPT_VERBOSE:
verbose = 1;
break;
case OPT_QUIET:
verbose = 0;
break;
case OPT_TRADITIONAL:
traditional = 1;
break;
@ -157,8 +160,7 @@ opthelp:
"Warning: It is not recommended to use more than %d bit for RSA keys.\n"
" Your key size is %d! Larger key size may behave not as expected.\n",
OPENSSL_RSA_MAX_MODULUS_BITS, num);
} else if (argc > 0) {
BIO_printf(bio_err, "Extra arguments given.\n");
} else if (!opt_check_rest_arg(NULL)) {
goto opthelp;
}
@ -166,10 +168,8 @@ opthelp:
goto end;
private = 1;
if (ciphername != NULL) {
if (!opt_cipher(ciphername, &enc))
goto end;
}
if (!app_passwd(NULL, passoutarg, NULL, &passout)) {
BIO_printf(bio_err, "Error getting password\n");
goto end;
@ -183,7 +183,8 @@ opthelp:
app_get0_propq()))
goto end;
EVP_PKEY_CTX_set_cb(ctx, genrsa_cb);
if (verbose)
EVP_PKEY_CTX_set_cb(ctx, progress_cb);
EVP_PKEY_CTX_set_app_data(ctx, bio_err);
if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, num) <= 0) {
@ -248,24 +249,3 @@ opthelp:
return ret;
}
static int genrsa_cb(EVP_PKEY_CTX *ctx)
{
char c = '*';
BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
if (!verbose)
return 1;
if (p == 0)
c = '.';
if (p == 1)
c = '+';
if (p == 2)
c = '*';
if (p == 3)
c = '\n';
BIO_write(b, &c, 1);
(void)BIO_flush(b);
return 1;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -10,10 +10,8 @@
#ifndef OSSL_APPS_H
# define OSSL_APPS_H
# include "e_os.h" /* struct timeval for DTLS */
# include "internal/common.h" /* for HAS_PREFIX */
# include "internal/nelem.h"
# include "internal/sockets.h" /* for openssl_fdset() */
# include "internal/cryptlib.h" /* ossl_assert() */
# include <assert.h>
# include <stdarg.h>
@ -65,6 +63,10 @@ BIO *dup_bio_err(int format);
BIO *bio_open_owner(const char *filename, int format, int private);
BIO *bio_open_default(const char *filename, char mode, int format);
BIO *bio_open_default_quiet(const char *filename, char mode, int format);
int mem_bio_to_file(BIO *in, const char *filename, int format, int private);
char *app_conf_try_string(const CONF *cnf, const char *group, const char *name);
int app_conf_try_number(const CONF *conf, const char *group, const char *name,
long *result);
CONF *app_load_config_bio(BIO *in, const char *filename);
# define app_load_config(filename) app_load_config_internal(filename, 0)
# define app_load_config_quiet(filename) app_load_config_internal(filename, 1)
@ -79,8 +81,12 @@ int has_stdin_waiting(void);
# endif
void corrupt_signature(const ASN1_STRING *signature);
/* Helpers for setting X509v3 certificate fields notBefore and notAfter */
int check_cert_time_string(const char *time, const char *desc);
int set_cert_times(X509 *x, const char *startdate, const char *enddate,
int days);
int days, int strict_compare_times);
int set_crl_lastupdate(X509_CRL *crl, const char *lastupdate);
int set_crl_nextupdate(X509_CRL *crl, const char *nextupdate,
long days, long hours, long secs);
@ -94,6 +100,9 @@ typedef struct args_st {
/* We need both wrap and the "real" function because libcrypto uses both. */
int wrap_password_callback(char *buf, int bufsiz, int verify, void *cb_data);
/* progress callback for dsaparam, dhparam, req, genpkey, etc. */
int progress_cb(EVP_PKEY_CTX *ctx);
int chopup_args(ARGS *arg, char *buf);
void dump_cert_text(BIO *out, X509 *x);
void print_name(BIO *out, const char *title, const X509_NAME *nm);
@ -111,6 +120,8 @@ char *get_passwd(const char *pass, const char *desc);
int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2);
int add_oid_section(CONF *conf);
X509_REQ *load_csr(const char *file, int format, const char *desc);
X509_REQ *load_csr_autofmt(const char *infile, int format,
STACK_OF(OPENSSL_STRING) *vfyopts, const char *desc);
X509 *load_cert_pass(const char *uri, int format, int maybe_stdin,
const char *pass, const char *desc);
# define load_cert(uri, format, desc) load_cert_pass(uri, format, 1, NULL, desc)
@ -120,6 +131,7 @@ void cleanse(char *str);
void clear_free(char *str);
EVP_PKEY *load_key(const char *uri, int format, int maybe_stdin,
const char *pass, ENGINE *e, const char *desc);
/* first try reading public key, on failure resort to loading private key */
EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin,
const char *pass, ENGINE *e, const char *desc);
EVP_PKEY *load_keyparams(const char *uri, int format, int maybe_stdin,
@ -141,15 +153,11 @@ int load_certs(const char *uri, int maybe_stdin, STACK_OF(X509) **certs,
int load_crls(const char *uri, STACK_OF(X509_CRL) **crls,
const char *pass, const char *desc);
int load_key_certs_crls(const char *uri, int format, int maybe_stdin,
const char *pass, const char *desc,
const char *pass, const char *desc, int quiet,
EVP_PKEY **ppkey, EVP_PKEY **ppubkey,
EVP_PKEY **pparams,
X509 **pcert, STACK_OF(X509) **pcerts,
X509_CRL **pcrl, STACK_OF(X509_CRL) **pcrls);
int load_key_cert_crl(const char *uri, int format, int maybe_stdin,
const char *pass, const char *desc,
EVP_PKEY **ppkey, EVP_PKEY **ppubkey,
X509 **pcert, X509_CRL **pcrl);
X509_STORE *setup_verify(const char *CAfile, int noCAfile,
const char *CApath, int noCApath,
const char *CAstore, int noCAstore);
@ -197,8 +205,7 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
# define DB_rev_date 2
# define DB_serial 3 /* index - unique */
# define DB_file 4
# define DB_name 5 /* index - unique when active and not
* disabled */
# define DB_name 5 /* index - unique when active and not disabled */
# define DB_NUMBER 6
# define DB_TYPE_REV 'R' /* Revoked */
@ -218,6 +225,8 @@ typedef struct ca_db_st {
# endif
} CA_DB;
extern int do_updatedb(CA_DB *db, time_t *now);
void app_bail_out(char *fmt, ...);
void *app_malloc(size_t sz, const char *what);
@ -252,7 +261,8 @@ int x509_req_ctrl_string(X509_REQ *x, const char *value);
int init_gen_str(EVP_PKEY_CTX **pctx,
const char *algname, ENGINE *e, int do_param,
OSSL_LIB_CTX *libctx, const char *propq);
int do_X509_sign(X509 *x, EVP_PKEY *pkey, const char *md,
int cert_matches_key(const X509 *cert, const EVP_PKEY *pkey);
int do_X509_sign(X509 *x, int force_v1, EVP_PKEY *pkey, const char *md,
STACK_OF(OPENSSL_STRING) *sigopts, X509V3_CTX *ext_ctx);
int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts);
int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const char *md,
@ -264,12 +274,11 @@ int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const char *md,
extern char *psk_key;
unsigned char *next_protos_parse(size_t *outlen, const char *in);
void print_cert_checks(BIO *bio, X509 *x,
const char *checkhost,
const char *checkemail, const char *checkip);
int check_cert_attributes(BIO *bio, X509 *x,
const char *checkhost, const char *checkemail,
const char *checkip, int print);
void store_setup_crl_download(X509_STORE *st);

View file

@ -1,5 +1,5 @@
/*
* Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright Siemens AG 2018-2020
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@ -20,11 +20,17 @@ OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx,
const char *propq);
void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx);
int ossl_cmp_mock_srv_set1_refCert(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
int ossl_cmp_mock_srv_set1_keyOut(OSSL_CMP_SRV_CTX *srv_ctx, EVP_PKEY *pkey);
int ossl_cmp_mock_srv_set1_crlOut(OSSL_CMP_SRV_CTX *srv_ctx, X509_CRL *crl);
int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
STACK_OF(X509) *chain);
int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx,
STACK_OF(X509) *caPubs);
int ossl_cmp_mock_srv_set1_newWithNew(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
int ossl_cmp_mock_srv_set1_newWithOld(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
int ossl_cmp_mock_srv_set1_oldWithNew(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status,
int fail_info, const char *text);
int ossl_cmp_mock_srv_set_sendError(OSSL_CMP_SRV_CTX *srv_ctx, int bodytype);

View file

@ -13,7 +13,7 @@
/* this is a private URI scheme */
# define ENGINE_SCHEME "org.openssl.engine"
# define ENGINE_SCHEME_COLON (ENGINE_SCHEME ":")
# define ENGINE_SCHEME_COLON ENGINE_SCHEME ":"
int setup_engine_loader(void);
void destroy_engine_loader(void);

View file

@ -29,7 +29,7 @@ typedef struct function_st {
const char *deprecated_version;
} FUNCTION;
DEFINE_LHASH_OF(FUNCTION);
DEFINE_LHASH_OF_EX(FUNCTION);
/* Structure to hold the number of columns to be displayed and the
* field width used to display them.

View file

@ -1,5 +1,5 @@
/*
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2022 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
@ -11,6 +11,7 @@
# define OSSL_HTTP_SERVER_H
# include "apps.h"
# include "log.h"
# ifndef HAVE_FORK
# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS)
@ -31,37 +32,19 @@
# define HTTP_DAEMON
# include <sys/types.h>
# include <sys/wait.h>
# include <syslog.h>
# include <signal.h>
# define MAXERRLEN 1000 /* limit error text sent to syslog to 1000 bytes */
# else
# undef LOG_DEBUG
# undef LOG_INFO
# undef LOG_WARNING
# undef LOG_ERR
# define LOG_DEBUG 7
# define LOG_INFO 6
# define LOG_WARNING 4
# define LOG_ERR 3
# endif
/*-
* Log a message to syslog if multi-threaded HTTP_DAEMON, else to bio_err
* prog: the name of the current app
* level: the severity of the message, e.g., LOG_ERR
* fmt: message with potential extra parameters like with printf()
* returns nothing
*/
void log_message(const char *prog, int level, const char *fmt, ...);
# ifndef OPENSSL_NO_SOCK
/*-
* Initialize an HTTP server by setting up its listening BIO
* Initialize an HTTP server, setting up its listening BIO
* prog: the name of the current app
* port: the port to listen on
* verbosity: the level of verbosity to use, or -1 for default: LOG_INFO
* returns a BIO for accepting requests, NULL on error
*/
BIO *http_server_init_bio(const char *prog, const char *port);
BIO *http_server_init(const char *prog, const char *port, int verbosity);
/*-
* Accept an ASN.1-formatted HTTP request
@ -72,7 +55,6 @@ BIO *http_server_init_bio(const char *prog, const char *port);
* acbio: the listening bio (typically as returned by http_server_init_bio())
* found_keep_alive: for returning flag if client requests persistent connection
* prog: the name of the current app, for diagnostics only
* port: the local port listening to, for diagnostics only
* accept_get: whether to accept GET requests (in addition to POST requests)
* timeout: connection timeout (in seconds), or 0 for none/infinite
* returns 0 in case caller should retry, then *preq == *ppath == *pcbio == NULL
@ -86,36 +68,38 @@ BIO *http_server_init_bio(const char *prog, const char *port);
int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
char **ppath, BIO **pcbio, BIO *acbio,
int *found_keep_alive,
const char *prog, const char *port,
int accept_get, int timeout);
const char *prog, int accept_get, int timeout);
/*-
* Send an ASN.1-formatted HTTP response
* prog: the name of the current app, for diagnostics only
* cbio: destination BIO (typically as returned by http_server_get_asn1_req())
* note: cbio should not do an encoding that changes the output length
* keep_alive: grant persistent connnection
* keep_alive: grant persistent connection
* content_type: string identifying the type of the response
* it: the response ASN.1 type
* resp: the response to send
* returns 1 on success, 0 on failure
*/
int http_server_send_asn1_resp(BIO *cbio, int keep_alive,
int http_server_send_asn1_resp(const char *prog, BIO *cbio, int keep_alive,
const char *content_type,
const ASN1_ITEM *it, const ASN1_VALUE *resp);
/*-
* Send a trivial HTTP response, typically to report an error or OK
* prog: the name of the current app, for diagnostics only
* cbio: destination BIO (typically as returned by http_server_get_asn1_req())
* status: the status code to send
* reason: the corresponding human-readable string
* returns 1 on success, 0 on failure
*/
int http_server_send_status(BIO *cbio, int status, const char *reason);
int http_server_send_status(const char *prog, BIO *cbio,
int status, const char *reason);
# endif
# ifdef HTTP_DAEMON
extern int multi;
extern int n_responders;
extern int acfd;
void socket_timeout(int signum);

50
deps/openssl/openssl/apps/include/log.h vendored Normal file
View file

@ -0,0 +1,50 @@
/*
* Copyright 1995-2022 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
*/
#ifndef OSSL_APPS_LOG_H
# define OSSL_APPS_LOG_H
# include <openssl/bio.h>
# if !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_WINDOWS) \
&& !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_POSIX_IO)
# include <syslog.h>
# else
# define LOG_EMERG 0
# define LOG_ALERT 1
# define LOG_CRIT 2
# define LOG_ERR 3
# define LOG_WARNING 4
# define LOG_NOTICE 5
# define LOG_INFO 6
# define LOG_DEBUG 7
# endif
# undef LOG_TRACE
# define LOG_TRACE (LOG_DEBUG + 1)
int log_set_verbosity(const char *prog, int level);
int log_get_verbosity(void);
/*-
* Output a message using the trace API with the given category
* if the category is >= 0 and tracing is enabled.
* Log the message to syslog if multi-threaded HTTP_DAEMON, else to bio_err
* if the verbosity is sufficient for the given level of severity.
* Yet cannot do both types of output in strict ANSI mode.
* category: trace category as defined in trace.h, or -1
* prog: the name of the current app, or NULL
* level: the severity of the message, e.g., LOG_ERR
* fmt: message format, which should not include a trailing newline
* ...: potential extra parameters like with printf()
* returns nothing
*/
void trace_log_message(int category,
const char *prog, int level, const char *fmt, ...);
#endif /* OSSL_APPS_LOG_H */

View file

@ -1,5 +1,5 @@
/*
* Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -157,13 +157,18 @@
OPT_S_NOTLS1_3, OPT_S_BUGS, OPT_S_NO_COMP, OPT_S_NOTICKET, \
OPT_S_SERVERPREF, OPT_S_LEGACYRENEG, OPT_S_CLIENTRENEG, \
OPT_S_LEGACYCONN, \
OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, OPT_S_ALLOW_NO_DHE_KEX, \
OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, \
OPT_S_ALLOW_NO_DHE_KEX, OPT_S_PREFER_NO_DHE_KEX, \
OPT_S_PRIORITIZE_CHACHA, \
OPT_S_STRICT, OPT_S_SIGALGS, OPT_S_CLIENTSIGALGS, OPT_S_GROUPS, \
OPT_S_CURVES, OPT_S_NAMEDCURVE, OPT_S_CIPHER, OPT_S_CIPHERSUITES, \
OPT_S_RECORD_PADDING, OPT_S_DEBUGBROKE, OPT_S_COMP, \
OPT_S_MINPROTO, OPT_S_MAXPROTO, \
OPT_S_NO_RENEGOTIATION, OPT_S_NO_MIDDLEBOX, OPT_S_NO_ETM, OPT_S__LAST
OPT_S_NO_RENEGOTIATION, OPT_S_NO_MIDDLEBOX, OPT_S_NO_ETM, \
OPT_S_NO_EMS, \
OPT_S_NO_TX_CERT_COMP, \
OPT_S_NO_RX_CERT_COMP, \
OPT_S__LAST
# define OPT_S_OPTIONS \
OPT_SECTION("TLS/SSL"), \
@ -175,6 +180,8 @@
{"bugs", OPT_S_BUGS, '-', "Turn on SSL bug compatibility"}, \
{"no_comp", OPT_S_NO_COMP, '-', "Disable SSL/TLS compression (default)" }, \
{"comp", OPT_S_COMP, '-', "Use SSL/TLS-level compression" }, \
{"no_tx_cert_comp", OPT_S_NO_TX_CERT_COMP, '-', "Disable sending TLSv1.3 compressed certificates" }, \
{"no_rx_cert_comp", OPT_S_NO_RX_CERT_COMP, '-', "Disable receiving TLSv1.3 compressed certificates" }, \
{"no_ticket", OPT_S_NOTICKET, '-', \
"Disable use of TLS session tickets"}, \
{"serverpref", OPT_S_SERVERPREF, '-', "Use server's cipher preferences"}, \
@ -192,6 +199,8 @@
"Disallow initial connection to servers that don't support RI"}, \
{"allow_no_dhe_kex", OPT_S_ALLOW_NO_DHE_KEX, '-', \
"In TLSv1.3 allow non-(ec)dhe based key exchange on resumption"}, \
{"prefer_no_dhe_kex", OPT_S_PREFER_NO_DHE_KEX, '-', \
"In TLSv1.3 prefer non-(ec)dhe over (ec)dhe-based key exchange on resumption"}, \
{"prioritize_chacha", OPT_S_PRIORITIZE_CHACHA, '-', \
"Prioritize ChaCha ciphers when preferred by clients"}, \
{"strict", OPT_S_STRICT, '-', \
@ -218,7 +227,9 @@
{"no_middlebox", OPT_S_NO_MIDDLEBOX, '-', \
"Disable TLSv1.3 middlebox compat mode" }, \
{"no_etm", OPT_S_NO_ETM, '-', \
"Disable Encrypt-then-Mac extension"}
"Disable Encrypt-then-Mac extension"}, \
{"no_ems", OPT_S_NO_EMS, '-', \
"Disable Extended master secret extension"}
# define OPT_S_CASES \
OPT_S__FIRST: case OPT_S__LAST: break; \
@ -230,6 +241,8 @@
case OPT_S_BUGS: \
case OPT_S_NO_COMP: \
case OPT_S_COMP: \
case OPT_S_NO_TX_CERT_COMP: \
case OPT_S_NO_RX_CERT_COMP: \
case OPT_S_NOTICKET: \
case OPT_S_SERVERPREF: \
case OPT_S_LEGACYRENEG: \
@ -238,6 +251,7 @@
case OPT_S_ONRESUMP: \
case OPT_S_NOLEGACYCONN: \
case OPT_S_ALLOW_NO_DHE_KEX: \
case OPT_S_PREFER_NO_DHE_KEX: \
case OPT_S_PRIORITIZE_CHACHA: \
case OPT_S_STRICT: \
case OPT_S_SIGALGS: \
@ -253,7 +267,8 @@
case OPT_S_MAXPROTO: \
case OPT_S_DEBUGBROKE: \
case OPT_S_NO_MIDDLEBOX: \
case OPT_S_NO_ETM
case OPT_S_NO_ETM: \
case OPT_S_NO_EMS
#define IS_NO_PROT_FLAG(o) \
(o == OPT_S_NOSSL3 || o == OPT_S_NOTLS1 || o == OPT_S_NOTLS1_1 \
@ -280,6 +295,7 @@
# define OPT_PROV_ENUM \
OPT_PROV__FIRST=1600, \
OPT_PROV_PROVIDER, OPT_PROV_PROVIDER_PATH, OPT_PROV_PROPQUERY, \
OPT_PROV_PARAM, \
OPT_PROV__LAST
# define OPT_CONFIG_OPTION \
@ -289,12 +305,14 @@
OPT_SECTION("Provider"), \
{ "provider-path", OPT_PROV_PROVIDER_PATH, 's', "Provider load path (must be before 'provider' argument if required)" }, \
{ "provider", OPT_PROV_PROVIDER, 's', "Provider to load (can be specified multiple times)" }, \
{ "provparam", OPT_PROV_PARAM, 's', "Set a provider key-value parameter" }, \
{ "propquery", OPT_PROV_PROPQUERY, 's', "Property query used when fetching algorithms" }
# define OPT_PROV_CASES \
OPT_PROV__FIRST: case OPT_PROV__LAST: break; \
case OPT_PROV_PROVIDER: \
case OPT_PROV_PROVIDER_PATH: \
case OPT_PROV_PARAM: \
case OPT_PROV_PROPQUERY
/*
@ -308,11 +326,28 @@ extern const char OPT_PARAM_STR[];
typedef struct options_st {
const char *name;
int retval;
/*
* value type: - no value (also the value zero), n number, p positive
* number, u unsigned, l long, s string, < input file, > output file,
* f any format, F der/pem format, E der/pem/engine format identifier.
* l, n and u include zero; p does not.
/*-
* value type:
*
* '-' no value (also the value zero)
* 'n' number (type 'int')
* 'p' positive number (type 'int')
* 'u' unsigned number (type 'unsigned long')
* 'l' number (type 'unsigned long')
* 'M' number (type 'intmax_t')
* 'U' unsigned number (type 'uintmax_t')
* 's' string
* '<' input file
* '>' output file
* '/' directory
* 'f' any format [OPT_FMT_ANY]
* 'F' der/pem format [OPT_FMT_PEMDER]
* 'A' any ASN1, der/pem/b64 format [OPT_FMT_ASN1]
* 'E' der/pem/engine format [OPT_FMT_PDE]
* 'c' pem/der/smime format [OPT_FMT_PDS]
*
* The 'l', 'n' and 'u' value types include the values zero,
* the 'p' value type does not.
*/
int valtype;
const char *helpstr;
@ -332,20 +367,25 @@ typedef struct string_int_pair_st {
} OPT_PAIR, STRINT_PAIR;
/* Flags to pass into opt_format; see FORMAT_xxx, below. */
# define OPT_FMT_PEMDER (1L << 1)
# define OPT_FMT_PKCS12 (1L << 2)
# define OPT_FMT_SMIME (1L << 3)
# define OPT_FMT_ENGINE (1L << 4)
# define OPT_FMT_MSBLOB (1L << 5)
/* (1L << 6) was OPT_FMT_NETSCAPE, but wasn't used */
# define OPT_FMT_NSS (1L << 7)
# define OPT_FMT_TEXT (1L << 8)
# define OPT_FMT_HTTP (1L << 9)
# define OPT_FMT_PVK (1L << 10)
# define OPT_FMT_PEM (1L << 1)
# define OPT_FMT_DER (1L << 2)
# define OPT_FMT_B64 (1L << 3)
# define OPT_FMT_PKCS12 (1L << 4)
# define OPT_FMT_SMIME (1L << 5)
# define OPT_FMT_ENGINE (1L << 6)
# define OPT_FMT_MSBLOB (1L << 7)
# define OPT_FMT_NSS (1L << 8)
# define OPT_FMT_TEXT (1L << 9)
# define OPT_FMT_HTTP (1L << 10)
# define OPT_FMT_PVK (1L << 11)
# define OPT_FMT_PEMDER (OPT_FMT_PEM | OPT_FMT_DER)
# define OPT_FMT_ASN1 (OPT_FMT_PEM | OPT_FMT_DER | OPT_FMT_B64)
# define OPT_FMT_PDE (OPT_FMT_PEMDER | OPT_FMT_ENGINE)
# define OPT_FMT_PDS (OPT_FMT_PEMDER | OPT_FMT_SMIME)
# define OPT_FMT_ANY ( \
OPT_FMT_PEMDER | OPT_FMT_PKCS12 | OPT_FMT_SMIME | \
OPT_FMT_PEM | OPT_FMT_DER | OPT_FMT_B64 | \
OPT_FMT_PKCS12 | OPT_FMT_SMIME | \
OPT_FMT_ENGINE | OPT_FMT_MSBLOB | OPT_FMT_NSS | \
OPT_FMT_TEXT | OPT_FMT_HTTP | OPT_FMT_PVK)
@ -365,13 +405,16 @@ int opt_next(void);
char *opt_flag(void);
char *opt_arg(void);
char *opt_unknown(void);
void reset_unknown(void);
int opt_cipher(const char *name, EVP_CIPHER **cipherp);
int opt_cipher_any(const char *name, EVP_CIPHER **cipherp);
int opt_cipher_silent(const char *name, EVP_CIPHER **cipherp);
int opt_check_md(const char *name);
int opt_md(const char *name, EVP_MD **mdp);
int opt_md_silent(const char *name, EVP_MD **mdp);
int opt_int(const char *arg, int *result);
void opt_set_unknown_name(const char *name);
int opt_int_arg(void);
int opt_long(const char *arg, long *result);
int opt_ulong(const char *arg, unsigned long *result);
@ -392,6 +435,7 @@ int opt_provider_option_given(void);
char **opt_rest(void);
int opt_num_rest(void);
int opt_check_rest_arg(const char *expected);
/* Returns non-zero if legacy paths are still available */
int opt_legacy_okay(void);

View file

@ -1,5 +1,5 @@
/*
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -16,7 +16,7 @@
/*
* VMS C only for now, implemented in vms_decc_init.c
* If other C compilers forget to terminate argv with NULL, this function
* can be re-used.
* can be reused.
*/
char **copy_argv(int *argc, char *argv[]);
# endif

View file

@ -1,5 +1,5 @@
/*
* 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
@ -15,12 +15,16 @@
#define PORT "4433"
#define PROTOCOL "tcp"
#define SSL_VERSION_ALLOWS_RENEGOTIATION(s) \
(SSL_is_dtls(s) || (SSL_version(s) < TLS1_3_VERSION))
typedef int (*do_server_cb)(int s, int stype, int prot, unsigned char *context);
void get_sock_info_address(int asock, char **hostname, char **service);
int report_server_accept(BIO *out, int asock, int with_address, int with_pid);
int do_server(int *accept_sock, const char *host, const char *port,
int family, int type, int protocol, do_server_cb cb,
unsigned char *context, int naccept, BIO *bio_s_out);
unsigned char *context, int naccept, BIO *bio_s_out,
int tfo);
int verify_callback(int ok, X509_STORE_CTX *ctx);
int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
@ -32,7 +36,8 @@ int ssl_print_groups(BIO *out, SSL *s, int noshared);
int ssl_print_tmp_key(BIO *out, SSL *s);
int init_client(int *sock, const char *host, const char *port,
const char *bindhost, const char *bindport,
int family, int type, int protocol);
int family, int type, int protocol, int tfo, int doconn,
BIO_ADDR **ba_ret);
int should_retry(int i);
void do_ssl_shutdown(SSL *ssl);
@ -79,6 +84,7 @@ int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath,
void ssl_ctx_security_debug(SSL_CTX *ctx, int verbose);
int set_keylog_file(SSL_CTX *ctx, const char *keylog_file);
void print_ca_names(BIO *bio, SSL *s);
void ssl_print_secure_renegotiation_notes(BIO *bio, SSL *s);
#ifndef OPENSSL_NO_SRP
/* The client side SRP context that we pass to all SRP related callbacks */

View file

@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -14,7 +14,7 @@
typedef enum OPTION_choice {
OPT_COMMON,
OPT_CONFIGDIR, OPT_ENGINESDIR, OPT_MODULESDIR, OPT_DSOEXT, OPT_DIRNAMESEP,
OPT_LISTSEP, OPT_SEEDS, OPT_CPUSETTINGS
OPT_LISTSEP, OPT_SEEDS, OPT_CPUSETTINGS, OPT_WINDOWSCONTEXT
} OPTION_CHOICE;
const OPTIONS info_options[] = {
@ -32,6 +32,7 @@ const OPTIONS info_options[] = {
{"listsep", OPT_LISTSEP, '-', "List separator character"},
{"seeds", OPT_SEEDS, '-', "Seed sources"},
{"cpusettings", OPT_CPUSETTINGS, '-', "CPU settings info"},
{"windowscontext", OPT_WINDOWSCONTEXT, '-', "Windows install context"},
{NULL}
};
@ -40,6 +41,7 @@ int info_main(int argc, char **argv)
int ret = 1, dirty = 0, type = 0;
char *prog;
OPTION_CHOICE o;
const char *typedata;
prog = opt_init(argc, argv, info_options);
while ((o = opt_next()) != OPT_EOF) {
@ -84,9 +86,13 @@ opthelp:
type = OPENSSL_INFO_CPU_SETTINGS;
dirty++;
break;
case OPT_WINDOWSCONTEXT:
type = OPENSSL_INFO_WINDOWS_CONTEXT;
dirty++;
break;
}
}
if (opt_num_rest() != 0)
if (!opt_check_rest_arg(NULL))
goto opthelp;
if (dirty > 1) {
BIO_printf(bio_err, "%s: Only one item allowed\n", prog);
@ -97,7 +103,8 @@ opthelp:
goto opthelp;
}
BIO_printf(bio_out, "%s\n", OPENSSL_info(type));
typedata = OPENSSL_info(type);
BIO_printf(bio_out, "%s\n", typedata == NULL ? "Undefined" : typedata);
ret = 0;
end:
return ret;

View file

@ -1,5 +1,5 @@
/*
* Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -8,6 +8,7 @@
*/
#include "apps.h"
#include <ctype.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/provider.h>
@ -65,6 +66,78 @@ static int opt_provider_path(const char *path)
return OSSL_PROVIDER_set_default_search_path(app_get0_libctx(), path);
}
struct prov_param_st {
char *name;
char *key;
char *val;
int found;
};
static int set_prov_param(OSSL_PROVIDER *prov, void *vp)
{
struct prov_param_st *p = (struct prov_param_st *)vp;
if (p->name != NULL && strcmp(OSSL_PROVIDER_get0_name(prov), p->name) != 0)
return 1;
p->found = 1;
return OSSL_PROVIDER_add_conf_parameter(prov, p->key, p->val);
}
static int opt_provider_param(const char *arg)
{
struct prov_param_st p;
char *copy, *tmp;
int ret = 0;
if ((copy = OPENSSL_strdup(arg)) == NULL
|| (p.val = strchr(copy, '=')) == NULL) {
opt_printf_stderr("%s: malformed '-provparam' option value: '%s'\n",
opt_getprog(), arg);
goto end;
}
/* Drop whitespace on both sides of the '=' sign */
*(tmp = p.val++) = '\0';
while (tmp > copy && isspace(_UC(*--tmp)))
*tmp = '\0';
while (isspace(_UC(*p.val)))
++p.val;
/*
* Split the key on ':', to get the optional provider, empty or missing
* means all.
*/
if ((p.key = strchr(copy, ':')) != NULL) {
*p.key++ = '\0';
p.name = *copy != '\0' ? copy : NULL;
} else {
p.name = NULL;
p.key = copy;
}
/* The key must not be empty */
if (*p.key == '\0') {
opt_printf_stderr("%s: malformed '-provparam' option value: '%s'\n",
opt_getprog(), arg);
goto end;
}
p.found = 0;
ret = OSSL_PROVIDER_do_all(app_get0_libctx(), set_prov_param, (void *)&p);
if (ret == 0) {
opt_printf_stderr("%s: Error setting provider '%s' parameter '%s'\n",
opt_getprog(), p.name, p.key);
} else if (p.found == 0) {
opt_printf_stderr("%s: No provider named '%s' is loaded\n",
opt_getprog(), p.name);
ret = 0;
}
end:
OPENSSL_free(copy);
return ret;
}
int opt_provider(int opt)
{
const int given = provider_option_given;
@ -78,6 +151,8 @@ int opt_provider(int opt)
return app_provider_load(app_get0_libctx(), opt_arg());
case OPT_PROV_PROVIDER_PATH:
return opt_provider_path(opt_arg());
case OPT_PROV_PARAM:
return opt_provider_param(opt_arg());
case OPT_PROV_PROPQUERY:
return app_set_propq(opt_arg());
}

View file

@ -1,5 +1,5 @@
/*
* 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
@ -7,6 +7,7 @@
* https://www.openssl.org/source/license.html
*/
#include "internal/e_os.h" /* LIST_SEPARATOR_CHAR */
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/err.h>
@ -18,12 +19,10 @@ static STACK_OF(OPENSSL_STRING) *randfiles;
void app_RAND_load_conf(CONF *c, const char *section)
{
const char *randfile = NCONF_get_string(c, section, "RANDFILE");
const char *randfile = app_conf_try_string(c, section, "RANDFILE");
if (randfile == NULL) {
ERR_clear_error();
if (randfile == NULL)
return;
}
if (RAND_load_file(randfile, -1) < 0) {
BIO_printf(bio_err, "Can't load %s into RNG\n", randfile);
ERR_print_errors(bio_err);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,25 @@
/*
* Copyright 2022 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 "opt.h"
#include <openssl/ui.h>
#include "apps_ui.h"
/* This function is defined here due to visibility of bio_err */
int opt_printf_stderr(const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = BIO_vprintf(bio_err, fmt, ap);
va_end(ap);
return ret;
}

View file

@ -8,9 +8,9 @@ IF[{- $config{target} =~ /^vms-/ -}]
ENDIF
# Source for libapps
$LIBAPPSSRC=apps.c apps_ui.c opt.c fmt.c s_cb.c s_socket.c app_rand.c \
$LIBAPPSSRC=apps.c apps_ui.c log.c opt.c fmt.c s_cb.c s_socket.c app_rand.c \
columns.c app_params.c names.c app_provider.c app_x509.c http_server.c \
engine.c engine_loader.c app_libctx.c
engine.c engine_loader.c app_libctx.c apps_opt_printf.c
IF[{- !$disabled{apps} -}]
LIBS{noinst}=../libapps.a

View file

@ -1,5 +1,5 @@
/*
* Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright Siemens AG 2018-2020
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@ -16,30 +16,35 @@
#include <openssl/cmperr.h>
/* the context for the CMP mock server */
typedef struct
{
typedef struct {
X509 *refCert; /* cert to expect for oldCertID in kur/rr msg */
X509 *certOut; /* certificate to be returned in cp/ip/kup msg */
EVP_PKEY *keyOut; /* Private key to be returned for central keygen */
X509_CRL *crlOut; /* CRL to be returned in genp for crls */
STACK_OF(X509) *chainOut; /* chain of certOut to add to extraCerts field */
STACK_OF(X509) *caPubsOut; /* certs to return in caPubs field of ip msg */
STACK_OF(X509) *caPubsOut; /* used in caPubs of ip and in caCerts of genp */
X509 *newWithNew; /* to return in newWithNew of rootKeyUpdate */
X509 *newWithOld; /* to return in newWithOld of rootKeyUpdate */
X509 *oldWithNew; /* to return in oldWithNew of rootKeyUpdate */
OSSL_CMP_PKISI *statusOut; /* status for ip/cp/kup/rp msg unless polling */
int sendError; /* send error response on given request type */
OSSL_CMP_MSG *certReq; /* ir/cr/p10cr/kur remembered while polling */
OSSL_CMP_MSG *req; /* original request message during polling */
int pollCount; /* number of polls before actual cert response */
int curr_pollCount; /* number of polls so far for current request */
int checkAfterTime; /* time the client should wait between polling */
} mock_srv_ctx;
static void mock_srv_ctx_free(mock_srv_ctx *ctx)
{
if (ctx == NULL)
return;
OSSL_CMP_PKISI_free(ctx->statusOut);
X509_free(ctx->refCert);
X509_free(ctx->certOut);
sk_X509_pop_free(ctx->chainOut, X509_free);
sk_X509_pop_free(ctx->caPubsOut, X509_free);
OSSL_CMP_MSG_free(ctx->certReq);
OSSL_STACK_OF_X509_free(ctx->chainOut);
OSSL_STACK_OF_X509_free(ctx->caPubsOut);
OSSL_CMP_MSG_free(ctx->req);
OPENSSL_free(ctx);
}
@ -62,7 +67,28 @@ static mock_srv_ctx *mock_srv_ctx_new(void)
return NULL;
}
int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert)
#define DEFINE_OSSL_SET1_CERT(FIELD) \
int ossl_cmp_mock_srv_set1_##FIELD(OSSL_CMP_SRV_CTX *srv_ctx, \
X509 *cert) \
{ \
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); \
\
if (ctx == NULL) { \
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \
return 0; \
} \
if (cert == NULL || X509_up_ref(cert)) { \
X509_free(ctx->FIELD); \
ctx->FIELD = cert; \
return 1; \
} \
return 0; \
}
DEFINE_OSSL_SET1_CERT(refCert)
DEFINE_OSSL_SET1_CERT(certOut)
int ossl_cmp_mock_srv_set1_keyOut(OSSL_CMP_SRV_CTX *srv_ctx, EVP_PKEY *pkey)
{
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
@ -70,13 +96,28 @@ int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert)
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return 0;
}
if (cert == NULL || X509_up_ref(cert)) {
X509_free(ctx->certOut);
ctx->certOut = cert;
if (pkey != NULL && !EVP_PKEY_up_ref(pkey))
return 0;
EVP_PKEY_free(ctx->keyOut);
ctx->keyOut = pkey;
return 1;
}
int ossl_cmp_mock_srv_set1_crlOut(OSSL_CMP_SRV_CTX *srv_ctx,
X509_CRL *crl)
{
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
if (ctx == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return 0;
}
if (crl != NULL && !X509_CRL_up_ref(crl))
return 0;
X509_CRL_free(ctx->crlOut);
ctx->crlOut = crl;
return 1;
}
int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
STACK_OF(X509) *chain)
@ -90,7 +131,7 @@ int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
}
if (chain != NULL && (chain_copy = X509_chain_up_ref(chain)) == NULL)
return 0;
sk_X509_pop_free(ctx->chainOut, X509_free);
OSSL_STACK_OF_X509_free(ctx->chainOut);
ctx->chainOut = chain_copy;
return 1;
}
@ -107,11 +148,15 @@ int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx,
}
if (caPubs != NULL && (caPubs_copy = X509_chain_up_ref(caPubs)) == NULL)
return 0;
sk_X509_pop_free(ctx->caPubsOut, X509_free);
OSSL_STACK_OF_X509_free(ctx->caPubsOut);
ctx->caPubsOut = caPubs_copy;
return 1;
}
DEFINE_OSSL_SET1_CERT(newWithNew)
DEFINE_OSSL_SET1_CERT(newWithOld)
DEFINE_OSSL_SET1_CERT(oldWithNew)
int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status,
int fail_info, const char *text)
{
@ -170,6 +215,70 @@ int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec)
return 1;
}
/* determine whether to delay response to (non-polling) request */
static int delayed_delivery(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *req)
{
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
int req_type = OSSL_CMP_MSG_get_bodytype(req);
if (ctx == NULL || req == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return -1;
}
/*
* For ir/cr/p10cr/kur delayed delivery is handled separately in
* process_cert_request
*/
if (req_type == OSSL_CMP_IR
|| req_type == OSSL_CMP_CR
|| req_type == OSSL_CMP_P10CR
|| req_type == OSSL_CMP_KUR
/* Client may use error to abort the ongoing polling */
|| req_type == OSSL_CMP_ERROR)
return 0;
if (ctx->pollCount > 0 && ctx->curr_pollCount == 0) {
/* start polling */
if ((ctx->req = OSSL_CMP_MSG_dup(req)) == NULL)
return -1;
return 1;
}
return 0;
}
/* check for matching reference cert components, as far as given */
static int refcert_cmp(const X509 *refcert,
const X509_NAME *issuer, const ASN1_INTEGER *serial)
{
const X509_NAME *ref_issuer;
const ASN1_INTEGER *ref_serial;
if (refcert == NULL)
return 1;
ref_issuer = X509_get_issuer_name(refcert);
ref_serial = X509_get0_serialNumber(refcert);
return (ref_issuer == NULL || X509_NAME_cmp(issuer, ref_issuer) == 0)
&& (ref_serial == NULL || ASN1_INTEGER_cmp(serial, ref_serial) == 0);
}
/* reset the state that belongs to a transaction */
static int clean_transaction(OSSL_CMP_SRV_CTX *srv_ctx,
ossl_unused const ASN1_OCTET_STRING *id)
{
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
if (ctx == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return 0;
}
ctx->curr_pollCount = 0;
OSSL_CMP_MSG_free(ctx->req);
ctx->req = NULL;
return 1;
}
static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
const OSSL_CMP_MSG *cert_req,
ossl_unused int certReqId,
@ -180,15 +289,17 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
STACK_OF(X509) **caPubs)
{
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
int bodytype, central_keygen;
OSSL_CMP_PKISI *si = NULL;
EVP_PKEY *keyOut = NULL;
if (ctx == NULL || cert_req == NULL
|| certOut == NULL || chainOut == NULL || caPubs == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return NULL;
}
if (ctx->sendError == 1
|| ctx->sendError == OSSL_CMP_MSG_get_bodytype(cert_req)) {
bodytype = OSSL_CMP_MSG_get_bodytype(cert_req);
if (ctx->sendError == 1 || ctx->sendError == bodytype) {
ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
return NULL;
}
@ -199,12 +310,7 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
if (ctx->pollCount > 0 && ctx->curr_pollCount == 0) {
/* start polling */
if (ctx->certReq != NULL) {
/* already in polling mode */
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
return NULL;
}
if ((ctx->certReq = OSSL_CMP_MSG_dup(cert_req)) == NULL)
if ((ctx->req = OSSL_CMP_MSG_dup(cert_req)) == NULL)
return NULL;
return OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_waiting, 0, NULL);
}
@ -212,24 +318,54 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
/* give final response after polling */
ctx->curr_pollCount = 0;
if (OSSL_CMP_MSG_get_bodytype(cert_req) == OSSL_CMP_KUR
&& crm != NULL && ctx->certOut != NULL) {
/* accept cert profile for cr messages only with the configured name */
if (OSSL_CMP_MSG_get_bodytype(cert_req) == OSSL_CMP_CR) {
STACK_OF(OSSL_CMP_ITAV) *itavs =
OSSL_CMP_HDR_get0_geninfo_ITAVs(OSSL_CMP_MSG_get0_header(cert_req));
int i;
for (i = 0; i < sk_OSSL_CMP_ITAV_num(itavs); i++) {
OSSL_CMP_ITAV *itav = sk_OSSL_CMP_ITAV_value(itavs, i);
ASN1_OBJECT *obj = OSSL_CMP_ITAV_get0_type(itav);
STACK_OF(ASN1_UTF8STRING) *strs;
ASN1_UTF8STRING *str;
const char *data;
if (OBJ_obj2nid(obj) == NID_id_it_certProfile) {
if (!OSSL_CMP_ITAV_get0_certProfile(itav, &strs))
return NULL;
if (sk_ASN1_UTF8STRING_num(strs) < 1) {
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CERTPROFILE);
return NULL;
}
str = sk_ASN1_UTF8STRING_value(strs, 0);
if (str == NULL
|| (data =
(const char *)ASN1_STRING_get0_data(str)) == NULL) {
ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT);
return NULL;
}
if (strcmp(data, "profile1") != 0) {
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CERTPROFILE);
return NULL;
}
break;
}
}
}
/* accept cert update request only for the reference cert, if given */
if (bodytype == OSSL_CMP_KUR
&& crm != NULL /* thus not p10cr */ && ctx->refCert != NULL) {
const OSSL_CRMF_CERTID *cid = OSSL_CRMF_MSG_get0_regCtrl_oldCertID(crm);
const X509_NAME *issuer = X509_get_issuer_name(ctx->certOut);
const ASN1_INTEGER *serial = X509_get0_serialNumber(ctx->certOut);
if (cid == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_CERTID);
return NULL;
}
if (issuer != NULL
&& X509_NAME_cmp(issuer, OSSL_CRMF_CERTID_get0_issuer(cid)) != 0) {
ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID);
return NULL;
}
if (serial != NULL
&& ASN1_INTEGER_cmp(serial,
OSSL_CRMF_CERTID_get0_serialNumber(cid)) != 0) {
if (!refcert_cmp(ctx->refCert,
OSSL_CRMF_CERTID_get0_issuer(cid),
OSSL_CRMF_CERTID_get0_serialNumber(cid))) {
ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID);
return NULL;
}
@ -237,11 +373,29 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
if (ctx->certOut != NULL
&& (*certOut = X509_dup(ctx->certOut)) == NULL)
/* Should return a cert produced from request template, see FR #16054 */
goto err;
central_keygen = OSSL_CRMF_MSG_centralkeygen_requested(crm, p10cr);
if (central_keygen < 0)
goto err;
if (central_keygen == 1
&& (ctx->keyOut == NULL
|| (keyOut = EVP_PKEY_dup(ctx->keyOut)) == NULL
|| !OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_SRV_CTX_get0_cmp_ctx(srv_ctx),
1 /* priv */, keyOut))) {
EVP_PKEY_free(keyOut);
goto err;
}
/*
* Note that this uses newPkey to return the private key
* and does not check whether the 'popo' field is absent.
*/
if (ctx->chainOut != NULL
&& (*chainOut = X509_chain_up_ref(ctx->chainOut)) == NULL)
goto err;
if (ctx->caPubsOut != NULL
if (ctx->caPubsOut != NULL /* OSSL_CMP_PKIBODY_IP not visible here */
&& (*caPubs = X509_chain_up_ref(ctx->caPubsOut)) == NULL)
goto err;
if (ctx->statusOut != NULL
@ -252,9 +406,9 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
err:
X509_free(*certOut);
*certOut = NULL;
sk_X509_pop_free(*chainOut, X509_free);
OSSL_STACK_OF_X509_free(*chainOut);
*chainOut = NULL;
sk_X509_pop_free(*caPubs, X509_free);
OSSL_STACK_OF_X509_free(*caPubs);
*caPubs = NULL;
return NULL;
}
@ -270,20 +424,16 @@ static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return NULL;
}
if (ctx->certOut == NULL || ctx->sendError == 1
if (ctx->sendError == 1
|| ctx->sendError == OSSL_CMP_MSG_get_bodytype(rr)) {
ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
return NULL;
}
/* Allow any RR derived from CSR, which may include subject and serial */
if (issuer == NULL || serial == NULL)
return OSSL_CMP_PKISI_dup(ctx->statusOut);
/* accept revocation only for the certificate we sent in ir/cr/kur */
if (X509_NAME_cmp(issuer, X509_get_issuer_name(ctx->certOut)) != 0
|| ASN1_INTEGER_cmp(serial,
X509_get0_serialNumber(ctx->certOut)) != 0) {
/* allow any RR derived from CSR which does not include issuer and serial */
if ((issuer != NULL || serial != NULL)
/* accept revocation only for the reference cert, if given */
&& !refcert_cmp(ctx->refCert, issuer, serial)) {
ERR_raise_data(ERR_LIB_CMP, CMP_R_REQUEST_NOT_ACCEPTED,
"wrong certificate to revoke");
return NULL;
@ -291,6 +441,136 @@ static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
return OSSL_CMP_PKISI_dup(ctx->statusOut);
}
/* return -1 for error, 0 for no update available */
static int check_client_crl(const STACK_OF(OSSL_CMP_CRLSTATUS) *crlStatusList,
const X509_CRL *crl)
{
OSSL_CMP_CRLSTATUS *crlstatus;
DIST_POINT_NAME *dpn = NULL;
GENERAL_NAMES *issuer = NULL;
ASN1_TIME *thisupd = NULL;
if (sk_OSSL_CMP_CRLSTATUS_num(crlStatusList) != 1) {
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CRLSTATUSLIST);
return -1;
}
if (crl == NULL)
return 0;
crlstatus = sk_OSSL_CMP_CRLSTATUS_value(crlStatusList, 0);
if (!OSSL_CMP_CRLSTATUS_get0(crlstatus, &dpn, &issuer, &thisupd))
return -1;
if (issuer != NULL) {
GENERAL_NAME *gn = sk_GENERAL_NAME_value(issuer, 0);
if (gn != NULL && gn->type == GEN_DIRNAME) {
X509_NAME *gen_name = gn->d.dirn;
if (X509_NAME_cmp(gen_name, X509_CRL_get_issuer(crl)) != 0) {
ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_CRL_ISSUER);
return -1;
}
} else {
ERR_raise(ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
return -1; /* error according to RFC 9483 section 4.3.4 */
}
}
return thisupd == NULL
|| ASN1_TIME_compare(thisupd, X509_CRL_get0_lastUpdate(crl)) < 0;
}
static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid,
const OSSL_CMP_ITAV *req)
{
OSSL_CMP_ITAV *rsp = NULL;
switch (req_nid) {
case NID_id_it_caCerts:
rsp = OSSL_CMP_ITAV_new_caCerts(ctx->caPubsOut);
break;
case NID_id_it_rootCaCert:
{
X509 *rootcacert = NULL;
if (!OSSL_CMP_ITAV_get0_rootCaCert(req, &rootcacert))
return NULL;
if (rootcacert != NULL
&& X509_NAME_cmp(X509_get_subject_name(rootcacert),
X509_get_subject_name(ctx->newWithNew)) != 0)
/* The subjects do not match */
rsp = OSSL_CMP_ITAV_new_rootCaKeyUpdate(NULL, NULL, NULL);
else
rsp = OSSL_CMP_ITAV_new_rootCaKeyUpdate(ctx->newWithNew,
ctx->newWithOld,
ctx->oldWithNew);
}
break;
case NID_id_it_crlStatusList:
{
STACK_OF(OSSL_CMP_CRLSTATUS) *crlstatuslist = NULL;
int res = 0;
if (!OSSL_CMP_ITAV_get0_crlStatusList(req, &crlstatuslist))
return NULL;
res = check_client_crl(crlstatuslist, ctx->crlOut);
if (res < 0)
rsp = NULL;
else
rsp = OSSL_CMP_ITAV_new_crls(res == 0 ? NULL : ctx->crlOut);
}
break;
case NID_id_it_certReqTemplate:
{
OSSL_CRMF_CERTTEMPLATE *reqtemp;
OSSL_CMP_ATAVS *keyspec = NULL;
X509_ALGOR *keyalg = NULL;
OSSL_CMP_ATAV *rsakeylen, *eckeyalg;
int ok = 0;
if ((reqtemp = OSSL_CRMF_CERTTEMPLATE_new()) == NULL)
return NULL;
if (!OSSL_CRMF_CERTTEMPLATE_fill(reqtemp, NULL, NULL,
X509_get_issuer_name(ctx->refCert),
NULL))
goto crt_err;
if ((keyalg = X509_ALGOR_new()) == NULL)
goto crt_err;
(void)X509_ALGOR_set0(keyalg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
V_ASN1_UNDEF, NULL); /* cannot fail */
eckeyalg = OSSL_CMP_ATAV_new_algId(keyalg);
rsakeylen = OSSL_CMP_ATAV_new_rsaKeyLen(4096);
ok = OSSL_CMP_ATAV_push1(&keyspec, eckeyalg)
&& OSSL_CMP_ATAV_push1(&keyspec, rsakeylen);
OSSL_CMP_ATAV_free(eckeyalg);
OSSL_CMP_ATAV_free(rsakeylen);
X509_ALGOR_free(keyalg);
if (!ok)
goto crt_err;
rsp = OSSL_CMP_ITAV_new0_certReqTemplate(reqtemp, keyspec);
return rsp;
crt_err:
OSSL_CRMF_CERTTEMPLATE_free(reqtemp);
OSSL_CMP_ATAVS_free(keyspec);
return NULL;
}
break;
default:
rsp = OSSL_CMP_ITAV_dup(req);
}
return rsp;
}
static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
const OSSL_CMP_MSG *genm,
const STACK_OF(OSSL_CMP_ITAV) *in,
@ -308,6 +588,18 @@ static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
return 0;
}
if (sk_OSSL_CMP_ITAV_num(in) == 1) {
OSSL_CMP_ITAV *req = sk_OSSL_CMP_ITAV_value(in, 0), *rsp;
ASN1_OBJECT *obj = OSSL_CMP_ITAV_get0_type(req);
if ((*out = sk_OSSL_CMP_ITAV_new_reserve(NULL, 1)) == NULL)
return 0;
rsp = process_genm_itav(ctx, OBJ_obj2nid(obj), req);
if (rsp != NULL && sk_OSSL_CMP_ITAV_push(*out, rsp))
return 1;
sk_OSSL_CMP_ITAV_free(*out);
return 0;
}
*out = sk_OSSL_CMP_ITAV_deep_copy(in, OSSL_CMP_ITAV_dup,
OSSL_CMP_ITAV_free);
@ -351,10 +643,9 @@ static void process_error(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *error,
for (i = 0; i < sk_ASN1_UTF8STRING_num(errorDetails); i++) {
if (i > 0)
BIO_printf(bio_err, ", ");
BIO_printf(bio_err, "\"");
ASN1_STRING_print(bio_err,
sk_ASN1_UTF8STRING_value(errorDetails, i));
BIO_printf(bio_err, "\"");
ASN1_STRING_print_ex(bio_err,
sk_ASN1_UTF8STRING_value(errorDetails, i),
ASN1_STRFLGS_ESC_QUOTE);
}
BIO_printf(bio_err, "\n");
}
@ -391,38 +682,38 @@ static int process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
return 1;
}
/* return 0 on failure, 1 on success, setting *req or otherwise *check_after */
static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
const OSSL_CMP_MSG *pollReq,
ossl_unused int certReqId,
OSSL_CMP_MSG **certReq, int64_t *check_after)
OSSL_CMP_MSG **req, int64_t *check_after)
{
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
if (req != NULL)
*req = NULL;
if (ctx == NULL || pollReq == NULL
|| certReq == NULL || check_after == NULL) {
|| req == NULL || check_after == NULL) {
ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
return 0;
}
if (ctx->sendError == 1
|| ctx->sendError == OSSL_CMP_MSG_get_bodytype(pollReq)) {
*certReq = NULL;
ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
return 0;
}
if (ctx->certReq == NULL) {
/* not currently in polling mode */
*certReq = NULL;
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY);
if (ctx->req == NULL) { /* not currently in polling mode */
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_POLLREQ);
return 0;
}
if (++ctx->curr_pollCount >= ctx->pollCount) {
/* end polling */
*certReq = ctx->certReq;
ctx->certReq = NULL;
*req = ctx->req;
ctx->req = NULL;
*check_after = 0;
} else {
*certReq = NULL;
*check_after = ctx->checkAfterTime;
}
return 1;
@ -436,7 +727,9 @@ OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx, const char *propq)
if (srv_ctx != NULL && ctx != NULL
&& OSSL_CMP_SRV_CTX_init(srv_ctx, ctx, process_cert_request,
process_rr, process_genm, process_error,
process_certConf, process_pollReq))
process_certConf, process_pollReq)
&& OSSL_CMP_SRV_CTX_init_trans(srv_ctx,
delayed_delivery, clean_transaction))
return srv_ctx;
mock_srv_ctx_free(ctx);

View file

@ -14,6 +14,7 @@
*/
#define OPENSSL_SUPPRESS_DEPRECATED
#include "internal/e_os.h"
#include "apps.h"
#ifndef OPENSSL_NO_ENGINE
@ -71,10 +72,8 @@ static OSSL_STORE_LOADER_CTX *engine_open(const OSSL_STORE_LOADER *loader,
char *keyid = NULL;
OSSL_STORE_LOADER_CTX *ctx = NULL;
if (OPENSSL_strncasecmp(p, ENGINE_SCHEME_COLON, sizeof(ENGINE_SCHEME_COLON) - 1)
!= 0)
if (!CHECK_AND_SKIP_CASE_PREFIX(p, ENGINE_SCHEME_COLON))
return NULL;
p += sizeof(ENGINE_SCHEME_COLON) - 1;
/* Look for engine ID */
q = strchr(p, ':');

View file

@ -1,5 +1,5 @@
/*
* Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -17,71 +17,36 @@
# define _POSIX_C_SOURCE 2
#endif
#include <string.h>
#include <ctype.h>
#include "internal/e_os.h"
#include "http_server.h"
#include "internal/sockets.h"
#include "internal/sockets.h" /* for openssl_fdset() */
#include <openssl/err.h>
#include <openssl/trace.h>
#include <openssl/rand.h>
#include "s_apps.h"
#if defined(__TANDEM)
# if defined(OPENSSL_TANDEM_FLOSS)
# include <floss.h(floss_fork)>
# endif
#endif
static int verbosity = LOG_INFO;
#include "log.h"
#define HTTP_PREFIX "HTTP/"
#define HTTP_VERSION_PATT "1." /* allow 1.x */
#define HTTP_PREFIX_VERSION HTTP_PREFIX""HTTP_VERSION_PATT
#define HTTP_1_0 HTTP_PREFIX_VERSION"0" /* "HTTP/1.0" */
#define HTTP_VERSION_STR " "HTTP_PREFIX_VERSION
#define log_HTTP(prog, level, text) \
trace_log_message(OSSL_TRACE_CATEGORY_HTTP, prog, level, "%s", text)
#define log_HTTP1(prog, level, fmt, arg) \
trace_log_message(OSSL_TRACE_CATEGORY_HTTP, prog, level, fmt, arg)
#define log_HTTP2(prog, level, fmt, arg1, arg2) \
trace_log_message(OSSL_TRACE_CATEGORY_HTTP, prog, level, fmt, arg1, arg2)
#define log_HTTP3(prog, level, fmt, a1, a2, a3) \
trace_log_message(OSSL_TRACE_CATEGORY_HTTP, prog, level, fmt, a1, a2, a3)
#ifdef HTTP_DAEMON
int multi = 0; /* run multiple responder processes */
int n_responders = 0; /* run multiple responder processes, set by ocsp.c */
int acfd = (int)INVALID_SOCKET;
static int print_syslog(const char *str, size_t len, void *levPtr)
{
int level = *(int *)levPtr;
int ilen = len > MAXERRLEN ? MAXERRLEN : len;
syslog(level, "%.*s", ilen, str);
return ilen;
}
#endif
void log_message(const char *prog, int level, const char *fmt, ...)
{
va_list ap;
if (verbosity < level)
return;
va_start(ap, fmt);
#ifdef HTTP_DAEMON
if (multi) {
char buf[1024];
if (vsnprintf(buf, sizeof(buf), fmt, ap) > 0)
syslog(level, "%s", buf);
if (level <= LOG_ERR)
ERR_print_errors_cb(print_syslog, &level);
} else
#endif
{
BIO_printf(bio_err, "%s: ", prog);
BIO_vprintf(bio_err, fmt, ap);
BIO_printf(bio_err, "\n");
(void)BIO_flush(bio_err);
}
va_end(ap);
}
#ifdef HTTP_DAEMON
void socket_timeout(int signum)
{
if (acfd != (int)INVALID_SOCKET)
@ -92,11 +57,11 @@ static void killall(int ret, pid_t *kidpids)
{
int i;
for (i = 0; i < multi; ++i)
for (i = 0; i < n_responders; ++i)
if (kidpids[i] != 0)
(void)kill(kidpids[i], SIGTERM);
OPENSSL_free(kidpids);
ossl_sleep(1000);
OSSL_sleep(1000);
exit(ret);
}
@ -122,12 +87,13 @@ void spawn_loop(const char *prog)
openlog(prog, LOG_PID, LOG_DAEMON);
if (setpgid(0, 0)) {
syslog(LOG_ERR, "fatal: error detaching from parent process group: %s",
log_HTTP1(prog, LOG_CRIT,
"error detaching from parent process group: %s",
strerror(errno));
exit(1);
}
kidpids = app_malloc(multi * sizeof(*kidpids), "child PID array");
for (i = 0; i < multi; ++i)
kidpids = app_malloc(n_responders * sizeof(*kidpids), "child PID array");
for (i = 0; i < n_responders; ++i)
kidpids[i] = 0;
signal(SIGINT, noteterm);
@ -140,7 +106,7 @@ void spawn_loop(const char *prog)
* Wait for a child to replace when we're at the limit.
* Slow down if a child exited abnormally or waitpid() < 0
*/
while (termsig == 0 && procs >= multi) {
while (termsig == 0 && procs >= n_responders) {
if ((fpid = waitpid(-1, &status, 0)) > 0) {
for (i = 0; i < procs; ++i) {
if (kidpids[i] == fpid) {
@ -149,28 +115,34 @@ void spawn_loop(const char *prog)
break;
}
}
if (i >= multi) {
syslog(LOG_ERR, "fatal: internal error: "
"no matching child slot for pid: %ld",
if (i >= n_responders) {
log_HTTP1(prog, LOG_CRIT,
"internal error: no matching child slot for pid: %ld",
(long)fpid);
killall(1, kidpids);
}
if (status != 0) {
if (WIFEXITED(status))
syslog(LOG_WARNING, "child process: %ld, exit status: %d",
if (WIFEXITED(status)) {
log_HTTP2(prog, LOG_WARNING,
"child process: %ld, exit status: %d",
(long)fpid, WEXITSTATUS(status));
else if (WIFSIGNALED(status))
syslog(LOG_WARNING, "child process: %ld, term signal %d%s",
(long)fpid, WTERMSIG(status),
} else if (WIFSIGNALED(status)) {
char *dumped = "";
# ifdef WCOREDUMP
WCOREDUMP(status) ? " (core dumped)" :
if (WCOREDUMP(status))
dumped = " (core dumped)";
# endif
"");
ossl_sleep(1000);
log_HTTP3(prog, LOG_WARNING,
"child process: %ld, term signal %d%s",
(long)fpid, WTERMSIG(status), dumped);
}
OSSL_sleep(1000);
}
break;
} else if (errno != EINTR) {
syslog(LOG_ERR, "fatal: waitpid(): %s", strerror(errno));
log_HTTP1(prog, LOG_CRIT,
"waitpid() failed: %s", strerror(errno));
killall(1, kidpids);
}
}
@ -180,7 +152,7 @@ void spawn_loop(const char *prog)
switch (fpid = fork()) {
case -1: /* error */
/* System critically low on memory, pause and try again later */
ossl_sleep(30000);
OSSL_sleep(30000);
break;
case 0: /* child */
OPENSSL_free(kidpids);
@ -189,20 +161,21 @@ void spawn_loop(const char *prog)
if (termsig)
_exit(0);
if (RAND_poll() <= 0) {
syslog(LOG_ERR, "fatal: RAND_poll() failed");
log_HTTP(prog, LOG_CRIT, "RAND_poll() failed");
_exit(1);
}
return;
default: /* parent */
for (i = 0; i < multi; ++i) {
for (i = 0; i < n_responders; ++i) {
if (kidpids[i] == 0) {
kidpids[i] = fpid;
procs++;
break;
}
}
if (i >= multi) {
syslog(LOG_ERR, "fatal: internal error: no free child slots");
if (i >= n_responders) {
log_HTTP(prog, LOG_CRIT,
"internal error: no free child slots");
killall(1, kidpids);
}
break;
@ -210,19 +183,22 @@ void spawn_loop(const char *prog)
}
/* The loop above can only break on termsig */
syslog(LOG_INFO, "terminating on signal: %d", termsig);
log_HTTP1(prog, LOG_INFO, "terminating on signal: %d", termsig);
killall(0, kidpids);
}
#endif
#ifndef OPENSSL_NO_SOCK
BIO *http_server_init_bio(const char *prog, const char *port)
BIO *http_server_init(const char *prog, const char *port, int verb)
{
BIO *acbio = NULL, *bufbio;
int asock;
int port_num;
char name[40];
BIO_snprintf(name, sizeof(name), "[::]:%s", port); /* port may be "0" */
BIO_snprintf(name, sizeof(name), "*:%s", port); /* port may be "0" */
if (verb >= 0 && !log_set_verbosity(prog, verb))
return NULL;
bufbio = BIO_new(BIO_f_buffer());
if (bufbio == NULL)
goto err;
@ -231,27 +207,29 @@ BIO *http_server_init_bio(const char *prog, const char *port)
|| BIO_set_accept_ip_family(acbio, BIO_FAMILY_IPANY) <= 0 /* IPv4/6 */
|| BIO_set_bind_mode(acbio, BIO_BIND_REUSEADDR) <= 0
|| BIO_set_accept_name(acbio, name) <= 0) {
log_message(prog, LOG_ERR, "Error setting up accept BIO");
log_HTTP(prog, LOG_ERR, "error setting up accept BIO");
goto err;
}
BIO_set_accept_bios(acbio, bufbio);
bufbio = NULL;
if (BIO_do_accept(acbio) <= 0) {
log_message(prog, LOG_ERR, "Error starting accept");
log_HTTP1(prog, LOG_ERR, "error setting accept on port %s", port);
goto err;
}
/* Report back what address and port are used */
BIO_get_fd(acbio, &asock);
if (!report_server_accept(bio_out, asock, 1, 1)) {
log_message(prog, LOG_ERR, "Error printing ACCEPT string");
port_num = report_server_accept(bio_out, asock, 1, 1);
if (port_num == 0) {
log_HTTP(prog, LOG_ERR, "error printing ACCEPT string");
goto err;
}
return acbio;
err:
ERR_print_errors(bio_err);
BIO_free_all(acbio);
BIO_free(bufbio);
return NULL;
@ -286,8 +264,7 @@ static int urldecode(char *p)
int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
char **ppath, BIO **pcbio, BIO *acbio,
int *found_keep_alive,
const char *prog, const char *port,
int accept_get, int timeout)
const char *prog, int accept_get, int timeout)
{
BIO *cbio = *pcbio, *getbio = NULL, *b64 = NULL;
int len;
@ -301,18 +278,27 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
*ppath = NULL;
if (cbio == NULL) {
log_message(prog, LOG_DEBUG,
"Awaiting new connection on port %s...", port);
char *port;
get_sock_info_address(BIO_get_fd(acbio, NULL), NULL, &port);
if (port == NULL) {
log_HTTP(prog, LOG_ERR, "cannot get port listening on");
goto fatal;
}
log_HTTP1(prog, LOG_DEBUG,
"awaiting new connection on port %s ...", port);
OPENSSL_free(port);
if (BIO_do_accept(acbio) <= 0)
/* Connection loss before accept() is routine, ignore silently */
return ret;
*pcbio = cbio = BIO_pop(acbio);
} else {
log_message(prog, LOG_DEBUG, "Awaiting next request...");
log_HTTP(prog, LOG_DEBUG, "awaiting next request ...");
}
if (cbio == NULL) {
/* Cannot call http_server_send_status(cbio, ...) */
/* Cannot call http_server_send_status(..., cbio, ...) */
ret = -1;
goto out;
}
@ -330,31 +316,39 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
return ret;
ret = 1;
if (len < 0) {
log_message(prog, LOG_WARNING, "Request line read error");
(void)http_server_send_status(cbio, 400, "Bad Request");
log_HTTP(prog, LOG_WARNING, "request line read error");
(void)http_server_send_status(prog, cbio, 400, "Bad Request");
goto out;
}
if ((end = strchr(reqbuf, '\r')) != NULL
if (((end = strchr(reqbuf, '\r')) != NULL && end[1] == '\n')
|| (end = strchr(reqbuf, '\n')) != NULL)
*end = '\0';
log_message(prog, LOG_INFO, "Received request, 1st line: %s", reqbuf);
if (log_get_verbosity() < LOG_TRACE)
trace_log_message(-1, prog, LOG_INFO,
"received request, 1st line: %s", reqbuf);
log_HTTP(prog, LOG_TRACE, "received request header:");
log_HTTP1(prog, LOG_TRACE, "%s", reqbuf);
if (end == NULL) {
log_HTTP(prog, LOG_WARNING,
"cannot parse HTTP header: missing end of line");
(void)http_server_send_status(prog, cbio, 400, "Bad Request");
goto out;
}
meth = reqbuf;
url = meth + 3;
if ((accept_get && strncmp(meth, "GET ", 4) == 0)
|| (url++, strncmp(meth, "POST ", 5) == 0)) {
static const char http_version_str[] = " "HTTP_PREFIX_VERSION;
static const size_t http_version_str_len = sizeof(http_version_str) - 1;
url = meth = reqbuf;
if ((accept_get && CHECK_AND_SKIP_PREFIX(url, "GET "))
|| CHECK_AND_SKIP_PREFIX(url, "POST ")) {
/* Expecting (GET|POST) {sp} /URL {sp} HTTP/1.x */
*(url++) = '\0';
url[-1] = '\0';
while (*url == ' ')
url++;
if (*url != '/') {
log_message(prog, LOG_WARNING,
"Invalid %s -- URL does not begin with '/': %s",
log_HTTP2(prog, LOG_WARNING,
"invalid %s -- URL does not begin with '/': %s",
meth, url);
(void)http_server_send_status(cbio, 400, "Bad Request");
(void)http_server_send_status(prog, cbio, 400, "Bad Request");
goto out;
}
url++;
@ -363,17 +357,17 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
for (end = url; *end != '\0'; end++)
if (*end == ' ')
break;
if (strncmp(end, http_version_str, http_version_str_len) != 0) {
log_message(prog, LOG_WARNING,
"Invalid %s -- bad HTTP/version string: %s",
if (!HAS_PREFIX(end, HTTP_VERSION_STR)) {
log_HTTP2(prog, LOG_WARNING,
"invalid %s -- bad HTTP/version string: %s",
meth, end + 1);
(void)http_server_send_status(cbio, 400, "Bad Request");
(void)http_server_send_status(prog, cbio, 400, "Bad Request");
goto out;
}
*end = '\0';
/* above HTTP 1.0, connection persistence is the default */
if (found_keep_alive != NULL)
*found_keep_alive = end[http_version_str_len] > '0';
*found_keep_alive = end[sizeof(HTTP_VERSION_STR) - 1] > '0';
/*-
* Skip "GET / HTTP..." requests often used by load-balancers.
@ -381,34 +375,32 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
* the leading slash, so in case 'GET / ' it is now an empty string.
*/
if (strlen(meth) == 3 && url[0] == '\0') {
(void)http_server_send_status(cbio, 200, "OK");
(void)http_server_send_status(prog, cbio, 200, "OK");
goto out;
}
len = urldecode(url);
if (len < 0) {
log_message(prog, LOG_WARNING,
"Invalid %s request -- bad URL encoding: %s",
meth, url);
(void)http_server_send_status(cbio, 400, "Bad Request");
log_HTTP2(prog, LOG_WARNING,
"invalid %s request -- bad URL encoding: %s", meth, url);
(void)http_server_send_status(prog, cbio, 400, "Bad Request");
goto out;
}
if (strlen(meth) == 3) { /* GET */
if ((getbio = BIO_new_mem_buf(url, len)) == NULL
|| (b64 = BIO_new(BIO_f_base64())) == NULL) {
log_message(prog, LOG_ERR,
"Could not allocate base64 bio with size = %d",
len);
log_HTTP1(prog, LOG_ERR,
"could not allocate base64 bio with size = %d", len);
goto fatal;
}
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
getbio = BIO_push(b64, getbio);
}
} else {
log_message(prog, LOG_WARNING,
log_HTTP2(prog, LOG_WARNING,
"HTTP request does not begin with %sPOST: %s",
accept_get ? "GET or " : "", reqbuf);
(void)http_server_send_status(cbio, 400, "Bad Request");
(void)http_server_send_status(prog, cbio, 400, "Bad Request");
goto out;
}
@ -421,40 +413,41 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
/* Read and skip past the headers. */
for (;;) {
char *key, *value, *line_end = NULL;
char *key, *value;
len = BIO_gets(cbio, inbuf, sizeof(inbuf));
if (len <= 0) {
log_message(prog, LOG_WARNING, "Error reading HTTP header");
(void)http_server_send_status(cbio, 400, "Bad Request");
log_HTTP(prog, LOG_WARNING, "error reading HTTP header");
(void)http_server_send_status(prog, cbio, 400, "Bad Request");
goto out;
}
if (inbuf[0] == '\r' || inbuf[0] == '\n')
if (((end = strchr(inbuf, '\r')) != NULL && end[1] == '\n')
|| (end = strchr(inbuf, '\n')) != NULL)
*end = '\0';
log_HTTP1(prog, LOG_TRACE, "%s", *inbuf == '\0' ?
" " /* workaround for "" getting ignored */ : inbuf);
if (end == NULL) {
log_HTTP(prog, LOG_WARNING,
"error parsing HTTP header: missing end of line");
(void)http_server_send_status(prog, cbio, 400, "Bad Request");
goto out;
}
if (inbuf[0] == '\0')
break;
key = inbuf;
value = strchr(key, ':');
if (value == NULL) {
log_message(prog, LOG_WARNING,
"Error parsing HTTP header: missing ':'");
(void)http_server_send_status(cbio, 400, "Bad Request");
log_HTTP(prog, LOG_WARNING,
"error parsing HTTP header: missing ':'");
(void)http_server_send_status(prog, cbio, 400, "Bad Request");
goto out;
}
*(value++) = '\0';
while (*value == ' ')
value++;
line_end = strchr(value, '\r');
if (line_end == NULL) {
line_end = strchr(value, '\n');
if (line_end == NULL) {
log_message(prog, LOG_WARNING,
"Error parsing HTTP header: missing end of line");
(void)http_server_send_status(cbio, 400, "Bad Request");
goto out;
}
}
*line_end = '\0';
/* https://tools.ietf.org/html/rfc7230#section-6.3 Persistence */
if (found_keep_alive != NULL
&& OPENSSL_strcasecmp(key, "Connection") == 0) {
@ -474,12 +467,12 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
/* Try to read and parse request */
req = ASN1_item_d2i_bio(it, getbio != NULL ? getbio : cbio, NULL);
if (req == NULL) {
log_message(prog, LOG_WARNING,
"Error parsing DER-encoded request content");
(void)http_server_send_status(cbio, 400, "Bad Request");
log_HTTP(prog, LOG_WARNING,
"error parsing DER-encoded request content");
(void)http_server_send_status(prog, cbio, 400, "Bad Request");
} else if (ppath != NULL && (*ppath = OPENSSL_strdup(url)) == NULL) {
log_message(prog, LOG_ERR,
"Out of memory allocating %zu bytes", strlen(url) + 1);
log_HTTP1(prog, LOG_ERR,
"out of memory allocating %zu bytes", strlen(url) + 1);
ASN1_item_free(req, it);
goto fatal;
}
@ -496,7 +489,7 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
return ret;
fatal:
(void)http_server_send_status(cbio, 500, "Internal Server Error");
(void)http_server_send_status(prog, cbio, 500, "Internal Server Error");
if (ppath != NULL) {
OPENSSL_free(*ppath);
*ppath = NULL;
@ -508,28 +501,46 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
}
/* assumes that cbio does not do an encoding that changes the output length */
int http_server_send_asn1_resp(BIO *cbio, int keep_alive,
int http_server_send_asn1_resp(const char *prog, BIO *cbio, int keep_alive,
const char *content_type,
const ASN1_ITEM *it, const ASN1_VALUE *resp)
{
int ret = BIO_printf(cbio, HTTP_1_0" 200 OK\r\n%s"
char buf[200], *p;
int ret = BIO_snprintf(buf, sizeof(buf), HTTP_1_0" 200 OK\r\n%s"
"Content-type: %s\r\n"
"Content-Length: %d\r\n\r\n",
"Content-Length: %d\r\n",
keep_alive ? "Connection: keep-alive\r\n" : "",
content_type,
ASN1_item_i2d(resp, NULL, it)) > 0
ASN1_item_i2d(resp, NULL, it));
if (ret < 0 || (size_t)ret >= sizeof(buf))
return 0;
if (log_get_verbosity() < LOG_TRACE && (p = strchr(buf, '\r')) != NULL)
trace_log_message(-1, prog, LOG_INFO,
"sending response, 1st line: %.*s", (int)(p - buf),
buf);
log_HTTP1(prog, LOG_TRACE, "sending response header:\n%s", buf);
ret = BIO_printf(cbio, "%s\r\n", buf) > 0
&& ASN1_item_i2d_bio(it, cbio, resp) > 0;
(void)BIO_flush(cbio);
return ret;
}
int http_server_send_status(BIO *cbio, int status, const char *reason)
int http_server_send_status(const char *prog, BIO *cbio,
int status, const char *reason)
{
int ret = BIO_printf(cbio, HTTP_1_0" %d %s\r\n\r\n",
char buf[200];
int ret = BIO_snprintf(buf, sizeof(buf), HTTP_1_0" %d %s\r\n\r\n",
/* This implicitly cancels keep-alive */
status, reason) > 0;
status, reason);
if (ret < 0 || (size_t)ret >= sizeof(buf))
return 0;
log_HTTP1(prog, LOG_TRACE, "sending response header:\n%s", buf);
ret = BIO_printf(cbio, "%s\r\n", buf) > 0;
(void)BIO_flush(cbio);
return ret;
}

108
deps/openssl/openssl/apps/lib/log.c vendored Normal file
View file

@ -0,0 +1,108 @@
/*
* 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
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <openssl/trace.h>
#include "apps.h"
#include "log.h"
static int verbosity = LOG_INFO;
int log_set_verbosity(const char *prog, int level)
{
if (level < LOG_EMERG || level > LOG_TRACE) {
trace_log_message(-1, prog, LOG_ERR,
"Invalid verbosity level %d", level);
return 0;
}
verbosity = level;
return 1;
}
int log_get_verbosity(void)
{
return verbosity;
}
#ifdef HTTP_DAEMON
static int print_syslog(const char *str, size_t len, void *levPtr)
{
int level = *(int *)levPtr;
int ilen = len > MAXERRLEN ? MAXERRLEN : len;
syslog(level, "%.*s", ilen, str);
return ilen;
}
#endif
static void log_with_prefix(const char *prog, const char *fmt, va_list ap)
{
char prefix[80];
BIO *bio, *pre = BIO_new(BIO_f_prefix());
(void)BIO_snprintf(prefix, sizeof(prefix), "%s: ", prog);
(void)BIO_set_prefix(pre, prefix);
bio = BIO_push(pre, bio_err);
(void)BIO_vprintf(bio, fmt, ap);
(void)BIO_printf(bio, "\n");
(void)BIO_flush(bio);
(void)BIO_pop(pre);
BIO_free(pre);
}
/*
* Unfortunately, C before C99 does not define va_copy, so we must
* check if it can be assumed to be present. We do that with an internal
* antifeature macro.
* C versions since C94 define __STDC_VERSION__, so it's enough to
* check its existence and value.
*/
#undef OSSL_NO_C99
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ + 0 < 199900L
# define OSSL_NO_C99
#endif
void trace_log_message(int category,
const char *prog, int level, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
#ifdef OSSL_NO_C99
if (verbosity >= level)
category = -1; /* disabling trace output in addition to logging */
#endif
if (category >= 0 && OSSL_trace_enabled(category)) {
BIO *out = OSSL_trace_begin(category);
#ifndef OSSL_NO_C99
va_list ap_copy;
va_copy(ap_copy, ap);
(void)BIO_vprintf(out, fmt, ap_copy);
va_end(ap_copy);
#else
(void)BIO_vprintf(out, fmt, ap);
#endif
(void)BIO_printf(out, "\n");
OSSL_trace_end(category, out);
}
if (verbosity < level) {
va_end(ap);
return;
}
#ifdef HTTP_DAEMON
if (n_responders != 0) {
vsyslog(level, fmt, ap);
if (level <= LOG_ERR)
ERR_print_errors_cb(print_syslog, &level);
} else
#endif
log_with_prefix(prog, fmt, ap);
va_end(ap);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -11,7 +11,7 @@
#include <openssl/bio.h>
#include <openssl/safestack.h>
#include "names.h"
#include "openssl/crypto.h"
#include "internal/e_os.h"
int name_cmp(const char * const *a, const char * const *b)
{
@ -22,7 +22,8 @@ void collect_names(const char *name, void *vdata)
{
STACK_OF(OPENSSL_CSTRING) *names = vdata;
sk_OPENSSL_CSTRING_push(names, name);
/* A failure to push cannot be handled so we ignore the result. */
(void)sk_OPENSSL_CSTRING_push(names, name);
}
void print_names(BIO *out, STACK_OF(OPENSSL_CSTRING) *names)

View file

@ -41,6 +41,7 @@ static int opt_index;
static char *arg;
static char *flag;
static char *dunno;
static const char *unknown_name;
static const OPTIONS *unknown;
static const OPTIONS *opts;
static char prog[40];
@ -166,7 +167,6 @@ char *opt_init(int ac, char **av, const OPTIONS *o)
opt_begin();
opts = o;
unknown = NULL;
/* Make sure prog name is set for usage output */
(void)opt_progname(argv[0]);
@ -194,7 +194,7 @@ char *opt_init(int ac, char **av, const OPTIONS *o)
case 0: case '-': case '.':
case '/': case '<': case '>': case 'E': case 'F':
case 'M': case 'U': case 'f': case 'l': case 'n': case 'p': case 's':
case 'u': case 'c': case ':': case 'N':
case 'u': case 'c': case ':': case 'N': case 'A':
break;
default:
OPENSSL_assert(0);
@ -215,6 +215,7 @@ char *opt_init(int ac, char **av, const OPTIONS *o)
}
#endif
if (o->name[0] == '\0') {
OPENSSL_assert(unknown_name != NULL);
OPENSSL_assert(unknown == NULL);
unknown = o;
OPENSSL_assert(unknown->valtype == 0 || unknown->valtype == '-');
@ -224,7 +225,9 @@ char *opt_init(int ac, char **av, const OPTIONS *o)
}
static OPT_PAIR formats[] = {
{"PEM/DER", OPT_FMT_PEMDER},
{"pem", OPT_FMT_PEM},
{"der", OPT_FMT_DER},
{"b64", OPT_FMT_B64},
{"pkcs12", OPT_FMT_PKCS12},
{"smime", OPT_FMT_SMIME},
{"engine", OPT_FMT_ENGINE},
@ -236,21 +239,22 @@ static OPT_PAIR formats[] = {
{NULL}
};
void opt_set_unknown_name(const char *name)
{
unknown_name = name;
}
/* Print an error message about a failed format parse. */
static int opt_format_error(const char *s, unsigned long flags)
{
OPT_PAIR *ap;
if (flags == OPT_FMT_PEMDER) {
opt_printf_stderr("%s: Bad format \"%s\"; must be pem or der\n",
prog, s);
} else {
opt_printf_stderr("%s: Bad format \"%s\"; must be one of:\n",
prog, s);
opt_printf_stderr("%s: Bad format \"%s\"; must be one of: ", prog, s);
for (ap = formats; ap->name; ap++)
if (flags & ap->retval)
opt_printf_stderr(" %s\n", ap->name);
}
opt_printf_stderr(" %s", ap->name);
opt_printf_stderr("\n");
return 0;
}
@ -261,9 +265,21 @@ int opt_format(const char *s, unsigned long flags, int *result)
default:
opt_printf_stderr("%s: Bad format \"%s\"\n", prog, s);
return 0;
case 'B':
case 'b':
if (s[1] == '\0'
|| strcmp(s, "B64") == 0 || strcmp(s, "b64") == 0
|| strcmp(s, "BASE64") == 0 || strcmp(s, "base64") == 0 ) {
if ((flags & OPT_FMT_B64) == 0)
return opt_format_error(s, flags);
*result = FORMAT_BASE64;
} else {
return 0;
}
break;
case 'D':
case 'd':
if ((flags & OPT_FMT_PEMDER) == 0)
if ((flags & OPT_FMT_DER) == 0)
return opt_format_error(s, flags);
*result = FORMAT_ASN1;
break;
@ -313,7 +329,7 @@ int opt_format(const char *s, unsigned long flags, int *result)
case 'P':
case 'p':
if (s[1] == '\0' || strcmp(s, "PEM") == 0 || strcmp(s, "pem") == 0) {
if ((flags & OPT_FMT_PEMDER) == 0)
if ((flags & OPT_FMT_PEM) == 0)
return opt_format_error(s, flags);
*result = FORMAT_PEM;
} else if (strcmp(s, "PVK") == 0 || strcmp(s, "pvk") == 0) {
@ -399,8 +415,10 @@ int opt_cipher_any(const char *name, EVP_CIPHER **cipherp)
{
int ret;
if (name == NULL)
return 1;
if ((ret = opt_cipher_silent(name, cipherp)) == 0)
opt_printf_stderr("%s: Unknown cipher: %s\n", prog, name);
opt_printf_stderr("%s: Unknown option or cipher: %s\n", prog, name);
return ret;
}
@ -410,6 +428,8 @@ int opt_cipher(const char *name, EVP_CIPHER **cipherp)
unsigned long int flags;
EVP_CIPHER *c = NULL;
if (name == NULL)
return 1;
if (opt_cipher_any(name, &c)) {
mode = EVP_CIPHER_get_mode(c);
flags = EVP_CIPHER_get_flags(c);
@ -454,12 +474,22 @@ int opt_md(const char *name, EVP_MD **mdp)
{
int ret;
if (name == NULL)
return 1;
if ((ret = opt_md_silent(name, mdp)) == 0)
opt_printf_stderr("%s: Unknown option or message digest: %s\n", prog,
name != NULL ? name : "\"\"");
opt_printf_stderr("%s: Unknown option or message digest: %s\n",
prog, name);
return ret;
}
int opt_check_md(const char *name)
{
if (opt_md(name, NULL))
return 1;
ERR_clear_error();
return 0;
}
/* Look through a list of name/value pairs. */
int opt_pair(const char *name, const OPT_PAIR* pairs, int *result)
{
@ -961,11 +991,14 @@ int opt_next(void)
case 'E':
case 'F':
case 'f':
case 'A':
case 'a':
if (opt_format(arg,
o->valtype == 'c' ? OPT_FMT_PDS :
o->valtype == 'E' ? OPT_FMT_PDE :
o->valtype == 'F' ? OPT_FMT_PEMDER
: OPT_FMT_ANY, &ival))
o->valtype == 'F' ? OPT_FMT_PEMDER :
o->valtype == 'A' ? OPT_FMT_ASN1 :
OPT_FMT_ANY, &ival))
break;
opt_printf_stderr("%s: Invalid format \"%s\" for option -%s\n",
prog, arg, o->name);
@ -976,6 +1009,11 @@ int opt_next(void)
return o->retval;
}
if (unknown != NULL) {
if (dunno != NULL) {
opt_printf_stderr("%s: Multiple %s or unknown options: -%s and -%s\n",
prog, unknown_name, dunno, p);
return -1;
}
dunno = p;
return unknown->retval;
}
@ -1001,6 +1039,12 @@ char *opt_unknown(void)
return dunno;
}
/* Reset the unknown option; needed by ocsp to allow multiple digest options. */
void reset_unknown(void)
{
dunno = NULL;
}
/* Return the rest of the arguments after parsing flags. */
char **opt_rest(void)
{
@ -1018,6 +1062,31 @@ int opt_num_rest(void)
return i;
}
int opt_check_rest_arg(const char *expected)
{
char *opt = *opt_rest();
if (opt == NULL || *opt == '\0') {
if (expected == NULL)
return 1;
opt_printf_stderr("%s: Missing argument: %s\n", prog, expected);
return 0;
}
if (expected != NULL) {
opt = argv[opt_index + 1];
if (opt == NULL || *opt == '\0')
return 1;
opt_printf_stderr("%s: Extra argument after %s: \"%s\"\n", prog, expected, opt);
return 0;
}
if (opt_unknown() == NULL)
opt_printf_stderr("%s: Extra option: \"%s\"\n", prog, opt);
else
opt_printf_stderr("%s: Extra (unknown) options: \"%s\" \"%s\"\n",
prog, opt_unknown(), opt);
return 0;
}
/* Return a string describing the parameter type. */
static const char *valtype2param(const OPTIONS *o)
{
@ -1063,19 +1132,21 @@ static void opt_print(const OPTIONS *o, int doingparams, int width)
{
const char* help;
char start[80 + 1];
char *p;
int linelen, printlen;
/* Avoid OOB if width is beyond the buffer size of start */
if (width >= (int)sizeof(start))
width = (int)sizeof(start) - 1;
help = o->helpstr ? o->helpstr : "(No additional info)";
if (o->name == OPT_HELP_STR) {
opt_printf_stderr(help, prog);
return;
}
if (o->name == OPT_SECTION_STR) {
} else if (o->name == OPT_SECTION_STR) {
opt_printf_stderr("\n");
opt_printf_stderr(help, prog);
return;
}
if (o->name == OPT_PARAM_STR) {
} else if (o->name == OPT_PARAM_STR) {
opt_printf_stderr("\nParameters:\n");
return;
}
@ -1092,24 +1163,27 @@ static void opt_print(const OPTIONS *o, int doingparams, int width)
}
/* Build up the "-flag [param]" part. */
p = start;
*p++ = ' ';
if (!doingparams)
*p++ = '-';
if (o->name[0])
p += strlen(strcpy(p, o->name));
else
*p++ = '*';
linelen = 0;
printlen = opt_printf_stderr(" %s", !doingparams ? "-" : "");
linelen += (printlen > 0) ? printlen : MAX_OPT_HELP_WIDTH;
printlen = opt_printf_stderr("%s" , o->name[0] ? o->name : "*");
linelen += (printlen > 0) ? printlen : MAX_OPT_HELP_WIDTH;
if (o->valtype != '-') {
*p++ = ' ';
p += strlen(strcpy(p, valtype2param(o)));
printlen = opt_printf_stderr(" %s" , valtype2param(o));
linelen += (printlen > 0) ? printlen : MAX_OPT_HELP_WIDTH;
}
*p = ' ';
if ((int)(p - start) >= MAX_OPT_HELP_WIDTH) {
*p = '\0';
opt_printf_stderr("%s\n", start);
if (linelen >= MAX_OPT_HELP_WIDTH || linelen > width) {
opt_printf_stderr("%s", "\n");
memset(start, ' ', sizeof(start));
linelen = 0;
}
width -= linelen;
start[width] = '\0';
opt_printf_stderr("%s %s\n", start, help);
}
@ -1119,7 +1193,6 @@ void opt_help(const OPTIONS *list)
const OPTIONS *o;
int i, sawparams = 0, width = 5;
int standard_prolog;
char start[80 + 1];
/* Starts with its own help message? */
standard_prolog = list[0].name != OPT_HELP_STR;
@ -1128,14 +1201,18 @@ void opt_help(const OPTIONS *list)
for (o = list; o->name; o++) {
if (o->name == OPT_MORE_STR)
continue;
i = 2 + (int)strlen(o->name);
if (o->valtype != '-')
i += 1 + strlen(valtype2param(o));
if (i < MAX_OPT_HELP_WIDTH && i > width)
if (i > width)
width = i;
OPENSSL_assert(i < (int)sizeof(start));
}
if (width > MAX_OPT_HELP_WIDTH)
width = MAX_OPT_HELP_WIDTH;
if (standard_prolog) {
opt_printf_stderr("Usage: %s [options]\n", prog);
if (list[0].name != OPT_SECTION_STR)

View file

@ -1,5 +1,5 @@
/*
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -7,7 +7,10 @@
* https://www.openssl.org/source/license.html
*/
/* callback functions used by s_client, s_server, and s_time */
/*
* callback functions used by s_client, s_server, and s_time,
* as well as other common logic for those apps
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* for memcpy() and strcmp() */
@ -255,7 +258,8 @@ static const char *get_sigtype(int nid)
return "gost2012_512";
default:
return NULL;
/* Try to output provider-registered sig alg name */
return OBJ_nid2sn(nid);
}
}
@ -324,6 +328,7 @@ static int do_print_sigalgs(BIO *out, SSL *s, int shared)
int ssl_print_sigalgs(BIO *out, SSL *s)
{
const char *name;
int nid;
if (!SSL_is_server(s))
@ -332,7 +337,9 @@ int ssl_print_sigalgs(BIO *out, SSL *s)
do_print_sigalgs(out, s, 1);
if (SSL_get_peer_signature_nid(s, &nid) && nid != NID_undef)
BIO_printf(out, "Peer signing digest: %s\n", OBJ_nid2sn(nid));
if (SSL_get_peer_signature_type_nid(s, &nid))
if (SSL_get0_peer_signature_name(s, &name))
BIO_printf(out, "Peer signature type: %s\n", name);
else if (SSL_get_peer_signature_type_nid(s, &nid))
BIO_printf(out, "Peer signature type: %s\n", get_sigtype(nid));
return 1;
}
@ -412,16 +419,28 @@ int ssl_print_groups(BIO *out, SSL *s, int noshared)
int ssl_print_tmp_key(BIO *out, SSL *s)
{
const char *keyname;
EVP_PKEY *key;
if (!SSL_get_peer_tmp_key(s, &key))
if (!SSL_get_peer_tmp_key(s, &key)) {
if (SSL_version(s) == TLS1_3_VERSION)
BIO_printf(out, "Negotiated TLS1.3 group: %s\n",
SSL_group_to_name(s, SSL_get_negotiated_group(s)));
return 1;
BIO_puts(out, "Server Temp Key: ");
}
BIO_puts(out, "Peer Temp Key: ");
switch (EVP_PKEY_get_id(key)) {
case EVP_PKEY_RSA:
BIO_printf(out, "RSA, %d bits\n", EVP_PKEY_get_bits(key));
break;
case EVP_PKEY_KEYMGMT:
if ((keyname = EVP_PKEY_get0_type_name(key)) == NULL)
keyname = "?";
BIO_printf(out, "%s\n", keyname);
break;
case EVP_PKEY_DH:
BIO_printf(out, "DH, %d bits\n", EVP_PKEY_get_bits(key));
break;
@ -450,12 +469,15 @@ long bio_dump_callback(BIO *bio, int cmd, const char *argp, size_t len,
int argi, long argl, int ret, size_t *processed)
{
BIO *out;
BIO_MMSG_CB_ARGS *mmsgargs;
size_t i;
out = (BIO *)BIO_get_callback_arg(bio);
if (out == NULL)
return ret;
if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
switch (cmd) {
case (BIO_CB_READ | BIO_CB_RETURN):
if (ret > 0 && processed != NULL) {
BIO_printf(out, "read from %p [%p] (%zu bytes => %zu (0x%zX))\n",
(void *)bio, (void *)argp, len, *processed, *processed);
@ -464,7 +486,9 @@ long bio_dump_callback(BIO *bio, int cmd, const char *argp, size_t len,
BIO_printf(out, "read from %p [%p] (%zu bytes => %d)\n",
(void *)bio, (void *)argp, len, ret);
}
} else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
break;
case (BIO_CB_WRITE | BIO_CB_RETURN):
if (ret > 0 && processed != NULL) {
BIO_printf(out, "write to %p [%p] (%zu bytes => %zu (0x%zX))\n",
(void *)bio, (void *)argp, len, *processed, *processed);
@ -473,6 +497,51 @@ long bio_dump_callback(BIO *bio, int cmd, const char *argp, size_t len,
BIO_printf(out, "write to %p [%p] (%zu bytes => %d)\n",
(void *)bio, (void *)argp, len, ret);
}
break;
case (BIO_CB_RECVMMSG | BIO_CB_RETURN):
mmsgargs = (BIO_MMSG_CB_ARGS *)argp;
if (ret > 0) {
for (i = 0; i < *(mmsgargs->msgs_processed); i++) {
BIO_MSG *msg = (BIO_MSG *)((char *)mmsgargs->msg
+ (i * mmsgargs->stride));
BIO_printf(out, "read from %p [%p] (%zu bytes => %zu (0x%zX))\n",
(void *)bio, (void *)msg->data, msg->data_len,
msg->data_len, msg->data_len);
BIO_dump(out, msg->data, msg->data_len);
}
} else if (mmsgargs->num_msg > 0) {
BIO_MSG *msg = mmsgargs->msg;
BIO_printf(out, "read from %p [%p] (%zu bytes => %d)\n",
(void *)bio, (void *)msg->data, msg->data_len, ret);
}
break;
case (BIO_CB_SENDMMSG | BIO_CB_RETURN):
mmsgargs = (BIO_MMSG_CB_ARGS *)argp;
if (ret > 0) {
for (i = 0; i < *(mmsgargs->msgs_processed); i++) {
BIO_MSG *msg = (BIO_MSG *)((char *)mmsgargs->msg
+ (i * mmsgargs->stride));
BIO_printf(out, "write to %p [%p] (%zu bytes => %zu (0x%zX))\n",
(void *)bio, (void *)msg->data, msg->data_len,
msg->data_len, msg->data_len);
BIO_dump(out, msg->data, msg->data_len);
}
} else if (mmsgargs->num_msg > 0) {
BIO_MSG *msg = mmsgargs->msg;
BIO_printf(out, "write to %p [%p] (%zu bytes => %d)\n",
(void *)bio, (void *)msg->data, msg->data_len, ret);
}
break;
default:
/* do nothing */
break;
}
return ret;
}
@ -576,6 +645,7 @@ static STRINT_PAIR handshakes[] = {
{", CertificateStatus", SSL3_MT_CERTIFICATE_STATUS},
{", SupplementalData", SSL3_MT_SUPPLEMENTAL_DATA},
{", KeyUpdate", SSL3_MT_KEY_UPDATE},
{", CompressedCertificate", SSL3_MT_COMPRESSED_CERTIFICATE},
#ifndef OPENSSL_NO_NEXTPROTONEG
{", NextProto", SSL3_MT_NEXT_PROTO},
#endif
@ -688,6 +758,8 @@ static const STRINT_PAIR tlsext_types[] = {
{"session ticket", TLSEXT_TYPE_session_ticket},
{"renegotiation info", TLSEXT_TYPE_renegotiate},
{"signed certificate timestamps", TLSEXT_TYPE_signed_certificate_timestamp},
{"client cert type", TLSEXT_TYPE_client_cert_type},
{"server cert type", TLSEXT_TYPE_server_cert_type},
{"TLS padding", TLSEXT_TYPE_padding},
#ifdef TLSEXT_TYPE_next_proto_neg
{"next protocol", TLSEXT_TYPE_next_proto_neg},
@ -702,6 +774,7 @@ static const STRINT_PAIR tlsext_types[] = {
#ifdef TLSEXT_TYPE_extended_master_secret
{"extended master secret", TLSEXT_TYPE_extended_master_secret},
#endif
{"compress certificate", TLSEXT_TYPE_compress_certificate},
{"key share", TLSEXT_TYPE_key_share},
{"supported versions", TLSEXT_TYPE_supported_versions},
{"psk", TLSEXT_TYPE_psk},
@ -1016,7 +1089,7 @@ void ssl_excert_free(SSL_EXCERT *exc)
while (exc) {
X509_free(exc->cert);
EVP_PKEY_free(exc->key);
sk_X509_pop_free(exc->chain, X509_free);
OSSL_STACK_OF_X509_free(exc->chain);
curr = exc;
exc = exc->next;
OPENSSL_free(curr);
@ -1186,7 +1259,7 @@ static char *hexencode(const unsigned char *data, size_t len)
void print_verify_detail(SSL *s, BIO *bio)
{
int mdpth;
EVP_PKEY *mspki;
EVP_PKEY *mspki = NULL;
long verify_err = SSL_get_verify_result(s);
if (verify_err == X509_V_OK) {
@ -1221,52 +1294,56 @@ void print_verify_detail(SSL *s, BIO *bio)
hexdata = hexencode(data + dlen - TLSA_TAIL_SIZE, TLSA_TAIL_SIZE);
else
hexdata = hexencode(data, dlen);
BIO_printf(bio, "DANE TLSA %d %d %d %s%s %s at depth %d\n",
BIO_printf(bio, "DANE TLSA %d %d %d %s%s ",
usage, selector, mtype,
(dlen > TLSA_TAIL_SIZE) ? "..." : "", hexdata,
(mspki != NULL) ? "signed the certificate" :
mdpth ? "matched TA certificate" : "matched EE certificate",
mdpth);
(dlen > TLSA_TAIL_SIZE) ? "..." : "", hexdata);
if (SSL_get0_peer_rpk(s) == NULL)
BIO_printf(bio, "%s certificate at depth %d\n",
(mspki != NULL) ? "signed the peer" :
mdpth ? "matched the TA" : "matched the EE", mdpth);
else
BIO_printf(bio, "matched the peer raw public key\n");
OPENSSL_free(hexdata);
}
}
void print_ssl_summary(SSL *s)
{
const char *sigalg;
const SSL_CIPHER *c;
X509 *peer;
X509 *peer = SSL_get0_peer_certificate(s);
EVP_PKEY *peer_rpk = SSL_get0_peer_rpk(s);
int nid;
BIO_printf(bio_err, "Protocol version: %s\n", SSL_get_version(s));
print_raw_cipherlist(s);
c = SSL_get_current_cipher(s);
BIO_printf(bio_err, "Ciphersuite: %s\n", SSL_CIPHER_get_name(c));
do_print_sigalgs(bio_err, s, 0);
peer = SSL_get0_peer_certificate(s);
if (peer != NULL) {
int nid;
BIO_puts(bio_err, "Peer certificate: ");
X509_NAME_print_ex(bio_err, X509_get_subject_name(peer),
0, get_nameopt());
BIO_puts(bio_err, "\n");
if (SSL_get_peer_signature_nid(s, &nid))
BIO_printf(bio_err, "Hash used: %s\n", OBJ_nid2sn(nid));
if (SSL_get_peer_signature_type_nid(s, &nid))
BIO_printf(bio_err, "Signature type: %s\n", get_sigtype(nid));
if (SSL_get0_peer_signature_name(s, &sigalg))
BIO_printf(bio_err, "Signature type: %s\n", sigalg);
print_verify_detail(s, bio_err);
} else if (peer_rpk != NULL) {
BIO_printf(bio_err, "Peer used raw public key\n");
if (SSL_get0_peer_signature_name(s, &sigalg))
BIO_printf(bio_err, "Signature type: %s\n", sigalg);
print_verify_detail(s, bio_err);
} else {
BIO_puts(bio_err, "No peer certificate\n");
BIO_puts(bio_err, "No peer certificate or raw public key\n");
}
#ifndef OPENSSL_NO_EC
ssl_print_point_formats(bio_err, s);
if (SSL_is_server(s))
ssl_print_groups(bio_err, s, 1);
else
ssl_print_tmp_key(bio_err, s);
#else
if (!SSL_is_server(s))
ssl_print_tmp_key(bio_err, s);
#endif
ssl_print_tmp_key(bio_err, s);
}
int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str,
@ -1590,3 +1667,25 @@ void print_ca_names(BIO *bio, SSL *s)
BIO_write(bio, "\n", 1);
}
}
void ssl_print_secure_renegotiation_notes(BIO *bio, SSL *s)
{
if (SSL_VERSION_ALLOWS_RENEGOTIATION(s)) {
BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
SSL_get_secure_renegotiation_support(s) ? "" : " NOT");
} else {
BIO_printf(bio, "This TLS version forbids renegotiation.\n");
}
}
int progress_cb(EVP_PKEY_CTX *ctx)
{
BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
static const char symbols[] = ".+*\n";
char c = (p >= 0 && (size_t)p <= sizeof(symbols) - 1) ? symbols[p] : '?';
BIO_write(b, &c, 1);
(void)BIO_flush(b);
return 1;
}

View file

@ -37,15 +37,10 @@ typedef unsigned int u_int;
#ifndef OPENSSL_NO_SOCK
# include "internal/e_os.h"
# include "apps.h"
# include "s_apps.h"
# include "internal/sockets.h"
# if defined(__TANDEM)
# if defined(OPENSSL_TANDEM_FLOSS)
# include <floss.h(floss_read)>
# endif
# endif
# include "internal/sockets.h" /* for openssl_fdset() */
# include <openssl/bio.h>
# include <openssl/err.h>
@ -64,6 +59,9 @@ BIO_ADDR *ourpeer = NULL;
* AF_UNSPEC
* @type: socket type, must be SOCK_STREAM or SOCK_DGRAM
* @protocol: socket protocol, e.g. IPPROTO_TCP or IPPROTO_UDP (or 0 for any)
* @tfo: flag to enable TCP Fast Open
* @doconn: whether we should call BIO_connect() on the socket
* @ba_ret: BIO_ADDR for the remote peer, to be freed by caller
*
* This will create a socket and use it to connect to a host:port, or if
* family == AF_UNIX, to the path found in host.
@ -76,7 +74,8 @@ BIO_ADDR *ourpeer = NULL;
*/
int init_client(int *sock, const char *host, const char *port,
const char *bindhost, const char *bindport,
int family, int type, int protocol)
int family, int type, int protocol, int tfo, int doconn,
BIO_ADDR **ba_ret)
{
BIO_ADDRINFO *res = NULL;
BIO_ADDRINFO *bindaddr = NULL;
@ -84,6 +83,7 @@ int init_client(int *sock, const char *host, const char *port,
const BIO_ADDRINFO *bi = NULL;
int found = 0;
int ret;
int options = 0;
if (BIO_sock_init() != 1)
return 0;
@ -160,14 +160,30 @@ int init_client(int *sock, const char *host, const char *port,
BIO_free(tmpbio);
}
#endif
if (BIO_ADDRINFO_protocol(ai) == IPPROTO_TCP) {
options |= BIO_SOCK_NODELAY;
if (tfo)
options |= BIO_SOCK_TFO;
}
if (!BIO_connect(*sock, BIO_ADDRINFO_address(ai),
BIO_ADDRINFO_protocol(ai) == IPPROTO_TCP ? BIO_SOCK_NODELAY : 0)) {
if (doconn && !BIO_connect(*sock, BIO_ADDRINFO_address(ai), options)) {
BIO_closesocket(*sock);
*sock = INVALID_SOCKET;
continue;
}
/* Save the address */
if (tfo || !doconn) {
if (ba_ret == NULL) {
BIO_printf(bio_err, "Internal error\n");
BIO_closesocket(*sock);
*sock = INVALID_SOCKET;
goto out;
}
*ba_ret = BIO_ADDR_dup(BIO_ADDRINFO_address(ai));
}
/* Success, don't try any more addresses */
break;
}
@ -188,6 +204,13 @@ int init_client(int *sock, const char *host, const char *port,
}
ERR_print_errors(bio_err);
} else {
char *hostname = NULL;
hostname = BIO_ADDR_hostname_string(BIO_ADDRINFO_address(ai), 1);
if (hostname != NULL) {
BIO_printf(bio_err, "Connecting to %s\n", hostname);
OPENSSL_free(hostname);
}
/* Remove any stale errors from previous connection attempts */
ERR_clear_error();
ret = 1;
@ -200,6 +223,25 @@ out:
return ret;
}
void get_sock_info_address(int asock, char **hostname, char **service)
{
union BIO_sock_info_u info;
if (hostname != NULL)
*hostname = NULL;
if (service != NULL)
*service = NULL;
if ((info.addr = BIO_ADDR_new()) != NULL
&& BIO_sock_info(asock, BIO_SOCK_INFO_ADDRESS, &info)) {
if (hostname != NULL)
*hostname = BIO_ADDR_hostname_string(info.addr, 1);
if (service != NULL)
*service = BIO_ADDR_service_string(info.addr, 1);
}
BIO_ADDR_free(info.addr);
}
int report_server_accept(BIO *out, int asock, int with_address, int with_pid)
{
int success = 1;
@ -207,30 +249,24 @@ int report_server_accept(BIO *out, int asock, int with_address, int with_pid)
if (BIO_printf(out, "ACCEPT") <= 0)
return 0;
if (with_address) {
union BIO_sock_info_u info;
char *hostname = NULL;
char *service = NULL;
char *hostname, *service;
if ((info.addr = BIO_ADDR_new()) != NULL
&& BIO_sock_info(asock, BIO_SOCK_INFO_ADDRESS, &info)
&& (hostname = BIO_ADDR_hostname_string(info.addr, 1)) != NULL
&& (service = BIO_ADDR_service_string(info.addr, 1)) != NULL) {
get_sock_info_address(asock, &hostname, &service);
success = hostname != NULL && service != NULL;
if (success)
success = BIO_printf(out,
strchr(hostname, ':') == NULL
? /* IPv4 */ " %s:%s"
: /* IPv6 */ " [%s]:%s",
hostname, service) > 0;
} else {
else
(void)BIO_printf(out, "unknown:error\n");
success = 0;
}
OPENSSL_free(hostname);
OPENSSL_free(service);
BIO_ADDR_free(info.addr);
}
if (with_pid)
success = success && BIO_printf(out, " PID=%d", getpid()) > 0;
success = success && BIO_printf(out, "\n") > 0;
success *= BIO_printf(out, " PID=%d", getpid()) > 0;
success *= BIO_printf(out, "\n") > 0;
(void)BIO_flush(out);
return success;
@ -258,7 +294,8 @@ int report_server_accept(BIO *out, int asock, int with_address, int with_pid)
*/
int do_server(int *accept_sock, const char *host, const char *port,
int family, int type, int protocol, do_server_cb cb,
unsigned char *context, int naccept, BIO *bio_s_out)
unsigned char *context, int naccept, BIO *bio_s_out,
int tfo)
{
int asock = 0;
int sock;
@ -292,6 +329,8 @@ int do_server(int *accept_sock, const char *host, const char *port,
sock_protocol = BIO_ADDRINFO_protocol(res);
sock_address = BIO_ADDRINFO_address(res);
next = BIO_ADDRINFO_next(res);
if (tfo && sock_type == SOCK_STREAM)
sock_options |= BIO_SOCK_TFO;
#ifdef AF_INET6
if (sock_family == AF_INET6)
sock_options |= BIO_SOCK_V6_ONLY;

View file

@ -1,5 +1,5 @@
/*
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2005 Nokia. All rights reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
@ -87,7 +87,7 @@ static int ssl_srp_verify_param_cb(SSL *s, void *arg)
"SRP param N and g are not known params, going to check deeper.\n");
/*
* The srp_moregroups is a real debugging feature. Implementors
* The srp_moregroups is a real debugging feature. Implementers
* should rather add the value to the known ones. The minimal size
* has already been tested.
*/

View file

@ -120,7 +120,7 @@ typedef struct _SocketPairTimeoutBlock {
} SPTB;
# ifdef TERM_SOCK_TEST
/*----------------------------------------------------------------------------*/
/* */
/*----------------------------------------------------------------------------*/
@ -160,7 +160,7 @@ int main (int argc, char *argv[], char *envp[])
}
# endif
/*----------------------------------------------------------------------------*/
/* */
/*----------------------------------------------------------------------------*/
@ -275,7 +275,7 @@ int TerminalSocket (int FunctionCode, int *ReturnSocket)
return TERM_SOCK_SUCCESS;
}
/*----------------------------------------------------------------------------*/
/* */
/*----------------------------------------------------------------------------*/
@ -485,7 +485,7 @@ static int CreateSocketPair (int SocketFamily,
return (0) ;
}
/*----------------------------------------------------------------------------*/
/* */
/*----------------------------------------------------------------------------*/
@ -499,7 +499,7 @@ static void SocketPairTimeoutAst (int astparm)
return;
}
/*----------------------------------------------------------------------------*/
/* */
/*----------------------------------------------------------------------------*/
@ -538,7 +538,7 @@ static int TerminalDeviceAst (int astparm)
return status;
}
/*----------------------------------------------------------------------------*/
/* */
/*----------------------------------------------------------------------------*/

View file

@ -1,5 +1,5 @@
/*
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -10,6 +10,8 @@
/* We need to use some deprecated APIs */
#define OPENSSL_SUPPRESS_DEPRECATED
#include "internal/e_os.h"
#include <string.h>
#include <openssl/evp.h>
#include <openssl/err.h>
@ -21,6 +23,9 @@
#include <openssl/store.h>
#include <openssl/core_names.h>
#include <openssl/rand.h>
#include <openssl/safestack.h>
#include <openssl/ssl.h>
#include <openssl/tls1.h>
#include "apps.h"
#include "app_params.h"
#include "progs.h"
@ -53,6 +58,7 @@ IS_FETCHABLE(mac, EVP_MAC)
IS_FETCHABLE(kdf, EVP_KDF)
IS_FETCHABLE(rand, EVP_RAND)
IS_FETCHABLE(keymgmt, EVP_KEYMGMT)
IS_FETCHABLE(skeymgmt, EVP_SKEYMGMT)
IS_FETCHABLE(signature, EVP_SIGNATURE)
IS_FETCHABLE(kem, EVP_KEM)
IS_FETCHABLE(asym_cipher, EVP_ASYM_CIPHER)
@ -98,11 +104,12 @@ static void collect_ciphers(EVP_CIPHER *cipher, void *stack)
STACK_OF(EVP_CIPHER) *cipher_stack = stack;
if (is_cipher_fetchable(cipher)
&& sk_EVP_CIPHER_push(cipher_stack, cipher) > 0)
EVP_CIPHER_up_ref(cipher);
&& EVP_CIPHER_up_ref(cipher)
&& sk_EVP_CIPHER_push(cipher_stack, cipher) <= 0)
EVP_CIPHER_free(cipher); /* up-ref successful but push to stack failed */
}
static void list_ciphers(void)
static void list_ciphers(const char *prefix)
{
STACK_OF(EVP_CIPHER) *ciphers = sk_EVP_CIPHER_new(cipher_cmp);
int i;
@ -113,12 +120,12 @@ static void list_ciphers(void)
}
#ifndef OPENSSL_NO_DEPRECATED_3_0
if (include_legacy()) {
BIO_printf(bio_out, "Legacy:\n");
BIO_printf(bio_out, "%sLegacy:\n", prefix);
EVP_CIPHER_do_all_sorted(legacy_cipher_fn, bio_out);
}
#endif
BIO_printf(bio_out, "Provided:\n");
BIO_printf(bio_out, "%sProvided:\n", prefix);
EVP_CIPHER_do_all_provided(app_get0_libctx(), collect_ciphers, ciphers);
sk_EVP_CIPHER_sort(ciphers);
for (i = 0; i < sk_EVP_CIPHER_num(ciphers); i++) {
@ -182,11 +189,12 @@ static void collect_digests(EVP_MD *digest, void *stack)
STACK_OF(EVP_MD) *digest_stack = stack;
if (is_digest_fetchable(digest)
&& sk_EVP_MD_push(digest_stack, digest) > 0)
EVP_MD_up_ref(digest);
&& EVP_MD_up_ref(digest)
&& sk_EVP_MD_push(digest_stack, digest) <= 0)
EVP_MD_free(digest); /* up-ref successful but push to stack failed */
}
static void list_digests(void)
static void list_digests(const char *prefix)
{
STACK_OF(EVP_MD) *digests = sk_EVP_MD_new(md_cmp);
int i;
@ -197,12 +205,12 @@ static void list_digests(void)
}
#ifndef OPENSSL_NO_DEPRECATED_3_0
if (include_legacy()) {
BIO_printf(bio_out, "Legacy:\n");
BIO_printf(bio_out, "%sLegacy:\n", prefix);
EVP_MD_do_all_sorted(legacy_md_fn, bio_out);
}
#endif
BIO_printf(bio_out, "Provided:\n");
BIO_printf(bio_out, "%sProvided:\n", prefix);
EVP_MD_do_all_provided(app_get0_libctx(), collect_digests, digests);
sk_EVP_MD_sort(digests);
for (i = 0; i < sk_EVP_MD_num(digests); i++) {
@ -314,8 +322,9 @@ static void collect_kdfs(EVP_KDF *kdf, void *stack)
STACK_OF(EVP_KDF) *kdf_stack = stack;
if (is_kdf_fetchable(kdf)
&& sk_EVP_KDF_push(kdf_stack, kdf) > 0)
EVP_KDF_up_ref(kdf);
&& EVP_KDF_up_ref(kdf)
&& sk_EVP_KDF_push(kdf_stack, kdf) <= 0)
EVP_KDF_free(kdf); /* up-ref successful but push to stack failed */
}
static void list_kdfs(void)
@ -384,8 +393,9 @@ static void collect_rands(EVP_RAND *rand, void *stack)
STACK_OF(EVP_RAND) *rand_stack = stack;
if (is_rand_fetchable(rand)
&& sk_EVP_RAND_push(rand_stack, rand) > 0)
EVP_RAND_up_ref(rand);
&& EVP_RAND_up_ref(rand)
&& sk_EVP_RAND_push(rand_stack, rand) <= 0)
EVP_RAND_free(rand); /* up-ref successful but push to stack failed */
}
static void list_random_generators(void)
@ -510,8 +520,9 @@ static void collect_encoders(OSSL_ENCODER *encoder, void *stack)
STACK_OF(OSSL_ENCODER) *encoder_stack = stack;
if (is_encoder_fetchable(encoder)
&& sk_OSSL_ENCODER_push(encoder_stack, encoder) > 0)
OSSL_ENCODER_up_ref(encoder);
&& OSSL_ENCODER_up_ref(encoder)
&& sk_OSSL_ENCODER_push(encoder_stack, encoder) <= 0)
OSSL_ENCODER_free(encoder); /* up-ref successful but push to stack failed */
}
static void list_encoders(void)
@ -575,8 +586,9 @@ static void collect_decoders(OSSL_DECODER *decoder, void *stack)
STACK_OF(OSSL_DECODER) *decoder_stack = stack;
if (is_decoder_fetchable(decoder)
&& sk_OSSL_DECODER_push(decoder_stack, decoder) > 0)
OSSL_DECODER_up_ref(decoder);
&& OSSL_DECODER_up_ref(decoder)
&& sk_OSSL_DECODER_push(decoder_stack, decoder) <= 0)
OSSL_DECODER_free(decoder); /* up-ref successful but push to stack failed */
}
static void list_decoders(void)
@ -637,8 +649,9 @@ static void collect_keymanagers(EVP_KEYMGMT *km, void *stack)
STACK_OF(EVP_KEYMGMT) *km_stack = stack;
if (is_keymgmt_fetchable(km)
&& sk_EVP_KEYMGMT_push(km_stack, km) > 0)
EVP_KEYMGMT_up_ref(km);
&& EVP_KEYMGMT_up_ref(km)
&& sk_EVP_KEYMGMT_push(km_stack, km) <= 0)
EVP_KEYMGMT_free(km); /* up-ref successful but push to stack failed */
}
static void list_keymanagers(void)
@ -687,6 +700,61 @@ static void list_keymanagers(void)
sk_EVP_KEYMGMT_pop_free(km_stack, EVP_KEYMGMT_free);
}
DEFINE_STACK_OF(EVP_SKEYMGMT)
static int skeymanager_cmp(const EVP_SKEYMGMT * const *a,
const EVP_SKEYMGMT * const *b)
{
return strcmp(OSSL_PROVIDER_get0_name(EVP_SKEYMGMT_get0_provider(*a)),
OSSL_PROVIDER_get0_name(EVP_SKEYMGMT_get0_provider(*b)));
}
static void collect_skeymanagers(EVP_SKEYMGMT *km, void *stack)
{
STACK_OF(EVP_SKEYMGMT) *km_stack = stack;
if (is_skeymgmt_fetchable(km)
&& sk_EVP_SKEYMGMT_push(km_stack, km) > 0)
EVP_SKEYMGMT_up_ref(km);
}
static void list_skeymanagers(void)
{
int i;
STACK_OF(EVP_SKEYMGMT) *km_stack = sk_EVP_SKEYMGMT_new(skeymanager_cmp);
EVP_SKEYMGMT_do_all_provided(app_get0_libctx(), collect_skeymanagers,
km_stack);
sk_EVP_SKEYMGMT_sort(km_stack);
for (i = 0; i < sk_EVP_SKEYMGMT_num(km_stack); i++) {
EVP_SKEYMGMT *k = sk_EVP_SKEYMGMT_value(km_stack, i);
STACK_OF(OPENSSL_CSTRING) *names = NULL;
if (select_name != NULL && !EVP_SKEYMGMT_is_a(k, select_name))
continue;
names = sk_OPENSSL_CSTRING_new(name_cmp);
if (names != NULL && EVP_SKEYMGMT_names_do_all(k, collect_names, names)) {
const char *desc = EVP_SKEYMGMT_get0_description(k);
BIO_printf(bio_out, " Name: ");
if (desc != NULL)
BIO_printf(bio_out, "%s", desc);
else
BIO_printf(bio_out, "%s", sk_OPENSSL_CSTRING_value(names, 0));
BIO_printf(bio_out, "\n");
BIO_printf(bio_out, " Type: Provider Algorithm\n");
BIO_printf(bio_out, " IDs: ");
print_names(bio_out, names);
BIO_printf(bio_out, " @ %s\n",
OSSL_PROVIDER_get0_name(EVP_SKEYMGMT_get0_provider(k)));
}
sk_OPENSSL_CSTRING_free(names);
}
sk_EVP_SKEYMGMT_pop_free(km_stack, EVP_SKEYMGMT_free);
}
DEFINE_STACK_OF(EVP_SIGNATURE)
static int signature_cmp(const EVP_SIGNATURE * const *a,
const EVP_SIGNATURE * const *b)
@ -700,8 +768,9 @@ static void collect_signatures(EVP_SIGNATURE *sig, void *stack)
STACK_OF(EVP_SIGNATURE) *sig_stack = stack;
if (is_signature_fetchable(sig)
&& sk_EVP_SIGNATURE_push(sig_stack, sig) > 0)
EVP_SIGNATURE_up_ref(sig);
&& EVP_SIGNATURE_up_ref(sig)
&& sk_EVP_SIGNATURE_push(sig_stack, sig) <= 0)
EVP_SIGNATURE_free(sig); /* up-ref successful but push to stack failed */
}
static void list_signatures(void)
@ -747,6 +816,90 @@ static void list_signatures(void)
BIO_printf(bio_out, " -\n");
}
static int list_provider_tls_sigalgs(const OSSL_PARAM params[], void *data)
{
const OSSL_PARAM *p;
/* Get registered IANA name */
p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME);
if (p != NULL && p->data_type == OSSL_PARAM_UTF8_STRING) {
if (*((int *)data) > 0)
BIO_printf(bio_out, ":");
BIO_printf(bio_out, "%s", (char *)(p->data));
/* mark presence of a provider-based sigalg */
*((int *)data) = 2;
}
/* As built-in providers don't have this capability, never error */
return 1;
}
static int list_tls_sigalg_caps(OSSL_PROVIDER *provider, void *cbdata)
{
OSSL_PROVIDER_get_capabilities(provider, "TLS-SIGALG",
list_provider_tls_sigalgs,
cbdata);
/* As built-in providers don't have this capability, never error */
return 1;
}
#if !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_TLS1_2)
static void list_tls_groups(int version, int all)
{
SSL_CTX *ctx = NULL;
STACK_OF(OPENSSL_CSTRING) *groups;
size_t i, num;
if ((groups = sk_OPENSSL_CSTRING_new_null()) == NULL) {
BIO_printf(bio_err, "ERROR: Memory allocation\n");
return;
}
if ((ctx = SSL_CTX_new(TLS_method())) == NULL) {
BIO_printf(bio_err, "ERROR: Memory allocation\n");
goto err;
}
if (!SSL_CTX_set_min_proto_version(ctx, version)
|| !SSL_CTX_set_max_proto_version(ctx, version)) {
BIO_printf(bio_err, "ERROR: setting TLS protocol version\n");
goto err;
}
if (!SSL_CTX_get0_implemented_groups(ctx, all, groups)) {
BIO_printf(bio_err, "ERROR: getting implemented TLS group list\n");
goto err;
}
num = sk_OPENSSL_CSTRING_num(groups);
for (i = 0; i < num; ++i) {
BIO_printf(bio_out, "%s%c", sk_OPENSSL_CSTRING_value(groups, i),
(i < num - 1) ? ':' : '\n');
}
err:
SSL_CTX_free(ctx);
sk_OPENSSL_CSTRING_free(groups);
return;
}
#endif
static void list_tls_signatures(void)
{
int tls_sigalg_listed = 0;
char *builtin_sigalgs = SSL_get1_builtin_sigalgs(app_get0_libctx());
if (builtin_sigalgs != NULL) {
if (builtin_sigalgs[0] != 0) {
BIO_printf(bio_out, "%s", builtin_sigalgs);
tls_sigalg_listed = 1;
}
OPENSSL_free(builtin_sigalgs);
}
if (!OSSL_PROVIDER_do_all(NULL, list_tls_sigalg_caps, &tls_sigalg_listed))
BIO_printf(bio_err,
"ERROR: could not list all provider signature algorithms\n");
if (tls_sigalg_listed < 2)
BIO_printf(bio_out,
"\nNo TLS sig algs registered by currently active providers");
BIO_printf(bio_out, "\n");
}
DEFINE_STACK_OF(EVP_KEM)
static int kem_cmp(const EVP_KEM * const *a,
const EVP_KEM * const *b)
@ -760,8 +913,9 @@ static void collect_kem(EVP_KEM *kem, void *stack)
STACK_OF(EVP_KEM) *kem_stack = stack;
if (is_kem_fetchable(kem)
&& sk_EVP_KEM_push(kem_stack, kem) > 0)
EVP_KEM_up_ref(kem);
&& EVP_KEM_up_ref(kem)
&& sk_EVP_KEM_push(kem_stack, kem) <= 0)
EVP_KEM_free(kem); /* up-ref successful but push to stack failed */
}
static void list_kems(void)
@ -819,8 +973,9 @@ static void collect_asymciph(EVP_ASYM_CIPHER *asym_cipher, void *stack)
STACK_OF(EVP_ASYM_CIPHER) *asym_cipher_stack = stack;
if (is_asym_cipher_fetchable(asym_cipher)
&& sk_EVP_ASYM_CIPHER_push(asym_cipher_stack, asym_cipher) > 0)
EVP_ASYM_CIPHER_up_ref(asym_cipher);
&& EVP_ASYM_CIPHER_up_ref(asym_cipher)
&& sk_EVP_ASYM_CIPHER_push(asym_cipher_stack, asym_cipher) <= 0)
EVP_ASYM_CIPHER_free(asym_cipher); /* up-ref successful but push to stack failed */
}
static void list_asymciphers(void)
@ -881,8 +1036,9 @@ static void collect_kex(EVP_KEYEXCH *kex, void *stack)
STACK_OF(EVP_KEYEXCH) *kex_stack = stack;
if (is_keyexch_fetchable(kex)
&& sk_EVP_KEYEXCH_push(kex_stack, kex) > 0)
EVP_KEYEXCH_up_ref(kex);
&& EVP_KEYEXCH_up_ref(kex)
&& sk_EVP_KEYEXCH_push(kex_stack, kex) <= 0)
EVP_KEYEXCH_free(kex); /* up-ref successful but push to stack failed */
}
static void list_keyexchanges(void)
@ -1161,8 +1317,9 @@ static void collect_store_loaders(OSSL_STORE_LOADER *store, void *stack)
{
STACK_OF(OSSL_STORE_LOADER) *store_stack = stack;
if (sk_OSSL_STORE_LOADER_push(store_stack, store) > 0)
OSSL_STORE_LOADER_up_ref(store);
if (OSSL_STORE_LOADER_up_ref(store)
&& sk_OSSL_STORE_LOADER_push(store_stack, store) <= 0)
OSSL_STORE_LOADER_free(store); /* up-ref successful but push to stack failed */
}
static void list_store_loaders(void)
@ -1209,6 +1366,7 @@ static int provider_cmp(const OSSL_PROVIDER * const *a,
static int collect_providers(OSSL_PROVIDER *provider, void *stack)
{
STACK_OF(OSSL_PROVIDER) *provider_stack = stack;
/*
* If OK - result is the index of inserted data
* Error - result is -1 or 0
@ -1297,6 +1455,9 @@ static void list_engines(void)
static void list_disabled(void)
{
BIO_puts(bio_out, "Disabled algorithms:\n");
#ifdef OPENSSL_NO_ARGON2
BIO_puts(bio_out, "ARGON2\n");
#endif
#ifdef OPENSSL_NO_ARIA
BIO_puts(bio_out, "ARIA\n");
#endif
@ -1345,6 +1506,9 @@ static void list_disabled(void)
#ifdef OPENSSL_NO_EC
BIO_puts(bio_out, "EC\n");
#endif
#ifdef OPENSSL_NO_ECX
BIO_puts(bio_out, "ECX\n");
#endif
#ifdef OPENSSL_NO_EC2M
BIO_puts(bio_out, "EC2M\n");
#endif
@ -1432,23 +1596,41 @@ static void list_disabled(void)
#ifdef OPENSSL_NO_WHIRLPOOL
BIO_puts(bio_out, "WHIRLPOOL\n");
#endif
#ifndef ZLIB
#ifdef OPENSSL_NO_ZLIB
BIO_puts(bio_out, "ZLIB\n");
#endif
#ifdef OPENSSL_NO_BROTLI
BIO_puts(bio_out, "BROTLI\n");
#endif
#ifdef OPENSSL_NO_ZSTD
BIO_puts(bio_out, "ZSTD\n");
#endif
}
/* Unified enum for help and list commands. */
typedef enum HELPLIST_CHOICE {
OPT_COMMON,
OPT_ONE, OPT_VERBOSE,
OPT_ALL_ARGORITHMS,
OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS,
OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS,
OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED,
OPT_KDF_ALGORITHMS, OPT_RANDOM_INSTANCES, OPT_RANDOM_GENERATORS,
OPT_ENCODERS, OPT_DECODERS, OPT_KEYMANAGERS, OPT_KEYEXCHANGE_ALGORITHMS,
OPT_KEM_ALGORITHMS, OPT_SIGNATURE_ALGORITHMS, OPT_ASYM_CIPHER_ALGORITHMS,
OPT_STORE_LOADERS, OPT_PROVIDER_INFO,
OPT_OBJECTS, OPT_SELECT_NAME,
OPT_SKEYMANAGERS,
OPT_KEM_ALGORITHMS, OPT_SIGNATURE_ALGORITHMS,
OPT_TLS_SIGNATURE_ALGORITHMS, OPT_ASYM_CIPHER_ALGORITHMS,
OPT_STORE_LOADERS, OPT_PROVIDER_INFO, OPT_OBJECTS,
OPT_SELECT_NAME,
#if !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_TLS1_2)
OPT_ALL_TLS_GROUPS, OPT_TLS_GROUPS,
# if !defined(OPENSSL_NO_TLS1_2)
OPT_TLS1_2,
# endif
# if !defined(OPENSSL_NO_TLS1_3)
OPT_TLS1_3,
# endif
#endif
#ifndef OPENSSL_NO_DEPRECATED_3_0
OPT_ENGINES,
#endif
@ -1466,6 +1648,7 @@ const OPTIONS list_options[] = {
{"select", OPT_SELECT_NAME, 's', "Select a single algorithm"},
{"commands", OPT_COMMANDS, '-', "List of standard commands"},
{"standard-commands", OPT_COMMANDS, '-', "List of standard commands"},
{"all-algorithms", OPT_ALL_ARGORITHMS, '-', "List of all algorithms"},
#ifndef OPENSSL_NO_DEPRECATED_3_0
{"digest-commands", OPT_DIGEST_COMMANDS, '-',
"List of message digest commands (deprecated)"},
@ -1489,12 +1672,15 @@ const OPTIONS list_options[] = {
{"encoders", OPT_ENCODERS, '-', "List of encoding methods" },
{"decoders", OPT_DECODERS, '-', "List of decoding methods" },
{"key-managers", OPT_KEYMANAGERS, '-', "List of key managers" },
{"skey-managers", OPT_SKEYMANAGERS, '-', "List of symmetric key managers" },
{"key-exchange-algorithms", OPT_KEYEXCHANGE_ALGORITHMS, '-',
"List of key exchange algorithms" },
{"kem-algorithms", OPT_KEM_ALGORITHMS, '-',
"List of key encapsulation mechanism algorithms" },
{"signature-algorithms", OPT_SIGNATURE_ALGORITHMS, '-',
"List of signature algorithms" },
{"tls-signature-algorithms", OPT_TLS_SIGNATURE_ALGORITHMS, '-',
"List of TLS signature algorithms" },
{"asymcipher-algorithms", OPT_ASYM_CIPHER_ALGORITHMS, '-',
"List of asymmetric cipher algorithms" },
{"public-key-algorithms", OPT_PK_ALGORITHMS, '-',
@ -1503,6 +1689,20 @@ const OPTIONS list_options[] = {
"List of public key methods"},
{"store-loaders", OPT_STORE_LOADERS, '-',
"List of store loaders"},
#if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3)
{"tls-groups", OPT_TLS_GROUPS, '-',
"List implemented TLS key exchange 'groups'" },
{"all-tls-groups", OPT_ALL_TLS_GROUPS, '-',
"List implemented TLS key exchange 'groups' and all aliases" },
# ifndef OPENSSL_NO_TLS1_2
{"tls1_2", OPT_TLS1_2, '-',
"When listing 'groups', list those compatible with TLS1.2"},
# endif
# ifndef OPENSSL_NO_TLS1_3
{"tls1_3", OPT_TLS1_3, '-',
"When listing 'groups', list those compatible with TLS1.3"},
# endif
#endif
{"providers", OPT_PROVIDER_INFO, '-',
"List of provider information"},
#ifndef OPENSSL_NO_DEPRECATED_3_0
@ -1524,8 +1724,18 @@ int list_main(int argc, char **argv)
char *prog;
HELPLIST_CHOICE o;
int one = 0, done = 0;
int print_newline = 0;
#if !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_TLS1_2)
int all_tls_groups = 0;
# if !defined(OPENSSL_NO_TLS1_3)
unsigned int tls_version = TLS1_3_VERSION;
# else
unsigned int tls_version = TLS1_2_VERSION;
# endif
#endif
struct {
unsigned int commands:1;
unsigned int all_algorithms:1;
unsigned int random_instances:1;
unsigned int random_generators:1;
unsigned int digest_commands:1;
@ -1537,9 +1747,12 @@ int list_main(int argc, char **argv)
unsigned int encoder_algorithms:1;
unsigned int decoder_algorithms:1;
unsigned int keymanager_algorithms:1;
unsigned int skeymanager_algorithms:1;
unsigned int signature_algorithms:1;
unsigned int tls_signature_algorithms:1;
unsigned int keyexchange_algorithms:1;
unsigned int kem_algorithms:1;
unsigned int tls_groups:1;
unsigned int asym_cipher_algorithms:1;
unsigned int pk_algorithms:1;
unsigned int pk_method:1;
@ -1569,6 +1782,9 @@ opthelp:
case OPT_ONE:
one = 1;
break;
case OPT_ALL_ARGORITHMS:
todo.all_algorithms = 1;
break;
case OPT_COMMANDS:
todo.commands = 1;
break;
@ -1605,15 +1821,40 @@ opthelp:
case OPT_KEYMANAGERS:
todo.keymanager_algorithms = 1;
break;
case OPT_SKEYMANAGERS:
todo.skeymanager_algorithms = 1;
break;
case OPT_SIGNATURE_ALGORITHMS:
todo.signature_algorithms = 1;
break;
case OPT_TLS_SIGNATURE_ALGORITHMS:
todo.tls_signature_algorithms = 1;
break;
case OPT_KEYEXCHANGE_ALGORITHMS:
todo.keyexchange_algorithms = 1;
break;
case OPT_KEM_ALGORITHMS:
todo.kem_algorithms = 1;
break;
#if !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_TLS1_2)
case OPT_TLS_GROUPS:
todo.tls_groups = 1;
break;
case OPT_ALL_TLS_GROUPS:
all_tls_groups = 1;
todo.tls_groups = 1;
break;
# if !defined(OPENSSL_NO_TLS1_2)
case OPT_TLS1_2:
tls_version = TLS1_2_VERSION;
break;
# endif
# if !defined(OPENSSL_NO_TLS1_3)
case OPT_TLS1_3:
tls_version = TLS1_3_VERSION;
break;
# endif
#endif
case OPT_ASYM_CIPHER_ALGORITHMS:
todo.asym_cipher_algorithms = 1;
break;
@ -1658,57 +1899,105 @@ opthelp:
}
/* No extra arguments. */
if (opt_num_rest() != 0)
if (!opt_check_rest_arg(NULL))
goto opthelp;
#define MAYBE_ADD_NL(cmd) \
do { \
if (print_newline++) { \
BIO_printf(bio_out, "\n"); \
} \
cmd; \
} while (0)
if (todo.commands)
list_type(FT_general, one);
if (todo.random_instances)
list_random_instances();
if (todo.random_generators)
list_random_generators();
if (todo.digest_commands)
list_type(FT_md, one);
if (todo.digest_algorithms)
list_digests();
if (todo.kdf_algorithms)
MAYBE_ADD_NL(list_type(FT_general, one));
if (todo.all_algorithms) {
MAYBE_ADD_NL({});
BIO_printf(bio_out, "Digests:\n");
list_digests(" ");
BIO_printf(bio_out, "\nSymmetric Ciphers:\n");
list_ciphers(" ");
BIO_printf(bio_out, "\n");
list_kdfs();
if (todo.mac_algorithms)
BIO_printf(bio_out, "\n");
list_macs();
if (todo.cipher_commands)
list_type(FT_cipher, one);
if (todo.cipher_algorithms)
list_ciphers();
if (todo.encoder_algorithms)
list_encoders();
if (todo.decoder_algorithms)
list_decoders();
if (todo.keymanager_algorithms)
list_keymanagers();
if (todo.signature_algorithms)
list_signatures();
if (todo.asym_cipher_algorithms)
BIO_printf(bio_out, "\nProvided Asymmetric Encryption:\n");
list_asymciphers();
if (todo.keyexchange_algorithms)
BIO_printf(bio_out, "\nProvided Key Exchange:\n");
list_keyexchanges();
if (todo.kem_algorithms)
BIO_printf(bio_out, "\nProvided Signatures:\n");
list_signatures();
BIO_printf(bio_out, "\nProvided Key encapsulation:\n");
list_kems();
if (todo.pk_algorithms)
list_pkey();
if (todo.pk_method)
list_pkey_meth();
if (todo.store_loaders)
BIO_printf(bio_out, "\nProvided Key managers:\n");
list_keymanagers();
BIO_printf(bio_out, "\n");
list_encoders();
BIO_printf(bio_out, "\n");
list_decoders();
BIO_printf(bio_out, "\n");
list_store_loaders();
}
if (todo.random_instances)
MAYBE_ADD_NL(list_random_instances());
if (todo.random_generators)
MAYBE_ADD_NL(list_random_generators());
if (todo.digest_commands)
MAYBE_ADD_NL(list_type(FT_md, one));
if (todo.digest_algorithms)
MAYBE_ADD_NL(list_digests(""));
if (todo.kdf_algorithms)
MAYBE_ADD_NL(list_kdfs());
if (todo.mac_algorithms)
MAYBE_ADD_NL(list_macs());
if (todo.cipher_commands)
MAYBE_ADD_NL(list_type(FT_cipher, one));
if (todo.cipher_algorithms)
MAYBE_ADD_NL(list_ciphers(""));
if (todo.encoder_algorithms)
MAYBE_ADD_NL(list_encoders());
if (todo.decoder_algorithms)
MAYBE_ADD_NL(list_decoders());
if (todo.keymanager_algorithms)
MAYBE_ADD_NL(list_keymanagers());
if (todo.skeymanager_algorithms)
MAYBE_ADD_NL(list_skeymanagers());
if (todo.signature_algorithms)
MAYBE_ADD_NL(list_signatures());
if (todo.tls_signature_algorithms)
MAYBE_ADD_NL(list_tls_signatures());
if (todo.asym_cipher_algorithms)
MAYBE_ADD_NL(list_asymciphers());
if (todo.keyexchange_algorithms)
MAYBE_ADD_NL(list_keyexchanges());
if (todo.kem_algorithms)
MAYBE_ADD_NL(list_kems());
#if !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_TLS1_2)
if (todo.tls_groups)
MAYBE_ADD_NL(list_tls_groups(tls_version, all_tls_groups));
#endif
if (todo.pk_algorithms)
MAYBE_ADD_NL(list_pkey());
if (todo.pk_method)
MAYBE_ADD_NL(list_pkey_meth());
if (todo.store_loaders)
MAYBE_ADD_NL(list_store_loaders());
if (todo.provider_info)
list_provider_info();
MAYBE_ADD_NL(list_provider_info());
#ifndef OPENSSL_NO_DEPRECATED_3_0
if (todo.engines)
list_engines();
MAYBE_ADD_NL(list_engines());
#endif
if (todo.disabled)
list_disabled();
MAYBE_ADD_NL(list_disabled());
if (todo.objects)
list_objects();
MAYBE_ADD_NL(list_objects());
#undef MAYBE_ADD_NL
if (!done)
goto opthelp;

View file

@ -1,5 +1,5 @@
/*
* Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2018-2021 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
@ -137,10 +137,9 @@ opthelp:
}
/* One argument, the MAC name. */
argc = opt_num_rest();
argv = opt_rest();
if (argc != 1)
if (!opt_check_rest_arg("MAC name"))
goto opthelp;
argv = opt_rest();
mac = EVP_MAC_fetch(app_get0_libctx(), argv[0], app_get0_propq());
if (mac == NULL) {

View file

@ -73,8 +73,7 @@ int nseq_main(int argc, char **argv)
}
/* No extra arguments. */
argc = opt_num_rest();
if (argc != 0)
if (!opt_check_rest_arg(NULL))
goto opthelp;
in = bio_open_default(infile, 'r', FORMAT_PEM);

View file

@ -11,7 +11,7 @@
#ifdef OPENSSL_SYS_VMS
/* So fd_set and friends get properly defined on OpenVMS */
# define _XOPEN_SOURCE_EXTENDED 1
# define _XOPEN_SOURCE_EXTENDED
#endif
#include <stdio.h>
@ -33,12 +33,6 @@
#include <openssl/bn.h>
#include <openssl/x509v3.h>
#if defined(__TANDEM)
# if defined(OPENSSL_TANDEM_FLOSS)
# include <floss.h(floss_fork)>
# endif
#endif
#if defined(OPENSSL_SYS_VXWORKS)
/* not supported */
int setpgid(pid_t pid, pid_t pgid)
@ -76,7 +70,7 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req
static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio,
const char *port, int timeout);
int timeout);
static int send_ocsp_response(BIO *cbio, const OCSP_RESPONSE *resp);
static char *prog;
@ -136,7 +130,7 @@ const OPTIONS ocsp_options[] = {
"Don't include any certificates in signed request"},
{"badsig", OPT_BADSIG, '-',
"Corrupt last byte of loaded OCSP response signature (for test)"},
{"CA", OPT_CA, '<', "CA certificate"},
{"CA", OPT_CA, '<', "CA certificates"},
{"nmin", OPT_NMIN, 'p', "Number of minutes before next update"},
{"nrequest", OPT_REQUEST, 'p',
"Number of requests to accept (default unlimited)"},
@ -196,8 +190,10 @@ const OPTIONS ocsp_options[] = {
{"VAfile", OPT_VAFILE, '<', "Validator certificates file"},
{"verify_other", OPT_VERIFY_OTHER, '<',
"Additional certificates to search for signer"},
{"cert", OPT_CERT, '<', "Certificate to check"},
{"serial", OPT_SERIAL, 's', "Serial number to check"},
{"cert", OPT_CERT, '<',
"Certificate to check; may be given multiple times"},
{"serial", OPT_SERIAL, 's',
"Serial number to check; may be given multiple times"},
{"validity_period", OPT_VALIDITY_PERIOD, 'u',
"Maximum validity discrepancy in seconds"},
{"signkey", OPT_SIGNKEY, 's', "Private key to sign OCSP request with"},
@ -228,7 +224,7 @@ int ocsp_main(int argc, char **argv)
STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
STACK_OF(X509) *issuers = NULL;
X509 *issuer = NULL, *cert = NULL;
STACK_OF(X509) *rca_cert = NULL;
STACK_OF(X509) *rca_certs = NULL;
EVP_MD *resp_certid_md = NULL;
X509 *signer = NULL, *rsigner = NULL;
X509_STORE *store = NULL;
@ -261,6 +257,7 @@ int ocsp_main(int argc, char **argv)
|| (vpm = X509_VERIFY_PARAM_new()) == NULL)
goto end;
opt_set_unknown_name("digest");
prog = opt_init(argc, argv, ocsp_options);
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
@ -436,6 +433,7 @@ int ocsp_main(int argc, char **argv)
goto end;
break;
case OPT_CERT:
reset_unknown();
X509_free(cert);
cert = load_cert(opt_arg(), FORMAT_UNDEF, "certificate");
if (cert == NULL)
@ -449,6 +447,7 @@ int ocsp_main(int argc, char **argv)
trailing_md = 0;
break;
case OPT_SERIAL:
reset_unknown();
if (cert_id_md == NULL)
cert_id_md = (EVP_MD *)EVP_sha1();
if (!add_ocsp_serial(&req, opt_arg(), cert_id_md, issuer, ids))
@ -524,7 +523,7 @@ int ocsp_main(int argc, char **argv)
break;
case OPT_MULTI:
#ifdef HTTP_DAEMON
multi = atoi(opt_arg());
n_responders = atoi(opt_arg());
#endif
break;
case OPT_PROV_CASES:
@ -535,8 +534,7 @@ int ocsp_main(int argc, char **argv)
}
/* No extra arguments. */
argc = opt_num_rest();
if (argc != 0)
if (!opt_check_rest_arg(NULL))
goto opthelp;
if (trailing_md) {
@ -555,10 +553,6 @@ int ocsp_main(int argc, char **argv)
&& respin == NULL && !(port != NULL && ridx_filename != NULL))
goto opthelp;
out = bio_open_default(outfile, 'w', FORMAT_TEXT);
if (out == NULL)
goto end;
if (req == NULL && (add_nonce != 2))
add_nonce = 0;
@ -576,7 +570,7 @@ int ocsp_main(int argc, char **argv)
if (req == NULL && port != NULL) {
#ifndef OPENSSL_NO_SOCK
acbio = http_server_init_bio(prog, port);
acbio = http_server_init(prog, port, -1);
if (acbio == NULL)
goto end;
#else
@ -593,7 +587,7 @@ int ocsp_main(int argc, char **argv)
BIO_printf(bio_err, "Error loading responder certificate\n");
goto end;
}
if (!load_certs(rca_filename, 0, &rca_cert, NULL, "CA certificates"))
if (!load_certs(rca_filename, 0, &rca_certs, NULL, "CA certificates"))
goto end;
if (rcertfile != NULL) {
if (!load_certs(rcertfile, 0, &rother, NULL,
@ -611,7 +605,7 @@ int ocsp_main(int argc, char **argv)
}
if (ridx_filename != NULL
&& (rkey == NULL || rsigner == NULL || rca_cert == NULL)) {
&& (rkey == NULL || rsigner == NULL || rca_certs == NULL)) {
BIO_printf(bio_err,
"Responder mode requires certificate, key, and CA.\n");
goto end;
@ -629,14 +623,15 @@ int ocsp_main(int argc, char **argv)
}
#ifdef HTTP_DAEMON
if (multi && acbio != NULL)
if (n_responders != 0 && acbio != NULL)
spawn_loop(prog);
if (acbio != NULL && req_timeout > 0)
signal(SIGALRM, socket_timeout);
#endif
if (acbio != NULL)
log_message(prog, LOG_INFO, "waiting for OCSP client connections...");
trace_log_message(-1, prog,
LOG_INFO, "waiting for OCSP client connections...");
redo_accept:
@ -650,14 +645,15 @@ redo_accept:
rdb = newrdb;
} else {
free_index(newrdb);
log_message(prog, LOG_ERR, "error reloading updated index: %s",
trace_log_message(-1, prog,
LOG_ERR, "error reloading updated index: %s",
ridx_filename);
}
}
#endif
req = NULL;
res = do_responder(&req, &cbio, acbio, port, req_timeout);
res = do_responder(&req, &cbio, acbio, req_timeout);
if (res == 0)
goto redo_accept;
@ -709,6 +705,10 @@ redo_accept:
}
}
out = bio_open_default(outfile, 'w', FORMAT_TEXT);
if (out == NULL)
goto end;
if (req_text && req != NULL)
OCSP_REQUEST_print(out, req, 0);
@ -721,7 +721,7 @@ redo_accept:
}
if (rdb != NULL) {
make_ocsp_response(bio_err, &resp, req, rdb, rca_cert, rsigner, rkey,
make_ocsp_response(bio_err, &resp, req, rdb, rca_certs, rsigner, rkey,
rsign_md, rsign_sigopts, rother, rflags, nmin, ndays,
badsig, resp_certid_md);
if (resp == NULL)
@ -858,9 +858,9 @@ redo_accept:
EVP_MD_free(rsign_md);
EVP_MD_free(resp_certid_md);
X509_free(cert);
sk_X509_pop_free(issuers, X509_free);
OSSL_STACK_OF_X509_free(issuers);
X509_free(rsigner);
sk_X509_pop_free(rca_cert, X509_free);
OSSL_STACK_OF_X509_free(rca_certs);
free_index(rdb);
BIO_free_all(cbio);
BIO_free_all(acbio);
@ -870,8 +870,8 @@ redo_accept:
OCSP_BASICRESP_free(bs);
sk_OPENSSL_STRING_free(reqnames);
sk_OCSP_CERTID_free(ids);
sk_X509_pop_free(sign_other, X509_free);
sk_X509_pop_free(verify_other, X509_free);
OSSL_STACK_OF_X509_free(sign_other);
OSSL_STACK_OF_X509_free(verify_other);
sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
OPENSSL_free(thost);
OPENSSL_free(tport);
@ -1201,13 +1201,13 @@ static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser)
}
static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio,
const char *port, int timeout)
int timeout)
{
#ifndef OPENSSL_NO_SOCK
return http_server_get_asn1_req(ASN1_ITEM_rptr(OCSP_REQUEST),
(ASN1_VALUE **)preq, NULL, pcbio, acbio,
NULL /* found_keep_alive */,
prog, port, 1 /* accept_get */, timeout);
prog, 1 /* accept_get */, timeout);
#else
BIO_printf(bio_err,
"Error getting OCSP request - sockets not supported\n");
@ -1219,7 +1219,7 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio,
static int send_ocsp_response(BIO *cbio, const OCSP_RESPONSE *resp)
{
#ifndef OPENSSL_NO_SOCK
return http_server_send_asn1_resp(cbio,
return http_server_send_asn1_resp(prog, cbio,
0 /* no keep-alive */,
"application/ocsp-response",
ASN1_ITEM_rptr(OCSP_RESPONSE),

View file

@ -330,8 +330,8 @@ tsa_name = yes # Must the TSA name be included in the reply?
# (optional, default: no)
ess_cert_id_chain = no # Must the ESS cert id chain be included?
# (optional, default: no)
ess_cert_id_alg = sha1 # algorithm to compute certificate
# identifier (optional, default: sha1)
ess_cert_id_alg = sha256 # algorithm to compute certificate
# identifier (optional, default: sha256)
[insta] # CMP using Insta Demo CA
# Message transfer
@ -342,8 +342,8 @@ path = pkix/
# Server authentication
recipient = "/C=FI/O=Insta Demo/CN=Insta Demo CA" # or set srvcert or issuer
ignore_keyusage = 1 # potentially needed quirk
unprotected_errors = 1 # potentially needed quirk
ignore_keyusage = 1 # quirk needed to accept Insta CA cert not including digitalsignature
unprotected_errors = 1 # quirk needed to accept negative responses possibly not protected
extracertsout = insta.extracerts.pem
# Client authentication

View file

@ -1,5 +1,5 @@
/*
* Copyright 1995-2022 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
@ -7,9 +7,11 @@
* https://www.openssl.org/source/license.html
*/
#include "internal/e_os.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "internal/common.h"
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/trace.h>
@ -157,8 +159,6 @@ static void tracedata_free(tracedata *data)
OPENSSL_free(data);
}
static STACK_OF(tracedata) *trace_data_stack;
static void cleanup_trace(void)
{
sk_tracedata_pop_free(trace_data_stack, tracedata_free);
@ -232,6 +232,7 @@ static void setup_trace(const char *str)
#endif /* OPENSSL_NO_TRACE */
static char *help_argv[] = { "help", NULL };
static char *version_argv[] = { "version", NULL };
int main(int argc, char *argv[])
{
@ -241,6 +242,7 @@ int main(int argc, char *argv[])
const char *fname;
ARGS arg;
int global_help = 0;
int global_version = 0;
int ret = 0;
arg.argv = NULL;
@ -285,16 +287,25 @@ int main(int argc, char *argv[])
global_help = argc > 1
&& (strcmp(argv[1], "-help") == 0 || strcmp(argv[1], "--help") == 0
|| strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--h") == 0);
global_version = argc > 1
&& (strcmp(argv[1], "-version") == 0 || strcmp(argv[1], "--version") == 0
|| strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--v") == 0);
argc--;
argv++;
opt_appname(argc == 1 || global_help ? "help" : argv[0]);
opt_appname(argc == 1 || global_help ? "help" : global_version ? "version" : argv[0]);
} else {
argv[0] = pname;
}
/* If there's a command, run with that, otherwise "help". */
ret = argc == 0 || global_help
/*
* If there's no command, assume "help". If there's an override for help
* or version run those, otherwise run the command given.
*/
ret = (argc == 0) || global_help
? do_cmd(prog, 1, help_argv)
: global_version
? do_cmd(prog, 1, version_argv)
: do_cmd(prog, argc, argv);
end:
@ -326,7 +337,6 @@ const OPTIONS help_options[] = {
{NULL}
};
int help_main(int argc, char **argv)
{
FUNCTION *fp;
@ -357,7 +367,7 @@ int help_main(int argc, char **argv)
new_argv[2] = NULL;
return do_cmd(prog_init(), 2, new_argv);
}
if (opt_num_rest() != 0) {
if (!opt_check_rest_arg(NULL)) {
BIO_printf(bio_err, "Usage: %s\n", prog);
return 1;
}
@ -417,12 +427,12 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
warn_deprecated(fp);
return fp->func(argc, argv);
}
if ((strncmp(argv[0], "no-", 3)) == 0) {
f.name = argv[0];
if (CHECK_AND_SKIP_PREFIX(f.name, "no-")) {
/*
* User is asking if foo is unsupported, by trying to "run" the
* no-foo command. Strange.
*/
f.name = argv[0] + 3;
if (lh_FUNCTION_retrieve(prog, &f) == NULL) {
BIO_printf(bio_out, "%s\n", argv[0]);
return 0;

View file

@ -330,8 +330,8 @@ tsa_name = yes # Must the TSA name be included in the reply?
# (optional, default: no)
ess_cert_id_chain = no # Must the ESS cert id chain be included?
# (optional, default: no)
ess_cert_id_alg = sha1 # algorithm to compute certificate
# identifier (optional, default: sha1)
ess_cert_id_alg = sha256 # algorithm to compute certificate
# identifier (optional, default: sha256)
[insta] # CMP using Insta Demo CA
# Message transfer
@ -342,8 +342,8 @@ path = pkix/
# Server authentication
recipient = "/C=FI/O=Insta Demo/CN=Insta Demo CA" # or set srvcert or issuer
ignore_keyusage = 1 # potentially needed quirk
unprotected_errors = 1 # potentially needed quirk
ignore_keyusage = 1 # quirk needed to accept Insta CA cert not including digitalsignature
unprotected_errors = 1 # quirk needed to accept negative responses possibly not protected
extracertsout = insta.extracerts.pem
# Client authentication

View file

@ -1,5 +1,5 @@
/*
* Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -369,8 +369,7 @@ static char *md5crypt(const char *passwd, const char *magic, const char *salt)
if (magic_len > 0)
salt_out += 2 + magic_len;
if (salt_len > 8)
goto err;
assert(salt_len <= 8);
md = EVP_MD_CTX_new();
if (md == NULL
@ -711,8 +710,7 @@ static char *shacrypt(const char *passwd, const char *magic, const char *salt)
do { \
unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
int i = (N); \
while (i-- > 0) \
{ \
while (i-- > 0) { \
*cp++ = cov_2char[w & 0x3f]; \
w >>= 6; \
} \

View file

@ -14,12 +14,14 @@
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/asn1.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
#include <openssl/provider.h>
#include <openssl/kdf.h>
#include <openssl/rand.h>
#define NOKEYS 0x1
#define NOCERTS 0x2
@ -53,6 +55,7 @@ void hex_prin(BIO *out, unsigned char *buf, int len);
static int alg_print(const X509_ALGOR *alg);
int cert_load(BIO *in, STACK_OF(X509) *sk);
static int set_pbe(int *ppbe, const char *str);
static int jdk_trust(PKCS12_SAFEBAG *bag, void *cbarg);
typedef enum OPTION_choice {
OPT_COMMON,
@ -61,13 +64,13 @@ typedef enum OPTION_choice {
#ifndef OPENSSL_NO_DES
OPT_DESCERT,
#endif
OPT_EXPORT, OPT_ITER, OPT_NOITER, OPT_MACITER, OPT_NOMACITER,
OPT_EXPORT, OPT_ITER, OPT_NOITER, OPT_MACITER, OPT_NOMACITER, OPT_MACSALTLEN,
OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_NOENC, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE,
OPT_INKEY, OPT_CERTFILE, OPT_UNTRUSTED, OPT_PASSCERTS,
OPT_NAME, OPT_CSP, OPT_CANAME,
OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH,
OPT_CAFILE, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_ENGINE,
OPT_R_ENUM, OPT_PROV_ENUM,
OPT_R_ENUM, OPT_PROV_ENUM, OPT_JDKTRUST, OPT_PBMAC1_PBKDF2, OPT_PBMAC1_PBKDF2_MD,
#ifndef OPENSSL_NO_DES
OPT_LEGACY_ALG
#endif
@ -144,33 +147,39 @@ const OPTIONS pkcs12_options[] = {
#endif
{"macalg", OPT_MACALG, 's',
"Digest algorithm to use in MAC (default SHA256)"},
{"pbmac1_pbkdf2", OPT_PBMAC1_PBKDF2, '-', "Use PBMAC1 with PBKDF2 instead of MAC"},
{"pbmac1_pbkdf2_md", OPT_PBMAC1_PBKDF2_MD, 's', "Digest to use for PBMAC1 KDF (default SHA256)"},
{"iter", OPT_ITER, 'p', "Specify the iteration count for encryption and MAC"},
{"noiter", OPT_NOITER, '-', "Don't use encryption iteration"},
{"nomaciter", OPT_NOMACITER, '-', "Don't use MAC iteration)"},
{"maciter", OPT_MACITER, '-', "Unused, kept for backwards compatibility"},
{"macsaltlen", OPT_MACSALTLEN, 'p', "Specify the salt len for MAC"},
{"nomac", OPT_NOMAC, '-', "Don't generate MAC"},
{"jdktrust", OPT_JDKTRUST, 's', "Mark certificate in PKCS#12 store as trusted for JDK compatibility"},
{NULL}
};
int pkcs12_main(int argc, char **argv)
{
char *infile = NULL, *outfile = NULL, *keyname = NULL, *certfile = NULL;
char *untrusted = NULL, *ciphername = NULL, *enc_flag = NULL;
char *untrusted = NULL, *ciphername = NULL, *enc_name = NULL;
char *passcertsarg = NULL, *passcerts = NULL;
char *name = NULL, *csp_name = NULL;
char pass[PASSWD_BUF_SIZE] = "", macpass[PASSWD_BUF_SIZE] = "";
int export_pkcs12 = 0, options = 0, chain = 0, twopass = 0, keytype = 0;
char *jdktrust = NULL;
#ifndef OPENSSL_NO_DES
int use_legacy = 0;
#endif
/* use library defaults for the iter, maciter, cert, and key PBE */
int iter = 0, maciter = 0;
int iter = 0, maciter = 0, pbmac1_pbkdf2 = 0;
int macsaltlen = PKCS12_SALT_LEN;
int cert_pbe = NID_undef;
int key_pbe = NID_undef;
int ret = 1, macver = 1, add_lmk = 0, private = 0;
int noprompt = 0;
char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL;
char *passin = NULL, *passout = NULL, *macalg = NULL;
char *passin = NULL, *passout = NULL, *macalg = NULL, *pbmac1_pbkdf2_md = NULL;
char *cpass = NULL, *mpass = NULL, *badpass = NULL;
const char *CApath = NULL, *CAfile = NULL, *CAstore = NULL, *prog;
int noCApath = 0, noCAfile = 0, noCAstore = 0;
@ -182,6 +191,7 @@ int pkcs12_main(int argc, char **argv)
EVP_CIPHER *enc = (EVP_CIPHER *)default_enc;
OPTION_CHOICE o;
opt_set_unknown_name("cipher");
prog = opt_init(argc, argv, pkcs12_options);
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
@ -215,6 +225,11 @@ int pkcs12_main(int argc, char **argv)
case OPT_NOOUT:
options |= (NOKEYS | NOCERTS);
break;
case OPT_JDKTRUST:
jdktrust = opt_arg();
/* Adding jdk trust implies nokeys */
options |= NOKEYS;
break;
case OPT_INFO:
options |= INFO;
break;
@ -238,16 +253,15 @@ int pkcs12_main(int argc, char **argv)
case OPT_NODES:
case OPT_NOENC:
/*
* |enc_flag| stores the name of the option used so it
* |enc_name| stores the name of the option used so it
* can be printed if an error message is output.
*/
enc_flag = opt_flag() + 1;
enc_name = opt_flag() + 1;
enc = NULL;
ciphername = NULL;
break;
case OPT_CIPHER:
ciphername = opt_unknown();
enc_flag = opt_unknown();
enc_name = ciphername = opt_unknown();
break;
case OPT_ITER:
maciter = iter = opt_int_arg();
@ -261,6 +275,9 @@ int pkcs12_main(int argc, char **argv)
case OPT_NOMACITER:
maciter = 1;
break;
case OPT_MACSALTLEN:
macsaltlen = opt_int_arg();
break;
case OPT_NOMAC:
cert_pbe = -1;
maciter = -1;
@ -268,6 +285,12 @@ int pkcs12_main(int argc, char **argv)
case OPT_MACALG:
macalg = opt_arg();
break;
case OPT_PBMAC1_PBKDF2:
pbmac1_pbkdf2 = 1;
break;
case OPT_PBMAC1_PBKDF2_MD:
pbmac1_pbkdf2_md = opt_arg();
break;
case OPT_CERTPBE:
if (!set_pbe(&cert_pbe, opt_arg()))
goto opthelp;
@ -357,17 +380,14 @@ int pkcs12_main(int argc, char **argv)
}
/* No extra arguments. */
argc = opt_num_rest();
if (argc != 0)
if (!opt_check_rest_arg(NULL))
goto opthelp;
if (!app_RAND_load())
goto end;
if (ciphername != NULL) {
if (!opt_cipher_any(ciphername, &enc))
goto opthelp;
}
if (export_pkcs12) {
if ((options & INFO) != 0)
WARN_EXPORT("info");
@ -379,7 +399,7 @@ int pkcs12_main(int argc, char **argv)
WARN_EXPORT("cacerts");
if (enc != default_enc)
BIO_printf(bio_err,
"Warning: output encryption option -%s ignored with -export\n", enc_flag);
"Warning: output encryption option -%s ignored with -export\n", enc_name);
} else {
if (keyname != NULL)
WARN_NO_EXPORT("inkey");
@ -427,6 +447,8 @@ int pkcs12_main(int argc, char **argv)
WARN_NO_EXPORT("nomaciter");
if (cert_pbe == -1 && maciter == -1)
WARN_NO_EXPORT("nomac");
if (macsaltlen != PKCS12_SALT_LEN)
WARN_NO_EXPORT("macsaltlen");
}
#ifndef OPENSSL_NO_DES
if (use_legacy) {
@ -521,6 +543,7 @@ int pkcs12_main(int argc, char **argv)
EVP_MD *macmd = NULL;
unsigned char *catmp = NULL;
int i;
ASN1_OBJECT *obj = NULL;
if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) {
BIO_printf(bio_err, "Nothing to export due to -noout or -nocerts and -nokeys\n");
@ -556,7 +579,7 @@ int pkcs12_main(int argc, char **argv)
/* Look for matching private key */
for (i = 0; i < sk_X509_num(certs); i++) {
x = sk_X509_value(certs, i);
if (X509_check_private_key(x, key)) {
if (cert_matches_key(x, key)) {
ee_cert = x;
/* Zero keyid and alias */
X509_keyid_set1(ee_cert, NULL, 0);
@ -614,7 +637,7 @@ int pkcs12_main(int argc, char **argv)
/* Add the remaining certs (except for duplicates) */
add_certs = X509_add_certs(certs, chain2, X509_ADD_FLAG_UP_REF
| X509_ADD_FLAG_NO_DUP);
sk_X509_pop_free(chain2, X509_free);
OSSL_STACK_OF_X509_free(chain2);
if (!add_certs)
goto export_end;
} else {
@ -665,9 +688,14 @@ int pkcs12_main(int argc, char **argv)
if (!twopass)
OPENSSL_strlcpy(macpass, pass, sizeof(macpass));
p12 = PKCS12_create_ex(cpass, name, key, ee_cert, certs,
if (jdktrust != NULL) {
obj = OBJ_txt2obj(jdktrust, 0);
}
p12 = PKCS12_create_ex2(cpass, name, key, ee_cert, certs,
key_pbe, cert_pbe, iter, -1, keytype,
app_get0_libctx(), app_get0_propq());
app_get0_libctx(), app_get0_propq(),
jdk_trust, (void*)obj);
if (p12 == NULL) {
BIO_printf(bio_err, "Error creating PKCS12 structure for %s\n",
@ -680,13 +708,23 @@ int pkcs12_main(int argc, char **argv)
goto opthelp;
}
if (maciter != -1)
if (!PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd)) {
BIO_printf(bio_err, "Error creating PKCS12 MAC; no PKCS12KDF support?\n");
BIO_printf(bio_err, "Use -nomac if MAC not required and PKCS12KDF support not available.\n");
if (maciter != -1) {
if (pbmac1_pbkdf2 == 1) {
if (!PKCS12_set_pbmac1_pbkdf2(p12, mpass, -1, NULL,
macsaltlen, maciter,
macmd, pbmac1_pbkdf2_md)) {
BIO_printf(bio_err, "Error creating PBMAC1\n");
goto export_end;
}
} else {
if (!PKCS12_set_mac(p12, mpass, -1, NULL, macsaltlen, maciter, macmd)) {
BIO_printf(bio_err, "Error creating PKCS12 MAC; no PKCS12KDF support?\n");
BIO_printf(bio_err,
"Use -nomac or -pbmac1_pbkdf2 if PKCS12KDF support not available\n");
goto export_end;
}
}
}
assert(private);
out = bio_open_owner(outfile, FORMAT_PKCS12, private);
@ -701,10 +739,10 @@ int pkcs12_main(int argc, char **argv)
EVP_PKEY_free(key);
EVP_MD_free(macmd);
sk_X509_pop_free(certs, X509_free);
sk_X509_pop_free(untrusted_certs, X509_free);
OSSL_STACK_OF_X509_free(certs);
OSSL_STACK_OF_X509_free(untrusted_certs);
X509_free(ee_cert);
ASN1_OBJECT_free(obj);
ERR_print_errors(bio_err);
goto end;
@ -755,13 +793,52 @@ int pkcs12_main(int argc, char **argv)
X509_ALGOR_get0(&macobj, NULL, NULL, macalgid);
BIO_puts(bio_err, "MAC: ");
i2a_ASN1_OBJECT(bio_err, macobj);
if (OBJ_obj2nid(macobj) == NID_pbmac1) {
PBKDF2PARAM *pbkdf2_param = PBMAC1_get1_pbkdf2_param(macalgid);
if (pbkdf2_param == NULL) {
BIO_printf(bio_err, ", Unsupported KDF or params for PBMAC1\n");
} else {
const ASN1_OBJECT *prfobj;
int prfnid;
BIO_printf(bio_err, " using PBKDF2, Iteration %ld\n",
ASN1_INTEGER_get(pbkdf2_param->iter));
BIO_printf(bio_err, "Key length: %ld, Salt length: %d\n",
ASN1_INTEGER_get(pbkdf2_param->keylength),
ASN1_STRING_length(pbkdf2_param->salt->value.octet_string));
if (pbkdf2_param->prf == NULL) {
prfnid = NID_hmacWithSHA1;
} else {
X509_ALGOR_get0(&prfobj, NULL, NULL, pbkdf2_param->prf);
prfnid = OBJ_obj2nid(prfobj);
}
BIO_printf(bio_err, "PBKDF2 PRF: %s\n", OBJ_nid2sn(prfnid));
}
PBKDF2PARAM_free(pbkdf2_param);
} else {
BIO_printf(bio_err, ", Iteration %ld\n",
tmaciter != NULL ? ASN1_INTEGER_get(tmaciter) : 1L);
BIO_printf(bio_err, "MAC length: %ld, salt length: %ld\n",
tmac != NULL ? ASN1_STRING_length(tmac) : 0L,
tsalt != NULL ? ASN1_STRING_length(tsalt) : 0L);
}
}
if (macver) {
const X509_ALGOR *macalgid;
const ASN1_OBJECT *macobj;
PKCS12_get0_mac(NULL, &macalgid, NULL, NULL, p12);
if (macalgid == NULL) {
BIO_printf(bio_err, "Warning: MAC is absent!\n");
goto dump;
}
X509_ALGOR_get0(&macobj, NULL, NULL, macalgid);
if (OBJ_obj2nid(macobj) != NID_pbmac1) {
EVP_KDF *pkcs12kdf;
pkcs12kdf = EVP_KDF_fetch(app_get0_libctx(), "PKCS12KDF",
@ -772,6 +849,8 @@ int pkcs12_main(int argc, char **argv)
goto end;
}
EVP_KDF_free(pkcs12kdf);
}
/* If we enter empty password try no password first */
if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
/* If mac and crypto pass the same set it to NULL too */
@ -836,12 +915,36 @@ int pkcs12_main(int argc, char **argv)
return ret;
}
static int jdk_trust(PKCS12_SAFEBAG *bag, void *cbarg)
{
STACK_OF(X509_ATTRIBUTE) *attrs = NULL;
X509_ATTRIBUTE *attr = NULL;
/* Nothing to do */
if (cbarg == NULL)
return 1;
/* Get the current attrs */
attrs = (STACK_OF(X509_ATTRIBUTE)*)PKCS12_SAFEBAG_get0_attrs(bag);
/* Create a new attr for the JDK Trusted Usage and add it */
attr = X509_ATTRIBUTE_create(NID_oracle_jdk_trustedkeyusage, V_ASN1_OBJECT, (ASN1_OBJECT*)cbarg);
/* Add the new attr, if attrs is NULL, it'll be initialised */
X509at_add1_attr(&attrs, attr);
/* Set the bag attrs */
PKCS12_SAFEBAG_set0_attrs(bag, attrs);
X509_ATTRIBUTE_free(attr);
return 1;
}
int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass,
int passlen, int options, char *pempass,
const EVP_CIPHER *enc)
{
STACK_OF(PKCS7) *asafes = NULL;
STACK_OF(PKCS12_SAFEBAG) *bags;
int i, bagnid;
int ret = 0;
PKCS7 *p7;
@ -849,6 +952,8 @@ int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass,
if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
return 0;
for (i = 0; i < sk_PKCS7_num(asafes); i++) {
STACK_OF(PKCS12_SAFEBAG) *bags;
p7 = sk_PKCS7_value(asafes, i);
bagnid = OBJ_obj2nid(p7->type);
if (bagnid == NID_pkcs7_data) {
@ -868,7 +973,7 @@ int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass,
} else {
continue;
}
if (!bags)
if (bags == NULL)
goto err;
if (!dump_certs_pkeys_bags(out, bags, pass, passlen,
options, pempass, enc)) {
@ -876,7 +981,6 @@ int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass,
goto err;
}
sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
bags = NULL;
}
ret = 1;
@ -1139,6 +1243,8 @@ int cert_load(BIO *in, STACK_OF(X509) *sk)
void print_attribute(BIO *out, const ASN1_TYPE *av)
{
char *value;
const char *ln;
char objbuf[80];
switch (av->type) {
case V_ASN1_BMPSTRING:
@ -1165,6 +1271,15 @@ void print_attribute(BIO *out, const ASN1_TYPE *av)
BIO_printf(out, "\n");
break;
case V_ASN1_OBJECT:
ln = OBJ_nid2ln(OBJ_obj2nid(av->value.object));
if (!ln)
ln = "";
OBJ_obj2txt(objbuf, sizeof(objbuf), av->value.object, 1);
BIO_printf(out, "%s (%s)", ln, objbuf);
BIO_printf(out, "\n");
break;
default:
BIO_printf(out, "<Unsupported tag %d>\n", av->type);
break;
@ -1202,8 +1317,7 @@ int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst,
}
if (X509_ATTRIBUTE_count(attr)) {
for (j = 0; j < X509_ATTRIBUTE_count(attr); j++)
{
for (j = 0; j < X509_ATTRIBUTE_count(attr); j++) {
av = X509_ATTRIBUTE_get0_type(attr, j);
print_attribute(out, av);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2022 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
@ -23,8 +23,8 @@
typedef enum OPTION_choice {
OPT_COMMON,
OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_NOOUT,
OPT_TEXT, OPT_PRINT, OPT_PRINT_CERTS, OPT_ENGINE,
OPT_PROV_ENUM
OPT_TEXT, OPT_PRINT, OPT_PRINT_CERTS, OPT_QUIET,
OPT_ENGINE, OPT_PROV_ENUM
} OPTION_CHOICE;
const OPTIONS pkcs7_options[] = {
@ -46,6 +46,8 @@ const OPTIONS pkcs7_options[] = {
{"print", OPT_PRINT, '-', "Print out all fields of the PKCS7 structure"},
{"print_certs", OPT_PRINT_CERTS, '-',
"Print_certs print any certs or crl in the input"},
{"quiet", OPT_QUIET, '-',
"When used with -print_certs, it produces a cleaner output"},
OPT_PROV_OPTIONS,
{NULL}
@ -58,7 +60,7 @@ int pkcs7_main(int argc, char **argv)
BIO *in = NULL, *out = NULL;
int informat = FORMAT_PEM, outformat = FORMAT_PEM;
char *infile = NULL, *outfile = NULL, *prog;
int i, print_certs = 0, text = 0, noout = 0, p7_print = 0, ret = 1;
int i, print_certs = 0, text = 0, noout = 0, p7_print = 0, quiet = 0, ret = 1;
OPTION_CHOICE o;
OSSL_LIB_CTX *libctx = app_get0_libctx();
@ -100,6 +102,9 @@ int pkcs7_main(int argc, char **argv)
case OPT_PRINT_CERTS:
print_certs = 1;
break;
case OPT_QUIET:
quiet = 1;
break;
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
break;
@ -111,8 +116,7 @@ int pkcs7_main(int argc, char **argv)
}
/* No extra arguments. */
argc = opt_num_rest();
if (argc != 0)
if (!opt_check_rest_arg(NULL))
goto opthelp;
in = bio_open_default(infile, 'r', informat);
@ -172,7 +176,7 @@ int pkcs7_main(int argc, char **argv)
x = sk_X509_value(certs, i);
if (text)
X509_print(out, x);
else
else if (!quiet)
dump_cert_text(out, x);
if (!noout)

View file

@ -1,5 +1,5 @@
/*
* Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1999-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
@ -17,6 +17,9 @@
#include <openssl/evp.h>
#include <openssl/pkcs12.h>
#define STR(a) XSTR(a)
#define XSTR(a) #a
typedef enum OPTION_choice {
OPT_COMMON,
OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT,
@ -26,6 +29,7 @@ typedef enum OPTION_choice {
#endif
OPT_V2, OPT_V1, OPT_V2PRF, OPT_ITER, OPT_PASSIN, OPT_PASSOUT,
OPT_TRADITIONAL,
OPT_SALTLEN,
OPT_R_ENUM, OPT_PROV_ENUM
} OPTION_CHOICE;
@ -53,7 +57,8 @@ const OPTIONS pkcs8_options[] = {
{"traditional", OPT_TRADITIONAL, '-', "use traditional format private key"},
{"iter", OPT_ITER, 'p', "Specify the iteration count"},
{"noiter", OPT_NOITER, '-', "Use 1 as iteration count"},
{"saltlen", OPT_SALTLEN, 'p', "Specify the salt length (in bytes)"},
{OPT_MORE_STR, 0, 0, "Default: 8 (For PBE1) or 16 (for PBE2)"},
#ifndef OPENSSL_NO_SCRYPT
OPT_SECTION("Scrypt"),
{"scrypt", OPT_SCRYPT, '-', "Use scrypt algorithm"},
@ -88,6 +93,7 @@ int pkcs8_main(int argc, char **argv)
#ifndef OPENSSL_NO_SCRYPT
long scrypt_N = 0, scrypt_r = 0, scrypt_p = 0;
#endif
int saltlen = 0; /* A value of zero chooses the default */
prog = opt_init(argc, argv, pkcs8_options);
while ((o = opt_next()) != OPT_EOF) {
@ -189,12 +195,15 @@ int pkcs8_main(int argc, char **argv)
goto opthelp;
break;
#endif
case OPT_SALTLEN:
if (!opt_int(opt_arg(), &saltlen))
goto opthelp;
break;
}
}
/* No extra arguments. */
argc = opt_num_rest();
if (argc != 0)
if (!opt_check_rest_arg(NULL))
goto opthelp;
private = 1;
@ -218,9 +227,6 @@ int pkcs8_main(int argc, char **argv)
informat == FORMAT_UNDEF ? FORMAT_PEM : informat);
if (in == NULL)
goto end;
out = bio_open_owner(outfile, outformat, private);
if (out == NULL)
goto end;
if (topk8) {
pkey = load_key(infile, informat, 1, passin, e, "key");
@ -231,6 +237,8 @@ int pkcs8_main(int argc, char **argv)
ERR_print_errors(bio_err);
goto end;
}
if ((out = bio_open_owner(outfile, outformat, private)) == NULL)
goto end;
if (nocrypt) {
assert(private);
if (outformat == FORMAT_PEM) {
@ -246,14 +254,14 @@ int pkcs8_main(int argc, char **argv)
if (cipher) {
#ifndef OPENSSL_NO_SCRYPT
if (scrypt_N && scrypt_r && scrypt_p)
pbe = PKCS5_pbe2_set_scrypt(cipher, NULL, 0, NULL,
pbe = PKCS5_pbe2_set_scrypt(cipher, NULL, saltlen, NULL,
scrypt_N, scrypt_r, scrypt_p);
else
#endif
pbe = PKCS5_pbe2_set_iv(cipher, iter, NULL, 0, NULL,
pbe = PKCS5_pbe2_set_iv(cipher, iter, NULL, saltlen, NULL,
pbe_nid);
} else {
pbe = PKCS5_pbe_set(pbe_nid, iter, NULL, 0);
pbe = PKCS5_pbe_set(pbe_nid, iter, NULL, saltlen);
}
if (pbe == NULL) {
BIO_printf(bio_err, "Error setting PBE algorithm\n");
@ -352,6 +360,9 @@ int pkcs8_main(int argc, char **argv)
}
assert(private);
out = bio_open_owner(outfile, outformat, private);
if (out == NULL)
goto end;
if (outformat == FORMAT_PEM) {
if (traditional)
PEM_write_bio_PrivateKey_traditional(out, pkey, NULL, NULL, 0,

Some files were not shown because too many files have changed in this diff Show more