Latest update.
This commit is contained in:
+48
-3
@@ -24,9 +24,28 @@ OpenSSL 3.0
|
||||
|
||||
### Changes between 1.1.1 and 3.0 [xx XXX xxxx] ###
|
||||
|
||||
* `ASN1_verify()`, `ASN1_digest()` and `ASN1_sign()` have been deprecated.
|
||||
* Added OSSL_PARAM_BLD to the public interface. This allows OSSL_PARAM
|
||||
arrays to be more easily constructed via a series of utility functions.
|
||||
Create a parameter builder using OSSL_PARAM_BLD_new(), add parameters using
|
||||
the various push functions and finally convert to a passable OSSL_PARAM
|
||||
array using OSSL_PARAM_BLD_to_param().
|
||||
|
||||
*Paul Dale*
|
||||
|
||||
* EVP_PKEY_get0_RSA(), EVP_PKEY_get0_DSA(), EVP_PKEY_get0_DH(), and
|
||||
EVP_PKEY_get0_EC_KEY() can now handle EVP_PKEYs with provider side
|
||||
internal keys, if they correspond to one of those built in types.
|
||||
|
||||
*Richard Levitte*
|
||||
|
||||
* Added EVP_PKEY_set_type_by_keymgmt(), to initialise an EVP_PKEY to
|
||||
contain a provider side internal key.
|
||||
|
||||
*Richard Levitte*
|
||||
|
||||
* ASN1_verify(), ASN1_digest() and ASN1_sign() have been deprecated.
|
||||
They are old functions that we don't use, and that you could disable with
|
||||
the macro `NO_ASN1_OLD`. This goes all the way back to OpenSSL 0.9.7.
|
||||
the macro NO_ASN1_OLD. This goes all the way back to OpenSSL 0.9.7.
|
||||
|
||||
*Richard Levitte*
|
||||
|
||||
@@ -938,7 +957,33 @@ OpenSSL 3.0
|
||||
OpenSSL 1.1.1
|
||||
-------------
|
||||
|
||||
### Changes between 1.1.1d and 1.1.1e [xx XXX xxxx] ###
|
||||
### Changes between 1.1.1e and 1.1.1f [xx XXX xxxx] ###
|
||||
|
||||
|
||||
### Changes between 1.1.1d and 1.1.1e [17 Mar 2020] ###
|
||||
|
||||
* Properly detect EOF while reading in libssl. Previously if we hit an EOF
|
||||
while reading in libssl then we would report an error back to the
|
||||
application (SSL_ERROR_SYSCALL) but errno would be 0. We now add
|
||||
an error to the stack (which means we instead return SSL_ERROR_SSL) and
|
||||
therefore give a hint as to what went wrong.
|
||||
|
||||
*Matt Caswell*
|
||||
|
||||
* Check that ed25519 and ed448 are allowed by the security level. Previously
|
||||
signature algorithms not using an MD were not being checked that they were
|
||||
allowed by the security level.
|
||||
|
||||
*Kurt Roeckx*
|
||||
|
||||
* Fixed SSL_get_servername() behaviour. The behaviour of SSL_get_servername()
|
||||
was not quite right. The behaviour was not consistent between resumption
|
||||
and normal handshakes, and also not quite consistent with historical
|
||||
behaviour. The behaviour in various scenarios has been clarified and
|
||||
it has been updated to make it match historical behaviour as closely as
|
||||
possible.
|
||||
|
||||
*Matt Caswell*
|
||||
|
||||
* *[VMS only]* The header files that the VMS compilers include automatically,
|
||||
`__DECC_INCLUDE_PROLOGUE.H` and `__DECC_INCLUDE_EPILOGUE.H`, use pragmas
|
||||
|
||||
@@ -24,17 +24,17 @@
|
||||
|
||||
my $ndk_var;
|
||||
my $ndk;
|
||||
foreach (qw(ANDROID_NDK_HOME ANDROID_NDK)) {
|
||||
foreach (qw(ANDROID_NDK_ROOT ANDROID_NDK)) {
|
||||
$ndk_var = $_;
|
||||
$ndk = $ENV{$ndk_var};
|
||||
last if defined $ndk;
|
||||
}
|
||||
die "\$ANDROID_NDK_HOME is not defined" if (!$ndk);
|
||||
die "\$ANDROID_NDK_ROOT is not defined" if (!$ndk);
|
||||
if (!-d "$ndk/platforms" && !-f "$ndk/AndroidVersion.txt") {
|
||||
# $ndk/platforms is traditional "all-inclusive" NDK, while
|
||||
# $ndk/AndroidVersion.txt is so-called standalone toolchain
|
||||
# tailored for specific target down to API level.
|
||||
die "\$ANDROID_NDK_HOME=$ndk is invalid";
|
||||
die "\$ANDROID_NDK_ROOT=$ndk is invalid";
|
||||
}
|
||||
$ndk = canonpath($ndk);
|
||||
|
||||
@@ -168,7 +168,8 @@ my %targets = (
|
||||
cppflags => add(sub { android_ndk()->{cppflags} }),
|
||||
cxxflags => add(sub { android_ndk()->{cflags} }),
|
||||
bn_ops => sub { android_ndk()->{bn_ops} },
|
||||
bin_cflags => "-pie",
|
||||
bin_cflags => "-fPIE",
|
||||
bin_lflags => "-pie",
|
||||
enable => [ ],
|
||||
},
|
||||
"android-arm" => {
|
||||
|
||||
@@ -1025,6 +1025,7 @@ errors:
|
||||
qw( include/internal/dso.h
|
||||
include/internal/o_dir.h
|
||||
include/internal/err.h
|
||||
include/internal/evp.h
|
||||
include/internal/sslconf.h );
|
||||
our @cryptoskipheaders = ( @sslheaders,
|
||||
qw( include/openssl/conf_api.h
|
||||
|
||||
@@ -47,19 +47,22 @@ SHLIB_VERSION_NUMBER={- $config{shlib_version} -}
|
||||
LIBS={- join(" ", map { ( platform->sharedlib_import($_), platform->staticlib($_) ) } @{$unified_info{libraries}}) -}
|
||||
SHLIBS={- join(" ", map { platform->sharedlib($_) // () } @{$unified_info{libraries}}) -}
|
||||
SHLIBPDBS={- join(" ", map { platform->sharedlibpdb($_) // () } @{$unified_info{libraries}}) -}
|
||||
MODULES={- join(" ", map { platform->dso($_) } @{$unified_info{modules}}) -}
|
||||
MODULES={- our @MODULES = map { platform->dso($_) } @{$unified_info{modules}};
|
||||
join(" ", @MODULES) -}
|
||||
MODULEPDBS={- join(" ", map { platform->dsopdb($_) } @{$unified_info{modules}}) -}
|
||||
PROGRAMS={- our @PROGRAMS = map { platform->bin($_) } @{$unified_info{programs}}; join(" ", @PROGRAMS) -}
|
||||
PROGRAMPDBS={- join(" ", map { $_.".pdb" } @{$unified_info{programs}}) -}
|
||||
SCRIPTS={- join(" ", @{$unified_info{scripts}}) -}
|
||||
SCRIPTS={- our @SCRIPTS = @{$unified_info{scripts}}; join(" ", @SCRIPTS) -}
|
||||
{- output_off() if $disabled{makedepend}; "" -}
|
||||
DEPS={- join(" ", map { platform->isobj($_) ? platform->dep($_) : () }
|
||||
grep { $unified_info{sources}->{$_}->[0] =~ /\.c$/ }
|
||||
keys %{$unified_info{sources}}); -}
|
||||
{- output_on() if $disabled{makedepend}; "" -}
|
||||
GENERATED_MANDATORY={- join(" ", @{$unified_info{depends}->{""}} ) -}
|
||||
GENERATED_MANDATORY={- our @GENERATED_MANDATORY = @{$unified_info{depends}->{""}};
|
||||
join(" ", @GENERATED_MANDATORY) -}
|
||||
GENERATED={- # common0.tmpl provides @generated
|
||||
join(" ", map { platform->convertext($_) } @generated) -}
|
||||
our @GENERATED = map { platform->convertext($_) } @generated;
|
||||
join(" ", @GENERATED) -}
|
||||
|
||||
INSTALL_LIBS={-
|
||||
join(" ", map { quotify1(platform->sharedlib_import($_)
|
||||
@@ -417,10 +420,10 @@ clean: libclean
|
||||
-rmdir /Q /S $(HTMLDOCS5_BLDDIRS)
|
||||
-rmdir /Q /S $(HTMLDOCS7_BLDDIRS)
|
||||
{- join("\n\t", map { "-del /Q /F $_" } @PROGRAMS) -}
|
||||
-del /Q /F $(MODULES)
|
||||
-del /Q /F $(SCRIPTS)
|
||||
-del /Q /F $(GENERATED_MANDATORY)
|
||||
-del /Q /F $(GENERATED)
|
||||
{- join("\n\t", map { "-del /Q /F $_" } @MODULES) -}
|
||||
{- join("\n\t", map { "-del /Q /F $_" } @SCRIPTS) -}
|
||||
{- join("\n\t", map { "-del /Q /F $_" } @GENERATED_MANDATORY) -}
|
||||
{- join("\n\t", map { "-del /Q /F $_" } @GENERATED) -}
|
||||
-del /Q /S /F *.d *.obj *.pdb *.ilk *.manifest
|
||||
-del /Q /S /F engines\*.lib engines\*.exp
|
||||
-del /Q /S /F apps\*.lib apps\*.rc apps\*.res apps\*.exp
|
||||
|
||||
@@ -31,6 +31,7 @@ OpenSSL 3.0
|
||||
* enable-crypto-mdebug and enable-crypto-mdebug-backtrace were mostly
|
||||
disabled; the project uses address sanitize/leak-detect instead.
|
||||
* Added OSSL_SERIALIZER, a generic serializer API.
|
||||
* Added OSSL_PARAM_BLD, an easier to use API to OSSL_PARAM.
|
||||
* Added error raising macros, ERR_raise() and ERR_raise_data().
|
||||
* Deprecated ERR_put_error().
|
||||
* Added OSSL_PROVIDER_available(), to check provider availibility.
|
||||
@@ -57,6 +58,15 @@ OpenSSL 3.0
|
||||
OpenSSL 1.1.1
|
||||
-------------
|
||||
|
||||
### Major changes between OpenSSL 1.1.1e and OpenSSL 1.1.1f [under development] ###
|
||||
|
||||
*
|
||||
|
||||
### Major changes between OpenSSL 1.1.1d and OpenSSL 1.1.1e [17 Mar 2020] ###
|
||||
|
||||
* Fixed an overflow bug in the x64_64 Montgomery squaring procedure
|
||||
used in exponentiation with 512-bit moduli ([CVE-2019-1551][])
|
||||
|
||||
### Major changes between OpenSSL 1.1.1c and OpenSSL 1.1.1d [10 Sep 2019] ###
|
||||
|
||||
* Fixed a fork protection issue ([CVE-2019-1549][])
|
||||
@@ -1295,6 +1305,7 @@ OpenSSL 0.9.x
|
||||
[CVE-2019-1563]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1563
|
||||
[CVE-2019-1559]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1559
|
||||
[CVE-2019-1552]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1552
|
||||
[CVE-2019-1551]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1551
|
||||
[CVE-2019-1549]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1549
|
||||
[CVE-2019-1547]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1547
|
||||
[CVE-2019-1543]: https://www.openssl.org/news/vulnerabilities.html#CVE-2019-1543
|
||||
|
||||
+8
-8
@@ -24,7 +24,7 @@
|
||||
need to know the prefix to extend your PATH, in order to 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_HOME environment to point at the
|
||||
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>.
|
||||
@@ -35,21 +35,21 @@
|
||||
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
|
||||
|
||||
export ANDROID_NDK_HOME=/home/whoever/Android/android-sdk/ndk/20.0.5594570
|
||||
PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH
|
||||
export ANDROID_NDK_ROOT=/home/whoever/Android/android-sdk/ndk/20.0.5594570
|
||||
PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH
|
||||
./Configure android-arm64 -D__ANDROID_API__=29
|
||||
make
|
||||
|
||||
Older versions of the NDK have GCC under their common prebuilt tools directory, so the bin path
|
||||
will be slightly different. EG: to compile for ICS on ARM with NDK 10d:
|
||||
|
||||
export ANDROID_NDK_HOME=/some/where/android-ndk-10d
|
||||
PATH=$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin:$PATH
|
||||
export ANDROID_NDK_ROOT=/some/where/android-ndk-10d
|
||||
PATH=$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin:$PATH
|
||||
./Configure android-arm -D__ANDROID_API__=14
|
||||
make
|
||||
|
||||
Caveat lector! Earlier OpenSSL versions relied on additional CROSS_SYSROOT
|
||||
variable set to $ANDROID_NDK_HOME/platforms/android-<api>/arch-<arch> to
|
||||
variable set to $ANDROID_NDK_ROOT/platforms/android-<api>/arch-<arch> to
|
||||
appoint headers-n-libraries' location. It's still recognized in order
|
||||
to facilitate migration from older projects. However, since API level
|
||||
appears in CROSS_SYSROOT value, passing -D__ANDROID_API__=N can be in
|
||||
@@ -64,9 +64,9 @@
|
||||
|
||||
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_HOME. 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_HOME/bin:$PATH suffices.
|
||||
adjustment becomes simpler, $ANDROID_NDK_ROOT/bin:$PATH suffices.
|
||||
|
||||
Running tests (on Linux)
|
||||
------------------------
|
||||
|
||||
+74
-54
@@ -14,57 +14,63 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $openssl = "openssl";
|
||||
if(defined $ENV{'OPENSSL'}) {
|
||||
$openssl = $ENV{'OPENSSL'};
|
||||
} else {
|
||||
$ENV{'OPENSSL'} = $openssl;
|
||||
}
|
||||
|
||||
my $verbose = 1;
|
||||
my @OPENSSL_CMDS = ("req", "ca", "pkcs12", "x509", "verify");
|
||||
|
||||
my $OPENSSL_CONFIG = $ENV{"OPENSSL_CONFIG"} || "";
|
||||
my $DAYS = "-days 365";
|
||||
my $CADAYS = "-days 1095"; # 3 years
|
||||
my $openssl = $ENV{'OPENSSL'} // "openssl";
|
||||
$ENV{'OPENSSL'} = $openssl;
|
||||
my $OPENSSL_CONFIG = $ENV{"OPENSSL_CONFIG"} // "";
|
||||
|
||||
# Command invocations.
|
||||
my $REQ = "$openssl req $OPENSSL_CONFIG";
|
||||
my $CA = "$openssl ca $OPENSSL_CONFIG";
|
||||
my $VERIFY = "$openssl verify";
|
||||
my $X509 = "$openssl x509";
|
||||
my $PKCS12 = "$openssl pkcs12";
|
||||
|
||||
# default openssl.cnf file has setup as per the following
|
||||
# Default values for various configuration settings.
|
||||
my $CATOP = "./demoCA";
|
||||
my $CAKEY = "cakey.pem";
|
||||
my $CAREQ = "careq.pem";
|
||||
my $CACERT = "cacert.pem";
|
||||
my $CACRL = "crl.pem";
|
||||
my $DIRMODE = 0777;
|
||||
|
||||
my $DAYS = "-days 365";
|
||||
my $CADAYS = "-days 1095"; # 3 years
|
||||
my $NEWKEY = "newkey.pem";
|
||||
my $NEWREQ = "newreq.pem";
|
||||
my $NEWCERT = "newcert.pem";
|
||||
my $NEWP12 = "newcert.p12";
|
||||
my $RET = 0;
|
||||
my $WHAT = shift @ARGV || "";
|
||||
my @OPENSSL_CMDS = ("req", "ca", "pkcs12", "x509", "verify");
|
||||
my %EXTRA = extra_args(\@ARGV, "-extra-");
|
||||
my $FILE;
|
||||
|
||||
sub extra_args {
|
||||
my ($args_ref, $arg_prefix) = @_;
|
||||
my %eargs = map {
|
||||
if ($_ < $#$args_ref) {
|
||||
my ($arg, $value) = splice(@$args_ref, $_, 2);
|
||||
$arg =~ s/$arg_prefix//;
|
||||
($arg, $value);
|
||||
} else {
|
||||
();
|
||||
# Commandline parsing
|
||||
my %EXTRA;
|
||||
my $WHAT = shift @ARGV || "";
|
||||
@ARGV = parse_extra(@ARGV);
|
||||
my $RET = 0;
|
||||
|
||||
# Split out "-extra-CMD value", and return new |@ARGV|. Fill in
|
||||
# |EXTRA{CMD}| with list of values.
|
||||
sub parse_extra
|
||||
{
|
||||
foreach ( @OPENSSL_CMDS ) {
|
||||
$EXTRA{$_} = '';
|
||||
}
|
||||
} reverse grep($$args_ref[$_] =~ /$arg_prefix/, 0..$#$args_ref);
|
||||
my %empty = map { ($_, "") } @OPENSSL_CMDS;
|
||||
return (%empty, %eargs);
|
||||
|
||||
my @result;
|
||||
while ( scalar(@_) > 0 ) {
|
||||
my $arg = shift;
|
||||
if ( $arg !~ m/-extra-([a-z0-9]+)/ ) {
|
||||
push @result, $arg;
|
||||
next;
|
||||
}
|
||||
$arg =~ s/-extra-//;
|
||||
die("Unknown \"-${arg}-extra\" option, exiting")
|
||||
unless scalar grep { $arg eq $_ } @OPENSSL_CMDS;
|
||||
$EXTRA{$arg} .= " " . shift;
|
||||
}
|
||||
return @result;
|
||||
}
|
||||
|
||||
|
||||
# See if reason for a CRL entry is valid; exit if not.
|
||||
sub crl_reason_ok
|
||||
{
|
||||
@@ -113,19 +119,25 @@ sub run
|
||||
|
||||
|
||||
if ( $WHAT =~ /^(-\?|-h|-help)$/ ) {
|
||||
print STDERR "usage: CA.pl -newcert | -newreq | -newreq-nodes | -xsign | -sign | -signCA | -signcert | -crl | -newca [-extra-cmd extra-params]\n";
|
||||
print STDERR " CA.pl -pkcs12 [-extra-pkcs12 extra-params] [certname]\n";
|
||||
print STDERR " CA.pl -verify [-extra-verify extra-params] certfile ...\n";
|
||||
print STDERR " CA.pl -revoke [-extra-ca extra-params] certfile [reason]\n";
|
||||
print STDERR <<EOF;
|
||||
Usage:
|
||||
CA.pl -newcert | -newreq | -newreq-nodes | -xsign | -sign | -signCA | -signcert | -crl | -newca [-extra-cmd parameter]
|
||||
CA.pl -pkcs12 [-extra-pkcs12 parameter] [certname]
|
||||
CA.pl -verify [-extra-verify parameter] certfile ...
|
||||
CA.pl -revoke [-extra-ca parameter] certfile [reason]
|
||||
EOF
|
||||
exit 0;
|
||||
}
|
||||
|
||||
if ($WHAT eq '-newcert' ) {
|
||||
# create a certificate
|
||||
$RET = run("$REQ -new -x509 -keyout $NEWKEY -out $NEWCERT $DAYS $EXTRA{req}");
|
||||
$RET = run("$REQ -new -x509 -keyout $NEWKEY -out $NEWCERT $DAYS"
|
||||
. " $EXTRA{req}");
|
||||
print "Cert is in $NEWCERT, private key is in $NEWKEY\n" if $RET == 0;
|
||||
} elsif ($WHAT eq '-precert' ) {
|
||||
# create a pre-certificate
|
||||
$RET = run("$REQ -x509 -precert -keyout $NEWKEY -out $NEWCERT $DAYS");
|
||||
$RET = run("$REQ -x509 -precert -keyout $NEWKEY -out $NEWCERT $DAYS"
|
||||
. " $EXTRA{req}");
|
||||
print "Pre-cert is in $NEWCERT, private key is in $NEWKEY\n" if $RET == 0;
|
||||
} elsif ($WHAT =~ /^\-newreq(\-nodes)?$/ ) {
|
||||
# create a certificate request
|
||||
@@ -133,11 +145,20 @@ if ($WHAT eq '-newcert' ) {
|
||||
print "Request is in $NEWREQ, private key is in $NEWKEY\n" if $RET == 0;
|
||||
} elsif ($WHAT eq '-newca' ) {
|
||||
# create the directory hierarchy
|
||||
mkdir ${CATOP}, $DIRMODE;
|
||||
mkdir "${CATOP}/certs", $DIRMODE;
|
||||
mkdir "${CATOP}/crl", $DIRMODE ;
|
||||
mkdir "${CATOP}/newcerts", $DIRMODE;
|
||||
mkdir "${CATOP}/private", $DIRMODE;
|
||||
my @dirs = ( "${CATOP}", "${CATOP}/certs", "${CATOP}/crl",
|
||||
"${CATOP}/newcerts", "${CATOP}/private" );
|
||||
die "${CATOP}/index.txt exists.\nRemove old sub-tree to proceed,"
|
||||
if -f "${CATOP}/index.txt";
|
||||
die "${CATOP}/serial exists.\nRemove old sub-tree to proceed,"
|
||||
if -f "${CATOP}/serial";
|
||||
foreach my $d ( @dirs ) {
|
||||
if ( -d $d ) {
|
||||
warn "Directory $d exists" if -d $d;
|
||||
} else {
|
||||
mkdir $d or die "Can't mkdir $d, $!";
|
||||
}
|
||||
}
|
||||
|
||||
open OUT, ">${CATOP}/index.txt";
|
||||
close OUT;
|
||||
open OUT, ">${CATOP}/crlnumber";
|
||||
@@ -145,6 +166,7 @@ if ($WHAT eq '-newcert' ) {
|
||||
close OUT;
|
||||
# ask user for existing CA certificate
|
||||
print "CA certificate filename (or enter to create)\n";
|
||||
my $FILE;
|
||||
$FILE = "" unless defined($FILE = <STDIN>);
|
||||
$FILE =~ s{\R$}{};
|
||||
if ($FILE ne "") {
|
||||
@@ -152,44 +174,42 @@ if ($WHAT eq '-newcert' ) {
|
||||
copy_pemfile($FILE,"${CATOP}/$CACERT", "CERTIFICATE");
|
||||
} else {
|
||||
print "Making CA certificate ...\n";
|
||||
$RET = run("$REQ -new -keyout"
|
||||
. " ${CATOP}/private/$CAKEY"
|
||||
$RET = run("$REQ -new -keyout ${CATOP}/private/$CAKEY"
|
||||
. " -out ${CATOP}/$CAREQ $EXTRA{req}");
|
||||
$RET = run("$CA -create_serial"
|
||||
. " -out ${CATOP}/$CACERT $CADAYS -batch"
|
||||
. " -keyfile ${CATOP}/private/$CAKEY -selfsign"
|
||||
. " -extensions v3_ca $EXTRA{ca}"
|
||||
. " -infiles ${CATOP}/$CAREQ") if $RET == 0;
|
||||
. " -extensions v3_ca"
|
||||
. " -infiles ${CATOP}/$CAREQ $EXTRA{ca}") if $RET == 0;
|
||||
print "CA certificate is in ${CATOP}/$CACERT\n" if $RET == 0;
|
||||
}
|
||||
} elsif ($WHAT eq '-pkcs12' ) {
|
||||
my $cname = $ARGV[0];
|
||||
$cname = "My Certificate" unless defined $cname;
|
||||
$RET = run("$PKCS12 -in $NEWCERT -inkey $NEWKEY"
|
||||
. " -certfile ${CATOP}/$CACERT"
|
||||
. " -out $NEWP12"
|
||||
. " -certfile ${CATOP}/$CACERT -out $NEWP12"
|
||||
. " -export -name \"$cname\" $EXTRA{pkcs12}");
|
||||
print "PKCS #12 file is in $NEWP12\n" if $RET == 0;
|
||||
} elsif ($WHAT eq '-xsign' ) {
|
||||
$RET = run("$CA -policy policy_anything $EXTRA{ca} -infiles $NEWREQ");
|
||||
$RET = run("$CA -policy policy_anything -infiles $NEWREQ $EXTRA{ca}");
|
||||
} elsif ($WHAT eq '-sign' ) {
|
||||
$RET = run("$CA -policy policy_anything -out $NEWCERT $EXTRA{ca} -infiles $NEWREQ");
|
||||
$RET = run("$CA -policy policy_anything -out $NEWCERT"
|
||||
. " -infiles $NEWREQ $EXTRA{ca}");
|
||||
print "Signed certificate is in $NEWCERT\n" if $RET == 0;
|
||||
} elsif ($WHAT eq '-signCA' ) {
|
||||
$RET = run("$CA -policy policy_anything -out $NEWCERT"
|
||||
. " -extensions v3_ca $EXTRA{ca} -infiles $NEWREQ");
|
||||
. " -extensions v3_ca -infiles $NEWREQ $EXTRA{ca}");
|
||||
print "Signed CA certificate is in $NEWCERT\n" if $RET == 0;
|
||||
} elsif ($WHAT eq '-signcert' ) {
|
||||
$RET = run("$X509 -x509toreq -in $NEWREQ -signkey $NEWREQ"
|
||||
. " -out tmp.pem $EXTRA{x509}");
|
||||
$RET = run("$CA -policy policy_anything -out $NEWCERT"
|
||||
. "$EXTRA{ca} -infiles tmp.pem") if $RET == 0;
|
||||
. "-infiles tmp.pem $EXTRA{ca}") if $RET == 0;
|
||||
print "Signed certificate is in $NEWCERT\n" if $RET == 0;
|
||||
} elsif ($WHAT eq '-verify' ) {
|
||||
my @files = @ARGV ? @ARGV : ( $NEWCERT );
|
||||
my $file;
|
||||
foreach $file (@files) {
|
||||
my $status = run("$VERIFY \"-CAfile\" ${CATOP}/$CACERT $file $EXTRA{verify}");
|
||||
foreach my $file (@files) {
|
||||
my $status = run("$VERIFY -CAfile ${CATOP}/$CACERT $file $EXTRA{verify}");
|
||||
$RET = $status if $status != 0;
|
||||
}
|
||||
} elsif ($WHAT eq '-crl' ) {
|
||||
|
||||
+29
-4
@@ -13,15 +13,40 @@ ENDIF
|
||||
$OPENSSLSRC=\
|
||||
openssl.c progs.c \
|
||||
asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c \
|
||||
ec.c ecparam.c enc.c engine.c errstr.c \
|
||||
enc.c errstr.c \
|
||||
genpkey.c genrsa.c kdf.c mac.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c \
|
||||
pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c \
|
||||
rsautl.c s_client.c s_server.c s_time.c sess_id.c smime.c speed.c \
|
||||
spkac.c srp.c ts.c verify.c version.c x509.c rehash.c storeutl.c \
|
||||
spkac.c verify.c version.c x509.c rehash.c storeutl.c \
|
||||
list.c info.c provider.c fipsinstall.c
|
||||
IF[{- !$disabled{'des'} -}]
|
||||
$OPENSSLSRC=$OPENSSLSRC pkcs12.c
|
||||
ENDIF
|
||||
IF[{- !$disabled{'ec'} -}]
|
||||
$OPENSSLSRC=$OPENSSLSRC ec.c ecparam.c
|
||||
ENDIF
|
||||
IF[{- !$disabled{'ocsp'} -}]
|
||||
$OPENSSLSRC=$OPENSSLSRC ocsp.c
|
||||
ENDIF
|
||||
IF[{- !$disabled{'srp'} -}]
|
||||
$OPENSSLSRC=$OPENSSLSRC srp.c
|
||||
ENDIF
|
||||
IF[{- !$disabled{'ts'} -}]
|
||||
$OPENSSLSRC=$OPENSSLSRC ts.c
|
||||
ENDIF
|
||||
IF[{- !$disabled{'deprecated-3.0'} -}]
|
||||
$OPENSSLSRC=$OPENSSLSRC \
|
||||
dhparam.c dsa.c dsaparam.c gendsa.c
|
||||
IF[{- !$disabled{'dh'} -}]
|
||||
$OPENSSLSRC=$OPENSSLSRC dhparam.c
|
||||
ENDIF
|
||||
IF[{- !$disabled{'dsa'} -}]
|
||||
$OPENSSLSRC=$OPENSSLSRC dsa.c dsaparam.c gendsa.c
|
||||
ENDIF
|
||||
IF[{- !$disabled{'engine'} -}]
|
||||
$OPENSSLSRC=$OPENSSLSRC engine.c
|
||||
ENDIF
|
||||
ENDIF
|
||||
IF[{- !$disabled{'cmp'} -}]
|
||||
$OPENSSLSRC=$OPENSSLSRC cmp_mock_srv.c
|
||||
ENDIF
|
||||
|
||||
IF[{- !$disabled{apps} -}]
|
||||
|
||||
@@ -89,17 +89,20 @@ typedef enum {
|
||||
static char *lookup_conf(const CONF *conf, const char *group, const char *tag);
|
||||
|
||||
static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
|
||||
const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
|
||||
const EVP_MD *dgst,
|
||||
STACK_OF(OPENSSL_STRING) *sigopts,
|
||||
STACK_OF(OPENSSL_STRING) *vfyopts,
|
||||
STACK_OF(CONF_VALUE) *policy, CA_DB *db,
|
||||
BIGNUM *serial, const char *subj, unsigned long chtype,
|
||||
int multirdn, int email_dn, const char *startdate,
|
||||
const char *enddate,
|
||||
long days, int batch, const char *ext_sect, CONF *conf,
|
||||
int verbose, unsigned long certopt, unsigned long nameopt,
|
||||
int default_op, int ext_copy, int selfsign,
|
||||
unsigned char *sm2_id, size_t sm2idlen);
|
||||
int default_op, int ext_copy, int selfsign);
|
||||
static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
|
||||
const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
|
||||
const EVP_MD *dgst,
|
||||
STACK_OF(OPENSSL_STRING) *sigopts,
|
||||
STACK_OF(OPENSSL_STRING) *vfyopts,
|
||||
STACK_OF(CONF_VALUE) *policy, CA_DB *db,
|
||||
BIGNUM *serial, const char *subj, unsigned long chtype,
|
||||
int multirdn, int email_dn, const char *startdate,
|
||||
@@ -142,13 +145,13 @@ typedef enum OPTION_choice {
|
||||
OPT_ENGINE, OPT_VERBOSE, OPT_CONFIG, OPT_NAME, OPT_SUBJ, OPT_UTF8,
|
||||
OPT_CREATE_SERIAL, OPT_MULTIVALUE_RDN, OPT_STARTDATE, OPT_ENDDATE,
|
||||
OPT_DAYS, OPT_MD, OPT_POLICY, OPT_KEYFILE, OPT_KEYFORM, OPT_PASSIN,
|
||||
OPT_KEY, OPT_CERT, OPT_SELFSIGN, OPT_IN, OPT_OUT, OPT_OUTDIR,
|
||||
OPT_KEY, OPT_CERT, OPT_SELFSIGN, OPT_IN, OPT_OUT, OPT_OUTDIR, OPT_VFYOPT,
|
||||
OPT_SIGOPT, OPT_NOTEXT, OPT_BATCH, OPT_PRESERVEDN, OPT_NOEMAILDN,
|
||||
OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC,
|
||||
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_R_ENUM, OPT_SM2ID, OPT_SM2HEXID, OPT_PROV_ENUM,
|
||||
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
|
||||
} OPTION_CHOICE;
|
||||
@@ -197,12 +200,6 @@ const OPTIONS ca_options[] = {
|
||||
"Extension section (override value in config file)"},
|
||||
{"extfile", OPT_EXTFILE, '<',
|
||||
"Configuration file with X509v3 extensions to add"},
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
{"sm2-id", OPT_SM2ID, 's',
|
||||
"Specify an ID string to verify an SM2 certificate request"},
|
||||
{"sm2-hex-id", OPT_SM2HEXID, 's',
|
||||
"Specify a hex ID string to verify an SM2 certificate request"},
|
||||
#endif
|
||||
{"preserveDN", OPT_PRESERVEDN, '-', "Don't re-order the DN"},
|
||||
{"noemailDN", OPT_NOEMAILDN, '-', "Don't add the EMAIL field to the DN"},
|
||||
|
||||
@@ -216,6 +213,7 @@ const OPTIONS ca_options[] = {
|
||||
{"selfsign", OPT_SELFSIGN, '-',
|
||||
"Sign a cert with the key associated with it"},
|
||||
{"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
|
||||
{"vfyopt", OPT_SIGOPT, 's', "Verification parameter in n:v form"},
|
||||
|
||||
OPT_SECTION("Revocation"),
|
||||
{"gencrl", OPT_GENCRL, '-', "Generate a new CRL"},
|
||||
@@ -257,7 +255,7 @@ int ca_main(int argc, char **argv)
|
||||
CA_DB *db = NULL;
|
||||
DB_ATTR db_attr;
|
||||
STACK_OF(CONF_VALUE) *attribs = NULL;
|
||||
STACK_OF(OPENSSL_STRING) *sigopts = NULL;
|
||||
STACK_OF(OPENSSL_STRING) *sigopts = NULL, *vfyopts = NULL;
|
||||
STACK_OF(X509) *cert_sk = NULL;
|
||||
X509_CRL *crl = NULL;
|
||||
const EVP_MD *dgst = NULL;
|
||||
@@ -286,9 +284,6 @@ int ca_main(int argc, char **argv)
|
||||
REVINFO_TYPE rev_type = REV_NONE;
|
||||
X509_REVOKED *r = NULL;
|
||||
OPTION_CHOICE o;
|
||||
unsigned char *sm2_id = NULL;
|
||||
size_t sm2_idlen = 0;
|
||||
int sm2_free = 0;
|
||||
|
||||
prog = opt_init(argc, argv, ca_options);
|
||||
while ((o = opt_next()) != OPT_EOF) {
|
||||
@@ -385,6 +380,12 @@ opthelp:
|
||||
if (sigopts == NULL || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
|
||||
goto end;
|
||||
break;
|
||||
case OPT_VFYOPT:
|
||||
if (vfyopts == NULL)
|
||||
vfyopts = sk_OPENSSL_STRING_new_null();
|
||||
if (vfyopts == NULL || !sk_OPENSSL_STRING_push(vfyopts, opt_arg()))
|
||||
goto end;
|
||||
break;
|
||||
case OPT_NOTEXT:
|
||||
notext = 1;
|
||||
break;
|
||||
@@ -456,30 +457,6 @@ opthelp:
|
||||
case OPT_ENGINE:
|
||||
e = setup_engine(opt_arg(), 0);
|
||||
break;
|
||||
case OPT_SM2ID:
|
||||
/* we assume the input is not a hex string */
|
||||
if (sm2_id != NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"Use one of the options 'sm2-hex-id' or 'sm2-id'\n");
|
||||
goto end;
|
||||
}
|
||||
sm2_id = (unsigned char *)opt_arg();
|
||||
sm2_idlen = strlen((const char *)sm2_id);
|
||||
break;
|
||||
case OPT_SM2HEXID:
|
||||
/* try to parse the input as hex string first */
|
||||
if (sm2_id != NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"Use one of the options 'sm2-hex-id' or 'sm2-id'\n");
|
||||
goto end;
|
||||
}
|
||||
sm2_free = 1;
|
||||
sm2_id = OPENSSL_hexstr2buf(opt_arg(), (long *)&sm2_idlen);
|
||||
if (sm2_id == NULL) {
|
||||
BIO_printf(bio_err, "Invalid hex string input\n");
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
end_of_options:
|
||||
@@ -944,8 +921,8 @@ end_of_options:
|
||||
}
|
||||
if (ss_cert_file != NULL) {
|
||||
total++;
|
||||
j = certify_cert(&x, ss_cert_file, pkey, x509, dgst, sigopts,
|
||||
attribs,
|
||||
j = certify_cert(&x, ss_cert_file, pkey, x509, dgst,
|
||||
sigopts, vfyopts, attribs,
|
||||
db, serial, subj, chtype, multirdn, email_dn,
|
||||
startdate, enddate, days, batch, extensions,
|
||||
conf, verbose, certopt, get_nameopt(), default_op,
|
||||
@@ -965,11 +942,11 @@ end_of_options:
|
||||
}
|
||||
if (infile != NULL) {
|
||||
total++;
|
||||
j = certify(&x, infile, pkey, x509p, dgst, sigopts, attribs, db,
|
||||
j = certify(&x, infile, pkey, x509p, dgst, sigopts, vfyopts,
|
||||
attribs, db,
|
||||
serial, subj, chtype, multirdn, email_dn, startdate,
|
||||
enddate, days, batch, extensions, conf, verbose,
|
||||
certopt, get_nameopt(), default_op, ext_copy, selfsign,
|
||||
sm2_id, sm2_idlen);
|
||||
certopt, get_nameopt(), default_op, ext_copy, selfsign);
|
||||
if (j < 0)
|
||||
goto end;
|
||||
if (j > 0) {
|
||||
@@ -985,11 +962,11 @@ end_of_options:
|
||||
}
|
||||
for (i = 0; i < argc; i++) {
|
||||
total++;
|
||||
j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, attribs, db,
|
||||
j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, vfyopts,
|
||||
attribs, db,
|
||||
serial, subj, chtype, multirdn, email_dn, startdate,
|
||||
enddate, days, batch, extensions, conf, verbose,
|
||||
certopt, get_nameopt(), default_op, ext_copy, selfsign,
|
||||
sm2_id, sm2_idlen);
|
||||
certopt, get_nameopt(), default_op, ext_copy, selfsign);
|
||||
if (j < 0)
|
||||
goto end;
|
||||
if (j > 0) {
|
||||
@@ -1287,8 +1264,6 @@ end_of_options:
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
if (sm2_free)
|
||||
OPENSSL_free(sm2_id);
|
||||
if (ret)
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_free_all(Sout);
|
||||
@@ -1302,6 +1277,7 @@ end_of_options:
|
||||
BN_free(crlnumber);
|
||||
free_index(db);
|
||||
sk_OPENSSL_STRING_free(sigopts);
|
||||
sk_OPENSSL_STRING_free(vfyopts);
|
||||
EVP_PKEY_free(pkey);
|
||||
X509_free(x509);
|
||||
X509_CRL_free(crl);
|
||||
@@ -1320,15 +1296,16 @@ static char *lookup_conf(const CONF *conf, const char *section, const char *tag)
|
||||
}
|
||||
|
||||
static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
|
||||
const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
|
||||
const EVP_MD *dgst,
|
||||
STACK_OF(OPENSSL_STRING) *sigopts,
|
||||
STACK_OF(OPENSSL_STRING) *vfyopts,
|
||||
STACK_OF(CONF_VALUE) *policy, CA_DB *db,
|
||||
BIGNUM *serial, const char *subj, unsigned long chtype,
|
||||
int multirdn, int email_dn, const char *startdate,
|
||||
const char *enddate,
|
||||
long days, int batch, const char *ext_sect, CONF *lconf,
|
||||
int verbose, unsigned long certopt, unsigned long nameopt,
|
||||
int default_op, int ext_copy, int selfsign,
|
||||
unsigned char *sm2id, size_t sm2idlen)
|
||||
int default_op, int ext_copy, int selfsign)
|
||||
{
|
||||
X509_REQ *req = NULL;
|
||||
BIO *in = NULL;
|
||||
@@ -1360,26 +1337,7 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
|
||||
BIO_printf(bio_err, "error unpacking public key\n");
|
||||
goto end;
|
||||
}
|
||||
if (sm2id != NULL) {
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
ASN1_OCTET_STRING *v;
|
||||
|
||||
v = ASN1_OCTET_STRING_new();
|
||||
if (v == NULL) {
|
||||
BIO_printf(bio_err, "error: SM2 ID allocation failed\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!ASN1_OCTET_STRING_set(v, sm2id, sm2idlen)) {
|
||||
BIO_printf(bio_err, "error: setting SM2 ID failed\n");
|
||||
ASN1_OCTET_STRING_free(v);
|
||||
goto end;
|
||||
}
|
||||
|
||||
X509_REQ_set0_sm2_id(req, v);
|
||||
#endif
|
||||
}
|
||||
i = X509_REQ_verify(req, pktmp);
|
||||
i = do_X509_REQ_verify(req, pktmp, vfyopts);
|
||||
pktmp = NULL;
|
||||
if (i < 0) {
|
||||
ok = 0;
|
||||
@@ -1409,7 +1367,9 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
|
||||
}
|
||||
|
||||
static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
|
||||
const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
|
||||
const EVP_MD *dgst,
|
||||
STACK_OF(OPENSSL_STRING) *sigopts,
|
||||
STACK_OF(OPENSSL_STRING) *vfyopts,
|
||||
STACK_OF(CONF_VALUE) *policy, CA_DB *db,
|
||||
BIGNUM *serial, const char *subj, unsigned long chtype,
|
||||
int multirdn, int email_dn, const char *startdate,
|
||||
@@ -1433,7 +1393,7 @@ static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x
|
||||
BIO_printf(bio_err, "error unpacking public key\n");
|
||||
goto end;
|
||||
}
|
||||
i = X509_verify(req, pktmp);
|
||||
i = do_X509_verify(req, pktmp, vfyopts);
|
||||
if (i < 0) {
|
||||
ok = 0;
|
||||
BIO_printf(bio_err, "Signature verification problems....\n");
|
||||
@@ -1470,7 +1430,8 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
|
||||
CONF *lconf, unsigned long certopt, unsigned long nameopt,
|
||||
int default_op, int ext_copy, int selfsign)
|
||||
{
|
||||
X509_NAME *name = NULL, *CAname = NULL, *subject = NULL;
|
||||
const X509_NAME *name = NULL;
|
||||
X509_NAME *CAname = NULL, *subject = NULL;
|
||||
const ASN1_TIME *tm;
|
||||
ASN1_STRING *str, *str2;
|
||||
ASN1_OBJECT *obj;
|
||||
|
||||
@@ -0,0 +1,407 @@
|
||||
/*
|
||||
* Copyright 2018-2020 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
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or atf
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "apps.h"
|
||||
#include "cmp_mock_srv.h"
|
||||
|
||||
#include <openssl/cmp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/cmperr.h>
|
||||
|
||||
/* the context for the CMP mock server */
|
||||
typedef struct
|
||||
{
|
||||
X509 *certOut; /* certificate to be returned in cp/ip/kup msg */
|
||||
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 */
|
||||
OSSL_CMP_PKISI *statusOut; /* status for ip/cp/kup/rp msg unless polling */
|
||||
int sendError; /* send error response also on valid requests */
|
||||
OSSL_CMP_MSG *certReq; /* ir/cr/p10cr/kur remembered while polling */
|
||||
int certReqId; /* id of last ir/cr/kur, used for polling */
|
||||
int pollCount; /* number of polls before actual cert response */
|
||||
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->certOut);
|
||||
sk_X509_pop_free(ctx->chainOut, X509_free);
|
||||
sk_X509_pop_free(ctx->caPubsOut, X509_free);
|
||||
OSSL_CMP_MSG_free(ctx->certReq);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
static mock_srv_ctx *mock_srv_ctx_new(void)
|
||||
{
|
||||
mock_srv_ctx *ctx = OPENSSL_zalloc(sizeof(mock_srv_ctx));
|
||||
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
|
||||
if ((ctx->statusOut = OSSL_CMP_PKISI_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
ctx->certReqId = -1;
|
||||
|
||||
/* all other elements are initialized to 0 or NULL, respectively */
|
||||
return ctx;
|
||||
err:
|
||||
mock_srv_ctx_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert)
|
||||
{
|
||||
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
|
||||
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
if (cert == NULL || X509_up_ref(cert)) {
|
||||
X509_free(ctx->certOut);
|
||||
ctx->certOut = cert;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
STACK_OF(X509) *chain)
|
||||
{
|
||||
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
|
||||
STACK_OF(X509) *chain_copy = NULL;
|
||||
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
if (chain != NULL && (chain_copy = X509_chain_up_ref(chain)) == NULL)
|
||||
return 0;
|
||||
sk_X509_pop_free(ctx->chainOut, X509_free);
|
||||
ctx->chainOut = chain_copy;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
STACK_OF(X509) *caPubs)
|
||||
{
|
||||
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
|
||||
STACK_OF(X509) *caPubs_copy = NULL;
|
||||
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
if (caPubs != NULL && (caPubs_copy = X509_chain_up_ref(caPubs)) == NULL)
|
||||
return 0;
|
||||
sk_X509_pop_free(ctx->caPubsOut, X509_free);
|
||||
ctx->caPubsOut = caPubs_copy;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status,
|
||||
int fail_info, const char *text)
|
||||
{
|
||||
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
|
||||
OSSL_CMP_PKISI *si;
|
||||
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
if ((si = OSSL_CMP_STATUSINFO_new(status, fail_info, text)) == NULL)
|
||||
return 0;
|
||||
OSSL_CMP_PKISI_free(ctx->statusOut);
|
||||
ctx->statusOut = si;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ossl_cmp_mock_srv_set_send_error(OSSL_CMP_SRV_CTX *srv_ctx, int val)
|
||||
{
|
||||
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
|
||||
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
ctx->sendError = val != 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX *srv_ctx, int count)
|
||||
{
|
||||
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
|
||||
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
if (count < 0) {
|
||||
CMPerr(0, CMP_R_INVALID_ARGS);
|
||||
return 0;
|
||||
}
|
||||
ctx->pollCount = count;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec)
|
||||
{
|
||||
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
|
||||
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
ctx->checkAfterTime = sec;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *cert_req,
|
||||
int certReqId,
|
||||
const OSSL_CRMF_MSG *crm,
|
||||
const X509_REQ *p10cr,
|
||||
X509 **certOut,
|
||||
STACK_OF(X509) **chainOut,
|
||||
STACK_OF(X509) **caPubs)
|
||||
{
|
||||
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
|
||||
OSSL_CMP_PKISI *si = NULL;
|
||||
|
||||
if (ctx == NULL || cert_req == NULL
|
||||
|| certOut == NULL || chainOut == NULL || caPubs == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
if (ctx->sendError) {
|
||||
CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*certOut = NULL;
|
||||
*chainOut = NULL;
|
||||
*caPubs = NULL;
|
||||
ctx->certReqId = certReqId;
|
||||
if (ctx->pollCount > 0) {
|
||||
ctx->pollCount--;
|
||||
OSSL_CMP_MSG_free(ctx->certReq);
|
||||
if ((ctx->certReq = OSSL_CMP_MSG_dup(cert_req)) == NULL)
|
||||
return NULL;
|
||||
return OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_waiting, 0, NULL);
|
||||
}
|
||||
if (ctx->certOut != NULL
|
||||
&& (*certOut = X509_dup(ctx->certOut)) == NULL)
|
||||
goto err;
|
||||
if (ctx->chainOut != NULL
|
||||
&& (*chainOut = X509_chain_up_ref(ctx->chainOut)) == NULL)
|
||||
goto err;
|
||||
if (ctx->caPubsOut != NULL
|
||||
&& (*caPubs = X509_chain_up_ref(ctx->caPubsOut)) == NULL)
|
||||
goto err;
|
||||
if (ctx->statusOut != NULL
|
||||
&& (si = OSSL_CMP_PKISI_dup(ctx->statusOut)) == NULL)
|
||||
goto err;
|
||||
return si;
|
||||
|
||||
err:
|
||||
X509_free(*certOut);
|
||||
*certOut = NULL;
|
||||
sk_X509_pop_free(*chainOut, X509_free);
|
||||
*chainOut = NULL;
|
||||
sk_X509_pop_free(*caPubs, X509_free);
|
||||
*caPubs = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *rr,
|
||||
const X509_NAME *issuer,
|
||||
const ASN1_INTEGER *serial)
|
||||
{
|
||||
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
|
||||
|
||||
if (ctx == NULL || rr == NULL || issuer == NULL || serial == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
if (ctx->sendError || ctx->certOut == NULL) {
|
||||
CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
CMPerr(0, CMP_R_REQUEST_NOT_ACCEPTED);
|
||||
return NULL;
|
||||
}
|
||||
return OSSL_CMP_PKISI_dup(ctx->statusOut);
|
||||
}
|
||||
|
||||
static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *genm,
|
||||
const STACK_OF(OSSL_CMP_ITAV) *in,
|
||||
STACK_OF(OSSL_CMP_ITAV) **out)
|
||||
{
|
||||
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
|
||||
|
||||
if (ctx == NULL || genm == NULL || in == NULL || out == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
if (ctx->sendError) {
|
||||
CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out = sk_OSSL_CMP_ITAV_deep_copy(in, OSSL_CMP_ITAV_dup,
|
||||
OSSL_CMP_ITAV_free);
|
||||
return *out != NULL;
|
||||
}
|
||||
|
||||
static void process_error(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *error,
|
||||
const OSSL_CMP_PKISI *statusInfo,
|
||||
const ASN1_INTEGER *errorCode,
|
||||
const OSSL_CMP_PKIFREETEXT *errorDetails)
|
||||
{
|
||||
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
|
||||
char buf[OSSL_CMP_PKISI_BUFLEN];
|
||||
char *sibuf;
|
||||
int i;
|
||||
|
||||
if (ctx == NULL || error == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
BIO_printf(bio_err, "mock server received error:\n");
|
||||
|
||||
if (statusInfo == NULL) {
|
||||
BIO_printf(bio_err, "pkiStatusInfo absent\n");
|
||||
} else {
|
||||
sibuf = OSSL_CMP_snprint_PKIStatusInfo(statusInfo, buf, sizeof(buf));
|
||||
BIO_printf(bio_err, "pkiStatusInfo: %s\n",
|
||||
sibuf != NULL ? sibuf: "<invalid>");
|
||||
}
|
||||
|
||||
if (errorCode == NULL)
|
||||
BIO_printf(bio_err, "errorCode absent\n");
|
||||
else
|
||||
BIO_printf(bio_err, "errorCode: %ld\n", ASN1_INTEGER_get(errorCode));
|
||||
|
||||
if (sk_ASN1_UTF8STRING_num(errorDetails) <= 0) {
|
||||
BIO_printf(bio_err, "errorDetails absent\n");
|
||||
} else {
|
||||
/* TODO could use sk_ASN1_UTF8STRING2text() if exported */
|
||||
BIO_printf(bio_err, "errorDetails: ");
|
||||
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, "\"");
|
||||
}
|
||||
BIO_printf(bio_err, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *certConf, int certReqId,
|
||||
const ASN1_OCTET_STRING *certHash,
|
||||
const OSSL_CMP_PKISI *si)
|
||||
{
|
||||
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
|
||||
ASN1_OCTET_STRING *digest;
|
||||
|
||||
if (ctx == NULL || certConf == NULL || certHash == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
if (ctx->sendError || ctx->certOut == NULL) {
|
||||
CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (certReqId != ctx->certReqId) {
|
||||
/* in case of error, invalid reqId -1 */
|
||||
CMPerr(0, CMP_R_BAD_REQUEST_ID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((digest = X509_digest_sig(ctx->certOut)) == NULL)
|
||||
return 0;
|
||||
if (ASN1_OCTET_STRING_cmp(certHash, digest) != 0) {
|
||||
ASN1_OCTET_STRING_free(digest);
|
||||
CMPerr(0, CMP_R_CERTHASH_UNMATCHED);
|
||||
return 0;
|
||||
}
|
||||
ASN1_OCTET_STRING_free(digest);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *pollReq, int certReqId,
|
||||
OSSL_CMP_MSG **certReq, int64_t *check_after)
|
||||
{
|
||||
mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
|
||||
|
||||
if (ctx == NULL || pollReq == NULL
|
||||
|| certReq == NULL || check_after == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
if (ctx->sendError || ctx->certReq == NULL) {
|
||||
*certReq = NULL;
|
||||
CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->pollCount == 0) {
|
||||
*certReq = ctx->certReq;
|
||||
ctx->certReq = NULL;
|
||||
*check_after = 0;
|
||||
} else {
|
||||
ctx->pollCount--;
|
||||
*certReq = NULL;
|
||||
*check_after = ctx->checkAfterTime;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(void)
|
||||
{
|
||||
OSSL_CMP_SRV_CTX *srv_ctx = OSSL_CMP_SRV_CTX_new();
|
||||
mock_srv_ctx *ctx = mock_srv_ctx_new();
|
||||
|
||||
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))
|
||||
return srv_ctx;
|
||||
|
||||
mock_srv_ctx_free(ctx);
|
||||
OSSL_CMP_SRV_CTX_free(srv_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx)
|
||||
{
|
||||
if (srv_ctx != NULL)
|
||||
mock_srv_ctx_free(OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx));
|
||||
OSSL_CMP_SRV_CTX_free(srv_ctx);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2018-2020 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
|
||||
* 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_CMP_MOCK_SRV_H
|
||||
# define OSSL_APPS_CMP_MOCK_SRV_H
|
||||
|
||||
# include <openssl/opensslconf.h>
|
||||
# ifndef OPENSSL_NO_CMP
|
||||
|
||||
# include <openssl/cmp.h>
|
||||
|
||||
OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(void);
|
||||
void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx);
|
||||
|
||||
int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
|
||||
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_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status,
|
||||
int fail_info, const char *text);
|
||||
int ossl_cmp_mock_srv_set_send_error(OSSL_CMP_SRV_CTX *srv_ctx, int val);
|
||||
int ossl_cmp_mock_srv_set_pollCount(OSSL_CMP_SRV_CTX *srv_ctx, int count);
|
||||
int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec);
|
||||
|
||||
# endif /* !defined(OPENSSL_NO_CMP) */
|
||||
#endif /* !defined(OSSL_APPS_CMP_MOCK_SRV_H) */
|
||||
@@ -1,10 +0,0 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR
|
||||
Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL
|
||||
/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC
|
||||
-----END DH PARAMETERS-----
|
||||
|
||||
These are the 1024-bit DH parameters from "Internet Key Exchange
|
||||
Protocol Version 2 (IKEv2)": https://tools.ietf.org/html/rfc5996
|
||||
|
||||
See https://tools.ietf.org/html/rfc2412 for how they were generated.
|
||||
@@ -1,14 +0,0 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIIBCAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb
|
||||
IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft
|
||||
awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT
|
||||
mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh
|
||||
fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq
|
||||
5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAg==
|
||||
-----END DH PARAMETERS-----
|
||||
|
||||
These are the 2048-bit DH parameters from "More Modular Exponential
|
||||
(MODP) Diffie-Hellman groups for Internet Key Exchange (IKE)":
|
||||
https://tools.ietf.org/html/rfc3526
|
||||
|
||||
See https://tools.ietf.org/html/rfc2412 for how they were generated.
|
||||
@@ -1,19 +0,0 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIICCAKCAgEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb
|
||||
IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft
|
||||
awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT
|
||||
mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh
|
||||
fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq
|
||||
5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM
|
||||
fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq
|
||||
ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI
|
||||
ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O
|
||||
+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI
|
||||
HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0BjGZ//////////8CAQI=
|
||||
-----END DH PARAMETERS-----
|
||||
|
||||
These are the 4096-bit DH parameters from "More Modular Exponential
|
||||
(MODP) Diffie-Hellman groups for Internet Key Exchange (IKE)":
|
||||
https://tools.ietf.org/html/rfc3526
|
||||
|
||||
See https://tools.ietf.org/html/rfc2412 for how they were generated.
|
||||
+25
-29
@@ -11,28 +11,25 @@
|
||||
#define OPENSSL_SUPPRESS_DEPRECATED
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_DH
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <time.h>
|
||||
# include <string.h>
|
||||
# include "apps.h"
|
||||
# include "progs.h"
|
||||
# include <openssl/bio.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/bn.h>
|
||||
# include <openssl/dh.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/pem.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
# ifndef OPENSSL_NO_DSA
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
# include <openssl/dsa.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
# define DEFBITS 2048
|
||||
#define DEFBITS 2048
|
||||
|
||||
static int dh_cb(int p, int n, BN_GENCB *cb);
|
||||
|
||||
@@ -50,13 +47,13 @@ const OPTIONS dhparam_options[] = {
|
||||
OPT_SECTION("General"),
|
||||
{"help", OPT_HELP, '-', "Display this summary"},
|
||||
{"check", OPT_CHECK, '-', "Check the DH parameters"},
|
||||
# ifndef OPENSSL_NO_DSA
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
{"dsaparam", OPT_DSAPARAM, '-',
|
||||
"Read or generate DSA parameters, convert to DH"},
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
|
||||
# endif
|
||||
#endif
|
||||
|
||||
OPT_SECTION("Input"),
|
||||
{"in", OPT_IN, '<', "Input file"},
|
||||
@@ -167,13 +164,13 @@ int dhparam_main(int argc, char **argv)
|
||||
if (g && !num)
|
||||
num = DEFBITS;
|
||||
|
||||
# ifndef OPENSSL_NO_DSA
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
if (dsaparam && g) {
|
||||
BIO_printf(bio_err,
|
||||
"generator may not be chosen for DSA parameters\n");
|
||||
goto end;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
out = bio_open_default(outfile, 'w', outformat);
|
||||
if (out == NULL)
|
||||
@@ -194,7 +191,7 @@ int dhparam_main(int argc, char **argv)
|
||||
|
||||
BN_GENCB_set(cb, dh_cb, bio_err);
|
||||
|
||||
# ifndef OPENSSL_NO_DSA
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
if (dsaparam) {
|
||||
DSA *dsa = DSA_new();
|
||||
|
||||
@@ -217,7 +214,7 @@ int dhparam_main(int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
} else
|
||||
# endif
|
||||
#endif
|
||||
{
|
||||
dh = DH_new();
|
||||
BIO_printf(bio_err,
|
||||
@@ -238,7 +235,7 @@ int dhparam_main(int argc, char **argv)
|
||||
if (in == NULL)
|
||||
goto end;
|
||||
|
||||
# ifndef OPENSSL_NO_DSA
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
if (dsaparam) {
|
||||
DSA *dsa;
|
||||
|
||||
@@ -260,7 +257,7 @@ int dhparam_main(int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
} else
|
||||
# endif
|
||||
#endif
|
||||
{
|
||||
if (informat == FORMAT_ASN1) {
|
||||
/*
|
||||
@@ -397,4 +394,3 @@ static int dh_cb(int p, int n, BN_GENCB *cb)
|
||||
(void)BIO_flush(BN_GENCB_get_arg(cb));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
+21
-25
@@ -11,23 +11,20 @@
|
||||
#define OPENSSL_SUPPRESS_DEPRECATED
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_DSA
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <time.h>
|
||||
# include "apps.h"
|
||||
# include "progs.h"
|
||||
# include <openssl/bio.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/dsa.h>
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/pem.h>
|
||||
# include <openssl/bn.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
@@ -43,14 +40,14 @@ const OPTIONS dsa_options[] = {
|
||||
OPT_SECTION("General"),
|
||||
{"help", OPT_HELP, '-', "Display this summary"},
|
||||
{"", OPT_CIPHER, '-', "Any supported cipher"},
|
||||
# ifndef OPENSSL_NO_RC4
|
||||
#ifndef OPENSSL_NO_RC4
|
||||
{"pvk-strong", OPT_PVK_STRONG, '-', "Enable 'Strong' PVK encoding level (default)"},
|
||||
{"pvk-weak", OPT_PVK_WEAK, '-', "Enable 'Weak' PVK encoding level"},
|
||||
{"pvk-none", OPT_PVK_NONE, '-', "Don't enforce PVK encoding"},
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
|
||||
# endif
|
||||
#endif
|
||||
|
||||
OPT_SECTION("Input"),
|
||||
{"in", OPT_IN, 's', "Input key"},
|
||||
@@ -82,9 +79,9 @@ int dsa_main(int argc, char **argv)
|
||||
OPTION_CHOICE o;
|
||||
int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, noout = 0;
|
||||
int i, modulus = 0, pubin = 0, pubout = 0, ret = 1;
|
||||
# ifndef OPENSSL_NO_RC4
|
||||
#ifndef OPENSSL_NO_RC4
|
||||
int pvk_encr = 2;
|
||||
# endif
|
||||
#endif
|
||||
int private = 0;
|
||||
|
||||
prog = opt_init(argc, argv, dsa_options);
|
||||
@@ -230,7 +227,7 @@ int dsa_main(int argc, char **argv)
|
||||
i = PEM_write_bio_DSAPrivateKey(out, dsa, enc,
|
||||
NULL, 0, NULL, passout);
|
||||
}
|
||||
# ifndef OPENSSL_NO_RSA
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
} else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {
|
||||
EVP_PKEY *pk;
|
||||
pk = EVP_PKEY_new();
|
||||
@@ -259,7 +256,7 @@ int dsa_main(int argc, char **argv)
|
||||
i = i2b_PrivateKey_bio(out, pk);
|
||||
}
|
||||
EVP_PKEY_free(pk);
|
||||
# endif
|
||||
#endif
|
||||
} else {
|
||||
BIO_printf(bio_err, "bad output format specified for outfile\n");
|
||||
goto end;
|
||||
@@ -278,4 +275,3 @@ int dsa_main(int argc, char **argv)
|
||||
OPENSSL_free(passout);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
+14
-18
@@ -11,22 +11,19 @@
|
||||
#define OPENSSL_SUPPRESS_DEPRECATED
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_DSA
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <time.h>
|
||||
# include <string.h>
|
||||
# include "apps.h"
|
||||
# include "progs.h"
|
||||
# include <openssl/bio.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/bn.h>
|
||||
# include <openssl/dsa.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/pem.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
static int verbose = 0;
|
||||
|
||||
@@ -44,9 +41,9 @@ const OPTIONS dsaparam_options[] = {
|
||||
|
||||
OPT_SECTION("General"),
|
||||
{"help", OPT_HELP, '-', "Display this summary"},
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
|
||||
# endif
|
||||
#endif
|
||||
|
||||
OPT_SECTION("Input"),
|
||||
{"in", OPT_IN, '<', "Input file"},
|
||||
@@ -286,4 +283,3 @@ static int dsa_cb(int p, int n, BN_GENCB *cb)
|
||||
(void)BIO_flush(BN_GENCB_get_arg(cb));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
@@ -8,19 +8,16 @@
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_EC
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include "apps.h"
|
||||
# include "progs.h"
|
||||
# include <openssl/bio.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/pem.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
static OPT_PAIR conv_forms[] = {
|
||||
{"compressed", POINT_CONVERSION_COMPRESSED},
|
||||
@@ -46,9 +43,9 @@ typedef enum OPTION_choice {
|
||||
const OPTIONS ec_options[] = {
|
||||
OPT_SECTION("General"),
|
||||
{"help", OPT_HELP, '-', "Display this summary"},
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
||||
# endif
|
||||
#endif
|
||||
|
||||
OPT_SECTION("Input"),
|
||||
{"in", OPT_IN, 's', "Input file"},
|
||||
@@ -291,4 +288,3 @@ int ec_main(int argc, char **argv)
|
||||
OPENSSL_free(passout);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
+14
-19
@@ -9,22 +9,19 @@
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_EC
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <time.h>
|
||||
# include <string.h>
|
||||
# include "apps.h"
|
||||
# include "progs.h"
|
||||
# include <openssl/bio.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/bn.h>
|
||||
# include <openssl/ec.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/pem.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
@@ -39,9 +36,9 @@ const OPTIONS ecparam_options[] = {
|
||||
{"help", OPT_HELP, '-', "Display this summary"},
|
||||
{"list_curves", OPT_LIST_CURVES, '-',
|
||||
"Prints a list of all curve 'short names'"},
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
||||
# endif
|
||||
#endif
|
||||
|
||||
{"genkey", OPT_GENKEY, '-', "Generate ec key"},
|
||||
{"in", OPT_IN, '<', "Input file - default stdin"},
|
||||
@@ -473,5 +470,3 @@ int ecparam_main(int argc, char **argv)
|
||||
BIO_free_all(out);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
+9
-13
@@ -8,19 +8,16 @@
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_ENGINE
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
# include "apps.h"
|
||||
# include "progs.h"
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/engine.h>
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/store.h>
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/store.h>
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
@@ -491,4 +488,3 @@ int engine_main(int argc, char **argv)
|
||||
BIO_free_all(out);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
+14
-18
@@ -11,22 +11,19 @@
|
||||
#define OPENSSL_SUPPRESS_DEPRECATED
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_DSA
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# include "apps.h"
|
||||
# include "progs.h"
|
||||
# include <openssl/bio.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/bn.h>
|
||||
# include <openssl/dsa.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/pem.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
@@ -39,9 +36,9 @@ const OPTIONS gendsa_options[] = {
|
||||
|
||||
OPT_SECTION("General"),
|
||||
{"help", OPT_HELP, '-', "Display this summary"},
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
||||
# endif
|
||||
#endif
|
||||
|
||||
OPT_SECTION("Output"),
|
||||
{"out", OPT_OUT, '>', "Output the key to the specified file"},
|
||||
@@ -162,4 +159,3 @@ int gendsa_main(int argc, char **argv)
|
||||
OPENSSL_free(passout);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
+18
-22
@@ -8,27 +8,24 @@
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_RSA
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# include "apps.h"
|
||||
# include "progs.h"
|
||||
# include <openssl/bio.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/bn.h>
|
||||
# include <openssl/rsa.h>
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/pem.h>
|
||||
# include <openssl/rand.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
# define DEFBITS 2048
|
||||
# define DEFPRIMES 2
|
||||
#define DEFBITS 2048
|
||||
#define DEFPRIMES 2
|
||||
|
||||
static int verbose = 0;
|
||||
|
||||
@@ -46,9 +43,9 @@ const OPTIONS genrsa_options[] = {
|
||||
|
||||
OPT_SECTION("General"),
|
||||
{"help", OPT_HELP, '-', "Display this summary"},
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
||||
# endif
|
||||
#endif
|
||||
|
||||
OPT_SECTION("Input"),
|
||||
{"3", OPT_3, '-', "Use 3 for the E value"},
|
||||
@@ -224,4 +221,3 @@ static int genrsa_cb(int p, int n, BN_GENCB *cb)
|
||||
(void)BIO_flush(BN_GENCB_get_arg(cb));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
+9
-3
@@ -91,7 +91,7 @@ int wrap_password_callback(char *buf, int bufsiz, int verify, void *cb_data);
|
||||
|
||||
int chopup_args(ARGS *arg, char *buf);
|
||||
int dump_cert_text(BIO *out, X509 *x);
|
||||
void print_name(BIO *out, const char *title, X509_NAME *nm,
|
||||
void print_name(BIO *out, const char *title, const X509_NAME *nm,
|
||||
unsigned long lflags);
|
||||
void print_bignum_var(BIO *, const BIGNUM *, const char*,
|
||||
int, unsigned char *);
|
||||
@@ -197,12 +197,17 @@ X509_NAME *parse_name(const char *str, long chtype, int multirdn);
|
||||
void policies_print(X509_STORE_CTX *ctx);
|
||||
int bio_to_mem(unsigned char **out, int maxlen, BIO *in);
|
||||
int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value);
|
||||
int x509_ctrl_string(X509 *x, const char *value);
|
||||
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);
|
||||
int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
|
||||
STACK_OF(OPENSSL_STRING) *sigopts);
|
||||
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 EVP_MD *md,
|
||||
STACK_OF(OPENSSL_STRING) *sigopts);
|
||||
int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey,
|
||||
STACK_OF(OPENSSL_STRING) *vfyopts);
|
||||
int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
|
||||
STACK_OF(OPENSSL_STRING) *sigopts);
|
||||
|
||||
@@ -228,13 +233,13 @@ BIO *app_http_tls_cb(BIO *hbio, /* APP_HTTP_TLS_INFO */ void *arg,
|
||||
int connect, int detail);
|
||||
# ifndef OPENSSL_NO_SOCK
|
||||
ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy,
|
||||
const char *proxy_port, SSL_CTX *ssl_ctx,
|
||||
const char *no_proxy, SSL_CTX *ssl_ctx,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
long timeout, const char *expected_content_type,
|
||||
const ASN1_ITEM *it);
|
||||
ASN1_VALUE *app_http_post_asn1(const char *host, const char *port,
|
||||
const char *path, const char *proxy,
|
||||
const char *proxy_port, SSL_CTX *ctx,
|
||||
const char *no_proxy, SSL_CTX *ctx,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
const char *content_type,
|
||||
ASN1_VALUE *req, const ASN1_ITEM *req_it,
|
||||
@@ -281,5 +286,6 @@ extern VERIFY_CB_ARGS verify_args;
|
||||
OSSL_PARAM *app_params_new_from_opts(STACK_OF(OPENSSL_STRING) *opts,
|
||||
const OSSL_PARAM *paramdefs);
|
||||
void app_params_free(OSSL_PARAM *params);
|
||||
void app_providers_cleanup(void);
|
||||
|
||||
#endif
|
||||
+2
-2
@@ -275,8 +275,8 @@
|
||||
|
||||
# define OPT_PROV_OPTIONS \
|
||||
OPT_SECTION("Provider"), \
|
||||
{ "provider", OPT_PROV_PROVIDER, 's', "Provder to load (can be specified multiple times)" }, \
|
||||
{ "provider_path", OPT_PROV_PROVIDER_PATH, 's', "Provider load path" }
|
||||
{ "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)" }
|
||||
|
||||
# define OPT_PROV_CASES \
|
||||
OPT_PROV__FIRST: case OPT_PROV__LAST: break; \
|
||||
|
||||
@@ -10,12 +10,17 @@
|
||||
#include "apps.h"
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/provider.h>
|
||||
#include <openssl/safestack.h>
|
||||
|
||||
DEFINE_STACK_OF(OSSL_PROVIDER)
|
||||
|
||||
/*
|
||||
* See comments in opt_verify for explanation of this.
|
||||
*/
|
||||
enum prov_range { OPT_PROV_ENUM };
|
||||
|
||||
static STACK_OF(OSSL_PROVIDER) *app_providers = NULL;
|
||||
|
||||
static int opt_provider_load(const char *provider)
|
||||
{
|
||||
OSSL_PROVIDER *prov;
|
||||
@@ -26,9 +31,27 @@ static int opt_provider_load(const char *provider)
|
||||
opt_getprog(), provider);
|
||||
return 0;
|
||||
}
|
||||
if (app_providers == NULL)
|
||||
app_providers = sk_OSSL_PROVIDER_new_null();
|
||||
if (app_providers == NULL
|
||||
|| !sk_OSSL_PROVIDER_push(app_providers, prov)) {
|
||||
app_providers_cleanup();
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void provider_free(OSSL_PROVIDER *prov)
|
||||
{
|
||||
OSSL_PROVIDER_unload(prov);
|
||||
}
|
||||
|
||||
void app_providers_cleanup(void)
|
||||
{
|
||||
sk_OSSL_PROVIDER_pop_free(app_providers, provider_free);
|
||||
app_providers = NULL;
|
||||
}
|
||||
|
||||
static int opt_provider_path(const char *path)
|
||||
{
|
||||
if (path != NULL && *path == '\0')
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2020 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 <string.h>
|
||||
#include "apps.h"
|
||||
|
||||
/*
|
||||
* X509_ctrl_str() is sorely lacking in libcrypto, but is still needed to
|
||||
* allow the application to process verification options in a manner similar
|
||||
* to signature or other options that pass through EVP_PKEY_CTX_ctrl_str(),
|
||||
* for uniformity.
|
||||
*
|
||||
* As soon as more stuff is added, the code will need serious rework. For
|
||||
* the moment, it only handles the FIPS 196 / SM2 distinguishing ID.
|
||||
*/
|
||||
#ifdef EVP_PKEY_CTRL_SET1_ID
|
||||
static ASN1_OCTET_STRING *mk_octet_string(void *value, size_t value_n)
|
||||
{
|
||||
ASN1_OCTET_STRING *v = ASN1_OCTET_STRING_new();
|
||||
|
||||
if (v == NULL) {
|
||||
BIO_printf(bio_err, "error: allocation failed\n");
|
||||
} else if (!ASN1_OCTET_STRING_set(v, value, value_n)) {
|
||||
ASN1_OCTET_STRING_free(v);
|
||||
v = NULL;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int x509_ctrl(void *object, int cmd, void *value, size_t value_n)
|
||||
{
|
||||
switch (cmd) {
|
||||
#ifdef EVP_PKEY_CTRL_SET1_ID
|
||||
case EVP_PKEY_CTRL_SET1_ID:
|
||||
{
|
||||
ASN1_OCTET_STRING *v = mk_octet_string(value, value_n);
|
||||
|
||||
if (v == NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"error: setting distinguishing ID in certificate failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
X509_set0_distinguishing_id(object, v);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -2; /* typical EVP_PKEY return for "unsupported" */
|
||||
}
|
||||
|
||||
static int x509_req_ctrl(void *object, int cmd, void *value, size_t value_n)
|
||||
{
|
||||
switch (cmd) {
|
||||
#ifdef EVP_PKEY_CTRL_SET1_ID
|
||||
case EVP_PKEY_CTRL_SET1_ID:
|
||||
{
|
||||
ASN1_OCTET_STRING *v = mk_octet_string(value, value_n);
|
||||
|
||||
if (v == NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"error: setting distinguishing ID in certificate signing request failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
X509_REQ_set0_distinguishing_id(object, v);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -2; /* typical EVP_PKEY return for "unsupported" */
|
||||
}
|
||||
|
||||
static int do_x509_ctrl_string(int (*ctrl)(void *object, int cmd,
|
||||
void *value, size_t value_n),
|
||||
void *object, const char *value)
|
||||
{
|
||||
int rv = 0;
|
||||
char *stmp, *vtmp = NULL;
|
||||
size_t vtmp_len = 0;
|
||||
int cmd = 0; /* Will get command values that make sense somehow */
|
||||
|
||||
stmp = OPENSSL_strdup(value);
|
||||
if (stmp == NULL)
|
||||
return -1;
|
||||
vtmp = strchr(stmp, ':');
|
||||
if (vtmp != NULL) {
|
||||
*vtmp = 0;
|
||||
vtmp++;
|
||||
vtmp_len = strlen(vtmp);
|
||||
}
|
||||
|
||||
if (strcmp(stmp, "distid") == 0) {
|
||||
#ifdef EVP_PKEY_CTRL_SET1_ID
|
||||
cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */
|
||||
#endif
|
||||
} else if (strcmp(stmp, "hexdistid") == 0) {
|
||||
long hexid_len = 0;
|
||||
void *hexid = OPENSSL_hexstr2buf((const char *)vtmp, &hexid_len);
|
||||
|
||||
OPENSSL_free(stmp);
|
||||
stmp = vtmp = hexid;
|
||||
vtmp_len = (size_t)hexid_len;
|
||||
#ifdef EVP_PKEY_CTRL_SET1_ID
|
||||
cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */
|
||||
#endif
|
||||
}
|
||||
|
||||
rv = ctrl(object, cmd, vtmp, vtmp_len);
|
||||
|
||||
OPENSSL_free(stmp);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int x509_ctrl_string(X509 *x, const char *value)
|
||||
{
|
||||
return do_x509_ctrl_string(x509_ctrl, x, value);
|
||||
}
|
||||
|
||||
int x509_req_ctrl_string(X509_REQ *x, const char *value)
|
||||
{
|
||||
return do_x509_ctrl_string(x509_req_ctrl, x, value);
|
||||
}
|
||||
+8
-7
@@ -968,7 +968,7 @@ static int set_table_opts(unsigned long *flags, const char *arg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_name(BIO *out, const char *title, X509_NAME *nm,
|
||||
void print_name(BIO *out, const char *title, const X509_NAME *nm,
|
||||
unsigned long lflags)
|
||||
{
|
||||
char *buf;
|
||||
@@ -1900,7 +1900,8 @@ static X509_CRL *load_crl_crldp(STACK_OF(DIST_POINT) *crldp)
|
||||
* anything.
|
||||
*/
|
||||
|
||||
static STACK_OF(X509_CRL) *crls_http_cb(X509_STORE_CTX *ctx, X509_NAME *nm)
|
||||
static STACK_OF(X509_CRL) *crls_http_cb(const X509_STORE_CTX *ctx,
|
||||
const X509_NAME *nm)
|
||||
{
|
||||
X509 *x;
|
||||
STACK_OF(X509_CRL) *crls = NULL;
|
||||
@@ -1989,7 +1990,7 @@ BIO *app_http_tls_cb(BIO *hbio, void *arg, int connect, int detail)
|
||||
} else if (!connect && !detail) { /* disconnecting after error */
|
||||
const char *hint = tls_error_hint();
|
||||
if (hint != NULL)
|
||||
ERR_add_error_data(1, hint);
|
||||
ERR_add_error_data(2, " : ", hint);
|
||||
/*
|
||||
* If we pop sbio and BIO_free() it this may lead to libssl double free.
|
||||
* Rely on BIO_free_all() done by OSSL_HTTP_transfer() in http_client.c
|
||||
@@ -1999,7 +2000,7 @@ BIO *app_http_tls_cb(BIO *hbio, void *arg, int connect, int detail)
|
||||
}
|
||||
|
||||
ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy,
|
||||
const char *proxy_port, SSL_CTX *ssl_ctx,
|
||||
const char *no_proxy, SSL_CTX *ssl_ctx,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
long timeout, const char *expected_content_type,
|
||||
const ASN1_ITEM *it)
|
||||
@@ -2028,7 +2029,7 @@ ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy,
|
||||
info.use_proxy = proxy != NULL;
|
||||
info.timeout = timeout;
|
||||
info.ssl_ctx = ssl_ctx;
|
||||
resp = OSSL_HTTP_get_asn1(url, proxy, proxy_port,
|
||||
resp = OSSL_HTTP_get_asn1(url, proxy, no_proxy,
|
||||
NULL, NULL, app_http_tls_cb, &info,
|
||||
headers, 0 /* maxline */, 0 /* max_resp_len */,
|
||||
timeout, expected_content_type, it);
|
||||
@@ -2041,7 +2042,7 @@ ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy,
|
||||
|
||||
ASN1_VALUE *app_http_post_asn1(const char *host, const char *port,
|
||||
const char *path, const char *proxy,
|
||||
const char *proxy_port, SSL_CTX *ssl_ctx,
|
||||
const char *no_proxy, SSL_CTX *ssl_ctx,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
const char *content_type,
|
||||
ASN1_VALUE *req, const ASN1_ITEM *req_it,
|
||||
@@ -2055,7 +2056,7 @@ ASN1_VALUE *app_http_post_asn1(const char *host, const char *port,
|
||||
info.timeout = timeout;
|
||||
info.ssl_ctx = ssl_ctx;
|
||||
return OSSL_HTTP_post_asn1(host, port, path, ssl_ctx != NULL,
|
||||
proxy, proxy_port,
|
||||
proxy, no_proxy,
|
||||
NULL, NULL, app_http_tls_cb, &info,
|
||||
headers, content_type, req, req_it,
|
||||
0 /* maxline */,
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ ENDIF
|
||||
|
||||
# Source for libapps
|
||||
$LIBAPPSSRC=apps.c apps_ui.c opt.c fmt.c s_cb.c s_socket.c app_rand.c \
|
||||
columns.c app_params.c names.c app_provider.c
|
||||
columns.c app_params.c names.c app_provider.c app_x509.c
|
||||
|
||||
IF[{- !$disabled{apps} -}]
|
||||
LIBS{noinst}=../libapps.a
|
||||
|
||||
+54
-59
@@ -9,32 +9,29 @@
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#ifdef OPENSSL_NO_OCSP
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
# ifdef OPENSSL_SYS_VMS
|
||||
# define _XOPEN_SOURCE_EXTENDED/* So fd_set and friends get properly defined
|
||||
* on OpenVMS */
|
||||
# endif
|
||||
#ifdef OPENSSL_SYS_VMS
|
||||
/* So fd_set and friends get properly defined on OpenVMS */
|
||||
# define _XOPEN_SOURCE_EXTENDED
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <time.h>
|
||||
# include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* Needs to be included before the openssl headers */
|
||||
# include "apps.h"
|
||||
# include "progs.h"
|
||||
# include "internal/sockets.h"
|
||||
# include <openssl/e_os2.h>
|
||||
# include <openssl/crypto.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/bn.h>
|
||||
# include <openssl/x509v3.h>
|
||||
# include <openssl/rand.h>
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
#include "internal/sockets.h"
|
||||
#include <openssl/e_os2.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#ifndef HAVE_FORK
|
||||
# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS)
|
||||
@@ -50,7 +47,7 @@ NON_EMPTY_TRANSLATION_UNIT
|
||||
# define NO_FORK
|
||||
#endif
|
||||
|
||||
# if !defined(NO_FORK) && !defined(OPENSSL_NO_SOCK) \
|
||||
#if !defined(NO_FORK) && !defined(OPENSSL_NO_SOCK) \
|
||||
&& !defined(OPENSSL_NO_POSIX_IO)
|
||||
# define OCSP_DAEMON
|
||||
# include <sys/types.h>
|
||||
@@ -58,16 +55,16 @@ NON_EMPTY_TRANSLATION_UNIT
|
||||
# include <syslog.h>
|
||||
# include <signal.h>
|
||||
# define MAXERRLEN 1000 /* limit error text sent to syslog to 1000 bytes */
|
||||
# else
|
||||
#else
|
||||
# undef LOG_INFO
|
||||
# undef LOG_WARNING
|
||||
# undef LOG_ERR
|
||||
# define LOG_INFO 0
|
||||
# define LOG_WARNING 1
|
||||
# define LOG_ERR 2
|
||||
# endif
|
||||
#endif
|
||||
|
||||
# if defined(OPENSSL_SYS_VXWORKS)
|
||||
#if defined(OPENSSL_SYS_VXWORKS)
|
||||
/* not supported */
|
||||
int setpgid(pid_t pid, pid_t pgid)
|
||||
{
|
||||
@@ -80,9 +77,9 @@ pid_t fork(void)
|
||||
errno = ENOSYS;
|
||||
return (pid_t) -1;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
/* Maximum leeway in validity period: default 5 minutes */
|
||||
# define MAX_VALIDITY_PERIOD (5 * 60)
|
||||
#define MAX_VALIDITY_PERIOD (5 * 60)
|
||||
|
||||
static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert,
|
||||
const EVP_MD *cert_id_md, X509 *issuer,
|
||||
@@ -110,13 +107,13 @@ static void log_message(int level, const char *fmt, ...);
|
||||
static char *prog;
|
||||
static int multi = 0;
|
||||
|
||||
# ifdef OCSP_DAEMON
|
||||
#ifdef OCSP_DAEMON
|
||||
static int acfd = (int) INVALID_SOCKET;
|
||||
static int index_changed(CA_DB *);
|
||||
static void spawn_loop(void);
|
||||
static int print_syslog(const char *str, size_t len, void *levPtr);
|
||||
static void socket_timeout(int signum);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
@@ -160,9 +157,9 @@ const OPTIONS ocsp_options[] = {
|
||||
"Connection timeout (in seconds) to the OCSP responder"},
|
||||
{"resp_no_certs", OPT_RESP_NO_CERTS, '-',
|
||||
"Don't include any certificates in response"},
|
||||
# ifdef OCSP_DAEMON
|
||||
#ifdef OCSP_DAEMON
|
||||
{"multi", OPT_MULTI, 'p', "run multiple responder processes"},
|
||||
# endif
|
||||
#endif
|
||||
{"no_certs", OPT_NO_CERTS, '-',
|
||||
"Don't include any certificates in signed request"},
|
||||
{"badsig", OPT_BADSIG, '-',
|
||||
@@ -538,9 +535,9 @@ int ocsp_main(int argc, char **argv)
|
||||
trailing_md = 1;
|
||||
break;
|
||||
case OPT_MULTI:
|
||||
# ifdef OCSP_DAEMON
|
||||
#ifdef OCSP_DAEMON
|
||||
multi = atoi(opt_arg());
|
||||
# endif
|
||||
#endif
|
||||
break;
|
||||
case OPT_PROV_CASES:
|
||||
if (!opt_provider(o))
|
||||
@@ -628,7 +625,7 @@ int ocsp_main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
# ifdef OCSP_DAEMON
|
||||
#ifdef OCSP_DAEMON
|
||||
if (multi && acbio != NULL)
|
||||
spawn_loop();
|
||||
if (acbio != NULL && req_timeout > 0)
|
||||
@@ -641,7 +638,7 @@ int ocsp_main(int argc, char **argv)
|
||||
redo_accept:
|
||||
|
||||
if (acbio != NULL) {
|
||||
# ifdef OCSP_DAEMON
|
||||
#ifdef OCSP_DAEMON
|
||||
if (index_changed(rdb)) {
|
||||
CA_DB *newrdb = load_index(ridx_filename, NULL);
|
||||
|
||||
@@ -654,7 +651,7 @@ redo_accept:
|
||||
ridx_filename);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
req = NULL;
|
||||
if (!do_responder(&req, &cbio, acbio, req_timeout))
|
||||
@@ -724,16 +721,16 @@ redo_accept:
|
||||
if (cbio != NULL)
|
||||
send_ocsp_response(cbio, resp);
|
||||
} else if (host != NULL) {
|
||||
# ifndef OPENSSL_NO_SOCK
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
resp = process_responder(req, host, path,
|
||||
port, use_ssl, headers, req_timeout);
|
||||
if (resp == NULL)
|
||||
goto end;
|
||||
# else
|
||||
#else
|
||||
BIO_printf(bio_err,
|
||||
"Error creating connect BIO - sockets not supported.\n");
|
||||
goto end;
|
||||
# endif
|
||||
#endif
|
||||
} else if (respin != NULL) {
|
||||
derbio = bio_open_default(respin, 'r', FORMAT_ASN1);
|
||||
if (derbio == NULL)
|
||||
@@ -877,7 +874,7 @@ log_message(int level, const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
# ifdef OCSP_DAEMON
|
||||
#ifdef OCSP_DAEMON
|
||||
if (multi) {
|
||||
char buf[1024];
|
||||
if (vsnprintf(buf, sizeof(buf), fmt, ap) > 0) {
|
||||
@@ -886,7 +883,7 @@ log_message(int level, const char *fmt, ...)
|
||||
if (level >= LOG_ERR)
|
||||
ERR_print_errors_cb(print_syslog, &level);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
if (!multi) {
|
||||
BIO_printf(bio_err, "%s: ", prog);
|
||||
BIO_vprintf(bio_err, fmt, ap);
|
||||
@@ -895,7 +892,7 @@ log_message(int level, const char *fmt, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
# ifdef OCSP_DAEMON
|
||||
#ifdef OCSP_DAEMON
|
||||
|
||||
static int print_syslog(const char *str, size_t len, void *levPtr)
|
||||
{
|
||||
@@ -1048,7 +1045,7 @@ static void spawn_loop(void)
|
||||
syslog(LOG_INFO, "terminating on signal: %d", termsig);
|
||||
killall(0, kidpids);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert,
|
||||
const EVP_MD *cert_id_md, X509 *issuer,
|
||||
@@ -1081,7 +1078,7 @@ static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,
|
||||
STACK_OF(OCSP_CERTID) *ids)
|
||||
{
|
||||
OCSP_CERTID *id;
|
||||
X509_NAME *iname;
|
||||
const X509_NAME *iname;
|
||||
ASN1_BIT_STRING *ikey;
|
||||
ASN1_INTEGER *sno;
|
||||
|
||||
@@ -1338,11 +1335,11 @@ static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser)
|
||||
|
||||
static BIO *init_responder(const char *port)
|
||||
{
|
||||
# ifdef OPENSSL_NO_SOCK
|
||||
#ifdef OPENSSL_NO_SOCK
|
||||
BIO_printf(bio_err,
|
||||
"Error setting up accept BIO - sockets not supported.\n");
|
||||
return NULL;
|
||||
# else
|
||||
#else
|
||||
BIO *acbio = NULL, *bufbio = NULL;
|
||||
|
||||
bufbio = BIO_new(BIO_f_buffer());
|
||||
@@ -1369,10 +1366,10 @@ static BIO *init_responder(const char *port)
|
||||
BIO_free_all(acbio);
|
||||
BIO_free(bufbio);
|
||||
return NULL;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
# ifndef OPENSSL_NO_SOCK
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
/*
|
||||
* Decode %xx URL-decoding in-place. Ignores mal-formed sequences.
|
||||
*/
|
||||
@@ -1396,22 +1393,22 @@ static int urldecode(char *p)
|
||||
*out = '\0';
|
||||
return (int)(out - save);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
# ifdef OCSP_DAEMON
|
||||
#ifdef OCSP_DAEMON
|
||||
static void socket_timeout(int signum)
|
||||
{
|
||||
if (acfd != (int)INVALID_SOCKET)
|
||||
(void)shutdown(acfd, SHUT_RD);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio,
|
||||
int timeout)
|
||||
{
|
||||
# ifdef OPENSSL_NO_SOCK
|
||||
#ifdef OPENSSL_NO_SOCK
|
||||
return 0;
|
||||
# else
|
||||
#else
|
||||
int len;
|
||||
OCSP_REQUEST *req = NULL;
|
||||
char inbuf[2048], reqbuf[2048];
|
||||
@@ -1523,7 +1520,7 @@ out:
|
||||
acfd = (int)INVALID_SOCKET;
|
||||
# endif
|
||||
return 1;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
|
||||
@@ -1539,7 +1536,7 @@ static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
# ifndef OPENSSL_NO_SOCK
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
OCSP_RESPONSE *process_responder(OCSP_REQUEST *req,
|
||||
const char *host, const char *path,
|
||||
const char *port, int use_ssl,
|
||||
@@ -1571,6 +1568,4 @@ OCSP_RESPONSE *process_responder(OCSP_REQUEST *req,
|
||||
SSL_CTX_free(ctx);
|
||||
return resp;
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
@@ -368,6 +368,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
ret = 1;
|
||||
end:
|
||||
app_providers_cleanup();
|
||||
OPENSSL_free(default_config_file);
|
||||
lh_FUNCTION_free(prog);
|
||||
OPENSSL_free(arg.argv);
|
||||
|
||||
+22
-27
@@ -8,25 +8,22 @@
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#if defined(OPENSSL_NO_DES)
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include "apps.h"
|
||||
# include "progs.h"
|
||||
# include <openssl/crypto.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/pem.h>
|
||||
# include <openssl/pkcs12.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
|
||||
# define NOKEYS 0x1
|
||||
# define NOCERTS 0x2
|
||||
# define INFO 0x4
|
||||
# define CLCERTS 0x8
|
||||
# define CACERTS 0x10
|
||||
#define NOKEYS 0x1
|
||||
#define NOCERTS 0x2
|
||||
#define INFO 0x4
|
||||
#define CLCERTS 0x8
|
||||
#define CACERTS 0x10
|
||||
|
||||
#define PASSWD_BUF_SIZE 2048
|
||||
|
||||
@@ -64,9 +61,9 @@ typedef enum OPTION_choice {
|
||||
const OPTIONS pkcs12_options[] = {
|
||||
OPT_SECTION("General"),
|
||||
{"help", OPT_HELP, '-', "Display this summary"},
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
||||
# endif
|
||||
#endif
|
||||
|
||||
OPT_SECTION("CA"),
|
||||
{"CApath", OPT_CAPATH, '/', "PEM-format directory of CA's"},
|
||||
@@ -112,15 +109,15 @@ const OPTIONS pkcs12_options[] = {
|
||||
{"keysig", OPT_KEYSIG, '-', "Set MS key signature type"},
|
||||
|
||||
OPT_SECTION("Encryption"),
|
||||
# ifndef OPENSSL_NO_RC2
|
||||
#ifndef OPENSSL_NO_RC2
|
||||
{"descert", OPT_DESCERT, '-',
|
||||
"Encrypt output with 3DES (default RC2-40)"},
|
||||
{"certpbe", OPT_CERTPBE, 's',
|
||||
"Certificate PBE algorithm (default RC2-40)"},
|
||||
# else
|
||||
#else
|
||||
{"descert", OPT_DESCERT, '-', "Encrypt output with 3DES (the default)"},
|
||||
{"certpbe", OPT_CERTPBE, 's', "Certificate PBE algorithm (default 3DES)"},
|
||||
# endif
|
||||
#endif
|
||||
{"iter", OPT_ITER, 'p', "Specify the iteration count for encryption key and MAC"},
|
||||
{"noiter", OPT_NOITER, '-', "Don't use encryption key iteration"},
|
||||
{"maciter", OPT_MACITER, '-', "Unused, kept for backwards compatibility"},
|
||||
@@ -141,11 +138,11 @@ int pkcs12_main(int argc, char **argv)
|
||||
char pass[PASSWD_BUF_SIZE] = "", macpass[PASSWD_BUF_SIZE] = "";
|
||||
int export_cert = 0, options = 0, chain = 0, twopass = 0, keytype = 0;
|
||||
int iter = PKCS12_DEFAULT_ITER, maciter = PKCS12_DEFAULT_ITER;
|
||||
# ifndef OPENSSL_NO_RC2
|
||||
#ifndef OPENSSL_NO_RC2
|
||||
int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
|
||||
# else
|
||||
#else
|
||||
int cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
|
||||
# endif
|
||||
#endif
|
||||
int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
|
||||
int ret = 1, macver = 1, add_lmk = 0, private = 0;
|
||||
int noprompt = 0;
|
||||
@@ -1008,5 +1005,3 @@ static int set_pbe(int *ppbe, const char *str)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -550,22 +550,6 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
|
||||
if (pkey == NULL)
|
||||
goto end;
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
/* SM2 needs a special treatment */
|
||||
if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
|
||||
EC_KEY *eckey = NULL;
|
||||
const EC_GROUP *group = NULL;
|
||||
int nid;
|
||||
|
||||
if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL
|
||||
|| (group = EC_KEY_get0_group(eckey)) == NULL
|
||||
|| (nid = EC_GROUP_get_curve_name(group)) == 0)
|
||||
goto end;
|
||||
if (nid == NID_sm2
|
||||
&& !EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2))
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
*pkeysize = EVP_PKEY_size(pkey);
|
||||
ctx = EVP_PKEY_CTX_new(pkey, impl);
|
||||
if (ppkey != NULL)
|
||||
|
||||
+12
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2013-2014 Timo Teräs <timo.teras@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
@@ -233,7 +233,7 @@ static int do_file(const char *filename, const char *fullpath, enum Hash h)
|
||||
{
|
||||
STACK_OF (X509_INFO) *inf = NULL;
|
||||
X509_INFO *x;
|
||||
X509_NAME *name = NULL;
|
||||
const X509_NAME *name = NULL;
|
||||
BIO *b;
|
||||
const char *ext;
|
||||
unsigned char digest[EVP_MAX_MD_SIZE];
|
||||
@@ -274,11 +274,19 @@ static int do_file(const char *filename, const char *fullpath, enum Hash h)
|
||||
if (x->x509 != NULL) {
|
||||
type = TYPE_CERT;
|
||||
name = X509_get_subject_name(x->x509);
|
||||
X509_digest(x->x509, evpmd, digest, NULL);
|
||||
if (!X509_digest(x->x509, evpmd, digest, NULL)) {
|
||||
BIO_printf(bio_err, "out of memory\n");
|
||||
++errs;
|
||||
goto end;
|
||||
}
|
||||
} else if (x->crl != NULL) {
|
||||
type = TYPE_CRL;
|
||||
name = X509_CRL_get_issuer(x->crl);
|
||||
X509_CRL_digest(x->crl, evpmd, digest, NULL);
|
||||
if (!X509_CRL_digest(x->crl, evpmd, digest, NULL)) {
|
||||
BIO_printf(bio_err, "out of memory\n");
|
||||
++errs;
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
++errs;
|
||||
goto end;
|
||||
|
||||
+97
-121
@@ -87,11 +87,11 @@ typedef enum OPTION_choice {
|
||||
OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_KEYGEN_ENGINE, OPT_KEY,
|
||||
OPT_PUBKEY, OPT_NEW, OPT_CONFIG, OPT_KEYFORM, OPT_IN, OPT_OUT,
|
||||
OPT_KEYOUT, OPT_PASSIN, OPT_PASSOUT, OPT_NEWKEY,
|
||||
OPT_PKEYOPT, OPT_SIGOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS,
|
||||
OPT_PKEYOPT, OPT_SIGOPT, OPT_VFYOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS,
|
||||
OPT_VERIFY, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8,
|
||||
OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT, OPT_X509,
|
||||
OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, OPT_ADDEXT, OPT_EXTENSIONS,
|
||||
OPT_REQEXTS, OPT_PRECERT, OPT_MD, OPT_SM2ID, OPT_SM2HEXID,
|
||||
OPT_REQEXTS, OPT_PRECERT, OPT_MD,
|
||||
OPT_SECTION,
|
||||
OPT_R_ENUM, OPT_PROV_ENUM
|
||||
} OPTION_CHOICE;
|
||||
@@ -143,13 +143,8 @@ const OPTIONS req_options[] = {
|
||||
{"newkey", OPT_NEWKEY, 's', "Specify as type:bits"},
|
||||
{"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"},
|
||||
{"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
|
||||
{"vfyopt", OPT_VFYOPT, 's', "Verification parameter in n:v form"},
|
||||
{"", OPT_MD, '-', "Any supported digest"},
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
{"sm2-id", OPT_SM2ID, 's',
|
||||
"Specify an ID string to verify an SM2 certificate request"},
|
||||
{"sm2-hex-id", OPT_SM2HEXID, 's',
|
||||
"Specify a hex ID string to verify an SM2 certificate request"},
|
||||
#endif
|
||||
|
||||
OPT_SECTION("Output"),
|
||||
{"out", OPT_OUT, '>', "Output file"},
|
||||
@@ -237,7 +232,7 @@ int req_main(int argc, char **argv)
|
||||
ENGINE *e = NULL, *gen_eng = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
EVP_PKEY_CTX *genctx = NULL;
|
||||
STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL;
|
||||
STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL, *vfyopts = NULL;
|
||||
LHASH_OF(OPENSSL_STRING) *addexts = NULL;
|
||||
X509 *x509ss = NULL;
|
||||
X509_REQ *req = NULL;
|
||||
@@ -260,9 +255,6 @@ int req_main(int argc, char **argv)
|
||||
int nodes = 0, newhdr = 0, subject = 0, pubkey = 0, precert = 0;
|
||||
long newkey = -1;
|
||||
unsigned long chtype = MBSTRING_ASC, reqflag = 0;
|
||||
unsigned char *sm2_id = NULL;
|
||||
size_t sm2_idlen = 0;
|
||||
int sm2_free = 0;
|
||||
|
||||
#ifndef OPENSSL_NO_DES
|
||||
cipher = EVP_des_ede3_cbc();
|
||||
@@ -359,6 +351,12 @@ int req_main(int argc, char **argv)
|
||||
if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
|
||||
goto opthelp;
|
||||
break;
|
||||
case OPT_VFYOPT:
|
||||
if (!vfyopts)
|
||||
vfyopts = sk_OPENSSL_STRING_new_null();
|
||||
if (!vfyopts || !sk_OPENSSL_STRING_push(vfyopts, opt_arg()))
|
||||
goto opthelp;
|
||||
break;
|
||||
case OPT_BATCH:
|
||||
batch = 1;
|
||||
break;
|
||||
@@ -446,29 +444,6 @@ int req_main(int argc, char **argv)
|
||||
goto opthelp;
|
||||
digest = md_alg;
|
||||
break;
|
||||
case OPT_SM2ID:
|
||||
if (sm2_id != NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"Use one of the options 'sm2-hex-id' or 'sm2-id'\n");
|
||||
goto end;
|
||||
}
|
||||
sm2_id = (unsigned char *)opt_arg();
|
||||
sm2_idlen = strlen((const char *)sm2_id);
|
||||
break;
|
||||
case OPT_SM2HEXID:
|
||||
if (sm2_id != NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"Use one of the options 'sm2-hex-id' or 'sm2-id'\n");
|
||||
goto end;
|
||||
}
|
||||
/* try to parse the input as hex string first */
|
||||
sm2_free = 1;
|
||||
sm2_id = OPENSSL_hexstr2buf(opt_arg(), (long *)&sm2_idlen);
|
||||
if (sm2_id == NULL) {
|
||||
BIO_printf(bio_err, "Invalid hex string input\n");
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc = opt_num_rest();
|
||||
@@ -901,27 +876,7 @@ int req_main(int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (sm2_id != NULL) {
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
ASN1_OCTET_STRING *v;
|
||||
|
||||
v = ASN1_OCTET_STRING_new();
|
||||
if (v == NULL) {
|
||||
BIO_printf(bio_err, "error: SM2 ID allocation failed\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!ASN1_OCTET_STRING_set(v, sm2_id, sm2_idlen)) {
|
||||
BIO_printf(bio_err, "error: setting SM2 ID failed\n");
|
||||
ASN1_OCTET_STRING_free(v);
|
||||
goto end;
|
||||
}
|
||||
|
||||
X509_REQ_set0_sm2_id(req, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
i = X509_REQ_verify(req, tpubkey);
|
||||
i = do_X509_REQ_verify(req, tpubkey, vfyopts);
|
||||
|
||||
if (i < 0) {
|
||||
goto end;
|
||||
@@ -1029,8 +984,6 @@ int req_main(int argc, char **argv)
|
||||
}
|
||||
ret = 0;
|
||||
end:
|
||||
if (sm2_free)
|
||||
OPENSSL_free(sm2_id);
|
||||
if (ret) {
|
||||
ERR_print_errors(bio_err);
|
||||
}
|
||||
@@ -1043,6 +996,7 @@ int req_main(int argc, char **argv)
|
||||
EVP_PKEY_CTX_free(genctx);
|
||||
sk_OPENSSL_STRING_free(pkeyopts);
|
||||
sk_OPENSSL_STRING_free(sigopts);
|
||||
sk_OPENSSL_STRING_free(vfyopts);
|
||||
lh_OPENSSL_STRING_doall(addexts, exts_cleanup);
|
||||
lh_OPENSSL_STRING_free(addexts);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
@@ -1153,8 +1107,7 @@ static int prompt_info(X509_REQ *req,
|
||||
char *type, *value;
|
||||
const char *def;
|
||||
CONF_VALUE *v;
|
||||
X509_NAME *subj;
|
||||
subj = X509_REQ_get_subject_name(req);
|
||||
X509_NAME *subj = X509_REQ_get_subject_name(req);
|
||||
|
||||
if (!batch) {
|
||||
BIO_printf(bio_err,
|
||||
@@ -1239,8 +1192,7 @@ static int prompt_info(X509_REQ *req,
|
||||
return 0;
|
||||
}
|
||||
if (X509_NAME_entry_count(subj) == 0) {
|
||||
BIO_printf(bio_err,
|
||||
"error, no objects specified in config file\n");
|
||||
BIO_printf(bio_err, "error, no objects specified in config file\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1685,32 +1637,71 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int do_pkey_ctx_init(EVP_PKEY_CTX *pkctx, STACK_OF(OPENSSL_STRING) *opts)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (opts == NULL)
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
|
||||
char *opt = sk_OPENSSL_STRING_value(opts, i);
|
||||
if (pkey_ctrl_string(pkctx, opt) <= 0) {
|
||||
BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
|
||||
ERR_print_errors(bio_err);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int do_x509_init(X509 *x, STACK_OF(OPENSSL_STRING) *opts)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (opts == NULL)
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
|
||||
char *opt = sk_OPENSSL_STRING_value(opts, i);
|
||||
if (x509_ctrl_string(x, opt) <= 0) {
|
||||
BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
|
||||
ERR_print_errors(bio_err);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int do_x509_req_init(X509_REQ *x, STACK_OF(OPENSSL_STRING) *opts)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (opts == NULL)
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
|
||||
char *opt = sk_OPENSSL_STRING_value(opts, i);
|
||||
if (x509_req_ctrl_string(x, opt) <= 0) {
|
||||
BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
|
||||
ERR_print_errors(bio_err);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
|
||||
const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
|
||||
{
|
||||
EVP_PKEY_CTX *pkctx = NULL;
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
int i, def_nid, ret = 0;
|
||||
int def_nid;
|
||||
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) {
|
||||
pctx = EVP_PKEY_CTX_new(pkey, NULL);
|
||||
if (pctx == NULL) {
|
||||
BIO_printf(bio_err, "memory allocation failure.\n");
|
||||
goto err;
|
||||
}
|
||||
/* set SM2 ID from sig options before calling the real init routine */
|
||||
for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
|
||||
char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
|
||||
if (pkey_ctrl_string(pctx, sigopt) <= 0) {
|
||||
BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt);
|
||||
ERR_print_errors(bio_err);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
|
||||
}
|
||||
return 0;
|
||||
/*
|
||||
* EVP_PKEY_get_default_digest_nid() returns 2 if the digest is mandatory
|
||||
* for this algorithm.
|
||||
@@ -1720,36 +1711,8 @@ static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
|
||||
/* The signing algorithm requires there to be no digest */
|
||||
md = NULL;
|
||||
}
|
||||
if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
|
||||
goto err;
|
||||
for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
|
||||
char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
|
||||
if (pkey_ctrl_string(pkctx, sigopt) <= 0) {
|
||||
BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt);
|
||||
ERR_print_errors(bio_err);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
if (!ret)
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void do_sign_cleanup(EVP_MD_CTX *ctx, EVP_PKEY *pkey)
|
||||
{
|
||||
/*
|
||||
* With SM2, do_sign_init() attached an EVP_PKEY_CTX to the EVP_MD_CTX,
|
||||
* and we have to free it explicitly.
|
||||
*/
|
||||
if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) {
|
||||
EVP_PKEY_CTX *pctx = EVP_MD_CTX_pkey_ctx(ctx);
|
||||
|
||||
EVP_MD_CTX_set_pkey_ctx(ctx, NULL);
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
}
|
||||
return EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey)
|
||||
&& do_pkey_ctx_init(pkctx, sigopts);
|
||||
}
|
||||
|
||||
int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
|
||||
@@ -1758,10 +1721,8 @@ int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
|
||||
int rv = 0;
|
||||
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
|
||||
|
||||
if (do_sign_init(mctx, pkey, md, sigopts) > 0) {
|
||||
if (do_sign_init(mctx, pkey, md, sigopts) > 0)
|
||||
rv = (X509_sign_ctx(x, mctx) > 0);
|
||||
do_sign_cleanup(mctx, pkey);
|
||||
}
|
||||
EVP_MD_CTX_free(mctx);
|
||||
return rv;
|
||||
}
|
||||
@@ -1772,24 +1733,39 @@ int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
|
||||
int rv = 0;
|
||||
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
|
||||
|
||||
if (do_sign_init(mctx, pkey, md, sigopts) > 0) {
|
||||
if (do_sign_init(mctx, pkey, md, sigopts) > 0)
|
||||
rv = (X509_REQ_sign_ctx(x, mctx) > 0);
|
||||
do_sign_cleanup(mctx, pkey);
|
||||
}
|
||||
EVP_MD_CTX_free(mctx);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
if (do_x509_init(x, vfyopts) > 0)
|
||||
rv = (X509_verify(x, pkey) > 0);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey,
|
||||
STACK_OF(OPENSSL_STRING) *vfyopts)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
if (do_x509_req_init(x, vfyopts) > 0)
|
||||
rv = (X509_REQ_verify(x, pkey) > 0);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
|
||||
STACK_OF(OPENSSL_STRING) *sigopts)
|
||||
{
|
||||
int rv = 0;
|
||||
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
|
||||
|
||||
if (do_sign_init(mctx, pkey, md, sigopts) > 0) {
|
||||
if (do_sign_init(mctx, pkey, md, sigopts) > 0)
|
||||
rv = (X509_CRL_sign_ctx(x, mctx) > 0);
|
||||
do_sign_cleanup(mctx, pkey);
|
||||
}
|
||||
EVP_MD_CTX_free(mctx);
|
||||
return rv;
|
||||
}
|
||||
+23
-27
@@ -8,23 +8,20 @@
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_RSA
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <time.h>
|
||||
# include "apps.h"
|
||||
# include "progs.h"
|
||||
# include <openssl/bio.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/rsa.h>
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/pem.h>
|
||||
# include <openssl/bn.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
@@ -42,9 +39,9 @@ const OPTIONS rsa_options[] = {
|
||||
{"help", OPT_HELP, '-', "Display this summary"},
|
||||
{"check", OPT_CHECK, '-', "Verify key consistency"},
|
||||
{"", OPT_CIPHER, '-', "Any supported cipher"},
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
||||
# endif
|
||||
#endif
|
||||
|
||||
OPT_SECTION("Input"),
|
||||
{"in", OPT_IN, 's', "Input file"},
|
||||
@@ -63,14 +60,14 @@ const OPTIONS rsa_options[] = {
|
||||
{"text", OPT_TEXT, '-', "Print the key in text"},
|
||||
{"modulus", OPT_MODULUS, '-', "Print the RSA key modulus"},
|
||||
|
||||
# if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
|
||||
#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
|
||||
OPT_SECTION("PVK"),
|
||||
{"pvk-strong", OPT_PVK_STRONG, '-', "Enable 'Strong' PVK encoding level (default)"},
|
||||
{"pvk-weak", OPT_PVK_WEAK, '-', "Enable 'Weak' PVK encoding level"},
|
||||
{"pvk-none", OPT_PVK_NONE, '-', "Don't enforce PVK encoding"},
|
||||
# endif
|
||||
|
||||
OPT_PROV_OPTIONS,
|
||||
#endif
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@@ -85,9 +82,9 @@ int rsa_main(int argc, char **argv)
|
||||
int i, private = 0;
|
||||
int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, check = 0;
|
||||
int noout = 0, modulus = 0, pubin = 0, pubout = 0, ret = 1;
|
||||
# if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
|
||||
#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
|
||||
int pvk_encr = 2;
|
||||
# endif
|
||||
#endif
|
||||
OPTION_CHOICE o;
|
||||
|
||||
prog = opt_init(argc, argv, rsa_options);
|
||||
@@ -140,9 +137,9 @@ int rsa_main(int argc, char **argv)
|
||||
case OPT_PVK_STRONG: /* pvk_encr:= 2 */
|
||||
case OPT_PVK_WEAK: /* pvk_encr:= 1 */
|
||||
case OPT_PVK_NONE: /* pvk_encr:= 0 */
|
||||
# if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
|
||||
#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
|
||||
pvk_encr = (o - OPT_PVK_NONE);
|
||||
# endif
|
||||
#endif
|
||||
break;
|
||||
case OPT_NOOUT:
|
||||
noout = 1;
|
||||
@@ -278,7 +275,7 @@ int rsa_main(int argc, char **argv)
|
||||
i = PEM_write_bio_RSAPrivateKey(out, rsa,
|
||||
enc, NULL, 0, NULL, passout);
|
||||
}
|
||||
# ifndef OPENSSL_NO_DSA
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
} else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {
|
||||
EVP_PKEY *pk;
|
||||
pk = EVP_PKEY_new();
|
||||
@@ -307,7 +304,7 @@ int rsa_main(int argc, char **argv)
|
||||
i = i2b_PrivateKey_bio(out, pk);
|
||||
}
|
||||
EVP_PKEY_free(pk);
|
||||
# endif
|
||||
#endif
|
||||
} else {
|
||||
BIO_printf(bio_err, "bad output format specified for outfile\n");
|
||||
goto end;
|
||||
@@ -326,4 +323,3 @@ int rsa_main(int argc, char **argv)
|
||||
OPENSSL_free(passout);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
+15
-19
@@ -8,25 +8,22 @@
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_RSA
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
# include "apps.h"
|
||||
# include "progs.h"
|
||||
# include <string.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/pem.h>
|
||||
# include <openssl/rsa.h>
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
#include <string.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
# define RSA_SIGN 1
|
||||
# define RSA_VERIFY 2
|
||||
# define RSA_ENCRYPT 3
|
||||
# define RSA_DECRYPT 4
|
||||
#define RSA_SIGN 1
|
||||
#define RSA_VERIFY 2
|
||||
#define RSA_ENCRYPT 3
|
||||
#define RSA_DECRYPT 4
|
||||
|
||||
# define KEY_PRIVKEY 1
|
||||
# define KEY_PUBKEY 2
|
||||
# define KEY_CERT 3
|
||||
#define KEY_PRIVKEY 1
|
||||
#define KEY_PUBKEY 2
|
||||
#define KEY_CERT 3
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
@@ -44,9 +41,9 @@ const OPTIONS rsautl_options[] = {
|
||||
{"verify", OPT_VERIFY, '-', "Verify with public key"},
|
||||
{"encrypt", OPT_ENCRYPT, '-', "Encrypt with public key"},
|
||||
{"decrypt", OPT_DECRYPT, '-', "Decrypt with private key"},
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
||||
# endif
|
||||
#endif
|
||||
|
||||
OPT_SECTION("Input"),
|
||||
{"in", OPT_IN, '<', "Input file"},
|
||||
@@ -290,4 +287,3 @@ int rsautl_main(int argc, char **argv)
|
||||
OPENSSL_free(passin);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
+72
-7
@@ -103,6 +103,8 @@ static int keymatexportlen = 20;
|
||||
|
||||
static int async = 0;
|
||||
|
||||
static int use_sendfile = 0;
|
||||
|
||||
static const char *session_id_prefix = NULL;
|
||||
|
||||
#ifndef OPENSSL_NO_DTLS
|
||||
@@ -707,7 +709,7 @@ static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
|
||||
if (SSL_select_next_proto
|
||||
((unsigned char **)out, outlen, alpn_ctx->data, alpn_ctx->len, in,
|
||||
inlen) != OPENSSL_NPN_NEGOTIATED) {
|
||||
return SSL_TLSEXT_ERR_NOACK;
|
||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||
}
|
||||
|
||||
if (!s_quiet) {
|
||||
@@ -749,7 +751,7 @@ typedef enum OPTION_choice {
|
||||
OPT_SSL3, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
|
||||
OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN, OPT_STATELESS,
|
||||
OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
|
||||
OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
|
||||
OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN, OPT_SENDFILE,
|
||||
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
|
||||
OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA,
|
||||
OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY, OPT_SCTP_LABEL_BUG,
|
||||
@@ -981,6 +983,9 @@ const OPTIONS s_server_options[] = {
|
||||
#endif
|
||||
{"alpn", OPT_ALPN, 's',
|
||||
"Set the advertised protocols for the ALPN extension (comma-separated list)"},
|
||||
#ifndef OPENSSL_NO_KTLS
|
||||
{"sendfile", OPT_SENDFILE, '-', "Use sendfile to response file with -WWW"},
|
||||
#endif
|
||||
|
||||
OPT_R_OPTIONS,
|
||||
OPT_S_OPTIONS,
|
||||
@@ -1095,6 +1100,7 @@ int s_server_main(int argc, char *argv[])
|
||||
s_quiet = 0;
|
||||
s_brief = 0;
|
||||
async = 0;
|
||||
use_sendfile = 0;
|
||||
|
||||
cctx = SSL_CONF_CTX_new();
|
||||
vpm = X509_VERIFY_PARAM_new();
|
||||
@@ -1643,6 +1649,11 @@ int s_server_main(int argc, char *argv[])
|
||||
case OPT_HTTP_SERVER_BINMODE:
|
||||
http_server_binmode = 1;
|
||||
break;
|
||||
case OPT_SENDFILE:
|
||||
#ifndef OPENSSL_NO_KTLS
|
||||
use_sendfile = 1;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc = opt_num_rest();
|
||||
@@ -1695,6 +1706,13 @@ int s_server_main(int argc, char *argv[])
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_KTLS
|
||||
if (use_sendfile && www <= 1) {
|
||||
BIO_printf(bio_err, "Can't use -sendfile without -WWW or -HTTP\n");
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!app_passwd(passarg, dpassarg, &pass, &dpass)) {
|
||||
BIO_printf(bio_err, "Error getting password\n");
|
||||
goto end;
|
||||
@@ -1958,7 +1976,7 @@ int s_server_main(int argc, char *argv[])
|
||||
BIO_printf(bio_s_out, "Setting secondary ctx parameters\n");
|
||||
|
||||
if (sdebug)
|
||||
ssl_ctx_security_debug(ctx, sdebug);
|
||||
ssl_ctx_security_debug(ctx2, sdebug);
|
||||
|
||||
if (session_id_prefix) {
|
||||
if (strlen(session_id_prefix) >= 32)
|
||||
@@ -2093,11 +2111,17 @@ int s_server_main(int argc, char *argv[])
|
||||
SSL_CTX_set_psk_server_callback(ctx, psk_server_cb);
|
||||
}
|
||||
|
||||
if (psk_identity_hint != NULL) {
|
||||
if (min_version == TLS1_3_VERSION) {
|
||||
BIO_printf(bio_s_out, "PSK warning: there is NO identity hint in TLSv1.3\n");
|
||||
} else {
|
||||
if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) {
|
||||
BIO_printf(bio_err, "error setting PSK identity hint to context\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (psksessf != NULL) {
|
||||
BIO *stmp = BIO_new_file(psksessf, "r");
|
||||
@@ -3330,6 +3354,47 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
|
||||
"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
|
||||
}
|
||||
/* send the file */
|
||||
#ifndef OPENSSL_NO_KTLS
|
||||
if (use_sendfile) {
|
||||
FILE *fp = NULL;
|
||||
int fd;
|
||||
struct stat st;
|
||||
off_t offset = 0;
|
||||
size_t filesize;
|
||||
|
||||
BIO_get_fp(file, &fp);
|
||||
fd = fileno(fp);
|
||||
if (fstat(fd, &st) < 0) {
|
||||
BIO_printf(io, "Error fstat '%s'\r\n", p);
|
||||
ERR_print_errors(io);
|
||||
goto write_error;
|
||||
}
|
||||
|
||||
filesize = st.st_size;
|
||||
if (((int)BIO_flush(io)) < 0)
|
||||
goto write_error;
|
||||
|
||||
for (;;) {
|
||||
i = SSL_sendfile(con, fd, offset, filesize, 0);
|
||||
if (i < 0) {
|
||||
BIO_printf(io, "Error SSL_sendfile '%s'\r\n", p);
|
||||
ERR_print_errors(io);
|
||||
break;
|
||||
} else {
|
||||
offset += i;
|
||||
filesize -= i;
|
||||
}
|
||||
|
||||
if (filesize <= 0) {
|
||||
if (!s_quiet)
|
||||
BIO_printf(bio_err, "KTLS SENDFILE '%s' OK\n", p);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
for (;;) {
|
||||
i = BIO_read(file, buf, bufsize);
|
||||
if (i <= 0)
|
||||
@@ -3348,16 +3413,15 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
|
||||
for (j = 0; j < i;) {
|
||||
#ifdef RENEG
|
||||
static count = 0;
|
||||
if (++count == 13) {
|
||||
if (++count == 13)
|
||||
SSL_renegotiate(con);
|
||||
}
|
||||
#endif
|
||||
k = BIO_write(io, &(buf[j]), i - j);
|
||||
if (k <= 0) {
|
||||
if (!BIO_should_retry(io)
|
||||
&& !SSL_waiting_for_async(con))
|
||||
&& !SSL_waiting_for_async(con)) {
|
||||
goto write_error;
|
||||
else {
|
||||
} else {
|
||||
BIO_printf(bio_s_out, "rwrite W BLOCK\n");
|
||||
}
|
||||
} else {
|
||||
@@ -3365,6 +3429,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
write_error:
|
||||
BIO_free(file);
|
||||
break;
|
||||
|
||||
+9
-2
@@ -145,8 +145,15 @@ int spkac_main(int argc, char **argv)
|
||||
if (challenge != NULL)
|
||||
ASN1_STRING_set(spki->spkac->challenge,
|
||||
challenge, (int)strlen(challenge));
|
||||
NETSCAPE_SPKI_set_pubkey(spki, pkey);
|
||||
NETSCAPE_SPKI_sign(spki, pkey, EVP_md5());
|
||||
if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) {
|
||||
BIO_printf(bio_err, "Error setting public key\n");
|
||||
goto end;
|
||||
}
|
||||
i = NETSCAPE_SPKI_sign(spki, pkey, EVP_md5());
|
||||
if (i <= 0) {
|
||||
BIO_printf(bio_err, "Error signing SPKAC\n");
|
||||
goto end;
|
||||
}
|
||||
spkstr = NETSCAPE_SPKI_b64_encode(spki);
|
||||
if (spkstr == NULL)
|
||||
goto end;
|
||||
|
||||
+17
-21
@@ -12,28 +12,25 @@
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_SRP
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <openssl/conf.h>
|
||||
# include <openssl/bio.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/txt_db.h>
|
||||
# include <openssl/buffer.h>
|
||||
# include <openssl/srp.h>
|
||||
# include "apps.h"
|
||||
# include "progs.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/txt_db.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/srp.h>
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
|
||||
# define BASE_SECTION "srp"
|
||||
# define CONFIG_FILE "openssl.cnf"
|
||||
#define BASE_SECTION "srp"
|
||||
#define CONFIG_FILE "openssl.cnf"
|
||||
|
||||
|
||||
# define ENV_DATABASE "srpvfile"
|
||||
# define ENV_DEFAULT_SRP "default_srp"
|
||||
#define ENV_DATABASE "srpvfile"
|
||||
#define ENV_DEFAULT_SRP "default_srp"
|
||||
|
||||
static int get_index(CA_DB *db, char *id, char type)
|
||||
{
|
||||
@@ -204,9 +201,9 @@ const OPTIONS srp_options[] = {
|
||||
{"verbose", OPT_VERBOSE, '-', "Talk a lot while doing things"},
|
||||
{"config", OPT_CONFIG, '<', "A config file"},
|
||||
{"name", OPT_NAME, 's', "The particular srp definition to use"},
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
||||
# endif
|
||||
#endif
|
||||
|
||||
OPT_SECTION("Action"),
|
||||
{"add", OPT_ADD, '-', "Add a user and srp verifier"},
|
||||
@@ -625,4 +622,3 @@ int srp_main(int argc, char **argv)
|
||||
release_engine(e);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
@@ -8,29 +8,26 @@
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#ifdef OPENSSL_NO_TS
|
||||
NON_EMPTY_TRANSLATION_UNIT
|
||||
#else
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include "apps.h"
|
||||
# include "progs.h"
|
||||
# include <openssl/bio.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/pem.h>
|
||||
# include <openssl/rand.h>
|
||||
# include <openssl/ts.h>
|
||||
# include <openssl/bn.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/ts.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
/* Request nonce length, in bits (must be a multiple of 8). */
|
||||
# define NONCE_LENGTH 64
|
||||
#define NONCE_LENGTH 64
|
||||
|
||||
/* Name of config entry that defines the OID file. */
|
||||
# define ENV_OID_FILE "oid_file"
|
||||
#define ENV_OID_FILE "oid_file"
|
||||
|
||||
/* Is |EXACTLY_ONE| of three pointers set? */
|
||||
# define EXACTLY_ONE(a, b, c) \
|
||||
#define EXACTLY_ONE(a, b, c) \
|
||||
(( a && !b && !c) || \
|
||||
( b && !a && !c) || \
|
||||
( c && !a && !b))
|
||||
@@ -94,9 +91,9 @@ const OPTIONS ts_options[] = {
|
||||
{"help", OPT_HELP, '-', "Display this summary"},
|
||||
{"config", OPT_CONFIG, '<', "Configuration file"},
|
||||
{"section", OPT_SECTION, 's', "Section to use within config file"},
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
||||
# endif
|
||||
#endif
|
||||
{"inkey", OPT_INKEY, 's', "File with private key for reply"},
|
||||
{"signer", OPT_SIGNER, 's', "Signer certificate file"},
|
||||
{"chain", OPT_CHAIN, '<', "File with signer CA chain"},
|
||||
@@ -146,11 +143,11 @@ static char* opt_helplist[] = {
|
||||
" [-signer tsa_cert.pem] [-inkey private_key.pem]",
|
||||
" [-chain certs_file.pem] [-tspolicy oid]",
|
||||
" [-in file] [-token_in] [-out file] [-token_out]",
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
" [-text] [-engine id]",
|
||||
# else
|
||||
#else
|
||||
" [-text]",
|
||||
# endif
|
||||
#endif
|
||||
"",
|
||||
" openssl ts -verify -CApath dir -CAfile file.pem -CAstore uri",
|
||||
" -untrusted file.pem [-data file] [-digest hexstring]",
|
||||
@@ -699,10 +696,10 @@ static TS_RESP *create_response(CONF *conf, const char *section, const char *eng
|
||||
goto end;
|
||||
if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx))
|
||||
goto end;
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (!TS_CONF_set_crypto_device(conf, section, engine))
|
||||
goto end;
|
||||
# endif
|
||||
#endif
|
||||
if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx))
|
||||
goto end;
|
||||
if (!TS_CONF_set_certs(conf, section, chain, resp_ctx))
|
||||
@@ -1013,4 +1010,3 @@ static int verify_cb(int ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
return ok;
|
||||
}
|
||||
#endif /* ndef OPENSSL_NO_TS */
|
||||
+24
-57
@@ -22,7 +22,7 @@ static int cb(int ok, X509_STORE_CTX *ctx);
|
||||
static int check(X509_STORE *ctx, const char *file,
|
||||
STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
|
||||
STACK_OF(X509_CRL) *crls, int show_chain,
|
||||
unsigned char *sm2id, size_t sm2idlen);
|
||||
STACK_OF(OPENSSL_STRING) *opts);
|
||||
static int v_verbose = 0, vflags = 0;
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
@@ -30,8 +30,8 @@ typedef enum OPTION_choice {
|
||||
OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_CASTORE,
|
||||
OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE,
|
||||
OPT_UNTRUSTED, OPT_TRUSTED, OPT_CRLFILE, OPT_CRL_DOWNLOAD, OPT_SHOW_CHAIN,
|
||||
OPT_V_ENUM, OPT_NAMEOPT,
|
||||
OPT_VERBOSE, OPT_SM2ID, OPT_SM2HEXID,
|
||||
OPT_V_ENUM, OPT_NAMEOPT, OPT_VFYOPT,
|
||||
OPT_VERBOSE,
|
||||
OPT_PROV_ENUM
|
||||
} OPTION_CHOICE;
|
||||
|
||||
@@ -67,12 +67,7 @@ const OPTIONS verify_options[] = {
|
||||
"Display information about the certificate chain"},
|
||||
|
||||
OPT_V_OPTIONS,
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
{"sm2-id", OPT_SM2ID, 's',
|
||||
"Specify an ID string to verify an SM2 certificate"},
|
||||
{"sm2-hex-id", OPT_SM2HEXID, 's',
|
||||
"Specify a hex ID string to verify an SM2 certificate"},
|
||||
#endif
|
||||
{"vfyopt", OPT_VFYOPT, 's', "Verification parameter in n:v form"},
|
||||
|
||||
OPT_PROV_OPTIONS,
|
||||
|
||||
@@ -86,15 +81,13 @@ int verify_main(int argc, char **argv)
|
||||
ENGINE *e = NULL;
|
||||
STACK_OF(X509) *untrusted = NULL, *trusted = NULL;
|
||||
STACK_OF(X509_CRL) *crls = NULL;
|
||||
STACK_OF(OPENSSL_STRING) *vfyopts = NULL;
|
||||
X509_STORE *store = NULL;
|
||||
X509_VERIFY_PARAM *vpm = NULL;
|
||||
const char *prog, *CApath = NULL, *CAfile = NULL, *CAstore = NULL;
|
||||
int noCApath = 0, noCAfile = 0, noCAstore = 0;
|
||||
int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1;
|
||||
OPTION_CHOICE o;
|
||||
unsigned char *sm2_id = NULL;
|
||||
size_t sm2_idlen = 0;
|
||||
int sm2_free = 0;
|
||||
|
||||
if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
|
||||
goto end;
|
||||
@@ -104,6 +97,7 @@ int verify_main(int argc, char **argv)
|
||||
switch (o) {
|
||||
case OPT_EOF:
|
||||
case OPT_ERR:
|
||||
opthelp:
|
||||
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
|
||||
goto end;
|
||||
case OPT_HELP:
|
||||
@@ -186,32 +180,15 @@ int verify_main(int argc, char **argv)
|
||||
if (!set_nameopt(opt_arg()))
|
||||
goto end;
|
||||
break;
|
||||
case OPT_VFYOPT:
|
||||
if (!vfyopts)
|
||||
vfyopts = sk_OPENSSL_STRING_new_null();
|
||||
if (!vfyopts || !sk_OPENSSL_STRING_push(vfyopts, opt_arg()))
|
||||
goto opthelp;
|
||||
break;
|
||||
case OPT_VERBOSE:
|
||||
v_verbose = 1;
|
||||
break;
|
||||
case OPT_SM2ID:
|
||||
if (sm2_id != NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"Use one of the options 'sm2-hex-id' or 'sm2-id' \n");
|
||||
goto end;
|
||||
}
|
||||
sm2_id = (unsigned char *)opt_arg();
|
||||
sm2_idlen = strlen((const char *)sm2_id);
|
||||
break;
|
||||
case OPT_SM2HEXID:
|
||||
if (sm2_id != NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"Use one of the options 'sm2-hex-id' or 'sm2-id' \n");
|
||||
goto end;
|
||||
}
|
||||
/* try to parse the input as hex string first */
|
||||
sm2_free = 1;
|
||||
sm2_id = OPENSSL_hexstr2buf(opt_arg(), (long *)&sm2_idlen);
|
||||
if (sm2_id == NULL) {
|
||||
BIO_printf(bio_err, "Invalid hex string input\n");
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case OPT_PROV_CASES:
|
||||
if (!opt_provider(o))
|
||||
goto end;
|
||||
@@ -244,23 +221,22 @@ int verify_main(int argc, char **argv)
|
||||
ret = 0;
|
||||
if (argc < 1) {
|
||||
if (check(store, NULL, untrusted, trusted, crls, show_chain,
|
||||
sm2_id, sm2_idlen) != 1)
|
||||
vfyopts) != 1)
|
||||
ret = -1;
|
||||
} else {
|
||||
for (i = 0; i < argc; i++)
|
||||
if (check(store, argv[i], untrusted, trusted, crls,
|
||||
show_chain, sm2_id, sm2_idlen) != 1)
|
||||
if (check(store, argv[i], untrusted, trusted, crls, show_chain,
|
||||
vfyopts) != 1)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
end:
|
||||
if (sm2_free)
|
||||
OPENSSL_free(sm2_id);
|
||||
X509_VERIFY_PARAM_free(vpm);
|
||||
X509_STORE_free(store);
|
||||
sk_X509_pop_free(untrusted, X509_free);
|
||||
sk_X509_pop_free(trusted, X509_free);
|
||||
sk_X509_CRL_pop_free(crls, X509_CRL_free);
|
||||
sk_OPENSSL_STRING_free(vfyopts);
|
||||
release_engine(e);
|
||||
return (ret < 0 ? 2 : ret);
|
||||
}
|
||||
@@ -268,7 +244,7 @@ int verify_main(int argc, char **argv)
|
||||
static int check(X509_STORE *ctx, const char *file,
|
||||
STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
|
||||
STACK_OF(X509_CRL) *crls, int show_chain,
|
||||
unsigned char *sm2id, size_t sm2idlen)
|
||||
STACK_OF(OPENSSL_STRING) *opts)
|
||||
{
|
||||
X509 *x = NULL;
|
||||
int i = 0, ret = 0;
|
||||
@@ -280,24 +256,15 @@ static int check(X509_STORE *ctx, const char *file,
|
||||
if (x == NULL)
|
||||
goto end;
|
||||
|
||||
if (sm2id != NULL) {
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
ASN1_OCTET_STRING *v;
|
||||
|
||||
v = ASN1_OCTET_STRING_new();
|
||||
if (v == NULL) {
|
||||
BIO_printf(bio_err, "error: SM2 ID allocation failed\n");
|
||||
goto end;
|
||||
if (opts != NULL) {
|
||||
for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
|
||||
char *opt = sk_OPENSSL_STRING_value(opts, i);
|
||||
if (x509_ctrl_string(x, opt) <= 0) {
|
||||
BIO_printf(bio_err, "parameter error \"%s\"\n", opt);
|
||||
ERR_print_errors(bio_err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ASN1_OCTET_STRING_set(v, sm2id, sm2idlen)) {
|
||||
BIO_printf(bio_err, "error: setting SM2 ID failed\n");
|
||||
ASN1_OCTET_STRING_free(v);
|
||||
goto end;
|
||||
}
|
||||
|
||||
X509_set0_sm2_id(x, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
csc = X509_STORE_CTX_new();
|
||||
|
||||
+20
-9
@@ -33,7 +33,9 @@
|
||||
#define DEF_DAYS 30
|
||||
|
||||
static int callb(int ok, X509_STORE_CTX *ctx);
|
||||
static int sign(X509 *x, EVP_PKEY *pkey, EVP_PKEY *fkey, int days, int clrext,
|
||||
static int sign(X509 *x, EVP_PKEY *pkey, EVP_PKEY *fkey,
|
||||
STACK_OF(OPENSSL_STRING) *sigopts,
|
||||
int days, int clrext,
|
||||
const EVP_MD *digest, CONF *conf, const char *section,
|
||||
int preserve_dates);
|
||||
static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *digest,
|
||||
@@ -48,7 +50,7 @@ static int print_x509v3_exts(BIO *bio, X509 *x, const char *exts);
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
OPT_INFORM, OPT_OUTFORM, OPT_KEYFORM, OPT_REQ, OPT_CAFORM,
|
||||
OPT_CAKEYFORM, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE,
|
||||
OPT_CAKEYFORM, OPT_VFYOPT, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE,
|
||||
OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_SIGNKEY, OPT_CA, OPT_CAKEY,
|
||||
OPT_CASERIAL, OPT_SET_SERIAL, OPT_NEW, OPT_FORCE_PUBKEY, OPT_SUBJ,
|
||||
OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_NAMEOPT,
|
||||
@@ -80,6 +82,7 @@ const OPTIONS x509_options[] = {
|
||||
{"out", OPT_OUT, '>', "Output file - default stdout"},
|
||||
{"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"},
|
||||
{"req", OPT_REQ, '-', "Input is a certificate request, sign and output"},
|
||||
{"vfyopt", OPT_VFYOPT, 's', "Verification parameter in n:v form"},
|
||||
|
||||
OPT_SECTION("Output"),
|
||||
{"serial", OPT_SERIAL, '-', "Print serial number value"},
|
||||
@@ -174,7 +177,7 @@ int x509_main(int argc, char **argv)
|
||||
const unsigned long chtype = MBSTRING_ASC;
|
||||
const int multirdn = 0;
|
||||
STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
|
||||
STACK_OF(OPENSSL_STRING) *sigopts = NULL;
|
||||
STACK_OF(OPENSSL_STRING) *sigopts = NULL, *vfyopts = NULL;
|
||||
X509 *x = NULL, *xca = NULL;
|
||||
X509_REQ *req = NULL, *rq = NULL;
|
||||
X509_STORE *ctx = NULL;
|
||||
@@ -256,6 +259,12 @@ int x509_main(int argc, char **argv)
|
||||
if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
|
||||
goto opthelp;
|
||||
break;
|
||||
case OPT_VFYOPT:
|
||||
if (!vfyopts)
|
||||
vfyopts = sk_OPENSSL_STRING_new_null();
|
||||
if (!vfyopts || !sk_OPENSSL_STRING_push(vfyopts, opt_arg()))
|
||||
goto opthelp;
|
||||
break;
|
||||
case OPT_DAYS:
|
||||
if (preserve_dates)
|
||||
goto opthelp;
|
||||
@@ -576,7 +585,7 @@ int x509_main(int argc, char **argv)
|
||||
BIO_printf(bio_err, "error unpacking public key\n");
|
||||
goto end;
|
||||
}
|
||||
i = X509_REQ_verify(req, pkey);
|
||||
i = do_X509_REQ_verify(req, pkey, vfyopts);
|
||||
if (i < 0) {
|
||||
BIO_printf(bio_err, "Request self-signature verification error\n");
|
||||
ERR_print_errors(bio_err);
|
||||
@@ -848,8 +857,8 @@ int x509_main(int argc, char **argv)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!sign(x, Upkey, fkey, days, clrext, digest, extconf,
|
||||
extsect, preserve_dates))
|
||||
if (!sign(x, Upkey, fkey, sigopts, days, clrext, digest,
|
||||
extconf, extsect, preserve_dates))
|
||||
goto end;
|
||||
} else if (CA_flag == i) {
|
||||
BIO_printf(bio_err, "Getting CA Private Key\n");
|
||||
@@ -949,6 +958,7 @@ int x509_main(int argc, char **argv)
|
||||
EVP_PKEY_free(CApkey);
|
||||
EVP_PKEY_free(fkey);
|
||||
sk_OPENSSL_STRING_free(sigopts);
|
||||
sk_OPENSSL_STRING_free(vfyopts);
|
||||
X509_REQ_free(rq);
|
||||
ASN1_INTEGER_free(sno);
|
||||
sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
|
||||
@@ -1106,11 +1116,12 @@ static int callb(int ok, X509_STORE_CTX *ctx)
|
||||
}
|
||||
|
||||
/* self-issue; self-sign unless a forced public key (fkey) is given */
|
||||
static int sign(X509 *x, EVP_PKEY *pkey, EVP_PKEY *fkey, int days, int clrext,
|
||||
static int sign(X509 *x, EVP_PKEY *pkey, EVP_PKEY *fkey,
|
||||
STACK_OF(OPENSSL_STRING) *sigopts,
|
||||
int days, int clrext,
|
||||
const EVP_MD *digest, CONF *conf, const char *section,
|
||||
int preserve_dates)
|
||||
{
|
||||
|
||||
if (!X509_set_issuer_name(x, X509_get_subject_name(x)))
|
||||
goto err;
|
||||
if (!preserve_dates && !set_cert_times(x, NULL, NULL, days))
|
||||
@@ -1129,7 +1140,7 @@ static int sign(X509 *x, EVP_PKEY *pkey, EVP_PKEY *fkey, int days, int clrext,
|
||||
if (!X509V3_EXT_add_nconf(conf, &ctx, section, x))
|
||||
goto err;
|
||||
}
|
||||
if (!X509_sign(x, pkey, digest))
|
||||
if (!do_X509_sign(x, pkey, digest, sigopts))
|
||||
goto err;
|
||||
return 1;
|
||||
err:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2000-2020 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
|
||||
@@ -145,6 +145,7 @@ static ASN1_ITEM_EXP *asn1_item_list[] = {
|
||||
#endif
|
||||
ASN1_ITEM_ref(SXNETID),
|
||||
ASN1_ITEM_ref(SXNET),
|
||||
ASN1_ITEM_ref(ISSUER_SIGN_TOOL),
|
||||
ASN1_ITEM_ref(USERNOTICE),
|
||||
ASN1_ITEM_ref(X509_ALGORS),
|
||||
ASN1_ITEM_ref(X509_ALGOR),
|
||||
|
||||
+85
-27
@@ -22,12 +22,14 @@ static int _asn1_check_infinite_end(const unsigned char **p, long len)
|
||||
/*
|
||||
* If there is 0 or 1 byte left, the length check should pick things up
|
||||
*/
|
||||
if (len <= 0)
|
||||
if (len <= 0) {
|
||||
return 1;
|
||||
else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
|
||||
} else {
|
||||
if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
|
||||
(*p) += 2;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -45,7 +47,7 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
|
||||
int *pclass, long omax)
|
||||
{
|
||||
int i, ret;
|
||||
long l;
|
||||
long len;
|
||||
const unsigned char *p = *pp;
|
||||
int tag, xclass, inf;
|
||||
long max = omax;
|
||||
@@ -59,18 +61,18 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
|
||||
p++;
|
||||
if (--max == 0)
|
||||
goto err;
|
||||
l = 0;
|
||||
len = 0;
|
||||
while (*p & 0x80) {
|
||||
l <<= 7L;
|
||||
l |= *(p++) & 0x7f;
|
||||
len <<= 7L;
|
||||
len |= *(p++) & 0x7f;
|
||||
if (--max == 0)
|
||||
goto err;
|
||||
if (l > (INT_MAX >> 7L))
|
||||
if (len > (INT_MAX >> 7L))
|
||||
goto err;
|
||||
}
|
||||
l <<= 7L;
|
||||
l |= *(p++) & 0x7f;
|
||||
tag = (int)l;
|
||||
len <<= 7L;
|
||||
len |= *(p++) & 0x7f;
|
||||
tag = (int)len;
|
||||
if (--max == 0)
|
||||
goto err;
|
||||
} else {
|
||||
@@ -141,9 +143,10 @@ static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
|
||||
}
|
||||
if (ret > LONG_MAX)
|
||||
return 0;
|
||||
} else
|
||||
} else {
|
||||
ret = i;
|
||||
}
|
||||
}
|
||||
*pp = p;
|
||||
*rl = (long)ret;
|
||||
return 1;
|
||||
@@ -160,9 +163,9 @@ void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
|
||||
|
||||
i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
|
||||
i |= (xclass & V_ASN1_PRIVATE);
|
||||
if (tag < 31)
|
||||
if (tag < 31) {
|
||||
*(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
|
||||
else {
|
||||
} else {
|
||||
*(p++) = i | V_ASN1_PRIMITIVE_TAG;
|
||||
for (i = 0, ttag = tag; ttag > 0; i++)
|
||||
ttag >>= 7;
|
||||
@@ -185,6 +188,7 @@ void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
|
||||
int ASN1_put_eoc(unsigned char **pp)
|
||||
{
|
||||
unsigned char *p = *pp;
|
||||
|
||||
*p++ = 0;
|
||||
*p++ = 0;
|
||||
*pp = p;
|
||||
@@ -194,20 +198,21 @@ int ASN1_put_eoc(unsigned char **pp)
|
||||
static void asn1_put_length(unsigned char **pp, int length)
|
||||
{
|
||||
unsigned char *p = *pp;
|
||||
int i, l;
|
||||
if (length <= 127)
|
||||
int i, len;
|
||||
|
||||
if (length <= 127) {
|
||||
*(p++) = (unsigned char)length;
|
||||
else {
|
||||
l = length;
|
||||
for (i = 0; l > 0; i++)
|
||||
l >>= 8;
|
||||
} else {
|
||||
len = length;
|
||||
for (i = 0; len > 0; i++)
|
||||
len >>= 8;
|
||||
*(p++) = i | 0x80;
|
||||
l = i;
|
||||
len = i;
|
||||
while (i-- > 0) {
|
||||
p[i] = length & 0xff;
|
||||
length >>= 8;
|
||||
}
|
||||
p += l;
|
||||
p += len;
|
||||
}
|
||||
*pp = p;
|
||||
}
|
||||
@@ -215,6 +220,7 @@ static void asn1_put_length(unsigned char **pp, int length)
|
||||
int ASN1_object_size(int constructed, int length, int tag)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
if (length < 0)
|
||||
return -1;
|
||||
if (tag >= 31) {
|
||||
@@ -256,6 +262,7 @@ int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
|
||||
ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
|
||||
{
|
||||
ASN1_STRING *ret;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
ret = ASN1_STRING_new();
|
||||
@@ -268,18 +275,29 @@ ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
|
||||
int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in)
|
||||
{
|
||||
unsigned char *c;
|
||||
const char *data = _data;
|
||||
size_t len;
|
||||
|
||||
if (len < 0) {
|
||||
if (len_in < 0) {
|
||||
if (data == NULL)
|
||||
return 0;
|
||||
else
|
||||
len = strlen(data);
|
||||
} else {
|
||||
len = (size_t)len_in;
|
||||
}
|
||||
if ((str->length <= len) || (str->data == NULL)) {
|
||||
/*
|
||||
* Verify that the length fits within an integer for assignment to
|
||||
* str->length below. The additional 1 is subtracted to allow for the
|
||||
* '\0' terminator even though this isn't strictly necessary.
|
||||
*/
|
||||
if (len > INT_MAX - 1) {
|
||||
ASN1err(0, ASN1_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
if ((size_t)str->length <= len || str->data == NULL) {
|
||||
c = str->data;
|
||||
str->data = OPENSSL_realloc(c, len + 1);
|
||||
if (str->data == NULL) {
|
||||
@@ -359,8 +377,9 @@ int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
|
||||
return a->type - b->type;
|
||||
else
|
||||
return i;
|
||||
} else
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
int ASN1_STRING_length(const ASN1_STRING *x)
|
||||
@@ -383,9 +402,48 @@ const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x)
|
||||
return x->data;
|
||||
}
|
||||
|
||||
# ifndef OPENSSL_NO_DEPRECATED_1_1_0
|
||||
#ifndef OPENSSL_NO_DEPRECATED_1_1_0
|
||||
unsigned char *ASN1_STRING_data(ASN1_STRING *x)
|
||||
{
|
||||
return x->data;
|
||||
}
|
||||
#endif
|
||||
|
||||
char *sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text, const char *sep,
|
||||
size_t max_len /* excluding NUL terminator */)
|
||||
{
|
||||
int i;
|
||||
ASN1_UTF8STRING *current;
|
||||
size_t length = 0, sep_len;
|
||||
char *result = NULL;
|
||||
char *p;
|
||||
|
||||
if (!ossl_assert(sep != NULL))
|
||||
return NULL;
|
||||
sep_len = strlen(sep);
|
||||
|
||||
for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) {
|
||||
current = sk_ASN1_UTF8STRING_value(text, i);
|
||||
if (i > 0)
|
||||
length += sep_len;
|
||||
length += ASN1_STRING_length(current);
|
||||
if (length > max_len)
|
||||
return NULL;
|
||||
}
|
||||
if ((result = OPENSSL_malloc(length + 1)) == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i) {
|
||||
current = sk_ASN1_UTF8STRING_value(text, i);
|
||||
length = ASN1_STRING_length(current);
|
||||
if (i > 0 && sep_len > 0) {
|
||||
strncpy(p, sep, sep_len + 1);
|
||||
p += sep_len;
|
||||
}
|
||||
strncpy(p, (const char *)ASN1_STRING_get0_data(current), length);
|
||||
p += length;
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -11,7 +11,15 @@ IF[{- !$disabled{asm} -}]
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
SOURCE[../../libcrypto]=bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c $BFASM
|
||||
$ALL=bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c $BFASM
|
||||
|
||||
SOURCE[../../libcrypto]=$ALL
|
||||
|
||||
# When all deprecated symbols are removed, libcrypto doesn't export the
|
||||
# blowfish functions, so we must include them directly in liblegacy.a
|
||||
IF[{- $disabled{'deprecated-3.0'} -}]
|
||||
SOURCE[../../providers/liblegacy.a]=$ALL
|
||||
ENDIF
|
||||
|
||||
GENERATE[bf-586.s]=asm/bf-586.pl
|
||||
DEPEND[bf-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "bio_local.h"
|
||||
#include "internal/ktls.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
@@ -51,6 +52,17 @@ int BIO_socket(int domain, int socktype, int protocol, int options)
|
||||
BIOerr(BIO_F_BIO_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
{
|
||||
/*
|
||||
* The new socket is created successfully regardless of ktls_enable.
|
||||
* ktls_enable doesn't change any functionality of the socket, except
|
||||
* changing the setsockopt to enable the processing of ktls_start.
|
||||
* Thus, it is not a problem to call it for non-TLS sockets.
|
||||
*/
|
||||
ktls_enable(sock);
|
||||
}
|
||||
# endif
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
@@ -750,7 +750,7 @@ int BIO_set_ex_data(BIO *bio, int idx, void *data)
|
||||
return CRYPTO_set_ex_data(&(bio->ex_data), idx, data);
|
||||
}
|
||||
|
||||
void *BIO_get_ex_data(BIO *bio, int idx)
|
||||
void *BIO_get_ex_data(const BIO *bio, int idx)
|
||||
{
|
||||
return CRYPTO_get_ex_data(&(bio->ex_data), idx);
|
||||
}
|
||||
|
||||
@@ -222,19 +222,20 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
|
||||
break;
|
||||
|
||||
case ACPT_S_CREATE_SOCKET:
|
||||
ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
|
||||
s = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
|
||||
BIO_ADDRINFO_socktype(c->addr_iter),
|
||||
BIO_ADDRINFO_protocol(c->addr_iter), 0);
|
||||
if (ret == (int)INVALID_SOCKET) {
|
||||
if (s == (int)INVALID_SOCKET) {
|
||||
ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
|
||||
"calling socket(%s, %s)",
|
||||
c->param_addr, c->param_serv);
|
||||
BIOerr(BIO_F_ACPT_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
|
||||
goto exit_loop;
|
||||
}
|
||||
c->accept_sock = ret;
|
||||
b->num = ret;
|
||||
c->accept_sock = s;
|
||||
b->num = s;
|
||||
c->state = ACPT_S_LISTEN;
|
||||
s = -1;
|
||||
break;
|
||||
|
||||
case ACPT_S_LISTEN:
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "bio_local.h"
|
||||
#include "internal/ktls.h"
|
||||
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
|
||||
@@ -20,6 +21,9 @@ typedef struct bio_connect_st {
|
||||
char *param_hostname;
|
||||
char *param_service;
|
||||
int connect_mode;
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
unsigned char record_type;
|
||||
# endif
|
||||
|
||||
BIO_ADDRINFO *addr_first;
|
||||
const BIO_ADDRINFO *addr_iter;
|
||||
@@ -308,6 +312,11 @@ static int conn_read(BIO *b, char *out, int outl)
|
||||
|
||||
if (out != NULL) {
|
||||
clear_socket_error();
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
if (BIO_get_ktls_recv(b))
|
||||
ret = ktls_read_record(b->num, out, outl);
|
||||
else
|
||||
# endif
|
||||
ret = readsocket(b->num, out, outl);
|
||||
BIO_clear_retry_flags(b);
|
||||
if (ret <= 0) {
|
||||
@@ -333,6 +342,15 @@ static int conn_write(BIO *b, const char *in, int inl)
|
||||
}
|
||||
|
||||
clear_socket_error();
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
if (BIO_should_ktls_ctrl_msg_flag(b)) {
|
||||
ret = ktls_send_ctrl_message(b->num, data->record_type, in, inl);
|
||||
if (ret >= 0) {
|
||||
ret = inl;
|
||||
BIO_clear_ktls_ctrl_msg_flag(b);
|
||||
}
|
||||
} else
|
||||
# endif
|
||||
ret = writesocket(b->num, in, inl);
|
||||
BIO_clear_retry_flags(b);
|
||||
if (ret <= 0) {
|
||||
@@ -349,6 +367,13 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
const char **pptr = NULL;
|
||||
long ret = 1;
|
||||
BIO_CONNECT *data;
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
# ifdef __FreeBSD__
|
||||
struct tls_enable *crypto_info;
|
||||
# else
|
||||
struct tls12_crypto_info_aes_gcm_128 *crypto_info;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
data = (BIO_CONNECT *)b->ptr;
|
||||
|
||||
@@ -497,6 +522,31 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
case BIO_CTRL_EOF:
|
||||
ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
|
||||
break;
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
case BIO_CTRL_SET_KTLS:
|
||||
# ifdef __FreeBSD__
|
||||
crypto_info = (struct tls_enable *)ptr;
|
||||
# else
|
||||
crypto_info = (struct tls12_crypto_info_aes_gcm_128 *)ptr;
|
||||
# endif
|
||||
ret = ktls_start(b->num, crypto_info, sizeof(*crypto_info), num);
|
||||
if (ret)
|
||||
BIO_set_ktls_flag(b, num);
|
||||
break;
|
||||
case BIO_CTRL_GET_KTLS_SEND:
|
||||
return BIO_should_ktls_flag(b, 1);
|
||||
case BIO_CTRL_GET_KTLS_RECV:
|
||||
return BIO_should_ktls_flag(b, 0);
|
||||
case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG:
|
||||
BIO_set_ktls_ctrl_msg_flag(b);
|
||||
data->record_type = num;
|
||||
ret = 0;
|
||||
break;
|
||||
case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG:
|
||||
BIO_clear_ktls_ctrl_msg_flag(b);
|
||||
ret = 0;
|
||||
break;
|
||||
# endif
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
+4
-1
@@ -70,7 +70,8 @@ SOURCE[../providers/libfips.a]=$CORE_COMMON
|
||||
$UTIL_COMMON=\
|
||||
cryptlib.c params.c params_from_text.c bsearch.c ex_data.c o_str.c \
|
||||
ctype.c threads_pthread.c threads_win.c threads_none.c initthread.c \
|
||||
context.c sparse_array.c asn1_dsa.c packet.c param_build.c $CPUIDASM
|
||||
context.c sparse_array.c asn1_dsa.c packet.c param_build.c $CPUIDASM \
|
||||
param_build_set.c der_writer.c
|
||||
$UTIL_DEFINE=$CPUIDDEF
|
||||
|
||||
SOURCE[../libcrypto]=$UTIL_COMMON \
|
||||
@@ -79,6 +80,7 @@ SOURCE[../libcrypto]=$UTIL_COMMON \
|
||||
o_fopen.c getenv.c o_init.c o_fips.c init.c trace.c provider.c \
|
||||
$UPLINKSRC
|
||||
SOURCE[../providers/libfips.a]=$UTIL_COMMON
|
||||
SOURCE[../providers/liblegacy.a]=$UTIL_COMMON
|
||||
|
||||
# Implementations are now spread across several libraries, so the defines
|
||||
# need to be applied to all affected libraries and modules.
|
||||
@@ -86,6 +88,7 @@ DEFINE[../libcrypto]=$UTIL_DEFINE $UPLINKDEF
|
||||
DEFINE[../providers/libfips.a]=$UTIL_DEFINE
|
||||
DEFINE[../providers/fips]=$UTIL_DEFINE
|
||||
DEFINE[../providers/libimplementations.a]=$UTIL_DEFINE
|
||||
DEFINE[../providers/liblegacy.a]=$UTIL_DEFINE
|
||||
DEFINE[../providers/libcommon.a]=$UTIL_DEFINE
|
||||
|
||||
DEPEND[info.o]=buildinf.h
|
||||
|
||||
@@ -12,7 +12,15 @@ IF[{- !$disabled{asm} && !$disabled{pic} -}]
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
SOURCE[../../libcrypto]=c_skey.c c_ecb.c $CASTASM c_cfb64.c c_ofb64.c
|
||||
$ALL=c_skey.c c_ecb.c $CASTASM c_cfb64.c c_ofb64.c
|
||||
|
||||
SOURCE[../../libcrypto]=$ALL
|
||||
|
||||
# When all deprecated symbols are removed, libcrypto doesn't export the
|
||||
# cast functions, so we must include them directly in liblegacy.a
|
||||
IF[{- $disabled{'deprecated-3.0'} -}]
|
||||
SOURCE[../../providers/liblegacy.a]=$ALL
|
||||
ENDIF
|
||||
|
||||
GENERATE[cast-586.s]=asm/cast-586.pl
|
||||
DEPEND[cast-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl
|
||||
@@ -1,3 +1,4 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]= cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c \
|
||||
cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c
|
||||
cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c \
|
||||
cmp_server.c cmp_client.c cmp_http.c
|
||||
@@ -0,0 +1,881 @@
|
||||
/*
|
||||
* Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright Nokia 2007-2019
|
||||
* Copyright Siemens AG 2015-2019
|
||||
*
|
||||
* 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 "cmp_local.h"
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
/* explicit #includes not strictly needed since implied by the above: */
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/cmp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "openssl/cmp_util.h"
|
||||
|
||||
#define IS_CREP(t) ((t) == OSSL_CMP_PKIBODY_IP || (t) == OSSL_CMP_PKIBODY_CP \
|
||||
|| (t) == OSSL_CMP_PKIBODY_KUP)
|
||||
|
||||
/*-
|
||||
* Evaluate whether there's an exception (violating the standard) configured for
|
||||
* handling negative responses without protection or with invalid protection.
|
||||
* Returns 1 on acceptance, 0 on rejection, or -1 on (internal) error.
|
||||
*/
|
||||
static int unprotected_exception(const OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *rep,
|
||||
int invalid_protection,
|
||||
int expected_type /* ignored here */)
|
||||
{
|
||||
int rcvd_type = ossl_cmp_msg_get_bodytype(rep /* may be NULL */);
|
||||
const char *msg_type = NULL;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && rep != NULL))
|
||||
return -1;
|
||||
|
||||
if (!ctx->unprotectedErrors)
|
||||
return 0;
|
||||
|
||||
switch (rcvd_type) {
|
||||
case OSSL_CMP_PKIBODY_ERROR:
|
||||
msg_type = "error response";
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_RP:
|
||||
{
|
||||
OSSL_CMP_PKISI *si =
|
||||
ossl_cmp_revrepcontent_get_pkisi(rep->body->value.rp,
|
||||
OSSL_CMP_REVREQSID);
|
||||
|
||||
if (si == NULL)
|
||||
return -1;
|
||||
if (ossl_cmp_pkisi_get_status(si) == OSSL_CMP_PKISTATUS_rejection)
|
||||
msg_type = "revocation response message with rejection status";
|
||||
break;
|
||||
}
|
||||
case OSSL_CMP_PKIBODY_PKICONF:
|
||||
msg_type = "PKI Confirmation message";
|
||||
break;
|
||||
default:
|
||||
if (IS_CREP(rcvd_type)) {
|
||||
OSSL_CMP_CERTREPMESSAGE *crepmsg = rep->body->value.ip;
|
||||
OSSL_CMP_CERTRESPONSE *crep =
|
||||
ossl_cmp_certrepmessage_get0_certresponse(crepmsg,
|
||||
-1 /* any rid */);
|
||||
|
||||
if (sk_OSSL_CMP_CERTRESPONSE_num(crepmsg->response) > 1)
|
||||
return -1;
|
||||
/* TODO: handle potentially multiple CertResponses in CertRepMsg */
|
||||
if (crep == NULL)
|
||||
return -1;
|
||||
if (ossl_cmp_pkisi_get_status(crep->status)
|
||||
== OSSL_CMP_PKISTATUS_rejection)
|
||||
msg_type = "CertRepMessage with rejection status";
|
||||
}
|
||||
}
|
||||
if (msg_type == NULL)
|
||||
return 0;
|
||||
ossl_cmp_log2(WARN, ctx, "ignoring %s protection of %s",
|
||||
invalid_protection ? "invalid" : "missing", msg_type);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Save error info from PKIStatusInfo field of a certresponse into ctx */
|
||||
static int save_statusInfo(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si)
|
||||
{
|
||||
int i;
|
||||
OSSL_CMP_PKIFREETEXT *ss;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && si != NULL))
|
||||
return 0;
|
||||
|
||||
if ((ctx->status = ossl_cmp_pkisi_get_status(si)) < 0)
|
||||
return 0;
|
||||
|
||||
ctx->failInfoCode = 0;
|
||||
if (si->failInfo != NULL) {
|
||||
for (i = 0; i <= OSSL_CMP_PKIFAILUREINFO_MAX; i++) {
|
||||
if (ASN1_BIT_STRING_get_bit(si->failInfo, i))
|
||||
ctx->failInfoCode |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ossl_cmp_ctx_set0_statusString(ctx, sk_ASN1_UTF8STRING_new_null())
|
||||
|| (ctx->statusString == NULL))
|
||||
return 0;
|
||||
|
||||
ss = si->statusString; /* may be NULL */
|
||||
for (i = 0; i < sk_ASN1_UTF8STRING_num(ss); i++) {
|
||||
ASN1_UTF8STRING *str = sk_ASN1_UTF8STRING_value(ss, i);
|
||||
|
||||
if (!sk_ASN1_UTF8STRING_push(ctx->statusString, ASN1_STRING_dup(str)))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Perform the generic aspects of sending a request and receiving a response.
|
||||
* Returns 1 on success and provides the received PKIMESSAGE in *rep.
|
||||
* Returns 0 on error.
|
||||
* Regardless of success, caller is responsible for freeing *rep (unless NULL).
|
||||
*/
|
||||
static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
|
||||
OSSL_CMP_MSG **rep, int expected_type)
|
||||
{
|
||||
const char *req_type_str =
|
||||
ossl_cmp_bodytype_to_string(ossl_cmp_msg_get_bodytype(req));
|
||||
const char *expected_type_str = ossl_cmp_bodytype_to_string(expected_type);
|
||||
int msg_timeout;
|
||||
int bt;
|
||||
time_t now = time(NULL);
|
||||
int time_left;
|
||||
OSSL_CMP_transfer_cb_t transfer_cb = ctx->transfer_cb;
|
||||
|
||||
if (transfer_cb == NULL)
|
||||
transfer_cb = OSSL_CMP_MSG_http_perform;
|
||||
|
||||
*rep = NULL;
|
||||
msg_timeout = ctx->msg_timeout; /* backup original value */
|
||||
if ((IS_CREP(expected_type) || expected_type == OSSL_CMP_PKIBODY_POLLREP)
|
||||
&& ctx->total_timeout > 0 /* timeout is not infinite */) {
|
||||
if (now >= ctx->end_time) {
|
||||
CMPerr(0, CMP_R_TOTAL_TIMEOUT);
|
||||
return 0;
|
||||
}
|
||||
if (!ossl_assert(ctx->end_time - time(NULL) < INT_MAX)) {
|
||||
/* cannot really happen due to the assignment in do_certreq_seq() */
|
||||
CMPerr(0, CMP_R_INVALID_ARGS);
|
||||
return 0;
|
||||
}
|
||||
time_left = (int)(ctx->end_time - now);
|
||||
if (ctx->msg_timeout == 0 || time_left < ctx->msg_timeout)
|
||||
ctx->msg_timeout = time_left;
|
||||
}
|
||||
|
||||
/* should print error queue since transfer_cb may call ERR_clear_error() */
|
||||
OSSL_CMP_CTX_print_errors(ctx);
|
||||
|
||||
ossl_cmp_log1(INFO, ctx, "sending %s", req_type_str);
|
||||
|
||||
*rep = (*transfer_cb)(ctx, req);
|
||||
ctx->msg_timeout = msg_timeout; /* restore original value */
|
||||
|
||||
if (*rep == NULL) {
|
||||
CMPerr(0, CMP_R_TRANSFER_ERROR); /* or receiving response */
|
||||
ERR_add_error_data(1, req_type_str);
|
||||
ERR_add_error_data(2, ", expected response: ", expected_type_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bt = ossl_cmp_msg_get_bodytype(*rep);
|
||||
/*
|
||||
* The body type in the 'bt' variable is not yet verified.
|
||||
* Still we use this preliminary value already for a progress report because
|
||||
* the following msg verification may also produce log entries and may fail.
|
||||
*/
|
||||
ossl_cmp_log1(INFO, ctx, "received %s", ossl_cmp_bodytype_to_string(bt));
|
||||
|
||||
if ((bt = ossl_cmp_msg_check_received(ctx, *rep, unprotected_exception,
|
||||
expected_type)) < 0)
|
||||
return 0;
|
||||
|
||||
if (bt == expected_type
|
||||
/* as an answer to polling, there could be IP/CP/KUP: */
|
||||
|| (IS_CREP(bt) && expected_type == OSSL_CMP_PKIBODY_POLLREP))
|
||||
return 1;
|
||||
|
||||
/* received message type is not one of the expected ones (e.g., error) */
|
||||
CMPerr(0, bt == OSSL_CMP_PKIBODY_ERROR ? CMP_R_RECEIVED_ERROR :
|
||||
CMP_R_UNEXPECTED_PKIBODY); /* in next line for mkerr.pl */
|
||||
|
||||
if (bt != OSSL_CMP_PKIBODY_ERROR) {
|
||||
ERR_add_error_data(3, "message type is '",
|
||||
ossl_cmp_bodytype_to_string(bt), "'");
|
||||
} else {
|
||||
OSSL_CMP_ERRORMSGCONTENT *emc = (*rep)->body->value.error;
|
||||
OSSL_CMP_PKISI *si = emc->pKIStatusInfo;
|
||||
char buf[OSSL_CMP_PKISI_BUFLEN];
|
||||
|
||||
if (save_statusInfo(ctx, si)
|
||||
&& OSSL_CMP_CTX_snprint_PKIStatus(ctx, buf, sizeof(buf)) != NULL)
|
||||
ERR_add_error_data(1, buf);
|
||||
if (emc->errorCode != NULL
|
||||
&& BIO_snprintf(buf, sizeof(buf), "; errorCode: %ld",
|
||||
ASN1_INTEGER_get(emc->errorCode)) > 0)
|
||||
ERR_add_error_data(1, buf);
|
||||
if (emc->errorDetails != NULL) {
|
||||
char *text = sk_ASN1_UTF8STRING2text(emc->errorDetails, ", ",
|
||||
OSSL_CMP_PKISI_BUFLEN - 1);
|
||||
|
||||
if (text != NULL)
|
||||
ERR_add_error_data(2, "; errorDetails: ", text);
|
||||
OPENSSL_free(text);
|
||||
}
|
||||
if (ctx->status != OSSL_CMP_PKISTATUS_rejection) {
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKISTATUS);
|
||||
if (ctx->status == OSSL_CMP_PKISTATUS_waiting)
|
||||
ctx->status = OSSL_CMP_PKISTATUS_rejection;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-
|
||||
* When a 'waiting' PKIStatus has been received, this function is used to
|
||||
* poll, which should yield a pollRep or finally a CertRepMessage in ip/cp/kup.
|
||||
* On receiving a pollRep, which includes a checkAfter value, it return this
|
||||
* value if sleep == 0, else it sleeps as long as indicated and retries.
|
||||
*
|
||||
* A transaction timeout is enabled if ctx->total_timeout is > 0.
|
||||
* In this case polling will continue until the timeout is reached and then
|
||||
* polling is done a last time even if this is before the "checkAfter" time.
|
||||
*
|
||||
* Returns -1 on receiving pollRep if sleep == 0, setting the checkAfter value.
|
||||
* Returns 1 on success and provides the received PKIMESSAGE in *rep.
|
||||
* In this case the caller is responsible for freeing *rep.
|
||||
* Returns 0 on error (which includes the case that timeout has been reached).
|
||||
*/
|
||||
static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
|
||||
OSSL_CMP_MSG **rep, int *checkAfter)
|
||||
{
|
||||
OSSL_CMP_MSG *preq = NULL;
|
||||
OSSL_CMP_MSG *prep = NULL;
|
||||
|
||||
ossl_cmp_info(ctx,
|
||||
"received 'waiting' PKIStatus, starting to poll for response");
|
||||
*rep = NULL;
|
||||
for (;;) {
|
||||
/* TODO: handle potentially multiple poll requests per message */
|
||||
if ((preq = ossl_cmp_pollReq_new(ctx, rid)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!send_receive_check(ctx, preq, &prep, OSSL_CMP_PKIBODY_POLLREP))
|
||||
goto err;
|
||||
|
||||
/* handle potential pollRep */
|
||||
if (ossl_cmp_msg_get_bodytype(prep) == OSSL_CMP_PKIBODY_POLLREP) {
|
||||
OSSL_CMP_POLLREPCONTENT *prc = prep->body->value.pollRep;
|
||||
OSSL_CMP_POLLREP *pollRep = NULL;
|
||||
int64_t check_after;
|
||||
char str[OSSL_CMP_PKISI_BUFLEN];
|
||||
int len;
|
||||
|
||||
/* TODO: handle potentially multiple elements in pollRep */
|
||||
if (sk_OSSL_CMP_POLLREP_num(prc) > 1) {
|
||||
CMPerr(0, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED);
|
||||
goto err;
|
||||
}
|
||||
pollRep = ossl_cmp_pollrepcontent_get0_pollrep(prc, rid);
|
||||
if (pollRep == NULL)
|
||||
goto err;
|
||||
|
||||
if (!ASN1_INTEGER_get_int64(&check_after, pollRep->checkAfter)) {
|
||||
CMPerr(0, CMP_R_BAD_CHECKAFTER_IN_POLLREP);
|
||||
goto err;
|
||||
}
|
||||
if (check_after < 0 || (uint64_t)check_after
|
||||
> (sleep ? ULONG_MAX / 1000 : INT_MAX)) {
|
||||
CMPerr(0, CMP_R_CHECKAFTER_OUT_OF_RANGE);
|
||||
if (BIO_snprintf(str, OSSL_CMP_PKISI_BUFLEN, "value = %jd",
|
||||
check_after) >= 0)
|
||||
ERR_add_error_data(1, str);
|
||||
goto err;
|
||||
}
|
||||
if (ctx->total_timeout > 0) { /* timeout is not infinite */
|
||||
const int exp = 5; /* expected max time per msg round trip */
|
||||
int64_t time_left = (int64_t)(ctx->end_time - exp - time(NULL));
|
||||
|
||||
if (time_left <= 0) {
|
||||
CMPerr(0, CMP_R_TOTAL_TIMEOUT);
|
||||
goto err;
|
||||
}
|
||||
if (time_left < check_after)
|
||||
check_after = time_left;
|
||||
/* poll one last time just when timeout was reached */
|
||||
}
|
||||
|
||||
if (pollRep->reason == NULL
|
||||
|| (len = BIO_snprintf(str, OSSL_CMP_PKISI_BUFLEN,
|
||||
" with reason = '")) < 0) {
|
||||
*str = '\0';
|
||||
} else {
|
||||
char *text = sk_ASN1_UTF8STRING2text(pollRep->reason, ", ",
|
||||
sizeof(str) - len - 2);
|
||||
|
||||
if (text == NULL
|
||||
|| BIO_snprintf(str + len, sizeof(str) - len,
|
||||
"%s'", text) < 0)
|
||||
*str = '\0';
|
||||
OPENSSL_free(text);
|
||||
}
|
||||
ossl_cmp_log2(INFO, ctx,
|
||||
"received polling response%s; checkAfter = %ld seconds",
|
||||
str, check_after);
|
||||
|
||||
OSSL_CMP_MSG_free(preq);
|
||||
preq = NULL;
|
||||
OSSL_CMP_MSG_free(prep);
|
||||
prep = NULL;
|
||||
if (sleep) {
|
||||
ossl_sleep((unsigned long)(1000 * check_after));
|
||||
} else {
|
||||
if (checkAfter != NULL)
|
||||
*checkAfter = (int)check_after;
|
||||
return -1; /* exits the loop */
|
||||
}
|
||||
} else {
|
||||
ossl_cmp_info(ctx, "received ip/cp/kup after polling");
|
||||
/* any other body type has been rejected by send_receive_check() */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (prep == NULL)
|
||||
goto err;
|
||||
|
||||
OSSL_CMP_MSG_free(preq);
|
||||
*rep = prep;
|
||||
|
||||
return 1;
|
||||
err:
|
||||
OSSL_CMP_MSG_free(preq);
|
||||
OSSL_CMP_MSG_free(prep);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Send certConf for IR, CR or KUR sequences and check response */
|
||||
int ossl_cmp_exchange_certConf(OSSL_CMP_CTX *ctx, int fail_info,
|
||||
const char *txt)
|
||||
{
|
||||
OSSL_CMP_MSG *certConf;
|
||||
OSSL_CMP_MSG *PKIconf = NULL;
|
||||
int res = 0;
|
||||
|
||||
/* OSSL_CMP_certConf_new() also checks if all necessary options are set */
|
||||
if ((certConf = ossl_cmp_certConf_new(ctx, fail_info, txt)) == NULL)
|
||||
goto err;
|
||||
|
||||
res = send_receive_check(ctx, certConf, &PKIconf, OSSL_CMP_PKIBODY_PKICONF);
|
||||
|
||||
err:
|
||||
OSSL_CMP_MSG_free(certConf);
|
||||
OSSL_CMP_MSG_free(PKIconf);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Send given error and check response */
|
||||
int ossl_cmp_exchange_error(OSSL_CMP_CTX *ctx, int status, int fail_info,
|
||||
const char *txt, int errorCode, const char *details)
|
||||
{
|
||||
OSSL_CMP_MSG *error = NULL;
|
||||
OSSL_CMP_PKISI *si = NULL;
|
||||
OSSL_CMP_MSG *PKIconf = NULL;
|
||||
int res = 0;
|
||||
|
||||
if ((si = OSSL_CMP_STATUSINFO_new(status, fail_info, txt)) == NULL)
|
||||
goto err;
|
||||
/* ossl_cmp_error_new() also checks if all necessary options are set */
|
||||
if ((error = ossl_cmp_error_new(ctx, si, errorCode, details, 0)) == NULL)
|
||||
goto err;
|
||||
|
||||
res = send_receive_check(ctx, error, &PKIconf, OSSL_CMP_PKIBODY_PKICONF);
|
||||
|
||||
err:
|
||||
OSSL_CMP_MSG_free(error);
|
||||
OSSL_CMP_PKISI_free(si);
|
||||
OSSL_CMP_MSG_free(PKIconf);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Retrieve a copy of the certificate, if any, from the given CertResponse.
|
||||
* Take into account PKIStatusInfo of CertResponse in ctx, report it on error.
|
||||
* Returns NULL if not found or on error.
|
||||
*/
|
||||
static X509 *get1_cert_status(OSSL_CMP_CTX *ctx, int bodytype,
|
||||
OSSL_CMP_CERTRESPONSE *crep)
|
||||
{
|
||||
char buf[OSSL_CMP_PKISI_BUFLEN];
|
||||
X509 *crt = NULL;
|
||||
EVP_PKEY *privkey;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && crep != NULL))
|
||||
return NULL;
|
||||
|
||||
privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
|
||||
switch (ossl_cmp_pkisi_get_status(crep->status)) {
|
||||
case OSSL_CMP_PKISTATUS_waiting:
|
||||
ossl_cmp_err(ctx,
|
||||
"received \"waiting\" status for cert when actually aiming to extract cert");
|
||||
CMPerr(0, CMP_R_ENCOUNTERED_WAITING);
|
||||
goto err;
|
||||
case OSSL_CMP_PKISTATUS_grantedWithMods:
|
||||
ossl_cmp_warn(ctx, "received \"grantedWithMods\" for certificate");
|
||||
crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
|
||||
break;
|
||||
case OSSL_CMP_PKISTATUS_accepted:
|
||||
crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
|
||||
break;
|
||||
/* get all information in case of a rejection before going to error */
|
||||
case OSSL_CMP_PKISTATUS_rejection:
|
||||
ossl_cmp_err(ctx, "received \"rejection\" status rather than cert");
|
||||
CMPerr(0, CMP_R_REQUEST_REJECTED_BY_SERVER);
|
||||
goto err;
|
||||
case OSSL_CMP_PKISTATUS_revocationWarning:
|
||||
ossl_cmp_warn(ctx,
|
||||
"received \"revocationWarning\" - a revocation of the cert is imminent");
|
||||
crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
|
||||
break;
|
||||
case OSSL_CMP_PKISTATUS_revocationNotification:
|
||||
ossl_cmp_warn(ctx,
|
||||
"received \"revocationNotification\" - a revocation of the cert has occurred");
|
||||
crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
|
||||
break;
|
||||
case OSSL_CMP_PKISTATUS_keyUpdateWarning:
|
||||
if (bodytype != OSSL_CMP_PKIBODY_KUR) {
|
||||
CMPerr(0, CMP_R_ENCOUNTERED_KEYUPDATEWARNING);
|
||||
goto err;
|
||||
}
|
||||
crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
|
||||
break;
|
||||
default:
|
||||
ossl_cmp_log1(ERROR, ctx,
|
||||
"received unsupported PKIStatus %d for certificate",
|
||||
ctx->status);
|
||||
CMPerr(0, CMP_R_UNKNOWN_PKISTATUS);
|
||||
goto err;
|
||||
}
|
||||
if (crt == NULL) /* according to PKIStatus, we can expect a cert */
|
||||
CMPerr(0, CMP_R_CERTIFICATE_NOT_FOUND);
|
||||
|
||||
return crt;
|
||||
|
||||
err:
|
||||
if (OSSL_CMP_CTX_snprint_PKIStatus(ctx, buf, sizeof(buf)) != NULL)
|
||||
ERR_add_error_data(1, buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Callback fn validating that the new certificate can be verified, using
|
||||
* ctx->certConf_cb_arg, which has been initialized using opt_out_trusted, and
|
||||
* ctx->untrusted_certs, which at this point already contains ctx->extraCertsIn.
|
||||
* Returns 0 on acceptance, else a bit field reflecting PKIFailureInfo.
|
||||
* Quoting from RFC 4210 section 5.1. Overall PKI Message:
|
||||
* The extraCerts field can contain certificates that may be useful to
|
||||
* the recipient. For example, this can be used by a CA or RA to
|
||||
* present an end entity with certificates that it needs to verify its
|
||||
* own new certificate (if, for example, the CA that issued the end
|
||||
* entity's certificate is not a root CA for the end entity). Note that
|
||||
* this field does not necessarily contain a certification path; the
|
||||
* recipient may have to sort, select from, or otherwise process the
|
||||
* extra certificates in order to use them.
|
||||
* Note: While often handy, there is no hard requirement by CMP that
|
||||
* an EE must be able to validate the certificates it gets enrolled.
|
||||
*/
|
||||
int OSSL_CMP_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info,
|
||||
const char **text)
|
||||
{
|
||||
X509_STORE *out_trusted = OSSL_CMP_CTX_get_certConf_cb_arg(ctx);
|
||||
(void)text; /* make (artificial) use of var to prevent compiler warning */
|
||||
|
||||
if (fail_info != 0) /* accept any error flagged by CMP core library */
|
||||
return fail_info;
|
||||
|
||||
if (out_trusted != NULL
|
||||
&& !OSSL_CMP_validate_cert_path(ctx, out_trusted, cert))
|
||||
fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_incorrectData;
|
||||
|
||||
return fail_info;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Perform the generic handling of certificate responses for IR/CR/KUR/P10CR.
|
||||
* Returns -1 on receiving pollRep if sleep == 0, setting the checkAfter value.
|
||||
* Returns 1 on success and provides the received PKIMESSAGE in *resp.
|
||||
* Returns 0 on error (which includes the case that timeout has been reached).
|
||||
* Regardless of success, caller is responsible for freeing *resp (unless NULL).
|
||||
*/
|
||||
static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
|
||||
OSSL_CMP_MSG **resp, int *checkAfter,
|
||||
int req_type, int expected_type)
|
||||
{
|
||||
EVP_PKEY *rkey = OSSL_CMP_CTX_get0_newPkey(ctx /* may be NULL */, 0);
|
||||
int fail_info = 0; /* no failure */
|
||||
const char *txt = NULL;
|
||||
OSSL_CMP_CERTREPMESSAGE *crepmsg;
|
||||
OSSL_CMP_CERTRESPONSE *crep;
|
||||
X509 *cert;
|
||||
char *subj = NULL;
|
||||
int ret = 1;
|
||||
|
||||
retry:
|
||||
crepmsg = (*resp)->body->value.ip; /* same for cp and kup */
|
||||
if (sk_OSSL_CMP_CERTRESPONSE_num(crepmsg->response) > 1) {
|
||||
CMPerr(0, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
/* TODO: handle potentially multiple CertResponses in CertRepMsg */
|
||||
crep = ossl_cmp_certrepmessage_get0_certresponse(crepmsg, rid);
|
||||
if (crep == NULL)
|
||||
return 0;
|
||||
if (!save_statusInfo(ctx, crep->status))
|
||||
return 0;
|
||||
if (rid == -1) {
|
||||
/* for OSSL_CMP_PKIBODY_P10CR learn CertReqId from response */
|
||||
rid = ossl_cmp_asn1_get_int(crep->certReqId);
|
||||
if (rid == -1) {
|
||||
CMPerr(0, CMP_R_BAD_REQUEST_ID);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ossl_cmp_pkisi_get_status(crep->status) == OSSL_CMP_PKISTATUS_waiting) {
|
||||
OSSL_CMP_MSG_free(*resp);
|
||||
*resp = NULL;
|
||||
if ((ret = poll_for_response(ctx, sleep, rid, resp, checkAfter)) != 0) {
|
||||
if (ret == -1) /* at this point implies sleep == 0 */
|
||||
return ret; /* waiting */
|
||||
goto retry; /* got ip/cp/kup, which may still indicate 'waiting' */
|
||||
} else {
|
||||
CMPerr(0, CMP_R_POLLING_FAILED);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
cert = get1_cert_status(ctx, (*resp)->body->type, crep);
|
||||
if (cert == NULL) {
|
||||
ERR_add_error_data(1, "; cannot extract certificate from response");
|
||||
return 0;
|
||||
}
|
||||
if (!ossl_cmp_ctx_set0_newCert(ctx, cert))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* if the CMP server returned certificates in the caPubs field, copy them
|
||||
* to the context so that they can be retrieved if necessary
|
||||
*/
|
||||
if (crepmsg->caPubs != NULL
|
||||
&& !ossl_cmp_ctx_set1_caPubs(ctx, crepmsg->caPubs))
|
||||
return 0;
|
||||
|
||||
/* copy received extraCerts to ctx->extraCertsIn so they can be retrieved */
|
||||
if (!ossl_cmp_ctx_set1_extraCertsIn(ctx, (*resp)->extraCerts))
|
||||
return 0;
|
||||
|
||||
subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
|
||||
if (rkey != NULL
|
||||
/* X509_check_private_key() also works if rkey is just public key */
|
||||
&& !(X509_check_private_key(ctx->newCert, rkey))) {
|
||||
fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_incorrectData;
|
||||
txt = "public key in new certificate does not match our enrollment key";
|
||||
/*-
|
||||
* not callling (void)ossl_cmp_exchange_error(ctx,
|
||||
* OSSL_CMP_PKISTATUS_rejection, fail_info, txt)
|
||||
* not throwing CMP_R_CERTIFICATE_NOT_ACCEPTED with txt
|
||||
* not returning 0
|
||||
* since we better leave this for any ctx->certConf_cb to decide
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute the certification checking callback function possibly set in ctx,
|
||||
* which can determine whether to accept a newly enrolled certificate.
|
||||
* It may overrule the pre-decision reflected in 'fail_info' and '*txt'.
|
||||
*/
|
||||
if (ctx->certConf_cb
|
||||
&& (fail_info = ctx->certConf_cb(ctx, ctx->newCert,
|
||||
fail_info, &txt)) != 0) {
|
||||
if (txt == NULL)
|
||||
txt = "CMP client application did not accept it";
|
||||
}
|
||||
if (fail_info != 0) /* immediately log error before any certConf exchange */
|
||||
ossl_cmp_log1(ERROR, ctx,
|
||||
"rejecting newly enrolled cert with subject: %s", subj);
|
||||
|
||||
/*
|
||||
* TODO: better move certConf exchange to do_certreq_seq() such that
|
||||
* also more low-level errors with CertReqMessages get reported to server
|
||||
*/
|
||||
if (!ctx->disableConfirm
|
||||
&& !ossl_cmp_hdr_has_implicitConfirm((*resp)->header)) {
|
||||
if (!ossl_cmp_exchange_certConf(ctx, fail_info, txt))
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
/* not throwing failure earlier as transfer_cb may call ERR_clear_error() */
|
||||
if (fail_info != 0) {
|
||||
CMPerr(0, CMP_R_CERTIFICATE_NOT_ACCEPTED);
|
||||
ERR_add_error_data(2, "rejecting newly enrolled cert with subject: ",
|
||||
subj);
|
||||
if (txt != NULL)
|
||||
ERR_add_error_txt("; ", txt);
|
||||
ret = 0;
|
||||
}
|
||||
OPENSSL_free(subj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int OSSL_CMP_try_certreq(OSSL_CMP_CTX *ctx, int req_type, int *checkAfter)
|
||||
{
|
||||
OSSL_CMP_MSG *req = NULL;
|
||||
OSSL_CMP_MSG *rep = NULL;
|
||||
int is_p10 = req_type == OSSL_CMP_PKIBODY_P10CR;
|
||||
int rid = is_p10 ? -1 : OSSL_CMP_CERTREQID;
|
||||
int rep_type = is_p10 ? OSSL_CMP_PKIBODY_CP : req_type + 1;
|
||||
int res = 0;
|
||||
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->status != OSSL_CMP_PKISTATUS_waiting) { /* not polling already */
|
||||
ctx->status = -1;
|
||||
if (!ossl_cmp_ctx_set0_newCert(ctx, NULL))
|
||||
return 0;
|
||||
|
||||
if (ctx->total_timeout > 0) /* else ctx->end_time is not used */
|
||||
ctx->end_time = time(NULL) + ctx->total_timeout;
|
||||
|
||||
req = ossl_cmp_certReq_new(ctx, req_type, 0 /* req_err */);
|
||||
if (req == NULL) /* also checks if all necessary options are set */
|
||||
return 0;
|
||||
|
||||
if (!send_receive_check(ctx, req, &rep, rep_type))
|
||||
goto err;
|
||||
} else {
|
||||
if (req_type < 0)
|
||||
return ossl_cmp_exchange_error(ctx, OSSL_CMP_PKISTATUS_rejection,
|
||||
0 /* TODO better fail_info value? */,
|
||||
"polling aborted", 0 /* errorCode */,
|
||||
"by application");
|
||||
res = poll_for_response(ctx, 0 /* no sleep */, rid, &rep, checkAfter);
|
||||
if (res <= 0) /* waiting or error */
|
||||
return res;
|
||||
}
|
||||
res = cert_response(ctx, 0 /* no sleep */, rid, &rep, checkAfter,
|
||||
req_type, rep_type);
|
||||
|
||||
err:
|
||||
OSSL_CMP_MSG_free(req);
|
||||
OSSL_CMP_MSG_free(rep);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Do the full sequence CR/IR/KUR/P10CR, CP/IP/KUP/CP,
|
||||
* certConf, PKIconf, and polling if required.
|
||||
* Will sleep as long as indicated by the server (according to checkAfter).
|
||||
* All enrollment options need to be present in the context.
|
||||
* TODO: another function to request two certificates at once should be created.
|
||||
* Returns pointer to received certificate, or NULL if none was received.
|
||||
*/
|
||||
static X509 *do_certreq_seq(OSSL_CMP_CTX *ctx, int req_type, int req_err,
|
||||
int rep_type)
|
||||
{
|
||||
OSSL_CMP_MSG *req = NULL;
|
||||
OSSL_CMP_MSG *rep = NULL;
|
||||
int rid = (req_type == OSSL_CMP_PKIBODY_P10CR) ? -1 : OSSL_CMP_CERTREQID;
|
||||
X509 *result = NULL;
|
||||
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
ctx->status = -1;
|
||||
if (!ossl_cmp_ctx_set0_newCert(ctx, NULL))
|
||||
return NULL;
|
||||
|
||||
if (ctx->total_timeout > 0) /* else ctx->end_time is not used */
|
||||
ctx->end_time = time(NULL) + ctx->total_timeout;
|
||||
|
||||
/* OSSL_CMP_certreq_new() also checks if all necessary options are set */
|
||||
if ((req = ossl_cmp_certReq_new(ctx, req_type, req_err)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!send_receive_check(ctx, req, &rep, rep_type))
|
||||
goto err;
|
||||
|
||||
if (cert_response(ctx, 1 /* sleep */, rid, &rep, NULL, req_type, rep_type)
|
||||
<= 0)
|
||||
goto err;
|
||||
|
||||
result = ctx->newCert;
|
||||
err:
|
||||
OSSL_CMP_MSG_free(req);
|
||||
OSSL_CMP_MSG_free(rep);
|
||||
return result;
|
||||
}
|
||||
|
||||
X509 *OSSL_CMP_exec_IR_ses(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
return do_certreq_seq(ctx, OSSL_CMP_PKIBODY_IR,
|
||||
CMP_R_ERROR_CREATING_IR, OSSL_CMP_PKIBODY_IP);
|
||||
}
|
||||
|
||||
X509 *OSSL_CMP_exec_CR_ses(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
return do_certreq_seq(ctx, OSSL_CMP_PKIBODY_CR,
|
||||
CMP_R_ERROR_CREATING_CR, OSSL_CMP_PKIBODY_CP);
|
||||
}
|
||||
|
||||
X509 *OSSL_CMP_exec_KUR_ses(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
return do_certreq_seq(ctx, OSSL_CMP_PKIBODY_KUR,
|
||||
CMP_R_ERROR_CREATING_KUR, OSSL_CMP_PKIBODY_KUP);
|
||||
}
|
||||
|
||||
X509 *OSSL_CMP_exec_P10CR_ses(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
return do_certreq_seq(ctx, OSSL_CMP_PKIBODY_P10CR,
|
||||
CMP_R_ERROR_CREATING_P10CR, OSSL_CMP_PKIBODY_CP);
|
||||
}
|
||||
|
||||
X509 *OSSL_CMP_exec_RR_ses(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
OSSL_CMP_MSG *rr = NULL;
|
||||
OSSL_CMP_MSG *rp = NULL;
|
||||
const int num_RevDetails = 1;
|
||||
const int rsid = OSSL_CMP_REVREQSID;
|
||||
OSSL_CMP_REVREPCONTENT *rrep = NULL;
|
||||
OSSL_CMP_PKISI *si = NULL;
|
||||
char buf[OSSL_CMP_PKISI_BUFLEN];
|
||||
X509 *result = NULL;
|
||||
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_INVALID_ARGS);
|
||||
return 0;
|
||||
}
|
||||
ctx->status = -1;
|
||||
|
||||
/* OSSL_CMP_rr_new() also checks if all necessary options are set */
|
||||
if ((rr = ossl_cmp_rr_new(ctx)) == NULL)
|
||||
goto end;
|
||||
|
||||
if (!send_receive_check(ctx, rr, &rp, OSSL_CMP_PKIBODY_RP))
|
||||
goto end;
|
||||
|
||||
rrep = rp->body->value.rp;
|
||||
if (sk_OSSL_CMP_PKISI_num(rrep->status) != num_RevDetails) {
|
||||
CMPerr(0, CMP_R_WRONG_RP_COMPONENT_COUNT);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* evaluate PKIStatus field */
|
||||
si = ossl_cmp_revrepcontent_get_pkisi(rrep, rsid);
|
||||
if (!save_statusInfo(ctx, si))
|
||||
goto err;
|
||||
switch (ossl_cmp_pkisi_get_status(si)) {
|
||||
case OSSL_CMP_PKISTATUS_accepted:
|
||||
ossl_cmp_info(ctx, "revocation accepted (PKIStatus=accepted)");
|
||||
result = ctx->oldCert;
|
||||
break;
|
||||
case OSSL_CMP_PKISTATUS_grantedWithMods:
|
||||
ossl_cmp_info(ctx, "revocation accepted (PKIStatus=grantedWithMods)");
|
||||
result = ctx->oldCert;
|
||||
break;
|
||||
case OSSL_CMP_PKISTATUS_rejection:
|
||||
CMPerr(0, CMP_R_REQUEST_REJECTED_BY_SERVER);
|
||||
goto err;
|
||||
case OSSL_CMP_PKISTATUS_revocationWarning:
|
||||
ossl_cmp_info(ctx, "revocation accepted (PKIStatus=revocationWarning)");
|
||||
result = ctx->oldCert;
|
||||
break;
|
||||
case OSSL_CMP_PKISTATUS_revocationNotification:
|
||||
/* interpretation as warning or error depends on CA */
|
||||
ossl_cmp_warn(ctx,
|
||||
"revocation accepted (PKIStatus=revocationNotification)");
|
||||
result = ctx->oldCert;
|
||||
break;
|
||||
case OSSL_CMP_PKISTATUS_waiting:
|
||||
case OSSL_CMP_PKISTATUS_keyUpdateWarning:
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKISTATUS);
|
||||
goto err;
|
||||
default:
|
||||
CMPerr(0, CMP_R_UNKNOWN_PKISTATUS);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* check any present CertId in optional revCerts field */
|
||||
if (rrep->revCerts != NULL) {
|
||||
OSSL_CRMF_CERTID *cid;
|
||||
OSSL_CRMF_CERTTEMPLATE *tmpl =
|
||||
sk_OSSL_CMP_REVDETAILS_value(rr->body->value.rr, rsid)->certDetails;
|
||||
const X509_NAME *issuer = OSSL_CRMF_CERTTEMPLATE_get0_issuer(tmpl);
|
||||
ASN1_INTEGER *serial = OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(tmpl);
|
||||
|
||||
if (sk_OSSL_CRMF_CERTID_num(rrep->revCerts) != num_RevDetails) {
|
||||
CMPerr(0, CMP_R_WRONG_RP_COMPONENT_COUNT);
|
||||
result = NULL;
|
||||
goto err;
|
||||
}
|
||||
if ((cid = ossl_cmp_revrepcontent_get_CertId(rrep, rsid)) == NULL) {
|
||||
result = NULL;
|
||||
goto err;
|
||||
}
|
||||
if (X509_NAME_cmp(issuer, OSSL_CRMF_CERTID_get0_issuer(cid)) != 0) {
|
||||
CMPerr(0, CMP_R_WRONG_CERTID_IN_RP);
|
||||
result = NULL;
|
||||
goto err;
|
||||
}
|
||||
if (ASN1_INTEGER_cmp(serial,
|
||||
OSSL_CRMF_CERTID_get0_serialNumber(cid)) != 0) {
|
||||
CMPerr(0, CMP_R_WRONG_SERIAL_IN_RP);
|
||||
result = NULL;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* check number of any optionally present crls */
|
||||
if (rrep->crls != NULL && sk_X509_CRL_num(rrep->crls) != num_RevDetails) {
|
||||
CMPerr(0, CMP_R_WRONG_RP_COMPONENT_COUNT);
|
||||
result = NULL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
err:
|
||||
if (result == NULL
|
||||
&& OSSL_CMP_CTX_snprint_PKIStatus(ctx, buf, sizeof(buf)) != NULL)
|
||||
ERR_add_error_data(1, buf);
|
||||
|
||||
end:
|
||||
OSSL_CMP_MSG_free(rr);
|
||||
OSSL_CMP_MSG_free(rp);
|
||||
return result;
|
||||
}
|
||||
|
||||
STACK_OF(OSSL_CMP_ITAV) *OSSL_CMP_exec_GENM_ses(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
OSSL_CMP_MSG *genm;
|
||||
OSSL_CMP_MSG *genp = NULL;
|
||||
STACK_OF(OSSL_CMP_ITAV) *rcvd_itavs = NULL;
|
||||
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_INVALID_ARGS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((genm = ossl_cmp_genm_new(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!send_receive_check(ctx, genm, &genp, OSSL_CMP_PKIBODY_GENP))
|
||||
goto err;
|
||||
|
||||
/* received stack of itavs not to be freed with the genp */
|
||||
rcvd_itavs = genp->body->value.genp;
|
||||
genp->body->value.genp = NULL;
|
||||
|
||||
err:
|
||||
OSSL_CMP_MSG_free(genm);
|
||||
OSSL_CMP_MSG_free(genp);
|
||||
|
||||
return rcvd_itavs; /* recv_itavs == NULL indicates an error */
|
||||
}
|
||||
+59
-170
@@ -20,9 +20,7 @@
|
||||
#include <openssl/crmf.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
/*
|
||||
* Get current certificate store containing trusted root CA certs
|
||||
*/
|
||||
/* Get current certificate store containing trusted root CA certs */
|
||||
X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -36,7 +34,6 @@ X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx)
|
||||
* Set certificate store containing trusted (root) CA certs and possibly CRLs
|
||||
* and a cert verification callback function used for CMP server authentication.
|
||||
* Any already existing store entry is freed. Given NULL, the entry is reset.
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store)
|
||||
{
|
||||
@@ -49,9 +46,7 @@ int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get current list of non-trusted intermediate certs
|
||||
*/
|
||||
/* Get current list of non-trusted intermediate certs */
|
||||
STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted_certs(const OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -64,7 +59,6 @@ STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted_certs(const OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Set untrusted certificates for path construction in authentication of
|
||||
* the CMP server and potentially others (TLS server, newly enrolled cert).
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_untrusted_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs)
|
||||
{
|
||||
@@ -101,9 +95,7 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(void)
|
||||
ctx->status = -1;
|
||||
ctx->failInfoCode = -1;
|
||||
|
||||
ctx->serverPort = OSSL_CMP_DEFAULT_PORT;
|
||||
ctx->proxyPort = OSSL_CMP_DEFAULT_PORT;
|
||||
ctx->msgtimeout = 2 * 60;
|
||||
ctx->msg_timeout = 2 * 60;
|
||||
|
||||
if ((ctx->untrusted_certs = sk_X509_new_null()) == NULL)
|
||||
goto err;
|
||||
@@ -125,9 +117,7 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare the OSSL_CMP_CTX for next use, partly re-initializing OSSL_CMP_CTX
|
||||
*/
|
||||
/* Prepare the OSSL_CMP_CTX for next use, partly re-initializing OSSL_CMP_CTX */
|
||||
int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -148,17 +138,16 @@ int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx)
|
||||
&& ossl_cmp_ctx_set1_recipNonce(ctx, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees OSSL_CMP_CTX variables allocated in OSSL_CMP_CTX_new()
|
||||
*/
|
||||
/* Frees OSSL_CMP_CTX variables allocated in OSSL_CMP_CTX_new() */
|
||||
void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
OPENSSL_free(ctx->serverPath);
|
||||
OPENSSL_free(ctx->serverName);
|
||||
OPENSSL_free(ctx->proxyName);
|
||||
OPENSSL_free(ctx->server);
|
||||
OPENSSL_free(ctx->proxy);
|
||||
OPENSSL_free(ctx->no_proxy);
|
||||
|
||||
X509_free(ctx->srvCert);
|
||||
X509_free(ctx->validatedSrvCert);
|
||||
@@ -252,12 +241,8 @@ int ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set callback function for checking if the cert is ok or should
|
||||
* it be rejected.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_cmp_certConf_cb_t cb)
|
||||
/* Set callback function for checking if the cert is ok or should be rejected */
|
||||
int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_certConf_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
@@ -270,7 +255,6 @@ int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_cmp_certConf_cb_t cb)
|
||||
/*
|
||||
* Set argument, respectively a pointer to a structure containing arguments,
|
||||
* optionally to be used by the certConf callback.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_certConf_cb_arg(OSSL_CMP_CTX *ctx, void *arg)
|
||||
{
|
||||
@@ -380,11 +364,8 @@ int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx,
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a callback function for error reporting and logging messages.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_cmp_log_cb_t cb)
|
||||
/* Set a callback function for error reporting and logging messages */
|
||||
int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
@@ -411,7 +392,6 @@ void OSSL_CMP_CTX_print_errors(OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Set or clear the reference value to be used for identification
|
||||
* (i.e., the user name) when using PBMAC.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx,
|
||||
const unsigned char *ref, int len)
|
||||
@@ -424,10 +404,7 @@ int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx,
|
||||
len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set or clear the password to be used for protecting messages with PBMAC.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set or clear the password to be used for protecting messages with PBMAC */
|
||||
int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx, const unsigned char *sec,
|
||||
const int len)
|
||||
{
|
||||
@@ -465,7 +442,6 @@ STACK_OF(X509) *OSSL_CMP_CTX_get1_extraCertsIn(const OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Copies any given stack of inbound X509 certificates to extraCertsIn
|
||||
* of the OSSL_CMP_CTX structure so that they may be retrieved later.
|
||||
* Returns 1 on success, 0 on error.
|
||||
*/
|
||||
int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx,
|
||||
STACK_OF(X509) *extraCertsIn)
|
||||
@@ -483,7 +459,6 @@ int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx,
|
||||
/*
|
||||
* Duplicate and set the given stack as the new stack of X509
|
||||
* certificates to send out in the extraCerts field.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx,
|
||||
STACK_OF(X509) *extraCertsOut)
|
||||
@@ -503,7 +478,6 @@ int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx,
|
||||
/*
|
||||
* Add the given policy info object
|
||||
* to the X509_EXTENSIONS of the requested certificate template.
|
||||
* Returns 1 on success, 0 on error.
|
||||
*/
|
||||
int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo)
|
||||
{
|
||||
@@ -519,9 +493,7 @@ int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo)
|
||||
return sk_POLICYINFO_push(ctx->policies, pinfo);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an ITAV for geninfo of the PKI message header
|
||||
*/
|
||||
/* Add an ITAV for geninfo of the PKI message header */
|
||||
int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -531,9 +503,7 @@ int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
|
||||
return OSSL_CMP_ITAV_push0_stack_item(&ctx->geninfo_ITAVs, itav);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an itav for the body of outgoing general messages
|
||||
*/
|
||||
/* Add an itav for the body of outgoing general messages */
|
||||
int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -562,7 +532,6 @@ STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Duplicate and copy the given stack of certificates to the given
|
||||
* OSSL_CMP_CTX structure so that they may be retrieved later.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int ossl_cmp_ctx_set1_caPubs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *caPubs)
|
||||
{
|
||||
@@ -614,39 +583,25 @@ int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \
|
||||
* Pins the server certificate to be directly trusted (even if it is expired)
|
||||
* for verifying response messages.
|
||||
* Cert pointer is not consumed. It may be NULL to clear the entry.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(srvCert, X509)
|
||||
|
||||
/*
|
||||
* Set the X509 name of the recipient. Set in the PKIHeader.
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the X509 name of the recipient. Set in the PKIHeader */
|
||||
DEFINE_OSSL_CMP_CTX_set1(recipient, X509_NAME)
|
||||
|
||||
/*
|
||||
* Store the X509 name of the expected sender in the PKIHeader of responses.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Store the X509 name of the expected sender in the PKIHeader of responses */
|
||||
DEFINE_OSSL_CMP_CTX_set1(expected_sender, X509_NAME)
|
||||
|
||||
/*
|
||||
* Set the X509 name of the issuer. Set in the PKIHeader.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the X509 name of the issuer. Set in the PKIHeader */
|
||||
DEFINE_OSSL_CMP_CTX_set1(issuer, X509_NAME)
|
||||
|
||||
/*
|
||||
* Set the subject name that will be placed in the certificate
|
||||
* request. This will be the subject name on the received certificate.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(subjectName, X509_NAME)
|
||||
|
||||
/*
|
||||
* Set the X.509v3 certificate request extensions to be used in IR/CR/KUR.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the X.509v3 certificate request extensions to be used in IR/CR/KUR */
|
||||
int OSSL_CMP_CTX_set0_reqExtensions(OSSL_CMP_CTX *ctx, X509_EXTENSIONS *exts)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -680,7 +635,6 @@ int OSSL_CMP_CTX_reqExtensions_have_SAN(OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Add a GENERAL_NAME structure that will be added to the CRMF
|
||||
* request's extensions field to request subject alternative names.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx,
|
||||
const GENERAL_NAME *name)
|
||||
@@ -712,7 +666,6 @@ int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx,
|
||||
/*
|
||||
* Set our own client certificate, used for example in KUR and when
|
||||
* doing the IR with existing certificate.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(clCert, X509)
|
||||
|
||||
@@ -721,19 +674,14 @@ DEFINE_OSSL_CMP_CTX_set1_up_ref(clCert, X509)
|
||||
* or the certificate to be revoked in RR, respectively.
|
||||
* Also used as reference cert (defaulting to clCert) for deriving subject DN
|
||||
* and SANs. Its issuer is used as default recipient in the CMP message header.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(oldCert, X509)
|
||||
|
||||
/*
|
||||
* Set the PKCS#10 CSR to be sent in P10CR.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the PKCS#10 CSR to be sent in P10CR */
|
||||
DEFINE_OSSL_CMP_CTX_set1(p10CSR, X509_REQ)
|
||||
|
||||
/*
|
||||
* Sets the (newly received in IP/KUP/CP) certificate in the context.
|
||||
* Returns 1 on success, 0 on error
|
||||
* Set the (newly received in IP/KUP/CP) certificate in the context.
|
||||
* TODO: this only permits for one cert to be enrolled at a time.
|
||||
*/
|
||||
int ossl_cmp_ctx_set0_newCert(OSSL_CMP_CTX *ctx, X509 *cert)
|
||||
@@ -759,16 +707,10 @@ X509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->newCert;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the client's current private key.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the client's current private key */
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(pkey, EVP_PKEY)
|
||||
|
||||
/*
|
||||
* Set new key pair. Used e.g. when doing Key Update.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set new key pair. Used e.g. when doing Key Update */
|
||||
int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -782,9 +724,7 @@ int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* gets the private/public key to use for certificate enrollment, NULL on error
|
||||
*/
|
||||
/* Get the private/public key to use for cert enrollment, or NULL on error */
|
||||
EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -799,10 +739,7 @@ EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv)
|
||||
return ctx->pkey; /* may be NULL */
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the given transactionID to the context.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the given transactionID to the context */
|
||||
int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *id)
|
||||
{
|
||||
@@ -813,11 +750,7 @@ int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx,
|
||||
return ossl_cmp_asn1_octet_string_set1(&ctx->transactionID, id);
|
||||
}
|
||||
|
||||
/*
|
||||
* sets the given nonce to be used for the recipNonce in the next message to be
|
||||
* created.
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the nonce to be used for the recipNonce in the message created next */
|
||||
int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *nonce)
|
||||
{
|
||||
@@ -826,10 +759,7 @@ int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
|
||||
return ossl_cmp_asn1_octet_string_set1(&ctx->recipNonce, nonce);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stores the given nonce as the last senderNonce sent out.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Stores the given nonce as the last senderNonce sent out */
|
||||
int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *nonce)
|
||||
{
|
||||
@@ -840,36 +770,16 @@ int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx,
|
||||
return ossl_cmp_asn1_octet_string_set1(&ctx->senderNonce, nonce);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the host name of the (HTTP) proxy server to use for all connections
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(proxyName, char)
|
||||
/* Set the proxy server to use for HTTP(S) connections */
|
||||
DEFINE_OSSL_CMP_CTX_set1(proxy, char)
|
||||
|
||||
/*
|
||||
* Set the (HTTP) host name of the CA server.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(serverName, char)
|
||||
/* Set the (HTTP) host name of the CMP server */
|
||||
DEFINE_OSSL_CMP_CTX_set1(server, char)
|
||||
|
||||
/*
|
||||
* Sets the (HTTP) proxy port to be used.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_proxyPort(OSSL_CMP_CTX *ctx, int port)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
ctx->proxyPort = port;
|
||||
return 1;
|
||||
}
|
||||
/* Set the server exclusion list of the HTTP proxy server */
|
||||
DEFINE_OSSL_CMP_CTX_set1(no_proxy, char)
|
||||
|
||||
/*
|
||||
* sets the http connect/disconnect callback function to be used for HTTP(S)
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the http connect/disconnect callback function to be used for HTTP(S) */
|
||||
int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -880,10 +790,7 @@ int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set argument optionally to be used by the http connect/disconnect callback.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set argument optionally to be used by the http connect/disconnect callback */
|
||||
int OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -907,11 +814,8 @@ void *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->http_cb_arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set callback function for sending CMP request and receiving response.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_cmp_transfer_cb_t cb)
|
||||
/* Set callback function for sending CMP request and receiving response */
|
||||
int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
@@ -921,10 +825,7 @@ int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_cmp_transfer_cb_t cb)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set argument optionally to be used by the transfer callback.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set argument optionally to be used by the transfer callback */
|
||||
int OSSL_CMP_CTX_set_transfer_cb_arg(OSSL_CMP_CTX *ctx, void *arg)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -948,10 +849,7 @@ void *OSSL_CMP_CTX_get_transfer_cb_arg(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->transfer_cb_arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the (HTTP) server port to be used.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/** Set the HTTP server port to be used */
|
||||
int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -962,16 +860,10 @@ int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the HTTP path to be used on the server (e.g "pkix/").
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the HTTP path to be used on the server (e.g "pkix/") */
|
||||
DEFINE_OSSL_CMP_CTX_set1(serverPath, char)
|
||||
|
||||
/*
|
||||
* Set the failInfo error code as bit encoding in OSSL_CMP_CTX.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the failInfo error code as bit encoding in OSSL_CMP_CTX */
|
||||
int ossl_cmp_ctx_set_failInfoCode(OSSL_CMP_CTX *ctx, int fail_info)
|
||||
{
|
||||
if (!ossl_assert(ctx != NULL))
|
||||
@@ -993,10 +885,7 @@ int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->failInfoCode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets a Boolean or integer option of the context to the "val" arg.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set a Boolean or integer option of the context to the "val" arg */
|
||||
int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
|
||||
{
|
||||
int min_val;
|
||||
@@ -1010,7 +899,7 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
|
||||
case OSSL_CMP_OPT_REVOCATION_REASON:
|
||||
min_val = OCSP_REVOKED_STATUS_NOSTATUS;
|
||||
break;
|
||||
case OSSL_CMP_OPT_POPOMETHOD:
|
||||
case OSSL_CMP_OPT_POPO_METHOD:
|
||||
min_val = OSSL_CRMF_POPO_NONE;
|
||||
break;
|
||||
default:
|
||||
@@ -1030,10 +919,10 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
|
||||
}
|
||||
ctx->log_verbosity = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_IMPLICITCONFIRM:
|
||||
case OSSL_CMP_OPT_IMPLICIT_CONFIRM:
|
||||
ctx->implicitConfirm = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_DISABLECONFIRM:
|
||||
case OSSL_CMP_OPT_DISABLE_CONFIRM:
|
||||
ctx->disableConfirm = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_UNPROTECTED_SEND:
|
||||
@@ -1042,7 +931,7 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
|
||||
case OSSL_CMP_OPT_UNPROTECTED_ERRORS:
|
||||
ctx->unprotectedErrors = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_VALIDITYDAYS:
|
||||
case OSSL_CMP_OPT_VALIDITY_DAYS:
|
||||
ctx->days = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT:
|
||||
@@ -1057,7 +946,7 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
|
||||
case OSSL_CMP_OPT_IGNORE_KEYUSAGE:
|
||||
ctx->ignore_keyusage = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_POPOMETHOD:
|
||||
case OSSL_CMP_OPT_POPO_METHOD:
|
||||
if (val > OSSL_CRMF_POPO_KEYAGREE) {
|
||||
CMPerr(0, CMP_R_INVALID_ARGS);
|
||||
return 0;
|
||||
@@ -1073,11 +962,11 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
|
||||
case OSSL_CMP_OPT_MAC_ALGNID:
|
||||
ctx->pbm_mac = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_MSGTIMEOUT:
|
||||
ctx->msgtimeout = val;
|
||||
case OSSL_CMP_OPT_MSG_TIMEOUT:
|
||||
ctx->msg_timeout = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_TOTALTIMEOUT:
|
||||
ctx->totaltimeout = val;
|
||||
case OSSL_CMP_OPT_TOTAL_TIMEOUT:
|
||||
ctx->total_timeout = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR:
|
||||
ctx->permitTAInExtraCertsForIR = val;
|
||||
@@ -1111,15 +1000,15 @@ int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt)
|
||||
switch (opt) {
|
||||
case OSSL_CMP_OPT_LOG_VERBOSITY:
|
||||
return ctx->log_verbosity;
|
||||
case OSSL_CMP_OPT_IMPLICITCONFIRM:
|
||||
case OSSL_CMP_OPT_IMPLICIT_CONFIRM:
|
||||
return ctx->implicitConfirm;
|
||||
case OSSL_CMP_OPT_DISABLECONFIRM:
|
||||
case OSSL_CMP_OPT_DISABLE_CONFIRM:
|
||||
return ctx->disableConfirm;
|
||||
case OSSL_CMP_OPT_UNPROTECTED_SEND:
|
||||
return ctx->unprotectedSend;
|
||||
case OSSL_CMP_OPT_UNPROTECTED_ERRORS:
|
||||
return ctx->unprotectedErrors;
|
||||
case OSSL_CMP_OPT_VALIDITYDAYS:
|
||||
case OSSL_CMP_OPT_VALIDITY_DAYS:
|
||||
return ctx->days;
|
||||
case OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT:
|
||||
return ctx->SubjectAltName_nodefault;
|
||||
@@ -1129,7 +1018,7 @@ int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt)
|
||||
return ctx->setPoliciesCritical;
|
||||
case OSSL_CMP_OPT_IGNORE_KEYUSAGE:
|
||||
return ctx->ignore_keyusage;
|
||||
case OSSL_CMP_OPT_POPOMETHOD:
|
||||
case OSSL_CMP_OPT_POPO_METHOD:
|
||||
return ctx->popoMethod;
|
||||
case OSSL_CMP_OPT_DIGEST_ALGNID:
|
||||
return ctx->digest;
|
||||
@@ -1137,10 +1026,10 @@ int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt)
|
||||
return ctx->pbm_owf;
|
||||
case OSSL_CMP_OPT_MAC_ALGNID:
|
||||
return ctx->pbm_mac;
|
||||
case OSSL_CMP_OPT_MSGTIMEOUT:
|
||||
return ctx->msgtimeout;
|
||||
case OSSL_CMP_OPT_TOTALTIMEOUT:
|
||||
return ctx->totaltimeout;
|
||||
case OSSL_CMP_OPT_MSG_TIMEOUT:
|
||||
return ctx->msg_timeout;
|
||||
case OSSL_CMP_OPT_TOTAL_TIMEOUT:
|
||||
return ctx->total_timeout;
|
||||
case OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR:
|
||||
return ctx->permitTAInExtraCertsForIR;
|
||||
case OSSL_CMP_OPT_REVOCATION_REASON:
|
||||
|
||||
+40
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 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,26 +16,44 @@
|
||||
static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ALGORITHM_NOT_SUPPORTED),
|
||||
"algorithm not supported"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_BAD_CHECKAFTER_IN_POLLREP),
|
||||
"bad checkafter in pollrep"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_BAD_REQUEST_ID), "bad request id"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTHASH_UNMATCHED), "certhash unmatched"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTID_NOT_FOUND), "certid not found"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTIFICATE_NOT_ACCEPTED),
|
||||
"certificate not accepted"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTIFICATE_NOT_FOUND),
|
||||
"certificate not found"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTREQMSG_NOT_FOUND),
|
||||
"certreqmsg not found"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTRESPONSE_NOT_FOUND),
|
||||
"certresponse not found"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERT_AND_KEY_DO_NOT_MATCH),
|
||||
"cert and key do not match"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CHECKAFTER_OUT_OF_RANGE),
|
||||
"checkafter out of range"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE),
|
||||
"checking pbm no secret available"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ENCOUNTERED_KEYUPDATEWARNING),
|
||||
"encountered keyupdatewarning"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ENCOUNTERED_WAITING),
|
||||
"encountered waiting"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CALCULATING_PROTECTION),
|
||||
"error calculating protection"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CERTCONF),
|
||||
"error creating certconf"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CERTREP),
|
||||
"error creating certrep"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CR), "error creating cr"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_ERROR),
|
||||
"error creating error"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_GENM),
|
||||
"error creating genm"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_GENP),
|
||||
"error creating genp"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_IR), "error creating ir"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_KUR), "error creating kur"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_P10CR),
|
||||
"error creating p10cr"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_PKICONF),
|
||||
@@ -48,10 +66,14 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_RR), "error creating rr"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PARSING_PKISTATUS),
|
||||
"error parsing pkistatus"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PROCESSING_MESSAGE),
|
||||
"error processing message"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PROTECTING_MESSAGE),
|
||||
"error protecting message"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_SETTING_CERTHASH),
|
||||
"error setting certhash"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_UNEXPECTED_CERTCONF),
|
||||
"error unexpected certconf"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_PROTECTION),
|
||||
"error validating protection"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY),
|
||||
@@ -72,6 +94,10 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
"missing sender identification"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_TRUST_STORE),
|
||||
"missing trust store"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED),
|
||||
"multiple requests not supported"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED),
|
||||
"multiple responses not supported"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_SAN_SOURCES),
|
||||
"multiple san sources"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NO_STDIO), "no stdio"},
|
||||
@@ -81,23 +107,32 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_PKIBODY_ERROR), "pkibody error"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_PKISTATUSINFO_NOT_FOUND),
|
||||
"pkistatusinfo not found"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_POLLING_FAILED), "polling failed"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_POTENTIALLY_INVALID_CERTIFICATE),
|
||||
"potentially invalid certificate"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_RECEIVED_ERROR), "received error"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_RECIPNONCE_UNMATCHED),
|
||||
"recipnonce unmatched"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_REQUEST_NOT_ACCEPTED),
|
||||
"request not accepted"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_REQUEST_REJECTED_BY_SERVER),
|
||||
"request rejected by server"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED),
|
||||
"sender generalname type not supported"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG),
|
||||
"srvcert does not validate msg"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TOTAL_TIMEOUT), "total timeout"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSACTIONID_UNMATCHED),
|
||||
"transactionid unmatched"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSFER_ERROR), "transfer error"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKISTATUS),
|
||||
"unexpected pkistatus"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PVNO), "unexpected pvno"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_ALGORITHM_ID),
|
||||
"unknown algorithm id"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_CERT_TYPE), "unknown cert type"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_PKISTATUS), "unknown pkistatus"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_ALGORITHM),
|
||||
"unsupported algorithm"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_KEY_TYPE),
|
||||
@@ -106,7 +141,11 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
"unsupported protection alg dhbasedmac"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_ALGORITHM_OID),
|
||||
"wrong algorithm oid"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_CERTID_IN_RP), "wrong certid in rp"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_PBM_VALUE), "wrong pbm value"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_RP_COMPONENT_COUNT),
|
||||
"wrong rp component count"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_SERIAL_IN_RP), "wrong serial in rp"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
|
||||
+27
-41
@@ -63,31 +63,42 @@ ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr)
|
||||
return hdr->recipNonce;
|
||||
}
|
||||
|
||||
int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name)
|
||||
{
|
||||
X509_NAME *null = X509_NAME_new();
|
||||
int res = name == NULL || null == NULL
|
||||
|| (name->type == GEN_DIRNAME
|
||||
&& X509_NAME_cmp(name->d.directoryName, null) == 0);
|
||||
|
||||
X509_NAME_free(null);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* assign to *tgt a copy of src (which may be NULL to indicate an empty DN) */
|
||||
static int set1_general_name(GENERAL_NAME **tgt, const X509_NAME *src)
|
||||
{
|
||||
GENERAL_NAME *gen;
|
||||
GENERAL_NAME *name;
|
||||
|
||||
if (!ossl_assert(tgt != NULL))
|
||||
return 0;
|
||||
if ((gen = GENERAL_NAME_new()) == NULL)
|
||||
if ((name = GENERAL_NAME_new()) == NULL)
|
||||
goto err;
|
||||
gen->type = GEN_DIRNAME;
|
||||
name->type = GEN_DIRNAME;
|
||||
|
||||
if (src == NULL) { /* NULL-DN */
|
||||
if ((gen->d.directoryName = X509_NAME_new()) == NULL)
|
||||
if ((name->d.directoryName = X509_NAME_new()) == NULL)
|
||||
goto err;
|
||||
} else if (!X509_NAME_set(&gen->d.directoryName, src)) {
|
||||
} else if (!X509_NAME_set(&name->d.directoryName, src)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
GENERAL_NAME_free(*tgt);
|
||||
*tgt = gen;
|
||||
*tgt = name;
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
GENERAL_NAME_free(gen);
|
||||
GENERAL_NAME_free(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -153,25 +164,6 @@ int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr,
|
||||
}
|
||||
|
||||
/* push the given text string to the given PKIFREETEXT ft */
|
||||
int ossl_cmp_pkifreetext_push_str(OSSL_CMP_PKIFREETEXT *ft, const char *text)
|
||||
{
|
||||
ASN1_UTF8STRING *utf8string;
|
||||
|
||||
if (!ossl_assert(ft != NULL && text != NULL))
|
||||
return 0;
|
||||
if ((utf8string = ASN1_UTF8STRING_new()) == NULL)
|
||||
return 0;
|
||||
if (!ASN1_STRING_set(utf8string, text, -1))
|
||||
goto err;
|
||||
if (!sk_ASN1_UTF8STRING_push(ft, utf8string))
|
||||
goto err;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
ASN1_UTF8STRING_free(utf8string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text)
|
||||
{
|
||||
if (!ossl_assert(hdr != NULL && text != NULL))
|
||||
@@ -193,7 +185,8 @@ int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text)
|
||||
&& (hdr->freeText = sk_ASN1_UTF8STRING_new_null()) == NULL)
|
||||
return 0;
|
||||
|
||||
return ossl_cmp_pkifreetext_push_str(hdr->freeText, (char *)text->data);
|
||||
return
|
||||
ossl_cmp_sk_ASN1_UTF8STRING_push_str(hdr->freeText, (char *)text->data);
|
||||
}
|
||||
|
||||
int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr,
|
||||
@@ -205,7 +198,7 @@ int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr,
|
||||
}
|
||||
|
||||
int ossl_cmp_hdr_generalInfo_push1_items(OSSL_CMP_PKIHEADER *hdr,
|
||||
STACK_OF(OSSL_CMP_ITAV) *itavs)
|
||||
const STACK_OF(OSSL_CMP_ITAV) *itavs)
|
||||
{
|
||||
int i;
|
||||
OSSL_CMP_ITAV *itav;
|
||||
@@ -250,7 +243,7 @@ int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr)
|
||||
}
|
||||
|
||||
/* return 1 if implicitConfirm in the generalInfo field of the header is set */
|
||||
int ossl_cmp_hdr_check_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr)
|
||||
int ossl_cmp_hdr_has_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr)
|
||||
{
|
||||
int itavCount;
|
||||
int i;
|
||||
@@ -273,8 +266,8 @@ int ossl_cmp_hdr_check_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr)
|
||||
/* fill in all fields of the hdr according to the info given in ctx */
|
||||
int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr)
|
||||
{
|
||||
X509_NAME *sender;
|
||||
X509_NAME *rcp = NULL;
|
||||
const X509_NAME *sender;
|
||||
const X509_NAME *rcp = NULL;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && hdr != NULL))
|
||||
return 0;
|
||||
@@ -283,19 +276,12 @@ int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr)
|
||||
if (!ossl_cmp_hdr_set_pvno(hdr, OSSL_CMP_PVNO))
|
||||
return 0;
|
||||
|
||||
sender = ctx->clCert != NULL ?
|
||||
X509_get_subject_name(ctx->clCert) : ctx->subjectName;
|
||||
/*
|
||||
* The sender name is copied from the subject of the client cert, if any,
|
||||
* or else from the the subject name provided for certification requests.
|
||||
* As required by RFC 4210 section 5.1.1., if the sender name is not known
|
||||
* to the client it set to NULL-DN. In this case for identification at least
|
||||
* the senderKID must be set, which we take from any referenceValue given.
|
||||
* or else from the subject name provided for certification requests.
|
||||
*/
|
||||
if (sender == NULL && ctx->referenceValue == NULL) {
|
||||
CMPerr(0, CMP_R_MISSING_SENDER_IDENTIFICATION);
|
||||
return 0;
|
||||
}
|
||||
sender = ctx->clCert != NULL ?
|
||||
X509_get_subject_name(ctx->clCert) : ctx->subjectName;
|
||||
if (!ossl_cmp_hdr_set1_sender(hdr, sender))
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright Nokia 2007-2019
|
||||
* Copyright Siemens AG 2015-2019
|
||||
*
|
||||
* 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 <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/http.h>
|
||||
#include "internal/sockets.h"
|
||||
|
||||
#include "openssl/cmp.h"
|
||||
#include "cmp_local.h"
|
||||
|
||||
/* explicit #includes not strictly needed since implied by the above: */
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/cmp.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
/*
|
||||
* Send the PKIMessage req and on success return the response, else NULL.
|
||||
* Any previous error queue entries will likely be removed by ERR_clear_error().
|
||||
*/
|
||||
OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
char server_port[32] = { '\0' };
|
||||
STACK_OF(CONF_VALUE) *headers = NULL;
|
||||
const char *const content_type_pkix = "application/pkixcmp";
|
||||
OSSL_CMP_MSG *res;
|
||||
|
||||
if (ctx == NULL || req == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!X509V3_add_value("Pragma", "no-cache", &headers))
|
||||
return NULL;
|
||||
|
||||
if (ctx->serverPort != 0)
|
||||
BIO_snprintf(server_port, sizeof(server_port), "%d", ctx->serverPort);
|
||||
|
||||
res = (OSSL_CMP_MSG *)
|
||||
OSSL_HTTP_post_asn1(ctx->server, server_port, ctx->serverPath,
|
||||
OSSL_CMP_CTX_get_http_cb_arg(ctx) != NULL,
|
||||
ctx->proxy, ctx->no_proxy, NULL, NULL,
|
||||
ctx->http_cb, OSSL_CMP_CTX_get_http_cb_arg(ctx),
|
||||
headers, content_type_pkix,
|
||||
(ASN1_VALUE *)req, ASN1_ITEM_rptr(OSSL_CMP_MSG),
|
||||
0, 0, ctx->msg_timeout, content_type_pkix,
|
||||
ASN1_ITEM_rptr(OSSL_CMP_MSG));
|
||||
|
||||
sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
|
||||
return res;
|
||||
}
|
||||
+42
-49
@@ -28,20 +28,20 @@
|
||||
* this structure is used to store the context for CMP sessions
|
||||
*/
|
||||
struct ossl_cmp_ctx_st {
|
||||
OSSL_cmp_log_cb_t log_cb; /* log callback for error/debug/etc. output */
|
||||
OSSL_CMP_log_cb_t log_cb; /* log callback for error/debug/etc. output */
|
||||
OSSL_CMP_severity log_verbosity; /* level of verbosity of log output */
|
||||
|
||||
/* message transfer */
|
||||
OSSL_cmp_transfer_cb_t transfer_cb; /* default: OSSL_CMP_MSG_http_perform */
|
||||
OSSL_CMP_transfer_cb_t transfer_cb; /* default: OSSL_CMP_MSG_http_perform */
|
||||
void *transfer_cb_arg; /* allows to store optional argument to cb */
|
||||
/* HTTP-based transfer */
|
||||
char *serverPath;
|
||||
char *serverName;
|
||||
char *server;
|
||||
int serverPort;
|
||||
char *proxyName;
|
||||
int proxyPort;
|
||||
int msgtimeout; /* max seconds to wait for each CMP message round trip */
|
||||
int totaltimeout; /* maximum number seconds an enrollment may take, incl. */
|
||||
char *proxy;
|
||||
char *no_proxy;
|
||||
int msg_timeout; /* max seconds to wait for each CMP message round trip */
|
||||
int total_timeout; /* max number of seconds an enrollment may take, incl. */
|
||||
/* attempts polling for a response if a 'waiting' PKIStatus is received */
|
||||
time_t end_time; /* session start time + totaltimeout */
|
||||
OSSL_HTTP_bio_cb_t http_cb;
|
||||
@@ -56,7 +56,7 @@ struct ossl_cmp_ctx_st {
|
||||
int unprotectedErrors;
|
||||
X509 *srvCert; /* certificate used to identify the server */
|
||||
X509 *validatedSrvCert; /* caches any already validated server cert */
|
||||
X509_NAME *expected_sender; /* expected sender in pkiheader of response */
|
||||
X509_NAME *expected_sender; /* expected sender in header of response */
|
||||
X509_STORE *trusted; /* trust store maybe w CRLs and cert verify callback */
|
||||
STACK_OF(X509) *untrusted_certs; /* untrusted (intermediate) certs */
|
||||
int ignore_keyusage; /* ignore key usage entry when validating certs */
|
||||
@@ -95,7 +95,7 @@ struct ossl_cmp_ctx_st {
|
||||
int newPkey_priv; /* flag indicating if newPkey contains private key */
|
||||
X509_NAME *issuer; /* issuer name to used in cert template */
|
||||
int days; /* Number of days new certificates are asked to be valid for */
|
||||
X509_NAME *subjectName; /* subject name to be used in the cert template */
|
||||
X509_NAME *subjectName; /* subject name to be used in cert template */
|
||||
STACK_OF(GENERAL_NAME) *subjectAltNames; /* to add to the cert template */
|
||||
int SubjectAltName_nodefault;
|
||||
int setSubjectAltNameCritical;
|
||||
@@ -122,7 +122,7 @@ struct ossl_cmp_ctx_st {
|
||||
STACK_OF(X509) *extraCertsIn; /* extraCerts received from server */
|
||||
|
||||
/* certificate confirmation */
|
||||
OSSL_cmp_certConf_cb_t certConf_cb; /* callback for app checking new cert */
|
||||
OSSL_CMP_certConf_cb_t certConf_cb; /* callback for app checking new cert */
|
||||
void *certConf_cb_arg; /* allows to store an argument individual to cb */
|
||||
} /* OSSL_CMP_CTX */;
|
||||
|
||||
@@ -246,7 +246,6 @@ struct ossl_cmp_itav_st {
|
||||
} infoValue;
|
||||
} /* OSSL_CMP_ITAV */;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ITAV)
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_ITAV)
|
||||
|
||||
typedef struct ossl_cmp_certorenccert_st {
|
||||
int type;
|
||||
@@ -284,8 +283,6 @@ struct ossl_cmp_pkisi_st {
|
||||
OSSL_CMP_PKIFREETEXT *statusString;
|
||||
OSSL_CMP_PKIFAILUREINFO *failInfo;
|
||||
} /* OSSL_CMP_PKISI */;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKISI)
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_PKISI)
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID)
|
||||
|
||||
/*-
|
||||
@@ -296,10 +293,11 @@ DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID)
|
||||
* crlEntryDetails Extensions OPTIONAL
|
||||
* }
|
||||
*/
|
||||
typedef struct ossl_cmp_revdetails_st {
|
||||
struct ossl_cmp_revdetails_st {
|
||||
OSSL_CRMF_CERTTEMPLATE *certDetails;
|
||||
X509_EXTENSIONS *crlEntryDetails;
|
||||
} OSSL_CMP_REVDETAILS;
|
||||
} /* OSSL_CMP_REVDETAILS */;
|
||||
typedef struct ossl_cmp_revdetails_st OSSL_CMP_REVDETAILS;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_REVDETAILS)
|
||||
DEFINE_STACK_OF(OSSL_CMP_REVDETAILS)
|
||||
|
||||
@@ -375,7 +373,6 @@ struct ossl_cmp_certstatus_st {
|
||||
OSSL_CMP_PKISI *statusInfo;
|
||||
} /* OSSL_CMP_CERTSTATUS */;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTSTATUS)
|
||||
|
||||
typedef STACK_OF(OSSL_CMP_CERTSTATUS) OSSL_CMP_CERTCONFIRMCONTENT;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTCONFIRMCONTENT)
|
||||
|
||||
@@ -670,7 +667,6 @@ struct ossl_cmp_msg_st {
|
||||
STACK_OF(X509) *extraCerts; /* 1 */
|
||||
} /* OSSL_CMP_MSG */;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_MSG)
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_MSG)
|
||||
|
||||
/*-
|
||||
* ProtectedPart ::= SEQUENCE {
|
||||
@@ -728,17 +724,6 @@ DECLARE_ASN1_FUNCTIONS(CMP_PROTECTEDPART)
|
||||
* }
|
||||
*/
|
||||
|
||||
/*
|
||||
* constants
|
||||
*/
|
||||
/* certReqId for the first - and so far only - certificate request */
|
||||
# define OSSL_CMP_CERTREQID 0
|
||||
/* sequence id for the first - and so far only - revocation request */
|
||||
# define OSSL_CMP_REVREQSID 0
|
||||
/*
|
||||
* functions
|
||||
*/
|
||||
|
||||
/* from cmp_asn.c */
|
||||
int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a);
|
||||
|
||||
@@ -755,6 +740,9 @@ int ossl_cmp_sk_X509_add1_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs,
|
||||
int no_self_issued, int no_dups, int prepend);
|
||||
int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs,
|
||||
int only_self_issued);
|
||||
STACK_OF(X509) *ossl_cmp_X509_STORE_get1_certs(X509_STORE *store);
|
||||
int ossl_cmp_sk_ASN1_UTF8STRING_push_str(STACK_OF(ASN1_UTF8STRING) *sk,
|
||||
const char *text);
|
||||
int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt,
|
||||
const ASN1_OCTET_STRING *src);
|
||||
int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt,
|
||||
@@ -800,32 +788,30 @@ int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *nonce);
|
||||
|
||||
/* from cmp_status.c */
|
||||
OSSL_CMP_PKISI *
|
||||
ossl_cmp_statusinfo_new(int status, int fail_info, const char *text);
|
||||
int ossl_cmp_pkisi_get_pkistatus(const OSSL_CMP_PKISI *statusInfo);
|
||||
int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si);
|
||||
const char *ossl_cmp_PKIStatus_to_string(int status);
|
||||
OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusstring(const OSSL_CMP_PKISI *si);
|
||||
OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *si);
|
||||
int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si);
|
||||
int ossl_cmp_pkisi_pkifailureinfo_check(const OSSL_CMP_PKISI *si, int bit_index);
|
||||
int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int index);
|
||||
|
||||
/* from cmp_hdr.c */
|
||||
int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno);
|
||||
int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr);
|
||||
ASN1_OCTET_STRING *ossl_cmp_hdr_get0_senderNonce(const OSSL_CMP_PKIHEADER *hdr);
|
||||
int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name);
|
||||
int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm);
|
||||
int ossl_cmp_hdr_set1_recipient(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm);
|
||||
int ossl_cmp_hdr_update_messageTime(OSSL_CMP_PKIHEADER *hdr);
|
||||
int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr,
|
||||
const ASN1_OCTET_STRING *senderKID);
|
||||
int ossl_cmp_pkifreetext_push_str(OSSL_CMP_PKIFREETEXT *ft, const char *text);
|
||||
int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text);
|
||||
int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text);
|
||||
int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr,
|
||||
OSSL_CMP_ITAV *itav);
|
||||
int ossl_cmp_hdr_generalInfo_push1_items(OSSL_CMP_PKIHEADER *hdr,
|
||||
STACK_OF(OSSL_CMP_ITAV) *itavs);
|
||||
const STACK_OF(OSSL_CMP_ITAV) *itavs);
|
||||
int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr);
|
||||
int ossl_cmp_hdr_check_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr);
|
||||
int ossl_cmp_hdr_has_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr);
|
||||
# define OSSL_CMP_TRANSACTIONID_LENGTH 16
|
||||
# define OSSL_CMP_SENDERNONCE_LENGTH 16
|
||||
int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr);
|
||||
@@ -860,6 +846,10 @@ int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr);
|
||||
# define OSSL_CMP_PKIBODY_POLLREQ 25
|
||||
# define OSSL_CMP_PKIBODY_POLLREP 26
|
||||
# define OSSL_CMP_PKIBODY_TYPE_MAX OSSL_CMP_PKIBODY_POLLREP
|
||||
/* certReqId for the first - and so far only - certificate request */
|
||||
# define OSSL_CMP_CERTREQID 0
|
||||
/* sequence id for the first - and so far only - revocation request */
|
||||
# define OSSL_CMP_REVREQSID 0
|
||||
const char *ossl_cmp_bodytype_to_string(int type);
|
||||
int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG *msg, int type);
|
||||
int ossl_cmp_msg_get_bodytype(const OSSL_CMP_MSG *msg);
|
||||
@@ -875,24 +865,26 @@ OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx);
|
||||
OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
|
||||
OSSL_CRMF_CERTID *certId, int unprot_err);
|
||||
OSSL_CMP_MSG *ossl_cmp_pkiconf_new(OSSL_CMP_CTX *ctx);
|
||||
OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid,
|
||||
int64_t poll_after);
|
||||
int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav);
|
||||
int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg,
|
||||
STACK_OF(OSSL_CMP_ITAV) *itavs);
|
||||
const STACK_OF(OSSL_CMP_ITAV) *itavs);
|
||||
OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx);
|
||||
OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx);
|
||||
OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx,
|
||||
const STACK_OF(OSSL_CMP_ITAV) *itavs);
|
||||
OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
|
||||
int errorCode,
|
||||
OSSL_CMP_PKIFREETEXT *errorDetails,
|
||||
int unprotected);
|
||||
int ossl_cmp_certstatus_set_certHash(OSSL_CMP_CERTSTATUS *certStatus,
|
||||
const X509 *cert);
|
||||
const char *details, int unprotected);
|
||||
int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS *certStatus,
|
||||
ASN1_OCTET_STRING *hash);
|
||||
OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
|
||||
const char *text);
|
||||
OSSL_CMP_MSG *ossl_cmp_pollReq_new(OSSL_CMP_CTX *ctx, int crid);
|
||||
OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid,
|
||||
int64_t poll_after);
|
||||
OSSL_CMP_PKISI *
|
||||
ossl_cmp_revrepcontent_get_pkistatusinfo(OSSL_CMP_REVREPCONTENT *rrep, int rsid);
|
||||
ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT *rrep, int rsid);
|
||||
OSSL_CRMF_CERTID *ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT *rrep,
|
||||
int rsid);
|
||||
OSSL_CMP_POLLREP *
|
||||
@@ -904,11 +896,6 @@ ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crepmsg
|
||||
X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey,
|
||||
const OSSL_CMP_CERTRESPONSE *crep);
|
||||
OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file);
|
||||
/* BIO definitions */
|
||||
# define OSSL_d2i_CMP_MSG_bio(bp, p) \
|
||||
ASN1_d2i_bio_of(OSSL_CMP_MSG, OSSL_CMP_MSG_new, d2i_OSSL_CMP_MSG, bp, p)
|
||||
# define OSSL_i2d_CMP_MSG_bio(bp, o) \
|
||||
ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bp, o)
|
||||
|
||||
/* from cmp_protect.c */
|
||||
ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
|
||||
@@ -925,4 +912,10 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg);
|
||||
int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified);
|
||||
|
||||
#endif /* !defined OSSL_CRYPTO_CMP_LOCAL_H */
|
||||
/* from cmp_client.c */
|
||||
int ossl_cmp_exchange_certConf(OSSL_CMP_CTX *ctx, int fail_info,
|
||||
const char *txt);
|
||||
int ossl_cmp_exchange_error(OSSL_CMP_CTX *ctx, int status, int fail_info,
|
||||
const char *txt, int errorCode, const char *details);
|
||||
|
||||
#endif /* !defined(OSSL_CRYPTO_CMP_LOCAL_H) */
|
||||
+64
-66
@@ -185,7 +185,7 @@ OSSL_CMP_MSG *ossl_cmp_msg_create(OSSL_CMP_CTX *ctx, int bodytype)
|
||||
(sk_GENERAL_NAME_num((ctx)->subjectAltNames) > 0 \
|
||||
|| OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1)
|
||||
|
||||
static X509_NAME *determine_subj(OSSL_CMP_CTX *ctx, X509 *refcert,
|
||||
static const X509_NAME *determine_subj(OSSL_CMP_CTX *ctx, X509 *refcert,
|
||||
int bodytype)
|
||||
{
|
||||
if (ctx->subjectName != NULL)
|
||||
@@ -205,18 +205,20 @@ static X509_NAME *determine_subj(OSSL_CMP_CTX *ctx, X509 *refcert,
|
||||
* Create CRMF certificate request message for IR/CR/KUR
|
||||
* returns a pointer to the OSSL_CRMF_MSG on success, NULL on error
|
||||
*/
|
||||
static OSSL_CRMF_MSG *crm_new(OSSL_CMP_CTX *ctx, int bodytype,
|
||||
int rid, EVP_PKEY *rkey)
|
||||
static OSSL_CRMF_MSG *crm_new(OSSL_CMP_CTX *ctx, int bodytype, int rid)
|
||||
{
|
||||
OSSL_CRMF_MSG *crm = NULL;
|
||||
X509 *refcert = ctx->oldCert != NULL ? ctx->oldCert : ctx->clCert;
|
||||
/* refcert defaults to current client cert */
|
||||
EVP_PKEY *rkey = OSSL_CMP_CTX_get0_newPkey(ctx, 0);
|
||||
STACK_OF(GENERAL_NAME) *default_sans = NULL;
|
||||
X509_NAME *subject = determine_subj(ctx, refcert, bodytype);
|
||||
const X509_NAME *subject = determine_subj(ctx, refcert, bodytype);
|
||||
int crit = ctx->setSubjectAltNameCritical || subject == NULL;
|
||||
/* RFC5280: subjectAltName MUST be critical if subject is null */
|
||||
X509_EXTENSIONS *exts = NULL;
|
||||
|
||||
if (rkey == NULL)
|
||||
rkey = ctx->pkey; /* default is independent of ctx->oldClCert */
|
||||
if (rkey == NULL
|
||||
|| (bodytype == OSSL_CMP_PKIBODY_KUR && refcert == NULL)) {
|
||||
CMPerr(0, CMP_R_INVALID_ARGS);
|
||||
@@ -300,19 +302,12 @@ static OSSL_CRMF_MSG *crm_new(OSSL_CMP_CTX *ctx, int bodytype,
|
||||
|
||||
OSSL_CMP_MSG *ossl_cmp_certReq_new(OSSL_CMP_CTX *ctx, int type, int err_code)
|
||||
{
|
||||
EVP_PKEY *rkey;
|
||||
EVP_PKEY *privkey;
|
||||
OSSL_CMP_MSG *msg;
|
||||
OSSL_CRMF_MSG *crm = NULL;
|
||||
|
||||
if (!ossl_assert(ctx != NULL))
|
||||
return NULL;
|
||||
|
||||
rkey = OSSL_CMP_CTX_get0_newPkey(ctx, 0);
|
||||
if (rkey == NULL)
|
||||
return NULL;
|
||||
privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
|
||||
|
||||
if (type != OSSL_CMP_PKIBODY_IR && type != OSSL_CMP_PKIBODY_CR
|
||||
&& type != OSSL_CMP_PKIBODY_KUR && type != OSSL_CMP_PKIBODY_P10CR) {
|
||||
CMPerr(0, CMP_R_INVALID_ARGS);
|
||||
@@ -329,11 +324,15 @@ OSSL_CMP_MSG *ossl_cmp_certReq_new(OSSL_CMP_CTX *ctx, int type, int err_code)
|
||||
/* body */
|
||||
/* For P10CR the content has already been set in OSSL_CMP_MSG_create */
|
||||
if (type != OSSL_CMP_PKIBODY_P10CR) {
|
||||
EVP_PKEY *privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
|
||||
|
||||
if (privkey == NULL)
|
||||
privkey = ctx->pkey; /* default is independent of ctx->oldCert */
|
||||
if (ctx->popoMethod == OSSL_CRMF_POPO_SIGNATURE && privkey == NULL) {
|
||||
CMPerr(0, CMP_R_MISSING_PRIVATE_KEY);
|
||||
goto err;
|
||||
}
|
||||
if ((crm = crm_new(ctx, type, OSSL_CMP_CERTREQID, rkey)) == NULL
|
||||
if ((crm = crm_new(ctx, type, OSSL_CMP_CERTREQID)) == NULL
|
||||
|| !OSSL_CRMF_MSG_create_popo(crm, privkey, ctx->digest,
|
||||
ctx->popoMethod)
|
||||
/* value.ir is same for cr and kur */
|
||||
@@ -349,6 +348,7 @@ OSSL_CMP_MSG *ossl_cmp_certReq_new(OSSL_CMP_CTX *ctx, int type, int err_code)
|
||||
return msg;
|
||||
|
||||
err:
|
||||
if (err_code != 0)
|
||||
CMPerr(0, err_code);
|
||||
OSSL_CRMF_MSG_free(crm);
|
||||
OSSL_CMP_MSG_free(msg);
|
||||
@@ -385,7 +385,7 @@ OSSL_CMP_MSG *ossl_cmp_certRep_new(OSSL_CMP_CTX *ctx, int bodytype,
|
||||
|| !ASN1_INTEGER_set(resp->certReqId, certReqId))
|
||||
goto err;
|
||||
|
||||
status = ossl_cmp_pkisi_get_pkistatus(resp->status);
|
||||
status = ossl_cmp_pkisi_get_status(resp->status);
|
||||
if (status != OSSL_CMP_PKISTATUS_rejection
|
||||
&& status != OSSL_CMP_PKISTATUS_waiting && cert != NULL) {
|
||||
if (encrypted) {
|
||||
@@ -416,7 +416,7 @@ OSSL_CMP_MSG *ossl_cmp_certRep_new(OSSL_CMP_CTX *ctx, int bodytype,
|
||||
goto err;
|
||||
|
||||
if (!unprotectedErrors
|
||||
|| ossl_cmp_pkisi_get_pkistatus(si) != OSSL_CMP_PKISTATUS_rejection)
|
||||
|| ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection)
|
||||
if (!ossl_cmp_msg_protect(ctx, msg))
|
||||
goto err;
|
||||
|
||||
@@ -511,7 +511,7 @@ OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
|
||||
}
|
||||
|
||||
if (!unprot_err
|
||||
|| ossl_cmp_pkisi_get_pkistatus(si) != OSSL_CMP_PKISTATUS_rejection)
|
||||
|| ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection)
|
||||
if (!ossl_cmp_msg_protect(ctx, msg))
|
||||
goto err;
|
||||
|
||||
@@ -560,7 +560,7 @@ int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav)
|
||||
}
|
||||
|
||||
int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg,
|
||||
STACK_OF(OSSL_CMP_ITAV) *itavs)
|
||||
const STACK_OF(OSSL_CMP_ITAV) *itavs)
|
||||
{
|
||||
int i;
|
||||
OSSL_CMP_ITAV *itav = NULL;
|
||||
@@ -583,7 +583,9 @@ int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg,
|
||||
* Creates a new General Message/Response with an empty itav stack
|
||||
* returns a pointer to the PKIMessage on success, NULL on error
|
||||
*/
|
||||
static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx, int body_type, int err_code)
|
||||
static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx,
|
||||
const STACK_OF(OSSL_CMP_ITAV) *itavs,
|
||||
int body_type, int err_code)
|
||||
{
|
||||
OSSL_CMP_MSG *msg = NULL;
|
||||
|
||||
@@ -594,7 +596,7 @@ static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx, int body_type, int err_code)
|
||||
return NULL;
|
||||
|
||||
if (ctx->genm_ITAVs != NULL
|
||||
&& !ossl_cmp_msg_gen_push1_ITAVs(msg, ctx->genm_ITAVs))
|
||||
&& !ossl_cmp_msg_gen_push1_ITAVs(msg, itavs))
|
||||
goto err;
|
||||
|
||||
if (!ossl_cmp_msg_protect(ctx, msg))
|
||||
@@ -610,20 +612,23 @@ static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx, int body_type, int err_code)
|
||||
|
||||
OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
return gen_new(ctx, OSSL_CMP_PKIBODY_GENM, CMP_R_ERROR_CREATING_GENM);
|
||||
return gen_new(ctx, ctx->genm_ITAVs,
|
||||
OSSL_CMP_PKIBODY_GENM, CMP_R_ERROR_CREATING_GENM);
|
||||
}
|
||||
|
||||
OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx)
|
||||
OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx,
|
||||
const STACK_OF(OSSL_CMP_ITAV) *itavs)
|
||||
{
|
||||
return gen_new(ctx, OSSL_CMP_PKIBODY_GENP, CMP_R_ERROR_CREATING_GENP);
|
||||
return gen_new(ctx, itavs,
|
||||
OSSL_CMP_PKIBODY_GENP, CMP_R_ERROR_CREATING_GENP);
|
||||
}
|
||||
|
||||
OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
|
||||
int errorCode,
|
||||
OSSL_CMP_PKIFREETEXT *errorDetails,
|
||||
int unprotected)
|
||||
const char *details, int unprotected)
|
||||
{
|
||||
OSSL_CMP_MSG *msg = NULL;
|
||||
OSSL_CMP_PKIFREETEXT *ft;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && si != NULL))
|
||||
return NULL;
|
||||
@@ -641,11 +646,13 @@ OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
|
||||
if (!ASN1_INTEGER_set(msg->body->value.error->errorCode, errorCode))
|
||||
goto err;
|
||||
}
|
||||
if (errorDetails != NULL)
|
||||
if ((msg->body->value.error->errorDetails =
|
||||
sk_ASN1_UTF8STRING_deep_copy(errorDetails, ASN1_STRING_dup,
|
||||
ASN1_STRING_free)) == NULL)
|
||||
if (details != NULL) {
|
||||
if ((ft = sk_ASN1_UTF8STRING_new_null()) == NULL)
|
||||
goto err;
|
||||
msg->body->value.error->errorDetails = ft;
|
||||
if (!ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, details))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!unprotected && !ossl_cmp_msg_protect(ctx, msg))
|
||||
goto err;
|
||||
@@ -658,44 +665,18 @@ OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
|
||||
}
|
||||
|
||||
/*
|
||||
* OSSL_CMP_CERTSTATUS_set_certHash() calculates a hash of the certificate,
|
||||
* using the same hash algorithm as is used to create and verify the
|
||||
* certificate signature, and places the hash into the certHash field of a
|
||||
* OSSL_CMP_CERTSTATUS structure. This is used in the certConf message,
|
||||
* for example, to confirm that the certificate was received successfully.
|
||||
* Set the certHash field of a OSSL_CMP_CERTSTATUS structure.
|
||||
* This is used in the certConf message, for example,
|
||||
* to confirm that the certificate was received successfully.
|
||||
*/
|
||||
int ossl_cmp_certstatus_set_certHash(OSSL_CMP_CERTSTATUS *certStatus,
|
||||
const X509 *cert)
|
||||
int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS *certStatus,
|
||||
ASN1_OCTET_STRING *hash)
|
||||
{
|
||||
unsigned int len;
|
||||
unsigned char hash[EVP_MAX_MD_SIZE];
|
||||
int md_NID;
|
||||
const EVP_MD *md = NULL;
|
||||
|
||||
if (!ossl_assert(certStatus != NULL && cert != NULL))
|
||||
if (!ossl_assert(certStatus != NULL))
|
||||
return 0;
|
||||
|
||||
/*-
|
||||
* select hash algorithm, as stated in Appendix F. Compilable ASN.1 defs:
|
||||
* the hash of the certificate, using the same hash algorithm
|
||||
* as is used to create and verify the certificate signature
|
||||
*/
|
||||
if (OBJ_find_sigid_algs(X509_get_signature_nid(cert), &md_NID, NULL)
|
||||
&& (md = EVP_get_digestbynid(md_NID)) != NULL) {
|
||||
if (!X509_digest(cert, md, hash, &len))
|
||||
goto err;
|
||||
if (!ossl_cmp_asn1_octet_string_set1_bytes(&certStatus->certHash, hash,
|
||||
len))
|
||||
goto err;
|
||||
} else {
|
||||
CMPerr(0, CMP_R_UNSUPPORTED_ALGORITHM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ASN1_OCTET_STRING_free(certStatus->certHash);
|
||||
certStatus->certHash = hash;
|
||||
return 1;
|
||||
err:
|
||||
CMPerr(0, CMP_R_ERROR_SETTING_CERTHASH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -707,6 +688,7 @@ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
|
||||
{
|
||||
OSSL_CMP_MSG *msg = NULL;
|
||||
OSSL_CMP_CERTSTATUS *certStatus = NULL;
|
||||
ASN1_OCTET_STRING *certHash = NULL;
|
||||
OSSL_CMP_PKISI *sinfo;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && ctx->newCert != NULL))
|
||||
@@ -732,8 +714,12 @@ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
|
||||
* the hash of the certificate, using the same hash algorithm
|
||||
* as is used to create and verify the certificate signature
|
||||
*/
|
||||
if (!ossl_cmp_certstatus_set_certHash(certStatus, ctx->newCert))
|
||||
if ((certHash = X509_digest_sig(ctx->newCert)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!ossl_cmp_certstatus_set0_certHash(certStatus, certHash))
|
||||
goto err;
|
||||
certHash = NULL;
|
||||
/*
|
||||
* For any particular CertStatus, omission of the statusInfo field
|
||||
* indicates ACCEPTANCE of the specified certificate. Alternatively,
|
||||
@@ -742,8 +728,8 @@ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
|
||||
* the CA/RA.
|
||||
*/
|
||||
sinfo = fail_info != 0 ?
|
||||
ossl_cmp_statusinfo_new(OSSL_CMP_PKISTATUS_rejection, fail_info, text) :
|
||||
ossl_cmp_statusinfo_new(OSSL_CMP_PKISTATUS_accepted, 0, text);
|
||||
OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection, fail_info, text) :
|
||||
OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_accepted, 0, text);
|
||||
if (sinfo == NULL)
|
||||
goto err;
|
||||
certStatus->statusInfo = sinfo;
|
||||
@@ -756,6 +742,7 @@ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
|
||||
err:
|
||||
CMPerr(0, CMP_R_ERROR_CREATING_CERTCONF);
|
||||
OSSL_CMP_MSG_free(msg);
|
||||
ASN1_OCTET_STRING_free(certHash);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -827,7 +814,7 @@ OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid,
|
||||
* returns NULL on error
|
||||
*/
|
||||
OSSL_CMP_PKISI *
|
||||
ossl_cmp_revrepcontent_get_pkistatusinfo(OSSL_CMP_REVREPCONTENT *rrep, int rsid)
|
||||
ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT *rrep, int rsid)
|
||||
{
|
||||
OSSL_CMP_PKISI *status;
|
||||
|
||||
@@ -990,7 +977,18 @@ OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file)
|
||||
|
||||
if ((bio = BIO_new_file(file, "rb")) == NULL)
|
||||
return NULL;
|
||||
msg = OSSL_d2i_CMP_MSG_bio(bio, NULL);
|
||||
msg = d2i_OSSL_CMP_MSG_bio(bio, NULL);
|
||||
BIO_free(bio);
|
||||
return msg;
|
||||
}
|
||||
|
||||
OSSL_CMP_MSG *d2i_OSSL_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg)
|
||||
{
|
||||
return ASN1_d2i_bio_of(OSSL_CMP_MSG, OSSL_CMP_MSG_new,
|
||||
d2i_OSSL_CMP_MSG, bio, msg);
|
||||
}
|
||||
|
||||
int i2d_OSSL_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
return ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bio, msg);
|
||||
}
|
||||
@@ -286,6 +286,8 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
|
||||
* to section 5.1.1
|
||||
*/
|
||||
subjKeyIDStr = X509_get0_subject_key_id(ctx->clCert);
|
||||
if (subjKeyIDStr == NULL)
|
||||
subjKeyIDStr = ctx->referenceValue; /* fallback */
|
||||
if (subjKeyIDStr != NULL
|
||||
&& !ossl_cmp_hdr_set1_senderKID(msg->header, subjKeyIDStr))
|
||||
goto err;
|
||||
@@ -306,7 +308,18 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* As required by RFC 4210 section 5.1.1., if the sender name is not known
|
||||
* to the client it set to NULL-DN. In this case for identification at least
|
||||
* the senderKID must be set, where we took the referenceValue as fallback.
|
||||
*/
|
||||
|
||||
if (ossl_cmp_general_name_is_NULL_DN(msg->header->sender)
|
||||
&& msg->header->senderKID == NULL)
|
||||
CMPerr(0, CMP_R_MISSING_SENDER_IDENTIFICATION);
|
||||
else
|
||||
return 1;
|
||||
|
||||
err:
|
||||
CMPerr(0, CMP_R_ERROR_PROTECTING_MESSAGE);
|
||||
return 0;
|
||||
|
||||
@@ -0,0 +1,619 @@
|
||||
/*
|
||||
* Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright Nokia 2007-2019
|
||||
* Copyright Siemens AG 2015-2019
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* general CMP server functions */
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
|
||||
#include "cmp_local.h"
|
||||
|
||||
/* explicit #includes not strictly needed since implied by the above: */
|
||||
#include <openssl/cmp.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
/* the context for the generic CMP server */
|
||||
struct ossl_cmp_srv_ctx_st
|
||||
{
|
||||
OSSL_CMP_CTX *ctx; /* Client CMP context, partly reused for srv */
|
||||
void *custom_ctx; /* pointer to specific server context */
|
||||
|
||||
OSSL_CMP_SRV_cert_request_cb_t process_cert_request;
|
||||
OSSL_CMP_SRV_rr_cb_t process_rr;
|
||||
OSSL_CMP_SRV_genm_cb_t process_genm;
|
||||
OSSL_CMP_SRV_error_cb_t process_error;
|
||||
OSSL_CMP_SRV_certConf_cb_t process_certConf;
|
||||
OSSL_CMP_SRV_pollReq_cb_t process_pollReq;
|
||||
|
||||
int sendUnprotectedErrors; /* Send error and rejection msgs unprotected */
|
||||
int acceptUnprotected; /* Accept requests with no/invalid prot. */
|
||||
int acceptRAVerified; /* Accept ir/cr/kur with POPO RAVerified */
|
||||
int grantImplicitConfirm; /* Grant implicit confirmation if requested */
|
||||
|
||||
}; /* OSSL_CMP_SRV_CTX */
|
||||
|
||||
void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx)
|
||||
{
|
||||
if (srv_ctx == NULL)
|
||||
return;
|
||||
|
||||
OSSL_CMP_CTX_free(srv_ctx->ctx);
|
||||
OPENSSL_free(srv_ctx);
|
||||
}
|
||||
|
||||
OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(void)
|
||||
{
|
||||
OSSL_CMP_SRV_CTX *ctx = OPENSSL_zalloc(sizeof(OSSL_CMP_SRV_CTX));
|
||||
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
|
||||
if ((ctx->ctx = OSSL_CMP_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
/* all other elements are initialized to 0 or NULL, respectively */
|
||||
return ctx;
|
||||
err:
|
||||
OSSL_CMP_SRV_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx,
|
||||
OSSL_CMP_SRV_cert_request_cb_t process_cert_request,
|
||||
OSSL_CMP_SRV_rr_cb_t process_rr,
|
||||
OSSL_CMP_SRV_genm_cb_t process_genm,
|
||||
OSSL_CMP_SRV_error_cb_t process_error,
|
||||
OSSL_CMP_SRV_certConf_cb_t process_certConf,
|
||||
OSSL_CMP_SRV_pollReq_cb_t process_pollReq)
|
||||
{
|
||||
if (srv_ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
srv_ctx->custom_ctx = custom_ctx;
|
||||
srv_ctx->process_cert_request = process_cert_request;
|
||||
srv_ctx->process_rr = process_rr;
|
||||
srv_ctx->process_genm = process_genm;
|
||||
srv_ctx->process_error = process_error;
|
||||
srv_ctx->process_certConf = process_certConf;
|
||||
srv_ctx->process_pollReq = process_pollReq;
|
||||
return 1;
|
||||
}
|
||||
|
||||
OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx)
|
||||
{
|
||||
if (srv_ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
return srv_ctx->ctx;
|
||||
}
|
||||
|
||||
void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx)
|
||||
{
|
||||
if (srv_ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
return srv_ctx->custom_ctx;
|
||||
}
|
||||
|
||||
int OSSL_CMP_SRV_CTX_set_send_unprotected_errors(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
int val)
|
||||
{
|
||||
if (srv_ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
srv_ctx->sendUnprotectedErrors = val != 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int OSSL_CMP_SRV_CTX_set_accept_unprotected(OSSL_CMP_SRV_CTX *srv_ctx, int val)
|
||||
{
|
||||
if (srv_ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
srv_ctx->acceptUnprotected = val != 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int OSSL_CMP_SRV_CTX_set_accept_raverified(OSSL_CMP_SRV_CTX *srv_ctx, int val)
|
||||
{
|
||||
if (srv_ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
srv_ctx->acceptRAVerified = val != 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
int val)
|
||||
{
|
||||
if (srv_ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
srv_ctx->grantImplicitConfirm = val != 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Processes an ir/cr/p10cr/kur and returns a certification response.
|
||||
* Only handles the first certification request contained in req
|
||||
* returns an ip/cp/kup on success and NULL on error
|
||||
*/
|
||||
static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_MSG *msg = NULL;
|
||||
OSSL_CMP_PKISI *si = NULL;
|
||||
X509 *certOut = NULL;
|
||||
STACK_OF(X509) *chainOut = NULL, *caPubs = NULL;
|
||||
const OSSL_CRMF_MSG *crm = NULL;
|
||||
const X509_REQ *p10cr = NULL;
|
||||
int bodytype;
|
||||
int certReqId;
|
||||
|
||||
if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
|
||||
return NULL;
|
||||
|
||||
switch (ossl_cmp_msg_get_bodytype(req)) {
|
||||
case OSSL_CMP_PKIBODY_P10CR:
|
||||
case OSSL_CMP_PKIBODY_CR:
|
||||
bodytype = OSSL_CMP_PKIBODY_CP;
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_IR:
|
||||
bodytype = OSSL_CMP_PKIBODY_IP;
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_KUR:
|
||||
bodytype = OSSL_CMP_PKIBODY_KUP;
|
||||
break;
|
||||
default:
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ossl_cmp_msg_get_bodytype(req) == OSSL_CMP_PKIBODY_P10CR) {
|
||||
certReqId = OSSL_CMP_CERTREQID;
|
||||
p10cr = req->body->value.p10cr;
|
||||
} else {
|
||||
OSSL_CRMF_MSGS *reqs = req->body->value.ir; /* same for cr and kur */
|
||||
|
||||
if (sk_OSSL_CRMF_MSG_num(reqs) != 1) { /* TODO: handle case > 1 */
|
||||
CMPerr(0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((crm = sk_OSSL_CRMF_MSG_value(reqs, OSSL_CMP_CERTREQID)) == NULL) {
|
||||
CMPerr(0, CMP_R_CERTREQMSG_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
certReqId = OSSL_CRMF_MSG_get_certReqId(crm);
|
||||
}
|
||||
|
||||
if (!ossl_cmp_verify_popo(req, srv_ctx->acceptRAVerified)) {
|
||||
/* Proof of possession could not be verified */
|
||||
si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
|
||||
1 << OSSL_CMP_PKIFAILUREINFO_badPOP,
|
||||
ERR_reason_error_string(ERR_peek_error()));
|
||||
if (si == NULL)
|
||||
return NULL;
|
||||
} else {
|
||||
OSSL_CMP_PKIHEADER *hdr = OSSL_CMP_MSG_get0_header(req);
|
||||
|
||||
si = srv_ctx->process_cert_request(srv_ctx, req, certReqId, crm, p10cr,
|
||||
&certOut, &chainOut, &caPubs);
|
||||
if (si == NULL)
|
||||
goto err;
|
||||
/* set OSSL_CMP_OPT_IMPLICIT_CONFIRM if and only if transaction ends */
|
||||
if (!OSSL_CMP_CTX_set_option(srv_ctx->ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM,
|
||||
ossl_cmp_hdr_has_implicitConfirm(hdr)
|
||||
&& srv_ctx->grantImplicitConfirm
|
||||
/* do not set if polling starts: */
|
||||
&& certOut != NULL))
|
||||
goto err;
|
||||
}
|
||||
|
||||
msg = ossl_cmp_certRep_new(srv_ctx->ctx, bodytype, certReqId, si,
|
||||
certOut, chainOut, caPubs, 0 /* encrypted */,
|
||||
srv_ctx->sendUnprotectedErrors);
|
||||
/*
|
||||
* TODO when implemented in ossl_cmp_certrep_new():
|
||||
* in case OSSL_CRMF_POPO_KEYENC, set encrypted
|
||||
*/
|
||||
if (msg == NULL)
|
||||
CMPerr(0, CMP_R_ERROR_CREATING_CERTREP);
|
||||
|
||||
err:
|
||||
OSSL_CMP_PKISI_free(si);
|
||||
X509_free(certOut);
|
||||
sk_X509_pop_free(chainOut, X509_free);
|
||||
sk_X509_pop_free(caPubs, X509_free);
|
||||
return msg;
|
||||
}
|
||||
|
||||
static OSSL_CMP_MSG *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_MSG *msg = NULL;
|
||||
OSSL_CMP_REVDETAILS *details;
|
||||
OSSL_CRMF_CERTID *certId;
|
||||
OSSL_CRMF_CERTTEMPLATE *tmpl;
|
||||
const X509_NAME *issuer;
|
||||
ASN1_INTEGER *serial;
|
||||
OSSL_CMP_PKISI *si;
|
||||
|
||||
if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
|
||||
return NULL;
|
||||
|
||||
if (sk_OSSL_CMP_REVDETAILS_num(req->body->value.rr) != 1) {
|
||||
/* TODO: handle multiple elements if multiple requests have been sent */
|
||||
CMPerr(0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((details = sk_OSSL_CMP_REVDETAILS_value(req->body->value.rr,
|
||||
OSSL_CMP_REVREQSID)) == NULL) {
|
||||
CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmpl = details->certDetails;
|
||||
issuer = OSSL_CRMF_CERTTEMPLATE_get0_issuer(tmpl);
|
||||
serial = OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(tmpl);
|
||||
/* here issuer and serial may safely be NULL */
|
||||
if ((certId = OSSL_CRMF_CERTID_gen(issuer, serial)) == NULL)
|
||||
return NULL;
|
||||
if ((si = srv_ctx->process_rr(srv_ctx, req, issuer, serial)) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((msg = ossl_cmp_rp_new(srv_ctx->ctx, si, certId,
|
||||
srv_ctx->sendUnprotectedErrors)) == NULL)
|
||||
CMPerr(0, CMP_R_ERROR_CREATING_RR);
|
||||
|
||||
err:
|
||||
OSSL_CRMF_CERTID_free(certId);
|
||||
OSSL_CMP_PKISI_free(si);
|
||||
return msg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Processes genm and creates a genp message mirroring the contents of the
|
||||
* incoming message
|
||||
*/
|
||||
static OSSL_CMP_MSG *process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_GENMSGCONTENT *itavs;
|
||||
OSSL_CMP_MSG *msg;
|
||||
|
||||
if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
|
||||
return NULL;
|
||||
|
||||
if (!srv_ctx->process_genm(srv_ctx, req, req->body->value.genm, &itavs))
|
||||
return NULL;
|
||||
|
||||
msg = ossl_cmp_genp_new(srv_ctx->ctx, itavs);
|
||||
sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free);
|
||||
return msg;
|
||||
}
|
||||
|
||||
static OSSL_CMP_MSG *process_error(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_ERRORMSGCONTENT *errorContent;
|
||||
OSSL_CMP_MSG *msg;
|
||||
|
||||
if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
|
||||
return NULL;
|
||||
errorContent = req->body->value.error;
|
||||
srv_ctx->process_error(srv_ctx, req, errorContent->pKIStatusInfo,
|
||||
errorContent->errorCode, errorContent->errorDetails);
|
||||
|
||||
if ((msg = ossl_cmp_pkiconf_new(srv_ctx->ctx)) == NULL)
|
||||
CMPerr(0, CMP_R_ERROR_CREATING_PKICONF);
|
||||
return msg;
|
||||
}
|
||||
|
||||
static OSSL_CMP_MSG *process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_CTX *ctx;
|
||||
OSSL_CMP_CERTCONFIRMCONTENT *ccc;
|
||||
int num;
|
||||
OSSL_CMP_MSG *msg = NULL;
|
||||
OSSL_CMP_CERTSTATUS *status = NULL;
|
||||
|
||||
if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
|
||||
return NULL;
|
||||
|
||||
ctx = srv_ctx->ctx;
|
||||
ccc = req->body->value.certConf;
|
||||
num = sk_OSSL_CMP_CERTSTATUS_num(ccc);
|
||||
|
||||
if (OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM) == 1) {
|
||||
CMPerr(0, CMP_R_ERROR_UNEXPECTED_CERTCONF);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (num == 0) {
|
||||
ossl_cmp_err(ctx, "certificate rejected by client");
|
||||
} else {
|
||||
if (num > 1)
|
||||
ossl_cmp_warn(ctx, "All CertStatus but the first will be ignored");
|
||||
status = sk_OSSL_CMP_CERTSTATUS_value(ccc, OSSL_CMP_CERTREQID);
|
||||
}
|
||||
|
||||
if (status != NULL) {
|
||||
int certReqId = ossl_cmp_asn1_get_int(status->certReqId);
|
||||
ASN1_OCTET_STRING *certHash = status->certHash;
|
||||
OSSL_CMP_PKISI *si = status->statusInfo;
|
||||
|
||||
if (!srv_ctx->process_certConf(srv_ctx, req, certReqId, certHash, si))
|
||||
return NULL; /* reason code may be: CMP_R_CERTHASH_UNMATCHED */
|
||||
|
||||
if (si != NULL && ossl_cmp_pkisi_get_status(si)
|
||||
!= OSSL_CMP_PKISTATUS_accepted) {
|
||||
int pki_status = ossl_cmp_pkisi_get_status(si);
|
||||
const char *str = ossl_cmp_PKIStatus_to_string(pki_status);
|
||||
|
||||
ossl_cmp_log2(INFO, ctx, "certificate rejected by client %s %s",
|
||||
str == NULL ? "without" : "with",
|
||||
str == NULL ? "PKIStatus" : str);
|
||||
}
|
||||
}
|
||||
|
||||
if ((msg = ossl_cmp_pkiconf_new(ctx)) == NULL)
|
||||
CMPerr(0, CMP_R_ERROR_CREATING_PKICONF);
|
||||
return msg;
|
||||
}
|
||||
|
||||
static OSSL_CMP_MSG *process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_POLLREQCONTENT *prc;
|
||||
OSSL_CMP_POLLREQ *pr;
|
||||
int certReqId;
|
||||
OSSL_CMP_MSG *certReq;
|
||||
int64_t check_after = 0;
|
||||
OSSL_CMP_MSG *msg = NULL;
|
||||
|
||||
if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
|
||||
return NULL;
|
||||
|
||||
prc = req->body->value.pollReq;
|
||||
if (sk_OSSL_CMP_POLLREQ_num(prc) != 1) { /* TODO: handle case > 1 */
|
||||
CMPerr(0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pr = sk_OSSL_CMP_POLLREQ_value(prc, 0);
|
||||
certReqId = ossl_cmp_asn1_get_int(pr->certReqId);
|
||||
if (!srv_ctx->process_pollReq(srv_ctx, req, certReqId,
|
||||
&certReq, &check_after))
|
||||
return NULL;
|
||||
|
||||
if (certReq != NULL) {
|
||||
msg = process_cert_request(srv_ctx, certReq);
|
||||
OSSL_CMP_MSG_free(certReq);
|
||||
} else {
|
||||
if ((msg = ossl_cmp_pollRep_new(srv_ctx->ctx, certReqId,
|
||||
check_after)) == NULL)
|
||||
CMPerr(0, CMP_R_ERROR_CREATING_POLLREP);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine whether missing/invalid protection of request message is allowed.
|
||||
* Return 1 on acceptance, 0 on rejection, or -1 on (internal) error.
|
||||
*/
|
||||
static int unprotected_exception(const OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *req,
|
||||
int invalid_protection,
|
||||
int accept_unprotected_requests)
|
||||
{
|
||||
if (!ossl_assert(ctx != NULL && req != NULL))
|
||||
return -1;
|
||||
|
||||
if (accept_unprotected_requests) {
|
||||
ossl_cmp_log1(WARN, ctx, "ignoring %s protection of request message",
|
||||
invalid_protection ? "invalid" : "missing");
|
||||
return 1;
|
||||
}
|
||||
if (ossl_cmp_msg_get_bodytype(req) == OSSL_CMP_PKIBODY_ERROR
|
||||
&& OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS) == 1) {
|
||||
ossl_cmp_warn(ctx, "ignoring missing protection of error message");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns created message and NULL on internal error
|
||||
*/
|
||||
OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_CTX *ctx;
|
||||
OSSL_CMP_PKIHEADER *hdr;
|
||||
int req_type, rsp_type;
|
||||
OSSL_CMP_MSG *rsp = NULL;
|
||||
|
||||
if (srv_ctx == NULL || srv_ctx->ctx == NULL
|
||||
|| req == NULL || req->body == NULL
|
||||
|| (hdr = OSSL_CMP_MSG_get0_header(req)) == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
ctx = srv_ctx->ctx;
|
||||
|
||||
if (hdr->sender->type != GEN_DIRNAME) {
|
||||
CMPerr(0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
|
||||
goto err;
|
||||
}
|
||||
if (!OSSL_CMP_CTX_set1_recipient(ctx, hdr->sender->d.directoryName))
|
||||
goto err;
|
||||
|
||||
req_type = ossl_cmp_msg_get_bodytype(req);
|
||||
switch (req_type) {
|
||||
case OSSL_CMP_PKIBODY_IR:
|
||||
case OSSL_CMP_PKIBODY_CR:
|
||||
case OSSL_CMP_PKIBODY_P10CR:
|
||||
case OSSL_CMP_PKIBODY_KUR:
|
||||
case OSSL_CMP_PKIBODY_RR:
|
||||
case OSSL_CMP_PKIBODY_GENM:
|
||||
case OSSL_CMP_PKIBODY_ERROR:
|
||||
if (ctx->transactionID != NULL) {
|
||||
char *tid;
|
||||
|
||||
tid = OPENSSL_buf2hexstr(ctx->transactionID->data,
|
||||
ctx->transactionID->length);
|
||||
ossl_cmp_log1(WARN, ctx,
|
||||
"Assuming that last transaction with ID=%s got aborted",
|
||||
tid);
|
||||
OPENSSL_free(tid);
|
||||
}
|
||||
/* start of a new transaction, set transactionID and senderNonce */
|
||||
if (!OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID)
|
||||
|| !ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce))
|
||||
goto err;
|
||||
break;
|
||||
default:
|
||||
/* transactionID should be already initialized */
|
||||
if (ctx->transactionID == NULL) {
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
/* ignore any (extra) error in next two function calls: */
|
||||
(void)OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID);
|
||||
(void)ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (ossl_cmp_msg_check_received(ctx, req, unprotected_exception,
|
||||
srv_ctx->acceptUnprotected) < 0)
|
||||
goto err;
|
||||
|
||||
switch (req_type) {
|
||||
case OSSL_CMP_PKIBODY_IR:
|
||||
case OSSL_CMP_PKIBODY_CR:
|
||||
case OSSL_CMP_PKIBODY_P10CR:
|
||||
case OSSL_CMP_PKIBODY_KUR:
|
||||
if (srv_ctx->process_cert_request == NULL)
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
else
|
||||
rsp = process_cert_request(srv_ctx, req);
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_RR:
|
||||
if (srv_ctx->process_rr == NULL)
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
else
|
||||
rsp = process_rr(srv_ctx, req);
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_GENM:
|
||||
if (srv_ctx->process_genm == NULL)
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
else
|
||||
rsp = process_genm(srv_ctx, req);
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_ERROR:
|
||||
if (srv_ctx->process_error == NULL)
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
else
|
||||
rsp = process_error(srv_ctx, req);
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_CERTCONF:
|
||||
if (srv_ctx->process_certConf == NULL)
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
else
|
||||
rsp = process_certConf(srv_ctx, req);
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_POLLREQ:
|
||||
if (srv_ctx->process_pollReq == NULL)
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
else
|
||||
rsp = process_pollReq(srv_ctx, req);
|
||||
break;
|
||||
default:
|
||||
/* TODO possibly support further request message types */
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
}
|
||||
|
||||
err:
|
||||
if (rsp == NULL) {
|
||||
/* on error, try to respond with CMP error message to client */
|
||||
const char *data = NULL;
|
||||
int flags = 0;
|
||||
unsigned long err = ERR_peek_error_data(&data, &flags);
|
||||
int fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_badRequest;
|
||||
/* TODO fail_info could be more specific */
|
||||
OSSL_CMP_PKISI *si = NULL;
|
||||
|
||||
if ((si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
|
||||
fail_info, NULL)) == NULL)
|
||||
return 0;
|
||||
if (err != 0 && (flags & ERR_TXT_STRING) != 0)
|
||||
data = ERR_reason_error_string(err);
|
||||
rsp = ossl_cmp_error_new(srv_ctx->ctx, si,
|
||||
err != 0 ? ERR_GET_REASON(err) : -1,
|
||||
data, srv_ctx->sendUnprotectedErrors);
|
||||
OSSL_CMP_PKISI_free(si);
|
||||
}
|
||||
|
||||
/* possibly close the transaction */
|
||||
rsp_type =
|
||||
rsp != NULL ? ossl_cmp_msg_get_bodytype(rsp) : OSSL_CMP_PKIBODY_ERROR;
|
||||
switch (rsp_type) {
|
||||
case OSSL_CMP_PKIBODY_IP:
|
||||
case OSSL_CMP_PKIBODY_CP:
|
||||
case OSSL_CMP_PKIBODY_KUP:
|
||||
case OSSL_CMP_PKIBODY_RP:
|
||||
if (OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM) == 0)
|
||||
break;
|
||||
/* fall through */
|
||||
|
||||
case OSSL_CMP_PKIBODY_PKICONF:
|
||||
case OSSL_CMP_PKIBODY_GENP:
|
||||
case OSSL_CMP_PKIBODY_ERROR:
|
||||
/* TODO possibly support further terminating response message types */
|
||||
(void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL); /* ignore any error */
|
||||
|
||||
default: /* not closing transaction in other cases */
|
||||
break;
|
||||
}
|
||||
return rsp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Server interface that may substitute OSSL_CMP_MSG_http_perform at the client.
|
||||
* The OSSL_CMP_SRV_CTX must be set as client_ctx->transfer_cb_arg.
|
||||
* returns received message on success, else NULL and pushes an element on the
|
||||
* error stack.
|
||||
*/
|
||||
OSSL_CMP_MSG * OSSL_CMP_CTX_server_perform(OSSL_CMP_CTX *client_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_SRV_CTX *srv_ctx = NULL;
|
||||
|
||||
if (client_ctx == NULL || req == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((srv_ctx = OSSL_CMP_CTX_get_transfer_cb_arg(client_ctx)) == NULL) {
|
||||
CMPerr(0, CMP_R_TRANSFER_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return OSSL_CMP_SRV_process_request(srv_ctx, req);
|
||||
}
|
||||
+52
-40
@@ -28,17 +28,13 @@
|
||||
|
||||
/* CMP functions related to PKIStatus */
|
||||
|
||||
int ossl_cmp_pkisi_get_pkistatus(const OSSL_CMP_PKISI *si)
|
||||
int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si)
|
||||
{
|
||||
if (!ossl_assert(si != NULL && si->status != NULL))
|
||||
return -1;
|
||||
return ossl_cmp_asn1_get_int(si->status);
|
||||
}
|
||||
|
||||
/*
|
||||
* return the declared identifier and a short explanation for the PKIStatus
|
||||
* value as specified in RFC4210, Appendix F.
|
||||
*/
|
||||
const char *ossl_cmp_PKIStatus_to_string(int status)
|
||||
{
|
||||
switch (status) {
|
||||
@@ -67,27 +63,19 @@ const char *ossl_cmp_PKIStatus_to_string(int status)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* returns a pointer to the statusString contained in a PKIStatusInfo
|
||||
* returns NULL on error
|
||||
*/
|
||||
OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusstring(const OSSL_CMP_PKISI *si)
|
||||
OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *si)
|
||||
{
|
||||
if (!ossl_assert(si != NULL))
|
||||
return NULL;
|
||||
return si->statusString;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns the FailureInfo bits of the given PKIStatusInfo
|
||||
* returns -1 on error
|
||||
*/
|
||||
int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si)
|
||||
{
|
||||
int i;
|
||||
int res = 0;
|
||||
|
||||
if (!ossl_assert(si != NULL && si->failInfo != NULL))
|
||||
if (!ossl_assert(si != NULL))
|
||||
return -1;
|
||||
for (i = 0; i <= OSSL_CMP_PKIFAILUREINFO_MAX; i++)
|
||||
if (ASN1_BIT_STRING_get_bit(si->failInfo, i))
|
||||
@@ -95,12 +83,9 @@ int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si)
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* internal function
|
||||
/*-
|
||||
* convert PKIFailureInfo number to human-readable string
|
||||
*
|
||||
* returns pointer to static string
|
||||
* returns NULL on error
|
||||
* returns pointer to static string, or NULL on error
|
||||
*/
|
||||
static const char *CMP_PKIFAILUREINFO_to_string(int number)
|
||||
{
|
||||
@@ -164,11 +149,7 @@ static const char *CMP_PKIFAILUREINFO_to_string(int number)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* checks PKIFailureInfo bits in a given PKIStatusInfo
|
||||
* returns 1 if a given bit is set, 0 if not, -1 on error
|
||||
*/
|
||||
int ossl_cmp_pkisi_pkifailureinfo_check(const OSSL_CMP_PKISI *si, int bit_index)
|
||||
int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int bit_index)
|
||||
{
|
||||
if (!ossl_assert(si != NULL && si->failInfo != NULL))
|
||||
return -1;
|
||||
@@ -180,16 +161,17 @@ int ossl_cmp_pkisi_pkifailureinfo_check(const OSSL_CMP_PKISI *si, int bit_index)
|
||||
return ASN1_BIT_STRING_get_bit(si->failInfo, bit_index);
|
||||
}
|
||||
|
||||
/*
|
||||
/*-
|
||||
* place human-readable error string created from PKIStatusInfo in given buffer
|
||||
* returns pointer to the same buffer containing the string, or NULL on error
|
||||
*/
|
||||
char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf,
|
||||
size_t bufsize)
|
||||
static
|
||||
char *snprint_PKIStatusInfo_parts(int status, int fail_info,
|
||||
const OSSL_CMP_PKIFREETEXT *status_strings,
|
||||
char *buf, size_t bufsize)
|
||||
{
|
||||
int status, failure, fail_info;
|
||||
int failure;
|
||||
const char *status_string, *failure_string;
|
||||
OSSL_CMP_PKIFREETEXT *status_strings;
|
||||
ASN1_UTF8STRING *text;
|
||||
int i;
|
||||
int printed_chars;
|
||||
@@ -197,22 +179,22 @@ char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf,
|
||||
int n_status_strings;
|
||||
char *write_ptr = buf;
|
||||
|
||||
if (buf == NULL
|
||||
|| status < 0
|
||||
|| (status_string = ossl_cmp_PKIStatus_to_string(status)) == NULL)
|
||||
return NULL;
|
||||
|
||||
#define ADVANCE_BUFFER \
|
||||
if (printed_chars < 0 || (size_t)printed_chars >= bufsize) \
|
||||
return NULL; \
|
||||
write_ptr += printed_chars; \
|
||||
bufsize -= printed_chars;
|
||||
|
||||
if (ctx == NULL
|
||||
|| buf == NULL
|
||||
|| (status = OSSL_CMP_CTX_get_status(ctx)) < 0
|
||||
|| (status_string = ossl_cmp_PKIStatus_to_string(status)) == NULL)
|
||||
return NULL;
|
||||
printed_chars = BIO_snprintf(write_ptr, bufsize, "%s", status_string);
|
||||
ADVANCE_BUFFER;
|
||||
|
||||
/* failInfo is optional and may be empty */
|
||||
if ((fail_info = OSSL_CMP_CTX_get_failInfoCode(ctx)) > 0) {
|
||||
if (fail_info != 0) {
|
||||
printed_chars = BIO_snprintf(write_ptr, bufsize, "; PKIFailureInfo: ");
|
||||
ADVANCE_BUFFER;
|
||||
for (failure = 0; failure <= OSSL_CMP_PKIFAILUREINFO_MAX; failure++) {
|
||||
@@ -220,7 +202,7 @@ char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf,
|
||||
failure_string = CMP_PKIFAILUREINFO_to_string(failure);
|
||||
if (failure_string != NULL) {
|
||||
printed_chars = BIO_snprintf(write_ptr, bufsize, "%s%s",
|
||||
failure > 0 ? ", " : "",
|
||||
failinfo_found ? ", " : "",
|
||||
failure_string);
|
||||
ADVANCE_BUFFER;
|
||||
failinfo_found = 1;
|
||||
@@ -235,7 +217,6 @@ char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf,
|
||||
}
|
||||
|
||||
/* statusString sequence is optional and may be empty */
|
||||
status_strings = OSSL_CMP_CTX_get0_statusString(ctx);
|
||||
n_status_strings = sk_ASN1_UTF8STRING_num(status_strings);
|
||||
if (n_status_strings > 0) {
|
||||
printed_chars = BIO_snprintf(write_ptr, bufsize, "; StatusString%s: ",
|
||||
@@ -253,13 +234,44 @@ char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf,
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
char *OSSL_CMP_snprint_PKIStatusInfo(const OSSL_CMP_PKISI *statusInfo,
|
||||
char *buf, size_t bufsize)
|
||||
{
|
||||
int failure_info;
|
||||
|
||||
if (statusInfo == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
failure_info = ossl_cmp_pkisi_get_pkifailureinfo(statusInfo);
|
||||
|
||||
return snprint_PKIStatusInfo_parts(ASN1_INTEGER_get(statusInfo->status),
|
||||
failure_info,
|
||||
statusInfo->statusString, buf, bufsize);
|
||||
}
|
||||
|
||||
char *OSSL_CMP_CTX_snprint_PKIStatus(const OSSL_CMP_CTX *ctx, char *buf,
|
||||
size_t bufsize)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return snprint_PKIStatusInfo_parts(OSSL_CMP_CTX_get_status(ctx),
|
||||
OSSL_CMP_CTX_get_failInfoCode(ctx),
|
||||
OSSL_CMP_CTX_get0_statusString(ctx),
|
||||
buf, bufsize);
|
||||
}
|
||||
|
||||
/*-
|
||||
* Creates a new PKIStatusInfo structure and fills it in
|
||||
* returns a pointer to the structure on success, NULL on error
|
||||
* note: strongly overlaps with TS_RESP_CTX_set_status_info()
|
||||
* and TS_RESP_CTX_add_failure_info() in ../ts/ts_rsp_sign.c
|
||||
*/
|
||||
OSSL_CMP_PKISI *ossl_cmp_statusinfo_new(int status, int fail_info,
|
||||
OSSL_CMP_PKISI *OSSL_CMP_STATUSINFO_new(int status, int fail_info,
|
||||
const char *text)
|
||||
{
|
||||
OSSL_CMP_PKISI *si = OSSL_CMP_PKISI_new();
|
||||
|
||||
+21
-1
@@ -144,7 +144,7 @@ int OSSL_CMP_print_to_bio(BIO *bio, const char *component, const char *file,
|
||||
|
||||
#define ERR_PRINT_BUF_SIZE 4096
|
||||
/* this is similar to ERR_print_errors_cb, but uses the CMP-specific cb type */
|
||||
void OSSL_CMP_print_errors_cb(OSSL_cmp_log_cb_t log_fn)
|
||||
void OSSL_CMP_print_errors_cb(OSSL_CMP_log_cb_t log_fn)
|
||||
{
|
||||
unsigned long err;
|
||||
char msg[ERR_PRINT_BUF_SIZE];
|
||||
@@ -320,6 +320,26 @@ STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert)
|
||||
return result;
|
||||
}
|
||||
|
||||
int ossl_cmp_sk_ASN1_UTF8STRING_push_str(STACK_OF(ASN1_UTF8STRING) *sk,
|
||||
const char *text)
|
||||
{
|
||||
ASN1_UTF8STRING *utf8string;
|
||||
|
||||
if (!ossl_assert(sk != NULL && text != NULL))
|
||||
return 0;
|
||||
if ((utf8string = ASN1_UTF8STRING_new()) == NULL)
|
||||
return 0;
|
||||
if (!ASN1_STRING_set(utf8string, text, -1))
|
||||
goto err;
|
||||
if (!sk_ASN1_UTF8STRING_push(sk, utf8string))
|
||||
goto err;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
ASN1_UTF8STRING_free(utf8string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt,
|
||||
const ASN1_OCTET_STRING *src)
|
||||
{
|
||||
|
||||
+98
-58
@@ -167,6 +167,8 @@ int OSSL_CMP_validate_cert_path(OSSL_CMP_CTX *ctx, X509_STORE *trusted_store,
|
||||
CMPerr(0, CMP_R_POTENTIALLY_INVALID_CERTIFICATE);
|
||||
|
||||
err:
|
||||
/* directly output any fresh errors, needed for check_msg_find_cert() */
|
||||
OSSL_CMP_CTX_print_errors(ctx);
|
||||
X509_STORE_CTX_free(csc);
|
||||
return valid;
|
||||
}
|
||||
@@ -250,17 +252,22 @@ static int cert_acceptable(OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
X509_STORE *ts = ctx->trusted;
|
||||
char *sub, *iss;
|
||||
int self_issued = X509_check_issued(cert, cert) == X509_V_OK;
|
||||
char *str;
|
||||
X509_VERIFY_PARAM *vpm = ts != NULL ? X509_STORE_get0_param(ts) : NULL;
|
||||
int time_cmp;
|
||||
|
||||
ossl_cmp_log2(INFO, ctx, " considering %s %s with..", desc1, desc2);
|
||||
if ((sub = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " subject = %s", sub);
|
||||
if ((iss = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " issuer = %s", iss);
|
||||
OPENSSL_free(iss);
|
||||
OPENSSL_free(sub);
|
||||
ossl_cmp_log3(INFO, ctx, " considering %s%s %s with..",
|
||||
self_issued ? "self-issued ": "", desc1, desc2);
|
||||
if ((str = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " subject = %s", str);
|
||||
OPENSSL_free(str);
|
||||
if (!self_issued) {
|
||||
str = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
|
||||
if (str != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " issuer = %s", str);
|
||||
OPENSSL_free(str);
|
||||
}
|
||||
|
||||
if (already_checked(cert, already_checked1)
|
||||
|| already_checked(cert, already_checked2)) {
|
||||
@@ -284,7 +291,7 @@ static int cert_acceptable(OSSL_CMP_CTX *ctx,
|
||||
if (!check_kid(ctx, cert, msg->header->senderKID))
|
||||
return 0;
|
||||
/* acceptable also if there is no senderKID in msg header */
|
||||
ossl_cmp_info(ctx, " cert is acceptable");
|
||||
ossl_cmp_info(ctx, " cert seems acceptable");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -295,38 +302,49 @@ static int check_msg_valid_cert(OSSL_CMP_CTX *ctx, X509_STORE *store,
|
||||
ossl_cmp_warn(ctx, "msg signature verification failed");
|
||||
return 0;
|
||||
}
|
||||
if (!OSSL_CMP_validate_cert_path(ctx, store, scrt)) {
|
||||
ossl_cmp_warn(ctx, "cert path validation failed");
|
||||
return 0;
|
||||
}
|
||||
if (OSSL_CMP_validate_cert_path(ctx, store, scrt))
|
||||
return 1;
|
||||
|
||||
ossl_cmp_warn(ctx,
|
||||
"msg signature validates but cert path validation failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Exceptional handling for 3GPP TS 33.310 [3G/LTE Network Domain Security
|
||||
* (NDS); Authentication Framework (AF)], only to use for IP and if the ctx
|
||||
* option is explicitly set: use self-issued certificates from extraCerts as
|
||||
* trust anchor to validate sender cert and msg -
|
||||
* (NDS); Authentication Framework (AF)], only to use for IP messages
|
||||
* and if the ctx option is explicitly set: use self-issued certificates
|
||||
* from extraCerts as trust anchor to validate sender cert and msg -
|
||||
* provided it also can validate the newly enrolled certificate
|
||||
*/
|
||||
static int check_msg_valid_cert_3gpp(OSSL_CMP_CTX *ctx, X509 *scrt,
|
||||
const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
int valid = 0;
|
||||
X509_STORE *store = X509_STORE_new();
|
||||
X509_STORE *store;
|
||||
|
||||
if (store != NULL /* store does not include CRLs */
|
||||
&& ossl_cmp_X509_STORE_add1_certs(store, msg->extraCerts,
|
||||
if (!ctx->permitTAInExtraCertsForIR)
|
||||
return 0;
|
||||
|
||||
if ((store = X509_STORE_new()) == NULL
|
||||
|| !ossl_cmp_X509_STORE_add1_certs(store, msg->extraCerts,
|
||||
1 /* self-issued only */))
|
||||
valid = check_msg_valid_cert(ctx, store, scrt, msg);
|
||||
if (valid) {
|
||||
goto err;
|
||||
|
||||
/* store does not include CRLs */
|
||||
valid = OSSL_CMP_validate_cert_path(ctx, store, scrt);
|
||||
if (!valid) {
|
||||
ossl_cmp_warn(ctx,
|
||||
"also exceptional 3GPP mode cert path validation failed");
|
||||
} else {
|
||||
/*
|
||||
* verify that the newly enrolled certificate (which is assumed to have
|
||||
* rid == 0) can also be validated with the same trusted store
|
||||
* verify that the newly enrolled certificate (which assumed rid ==
|
||||
* OSSL_CMP_CERTREQID) can also be validated with the same trusted store
|
||||
*/
|
||||
EVP_PKEY *privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
|
||||
OSSL_CMP_CERTRESPONSE *crep =
|
||||
ossl_cmp_certrepmessage_get0_certresponse(msg->body->value.ip, 0);
|
||||
ossl_cmp_certrepmessage_get0_certresponse(msg->body->value.ip,
|
||||
OSSL_CMP_CERTREQID);
|
||||
X509 *newcrt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
|
||||
/*
|
||||
* maybe better use get_cert_status() from cmp_client.c, which catches
|
||||
@@ -335,6 +353,8 @@ static int check_msg_valid_cert_3gpp(OSSL_CMP_CTX *ctx, X509 *scrt,
|
||||
valid = OSSL_CMP_validate_cert_path(ctx, store, newcrt);
|
||||
X509_free(newcrt);
|
||||
}
|
||||
|
||||
err:
|
||||
X509_STORE_free(store);
|
||||
return valid;
|
||||
}
|
||||
@@ -393,8 +413,13 @@ static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (mode_3gpp
|
||||
&& ((!ctx->permitTAInExtraCertsForIR
|
||||
|| ossl_cmp_msg_get_bodytype(msg) != OSSL_CMP_PKIBODY_IP)))
|
||||
return 0;
|
||||
|
||||
ossl_cmp_info(ctx,
|
||||
mode_3gpp ? "failed; trying now 3GPP mode trusting extraCerts"
|
||||
mode_3gpp ? "normal mode failed; trying now 3GPP mode trusting extraCerts"
|
||||
: "trying first normal mode using trust store");
|
||||
if (check_msg_with_certs(ctx, msg->extraCerts, "extraCerts",
|
||||
NULL, NULL, msg, mode_3gpp))
|
||||
@@ -418,6 +443,12 @@ static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int no_log_cb(const char *func, const char *file, int line,
|
||||
OSSL_CMP_severity level, const char *msg)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* verify message signature with any acceptable and valid candidate cert */
|
||||
static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
@@ -426,7 +457,7 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
char *sname = NULL;
|
||||
char *skid_str = NULL;
|
||||
const ASN1_OCTET_STRING *skid = msg->header->senderKID;
|
||||
OSSL_cmp_log_cb_t backup_log_cb = ctx->log_cb;
|
||||
OSSL_CMP_log_cb_t backup_log_cb = ctx->log_cb;
|
||||
int res = 0;
|
||||
|
||||
if (sender == NULL || msg->body == NULL)
|
||||
@@ -436,13 +467,18 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* dump any hitherto errors to avoid confusion when printing further ones */
|
||||
OSSL_CMP_CTX_print_errors(ctx);
|
||||
|
||||
/*
|
||||
* try first cached scrt, used successfully earlier in same transaction,
|
||||
* for validating this and any further msgs where extraCerts may be left out
|
||||
*/
|
||||
if (scrt != NULL) {
|
||||
(void)ERR_set_mark();
|
||||
if (scrt != NULL
|
||||
&& cert_acceptable(ctx, "previously validated", "sender cert", scrt,
|
||||
ossl_cmp_info(ctx,
|
||||
"trying to verify msg signature with previously validated cert");
|
||||
if (cert_acceptable(ctx, "previously validated", "sender cert", scrt,
|
||||
NULL, NULL, msg)
|
||||
&& (check_msg_valid_cert(ctx, ctx->trusted, scrt, msg)
|
||||
|| check_msg_valid_cert_3gpp(ctx, scrt, msg))) {
|
||||
@@ -450,33 +486,31 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
return 1;
|
||||
}
|
||||
(void)ERR_pop_to_mark();
|
||||
|
||||
/* release any cached sender cert that proved no more successfully usable */
|
||||
/* cached sender cert has shown to be no more successfully usable */
|
||||
(void)ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL);
|
||||
}
|
||||
|
||||
/* enable clearing irrelevant errors in attempts to validate sender certs */
|
||||
(void)ERR_set_mark();
|
||||
ctx->log_cb = NULL; /* temporarily disable logging diagnostic info */
|
||||
|
||||
if (check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */)
|
||||
|| check_msg_all_certs(ctx, msg, 1 /* 3gpp */)) {
|
||||
/* discard any diagnostic info on trying to use certs */
|
||||
ctx->log_cb = backup_log_cb; /* restore any logging */
|
||||
ctx->log_cb = no_log_cb; /* temporarily disable logging */
|
||||
res = check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */)
|
||||
|| check_msg_all_certs(ctx, msg, 1 /* 3gpp */);
|
||||
ctx->log_cb = backup_log_cb;
|
||||
if (res) {
|
||||
/* discard any diagnostic information on trying to use certs */
|
||||
(void)ERR_pop_to_mark();
|
||||
res = 1;
|
||||
goto end;
|
||||
}
|
||||
/* failed finding a sender cert that verifies the message signature */
|
||||
ctx->log_cb = backup_log_cb; /* restore any logging */
|
||||
(void)ERR_clear_last_mark();
|
||||
|
||||
sname = X509_NAME_oneline(sender->d.directoryName, NULL, 0);
|
||||
skid_str = skid == NULL ? NULL
|
||||
: OPENSSL_buf2hexstr(skid->data, skid->length);
|
||||
if (ctx->log_cb != NULL) {
|
||||
ossl_cmp_info(ctx, "verifying msg signature with valid cert that..");
|
||||
ossl_cmp_info(ctx, "trying to verify msg signature with a valid cert that..");
|
||||
if (sname != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, "matches msg sender name = %s", sname);
|
||||
ossl_cmp_log1(INFO, ctx, "matches msg sender = %s", sname);
|
||||
if (skid_str != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, "matches msg senderKID = %s", skid_str);
|
||||
else
|
||||
@@ -543,6 +577,11 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
switch (nid) {
|
||||
/* 5.1.3.1. Shared Secret Information */
|
||||
case NID_id_PasswordBasedMAC:
|
||||
if (ctx->secretValue == 0) {
|
||||
CMPerr(0, CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (verify_PBMAC(msg, ctx->secretValue)) {
|
||||
/*
|
||||
* RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is
|
||||
@@ -633,8 +672,8 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
*
|
||||
* Ensures that:
|
||||
* it has a valid body type
|
||||
* its protection is valid or absent (allowed only if callback function is
|
||||
* present and function yields non-zero result using also supplied argument)
|
||||
* its protection is valid (or invalid/absent, but only if a callback function
|
||||
* is present and yields a positive result using also the supplied argument)
|
||||
* its transaction ID matches the previous transaction ID stored in ctx (if any)
|
||||
* its recipNonce matches the previous senderNonce stored in the ctx (if any)
|
||||
*
|
||||
@@ -660,35 +699,29 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
if (msg->header->protectionAlg != 0) {
|
||||
/* detect explicitly permitted exceptions for invalid protection */
|
||||
if (!OSSL_CMP_validate_msg(ctx, msg)
|
||||
&& (cb == NULL || !(*cb)(ctx, msg, 1, cb_arg))) {
|
||||
&& (cb == NULL || (*cb)(ctx, msg, 1, cb_arg) <= 0)) {
|
||||
CMPerr(0, CMP_R_ERROR_VALIDATING_PROTECTION);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* detect explicitly permitted exceptions for missing protection */
|
||||
if (cb == NULL || !(*cb)(ctx, msg, 0, cb_arg)) {
|
||||
if (cb == NULL || (*cb)(ctx, msg, 0, cb_arg) <= 0) {
|
||||
CMPerr(0, CMP_R_MISSING_PROTECTION);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Store any provided extraCerts in ctx for future use,
|
||||
* such that they are available to ctx->certConf_cb and
|
||||
* the peer does not need to send them again in the same transaction.
|
||||
* For efficiency, the extraCerts are prepended so they get used first.
|
||||
*/
|
||||
if (!ossl_cmp_sk_X509_add1_certs(ctx->untrusted_certs, msg->extraCerts,
|
||||
0 /* this allows self-issued certs */,
|
||||
1 /* no_dups */, 1 /* prepend */))
|
||||
return -1;
|
||||
|
||||
/* check CMP version number in header */
|
||||
if (ossl_cmp_hdr_get_pvno(OSSL_CMP_MSG_get0_header(msg)) != OSSL_CMP_PVNO) {
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PVNO);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((rcvd_type = ossl_cmp_msg_get_bodytype(msg)) < 0) {
|
||||
CMPerr(0, CMP_R_PKIBODY_ERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* compare received transactionID with the expected one in previous msg */
|
||||
if (ctx->transactionID != NULL
|
||||
&& (msg->header->transactionID == NULL
|
||||
@@ -720,10 +753,17 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
&& !OSSL_CMP_CTX_set1_transactionID(ctx, msg->header->transactionID))
|
||||
return -1;
|
||||
|
||||
if ((rcvd_type = ossl_cmp_msg_get_bodytype(msg)) < 0) {
|
||||
CMPerr(0, CMP_R_PKIBODY_ERROR);
|
||||
/*
|
||||
* Store any provided extraCerts in ctx for future use,
|
||||
* such that they are available to ctx->certConf_cb and
|
||||
* the peer does not need to send them again in the same transaction.
|
||||
* For efficiency, the extraCerts are prepended so they get used first.
|
||||
*/
|
||||
if (!ossl_cmp_sk_X509_add1_certs(ctx->untrusted_certs, msg->extraCerts,
|
||||
0 /* this allows self-issued certs */,
|
||||
1 /* no_dups */, 1 /* prepend */))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rcvd_type;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 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
|
||||
|
||||
@@ -248,6 +248,27 @@ int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
|
||||
size_t enckeylen;
|
||||
size_t ceklen;
|
||||
CMS_EncryptedContentInfo *ec;
|
||||
|
||||
{
|
||||
/*
|
||||
* TODO(3.0) Remove this when we have functionality to deserialize
|
||||
* parameters in EVP_PKEY form from an X509_ALGOR.
|
||||
* This is needed to be able to replace the EC_KEY specific decoding
|
||||
* that happens in ecdh_cms_set_peerkey() (crypto/ec/ec_ameth.c)
|
||||
*
|
||||
* THIS IS TEMPORARY
|
||||
*/
|
||||
EVP_PKEY_CTX *pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
|
||||
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
|
||||
|
||||
EVP_PKEY_get0(pkey);
|
||||
if (EVP_PKEY_id(pkey) == EVP_PKEY_NONE) {
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_DECRYPT,
|
||||
CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
enckeylen = rek->encryptedKey->length;
|
||||
enckey = rek->encryptedKey->data;
|
||||
/* Setup all parameters to derive KEK */
|
||||
@@ -446,6 +467,32 @@ int cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms,
|
||||
STACK_OF(CMS_RecipientEncryptedKey) *reks;
|
||||
int i;
|
||||
|
||||
{
|
||||
/*
|
||||
* TODO(3.0) Remove this when we have figured out all the details
|
||||
* need to set up encryption right. With legacy keys, a *lot* is
|
||||
* happening in the CMS specific EVP_PKEY_ASN1_METHOD functions,
|
||||
* such as automatically setting a default KDF type, KDF digest,
|
||||
* all that kind of stuff.
|
||||
* With EVP_SIGNATURE, setting a default digest is done by getting
|
||||
* the default MD for the key, and then inject that back into the
|
||||
* signature implementation... we could do something similar with
|
||||
* CMS, possibly using CMS specific OSSL_PARAM keys, just like we
|
||||
* have for certain AlgorithmIdentifier retrievals.
|
||||
*
|
||||
* THIS IS TEMPORARY
|
||||
*/
|
||||
EVP_PKEY_CTX *pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
|
||||
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
|
||||
|
||||
EVP_PKEY_get0(pkey);
|
||||
if (EVP_PKEY_id(pkey) == EVP_PKEY_NONE) {
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT,
|
||||
CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ri->type != CMS_RECIPINFO_AGREE) {
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, CMS_R_NOT_KEY_AGREEMENT);
|
||||
return 0;
|
||||
|
||||
@@ -174,7 +174,7 @@ int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out)
|
||||
* the "CONF classic" functions, for consistency.
|
||||
*/
|
||||
|
||||
CONF *NCONF_new(CONF_METHOD *meth)
|
||||
CONF *NCONF_new_with_libctx(OPENSSL_CTX *libctx, CONF_METHOD *meth)
|
||||
{
|
||||
CONF *ret;
|
||||
|
||||
@@ -183,13 +183,19 @@ CONF *NCONF_new(CONF_METHOD *meth)
|
||||
|
||||
ret = meth->create(meth);
|
||||
if (ret == NULL) {
|
||||
CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE);
|
||||
CONFerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
ret->libctx = libctx;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
CONF *NCONF_new(CONF_METHOD *meth)
|
||||
{
|
||||
return NCONF_new_with_libctx(NULL, meth);
|
||||
}
|
||||
|
||||
void NCONF_free(CONF *conf)
|
||||
{
|
||||
if (conf == NULL)
|
||||
|
||||
+33
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2020 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
|
||||
@@ -13,8 +13,10 @@
|
||||
#include <openssl/crypto.h>
|
||||
#include "internal/conf.h"
|
||||
#include "internal/dso.h"
|
||||
#include "internal/thread_once.h"
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/trace.h>
|
||||
#include <openssl/engine.h>
|
||||
|
||||
#define DSO_mod_init_name "OPENSSL_init"
|
||||
#define DSO_mod_finish_name "OPENSSL_finish"
|
||||
@@ -55,6 +57,8 @@ struct conf_imodule_st {
|
||||
static STACK_OF(CONF_MODULE) *supported_modules = NULL;
|
||||
static STACK_OF(CONF_IMODULE) *initialized_modules = NULL;
|
||||
|
||||
static CRYPTO_ONCE load_builtin_modules = CRYPTO_ONCE_STATIC_INIT;
|
||||
|
||||
static void module_free(CONF_MODULE *md);
|
||||
static void module_finish(CONF_IMODULE *imod);
|
||||
static int module_run(const CONF *cnf, const char *name, const char *value,
|
||||
@@ -113,22 +117,25 @@ int CONF_modules_load(const CONF *cnf, const char *appname,
|
||||
|
||||
}
|
||||
|
||||
int CONF_modules_load_file(const char *filename, const char *appname,
|
||||
unsigned long flags)
|
||||
int CONF_modules_load_file_with_libctx(OPENSSL_CTX *libctx,
|
||||
const char *filename,
|
||||
const char *appname, unsigned long flags)
|
||||
{
|
||||
char *file = NULL;
|
||||
CONF *conf = NULL;
|
||||
int ret = 0;
|
||||
conf = NCONF_new(NULL);
|
||||
|
||||
conf = NCONF_new_with_libctx(libctx, NULL);
|
||||
if (conf == NULL)
|
||||
goto err;
|
||||
|
||||
if (filename == NULL) {
|
||||
file = CONF_get1_default_config_file();
|
||||
if (!file)
|
||||
if (file == NULL)
|
||||
goto err;
|
||||
} else
|
||||
} else {
|
||||
file = (char *)filename;
|
||||
}
|
||||
|
||||
if (NCONF_load(conf, file, NULL) <= 0) {
|
||||
if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&
|
||||
@@ -152,12 +159,32 @@ int CONF_modules_load_file(const char *filename, const char *appname,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CONF_modules_load_file(const char *filename,
|
||||
const char *appname, unsigned long flags)
|
||||
{
|
||||
return CONF_modules_load_file_with_libctx(NULL, filename, appname, flags);
|
||||
}
|
||||
|
||||
DEFINE_RUN_ONCE_STATIC(do_load_builtin_modules)
|
||||
{
|
||||
OPENSSL_load_builtin_modules();
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
/* Need to load ENGINEs */
|
||||
ENGINE_load_builtin_engines();
|
||||
#endif
|
||||
ERR_clear_error();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int module_run(const CONF *cnf, const char *name, const char *value,
|
||||
unsigned long flags)
|
||||
{
|
||||
CONF_MODULE *md;
|
||||
int ret;
|
||||
|
||||
if (!RUN_ONCE(&load_builtin_modules, do_load_builtin_modules))
|
||||
return -1;
|
||||
|
||||
md = module_find(name);
|
||||
|
||||
/* Module not found: try to load DSO */
|
||||
|
||||
@@ -59,12 +59,6 @@ int openssl_config_int(const OPENSSL_INIT_SETTINGS *settings)
|
||||
filename, appname, flags);
|
||||
#endif
|
||||
|
||||
OPENSSL_load_builtin_modules();
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
/* Need to load ENGINEs */
|
||||
ENGINE_load_builtin_engines();
|
||||
#endif
|
||||
ERR_clear_error();
|
||||
#ifndef OPENSSL_SYS_UEFI
|
||||
ret = CONF_modules_load_file(filename, appname, flags);
|
||||
#endif
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include "crypto/cryptlib.h"
|
||||
#include <openssl/conf.h>
|
||||
#include "internal/thread_once.h"
|
||||
#include "internal/property.h"
|
||||
|
||||
@@ -145,6 +146,13 @@ OPENSSL_CTX *OPENSSL_CTX_new(void)
|
||||
return ctx;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
int OPENSSL_CTX_load_config(OPENSSL_CTX *ctx, const char *config_file)
|
||||
{
|
||||
return CONF_modules_load_file_with_libctx(ctx, config_file, NULL, 0) > 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void OPENSSL_CTX_free(OPENSSL_CTX *ctx)
|
||||
{
|
||||
if (ctx != NULL)
|
||||
@@ -164,6 +172,15 @@ OPENSSL_CTX *openssl_ctx_get_concrete(OPENSSL_CTX *ctx)
|
||||
return ctx;
|
||||
}
|
||||
|
||||
int openssl_ctx_is_default(OPENSSL_CTX *ctx)
|
||||
{
|
||||
#ifndef FIPS_MODE
|
||||
if (ctx == NULL || ctx == default_context)
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void openssl_ctx_generic_new(void *parent_ign, void *ptr_ign,
|
||||
CRYPTO_EX_DATA *ad, int index,
|
||||
long argl_ign, void *argp)
|
||||
|
||||
+10
-3
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 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
|
||||
@@ -30,6 +30,15 @@ static const ERR_STRING_DATA CRMF_str_reasons[] = {
|
||||
"iterationcount below 100"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_MALFORMED_IV), "malformed iv"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_NULL_ARGUMENT), "null argument"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY),
|
||||
"popo inconsistent public key"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING), "popo missing"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING_PUBLIC_KEY),
|
||||
"popo missing public key"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING_SUBJECT),
|
||||
"popo missing subject"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED),
|
||||
"popo raverified not accepted"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_MAC_ALGOR_FAILURE),
|
||||
"setting mac algor failure"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_OWF_ALGOR_FAILURE),
|
||||
@@ -44,8 +53,6 @@ static const ERR_STRING_DATA CRMF_str_reasons[] = {
|
||||
"unsupported method for creating popo"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_POPO_METHOD),
|
||||
"unsupported popo method"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED),
|
||||
"unsupported popo not accepted"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
|
||||
+64
-83
@@ -303,7 +303,7 @@ static int crmf_asn1_get_int(const ASN1_INTEGER *a)
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
int OSSL_CRMF_MSG_get_certReqId(OSSL_CRMF_MSG *crm)
|
||||
int OSSL_CRMF_MSG_get_certReqId(const OSSL_CRMF_MSG *crm)
|
||||
{
|
||||
if (crm == NULL || /* not really needed: */ crm->certReq == NULL) {
|
||||
CRMFerr(CRMF_F_OSSL_CRMF_MSG_GET_CERTREQID, CRMF_R_NULL_ARGUMENT);
|
||||
@@ -367,65 +367,30 @@ static int CRMF_poposigningkey_init(OSSL_CRMF_POPOSIGNINGKEY *ps,
|
||||
OSSL_CRMF_CERTREQUEST *cr,
|
||||
EVP_PKEY *pkey, int dgst)
|
||||
{
|
||||
int len;
|
||||
size_t crlen;
|
||||
size_t siglen;
|
||||
unsigned char *crder = NULL, *sig = NULL;
|
||||
int alg_nid = 0;
|
||||
int md_nid = 0;
|
||||
const EVP_MD *alg = NULL;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
int ret = 0;
|
||||
EVP_MD *fetched_md = NULL;
|
||||
const EVP_MD *md = EVP_get_digestbynid(dgst);
|
||||
|
||||
if (ps == NULL || cr == NULL || pkey == NULL) {
|
||||
CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* OpenSSL defaults all bit strings to be encoded as ASN.1 NamedBitList */
|
||||
ps->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
|
||||
ps->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
|
||||
/* If we didn't find legacy MD, we try an implicit fetch */
|
||||
if (md == NULL)
|
||||
md = fetched_md = EVP_MD_fetch(NULL, OBJ_nid2sn(dgst), NULL);
|
||||
|
||||
len = i2d_OSSL_CRMF_CERTREQUEST(cr, &crder);
|
||||
if (len < 0 || crder == NULL) {
|
||||
CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_ERROR);
|
||||
goto err;
|
||||
}
|
||||
crlen = (size_t)len;
|
||||
|
||||
if (!OBJ_find_sigid_by_algs(&alg_nid, dgst, EVP_PKEY_id(pkey))) {
|
||||
if (md == NULL) {
|
||||
CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT,
|
||||
CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY);
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
if (!OBJ_find_sigid_algs(alg_nid, &md_nid, NULL)
|
||||
|| (alg = EVP_get_digestbynid(md_nid)) == NULL) {
|
||||
CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT,
|
||||
CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY);
|
||||
goto err;
|
||||
}
|
||||
if (!X509_ALGOR_set0(ps->algorithmIdentifier, OBJ_nid2obj(alg_nid),
|
||||
V_ASN1_NULL, NULL)
|
||||
|| (ctx = EVP_MD_CTX_new()) == NULL
|
||||
|| EVP_DigestSignInit(ctx, NULL, alg, NULL, pkey) <= 0
|
||||
|| EVP_DigestSignUpdate(ctx, crder, crlen) <= 0
|
||||
|| EVP_DigestSignFinal(ctx, NULL, &siglen) <= 0) {
|
||||
CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if ((sig = OPENSSL_malloc(siglen)) == NULL)
|
||||
goto err;
|
||||
if (EVP_DigestSignFinal(ctx, sig, &siglen) <= 0
|
||||
|| !ASN1_BIT_STRING_set(ps->signature, sig, siglen)) {
|
||||
CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_ERROR);
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
OPENSSL_free(crder);
|
||||
EVP_MD_CTX_free(ctx);
|
||||
OPENSSL_free(sig);
|
||||
ret = ASN1_item_sign(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST),
|
||||
ps->algorithmIdentifier, NULL, ps->signature,
|
||||
cr, pkey, md);
|
||||
|
||||
EVP_MD_free(fetched_md);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -520,21 +485,29 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
|
||||
X509_PUBKEY *pubkey = NULL;
|
||||
OSSL_CRMF_POPOSIGNINGKEY *sig = NULL;
|
||||
|
||||
if (reqs == NULL
|
||||
|| (req = sk_OSSL_CRMF_MSG_value(reqs, rid)) == NULL
|
||||
|| req->popo == NULL) {
|
||||
CRMFerr(CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO,
|
||||
CRMF_R_NULL_ARGUMENT);
|
||||
if (reqs == NULL || (req = sk_OSSL_CRMF_MSG_value(reqs, rid)) == NULL) {
|
||||
CRMFerr(CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO, CRMF_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (req->popo == NULL) {
|
||||
CRMFerr(0, CRMF_R_POPO_MISSING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (req->popo->type) {
|
||||
case OSSL_CRMF_POPO_RAVERIFIED:
|
||||
if (acceptRAVerified)
|
||||
return 1;
|
||||
if (!acceptRAVerified) {
|
||||
CRMFerr(0, CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case OSSL_CRMF_POPO_SIGNATURE:
|
||||
pubkey = req->certReq->certTemplate->publicKey;
|
||||
if (pubkey == NULL) {
|
||||
CRMFerr(0, CRMF_R_POPO_MISSING_PUBLIC_KEY);
|
||||
return 0;
|
||||
}
|
||||
sig = req->popo->value.signature;
|
||||
if (sig->poposkInput != NULL) {
|
||||
/*
|
||||
@@ -542,26 +515,34 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
|
||||
* the public key from the certificate template. This MUST be
|
||||
* exactly the same value as contained in the certificate template.
|
||||
*/
|
||||
const ASN1_ITEM *rptr = ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT);
|
||||
|
||||
if (pubkey == NULL
|
||||
|| sig->poposkInput->publicKey == NULL
|
||||
|| X509_PUBKEY_cmp(pubkey, sig->poposkInput->publicKey)
|
||||
|| ASN1_item_verify(rptr, sig->algorithmIdentifier,
|
||||
sig->signature, sig->poposkInput,
|
||||
X509_PUBKEY_get0(pubkey)) < 1)
|
||||
break;
|
||||
} else {
|
||||
if (pubkey == NULL
|
||||
|| req->certReq->certTemplate->subject == NULL
|
||||
|| ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST),
|
||||
sig->algorithmIdentifier,
|
||||
sig->signature,
|
||||
req->certReq,
|
||||
X509_PUBKEY_get0(pubkey)) < 1)
|
||||
break;
|
||||
if (sig->poposkInput->publicKey == NULL) {
|
||||
CRMFerr(0, CRMF_R_POPO_MISSING_PUBLIC_KEY);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
if (X509_PUBKEY_cmp(pubkey, sig->poposkInput->publicKey) != 0) {
|
||||
CRMFerr(0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* TODO check the contents of the authInfo sub-field,
|
||||
* see RFC 4211 https://tools.ietf.org/html/rfc4211#section-4.1
|
||||
*/
|
||||
if (ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT),
|
||||
sig->algorithmIdentifier, sig->signature,
|
||||
sig->poposkInput,
|
||||
X509_PUBKEY_get0(pubkey)) < 1)
|
||||
return 0;
|
||||
} else {
|
||||
if (req->certReq->certTemplate->subject == NULL) {
|
||||
CRMFerr(0, CRMF_R_POPO_MISSING_SUBJECT);
|
||||
return 0;
|
||||
}
|
||||
if (ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST),
|
||||
sig->algorithmIdentifier, sig->signature,
|
||||
req->certReq, X509_PUBKEY_get0(pubkey)) < 1)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case OSSL_CRMF_POPO_KEYENC:
|
||||
/*
|
||||
* TODO: when OSSL_CMP_certrep_new() supports encrypted certs,
|
||||
@@ -575,25 +556,25 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
|
||||
CRMF_R_UNSUPPORTED_POPO_METHOD);
|
||||
return 0;
|
||||
}
|
||||
CRMFerr(CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO,
|
||||
CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* retrieves the serialNumber of the given cert template or NULL on error */
|
||||
ASN1_INTEGER *OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(OSSL_CRMF_CERTTEMPLATE *tmpl)
|
||||
ASN1_INTEGER
|
||||
*OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl)
|
||||
{
|
||||
return tmpl != NULL ? tmpl->serialNumber : NULL;
|
||||
}
|
||||
|
||||
/* retrieves the issuer name of the given cert template or NULL on error */
|
||||
X509_NAME *OSSL_CRMF_CERTTEMPLATE_get0_issuer(OSSL_CRMF_CERTTEMPLATE *tmpl)
|
||||
const X509_NAME
|
||||
*OSSL_CRMF_CERTTEMPLATE_get0_issuer(const OSSL_CRMF_CERTTEMPLATE *tmpl)
|
||||
{
|
||||
return tmpl != NULL ? tmpl->issuer : NULL;
|
||||
}
|
||||
|
||||
/* retrieves the issuer name of the given CertId or NULL on error */
|
||||
X509_NAME *OSSL_CRMF_CERTID_get0_issuer(const OSSL_CRMF_CERTID *cid)
|
||||
const X509_NAME *OSSL_CRMF_CERTID_get0_issuer(const OSSL_CRMF_CERTID *cid)
|
||||
{
|
||||
return cid != NULL && cid->issuer->type == GEN_DIRNAME ?
|
||||
cid->issuer->d.directoryName : NULL;
|
||||
@@ -619,9 +600,9 @@ int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl,
|
||||
CRMFerr(CRMF_F_OSSL_CRMF_CERTTEMPLATE_FILL, CRMF_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
if (subject != NULL && !X509_NAME_set(&tmpl->subject, subject))
|
||||
if (subject != NULL && !X509_NAME_set((X509_NAME **)&tmpl->subject, subject))
|
||||
return 0;
|
||||
if (issuer != NULL && !X509_NAME_set(&tmpl->issuer, issuer))
|
||||
if (issuer != NULL && !X509_NAME_set((X509_NAME **)&tmpl->issuer, issuer))
|
||||
return 0;
|
||||
if (serial != NULL) {
|
||||
ASN1_INTEGER_free(tmpl->serialNumber);
|
||||
@@ -641,7 +622,7 @@ int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl,
|
||||
* returns a pointer to the decrypted certificate
|
||||
* returns NULL on error or if no certificate available
|
||||
*/
|
||||
X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert,
|
||||
X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
|
||||
EVP_PKEY *pkey)
|
||||
{
|
||||
X509 *cert = NULL; /* decrypted certificate */
|
||||
|
||||
@@ -315,9 +315,9 @@ struct ossl_crmf_certtemplate_st {
|
||||
/* This field is assigned by the CA during certificate creation */
|
||||
X509_ALGOR *signingAlg; /* signingAlg MUST be omitted */
|
||||
/* This field is assigned by the CA during certificate creation */
|
||||
X509_NAME *issuer;
|
||||
const X509_NAME *issuer;
|
||||
OSSL_CRMF_OPTIONALVALIDITY *validity;
|
||||
X509_NAME *subject;
|
||||
const X509_NAME *subject;
|
||||
X509_PUBKEY *publicKey;
|
||||
ASN1_BIT_STRING *issuerUID; /* deprecated in version 2 */
|
||||
/* According to rfc 3280: UniqueIdentifier ::= BIT STRING */
|
||||
|
||||
+14
-5
@@ -132,7 +132,9 @@ SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64,
|
||||
* 0 on decoding failure, or invalid parameter if any
|
||||
* -1 on internal (malloc) failure
|
||||
*/
|
||||
int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *name)
|
||||
int CTLOG_new_from_base64_with_libctx(CTLOG **ct_log, const char *pkey_base64,
|
||||
const char *name, OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
unsigned char *pkey_der = NULL;
|
||||
int pkey_der_len;
|
||||
@@ -140,13 +142,13 @@ int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *n
|
||||
EVP_PKEY *pkey = NULL;
|
||||
|
||||
if (ct_log == NULL) {
|
||||
CTerr(CT_F_CTLOG_NEW_FROM_BASE64, ERR_R_PASSED_INVALID_ARGUMENT);
|
||||
CTerr(0, ERR_R_PASSED_INVALID_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkey_der_len = ct_base64_decode(pkey_base64, &pkey_der);
|
||||
if (pkey_der_len < 0) {
|
||||
CTerr(CT_F_CTLOG_NEW_FROM_BASE64, CT_R_LOG_CONF_INVALID_KEY);
|
||||
CTerr(0, CT_R_LOG_CONF_INVALID_KEY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -154,11 +156,11 @@ int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *n
|
||||
pkey = d2i_PUBKEY(NULL, &p, pkey_der_len);
|
||||
OPENSSL_free(pkey_der);
|
||||
if (pkey == NULL) {
|
||||
CTerr(CT_F_CTLOG_NEW_FROM_BASE64, CT_R_LOG_CONF_INVALID_KEY);
|
||||
CTerr(0, CT_R_LOG_CONF_INVALID_KEY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*ct_log = CTLOG_new(pkey, name);
|
||||
*ct_log = CTLOG_new_with_libctx(pkey, name, libctx, propq);
|
||||
if (*ct_log == NULL) {
|
||||
EVP_PKEY_free(pkey);
|
||||
return 0;
|
||||
@@ -166,3 +168,10 @@ int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *n
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64,
|
||||
const char *name)
|
||||
{
|
||||
return CTLOG_new_from_base64_with_libctx(ct_log, pkey_base64, name, NULL,
|
||||
NULL);
|
||||
}
|
||||
@@ -100,6 +100,9 @@ struct sct_ctx_st {
|
||||
size_t prederlen;
|
||||
/* milliseconds since epoch (to check that the SCT isn't from the future) */
|
||||
uint64_t epoch_time_in_ms;
|
||||
|
||||
OPENSSL_CTX *libctx;
|
||||
char *propq;
|
||||
};
|
||||
|
||||
/* Context when evaluating whether a Certificate Transparency policy is met */
|
||||
@@ -109,12 +112,15 @@ struct ct_policy_eval_ctx_st {
|
||||
CTLOG_STORE *log_store;
|
||||
/* milliseconds since epoch (to check that SCTs aren't from the future) */
|
||||
uint64_t epoch_time_in_ms;
|
||||
|
||||
OPENSSL_CTX *libctx;
|
||||
char *propq;
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates a new context for verifying an SCT.
|
||||
*/
|
||||
SCT_CTX *SCT_CTX_new(void);
|
||||
SCT_CTX *SCT_CTX_new(OPENSSL_CTX *ctx, const char *propq);
|
||||
/*
|
||||
* Deletes an SCT verification context.
|
||||
*/
|
||||
|
||||
+61
-15
@@ -22,6 +22,8 @@
|
||||
* Information about a CT log server.
|
||||
*/
|
||||
struct ctlog_st {
|
||||
OPENSSL_CTX *libctx;
|
||||
char *propq;
|
||||
char *name;
|
||||
uint8_t log_id[CT_V1_HASHLEN];
|
||||
EVP_PKEY *public_key;
|
||||
@@ -32,6 +34,8 @@ struct ctlog_st {
|
||||
* It takes ownership of any CTLOG instances added to it.
|
||||
*/
|
||||
struct ctlog_store_st {
|
||||
OPENSSL_CTX *libctx;
|
||||
char *propq;
|
||||
STACK_OF(CTLOG) *logs;
|
||||
};
|
||||
|
||||
@@ -70,53 +74,78 @@ static void ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX* ctx)
|
||||
}
|
||||
|
||||
/* Converts a log's public key into a SHA256 log ID */
|
||||
static int ct_v1_log_id_from_pkey(EVP_PKEY *pkey,
|
||||
unsigned char log_id[CT_V1_HASHLEN])
|
||||
static int ct_v1_log_id_from_pkey(CTLOG *log, EVP_PKEY *pkey)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char *pkey_der = NULL;
|
||||
int pkey_der_len = i2d_PUBKEY(pkey, &pkey_der);
|
||||
unsigned int len;
|
||||
EVP_MD *sha256 = NULL;
|
||||
|
||||
if (pkey_der_len <= 0) {
|
||||
CTerr(CT_F_CT_V1_LOG_ID_FROM_PKEY, CT_R_LOG_KEY_INVALID);
|
||||
goto err;
|
||||
}
|
||||
sha256 = EVP_MD_fetch(log->libctx, "SHA2-256", log->propq);
|
||||
if (sha256 == NULL) {
|
||||
CTerr(CT_F_CT_V1_LOG_ID_FROM_PKEY, ERR_LIB_EVP);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = EVP_Digest(pkey_der, pkey_der_len, log_id, &len, EVP_sha256(), NULL);
|
||||
ret = EVP_Digest(pkey_der, pkey_der_len, log->log_id, &len, sha256,
|
||||
NULL);
|
||||
err:
|
||||
EVP_MD_free(sha256);
|
||||
OPENSSL_free(pkey_der);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CTLOG_STORE *CTLOG_STORE_new(void)
|
||||
CTLOG_STORE *CTLOG_STORE_new_with_libctx(OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
CTLOG_STORE *ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
CTerr(CT_F_CTLOG_STORE_NEW, ERR_R_MALLOC_FAILURE);
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->logs = sk_CTLOG_new_null();
|
||||
if (ret->logs == NULL)
|
||||
ret->libctx = libctx;
|
||||
if (propq != NULL) {
|
||||
ret->propq = OPENSSL_strdup(propq);
|
||||
if (ret->propq == NULL) {
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
ret->logs = sk_CTLOG_new_null();
|
||||
if (ret->logs == NULL) {
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return ret;
|
||||
err:
|
||||
OPENSSL_free(ret);
|
||||
CTLOG_STORE_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CTLOG_STORE *CTLOG_STORE_new(void)
|
||||
{
|
||||
return CTLOG_STORE_new_with_libctx(NULL, NULL);
|
||||
}
|
||||
|
||||
void CTLOG_STORE_free(CTLOG_STORE *store)
|
||||
{
|
||||
if (store != NULL) {
|
||||
OPENSSL_free(store->propq);
|
||||
sk_CTLOG_pop_free(store->logs, CTLOG_free);
|
||||
OPENSSL_free(store);
|
||||
}
|
||||
}
|
||||
|
||||
static int ctlog_new_from_conf(CTLOG **ct_log, const CONF *conf, const char *section)
|
||||
static int ctlog_new_from_conf(CTLOG_STORE *store, CTLOG **ct_log,
|
||||
const CONF *conf, const char *section)
|
||||
{
|
||||
const char *description = NCONF_get_string(conf, section, "description");
|
||||
char *pkey_base64;
|
||||
@@ -132,7 +161,8 @@ static int ctlog_new_from_conf(CTLOG **ct_log, const CONF *conf, const char *sec
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CTLOG_new_from_base64(ct_log, pkey_base64, description);
|
||||
return CTLOG_new_from_base64_with_libctx(ct_log, pkey_base64, description,
|
||||
store->libctx, store->propq);
|
||||
}
|
||||
|
||||
int CTLOG_STORE_load_default_file(CTLOG_STORE *store)
|
||||
@@ -168,7 +198,7 @@ static int ctlog_store_load_log(const char *log_name, int log_name_len,
|
||||
if (tmp == NULL)
|
||||
goto mem_err;
|
||||
|
||||
ret = ctlog_new_from_conf(&ct_log, load_ctx->conf, tmp);
|
||||
ret = ctlog_new_from_conf(load_ctx->log_store, &ct_log, load_ctx->conf, tmp);
|
||||
OPENSSL_free(tmp);
|
||||
|
||||
if (ret < 0) {
|
||||
@@ -234,22 +264,32 @@ end:
|
||||
* Takes ownership of the public key.
|
||||
* Copies the name.
|
||||
*/
|
||||
CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name)
|
||||
CTLOG *CTLOG_new_with_libctx(EVP_PKEY *public_key, const char *name,
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
CTLOG *ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE);
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->libctx = libctx;
|
||||
if (propq != NULL) {
|
||||
ret->name = OPENSSL_strdup(propq);
|
||||
if (ret->propq == NULL) {
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
ret->name = OPENSSL_strdup(name);
|
||||
if (ret->name == NULL) {
|
||||
CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE);
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ct_v1_log_id_from_pkey(public_key, ret->log_id) != 1)
|
||||
if (ct_v1_log_id_from_pkey(ret, public_key) != 1)
|
||||
goto err;
|
||||
|
||||
ret->public_key = public_key;
|
||||
@@ -259,12 +299,18 @@ err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name)
|
||||
{
|
||||
return CTLOG_new_with_libctx(public_key, name, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Frees CT log and associated structures */
|
||||
void CTLOG_free(CTLOG *log)
|
||||
{
|
||||
if (log != NULL) {
|
||||
OPENSSL_free(log->name);
|
||||
EVP_PKEY_free(log->public_key);
|
||||
OPENSSL_free(log->propq);
|
||||
OPENSSL_free(log);
|
||||
}
|
||||
}
|
||||
|
||||
+18
-2
@@ -25,15 +25,25 @@
|
||||
*/
|
||||
static const time_t SCT_CLOCK_DRIFT_TOLERANCE = 300;
|
||||
|
||||
CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void)
|
||||
CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_with_libctx(OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
CT_POLICY_EVAL_CTX *ctx = OPENSSL_zalloc(sizeof(CT_POLICY_EVAL_CTX));
|
||||
|
||||
if (ctx == NULL) {
|
||||
CTerr(CT_F_CT_POLICY_EVAL_CTX_NEW, ERR_R_MALLOC_FAILURE);
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->libctx = libctx;
|
||||
if (propq != NULL) {
|
||||
ctx->propq = OPENSSL_strdup(propq);
|
||||
if (ctx->propq == NULL) {
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* time(NULL) shouldn't ever fail, so don't bother checking for -1. */
|
||||
ctx->epoch_time_in_ms = (uint64_t)(time(NULL) + SCT_CLOCK_DRIFT_TOLERANCE) *
|
||||
1000;
|
||||
@@ -41,12 +51,18 @@ CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void)
|
||||
return ctx;
|
||||
}
|
||||
|
||||
CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void)
|
||||
{
|
||||
return CT_POLICY_EVAL_CTX_new_with_libctx(NULL, NULL);
|
||||
}
|
||||
|
||||
void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
X509_free(ctx->cert);
|
||||
X509_free(ctx->issuer);
|
||||
OPENSSL_free(ctx->propq);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -312,7 +312,7 @@ int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
sctx = SCT_CTX_new();
|
||||
sctx = SCT_CTX_new(ctx->libctx, ctx->propq);
|
||||
if (sctx == NULL)
|
||||
goto err;
|
||||
|
||||
|
||||
+22
-6
@@ -20,13 +20,23 @@
|
||||
|
||||
#include "ct_local.h"
|
||||
|
||||
SCT_CTX *SCT_CTX_new(void)
|
||||
SCT_CTX *SCT_CTX_new(OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
SCT_CTX *sctx = OPENSSL_zalloc(sizeof(*sctx));
|
||||
|
||||
if (sctx == NULL)
|
||||
CTerr(CT_F_SCT_CTX_NEW, ERR_R_MALLOC_FAILURE);
|
||||
|
||||
sctx->libctx = libctx;
|
||||
if (propq != NULL) {
|
||||
sctx->propq = OPENSSL_strdup(propq);
|
||||
if (sctx->propq == NULL) {
|
||||
CTerr(CT_F_SCT_CTX_NEW, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(sctx);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return sctx;
|
||||
}
|
||||
|
||||
@@ -39,6 +49,7 @@ void SCT_CTX_free(SCT_CTX *sctx)
|
||||
OPENSSL_free(sctx->ihash);
|
||||
OPENSSL_free(sctx->certder);
|
||||
OPENSSL_free(sctx->preder);
|
||||
OPENSSL_free(sctx->propq);
|
||||
OPENSSL_free(sctx);
|
||||
}
|
||||
|
||||
@@ -191,13 +202,17 @@ err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
__owur static int ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash,
|
||||
size_t *hash_len)
|
||||
__owur static int ct_public_key_hash(SCT_CTX *sctx, X509_PUBKEY *pkey,
|
||||
unsigned char **hash, size_t *hash_len)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char *md = NULL, *der = NULL;
|
||||
int der_len;
|
||||
unsigned int md_len;
|
||||
EVP_MD *sha256 = EVP_MD_fetch(sctx->libctx, "SHA2-256", sctx->propq);
|
||||
|
||||
if (sha256 == NULL)
|
||||
goto err;
|
||||
|
||||
/* Reuse buffer if possible */
|
||||
if (*hash != NULL && *hash_len >= SHA256_DIGEST_LENGTH) {
|
||||
@@ -213,7 +228,7 @@ __owur static int ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash,
|
||||
if (der_len <= 0)
|
||||
goto err;
|
||||
|
||||
if (!EVP_Digest(der, der_len, md, &md_len, EVP_sha256(), NULL))
|
||||
if (!EVP_Digest(der, der_len, md, &md_len, sha256, NULL))
|
||||
goto err;
|
||||
|
||||
if (md != *hash) {
|
||||
@@ -225,6 +240,7 @@ __owur static int ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash,
|
||||
md = NULL;
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_MD_free(sha256);
|
||||
OPENSSL_free(md);
|
||||
OPENSSL_free(der);
|
||||
return ret;
|
||||
@@ -237,7 +253,7 @@ int SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *issuer)
|
||||
|
||||
int SCT_CTX_set1_issuer_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
|
||||
{
|
||||
return ct_public_key_hash(pubkey, &sctx->ihash, &sctx->ihashlen);
|
||||
return ct_public_key_hash(sctx, pubkey, &sctx->ihash, &sctx->ihashlen);
|
||||
}
|
||||
|
||||
int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
|
||||
@@ -247,7 +263,7 @@ int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
|
||||
if (pkey == NULL)
|
||||
return 0;
|
||||
|
||||
if (!ct_public_key_hash(pubkey, &sctx->pkeyhash, &sctx->pkeyhashlen)) {
|
||||
if (!ct_public_key_hash(sctx, pubkey, &sctx->pkeyhash, &sctx->pkeyhashlen)) {
|
||||
EVP_PKEY_free(pkey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+2
-1
@@ -122,7 +122,8 @@ int SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct)
|
||||
if (ctx == NULL)
|
||||
goto end;
|
||||
|
||||
if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, sctx->pkey))
|
||||
if (!EVP_DigestVerifyInit_ex(ctx, NULL, "SHA2-256", sctx->propq, sctx->pkey,
|
||||
sctx->libctx))
|
||||
goto end;
|
||||
|
||||
if (!sct_ctx_update(ctx, sctx, sct))
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2020 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/der.h"
|
||||
#include "crypto/bn.h"
|
||||
|
||||
static int int_start_context(WPACKET *pkt, int tag)
|
||||
{
|
||||
if (tag < 0)
|
||||
return 1;
|
||||
if (!ossl_assert(tag <= 30))
|
||||
return 0;
|
||||
return WPACKET_start_sub_packet(pkt);
|
||||
}
|
||||
|
||||
static int int_end_context(WPACKET *pkt, int tag)
|
||||
{
|
||||
if (tag < 0)
|
||||
return 1;
|
||||
if (!ossl_assert(tag <= 30))
|
||||
return 0;
|
||||
return WPACKET_close(pkt)
|
||||
&& WPACKET_put_bytes_u8(pkt, DER_C_CONTEXT | tag);
|
||||
}
|
||||
|
||||
int DER_w_precompiled(WPACKET *pkt, int tag,
|
||||
const unsigned char *precompiled, size_t precompiled_n)
|
||||
{
|
||||
return int_start_context(pkt, tag)
|
||||
&& WPACKET_memcpy(pkt, precompiled, precompiled_n)
|
||||
&& int_end_context(pkt, tag);
|
||||
}
|
||||
|
||||
int DER_w_boolean(WPACKET *pkt, int tag, int b)
|
||||
{
|
||||
return int_start_context(pkt, tag)
|
||||
&& WPACKET_start_sub_packet(pkt)
|
||||
&& (!b || WPACKET_put_bytes_u8(pkt, 0xFF))
|
||||
&& !WPACKET_close(pkt)
|
||||
&& !WPACKET_put_bytes_u8(pkt, DER_P_BOOLEAN)
|
||||
&& int_end_context(pkt, tag);
|
||||
}
|
||||
|
||||
static int int_der_w_integer(WPACKET *pkt, int tag,
|
||||
int (*put_bytes)(WPACKET *pkt, const void *v,
|
||||
unsigned int *top_byte),
|
||||
const void *v)
|
||||
{
|
||||
unsigned int top_byte = 0;
|
||||
|
||||
return int_start_context(pkt, tag)
|
||||
&& WPACKET_start_sub_packet(pkt)
|
||||
&& put_bytes(pkt, v, &top_byte)
|
||||
&& ((top_byte & 0x80) == 0 || WPACKET_put_bytes_u8(pkt, 0))
|
||||
&& WPACKET_close(pkt)
|
||||
&& WPACKET_put_bytes_u8(pkt, DER_P_INTEGER)
|
||||
&& int_end_context(pkt, tag);
|
||||
}
|
||||
|
||||
static int int_put_bytes_ulong(WPACKET *pkt, const void *v,
|
||||
unsigned int *top_byte)
|
||||
{
|
||||
const unsigned long *value = v;
|
||||
unsigned long tmp = *value;
|
||||
size_t n = 0;
|
||||
|
||||
while (tmp != 0) {
|
||||
n++;
|
||||
*top_byte = (tmp & 0xFF);
|
||||
tmp >>= 8;
|
||||
}
|
||||
if (n == 0)
|
||||
n = 1;
|
||||
|
||||
return WPACKET_put_bytes__(pkt, *value, n);
|
||||
}
|
||||
|
||||
/* For integers, we only support unsigned values for now */
|
||||
int DER_w_ulong(WPACKET *pkt, int tag, unsigned long v)
|
||||
{
|
||||
return int_der_w_integer(pkt, tag, int_put_bytes_ulong, &v);
|
||||
}
|
||||
|
||||
static int int_put_bytes_bn(WPACKET *pkt, const void *v,
|
||||
unsigned int *top_byte)
|
||||
{
|
||||
unsigned char *p = NULL;
|
||||
size_t n = BN_num_bytes(v);
|
||||
|
||||
/* The BIGNUM limbs are in LE order */
|
||||
*top_byte =
|
||||
((bn_get_words(v) [(n - 1) / BN_BYTES]) >> (8 * ((n - 1) % BN_BYTES)))
|
||||
& 0xFF;
|
||||
|
||||
if (!WPACKET_allocate_bytes(pkt, n, &p))
|
||||
return 0;
|
||||
if (p != NULL)
|
||||
BN_bn2bin(v, p);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int DER_w_bn(WPACKET *pkt, int tag, const BIGNUM *v)
|
||||
{
|
||||
if (v == NULL || BN_is_negative(v))
|
||||
return 0;
|
||||
if (BN_is_zero(v))
|
||||
return DER_w_ulong(pkt, tag, 0);
|
||||
|
||||
return int_der_w_integer(pkt, tag, int_put_bytes_bn, v);
|
||||
}
|
||||
|
||||
int DER_w_null(WPACKET *pkt, int tag)
|
||||
{
|
||||
return int_start_context(pkt, tag)
|
||||
&& WPACKET_start_sub_packet(pkt)
|
||||
&& WPACKET_close(pkt)
|
||||
&& WPACKET_put_bytes_u8(pkt, DER_P_NULL)
|
||||
&& int_end_context(pkt, tag);
|
||||
}
|
||||
|
||||
/* Constructed things need a start and an end */
|
||||
int DER_w_begin_sequence(WPACKET *pkt, int tag)
|
||||
{
|
||||
return int_start_context(pkt, tag)
|
||||
&& WPACKET_start_sub_packet(pkt);
|
||||
}
|
||||
|
||||
int DER_w_end_sequence(WPACKET *pkt, int tag)
|
||||
{
|
||||
return WPACKET_close(pkt)
|
||||
&& WPACKET_put_bytes_u8(pkt, DER_F_CONSTRUCTED | DER_P_SEQUENCE)
|
||||
&& int_end_context(pkt, tag);
|
||||
}
|
||||
@@ -15,20 +15,23 @@ ENDIF
|
||||
|
||||
LIBS=../../libcrypto
|
||||
$COMMON=set_key.c ecb3_enc.c $DESASM
|
||||
SOURCE[../../libcrypto]=$COMMON\
|
||||
$ALL=$COMMON\
|
||||
ecb_enc.c cbc_enc.c \
|
||||
cfb64enc.c cfb64ede.c cfb_enc.c \
|
||||
ofb64ede.c ofb64enc.c ofb_enc.c \
|
||||
str2key.c pcbc_enc.c qud_cksm.c rand_key.c \
|
||||
fcrypt.c xcbc_enc.c cbc_cksm.c
|
||||
|
||||
SOURCE[../../libcrypto]=$ALL
|
||||
SOURCE[../../providers/libfips.a]=$COMMON
|
||||
DEFINE[../../libcrypto]=$DESDEF
|
||||
DEFINE[../../providers/libfips.a]=$DESDEF
|
||||
DEFINE[../../providers/liblegacy.a]=$DESDEF
|
||||
|
||||
# When all deprecated symbols are removed, libcrypto doesn't export the
|
||||
# DES functions, so we must include them directly in liblegacy.a
|
||||
IF[{- $disabled{'deprecated-3.0'} && !$disabled{"mdc2"} -}]
|
||||
SOURCE[../../providers/liblegacy.a]=set_key.c $DESASM
|
||||
SOURCE[../../providers/liblegacy.a]=$ALL
|
||||
DEFINE[../../providers/liblegacy.a]=$DESDEF
|
||||
ENDIF
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
LIBS=../../libcrypto
|
||||
|
||||
$COMMON=dh_lib.c dh_key.c dh_group_params.c dh_check.c
|
||||
$COMMON=dh_lib.c dh_key.c dh_group_params.c dh_check.c dh_backend.c
|
||||
|
||||
SOURCE[../../libcrypto]=$COMMON\
|
||||
dh_asn1.c dh_gen.c dh_err.c dh_depr.c \
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq
|
||||
/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx
|
||||
/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC
|
||||
-----END DH PARAMETERS-----
|
||||
@@ -1,3 +0,0 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MB4CGQDUoLoCULb9LsYm5+/WN992xxbiLQlEuIsCAQM=
|
||||
-----END DH PARAMETERS-----
|
||||
@@ -1,16 +0,0 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIIBCAKCAQEA7ZKJNYJFVcs7+6J2WmkEYb8h86tT0s0h2v94GRFS8Q7B4lW9aG9o
|
||||
AFO5Imov5Jo0H2XMWTKKvbHbSe3fpxJmw/0hBHAY8H/W91hRGXKCeyKpNBgdL8sh
|
||||
z22SrkO2qCnHJ6PLAMXy5fsKpFmFor2tRfCzrfnggTXu2YOzzK7q62bmqVdmufEo
|
||||
pT8igNcLpvZxk5uBDvhakObMym9mX3rAEBoe8PwttggMYiiw7NuJKO4MqD1llGkW
|
||||
aVM8U2ATsCun1IKHrRxynkE1/MJ86VHeYYX8GZt2YA8z+GuzylIOKcMH6JAWzMwA
|
||||
Gbatw6QwizOhr9iMjZ0B26TE3X8LvW84wwIBAg==
|
||||
-----END DH PARAMETERS-----
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIIBCAKCAQEArtA3w73zP6Lu3EOQtwogiXt3AXXpuS6yD4BhzNS1pZFyPHk0/an5
|
||||
8ydEkPhQZHKDW+BZJxxPLANaTudWo2YT8TgtvUdN6KSgMiEi6McwqDw+SADuvW+F
|
||||
SKUYFxG6VFIxyEP6xBdf+vhJxEDbRG2EYsHDRRtJ76gp9cSKTHusf2R+4AAVGqnt
|
||||
gRAbNqtcOar/7FSj+Pl8G3v0Bty0LcCSpbqgYlnv6z+rErQmmC6PPvSz97TDMCok
|
||||
yKpCE9hFA1zkqK3TH4FmFvGeIaXJUIBZf4mArWuBTjWFW3nmhESRUn1VK3K3x42N
|
||||
a5k6c2+EhrMFiLjxuH6JZoqL0/E93FF9SwIBAg==
|
||||
-----END DH PARAMETERS-----
|
||||
@@ -1,14 +0,0 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIICCAKCAgEA/urRnb6vkPYc/KEGXWnbCIOaKitq7ySIq9dTH7s+Ri59zs77zty7
|
||||
vfVlSe6VFTBWgYjD2XKUFmtqq6CqXMhVX5ElUDoYDpAyTH85xqNFLzFC7nKrff/H
|
||||
TFKNttp22cZE9V0IPpzedPfnQkE7aUdmF9JnDyv21Z/818O93u1B4r0szdnmEvEF
|
||||
bKuIxEHX+bp0ZR7RqE1AeifXGJX3d6tsd2PMAObxwwsv55RGkn50vHO4QxtTARr1
|
||||
rRUV5j3B3oPMgC7Offxx+98Xn45B1/G0Prp11anDsR1PGwtaCYipqsvMwQUSJtyE
|
||||
EOQWk+yFkeMe4vWv367eEi0Sd/wnC+TSXBE3pYvpYerJ8n1MceI5GQTdarJ77OW9
|
||||
bGTHmxRsLSCM1jpLdPja5jjb4siAa6EHc4qN9c/iFKS3PQPJEnX7pXKBRs5f7AF3
|
||||
W3RIGt+G9IVNZfXaS7Z/iCpgzgvKCs0VeqN38QsJGtC1aIkwOeyjPNy2G6jJ4yqH
|
||||
ovXYt/0mc00vCWeSNS1wren0pR2EiLxX0ypjjgsU1mk/Z3b/+zVf7fZSIB+nDLjb
|
||||
NPtUlJCVGnAeBK1J1nG3TQicqowOXoM6ISkdaXj5GPJdXHab2+S7cqhKGv5qC7rR
|
||||
jT6sx7RUr0CNTxzLI7muV2/a4tGmj0PSdXQdsZ7tw7gbXlaWT1+MM2MCAQI=
|
||||
-----END DH PARAMETERS-----
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn
|
||||
a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC
|
||||
-----END DH PARAMETERS-----
|
||||
+58
-21
@@ -20,10 +20,12 @@
|
||||
#include "dh_local.h"
|
||||
#include <openssl/bn.h>
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/dh.h"
|
||||
#include "crypto/evp.h"
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include "internal/param_build.h"
|
||||
#include "openssl/param_build.h"
|
||||
#include "internal/ffc.h"
|
||||
|
||||
/*
|
||||
* i2d/d2i like DH parameter functions which use the appropriate routine for
|
||||
@@ -489,48 +491,82 @@ static size_t dh_pkey_dirty_cnt(const EVP_PKEY *pkey)
|
||||
}
|
||||
|
||||
static int dh_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
EVP_KEYMGMT *to_keymgmt)
|
||||
EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
DH *dh = from->pkey.dh;
|
||||
OSSL_PARAM_BLD tmpl;
|
||||
OSSL_PARAM_BLD *tmpl;
|
||||
const BIGNUM *p = DH_get0_p(dh), *g = DH_get0_g(dh), *q = DH_get0_q(dh);
|
||||
const BIGNUM *pub_key = DH_get0_pub_key(dh);
|
||||
const BIGNUM *priv_key = DH_get0_priv_key(dh);
|
||||
OSSL_PARAM *params;
|
||||
int rv;
|
||||
OSSL_PARAM *params = NULL;
|
||||
int selection = 0;
|
||||
int rv = 0;
|
||||
|
||||
/*
|
||||
* If the DH method is foreign, then we can't be sure of anything, and
|
||||
* can therefore not export or pretend to export.
|
||||
*/
|
||||
if (dh_get_method(dh) != DH_OpenSSL())
|
||||
return 0;
|
||||
|
||||
if (p == NULL || g == NULL)
|
||||
return 0;
|
||||
|
||||
ossl_param_bld_init(&tmpl);
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_P, p)
|
||||
|| !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g))
|
||||
tmpl = OSSL_PARAM_BLD_new();
|
||||
if (tmpl == NULL)
|
||||
return 0;
|
||||
if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
|
||||
|| !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g))
|
||||
goto err;
|
||||
if (q != NULL) {
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q))
|
||||
return 0;
|
||||
if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, q))
|
||||
goto err;
|
||||
}
|
||||
selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
|
||||
if (pub_key != NULL) {
|
||||
if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY, pub_key))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
|
||||
}
|
||||
/* A key must at least have a public part. */
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_PUB_KEY, pub_key))
|
||||
return 0;
|
||||
if (priv_key != NULL) {
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
priv_key))
|
||||
return 0;
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
|
||||
}
|
||||
|
||||
if ((params = ossl_param_bld_to_param(&tmpl)) == NULL)
|
||||
return 0;
|
||||
if ((params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* We export, the provider imports */
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
|
||||
params);
|
||||
|
||||
ossl_param_bld_free(params);
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
|
||||
|
||||
OSSL_PARAM_BLD_free_params(params);
|
||||
err:
|
||||
OSSL_PARAM_BLD_free(tmpl);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int dh_pkey_import_from(const OSSL_PARAM params[], void *key)
|
||||
{
|
||||
EVP_PKEY *pkey = key;
|
||||
DH *dh = DH_new();
|
||||
|
||||
if (dh == NULL) {
|
||||
ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ffc_fromdata(dh_get0_params(dh), params)
|
||||
|| !dh_key_fromdata(dh, params)
|
||||
|| !EVP_PKEY_assign_DH(pkey, dh)) {
|
||||
DH_free(dh);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
|
||||
EVP_PKEY_DH,
|
||||
EVP_PKEY_DH,
|
||||
@@ -573,6 +609,7 @@ const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
|
||||
|
||||
dh_pkey_dirty_cnt,
|
||||
dh_pkey_export_to,
|
||||
dh_pkey_import_from,
|
||||
};
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = {
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2020 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/core_names.h>
|
||||
#include "crypto/dh.h"
|
||||
|
||||
/*
|
||||
* The intention with the "backend" source file is to offer backend functions
|
||||
* for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider
|
||||
* implementations alike.
|
||||
*/
|
||||
|
||||
int dh_key_fromdata(DH *dh, const OSSL_PARAM params[])
|
||||
{
|
||||
const OSSL_PARAM *param_priv_key, *param_pub_key;
|
||||
BIGNUM *priv_key = NULL, *pub_key = NULL;
|
||||
|
||||
if (dh == NULL)
|
||||
return 0;
|
||||
|
||||
param_priv_key =
|
||||
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
|
||||
param_pub_key =
|
||||
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
|
||||
|
||||
/*
|
||||
* DH documentation says that a public key must be present if a
|
||||
* private key is present.
|
||||
* We want to have at least a public key either way, so we end up
|
||||
* requiring it unconditionally.
|
||||
*/
|
||||
if (param_priv_key != NULL && param_pub_key == NULL)
|
||||
return 0;
|
||||
|
||||
if ((param_priv_key != NULL
|
||||
&& !OSSL_PARAM_get_BN(param_priv_key, &priv_key))
|
||||
|| (param_pub_key != NULL
|
||||
&& !OSSL_PARAM_get_BN(param_pub_key, &pub_key)))
|
||||
goto err;
|
||||
|
||||
if (!DH_set0_key(dh, pub_key, priv_key))
|
||||
goto err;
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
BN_clear_free(priv_key);
|
||||
BN_free(pub_key);
|
||||
return 0;
|
||||
}
|
||||
+6
-1
@@ -45,6 +45,11 @@ int DH_set_method(DH *dh, const DH_METHOD *meth)
|
||||
return 1;
|
||||
}
|
||||
|
||||
const DH_METHOD *dh_get_method(const DH *dh)
|
||||
{
|
||||
return dh->meth;
|
||||
}
|
||||
|
||||
DH *DH_new(void)
|
||||
{
|
||||
return dh_new_intern(NULL, NULL);
|
||||
@@ -166,7 +171,7 @@ int DH_set_ex_data(DH *d, int idx, void *arg)
|
||||
return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
|
||||
}
|
||||
|
||||
void *DH_get_ex_data(DH *d, int idx)
|
||||
void *DH_get_ex_data(const DH *d, int idx)
|
||||
{
|
||||
return CRYPTO_get_ex_data(&d->ex_data, idx);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
LIBS=../../libcrypto
|
||||
|
||||
$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c dsa_aid.c dsa_check.c \
|
||||
dsa_key.c
|
||||
$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c dsa_check.c \
|
||||
dsa_key.c dsa_backend.c
|
||||
|
||||
SOURCE[../../libcrypto]=$COMMON\
|
||||
dsa_gen.c dsa_asn1.c \
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 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 <stdlib.h>
|
||||
|
||||
#include <openssl/objects.h>
|
||||
#include "crypto/dsa.h"
|
||||
|
||||
#define ASN1_SEQUENCE 0x30
|
||||
#define ASN1_OID 0x06
|
||||
|
||||
/*
|
||||
* id-dsa-with-sha1 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3
|
||||
* }
|
||||
*/
|
||||
#define ENCODE_ALGORITHMIDENTIFIER_RFC3279(name, n) \
|
||||
static const unsigned char algorithmidentifier_##name##_der[] = { \
|
||||
ASN1_SEQUENCE, 0x09, \
|
||||
ASN1_OID, 0x07, 1 * 40 + 2, 134, 72, 206, 56, 4, n \
|
||||
}
|
||||
|
||||
ENCODE_ALGORITHMIDENTIFIER_RFC3279(sha1, 3);
|
||||
|
||||
/*
|
||||
* dsaWithSHAx OIDs are of the form: (sigAlgs |n|)
|
||||
* where sigAlgs OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 4 3 }
|
||||
*/
|
||||
#define ENCODE_ALGORITHMIDENTIFIER_SIGALGS(name, n) \
|
||||
static const unsigned char algorithmidentifier_##name##_der[] = { \
|
||||
ASN1_SEQUENCE, 0x0b, \
|
||||
ASN1_OID, 0x09, 2 * 40 + 16, 0x86, 0x48, 1, 101, 3, 4, 3, n \
|
||||
}
|
||||
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha224, 1);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha256, 2);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha384, 3);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha512, 4);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_224, 5);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_256, 6);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_384, 7);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_512, 8);
|
||||
|
||||
#define MD_CASE(name) \
|
||||
case NID_##name: \
|
||||
*len = sizeof(algorithmidentifier_##name##_der); \
|
||||
return algorithmidentifier_##name##_der
|
||||
|
||||
const unsigned char *dsa_algorithmidentifier_encoding(int md_nid, size_t *len)
|
||||
{
|
||||
switch (md_nid) {
|
||||
MD_CASE(sha1);
|
||||
MD_CASE(sha224);
|
||||
MD_CASE(sha256);
|
||||
MD_CASE(sha384);
|
||||
MD_CASE(sha512);
|
||||
MD_CASE(sha3_224);
|
||||
MD_CASE(sha3_256);
|
||||
MD_CASE(sha3_384);
|
||||
MD_CASE(sha3_512);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
+60
-21
@@ -21,8 +21,10 @@
|
||||
#include <openssl/core_names.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/dsa.h"
|
||||
#include "crypto/evp.h"
|
||||
#include "internal/param_build.h"
|
||||
#include "openssl/param_build.h"
|
||||
#include "internal/ffc.h"
|
||||
#include "dsa_local.h"
|
||||
|
||||
static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
@@ -518,43 +520,79 @@ static size_t dsa_pkey_dirty_cnt(const EVP_PKEY *pkey)
|
||||
}
|
||||
|
||||
static int dsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
EVP_KEYMGMT *to_keymgmt)
|
||||
EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
DSA *dsa = from->pkey.dsa;
|
||||
OSSL_PARAM_BLD tmpl;
|
||||
OSSL_PARAM_BLD *tmpl;
|
||||
const BIGNUM *p = DSA_get0_p(dsa), *g = DSA_get0_g(dsa);
|
||||
const BIGNUM *q = DSA_get0_q(dsa), *pub_key = DSA_get0_pub_key(dsa);
|
||||
const BIGNUM *priv_key = DSA_get0_priv_key(dsa);
|
||||
OSSL_PARAM *params;
|
||||
int rv;
|
||||
int selection = 0;
|
||||
int rv = 0;
|
||||
|
||||
/*
|
||||
* If the DSA method is foreign, then we can't be sure of anything, and
|
||||
* can therefore not export or pretend to export.
|
||||
*/
|
||||
if (DSA_get_method(dsa) != DSA_OpenSSL())
|
||||
return 0;
|
||||
|
||||
if (p == NULL || q == NULL || g == NULL)
|
||||
return 0;
|
||||
|
||||
ossl_param_bld_init(&tmpl);
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_P, p)
|
||||
|| !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q)
|
||||
|| !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g))
|
||||
tmpl = OSSL_PARAM_BLD_new();
|
||||
if (tmpl == NULL)
|
||||
return 0;
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_PUB_KEY,
|
||||
|
||||
if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
|
||||
|| !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, q)
|
||||
|| !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
|
||||
if (pub_key != NULL) {
|
||||
if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
|
||||
pub_key))
|
||||
return 0;
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
|
||||
}
|
||||
if (priv_key != NULL) {
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
priv_key))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
|
||||
}
|
||||
|
||||
if ((params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* We export, the provider imports */
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
|
||||
|
||||
OSSL_PARAM_BLD_free_params(params);
|
||||
err:
|
||||
OSSL_PARAM_BLD_free(tmpl);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int dsa_pkey_import_from(const OSSL_PARAM params[], void *key)
|
||||
{
|
||||
EVP_PKEY *pkey = key;
|
||||
DSA *dsa = DSA_new();
|
||||
|
||||
if (dsa == NULL) {
|
||||
ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((params = ossl_param_bld_to_param(&tmpl)) == NULL)
|
||||
if (!ffc_fromdata(dsa_get0_params(dsa), params)
|
||||
|| !dsa_key_fromdata(dsa, params)
|
||||
|| !EVP_PKEY_assign_DSA(pkey, dsa)) {
|
||||
DSA_free(dsa);
|
||||
return 0;
|
||||
|
||||
/* We export, the provider imports */
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
|
||||
params);
|
||||
|
||||
ossl_param_bld_free(params);
|
||||
|
||||
return rv;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* NB these are sorted in pkey_id order, lowest first */
|
||||
@@ -620,6 +658,7 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5] = {
|
||||
NULL, NULL, NULL, NULL,
|
||||
|
||||
dsa_pkey_dirty_cnt,
|
||||
dsa_pkey_export_to
|
||||
dsa_pkey_export_to,
|
||||
dsa_pkey_import_from
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2020 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/core_names.h>
|
||||
#include "crypto/dsa.h"
|
||||
|
||||
/*
|
||||
* The intention with the "backend" source file is to offer backend support
|
||||
* for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider
|
||||
* implementations alike.
|
||||
*/
|
||||
|
||||
int dsa_key_fromdata(DSA *dsa, const OSSL_PARAM params[])
|
||||
{
|
||||
const OSSL_PARAM *param_priv_key, *param_pub_key;
|
||||
BIGNUM *priv_key = NULL, *pub_key = NULL;
|
||||
|
||||
if (dsa == NULL)
|
||||
return 0;
|
||||
|
||||
param_priv_key =
|
||||
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
|
||||
param_pub_key =
|
||||
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
|
||||
|
||||
/* It's ok if neither half is present */
|
||||
if (param_priv_key == NULL && param_pub_key == NULL)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* DH documentation says that a public key must be present if a
|
||||
* private key is present.
|
||||
*/
|
||||
if (param_priv_key != NULL && param_pub_key == NULL)
|
||||
return 0;
|
||||
|
||||
if (param_pub_key != NULL && !OSSL_PARAM_get_BN(param_pub_key, &pub_key))
|
||||
goto err;
|
||||
if (param_priv_key != NULL && !OSSL_PARAM_get_BN(param_priv_key, &priv_key))
|
||||
goto err;
|
||||
|
||||
if (!DSA_set0_key(dsa, pub_key, priv_key))
|
||||
goto err;
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
BN_clear_free(priv_key);
|
||||
BN_free(pub_key);
|
||||
return 0;
|
||||
}
|
||||
@@ -32,7 +32,7 @@ int DSA_set_ex_data(DSA *d, int idx, void *arg)
|
||||
return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
|
||||
}
|
||||
|
||||
void *DSA_get_ex_data(DSA *d, int idx)
|
||||
void *DSA_get_ex_data(const DSA *d, int idx)
|
||||
{
|
||||
return CRYPTO_get_ex_data(&d->ex_data, idx);
|
||||
}
|
||||
|
||||
@@ -51,9 +51,9 @@ $COMMON=ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \
|
||||
ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c \
|
||||
curve448/arch_32/f_impl.c curve448/f_generic.c curve448/scalar.c \
|
||||
curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \
|
||||
$ECASM
|
||||
$ECASM ec_backend.c ecx_backend.c
|
||||
SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c ecx_meth.c ecx_key.c \
|
||||
ec_err.c ecdh_kdf.c eck_prn.c ec_evp_lib.c
|
||||
ec_err.c ecdh_kdf.c eck_prn.c ec_ctrl.c
|
||||
SOURCE[../../providers/libfips.a]=$COMMON
|
||||
|
||||
# Implementations are now spread across several libraries, so the defines
|
||||
|
||||
@@ -5438,13 +5438,14 @@ static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b,
|
||||
}
|
||||
|
||||
int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
|
||||
const uint8_t public_key[32], const uint8_t private_key[32])
|
||||
const uint8_t public_key[32], const uint8_t private_key[32],
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
uint8_t az[SHA512_DIGEST_LENGTH];
|
||||
uint8_t nonce[SHA512_DIGEST_LENGTH];
|
||||
ge_p3 R;
|
||||
uint8_t hram[SHA512_DIGEST_LENGTH];
|
||||
EVP_MD *sha512 = EVP_MD_fetch(NULL, SN_sha512, NULL);
|
||||
EVP_MD *sha512 = EVP_MD_fetch(libctx, SN_sha512, propq);
|
||||
EVP_MD_CTX *hash_ctx = EVP_MD_CTX_new();
|
||||
unsigned int sz;
|
||||
int res = 0;
|
||||
@@ -5493,7 +5494,8 @@ err:
|
||||
static const char allzeroes[15];
|
||||
|
||||
int ED25519_verify(const uint8_t *message, size_t message_len,
|
||||
const uint8_t signature[64], const uint8_t public_key[32])
|
||||
const uint8_t signature[64], const uint8_t public_key[32],
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
int i;
|
||||
ge_p3 A;
|
||||
@@ -5548,7 +5550,7 @@ int ED25519_verify(const uint8_t *message, size_t message_len,
|
||||
fe_neg(A.X, A.X);
|
||||
fe_neg(A.T, A.T);
|
||||
|
||||
sha512 = EVP_MD_fetch(NULL, SN_sha512, NULL);
|
||||
sha512 = EVP_MD_fetch(libctx, SN_sha512, propq);
|
||||
if (sha512 == NULL)
|
||||
return 0;
|
||||
hash_ctx = EVP_MD_CTX_new();
|
||||
|
||||
@@ -10,15 +10,6 @@
|
||||
# define OSSL_CRYPTO_EC_CURVE448_LOCAL_H
|
||||
# include "curve448utils.h"
|
||||
|
||||
int ED448_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t *message,
|
||||
size_t message_len, const uint8_t public_key[57],
|
||||
const uint8_t private_key[57], const uint8_t *context,
|
||||
size_t context_len);
|
||||
|
||||
int ED448_verify(OPENSSL_CTX *ctx, const uint8_t *message, size_t message_len,
|
||||
const uint8_t signature[114], const uint8_t public_key[57],
|
||||
const uint8_t *context, size_t context_len);
|
||||
|
||||
int ED448ph_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64],
|
||||
const uint8_t public_key[57], const uint8_t private_key[57],
|
||||
const uint8_t *context, size_t context_len);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <string.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "crypto/ecx.h"
|
||||
#include "curve448_local.h"
|
||||
#include "word.h"
|
||||
#include "ed448.h"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user