diff options
184 files changed, 2661 insertions, 825 deletions
| diff --git a/CHANGES.md b/CHANGES.md index 5b0193bc3955..393b7700cf17 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -28,6 +28,78 @@ breaking changes, and mappings for the large list of deprecated functions.  [Migration guide]: https://github.com/openssl/openssl/tree/master/doc/man7/migration_guide.pod +### Changes between 3.0.17 and 3.0.18 [30 Sep 2025] + + * Fix Out-of-bounds read & write in RFC 3211 KEK Unwrap + +   Issue summary: An application trying to decrypt CMS messages encrypted using +   password based encryption can trigger an out-of-bounds read and write. + +   Impact summary: This out-of-bounds read may trigger a crash which leads to +   Denial of Service for an application. The out-of-bounds write can cause +   a memory corruption which can have various consequences including +   a Denial of Service or Execution of attacker-supplied code. + +   The issue was reported by Stanislav Fort (Aisle Research). + +   ([CVE-2025-9230]) + +   *Viktor Dukhovni* + + * Fix Out-of-bounds read in HTTP client no_proxy handling + +   Issue summary: An application using the OpenSSL HTTP client API functions +   may trigger an out-of-bounds read if the "no_proxy" environment variable is +   set and the host portion of the authority component of the HTTP URL is an +   IPv6 address. + +   Impact summary: An out-of-bounds read can trigger a crash which leads to +   Denial of Service for an application. + +   The issue was reported by Stanislav Fort (Aisle Research). + +   ([CVE-2025-9232]) + +   *Stanislav Fort* + + * Avoided a potential race condition introduced in 3.0.17, where +   `OSSL_STORE_CTX` kept open during lookup while potentially being used +   by multiple threads simultaneously, that could lead to potential crashes +   when multiple concurrent TLS connections are served. + +   *Matt Caswell* + + * Secure memory allocation calls are no longer used for HMAC keys. + +   *Dr Paul Dale* + + * `openssl req` no longer generates certificates with an empty extension list +   when SKID/AKID are set to `none` during generation. + +   *David Benjamin* + + * The man page date is now derived from the release date provided +   in `VERSION.dat` and not the current date for the released builds. + +   *Enji Cooper* + + * Hardened the provider implementation of the RSA public key "encrypt" +   operation to add a missing check that the caller-indicated output buffer +   size is at least as large as the byte count of the RSA modulus.  The issue +   was reported by Arash Ale Ebrahim from SYSPWN. + +   This operation is typically invoked via `EVP_PKEY_encrypt(3)`.  Callers that +   in fact provide a sufficiently large buffer, but fail to correctly indicate +   its size may now encounter unexpected errors.  In applications that attempt +   RSA public encryption into a buffer that is too small, an out-of-bounds +   write is now avoided and an error is reported instead. + +   *Viktor Dukhovni* + +### Changes between 3.0.16 and 3.0.17 [1 Jul 2025] + + * none yet +  ### Changes between 3.0.15 and 3.0.16 [11 Feb 2025]   * Fixed timing side-channel in ECDSA signature computation. @@ -3273,7 +3345,7 @@ OpenSSL 1.1.1   * Support for TLSv1.3 added. Note that users upgrading from an earlier     version of OpenSSL should review their configuration settings to ensure     that they are still appropriate for TLSv1.3. For further information see: -   <https://wiki.openssl.org/index.php/TLS1.3> +   <https://github.com/openssl/openssl/wiki/TLS1.3>     *Matt Caswell* @@ -4561,7 +4633,7 @@ OpenSSL 1.1.0   * The GOST engine was out of date and therefore it has been removed. An up     to date GOST engine is now being maintained in an external repository. -   See: <https://wiki.openssl.org/index.php/Binaries>. Libssl still retains +   See: <https://github.com/openssl/openssl/wiki/Binaries>. Libssl still retains     support for GOST ciphersuites (these are only activated if a GOST engine     is present). @@ -5340,6 +5412,11 @@ OpenSSL 1.1.0     *Rob Percival <robpercival@google.com>* + * SSLv3 is by default disabled at build-time. Builds that are not +   configured with "enable-ssl3" will not support SSLv3. + +   *Kurt Roeckx* +  OpenSSL 1.0.2  ------------- @@ -19953,6 +20030,8 @@ ndif  <!-- Links --> +[CVE-2025-9232]: https://www.openssl.org/news/vulnerabilities.html#CVE-2025-9232 +[CVE-2025-9230]: https://www.openssl.org/news/vulnerabilities.html#CVE-2025-9230  [CVE-2024-13176]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-13176  [CVE-2024-9143]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-9143  [CVE-2024-6119]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-6119 diff --git a/Configurations/50-nonstop.conf b/Configurations/50-nonstop.conf index ed3fe828b318..b131ca602bc4 100644 --- a/Configurations/50-nonstop.conf +++ b/Configurations/50-nonstop.conf @@ -167,12 +167,14 @@      # Build models      'nonstop-model-put' => {          template         => 1, +        disable          => [ 'secure-memory' ],          defines          => ['_PUT_MODEL_',                               '_REENTRANT', '_THREAD_SUPPORT_FUNCTIONS'],          ex_libs          => '-lput',      },      'nonstop-model-spt' => {          template         => 1, +        disable          => [ 'secure-memory' ],          defines          => ['_SPT_MODEL_',                               '_REENTRANT', '_ENABLE_FLOSS_THREADS'],          ex_libs          => '-lspt', diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl index d2b0797a7edf..a68ae9f26fa1 100644 --- a/Configurations/unix-Makefile.tmpl +++ b/Configurations/unix-Makefile.tmpl @@ -3,6 +3,8 @@  ##  ## {- join("\n## ", @autowarntext) -}  {- +     use Time::Piece; +       use OpenSSL::Util;       our $makedep_scheme = $config{makedep_scheme}; @@ -68,6 +70,15 @@ FIPSKEY={- $config{FIPSKEY} -}  VERSION={- "$config{full_version}" -}  VERSION_NUMBER={- "$config{version}" -} +RELEASE_DATE={- my $t = localtime; +		if ($config{"release_date"}) { +			# Provide the user with a more meaningful error message +			# than the default internal parsing error from +			# `Time::Piece->strptime(..)`. +			eval { $t = Time::Piece->strptime($config{"release_date"}, "%d %b %Y"); } || +				die "Parsing \$config{release_date} ('$config{release_date}') failed: $@"; +		} +		$t->strftime("%Y-%m-%d") -}  MAJOR={- $config{major} -}  MINOR={- $config{minor} -}  SHLIB_VERSION_NUMBER={- $config{shlib_version} -} @@ -1540,7 +1551,8 @@ EOF            return <<"EOF";  $args{src}: $pod  	pod2man --name=$name --section=$section\$(MANSUFFIX) --center=OpenSSL \\ -		--release=\$(VERSION) $pod >\$\@ +		--date=\$(RELEASE_DATE) --release=\$(VERSION) \\ +		$pod >\$\@  EOF        } elsif (platform->isdef($args{src})) {            # diff --git a/Configure b/Configure index 0c60d1da1659..77bf0cfb96f2 100755 --- a/Configure +++ b/Configure @@ -1,6 +1,6 @@  #! /usr/bin/env perl  # -*- mode: perl; -*- -# Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.  #  # Licensed under the Apache License 2.0 (the "License").  You may not use  # this file except in compliance with the License.  You can obtain a copy @@ -157,6 +157,7 @@ my @gcc_devteam_warn = qw(      -Wextra      -Wno-unused-parameter      -Wno-missing-field-initializers +    -Wno-unterminated-string-initialization      -Wswitch      -Wsign-compare      -Wshadow @@ -18,6 +18,27 @@ OpenSSL Releases  OpenSSL 3.0  ----------- +### Major changes between OpenSSL 3.0.17 and OpenSSL 3.0.18 [30 Sep 2025] + +OpenSSL 3.0.18 is a security patch release. The most severe CVE fixed in this +release is Moderate. + +This release incorporates the following bug fixes and mitigations: + +  * Fix Out-of-bounds read & write in RFC 3211 KEK Unwrap. +    ([CVE-2025-9230]) + +  * Fix Out-of-bounds read in HTTP client no_proxy handling. +    ([CVE-2025-9232]) + +### Major changes between OpenSSL 3.0.16 and OpenSSL 3.0.17 [1 Jul 2025] + +OpenSSL 3.0.17 is a bug fix release. + +This release incorporates the following bug fixes and mitigations: + +  * Miscellaneous minor bug fixes. +  ### Major changes between OpenSSL 3.0.15 and OpenSSL 3.0.16 [11 Feb 2025]  OpenSSL 3.0.16 is a security patch release. The most severe CVE fixed in this @@ -329,7 +350,7 @@ OpenSSL 1.1.1      * Rewrite of the packet construction code for "safer" packet handling      * Rewrite of the extension handling code      For further important information, see the [TLS1.3 page]( -    https://wiki.openssl.org/index.php/TLS1.3) in the OpenSSL Wiki. +    https://github.com/openssl/openssl/wiki/TLS1.3) in the OpenSSL Wiki.    * Complete rewrite of the OpenSSL random number generator to introduce the      following capabilities @@ -1508,7 +1529,8 @@ OpenSSL 0.9.x    * Support for various new platforms  <!-- Links --> - +[CVE-2025-9232]: https://www.openssl.org/news/vulnerabilities.html#CVE-2025-9232 +[CVE-2025-9230]: https://www.openssl.org/news/vulnerabilities.html#CVE-2025-9230  [CVE-2024-13176]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-13176  [CVE-2024-9143]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-9143  [CVE-2024-6119]: https://www.openssl.org/news/vulnerabilities.html#CVE-2024-6119 diff --git a/NOTES-WINDOWS.md b/NOTES-WINDOWS.md index b1d6c4fe13bb..44a5f5bf153d 100644 --- a/NOTES-WINDOWS.md +++ b/NOTES-WINDOWS.md @@ -79,6 +79,11 @@ Quick start         OpenSSL or      - `perl Configure`              to let Configure figure out the platform +    a. If you don't plan to develop OpenSSL yourself and don't need to rebuild, +       in other words, if you always do a new build, turning off the build +       dependency feature can speed up build times by up to 50%: +       `perl Configure no-makedepend` +   6. `nmake`   7. `nmake test` diff --git a/README.md b/README.md index 477f5cbb7d12..c6fbca920b92 100644 --- a/README.md +++ b/README.md @@ -128,8 +128,7 @@ available online.  Wiki  ---- -There is a Wiki at [wiki.openssl.org] which is currently not very active. -It contains a lot of useful information, not all of which is up to date. +There is a [GitHub Wiki] which is currently not very active.  License  ======= @@ -178,8 +177,8 @@ All rights reserved.      <https://github.com/openssl/openssl>      "OpenSSL GitHub Mirror" -[wiki.openssl.org]: -    <https://wiki.openssl.org> +[GitHub Wiki]: +    <https://github.com/openssl/openssl/wiki>      "OpenSSL Wiki"  [migration_guide(7ossl)]: diff --git a/VERSION.dat b/VERSION.dat index 4b7eb91a451a..817a2ed0fb4d 100644 --- a/VERSION.dat +++ b/VERSION.dat @@ -1,7 +1,7 @@  MAJOR=3  MINOR=0 -PATCH=16 +PATCH=18  PRE_RELEASE_TAG=  BUILD_METADATA= -RELEASE_DATE="11 Feb 2025" +RELEASE_DATE="30 Sep 2025"  SHLIB_VERSION=3 diff --git a/apps/CA.pl.in b/apps/CA.pl.in index f029470005d9..0bad37d46955 100644 --- a/apps/CA.pl.in +++ b/apps/CA.pl.in @@ -1,5 +1,5 @@  #!{- $config{HASHBANGPERL} -} -# Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved.  #  # Licensed under the Apache License 2.0 (the "License").  You may not use  # this file except in compliance with the License.  You can obtain a copy @@ -19,14 +19,17 @@ my @OPENSSL_CMDS = ("req", "ca", "pkcs12", "x509", "verify");  my $openssl = $ENV{'OPENSSL'} // "openssl";  $ENV{'OPENSSL'} = $openssl; +my @openssl = split_val($openssl); +  my $OPENSSL_CONFIG = $ENV{"OPENSSL_CONFIG"} // ""; +my @OPENSSL_CONFIG = split_val($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"; +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 values for various configuration settings.  my $CATOP = "./demoCA"; @@ -34,8 +37,10 @@ my $CAKEY = "cakey.pem";  my $CAREQ = "careq.pem";  my $CACERT = "cacert.pem";  my $CACRL = "crl.pem"; -my $DAYS = "-days 365"; -my $CADAYS = "-days 1095";	# 3 years +my @DAYS = qw(-days 365); +my @CADAYS = qw(-days 1095);	# 3 years +my @EXTENSIONS = qw(-extensions v3_ca); +my @POLICY = qw(-policy policy_anything);  my $NEWKEY = "newkey.pem";  my $NEWREQ = "newreq.pem";  my $NEWCERT = "newcert.pem"; @@ -43,31 +48,177 @@ my $NEWP12 = "newcert.p12";  # Commandline parsing  my %EXTRA; -my $WHAT = shift @ARGV || ""; +my $WHAT = shift @ARGV // "";  @ARGV = parse_extra(@ARGV);  my $RET = 0; +sub split_val { +    return split_val_win32(@_) if ($^O eq 'MSWin32'); +    my ($val) = @_; +    my (@ret, @frag); + +    # Skip leading whitespace +    $val =~ m{\A[ \t]*}ogc; + +    # Unix shell-compatible split +    # +    # Handles backslash escapes outside quotes and +    # in double-quoted strings.  Parameter and +    # command-substitution is silently ignored. +    # Bare newlines outside quotes and (trailing) backslashes are disallowed. + +    while (1) { +        last if (pos($val) == length($val)); + +        # The first char is never a SPACE or TAB.  Possible matches are: +        # 1. Ordinary string fragment +        # 2. Single-quoted string +        # 3. Double-quoted string +        # 4. Backslash escape +        # 5. Bare backlash or newline (rejected) +        # +        if ($val =~ m{\G([^'" \t\n\\]+)}ogc) { +            # Ordinary string +            push @frag, $1; +        } elsif ($val =~ m{\G'([^']*)'}ogc) { +            # Single-quoted string +            push @frag, $1; +        } elsif ($val =~ m{\G"}ogc) { +            # Double-quoted string +            push @frag, ""; +            while (1) { +                last if ($val =~ m{\G"}ogc); +                if ($val =~ m{\G([^"\\]+)}ogcs) { +                    # literals +                    push @frag, $1; +                } elsif ($val =~ m{\G.(["\`\$\\])}ogc) { +                    # backslash-escaped special +                    push @frag, $1; +                } elsif ($val =~ m{\G.(.)}ogcs) { +                    # backslashed non-special +                    push @frag, "\\$1" unless $1 eq "\n"; +                } else { +                    die sprintf("Malformed quoted string: %s\n", $val); +                } +            } +        } elsif ($val =~ m{\G\\(.)}ogc) { +            # Backslash is unconditional escape outside quoted strings +            push @frag, $1 unless $1 eq "\n"; +        } else { +            die sprintf("Bare backslash or newline in: '%s'\n", $val); +        } +        # Done if at SPACE, TAB or end, otherwise continue current fragment +        # +        next unless ($val =~ m{\G(?:[ \t]+|\z)}ogcs); +        push @ret, join("", splice(@frag)) if (@frag > 0); +    } +    # Handle final fragment +    push @ret, join("", splice(@frag)) if (@frag > 0); +    return @ret; +} + +sub split_val_win32 { +    my ($val) = @_; +    my (@ret, @frag); + +    # Skip leading whitespace +    $val =~ m{\A[ \t]*}ogc; + +    # Windows-compatible split +    # See: "Parsing C++ command-line arguments" in: +    # https://learn.microsoft.com/en-us/cpp/cpp/main-function-command-line-args?view=msvc-170 +    # +    # Backslashes are special only when followed by a double-quote +    # Pairs of double-quotes make a single double-quote. +    # Closing double-quotes may be omitted. + +    while (1) { +        last if (pos($val) == length($val)); + +        # The first char is never a SPACE or TAB. +        # 1. Ordinary string fragment +        # 2. Double-quoted string +        # 3. Backslashes preceding a double-quote +        # 4. Literal backslashes +        # 5. Bare newline (rejected) +        # +        if ($val =~ m{\G([^" \t\n\\]+)}ogc) { +            # Ordinary string +            push @frag, $1; +        } elsif ($val =~ m{\G"}ogc) { +            # Double-quoted string +            push @frag, ""; +            while (1) { +                if ($val =~ m{\G("+)}ogc) { +                    # Two double-quotes make one literal double-quote +                    my $l = length($1); +                    push @frag, q{"} x int($l/2) if ($l > 1); +                    next if ($l % 2 == 0); +                    last; +                } +                if ($val =~ m{\G([^"\\]+)}ogc) { +                    push @frag, $1; +                } elsif ($val =~ m{\G((?>[\\]+))(?=")}ogc) { +                    # Backslashes before a double-quote are escapes +                    my $l = length($1); +                    push @frag, q{\\} x int($l / 2); +                    if ($l % 2 == 1) { +                        ++pos($val); +                        push @frag, q{"}; +                    } +                } elsif ($val =~ m{\G((?:(?>[\\]+)[^"\\]+)+)}ogc) { +                    # Backslashes not before a double-quote are not special +                    push @frag, $1; +                } else { +                    # Tolerate missing closing double-quote +                    last; +                } +            } +        } elsif ($val =~ m{\G((?>[\\]+))(?=")}ogc) { +            my $l = length($1); +            push @frag, q{\\} x int($l / 2); +            if ($l % 2 == 1) { +                ++pos($val); +                push @frag, q{"}; +            } +        } elsif ($val =~ m{\G([\\]+)}ogc) { +            # Backslashes not before a double-quote are not special +            push @frag, $1; +        } else { +            die sprintf("Bare newline in: '%s'\n", $val); +        } +        # Done if at SPACE, TAB or end, otherwise continue current fragment +        # +        next unless ($val =~ m{\G(?:[ \t]+|\z)}ogcs); +        push @ret, join("", splice(@frag)) if (@frag > 0); +    } +    # Handle final fragment +    push @ret, join("", splice(@frag)) if (@frag); +    return @ret; +} +  # Split out "-extra-CMD value", and return new |@ARGV|. Fill in  # |EXTRA{CMD}| with list of values.  sub parse_extra  { +    my @args;      foreach ( @OPENSSL_CMDS ) { -        $EXTRA{$_} = ''; +        $EXTRA{$_} = [];      } - -    my @result; -    while ( scalar(@_) > 0 ) { -        my $arg = shift; -        if ( $arg !~ m/-extra-([a-z0-9]+)/ ) { -            push @result, $arg; +    while (@_) { +        my $arg = shift(@_); +        if ( $arg !~ m{^-extra-(\w+)$} ) { +            push @args, split_val($arg);              next;          } -        $arg =~ s/-extra-//; -        die("Unknown \"-${arg}-extra\" option, exiting") -            unless scalar grep { $arg eq $_ } @OPENSSL_CMDS; -        $EXTRA{$arg} .= " " . shift; +        $arg = $1; +        die "Unknown \"-extra-${arg}\" option, exiting\n" +            unless grep { $arg eq $_ } @OPENSSL_CMDS; +        die "Missing \"-extra-${arg}\" option value, exiting\n" +            unless (@_ > 0); +        push @{$EXTRA{$arg}}, split_val(shift(@_));      } -    return @result; +    return @args;  } @@ -110,9 +261,9 @@ sub copy_pemfile  # Wrapper around system; useful for debugging.  Returns just the exit status  sub run  { -    my $cmd = shift; -    print "====\n$cmd\n" if $verbose; -    my $status = system($cmd); +    my ($cmd, @args) = @_; +    print "====\n$cmd @args\n" if $verbose; +    my $status = system {$cmd} $cmd, @args;      print "==> $status\n====\n" if $verbose;      return $status >> 8;  } @@ -131,17 +282,15 @@ EOF  if ($WHAT eq '-newcert' ) {      # create a certificate -    $RET = run("$REQ -new -x509 -keyout $NEWKEY -out $NEWCERT $DAYS" -            . " $EXTRA{req}"); +    $RET = run(@REQ, qw(-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" -            . " $EXTRA{req}"); +    $RET = run(@REQ, qw(-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 -    $RET = run("$REQ -new $1 -keyout $NEWKEY -out $NEWREQ $DAYS $EXTRA{req}"); +    $RET = run(@REQ, "-new", (defined $1 ? ($1,) : ()), "-keyout", $NEWKEY, "-out", $NEWREQ, @{$EXTRA{req}});      print "Request is in $NEWREQ, private key is in $NEWKEY\n" if $RET == 0;  } elsif ($WHAT eq '-newca' ) {      # create the directory hierarchy @@ -174,48 +323,45 @@ if ($WHAT eq '-newcert' ) {          copy_pemfile($FILE,"${CATOP}/$CACERT", "CERTIFICATE");      } else {          print "Making CA certificate ...\n"; -        $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" -                . " -infiles ${CATOP}/$CAREQ $EXTRA{ca}") if $RET == 0; +        $RET = run(@REQ, qw(-new -keyout), "${CATOP}/private/$CAKEY", +                   "-out", "${CATOP}/$CAREQ", @{$EXTRA{req}}); +        $RET = run(@CA, qw(-create_serial -out), "${CATOP}/$CACERT", @CADAYS, +                   qw(-batch -keyfile), "${CATOP}/private/$CAKEY", "-selfsign", +                   @EXTENSIONS, "-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" -            . " -export -name \"$cname\" $EXTRA{pkcs12}"); -    print "PKCS #12 file is in $NEWP12\n" if $RET == 0; +    $RET = run(@PKCS12, "-in", $NEWCERT, "-inkey", $NEWKEY, +               "-certfile", "${CATOP}/$CACERT", "-out", $NEWP12, +               qw(-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 -infiles $NEWREQ $EXTRA{ca}"); +    $RET = run(@CA, @POLICY, "-infiles", $NEWREQ, @{$EXTRA{ca}});  } elsif ($WHAT eq '-sign' ) { -    $RET = run("$CA -policy policy_anything -out $NEWCERT" -            . " -infiles $NEWREQ $EXTRA{ca}"); +    $RET = run(@CA, @POLICY, "-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 -infiles $NEWREQ $EXTRA{ca}"); +    $RET = run(@CA, @POLICY, "-out", $NEWCERT, @EXTENSIONS, +               "-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" -            .  "-infiles tmp.pem $EXTRA{ca}") if $RET == 0; +    $RET = run(@X509, qw(-x509toreq -in), $NEWREQ, "-signkey", $NEWREQ, +               qw(-out tmp.pem), @{$EXTRA{x509}}); +    $RET = run(@CA, @POLICY, "-out", $NEWCERT, +               qw(-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 );      foreach my $file (@files) { -        # -CAfile quoted for VMS, since the C RTL downcases all unquoted -        # arguments to C programs -        my $status = run("$VERIFY \"-CAfile\" ${CATOP}/$CACERT $file $EXTRA{verify}"); +        my $status = run(@VERIFY, "-CAfile", "${CATOP}/$CACERT", $file, @{$EXTRA{verify}});          $RET = $status if $status != 0;      }  } elsif ($WHAT eq '-crl' ) { -    $RET = run("$CA -gencrl -out ${CATOP}/crl/$CACRL $EXTRA{ca}"); +    $RET = run(@CA, qw(-gencrl -out), "${CATOP}/crl/$CACRL", @{$EXTRA{ca}});      print "Generated CRL is in ${CATOP}/crl/$CACRL\n" if $RET == 0;  } elsif ($WHAT eq '-revoke' ) {      my $cname = $ARGV[0]; @@ -223,10 +369,10 @@ if ($WHAT eq '-newcert' ) {          print "Certificate filename is required; reason optional.\n";          exit 1;      } -    my $reason = $ARGV[1]; -    $reason = " -crl_reason $reason" -        if defined $reason && crl_reason_ok($reason); -    $RET = run("$CA -revoke \"$cname\"" . $reason . $EXTRA{ca}); +    my @reason; +    @reason = ("-crl_reason", $ARGV[1]) +        if defined $ARGV[1] && crl_reason_ok($ARGV[1]); +    $RET = run(@CA, "-revoke", $cname, @reason, @{$EXTRA{ca}});  } else {      print STDERR "Unknown arg \"$WHAT\"\n";      print STDERR "Use -help for help.\n"; diff --git a/apps/asn1parse.c b/apps/asn1parse.c index 129b867c8cc7..04263eeb034d 100644 --- a/apps/asn1parse.c +++ b/apps/asn1parse.c @@ -40,8 +40,8 @@ const OPTIONS asn1parse_options[] = {      {"length", OPT_LENGTH, 'p', "length of section in file"},      {"strparse", OPT_STRPARSE, 'p',       "offset; a series of these can be used to 'dig'"}, -    {"genstr", OPT_GENSTR, 's', "string to generate ASN1 structure from"},      {OPT_MORE_STR, 0, 0, "into multiple ASN1 blob wrappings"}, +    {"genstr", OPT_GENSTR, 's', "string to generate ASN1 structure from"},      {"genconf", OPT_GENCONF, 's', "file to generate ASN1 structure from"},      {"strictpem", OPT_STRICTPEM, 0,       "do not attempt base64 decode outside PEM markers"}, diff --git a/apps/cmp.c b/apps/cmp.c index c479b1549660..cb65277e6ad9 100644 --- a/apps/cmp.c +++ b/apps/cmp.c @@ -1,5 +1,5 @@  /* - * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved.   * Copyright Nokia 2007-2019   * Copyright Siemens AG 2015-2019   * @@ -878,7 +878,7 @@ static int set_name(const char *str,                      OSSL_CMP_CTX *ctx, const char *desc)  {      if (str != NULL) { -        X509_NAME *n = parse_name(str, MBSTRING_ASC, 1, desc); +        X509_NAME *n = parse_name(str, MBSTRING_UTF8, 1, desc);          if (n == NULL)              return 0; diff --git a/apps/cms.c b/apps/cms.c index dce227ef2db5..6184f7143fef 100644 --- a/apps/cms.c +++ b/apps/cms.c @@ -983,7 +983,7 @@ int cms_main(int argc, char **argv)                  goto end;              pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); -            if (kparam != NULL) { +            if (pctx != NULL && kparam != NULL) {                  if (!cms_set_pkey_param(pctx, kparam->param))                      goto end;              } @@ -1246,6 +1246,7 @@ int cms_main(int argc, char **argv)              goto end;          }          if (ret <= 0) { +            BIO_printf(bio_err, "Error writing CMS output\n");              ret = 6;              goto end;          } diff --git a/apps/ecparam.c b/apps/ecparam.c index 9e9ad136837b..e78eb234d6d8 100644 --- a/apps/ecparam.c +++ b/apps/ecparam.c @@ -1,5 +1,5 @@  /* - * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2025 The OpenSSL Project Authors. All Rights Reserved.   * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved   *   * Licensed under the Apache License 2.0 (the "License").  You may not use @@ -243,9 +243,17 @@ int ecparam_main(int argc, char **argv)              goto end;          }      } else { -        params_key = load_keyparams(infile, informat, 1, "EC", "EC parameters"); -        if (params_key == NULL || !EVP_PKEY_is_a(params_key, "EC")) +        params_key = load_keyparams_suppress(infile, informat, 1, "EC", +                                             "EC parameters", 1); +        if (params_key == NULL) +            params_key = load_keyparams_suppress(infile, informat, 1, "SM2", +                                                 "SM2 parameters", 1); + +        if (params_key == NULL) { +            BIO_printf(bio_err, "Unable to load parameters from %s\n", infile);              goto end; +        } +          if (point_format              && !EVP_PKEY_set_utf8_string_param(                      params_key, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, diff --git a/apps/enc.c b/apps/enc.c index c275046cf57a..3846d4ad3e5e 100644 --- a/apps/enc.c +++ b/apps/enc.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -234,6 +234,8 @@ int enc_main(int argc, char **argv)                  goto opthelp;              if (k)                  n *= 1024; +            if (n > INT_MAX) +                goto opthelp;              bsize = (int)n;              break;          case OPT_K: diff --git a/apps/include/apps.h b/apps/include/apps.h index baacd0025d68..c7e3e0351cb2 100644 --- a/apps/include/apps.h +++ b/apps/include/apps.h @@ -1,5 +1,5 @@  /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -94,7 +94,6 @@ typedef struct args_st {  /* We need both wrap and the "real" function because libcrypto uses both. */  int wrap_password_callback(char *buf, int bufsiz, int verify, void *cb_data); -int chopup_args(ARGS *arg, char *buf);  void dump_cert_text(BIO *out, X509 *x);  void print_name(BIO *out, const char *title, const X509_NAME *nm);  void print_bignum_var(BIO *, const BIGNUM *, const char*, diff --git a/apps/lib/apps.c b/apps/lib/apps.c index a632b0cff2bf..ea827464dda1 100644 --- a/apps/lib/apps.c +++ b/apps/lib/apps.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -90,54 +90,6 @@ int load_key_certs_crls_suppress(const char *uri, int format, int maybe_stdin,  int app_init(long mesgwin); -int chopup_args(ARGS *arg, char *buf) -{ -    int quoted; -    char c = '\0', *p = NULL; - -    arg->argc = 0; -    if (arg->size == 0) { -        arg->size = 20; -        arg->argv = app_malloc(sizeof(*arg->argv) * arg->size, "argv space"); -    } - -    for (p = buf;;) { -        /* Skip whitespace. */ -        while (*p && isspace(_UC(*p))) -            p++; -        if (*p == '\0') -            break; - -        /* The start of something good :-) */ -        if (arg->argc >= arg->size) { -            char **tmp; -            arg->size += 20; -            tmp = OPENSSL_realloc(arg->argv, sizeof(*arg->argv) * arg->size); -            if (tmp == NULL) -                return 0; -            arg->argv = tmp; -        } -        quoted = *p == '\'' || *p == '"'; -        if (quoted) -            c = *p++; -        arg->argv[arg->argc++] = p; - -        /* now look for the end of this */ -        if (quoted) { -            while (*p && *p != c) -                p++; -            *p++ = '\0'; -        } else { -            while (*p && !isspace(_UC(*p))) -                p++; -            if (*p) -                *p++ = '\0'; -        } -    } -    arg->argv[arg->argc] = NULL; -    return 1; -} -  #ifndef APP_INIT  int app_init(long mesgwin)  { @@ -1688,6 +1640,9 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr)      }      retdb->dbfname = OPENSSL_strdup(dbfile); +    if (retdb->dbfname == NULL) +        goto err; +  #ifndef OPENSSL_NO_POSIX_IO      retdb->dbst = dbst;  #endif diff --git a/apps/lib/http_server.c b/apps/lib/http_server.c index 33ae886d4a1c..d2bfa432d966 100644 --- a/apps/lib/http_server.c +++ b/apps/lib/http_server.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -222,7 +222,7 @@ BIO *http_server_init_bio(const char *prog, const char *port)      int asock;      char name[40]; -    snprintf(name, sizeof(name), "[::]:%s", port); /* port may be "0" */ +    BIO_snprintf(name, sizeof(name), "[::]:%s", port); /* port may be "0" */      bufbio = BIO_new(BIO_f_buffer());      if (bufbio == NULL)          goto err; diff --git a/apps/ocsp.c b/apps/ocsp.c index fb3105da5526..355adf92bf90 100644 --- a/apps/ocsp.c +++ b/apps/ocsp.c @@ -1,5 +1,5 @@  /* - * Copyright 2001-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -666,7 +666,8 @@ redo_accept:                  resp =                      OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST,                                           NULL); -                send_ocsp_response(cbio, resp); +                if (resp != NULL) +                    send_ocsp_response(cbio, resp);              }              goto done_resp;          } @@ -764,16 +765,18 @@ redo_accept:          BIO_free(derbio);      } -    i = OCSP_response_status(resp); -    if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { -        BIO_printf(out, "Responder Error: %s (%d)\n", -                   OCSP_response_status_str(i), i); -        if (!ignore_err) +    if (resp != NULL) { +        i = OCSP_response_status(resp); +        if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { +            BIO_printf(out, "Responder Error: %s (%d)\n", +                       OCSP_response_status_str(i), i); +            if (!ignore_err)                  goto end; -    } +        } -    if (resp_text) -        OCSP_RESPONSE_print(out, resp, 0); +        if (resp_text) +            OCSP_RESPONSE_print(out, resp, 0); +    }      /* If running as responder don't verify our own response */      if (cbio != NULL) { @@ -1049,6 +1052,10 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req      }      bs = OCSP_BASICRESP_new(); +    if (bs == NULL) { +        *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, bs); +        goto end; +    }      thisupd = X509_gmtime_adj(NULL, 0);      if (ndays != -1)          nextupd = X509_time_adj_ex(NULL, ndays, nmin * 60, NULL); diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c index 5e5047137632..caf3f639eae5 100644 --- a/apps/pkeyutl.c +++ b/apps/pkeyutl.c @@ -1,5 +1,5 @@  /* - * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -371,6 +371,7 @@ int pkeyutl_main(int argc, char **argv)              if (EVP_PKEY_CTX_ctrl_str(ctx, opt, passwd) <= 0) {                  BIO_printf(bio_err, "%s: Can't set parameter \"%s\":\n",                             prog, opt); +                OPENSSL_free(passwd);                  goto end;              }              OPENSSL_free(passwd); diff --git a/apps/s_time.c b/apps/s_time.c index 1a58e19de53f..b77619156261 100644 --- a/apps/s_time.c +++ b/apps/s_time.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -325,8 +325,10 @@ int s_time_main(int argc, char **argv)       */   next: -    if (!(perform & 2)) +    if (!(perform & 2)) { +        ret = 0;          goto end; +    }      printf("\n\nNow timing with session id reuse.\n");      /* Get an SSL object so we can reuse the session id */ diff --git a/apps/storeutl.c b/apps/storeutl.c index 30c9915de3e8..e7e614833769 100644 --- a/apps/storeutl.c +++ b/apps/storeutl.c @@ -1,5 +1,5 @@  /* - * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -198,9 +198,7 @@ int storeutl_main(int argc, char *argv[])              }              break;          case OPT_CRITERION_FINGERPRINT: -            if (criterion != 0 -                || (criterion == OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT -                    && fingerprint != NULL)) { +            if (criterion != 0) {                  BIO_printf(bio_err, "%s: criterion already given.\n",                             prog);                  goto end; @@ -337,14 +335,22 @@ int storeutl_main(int argc, char *argv[])  static int indent_printf(int indent, BIO *bio, const char *format, ...)  {      va_list args; -    int ret; +    int ret, vret; + +    ret = BIO_printf(bio, "%*s", indent, ""); +    if (ret < 0) +        return ret;      va_start(args, format); +    vret = BIO_vprintf(bio, format, args); +    va_end(args); -    ret = BIO_printf(bio, "%*s", indent, "") + BIO_vprintf(bio, format, args); +    if (vret < 0) +        return vret; +    if (vret > INT_MAX - ret) +        return INT_MAX; -    va_end(args); -    return ret; +    return ret + vret;  }  static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, diff --git a/crypto/aes/asm/aes-s390x.pl b/crypto/aes/asm/aes-s390x.pl index 5d1283f57690..2345d4574a41 100644 --- a/crypto/aes/asm/aes-s390x.pl +++ b/crypto/aes/asm/aes-s390x.pl @@ -1,5 +1,5 @@  #! /usr/bin/env perl -# Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved.  #  # Licensed under the Apache License 2.0 (the "License").  You may not use  # this file except in compliance with the License.  You can obtain a copy @@ -1431,6 +1431,9 @@ $code.=<<___ if (!$softonly);  	st${g}	$s3,0($sp)			# backchain  	la	%r1,$stdframe($sp) +	xc	$stdframe+0(64,$sp),$stdframe+0($sp)	# clear reserved/unused +							# in parameter block +  	lmg	$s2,$s3,0($key)			# copy key  	stg	$s2,$stdframe+80($sp)  	stg	$s3,$stdframe+88($sp) diff --git a/crypto/asn1/asn_mime.c b/crypto/asn1/asn_mime.c index 8bb7089292d0..f744398fd65a 100644 --- a/crypto/asn1/asn_mime.c +++ b/crypto/asn1/asn_mime.c @@ -1,5 +1,5 @@  /* - * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -96,7 +96,7 @@ int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,       * internally       */      else -        ASN1_item_i2d_bio(it, out, val); +        rv = ASN1_item_i2d_bio(it, out, val);      return rv;  } @@ -168,6 +168,19 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)              BIO_write(out, ",", 1);          write_comma = 1;          md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm); + +        /* RFC 8702 does not define a micalg for SHAKE, assuming "shake-<bitlen>" */ +        if (md_nid == NID_shake128) { +            if (BIO_puts(out, "shake-128") < 0) +                goto err; +            continue; +        } +        if (md_nid == NID_shake256) { +            if (BIO_puts(out, "shake-256") < 0) +                goto err; +            continue; +        } +          md = EVP_get_digestbynid(md_nid);          if (md && md->md_ctrl) {              int rv; @@ -204,15 +217,15 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)          case NID_id_GostR3411_94:              BIO_puts(out, "gostr3411-94"); -            goto err; +            break;          case NID_id_GostR3411_2012_256:              BIO_puts(out, "gostr3411-2012-256"); -            goto err; +            break;          case NID_id_GostR3411_2012_512:              BIO_puts(out, "gostr3411-2012-512"); -            goto err; +            break;          default:              if (have_unknown) { @@ -272,7 +285,8 @@ int SMIME_write_ASN1_ex(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,          BIO_printf(bio, "Content-Type: multipart/signed;");          BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);          BIO_puts(bio, " micalg=\""); -        asn1_write_micalg(bio, mdalgs); +        if (!asn1_write_micalg(bio, mdalgs)) +            return 0;          BIO_printf(bio, "\"; boundary=\"----%s\"%s%s",                     bound, mime_eol, mime_eol);          BIO_printf(bio, "This is an S/MIME signed message%s%s", diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c index 3ea18b0280dd..fb2e040c7c56 100644 --- a/crypto/asn1/tasn_enc.c +++ b/crypto/asn1/tasn_enc.c @@ -1,5 +1,5 @@  /* - * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -571,6 +571,9 @@ static int asn1_ex_i2c(const ASN1_VALUE **pval, unsigned char *cout, int *putype              return -1;          break; +    case V_ASN1_UNDEF: +        return -2; +      case V_ASN1_NULL:          cont = NULL;          len = 0; diff --git a/crypto/bio/bio_dump.c b/crypto/bio/bio_dump.c index c453da62688c..04191a653054 100644 --- a/crypto/bio/bio_dump.c +++ b/crypto/bio/bio_dump.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -47,6 +47,8 @@ int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),      for (i = 0; i < rows; i++) {          n = BIO_snprintf(buf, sizeof(buf), "%*s%04x - ", indent, "",                           i * dump_width); +        if (n < 0) +            return -1;          for (j = 0; j < dump_width; j++) {              if (SPACE(buf, n, 3)) {                  if (((i * dump_width) + j) >= len) { diff --git a/crypto/bio/bio_print.c b/crypto/bio/bio_print.c index 4c9c3af7cfd6..1934a6884251 100644 --- a/crypto/bio/bio_print.c +++ b/crypto/bio/bio_print.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -535,6 +535,10 @@ static LDOUBLE abs_val(LDOUBLE value)      LDOUBLE result = value;      if (value < 0)          result = -value; +    if (result > 0 && result / 2 == result) /* INF */ +        result = 0; +    else if (result != result) /* NAN */ +        result = 0;      return result;  } @@ -590,6 +594,9 @@ fmtfp(char **sbuffer,          signvalue = '+';      else if (flags & DP_F_SPACE)          signvalue = ' '; +    ufvalue = abs_val(fvalue); +    if (ufvalue == 0 && fvalue != 0) /* INF or NAN? */ +        signvalue = '?';      /*       * G_FORMAT sometimes prints like E_FORMAT and sometimes like F_FORMAT @@ -597,12 +604,12 @@ fmtfp(char **sbuffer,       * that from here on.       */      if (style == G_FORMAT) { -        if (fvalue == 0.0) { +        if (ufvalue == 0.0) {              realstyle = F_FORMAT; -        } else if (fvalue < 0.0001) { +        } else if (ufvalue < 0.0001) {              realstyle = E_FORMAT; -        } else if ((max == 0 && fvalue >= 10) -                    || (max > 0 && fvalue >= pow_10(max))) { +        } else if ((max == 0 && ufvalue >= 10) +                   || (max > 0 && ufvalue >= pow_10(max))) {              realstyle = E_FORMAT;          } else {              realstyle = F_FORMAT; @@ -612,9 +619,9 @@ fmtfp(char **sbuffer,      }      if (style != F_FORMAT) { -        tmpvalue = fvalue; +        tmpvalue = ufvalue;          /* Calculate the exponent */ -        if (fvalue != 0.0) { +        if (ufvalue != 0.0) {              while (tmpvalue < 1) {                  tmpvalue *= 10;                  exp--; @@ -651,9 +658,9 @@ fmtfp(char **sbuffer,              }          }          if (realstyle == E_FORMAT) -            fvalue = tmpvalue; +            ufvalue = tmpvalue;      } -    ufvalue = abs_val(fvalue); +      /*       * By subtracting 65535 (2^16-1) we cancel the low order 15 bits       * of ULONG_MAX to avoid using imprecise floating point values. diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c index 8ca1cf64ed47..4292d805a16a 100644 --- a/crypto/bio/bss_dgram.c +++ b/crypto/bio/bss_dgram.c @@ -1,5 +1,5 @@  /* - * Copyright 2005-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -349,11 +349,11 @@ static int dgram_write(BIO *b, const char *in, int inl)      return ret;  } -static long dgram_get_mtu_overhead(bio_dgram_data *data) +static long dgram_get_mtu_overhead(BIO_ADDR *addr)  {      long ret; -    switch (BIO_ADDR_family(&data->peer)) { +    switch (BIO_ADDR_family(addr)) {      case AF_INET:          /*           * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP @@ -365,7 +365,8 @@ static long dgram_get_mtu_overhead(bio_dgram_data *data)          {  #  ifdef IN6_IS_ADDR_V4MAPPED              struct in6_addr tmp_addr; -            if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL) + +            if (BIO_ADDR_rawaddress(addr, &tmp_addr, NULL)                  && IN6_IS_ADDR_V4MAPPED(&tmp_addr))                  /*                   * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP @@ -492,11 +493,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)                              &sockopt_len)) < 0 || sockopt_val < 0) {                  ret = 0;              } else { -                /* -                 * we assume that the transport protocol is UDP and no IP -                 * options are used. -                 */ -                data->mtu = sockopt_val - 8 - 20; +                data->mtu = sockopt_val - dgram_get_mtu_overhead(&addr);                  ret = data->mtu;              }              break; @@ -508,11 +505,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)                  || sockopt_val < 0) {                  ret = 0;              } else { -                /* -                 * we assume that the transport protocol is UDP and no IPV6 -                 * options are used. -                 */ -                data->mtu = sockopt_val - 8 - 40; +                data->mtu = sockopt_val - dgram_get_mtu_overhead(&addr);                  ret = data->mtu;              }              break; @@ -526,7 +519,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)  # endif          break;      case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: -        ret = -dgram_get_mtu_overhead(data); +        ret = -dgram_get_mtu_overhead(&data->peer);          switch (BIO_ADDR_family(&data->peer)) {          case AF_INET:              ret += 576; @@ -760,7 +753,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)          }          break;      case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD: -        ret = dgram_get_mtu_overhead(data); +        ret = dgram_get_mtu_overhead(&data->peer);          break;      /* diff --git a/crypto/bio/bss_file.c b/crypto/bio/bss_file.c index a6143b6abcf6..0c57c1bfb474 100644 --- a/crypto/bio/bss_file.c +++ b/crypto/bio/bss_file.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -296,7 +296,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)          if (fp == NULL) {              ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),                             "calling fopen(%s, %s)", -                           ptr, p); +                           (const char *)ptr, p);              ERR_raise(ERR_LIB_BIO, ERR_R_SYS_LIB);              ret = 0;              break; diff --git a/crypto/cmp/cmp_client.c b/crypto/cmp/cmp_client.c index 4c8dbfdcd739..8950091b93ee 100644 --- a/crypto/cmp/cmp_client.c +++ b/crypto/cmp/cmp_client.c @@ -1,5 +1,5 @@  /* - * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved.   * Copyright Nokia 2007-2019   * Copyright Siemens AG 2015-2019   * @@ -611,8 +611,10 @@ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid,          ERR_add_error_data(1, "; cannot extract certificate from response");          return 0;      } -    if (!ossl_cmp_ctx_set0_newCert(ctx, cert)) +    if (!ossl_cmp_ctx_set0_newCert(ctx, cert)) { +        X509_free(cert);          return 0; +    }      /*       * if the CMP server returned certificates in the caPubs field, copy them diff --git a/crypto/cms/cms_pwri.c b/crypto/cms/cms_pwri.c index 2373092bed55..33a7ccaa76a3 100644 --- a/crypto/cms/cms_pwri.c +++ b/crypto/cms/cms_pwri.c @@ -1,5 +1,5 @@  /* - * Copyright 2009-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2009-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -157,7 +157,8 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,      /* Setup PBE algorithm */ -    pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1); +    pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set_ex(iter, NULL, 0, -1, -1, +                                                       cms_ctx->libctx);      if (pwri->keyDerivationAlgorithm == NULL)          goto err; @@ -228,7 +229,7 @@ static int kek_unwrap_key(unsigned char *out, size_t *outlen,          /* Check byte failure */          goto err;      } -    if (inlen < (size_t)(tmp[0] - 4)) { +    if (inlen < 4 + (size_t)tmp[0]) {          /* Invalid length value */          goto err;      } @@ -351,9 +352,10 @@ int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms,      /* Finish password based key derivation to setup key in "ctx" */ -    if (EVP_PBE_CipherInit(algtmp->algorithm, -                           (char *)pwri->pass, pwri->passlen, -                           algtmp->parameter, kekctx, en_de) < 0) { +    if (EVP_PBE_CipherInit_ex(algtmp->algorithm, +                              (char *)pwri->pass, pwri->passlen, +                              algtmp->parameter, kekctx, en_de, +                              cms_ctx->libctx, cms_ctx->propq) < 0) {          ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);          goto err;      } diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index afc49f5cdc87..19208a860212 100644 --- a/crypto/dh/dh_key.c +++ b/crypto/dh/dh_key.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -263,7 +263,7 @@ static int generate_key(DH *dh)      int ok = 0;      int generate_new_key = 0;  #ifndef FIPS_MODULE -    unsigned l; +    int l;  #endif      BN_CTX *ctx = NULL;      BIGNUM *pub_key = NULL, *priv_key = NULL; @@ -323,11 +323,13 @@ static int generate_key(DH *dh)                  goto err;  #else              if (dh->params.q == NULL) { -                /* secret exponent length, must satisfy 2^(l-1) <= p */ -                if (dh->length != 0 -                    && dh->length >= BN_num_bits(dh->params.p)) +                /* secret exponent length, must satisfy 2^l < (p-1)/2 */ +                l = BN_num_bits(dh->params.p); +                if (dh->length >= l)                      goto err; -                l = dh->length ? dh->length : BN_num_bits(dh->params.p) - 1; +                l -= 2; +                if (dh->length != 0 && dh->length < l) +                    l = dh->length;                  if (!BN_priv_rand_ex(priv_key, l, BN_RAND_TOP_ONE,                                       BN_RAND_BOTTOM_ANY, 0, ctx))                      goto err; diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c index f201eede0df4..931e1b88ec6f 100644 --- a/crypto/dh/dh_pmeth.c +++ b/crypto/dh/dh_pmeth.c @@ -1,5 +1,5 @@  /* - * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -410,7 +410,7 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,      }      dh = (DH *)EVP_PKEY_get0_DH(ctx->pkey);      dhpub = EVP_PKEY_get0_DH(ctx->peerkey); -    if (dhpub == NULL) { +    if (dhpub == NULL || dh == NULL) {          ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);          return 0;      } @@ -424,7 +424,7 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,              ret = DH_compute_key_padded(key, dhpubbn, dh);          else              ret = DH_compute_key(key, dhpubbn, dh); -        if (ret < 0) +        if (ret <= 0)              return ret;          *keylen = ret;          return 1; diff --git a/crypto/encode_decode/encoder_pkey.c b/crypto/encode_decode/encoder_pkey.c index 39266a95309d..b372170db256 100644 --- a/crypto/encode_decode/encoder_pkey.c +++ b/crypto/encode_decode/encoder_pkey.c @@ -1,5 +1,5 @@  /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -207,6 +207,7 @@ encoder_construct_pkey(OSSL_ENCODER_INSTANCE *encoder_inst, void *arg)  static void encoder_destruct_pkey(void *arg)  {      struct construct_data_st *data = arg; +    int match = (data->obj == data->constructed_obj);      if (data->encoder_inst != NULL) {          OSSL_ENCODER *encoder = @@ -215,6 +216,8 @@ static void encoder_destruct_pkey(void *arg)          encoder->free_object(data->constructed_obj);      }      data->constructed_obj = NULL; +    if (match) +        data->obj = NULL;  }  /* diff --git a/crypto/evp/bio_enc.c b/crypto/evp/bio_enc.c index 304030bcb3b5..d0cb91114278 100644 --- a/crypto/evp/bio_enc.c +++ b/crypto/evp/bio_enc.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -159,6 +159,7 @@ static int enc_read(BIO *b, char *out, int outl)              /* Should be continue next time we are called? */              if (!BIO_should_retry(next)) {                  ctx->cont = i; +                ctx->finished = 1;                  i = EVP_CipherFinal_ex(ctx->cipher,                                         ctx->buf, &(ctx->buf_len));                  ctx->ok = i; diff --git a/crypto/evp/bio_ok.c b/crypto/evp/bio_ok.c index 97e67fcb6814..ec3664b40661 100644 --- a/crypto/evp/bio_ok.c +++ b/crypto/evp/bio_ok.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -557,7 +557,7 @@ static int block_in(BIO *b)  {      BIO_OK_CTX *ctx;      EVP_MD_CTX *md; -    unsigned long tl = 0; +    size_t tl = 0;      unsigned char tmp[EVP_MAX_MD_SIZE];      int md_size; @@ -568,15 +568,18 @@ static int block_in(BIO *b)          goto berr;      assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */ -    tl = ctx->buf[0]; -    tl <<= 8; -    tl |= ctx->buf[1]; -    tl <<= 8; -    tl |= ctx->buf[2]; -    tl <<= 8; -    tl |= ctx->buf[3]; - -    if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md_size) +    tl = ((size_t)ctx->buf[0] << 24) +           | ((size_t)ctx->buf[1] << 16) +           | ((size_t)ctx->buf[2] << 8) +           | ((size_t)ctx->buf[3]); + +    if (tl > OK_BLOCK_SIZE) +        goto berr; + +    if (tl > SIZE_MAX - OK_BLOCK_BLOCK - (size_t)md_size) +        goto berr; + +    if (ctx->buf_len < tl + OK_BLOCK_BLOCK + (size_t)md_size)          return 1;      if (!EVP_DigestUpdate(md, @@ -584,7 +587,7 @@ static int block_in(BIO *b)          goto berr;      if (!EVP_DigestFinal_ex(md, tmp, NULL))          goto berr; -    if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md_size) == 0) { +    if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, (size_t)md_size) == 0) {          /* there might be parts from next block lurking around ! */          ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md_size;          ctx->buf_len_save = ctx->buf_len; diff --git a/crypto/evp/ctrl_params_translate.c b/crypto/evp/ctrl_params_translate.c index 44d0895bcf14..6f9f1ce68277 100644 --- a/crypto/evp/ctrl_params_translate.c +++ b/crypto/evp/ctrl_params_translate.c @@ -1,5 +1,5 @@  /* - * Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -1355,7 +1355,7 @@ static int fix_rsa_padding_mode(enum state state,          if (i == OSSL_NELEM(str_value_map)) {              ERR_raise_data(ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE,                             "[action:%d, state:%d] padding name %s", -                           ctx->action_type, state, ctx->p1); +                           ctx->action_type, state, (const char *)ctx->p2);              ctx->p1 = ret = -2;          } else if (state == POST_CTRL_TO_PARAMS) {              /* EVP_PKEY_CTRL_GET_RSA_PADDING weirdness explained further up */ @@ -2827,11 +2827,15 @@ static int evp_pkey_ctx_setget_params_to_ctrl(EVP_PKEY_CTX *pctx,  int evp_pkey_ctx_set_params_to_ctrl(EVP_PKEY_CTX *ctx, const OSSL_PARAM *params)  { +    if (ctx->keymgmt != NULL) +        return 0;      return evp_pkey_ctx_setget_params_to_ctrl(ctx, SET, (OSSL_PARAM *)params);  }  int evp_pkey_ctx_get_params_to_ctrl(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)  { +    if (ctx->keymgmt != NULL) +        return 0;      return evp_pkey_ctx_setget_params_to_ctrl(ctx, GET, params);  } diff --git a/crypto/evp/evp_pbe.c b/crypto/evp/evp_pbe.c index 56ee69865c9e..1eb03a119a64 100644 --- a/crypto/evp/evp_pbe.c +++ b/crypto/evp/evp_pbe.c @@ -1,5 +1,5 @@  /* - * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -40,7 +40,8 @@ static const EVP_PBE_CTL builtin_pbe[] = {      {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC,       NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen, PKCS5_PBE_keyivgen_ex}, -    {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen}, +    {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen, +     PKCS5_v2_PBKDF2_keyivgen_ex},      {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4,       NID_rc4, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex}, diff --git a/crypto/evp/evp_rand.c b/crypto/evp/evp_rand.c index c36dbdc56c77..99c2da0b161d 100644 --- a/crypto/evp/evp_rand.c +++ b/crypto/evp/evp_rand.c @@ -1,5 +1,5 @@  /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -634,10 +634,8 @@ static int evp_rand_nonce_locked(EVP_RAND_CTX *ctx, unsigned char *out,  {      unsigned int str = evp_rand_strength_locked(ctx); -    if (ctx->meth->nonce == NULL) -        return 0; -    if (ctx->meth->nonce(ctx->algctx, out, str, outlen, outlen)) -        return 1; +    if (ctx->meth->nonce != NULL) +        return ctx->meth->nonce(ctx->algctx, out, str, outlen, outlen) > 0;      return evp_rand_generate_locked(ctx, out, outlen, str, 0, NULL, 0);  } diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c index d7a4ad142aa7..859c77ca420e 100644 --- a/crypto/evp/exchange.c +++ b/crypto/evp/exchange.c @@ -1,5 +1,5 @@  /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -430,7 +430,13 @@ int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, EVP_PKEY *peer,       */      if (provkey == NULL)          goto legacy; -    return ctx->op.kex.exchange->set_peer(ctx->op.kex.algctx, provkey); +    ret = ctx->op.kex.exchange->set_peer(ctx->op.kex.algctx, provkey); +    if (ret <= 0) +        return ret; +    EVP_PKEY_free(ctx->peerkey); +    ctx->peerkey = peer; +    EVP_PKEY_up_ref(peer); +    return 1;   legacy:  #ifdef FIPS_MODULE diff --git a/crypto/evp/legacy_sha.c b/crypto/evp/legacy_sha.c index ca9a3264978a..02ce0f042c5a 100644 --- a/crypto/evp/legacy_sha.c +++ b/crypto/evp/legacy_sha.c @@ -1,5 +1,5 @@  /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -215,7 +215,7 @@ const EVP_MD *EVP_shake##bitlen(void)                                          \          NID_shake##bitlen,                                                     \          0,                                                                     \          bitlen / 8,                                                            \ -        EVP_MD_FLAG_XOF,                                                       \ +        EVP_MD_FLAG_XOF | EVP_MD_FLAG_DIGALGID_ABSENT,                         \          EVP_ORIG_GLOBAL,                                                       \          LEGACY_EVP_MD_METH_TABLE(shake_init, sha3_int_update, sha3_int_final,  \                          shake_ctrl, (KECCAK1600_WIDTH - bitlen * 2) / 8),      \ diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 6ff7eb7e02cf..0ce7f19b4128 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -1095,15 +1095,14 @@ int EVP_PKEY_can_sign(const EVP_PKEY *pkey)      } else {          const OSSL_PROVIDER *prov = EVP_KEYMGMT_get0_provider(pkey->keymgmt);          OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); -        const char *supported_sig = -            pkey->keymgmt->query_operation_name != NULL -            ? pkey->keymgmt->query_operation_name(OSSL_OP_SIGNATURE) -            : EVP_KEYMGMT_get0_name(pkey->keymgmt); -        EVP_SIGNATURE *signature = NULL; - -        signature = EVP_SIGNATURE_fetch(libctx, supported_sig, NULL); -        if (signature != NULL) { -            EVP_SIGNATURE_free(signature); +        EVP_SIGNATURE *sig; +        const char *name; + +        name = evp_keymgmt_util_query_operation_name(pkey->keymgmt, +                                                     OSSL_OP_SIGNATURE); +        sig = EVP_SIGNATURE_fetch(libctx, name, NULL); +        if (sig != NULL) { +            EVP_SIGNATURE_free(sig);              return 1;          }      } diff --git a/crypto/evp/p_seal.c b/crypto/evp/p_seal.c index 475082d43116..3cb66ef84625 100644 --- a/crypto/evp/p_seal.c +++ b/crypto/evp/p_seal.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -56,6 +56,7 @@ int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,      for (i = 0; i < npubk; i++) {          size_t keylen = len; +        size_t outlen = EVP_PKEY_get_size(pubk[i]);          pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pubk[i], NULL);          if (pctx == NULL) { @@ -64,9 +65,9 @@ int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,          }          if (EVP_PKEY_encrypt_init(pctx) <= 0 -            || EVP_PKEY_encrypt(pctx, ek[i], &keylen, key, keylen) <= 0) +            || EVP_PKEY_encrypt(pctx, ek[i], &outlen, key, keylen) <= 0)              goto err; -        ekl[i] = (int)keylen; +        ekl[i] = (int)outlen;          EVP_PKEY_CTX_free(pctx);      }      pctx = NULL; diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 5cd0c4b27f6d..d9a22799d051 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -1,5 +1,5 @@  /* - * Copyright 2006-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -501,6 +501,12 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)      }      rctx->legacy_keytype = pctx->legacy_keytype; +    if (pctx->keymgmt != NULL) { +        if (!EVP_KEYMGMT_up_ref(pctx->keymgmt)) +            goto err; +        rctx->keymgmt = pctx->keymgmt; +    } +      if (EVP_PKEY_CTX_IS_DERIVE_OP(pctx)) {          if (pctx->op.kex.exchange != NULL) {              rctx->op.kex.exchange = pctx->op.kex.exchange; @@ -604,6 +610,9 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)              EVP_KEYMGMT *tmp_keymgmt = pctx->keymgmt;              void *provkey; +            if (pctx->pkey == NULL) +                return rctx; +              provkey = evp_pkey_export_to_provider(pctx->pkey, pctx->libctx,                                                    &tmp_keymgmt, pctx->propquery);              if (provkey == NULL) @@ -721,8 +730,9 @@ int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, const OSSL_PARAM *params)                  ctx->op.encap.kem->set_ctx_params(ctx->op.encap.algctx,                                                    params);          break; -#ifndef FIPS_MODULE      case EVP_PKEY_STATE_UNKNOWN: +        break; +#ifndef FIPS_MODULE      case EVP_PKEY_STATE_LEGACY:          return evp_pkey_ctx_set_params_to_ctrl(ctx, params);  #endif @@ -759,8 +769,9 @@ int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)                  ctx->op.encap.kem->get_ctx_params(ctx->op.encap.algctx,                                                    params);          break; -#ifndef FIPS_MODULE      case EVP_PKEY_STATE_UNKNOWN: +        break; +#ifndef FIPS_MODULE      case EVP_PKEY_STATE_LEGACY:          return evp_pkey_ctx_get_params_to_ctrl(ctx, params);  #endif diff --git a/crypto/http/http_client.c b/crypto/http/http_client.c index c86db4405b8f..c1fe9df5d02f 100644 --- a/crypto/http/http_client.c +++ b/crypto/http/http_client.c @@ -1,5 +1,5 @@  /* - * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.   * Copyright Siemens AG 2018-2020   *   * Licensed under the Apache License 2.0 (the "License").  You may not use @@ -1138,13 +1138,12 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy,                     const char *expected_ct, int expect_asn1,                     size_t max_resp_len, int timeout)  { -    char *current_url, *redirection_url = NULL; +    char *current_url;      int n_redirs = 0;      char *host;      char *port;      char *path;      int use_ssl; -    OSSL_HTTP_REQ_CTX *rctx = NULL;      BIO *resp = NULL;      time_t max_time = timeout > 0 ? time(NULL) + timeout : 0; @@ -1156,6 +1155,9 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy,          return NULL;      for (;;) { +        char *redirection_url; +        OSSL_HTTP_REQ_CTX *rctx; +          if (!OSSL_HTTP_parse_url(current_url, &use_ssl, NULL /* user */, &host,                                   &port, NULL /* port_num */, &path, NULL, NULL))              break; @@ -1164,6 +1166,7 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy,                                use_ssl, bio, rbio, bio_update_fn, arg,                                buf_size, timeout);      new_rpath: +        redirection_url = NULL;          if (rctx != NULL) {              if (!OSSL_HTTP_set1_request(rctx, path, headers,                                          NULL /* content_type */, @@ -1173,9 +1176,9 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy,                                          0 /* no keep_alive */)) {                  OSSL_HTTP_REQ_CTX_free(rctx);                  rctx = NULL; -           } else { +            } else {                  resp = OSSL_HTTP_exchange(rctx, &redirection_url); -           } +            }          }          OPENSSL_free(path);          if (resp == NULL && redirection_url != NULL) { @@ -1190,7 +1193,6 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy,                          OPENSSL_free(host);                          OPENSSL_free(port);                          (void)OSSL_HTTP_close(rctx, 1); -                        rctx = NULL;                          BIO_free(resp);                          OPENSSL_free(current_url);                          return NULL; @@ -1200,7 +1202,6 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy,                  OPENSSL_free(host);                  OPENSSL_free(port);                  (void)OSSL_HTTP_close(rctx, 1); -                rctx = NULL;                  continue;              }              /* if redirection not allowed, ignore it */ @@ -1210,7 +1211,6 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy,          OPENSSL_free(port);          if (!OSSL_HTTP_close(rctx, resp != NULL)) {              BIO_free(resp); -            rctx = NULL;              resp = NULL;          }          break; diff --git a/crypto/http/http_lib.c b/crypto/http/http_lib.c index 9c41f57541d7..614fd200b7c0 100644 --- a/crypto/http/http_lib.c +++ b/crypto/http/http_lib.c @@ -267,6 +267,7 @@ static int use_proxy(const char *no_proxy, const char *server)          /* strip leading '[' and trailing ']' from escaped IPv6 address */          sl -= 2;          strncpy(host, server + 1, sl); +        host[sl] = '\0';          server = host;      } diff --git a/crypto/info.c b/crypto/info.c index a0dc2e80136f..b14afc777339 100644 --- a/crypto/info.c +++ b/crypto/info.c @@ -1,5 +1,5 @@  /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -18,6 +18,9 @@  #if defined(__arm__) || defined(__arm) || defined(__aarch64__)  # include "arm_arch.h"  # define CPU_INFO_STR_LEN 128 +#elif defined(__powerpc__) || defined(__POWERPC__) || defined(_ARCH_PPC) +# include "crypto/ppc_arch.h" +# define CPU_INFO_STR_LEN 128  #elif defined(__s390__) || defined(__s390x__)  # include "s390x_arch.h"  # define CPU_INFO_STR_LEN 2048 @@ -62,6 +65,15 @@ DEFINE_RUN_ONCE_STATIC(init_info_strings)          BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str),                       sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str),                       " env:%s", env); +# elif defined(__powerpc__) || defined(__POWERPC__) || defined(_ARCH_PPC) +    const char *env; + +    BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str), +                 CPUINFO_PREFIX "OPENSSL_ppccap=0x%x", OPENSSL_ppccap_P); +    if ((env = getenv("OPENSSL_ppccap")) != NULL) +        BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str), +                     sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str), +                     " env:%s", env);  # elif defined(__s390__) || defined(__s390x__)      const char *env; diff --git a/crypto/modes/siv128.c b/crypto/modes/siv128.c index e6348a8d3753..76f43e347671 100644 --- a/crypto/modes/siv128.c +++ b/crypto/modes/siv128.c @@ -1,5 +1,5 @@  /* - * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -202,9 +202,12 @@ int ossl_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen,              || !EVP_MAC_final(mac_ctx, ctx->d.byte, &out_len,                                sizeof(ctx->d.byte))) {          EVP_CIPHER_CTX_free(ctx->cipher_ctx); +        ctx->cipher_ctx = NULL;          EVP_MAC_CTX_free(ctx->mac_ctx_init); +        ctx->mac_ctx_init = NULL;          EVP_MAC_CTX_free(mac_ctx);          EVP_MAC_free(ctx->mac); +        ctx->mac = NULL;          return 0;      }      EVP_MAC_CTX_free(mac_ctx); diff --git a/crypto/params_dup.c b/crypto/params_dup.c index bc1546fc53cb..f2c9537be8b1 100644 --- a/crypto/params_dup.c +++ b/crypto/params_dup.c @@ -1,5 +1,5 @@  /* - * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -189,18 +189,18 @@ OSSL_PARAM *OSSL_PARAM_merge(const OSSL_PARAM *p1, const OSSL_PARAM *p2)      while (1) {          /* If list1 is finished just tack list2 onto the end */          if (*p1cur == NULL) { -            do { +            while (*p2cur != NULL) {                  *dst++ = **p2cur;                  p2cur++; -            } while (*p2cur != NULL); +            }              break;          }          /* If list2 is finished just tack list1 onto the end */          if (*p2cur == NULL) { -            do { +            while (*p1cur != NULL) {                  *dst++ = **p1cur;                  p1cur++; -            } while (*p1cur != NULL); +            }              break;          }          /* consume the list element with the smaller key */ diff --git a/crypto/perlasm/sparcv9_modes.pl b/crypto/perlasm/sparcv9_modes.pl index 76a2727aba62..3f24511c1a6b 100644 --- a/crypto/perlasm/sparcv9_modes.pl +++ b/crypto/perlasm/sparcv9_modes.pl @@ -1,5 +1,5 @@  #! /usr/bin/env perl -# Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2012-2025 The OpenSSL Project Authors. All Rights Reserved.  #  # Licensed under the Apache License 2.0 (the "License").  You may not use  # this file except in compliance with the License.  You can obtain a copy @@ -46,8 +46,8 @@ $::code.=<<___;  .align	32  ${alg}${bits}_t4_cbc_encrypt:  	save		%sp, -$::frame, %sp -	cmp		$len, 0 -	be,pn		$::size_t_cc, .L${bits}_cbc_enc_abort +	cmp		$len, 15 +	bleu,pn	$::size_t_cc, .L${bits}_cbc_enc_abort  	srln		$len, 0, $len		! needed on v8+, "nop" on v9  	sub		$inp, $out, $blk_init	! $inp!=$out  ___ @@ -264,8 +264,8 @@ $::code.=<<___;  .align	32  ${alg}${bits}_t4_cbc_decrypt:  	save		%sp, -$::frame, %sp -	cmp		$len, 0 -	be,pn		$::size_t_cc, .L${bits}_cbc_dec_abort +	cmp		$len, 15 +	bleu,pn		$::size_t_cc, .L${bits}_cbc_dec_abort  	srln		$len, 0, $len		! needed on v8+, "nop" on v9  	sub		$inp, $out, $blk_init	! $inp!=$out  ___ diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c index e9de097da186..ad9416d423b5 100644 --- a/crypto/pkcs7/pk7_doit.c +++ b/crypto/pkcs7/pk7_doit.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -334,8 +334,11 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)                  if (xalg->parameter == NULL)                      goto err;              } -            if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) <= 0) +            if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) <= 0) { +                ASN1_TYPE_free(xalg->parameter); +                xalg->parameter = NULL;                  goto err; +            }          }          /* Lets do the pub key stuff :-) */ diff --git a/crypto/pkcs7/pk7_smime.c b/crypto/pkcs7/pk7_smime.c index 4593da8f5b41..6812829ead30 100644 --- a/crypto/pkcs7/pk7_smime.c +++ b/crypto/pkcs7/pk7_smime.c @@ -1,5 +1,5 @@  /* - * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -347,10 +347,8 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,      if (flags & PKCS7_TEXT) {          if (!SMIME_text(tmpout, out)) {              ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SMIME_TEXT_ERROR); -            BIO_free(tmpout);              goto err;          } -        BIO_free(tmpout);      }      /* Now Verify All Signatures */ @@ -368,6 +366,8 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,      ret = 1;   err: +    if (flags & PKCS7_TEXT) +        BIO_free(tmpout);      X509_STORE_CTX_free(cert_ctx);      OPENSSL_free(buf);      if (tmpin == indata) { diff --git a/crypto/property/property.c b/crypto/property/property.c index 75615d39af36..b0a24a7ccb6e 100644 --- a/crypto/property/property.c +++ b/crypto/property/property.c @@ -1,5 +1,5 @@  /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.   * Copyright (c) 2019, Oracle and/or its affiliates.  All rights reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use @@ -329,7 +329,7 @@ int ossl_method_store_add(OSSL_METHOD_STORE *store, const OSSL_PROVIDER *prov,      /* Insert into the hash table if required */      if (!ossl_property_write_lock(store)) { -        OPENSSL_free(impl); +        impl_free(impl);          return 0;      }      ossl_method_cache_flush(store, nid); diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c index 45c798f1b50b..1548c07563e5 100644 --- a/crypto/property/property_parse.c +++ b/crypto/property/property_parse.c @@ -1,5 +1,5 @@  /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.   * Copyright (c) 2019, Oracle and/or its affiliates.  All rights reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use @@ -642,7 +642,7 @@ static void put_str(const char *str, char **buf, size_t *remain, size_t *needed)          }      quotes = quote != '\0'; -    if (*remain == 0) { +    if (*remain <= (size_t)quotes) {          *needed += 2 * quotes;          return;      } diff --git a/crypto/provider_conf.c b/crypto/provider_conf.c index 9333b8777f2b..b42e8412bec0 100644 --- a/crypto/provider_conf.c +++ b/crypto/provider_conf.c @@ -1,5 +1,5 @@  /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -331,7 +331,7 @@ static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name,              ok = provider_conf_params(NULL, &entry, NULL, value, cnf);          if (ok >= 1 && (entry.path != NULL || entry.parameters != NULL)) {              ok = ossl_provider_info_add_to_store(libctx, &entry); -            added = 1; +            added = ok;          }          if (added == 0)              ossl_provider_info_clear(&entry); diff --git a/crypto/rand/randfile.c b/crypto/rand/randfile.c index b4854a4c4eab..e7a5cc6b8e5f 100644 --- a/crypto/rand/randfile.c +++ b/crypto/rand/randfile.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -167,6 +167,10 @@ int RAND_load_file(const char *file, long bytes)          /* If given a bytecount, and we did it, break. */          if (bytes > 0 && (bytes -= i) <= 0)              break; + +        /* We can hit a signed integer overflow on the next iteration */ +        if (ret > INT_MAX - RAND_LOAD_BUF_SIZE) +            break;      }      OPENSSL_cleanse(buf, sizeof(buf)); diff --git a/crypto/sm2/sm2_sign.c b/crypto/sm2/sm2_sign.c index 2097cd2fca86..85b42d8d7725 100644 --- a/crypto/sm2/sm2_sign.c +++ b/crypto/sm2/sm2_sign.c @@ -1,5 +1,5 @@  /* - * Copyright 2017-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved.   * Copyright 2017 Ribose Inc. All Rights Reserved.   * Ported from Ribose contributions from Botan.   * @@ -217,6 +217,10 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e)      BIGNUM *tmp = NULL;      OSSL_LIB_CTX *libctx = ossl_ec_key_get_libctx(key); +    if (dA == NULL) { +        ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_PRIVATE_KEY); +        goto done; +    }      kG = EC_POINT_new(group);      ctx = BN_CTX_new_ex(libctx);      if (kG == NULL || ctx == NULL) { diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c index bc12d8dd13a2..b81d3982c567 100644 --- a/crypto/store/store_lib.c +++ b/crypto/store/store_lib.c @@ -1,5 +1,5 @@  /* - * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -410,12 +410,6 @@ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx)      if (ctx->loader != NULL)          OSSL_TRACE(STORE, "Loading next object\n"); -    if (ctx->cached_info != NULL -        && sk_OSSL_STORE_INFO_num(ctx->cached_info) == 0) { -        sk_OSSL_STORE_INFO_free(ctx->cached_info); -        ctx->cached_info = NULL; -    } -      if (ctx->cached_info != NULL) {          v = sk_OSSL_STORE_INFO_shift(ctx->cached_info);      } else { @@ -491,14 +485,23 @@ int OSSL_STORE_error(OSSL_STORE_CTX *ctx)  int OSSL_STORE_eof(OSSL_STORE_CTX *ctx)  { -    int ret = 1; +    int ret = 0; -    if (ctx->fetched_loader != NULL) -        ret = ctx->loader->p_eof(ctx->loader_ctx); +    if (ctx->cached_info != NULL +        && sk_OSSL_STORE_INFO_num(ctx->cached_info) == 0) { +        sk_OSSL_STORE_INFO_free(ctx->cached_info); +        ctx->cached_info = NULL; +    } + +    if (ctx->cached_info == NULL) { +        ret = 1; +        if (ctx->fetched_loader != NULL) +            ret = ctx->loader->p_eof(ctx->loader_ctx);  #ifndef OPENSSL_NO_DEPRECATED_3_0 -    if (ctx->fetched_loader == NULL) -        ret = ctx->loader->eof(ctx->loader_ctx); +        if (ctx->fetched_loader == NULL) +            ret = ctx->loader->eof(ctx->loader_ctx);  #endif +    }      return ret != 0;  } diff --git a/crypto/threads_pthread.c b/crypto/threads_pthread.c index 801855c9306e..dfa338b11734 100644 --- a/crypto/threads_pthread.c +++ b/crypto/threads_pthread.c @@ -1,5 +1,5 @@  /* - * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -38,7 +38,13 @@  # include <assert.h> -# ifdef PTHREAD_RWLOCK_INITIALIZER +/* + * The Non-Stop KLT thread model currently seems broken in its rwlock + * implementation + * Likewise is there a problem with the glibc implementation on riscv. + */ +# if defined(PTHREAD_RWLOCK_INITIALIZER) && !defined(_KLT_MODEL_) \ +                                         && !defined(__riscv)  #  define USE_RWLOCK  # endif @@ -250,7 +256,7 @@ int CRYPTO_atomic_or(uint64_t *val, uint64_t op, uint64_t *ret,  int CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock)  { -# if defined(__GNUC__) && defined(__ATOMIC_ACQUIRE) && !defined(BROKEN_CLANG_ATOMICS) +# if defined(__GNUC__) && defined(__ATOMIC_ACQ_REL) && !defined(BROKEN_CLANG_ATOMICS)      if (__atomic_is_lock_free(sizeof(*val), val)) {          __atomic_load(val, ret, __ATOMIC_ACQUIRE);          return 1; diff --git a/crypto/ts/ts_rsp_sign.c b/crypto/ts/ts_rsp_sign.c index 8937bb2d6671..99de0bb1a2e5 100644 --- a/crypto/ts/ts_rsp_sign.c +++ b/crypto/ts/ts_rsp_sign.c @@ -1,5 +1,5 @@  /* - * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -645,8 +645,12 @@ static int ossl_ess_add1_signing_cert(PKCS7_SIGNER_INFO *si,      }      OPENSSL_free(pp); -    return PKCS7_add_signed_attribute(si, NID_id_smime_aa_signingCertificate, -                                      V_ASN1_SEQUENCE, seq); +    if (!PKCS7_add_signed_attribute(si, NID_id_smime_aa_signingCertificate, +                                    V_ASN1_SEQUENCE, seq)) { +        ASN1_STRING_free(seq); +        return 0; +    } +    return 1;  }  static int ossl_ess_add1_signing_cert_v2(PKCS7_SIGNER_INFO *si, @@ -668,8 +672,12 @@ static int ossl_ess_add1_signing_cert_v2(PKCS7_SIGNER_INFO *si,      }      OPENSSL_free(pp); -    return PKCS7_add_signed_attribute(si, NID_id_smime_aa_signingCertificateV2, -                                      V_ASN1_SEQUENCE, seq); +    if (!PKCS7_add_signed_attribute(si, NID_id_smime_aa_signingCertificateV2, +                                    V_ASN1_SEQUENCE, seq)) { +        ASN1_STRING_free(seq); +        return 0; +    } +    return 1;  }  static int ts_RESP_sign(TS_RESP_CTX *ctx) diff --git a/crypto/ui/ui_lib.c b/crypto/ui/ui_lib.c index 2ddf76cb5357..fe7393bfd610 100644 --- a/crypto/ui/ui_lib.c +++ b/crypto/ui/ui_lib.c @@ -1,5 +1,5 @@  /* - * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -207,6 +207,7 @@ int UI_dup_input_string(UI *ui, const char *prompt, int flags,                          char *result_buf, int minsize, int maxsize)  {      char *prompt_copy = NULL; +    int ret;      if (prompt != NULL) {          prompt_copy = OPENSSL_strdup(prompt); @@ -216,9 +217,13 @@ int UI_dup_input_string(UI *ui, const char *prompt, int flags,          }      } -    return general_allocate_string(ui, prompt_copy, 1, -                                   UIT_PROMPT, flags, result_buf, minsize, -                                   maxsize, NULL); +    ret = general_allocate_string(ui, prompt_copy, 1, +                                  UIT_PROMPT, flags, result_buf, minsize, +                                  maxsize, NULL); +    if (ret <= 0) +        OPENSSL_free(prompt_copy); + +    return ret;  }  int UI_add_verify_string(UI *ui, const char *prompt, int flags, @@ -235,6 +240,7 @@ int UI_dup_verify_string(UI *ui, const char *prompt, int flags,                           const char *test_buf)  {      char *prompt_copy = NULL; +    int ret;      if (prompt != NULL) {          prompt_copy = OPENSSL_strdup(prompt); @@ -244,9 +250,12 @@ int UI_dup_verify_string(UI *ui, const char *prompt, int flags,          }      } -    return general_allocate_string(ui, prompt_copy, 1, -                                   UIT_VERIFY, flags, result_buf, minsize, -                                   maxsize, test_buf); +    ret = general_allocate_string(ui, prompt_copy, 1, +                                  UIT_VERIFY, flags, result_buf, minsize, +                                  maxsize, test_buf); +    if (ret <= 0) +        OPENSSL_free(prompt_copy); +    return ret;  }  int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, @@ -266,6 +275,7 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,      char *action_desc_copy = NULL;      char *ok_chars_copy = NULL;      char *cancel_chars_copy = NULL; +    int ret;      if (prompt != NULL) {          prompt_copy = OPENSSL_strdup(prompt); @@ -299,9 +309,14 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,          }      } -    return general_allocate_boolean(ui, prompt_copy, action_desc_copy, -                                    ok_chars_copy, cancel_chars_copy, 1, -                                    UIT_BOOLEAN, flags, result_buf); +    ret = general_allocate_boolean(ui, prompt_copy, action_desc_copy, +                                   ok_chars_copy, cancel_chars_copy, 1, +                                   UIT_BOOLEAN, flags, result_buf); +    if (ret <= 0) +        goto err; + +    return ret; +   err:      OPENSSL_free(prompt_copy);      OPENSSL_free(action_desc_copy); @@ -319,6 +334,7 @@ int UI_add_info_string(UI *ui, const char *text)  int UI_dup_info_string(UI *ui, const char *text)  {      char *text_copy = NULL; +    int ret;      if (text != NULL) {          text_copy = OPENSSL_strdup(text); @@ -328,8 +344,11 @@ int UI_dup_info_string(UI *ui, const char *text)          }      } -    return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL, -                                   0, 0, NULL); +    ret = general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL, +                                  0, 0, NULL); +    if (ret <= 0) +        OPENSSL_free(text_copy); +    return ret;  }  int UI_add_error_string(UI *ui, const char *text) @@ -341,6 +360,7 @@ int UI_add_error_string(UI *ui, const char *text)  int UI_dup_error_string(UI *ui, const char *text)  {      char *text_copy = NULL; +    int ret;      if (text != NULL) {          text_copy = OPENSSL_strdup(text); @@ -349,8 +369,12 @@ int UI_dup_error_string(UI *ui, const char *text)              return -1;          }      } -    return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL, -                                   0, 0, NULL); + +    ret = general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL, +                                  0, 0, NULL); +    if (ret <= 0) +        OPENSSL_free(text_copy); +    return ret;  }  char *UI_construct_prompt(UI *ui, const char *phrase_desc, diff --git a/crypto/x509/by_store.c b/crypto/x509/by_store.c index 050735ce3247..a00fc2c7352f 100644 --- a/crypto/x509/by_store.c +++ b/crypto/x509/by_store.c @@ -1,5 +1,5 @@  /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -7,22 +7,30 @@   * https://www.openssl.org/source/license.html   */ +#include <openssl/safestack.h>  #include <openssl/store.h>  #include "internal/cryptlib.h"  #include "crypto/x509.h"  #include "x509_local.h" +typedef struct cached_store_st { +    char *uri; +    OSSL_LIB_CTX *libctx; +    char *propq; +} CACHED_STORE; + +DEFINE_STACK_OF(CACHED_STORE) +  /* Generic object loader, given expected type and criterion */ -static int cache_objects(X509_LOOKUP *lctx, const char *uri, -                         const OSSL_STORE_SEARCH *criterion, -                         int depth, OSSL_LIB_CTX *libctx, const char *propq) +static int cache_objects(X509_LOOKUP *lctx, CACHED_STORE *store, +                         const OSSL_STORE_SEARCH *criterion, int depth)  {      int ok = 0; -    OSSL_STORE_CTX *ctx = NULL; +    OSSL_STORE_CTX *ctx;      X509_STORE *xstore = X509_LOOKUP_get_store(lctx); -    if ((ctx = OSSL_STORE_open_ex(uri, libctx, propq, NULL, NULL, NULL, -                                  NULL, NULL)) == NULL) +    if ((ctx = OSSL_STORE_open_ex(store->uri, store->libctx, store->propq, +                                  NULL, NULL, NULL, NULL, NULL)) == NULL)          return 0;      /* @@ -62,9 +70,14 @@ static int cache_objects(X509_LOOKUP *lctx, const char *uri,               * This is an entry in the "directory" represented by the current               * uri.  if |depth| allows, dive into it.               */ -            if (depth > 0) -                ok = cache_objects(lctx, OSSL_STORE_INFO_get0_NAME(info), -                                   criterion, depth - 1, libctx, propq); +            if (depth > 0) { +                CACHED_STORE substore; + +                substore.uri = (char *)OSSL_STORE_INFO_get0_NAME(info); +                substore.libctx = store->libctx; +                substore.propq = store->propq; +                ok = cache_objects(lctx, &substore, criterion, depth - 1); +            }          } else {              /*               * We know that X509_STORE_add_{cert|crl} increments the object's @@ -93,22 +106,31 @@ static int cache_objects(X509_LOOKUP *lctx, const char *uri,  } -/* Because OPENSSL_free is a macro and for C type match */ -static void free_uri(OPENSSL_STRING data) +static void free_store(CACHED_STORE *store)  { -    OPENSSL_free(data); +    if (store != NULL) { +        OPENSSL_free(store->uri); +        OPENSSL_free(store->propq); +        OPENSSL_free(store); +    }  }  static void by_store_free(X509_LOOKUP *ctx)  { -    STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx); -    sk_OPENSSL_STRING_pop_free(uris, free_uri); +    STACK_OF(CACHED_STORE) *stores = X509_LOOKUP_get_method_data(ctx); +    sk_CACHED_STORE_pop_free(stores, free_store);  }  static int by_store_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argp,                              long argl, char **retp, OSSL_LIB_CTX *libctx,                              const char *propq)  { +    /* +     * In some cases below, failing to use the defaults shouldn't result in +     * an error.  |use_default| is used as the return code in those cases. +     */ +    int use_default = argp == NULL; +      switch (cmd) {      case X509_L_ADD_STORE:          /* If no URI is given, use the default cert dir as default URI */ @@ -118,21 +140,56 @@ static int by_store_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argp,              argp = X509_get_default_cert_dir();          { -            STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx); -            char *data = OPENSSL_strdup(argp); +            STACK_OF(CACHED_STORE) *stores = X509_LOOKUP_get_method_data(ctx); +            CACHED_STORE *store = OPENSSL_zalloc(sizeof(*store)); +            OSSL_STORE_CTX *sctx; -            if (data == NULL) { +            if (store == NULL) {                  return 0;              } -            if (uris == NULL) { -                uris = sk_OPENSSL_STRING_new_null(); -                X509_LOOKUP_set_method_data(ctx, uris); + +            store->uri = OPENSSL_strdup(argp); +            store->libctx = libctx; +            if (propq != NULL) +                store->propq = OPENSSL_strdup(propq); +            /* +             * We open this to check for errors now - so we can report those +             * errors early. +             */ +            sctx = OSSL_STORE_open_ex(argp, libctx, propq, NULL, NULL, +                                      NULL, NULL, NULL); +            if (sctx == NULL +                || (propq != NULL && store->propq == NULL) +                || store->uri == NULL) { +                OSSL_STORE_close(sctx); +                free_store(store); +                return use_default;              } -            return sk_OPENSSL_STRING_push(uris, data) > 0; +            OSSL_STORE_close(sctx); + +            if (stores == NULL) { +                stores = sk_CACHED_STORE_new_null(); +                if (stores != NULL) +                    X509_LOOKUP_set_method_data(ctx, stores); +            } +            if (stores == NULL || sk_CACHED_STORE_push(stores, store) <= 0) { +                free_store(store); +                return 0; +            } +            return 1;          } -    case X509_L_LOAD_STORE: +    case X509_L_LOAD_STORE: {          /* This is a shortcut for quick loading of specific containers */ -        return cache_objects(ctx, argp, NULL, 0, libctx, propq); +        CACHED_STORE store; + +        store.uri = (char *)argp; +        store.libctx = libctx; +        store.propq = (char *)propq; +        return cache_objects(ctx, &store, NULL, 0); +    } +    default: +        /* Unsupported command */ +        return 0;      }      return 0; @@ -145,16 +202,15 @@ static int by_store_ctrl(X509_LOOKUP *ctx, int cmd,  }  static int by_store(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, -                    const OSSL_STORE_SEARCH *criterion, X509_OBJECT *ret, -                    OSSL_LIB_CTX *libctx, const char *propq) +                    const OSSL_STORE_SEARCH *criterion, X509_OBJECT *ret)  { -    STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx); +    STACK_OF(CACHED_STORE) *stores = X509_LOOKUP_get_method_data(ctx);      int i;      int ok = 0; -    for (i = 0; i < sk_OPENSSL_STRING_num(uris); i++) { -        ok = cache_objects(ctx, sk_OPENSSL_STRING_value(uris, i), criterion, -                           1 /* depth */, libctx, propq); +    for (i = 0; i < sk_CACHED_STORE_num(stores); i++) { +        ok = cache_objects(ctx, sk_CACHED_STORE_value(stores, i), criterion, +                           1 /* depth */);          if (ok)              break; @@ -162,21 +218,26 @@ static int by_store(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,      return ok;  } -static int by_store_subject_ex(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, -                               const X509_NAME *name, X509_OBJECT *ret, -                               OSSL_LIB_CTX *libctx, const char *propq) +static int by_store_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, +                            const X509_NAME *name, X509_OBJECT *ret)  {      OSSL_STORE_SEARCH *criterion =          OSSL_STORE_SEARCH_by_name((X509_NAME *)name); /* won't modify it */ -    int ok = by_store(ctx, type, criterion, ret, libctx, propq); +    int ok = by_store(ctx, type, criterion, ret);      STACK_OF(X509_OBJECT) *store_objects =          X509_STORE_get0_objects(X509_LOOKUP_get_store(ctx));      X509_OBJECT *tmp = NULL;      OSSL_STORE_SEARCH_free(criterion); -    if (ok) +    if (ok) { +        X509_STORE *store = X509_LOOKUP_get_store(ctx); + +        if (!X509_STORE_lock(store)) +            return 0;          tmp = X509_OBJECT_retrieve_by_subject(store_objects, type, name); +        X509_STORE_unlock(store); +    }      ok = 0;      if (tmp != NULL) { @@ -216,12 +277,6 @@ static int by_store_subject_ex(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,      return ok;  } -static int by_store_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, -                            const X509_NAME *name, X509_OBJECT *ret) -{ -    return by_store_subject_ex(ctx, type, name, ret, NULL, NULL); -} -  /*   * We lack the implementations for get_by_issuer_serial, get_by_fingerprint   * and get_by_alias.  There's simply not enough support in the X509_LOOKUP @@ -239,7 +294,7 @@ static X509_LOOKUP_METHOD x509_store_lookup = {      NULL,                        /* get_by_issuer_serial */      NULL,                        /* get_by_fingerprint */      NULL,                        /* get_by_alias */ -    by_store_subject_ex, +    NULL,                        /* get_by_subject_ex */      by_store_ctrl_ex  }; diff --git a/crypto/x509/t_req.c b/crypto/x509/t_req.c index 63626c0d9810..c6b73c1d6208 100644 --- a/crypto/x509/t_req.c +++ b/crypto/x509/t_req.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -40,7 +40,7 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,      long l;      int i;      EVP_PKEY *pkey; -    STACK_OF(X509_EXTENSION) *exts; +    STACK_OF(X509_EXTENSION) *exts = NULL;      char mlch = ' ';      int nmindent = 0, printok = 0; @@ -191,6 +191,7 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,                      goto err;              }              sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); +            exts = NULL;          }      } @@ -204,6 +205,7 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,      return 1;   err: +    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);      ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB);      return 0;  } diff --git a/crypto/x509/t_x509.c b/crypto/x509/t_x509.c index 5b0282bc132f..3333cf131d92 100644 --- a/crypto/x509/t_x509.c +++ b/crypto/x509/t_x509.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -243,7 +243,8 @@ int X509_ocspid_print(BIO *bp, X509 *x)          goto err;      if ((der = dertmp = OPENSSL_malloc(derlen)) == NULL)          goto err; -    i2d_X509_NAME(subj, &dertmp); +    if (i2d_X509_NAME(subj, &dertmp) < 0) +        goto err;      md = EVP_MD_fetch(x->libctx, SN_sha1, x->propq);      if (md == NULL) diff --git a/crypto/x509/v3_lib.c b/crypto/x509/v3_lib.c index 5ffeb75d9f5b..6d91df99550f 100644 --- a/crypto/x509/v3_lib.c +++ b/crypto/x509/v3_lib.c @@ -1,5 +1,5 @@  /* - * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -99,7 +99,11 @@ int X509V3_EXT_add_alias(int nid_to, int nid_from)      *tmpext = *ext;      tmpext->ext_nid = nid_to;      tmpext->ext_flags |= X509V3_EXT_DYNAMIC; -    return X509V3_EXT_add(tmpext); +    if (!X509V3_EXT_add(tmpext)) { +        OPENSSL_free(tmpext); +        return 0; +    } +    return 1;  }  void X509V3_EXT_cleanup(void) diff --git a/crypto/x509/x509_ext.c b/crypto/x509/x509_ext.c index a7b85857bdad..1d40cb5c3811 100644 --- a/crypto/x509/x509_ext.c +++ b/crypto/x509/x509_ext.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -42,9 +42,21 @@ X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc)      return X509v3_get_ext(x->crl.extensions, loc);  } +static X509_EXTENSION *delete_ext(STACK_OF(X509_EXTENSION) **sk, int loc) +{ +    X509_EXTENSION *ret = X509v3_delete_ext(*sk, loc); + +    /* Empty extension lists are omitted. */ +    if (*sk != NULL && sk_X509_EXTENSION_num(*sk) == 0) { +        sk_X509_EXTENSION_pop_free(*sk, X509_EXTENSION_free); +        *sk = NULL; +    } +    return ret; +} +  X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc)  { -    return X509v3_delete_ext(x->crl.extensions, loc); +    return delete_ext(&x->crl.extensions, loc);  }  void *X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx) @@ -91,7 +103,7 @@ X509_EXTENSION *X509_get_ext(const X509 *x, int loc)  X509_EXTENSION *X509_delete_ext(X509 *x, int loc)  { -    return X509v3_delete_ext(x->cert_info.extensions, loc); +    return delete_ext(&x->cert_info.extensions, loc);  }  int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc) @@ -139,7 +151,7 @@ X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc)  X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc)  { -    return X509v3_delete_ext(x->extensions, loc); +    return delete_ext(&x->extensions, loc);  }  int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc) diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index d8927bda0706..a9bd41faba22 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -374,7 +374,6 @@ static int x509_store_add(X509_STORE *store, void *x, int crl) {      }      if (!X509_STORE_lock(store)) { -        obj->type = X509_LU_NONE;          X509_OBJECT_free(obj);          return 0;      } diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c index 998ce8ac1ba1..0f62e331f68c 100644 --- a/crypto/x509/x509_vpm.c +++ b/crypto/x509/x509_vpm.c @@ -1,5 +1,5 @@  /* - * Copyright 2004-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -614,6 +614,11 @@ const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id)  {      int num = OSSL_NELEM(default_table); +    if (id < 0) { +        ERR_raise(ERR_LIB_X509, ERR_R_PASSED_INVALID_ARGUMENT); +        return NULL; +    } +      if (id < num)          return default_table + id;      return sk_X509_VERIFY_PARAM_value(param_table, id - num); diff --git a/demos/bio/saccept.c b/demos/bio/saccept.c index 6da22ea44091..206efbf54506 100644 --- a/demos/bio/saccept.c +++ b/demos/bio/saccept.c @@ -1,5 +1,5 @@  /* - * Copyright 1998-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -49,7 +49,8 @@ int main(int argc, char *argv[])  {      char *port = NULL;      BIO *in = NULL; -    BIO *ssl_bio, *tmp; +    BIO *ssl_bio = NULL; +    BIO *tmp;      SSL_CTX *ctx;      char buf[512];      int ret = EXIT_FAILURE, i; @@ -79,6 +80,7 @@ int main(int argc, char *argv[])       * Basically it means the SSL BIO will be automatically setup       */      BIO_set_accept_bios(in, ssl_bio); +    ssl_bio = NULL;      /* Arrange to leave server loop on interrupt */      sigsetup(); @@ -117,5 +119,6 @@ int main(int argc, char *argv[])      if (ret != EXIT_SUCCESS)          ERR_print_errors_fp(stderr);      BIO_free(in); +    BIO_free_all(ssl_bio);      return ret;  } diff --git a/demos/bio/sconnect.c b/demos/bio/sconnect.c index 18f7007ce708..27d5a9eca7a7 100644 --- a/demos/bio/sconnect.c +++ b/demos/bio/sconnect.c @@ -1,5 +1,5 @@  /* - * Copyright 1998-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -69,8 +69,10 @@ int main(int argc, char *argv[])      /* The BIO has parsed the host:port and even IPv6 literals in [] */      hostname = BIO_get_conn_hostname(out); -    if (!hostname || SSL_set1_host(ssl, hostname) <= 0) +    if (!hostname || SSL_set1_host(ssl, hostname) <= 0) { +        BIO_free(ssl_bio);          goto err; +    }      BIO_set_nbio(out, 1);      out = BIO_push(ssl_bio, out); diff --git a/demos/bio/server-arg.c b/demos/bio/server-arg.c index 60a87725a9de..ccf59b14056b 100644 --- a/demos/bio/server-arg.c +++ b/demos/bio/server-arg.c @@ -1,5 +1,5 @@  /* - * Copyright 2013-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2013-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -23,7 +23,8 @@  int main(int argc, char *argv[])  {      char *port = "*:4433"; -    BIO *ssl_bio, *tmp; +    BIO *ssl_bio = NULL; +    BIO *tmp;      SSL_CTX *ctx;      SSL_CONF_CTX *cctx;      char buf[512]; @@ -105,6 +106,7 @@ int main(int argc, char *argv[])       * Basically it means the SSL BIO will be automatically setup       */      BIO_set_accept_bios(in, ssl_bio); +    ssl_bio = NULL;   again:      /* @@ -140,5 +142,6 @@ int main(int argc, char *argv[])      if (ret != EXIT_SUCCESS)          ERR_print_errors_fp(stderr);      BIO_free(in); +    BIO_free_all(ssl_bio);      return ret;  } diff --git a/demos/bio/server-cmod.c b/demos/bio/server-cmod.c index 3642fbacf6ce..4970a6b6466b 100644 --- a/demos/bio/server-cmod.c +++ b/demos/bio/server-cmod.c @@ -1,5 +1,5 @@  /* - * Copyright 2015-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -24,7 +24,8 @@ int main(int argc, char *argv[])      unsigned char buf[512];      char *port = "*:4433";      BIO *in = NULL; -    BIO *ssl_bio, *tmp; +    BIO *ssl_bio = NULL; +    BIO *tmp;      SSL_CTX *ctx;      int ret = EXIT_FAILURE, i; @@ -52,6 +53,7 @@ int main(int argc, char *argv[])       * Basically it means the SSL BIO will be automatically setup       */      BIO_set_accept_bios(in, ssl_bio); +    ssl_bio = NULL;   again:      /* @@ -90,5 +92,6 @@ int main(int argc, char *argv[])      if (ret != EXIT_SUCCESS)          ERR_print_errors_fp(stderr);      BIO_free(in); +    BIO_free_all(ssl_bio);      return ret;  } diff --git a/demos/bio/server-conf.c b/demos/bio/server-conf.c index 5e07a15e7bc7..2c03d1d367cc 100644 --- a/demos/bio/server-conf.c +++ b/demos/bio/server-conf.c @@ -1,5 +1,5 @@  /* - * Copyright 2013-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2013-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -25,7 +25,8 @@ int main(int argc, char *argv[])  {      char *port = "*:4433";      BIO *in = NULL; -    BIO *ssl_bio, *tmp; +    BIO *ssl_bio = NULL; +    BIO *tmp;      SSL_CTX *ctx;      SSL_CONF_CTX *cctx = NULL;      CONF *conf = NULL; @@ -97,6 +98,7 @@ int main(int argc, char *argv[])       * Basically it means the SSL BIO will be automatically setup       */      BIO_set_accept_bios(in, ssl_bio); +    ssl_bio = NULL;   again:      /* @@ -135,5 +137,6 @@ int main(int argc, char *argv[])      if (ret != EXIT_SUCCESS)          ERR_print_errors_fp(stderr);      BIO_free(in); +    BIO_free_all(ssl_bio);      return ret;  } diff --git a/demos/cms/cms_ddec.c b/demos/cms/cms_ddec.c index cb6c2694c697..462067b075a7 100644 --- a/demos/cms/cms_ddec.c +++ b/demos/cms/cms_ddec.c @@ -1,5 +1,5 @@  /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -57,7 +57,7 @@ int main(int argc, char **argv)      /* Open file containing detached content */      dcont = BIO_new_file("smencr.out", "rb"); -    if (!in) +    if (dcont == NULL)          goto err;      out = BIO_new_file("encrout.txt", "w"); diff --git a/demos/cms/cms_denc.c b/demos/cms/cms_denc.c index 60b0aa192bc0..d48ffd00f06c 100644 --- a/demos/cms/cms_denc.c +++ b/demos/cms/cms_denc.c @@ -1,5 +1,5 @@  /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -57,7 +57,7 @@ int main(int argc, char **argv)      dout = BIO_new_file("smencr.out", "wb"); -    if (!in) +    if (in == NULL || dout == NULL)          goto err;      /* encrypt content */ diff --git a/demos/pkey/EVP_PKEY_RSA_keygen.c b/demos/pkey/EVP_PKEY_RSA_keygen.c index fbecfb6bdb0a..6f46efd24dad 100644 --- a/demos/pkey/EVP_PKEY_RSA_keygen.c +++ b/demos/pkey/EVP_PKEY_RSA_keygen.c @@ -1,5 +1,5 @@  /*- - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -254,7 +254,7 @@ int main(int argc, char **argv)      if (argc > 1) {          bits_i = atoi(argv[1]); -        if (bits < 512) { +        if (bits_i < 512) {              fprintf(stderr, "Invalid RSA key size\n");              return 1;          } diff --git a/doc/README.md b/doc/README.md index 12bb37ddb8fc..d999b0262b76 100644 --- a/doc/README.md +++ b/doc/README.md @@ -6,10 +6,6 @@ README.md  This file  [fingerprints.txt](fingerprints.txt)          PGP fingerprints of authorised release signers -standards.txt -standards.txt -        Moved to the web, <https://www.openssl.org/docs/standards.html> -  [HOWTO/](HOWTO/)          A few how-to documents; not necessarily up-to-date @@ -27,4 +23,4 @@ standards.txt          Algorithm specific EVP_PKEY documentation.  Formatted versions of the manpages (apps,ssl,crypto) can be found at -        <https://www.openssl.org/docs/manpages.html> +        <https://docs.openssl.org/master/> diff --git a/crypto/bn/README.pod b/doc/internal/man3/bn_mul_words.pod index 1286fc0d4132..d2d8e3397a14 100644 --- a/crypto/bn/README.pod +++ b/doc/internal/man3/bn_mul_words.pod @@ -8,7 +8,7 @@ bn_sqr_comba4, bn_sqr_comba8, bn_cmp_words, bn_mul_normal,  bn_mul_low_normal, bn_mul_recursive, bn_mul_part_recursive,  bn_mul_low_recursive, bn_sqr_normal, bn_sqr_recursive,  bn_expand, bn_wexpand, bn_expand2, bn_fix_top, bn_check_top, -bn_print, bn_dump, bn_set_max, bn_set_high, bn_set_low - BIGNUM +mul, mul_add, sqr - BIGNUM  library internal functions  =head1 SYNOPSIS @@ -45,21 +45,18 @@ library internal functions   void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp);   void bn_sqr_recursive(BN_ULONG *r, BN_ULONG *a, int n2, BN_ULONG *tmp); - void mul(BN_ULONG r, BN_ULONG a, BN_ULONG w, BN_ULONG c); - void mul_add(BN_ULONG r, BN_ULONG a, BN_ULONG w, BN_ULONG c); - void sqr(BN_ULONG r0, BN_ULONG r1, BN_ULONG a); -   BIGNUM *bn_expand(BIGNUM *a, int bits);   BIGNUM *bn_wexpand(BIGNUM *a, int n);   BIGNUM *bn_expand2(BIGNUM *a, int n);   void bn_fix_top(BIGNUM *a); +The following are macros: + + void mul(BN_ULONG r, BN_ULONG a, BN_ULONG w, BN_ULONG c); + void mul_add(BN_ULONG r, BN_ULONG a, BN_ULONG w, BN_ULONG c); + void sqr(BN_ULONG r0, BN_ULONG r1, BN_ULONG a); +   void bn_check_top(BIGNUM *a); - void bn_print(BIGNUM *a); - void bn_dump(BN_ULONG *d, int n); - void bn_set_max(BIGNUM *a); - void bn_set_high(BIGNUM *r, BIGNUM *a, int n); - void bn_set_low(BIGNUM *r, BIGNUM *a, int n);  =head1 DESCRIPTION @@ -208,30 +205,23 @@ call bn_expand2(), which allocates a new B<d> array and copies the  data.  They return B<NULL> on error, B<b> otherwise.  The bn_fix_top() macro reduces B<a-E<gt>top> to point to the most -significant non-zero word plus one when B<a> has shrunk. +significant nonzero word plus one when B<a> has shrunk.  =head2 Debugging  bn_check_top() verifies that C<((a)-E<gt>top E<gt>= 0 && (a)-E<gt>top  E<lt>= (a)-E<gt>dmax)>.  A violation will cause the program to abort. -bn_print() prints B<a> to stderr. bn_dump() prints B<n> words at B<d> -(in reverse order, i.e. most significant word first) to stderr. - -bn_set_max() makes B<a> a static number with a B<dmax> of its current size. -This is used by bn_set_low() and bn_set_high() to make B<r> a read-only -B<BIGNUM> that contains the B<n> low or high words of B<a>. - -If B<BN_DEBUG> is not defined, bn_check_top(), bn_print(), bn_dump() -and bn_set_max() are defined as empty macros. +If B<BN_DEBUG> is not defined, bn_check_top() is +defined as an empty macro. -=head1 SEE ALSO +=head1 RETURN VALUES -L<bn(3)> +Described above.  =head1 COPYRIGHT -Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man1/openssl-enc.pod.in b/doc/man1/openssl-enc.pod.in index a47e783e2d63..ad2d918c7a1a 100644 --- a/doc/man1/openssl-enc.pod.in +++ b/doc/man1/openssl-enc.pod.in @@ -180,9 +180,12 @@ Print out the key and IV used.  Print out the key and IV used then immediately exit: don't do any encryption  or decryption. -=item B<-bufsize> I<number> +=item B<-bufsize> I<number>[B<k>]  Set the buffer size for I/O. +The maximum size that can be specified is B<2^31-1> (2147483647) bytes. +The B<k> suffix can be specified to indicate that I<number> is provided +in kibibytes (multiples of 1024 bytes).  =item B<-nopad> @@ -251,7 +254,7 @@ Some of the ciphers do not have large keys and others have security  implications if not used correctly. A beginner is advised to just use  a strong block cipher, such as AES, in CBC mode. -All the block ciphers normally use PKCS#5 padding, also known as standard +All the block ciphers normally use PKCS#7 padding, also known as standard  block padding. This allows a rudimentary integrity or password check to  be performed. However, since the chance of random data passing the test  is better than 1 in 256 it isn't a very good test. @@ -458,7 +461,7 @@ The B<-ciphers> and B<-engine> options were deprecated in OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man1/openssl-s_client.pod.in b/doc/man1/openssl-s_client.pod.in index caebe10bffb8..29025ef1161b 100644 --- a/doc/man1/openssl-s_client.pod.in +++ b/doc/man1/openssl-s_client.pod.in @@ -499,12 +499,12 @@ by some servers.  =item B<-ign_eof>  Inhibit shutting down the connection when end of file is reached in the -input. +input. This implicitly turns on B<-nocommands> as well.  =item B<-quiet>  Inhibit printing of session and certificate information.  This implicitly -turns on B<-ign_eof> as well. +turns on B<-ign_eof> and B<-nocommands> as well.  =item B<-no_ign_eof> @@ -971,7 +971,7 @@ The B<-engine> option was deprecated in OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/BN_generate_prime.pod b/doc/man3/BN_generate_prime.pod index accc8a749f0c..6b8d1de19cd8 100644 --- a/doc/man3/BN_generate_prime.pod +++ b/doc/man3/BN_generate_prime.pod @@ -130,7 +130,7 @@ or all the tests passed.  If B<p> passes all these tests, it is considered a probable prime.  The test performed on B<p> are trial division by a number of small primes -and rounds of the of the Miller-Rabin probabilistic primality test. +and rounds of the Miller-Rabin probabilistic primality test.  The functions do at least 64 rounds of the Miller-Rabin test giving a maximum  false positive rate of 2^-128. @@ -148,7 +148,7 @@ and BN_is_prime_fasttest() are deprecated.  BN_is_prime_fasttest() and BN_is_prime() behave just like  BN_is_prime_fasttest_ex() and BN_is_prime_ex() respectively, but with the old -style call back. +style callback.  B<ctx> is a preallocated B<BN_CTX> (to save the overhead of allocating and  freeing the structure in a loop), or B<NULL>. @@ -246,7 +246,7 @@ BN_check_prime() was added in OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/CMS_sign.pod b/doc/man3/CMS_sign.pod index 03bfc6fce16a..9e28d6b7d3b5 100644 --- a/doc/man3/CMS_sign.pod +++ b/doc/man3/CMS_sign.pod @@ -96,7 +96,7 @@ can be performed by obtaining the streaming ASN1 B<BIO> directly using  BIO_new_CMS().  If a signer is specified it will use the default digest for the signing -algorithm. This is B<SHA1> for both RSA and DSA keys. +algorithm. This is B<SHA256> for both RSA and DSA keys.  If B<signcert> and B<pkey> are NULL then a certificates only CMS structure is  output. @@ -132,7 +132,7 @@ The CMS_sign_ex() method was added in OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2008-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/DTLS_set_timer_cb.pod b/doc/man3/DTLS_set_timer_cb.pod index 5014e77d0fc8..618fd1f6ff0e 100644 --- a/doc/man3/DTLS_set_timer_cb.pod +++ b/doc/man3/DTLS_set_timer_cb.pod @@ -20,6 +20,17 @@ This function sets an optional callback function for controlling the  timeout interval on the DTLS protocol. The callback function will be  called by DTLS for every new DTLS packet that is sent. +The callback should return the timeout interval in micro seconds. + +The I<timer_us> parameter of the callback is the last set timeout +interval returned. On the first invocation of the callback, +this value will be 0. + +At the beginning of the connection, if no timeout callback has been +set via DTLS_set_timer_cb(), the default timeout value is 1 second. +For all subsequent timeouts, the default behavior is to double the +duration up to a maximum of 1 minute. +  =head1 RETURN VALUES  Returns void. @@ -30,7 +41,7 @@ The DTLS_set_timer_cb() function was added in OpenSSL 1.1.1.  =head1 COPYRIGHT -Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/EVP_EncryptInit.pod b/doc/man3/EVP_EncryptInit.pod index a4635f994c2f..497e6cfe26da 100644 --- a/doc/man3/EVP_EncryptInit.pod +++ b/doc/man3/EVP_EncryptInit.pod @@ -744,7 +744,7 @@ See also EVP_CIPHER_CTX_get_key_length() and EVP_CIPHER_CTX_set_key_length().  =item "tag" (B<OSSL_CIPHER_PARAM_AEAD_TAG>) <octet string>  Gets or sets the AEAD tag for the associated cipher context I<ctx>. -See L<EVP_EncryptInit(3)/AEAD Interface>. +See L<EVP_EncryptInit(3)/AEAD INTERFACE>.  =item "keybits" (B<OSSL_CIPHER_PARAM_RC2_KEYBITS>) <unsigned integer> @@ -1746,7 +1746,7 @@ The EVP_CIPHER_CTX_flags() macro was deprecated in OpenSSL 1.1.0.  =head1 COPYRIGHT -Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/EVP_PKEY_CTX_new.pod b/doc/man3/EVP_PKEY_CTX_new.pod index d7ac221f7c19..a15abc2c3e17 100644 --- a/doc/man3/EVP_PKEY_CTX_new.pod +++ b/doc/man3/EVP_PKEY_CTX_new.pod @@ -49,8 +49,11 @@ used when no B<EVP_PKEY> structure is associated with the operations,  for example during parameter generation or key generation for some  algorithms. -EVP_PKEY_CTX_dup() duplicates the context I<ctx>. It is not supported for a -keygen operation. +EVP_PKEY_CTX_dup() duplicates the context I<ctx>. +It is not supported for a keygen operation. +It is however possible to duplicate a context freshly created via any of the +above C<new> functions, provided L<EVP_PKEY_keygen_init(3)> has not yet been +called on the source context, and then use the copy for key generation.  EVP_PKEY_CTX_free() frees up the context I<ctx>.  If I<ctx> is NULL, nothing is done. @@ -122,7 +125,7 @@ added in OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/EVP_PKEY_new.pod b/doc/man3/EVP_PKEY_new.pod index 1c75c7571994..1815f56f743e 100644 --- a/doc/man3/EVP_PKEY_new.pod +++ b/doc/man3/EVP_PKEY_new.pod @@ -168,7 +168,19 @@ general private key without reference to any particular algorithm.  The structure returned by EVP_PKEY_new() is empty. To add a private or public  key to this empty structure use the appropriate functions described in  L<EVP_PKEY_set1_RSA(3)>, L<EVP_PKEY_set1_DSA(3)>, L<EVP_PKEY_set1_DH(3)> or -L<EVP_PKEY_set1_EC_KEY(3)>. +L<EVP_PKEY_set1_EC_KEY(3)> for legacy key types implemented in internal +OpenSSL providers. + +For fully provider-managed key types (see L<provider-keymgmt(7)>), +possibly implemented in external providers, use functions such as +L<EVP_PKEY_set1_encoded_public_key(3)> or L<EVP_PKEY_fromdata(3)> +to populate key data. + +Generally caution is advised for using an B<EVP_PKEY> structure across +different library contexts: In order for an B<EVP_PKEY> to be shared by +multiple library contexts the providers associated with the library contexts +must have key managers that support the key type and implement the +OSSL_FUNC_keymgmt_import() and OSSL_FUNC_keymgmt_export() functions.  =head1 RETURN VALUES @@ -210,7 +222,7 @@ previously implied to be disallowed.  =head1 COPYRIGHT -Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2002-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/EVP_RAND.pod b/doc/man3/EVP_RAND.pod index e5f75010499c..667599273cdc 100644 --- a/doc/man3/EVP_RAND.pod +++ b/doc/man3/EVP_RAND.pod @@ -151,11 +151,8 @@ operating system.  If I<prediction_resistance> is specified, fresh entropy  from a live source will be sought.  This call operates as per NIST SP 800-90A  and SP 800-90C. -EVP_RAND_nonce() creates a nonce in I<out> of maximum length I<outlen> -bytes from the RAND I<ctx>. The function returns the length of the generated -nonce. If I<out> is NULL, the length is still returned but no generation -takes place. This allows a caller to dynamically allocate a buffer of the -appropriate size. +EVP_RAND_nonce() creates a nonce in I<out> of length I<outlen> +bytes from the RAND I<ctx>.  EVP_RAND_enable_locking() enables locking for the RAND I<ctx> and all of  its parents.  After this I<ctx> will operate in a thread safe manner, albeit @@ -376,7 +373,7 @@ B<EVP_RAND_CTX> structure or NULL if an error occurred.  EVP_RAND_CTX_free() does not return a value. -EVP_RAND_nonce() returns the length of the nonce. +EVP_RAND_nonce() returns 1 on success, 0 on error.  EVP_RAND_get_strength() returns the strength of the random number generator  in bits. @@ -406,7 +403,7 @@ This functionality was added to OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/EVP_aes_128_gcm.pod b/doc/man3/EVP_aes_128_gcm.pod index 485705ea7889..9bac62b10b32 100644 --- a/doc/man3/EVP_aes_128_gcm.pod +++ b/doc/man3/EVP_aes_128_gcm.pod @@ -127,7 +127,7 @@ EVP_aes_256_ocb()  AES for 128, 192 and 256 bit keys in CBC-MAC Mode (CCM), Galois Counter Mode  (GCM) and OCB Mode respectively. These ciphers require additional control -operations to function correctly, see the L<EVP_EncryptInit(3)/AEAD Interface> +operations to function correctly, see the L<EVP_EncryptInit(3)/AEAD INTERFACE>  section for details.  =item EVP_aes_128_wrap(), @@ -184,7 +184,7 @@ L<EVP_CIPHER_meth_new(3)>  =head1 COPYRIGHT -Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/EVP_aria_128_gcm.pod b/doc/man3/EVP_aria_128_gcm.pod index 91aa75ec3871..74e21444db8f 100644 --- a/doc/man3/EVP_aria_128_gcm.pod +++ b/doc/man3/EVP_aria_128_gcm.pod @@ -88,7 +88,7 @@ EVP_aria_256_gcm(),  ARIA for 128, 192 and 256 bit keys in CBC-MAC Mode (CCM) and Galois Counter  Mode (GCM). These ciphers require additional control operations to function -correctly, see the L<EVP_EncryptInit(3)/AEAD Interface> section for details. +correctly, see the L<EVP_EncryptInit(3)/AEAD INTERFACE> section for details.  =back @@ -113,7 +113,7 @@ L<EVP_CIPHER_meth_new(3)>  =head1 COPYRIGHT -Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/EVP_chacha20.pod b/doc/man3/EVP_chacha20.pod index 7e80c8de40c9..0dfce7389b78 100644 --- a/doc/man3/EVP_chacha20.pod +++ b/doc/man3/EVP_chacha20.pod @@ -36,7 +36,7 @@ With an initial counter of 42 (2a in hex) would be expressed as:  Authenticated encryption with ChaCha20-Poly1305. Like EVP_chacha20(), the key  is 256 bits and the IV is 96 bits. This supports additional authenticated data  (AAD) and produces a 128-bit authentication tag. See the -L<EVP_EncryptInit(3)/AEAD Interface> section for more information. +L<EVP_EncryptInit(3)/AEAD INTERFACE> section for more information.  =back @@ -64,7 +64,7 @@ L<EVP_CIPHER_meth_new(3)>  =head1 COPYRIGHT -Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/OPENSSL_secure_malloc.pod b/doc/man3/OPENSSL_secure_malloc.pod index 1bddd7737069..dbc7073aac18 100644 --- a/doc/man3/OPENSSL_secure_malloc.pod +++ b/doc/man3/OPENSSL_secure_malloc.pod @@ -45,7 +45,12 @@ the program's dynamic memory area, where keys and other sensitive  information might be stored, OpenSSL supports the concept of a "secure heap."  The level and type of security guarantees depend on the operating system.  It is a good idea to review the code and see if it addresses your -threat model and concerns. +threat model and concerns. It should be noted that the secure heap +uses a single read/write lock, and therefore any operations +that involve allocation or freeing of secure heap memory are serialised, +blocking other threads. With that in mind, highly concurrent applications +should enable the secure heap with caution and be aware of the performance +implications for multi-threaded code.  If a secure heap is used, then private key B<BIGNUM> values are stored there.  This protects long-term storage of private keys, but will not necessarily @@ -135,7 +140,7 @@ a B<size_t> in OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2015-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/OSSL_PARAM.pod b/doc/man3/OSSL_PARAM.pod index 22fd0f0d7dd7..8a50db2b94d4 100644 --- a/doc/man3/OSSL_PARAM.pod +++ b/doc/man3/OSSL_PARAM.pod @@ -356,7 +356,7 @@ could fill in the parameters like this:  =head1 SEE ALSO -L<openssl-core.h(7)>, L<OSSL_PARAM_get_int(3)>, L<OSSL_PARAM_dup(3)> +L<openssl-core.h(7)>, L<OSSL_PARAM_get_int(3)>, L<OSSL_PARAM_dup(3)>, L<OSSL_PARAM_construct_utf8_string(3)>  =head1 HISTORY @@ -364,7 +364,7 @@ B<OSSL_PARAM> was added in OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/OSSL_PARAM_int.pod b/doc/man3/OSSL_PARAM_int.pod index 105fe3241f87..aaecd0a87ce9 100644 --- a/doc/man3/OSSL_PARAM_int.pod +++ b/doc/man3/OSSL_PARAM_int.pod @@ -393,6 +393,29 @@ could fill in the parameters like this:      if ((p = OSSL_PARAM_locate(params, "cookie")) != NULL)          OSSL_PARAM_set_utf8_ptr(p, "cookie value"); +=head2 Example 3 + +This example shows a special case where +I<-Wincompatible-pointer-types-discards-qualifiers> may be set during +compilation. The value for I<buf> cannot be a I<const char *> type string. An +alternative in this case would be to use B<OSSL_PARAM> macro abbreviated calls +rather than the specific callers which allows you to define the sha1 argument +as a standard character array (I<char[]>). + +For example, this code: + +    OSSL_PARAM params[2]; +    params[0] = OSSL_PARAM_construct_utf8_string("digest", "SHA1", 0); +    params[1] = OSSL_PARAM_construct_end(); + +Can be made compatible with the following version: + +    char sha1[] = "SHA1"; /* sha1 is defined as char[] in this case */ +    OSSL_PARAM params[2]; + +    params[0] = OSSL_PARAM_construct_utf8_string("digest", sha1, 0); +    params[1] = OSSL_PARAM_construct_end(); +  =head1 SEE ALSO  L<openssl-core.h(7)>, L<OSSL_PARAM(3)> @@ -403,7 +426,7 @@ These APIs were introduced in OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/OpenSSL_version.pod b/doc/man3/OpenSSL_version.pod index e1cf16e2a109..2cc6c3dfebb9 100644 --- a/doc/man3/OpenSSL_version.pod +++ b/doc/man3/OpenSSL_version.pod @@ -238,9 +238,16 @@ L<crypto(7)>  The macros and functions described here were added in OpenSSL 3.0,  except for OPENSSL_VERSION_NUMBER and OpenSSL_version_num(). +=head1 BUGS + +There was a discrepancy between this manual and commentary + code +in F<< <openssl/opensslv.h> >>, where the latter suggested that the +four least significant bits of B<OPENSSL_VERSION_NUMBER> could be +C<0x0f> in released OpenSSL versions. +  =head1 COPYRIGHT -Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/PEM_read_CMS.pod b/doc/man3/PEM_read_CMS.pod index dbccf26cd893..880e31481029 100644 --- a/doc/man3/PEM_read_CMS.pod +++ b/doc/man3/PEM_read_CMS.pod @@ -84,9 +84,9 @@ see L<openssl_user_macros(7)>:  =head1 DESCRIPTION -All of the functions described on this page are deprecated. -Applications should use OSSL_ENCODER_to_bio() and OSSL_DECODER_from_bio() -instead. +To replace the deprecated functions listed above, applications should use the +B<EVP_PKEY> type and OSSL_DECODER_from_bio() and OSSL_ENCODER_to_bio() to +read and write PEM data containing key parameters or private and public keys.  In the description below, B<I<TYPE>> is used  as a placeholder for any of the OpenSSL datatypes, such as B<X509>. @@ -142,7 +142,7 @@ were deprecated in OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 1998-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/PKCS7_sign.pod b/doc/man3/PKCS7_sign.pod index 1d997045fe14..5c55aa191def 100644 --- a/doc/man3/PKCS7_sign.pod +++ b/doc/man3/PKCS7_sign.pod @@ -80,7 +80,7 @@ can be performed by obtaining the streaming ASN1 B<BIO> directly using  BIO_new_PKCS7().  If a signer is specified it will use the default digest for the signing -algorithm. This is B<SHA1> for both RSA and DSA keys. +algorithm. This is B<SHA256> for both RSA and DSA keys.  The I<certs>, I<signcert> and I<pkey> parameters can all be  NULL if the B<PKCS7_PARTIAL> flag is set. One or more signers can be added @@ -122,7 +122,7 @@ The B<PKCS7_STREAM> flag was added in OpenSSL 1.0.0.  =head1 COPYRIGHT -Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2002-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/RAND_load_file.pod b/doc/man3/RAND_load_file.pod index baca54cb3c89..45570920ca95 100644 --- a/doc/man3/RAND_load_file.pod +++ b/doc/man3/RAND_load_file.pod @@ -19,7 +19,11 @@ RAND_load_file, RAND_write_file, RAND_file_name - PRNG seed file  RAND_load_file() reads a number of bytes from file B<filename> and  adds them to the PRNG. If B<max_bytes> is nonnegative,  up to B<max_bytes> are read; -if B<max_bytes> is -1, the complete file is read. +if B<max_bytes> is -1, the complete file is read (unless the file +is not a regular file, in that case a fixed number of bytes, +256 in the current implementation, is attempted to be read). +RAND_load_file() can read less than the complete file or the requested number +of bytes if it doesn't fit in the return value type.  Do not load the same file multiple times unless its contents have  been updated by RAND_write_file() between reads.  Also, note that B<filename> should be adequately protected so that an @@ -77,7 +81,7 @@ L<RAND(7)>  =head1 COPYRIGHT -Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/SSL_CIPHER_get_name.pod b/doc/man3/SSL_CIPHER_get_name.pod index 09b7280bdd58..a10942433aa7 100644 --- a/doc/man3/SSL_CIPHER_get_name.pod +++ b/doc/man3/SSL_CIPHER_get_name.pod @@ -37,7 +37,7 @@ SSL_CIPHER_get_protocol_id   int SSL_CIPHER_is_aead(const SSL_CIPHER *c);   const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr);   uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *c); - uint32_t SSL_CIPHER_get_protocol_id(const SSL_CIPHER *c); + uint16_t SSL_CIPHER_get_protocol_id(const SSL_CIPHER *c);  =head1 DESCRIPTION @@ -203,7 +203,7 @@ The OPENSSL_cipher_name() function was added in OpenSSL 1.1.1.  =head1 COPYRIGHT -Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/SSL_CONF_cmd.pod b/doc/man3/SSL_CONF_cmd.pod index ae6ca432829e..0645c75d9878 100644 --- a/doc/man3/SSL_CONF_cmd.pod +++ b/doc/man3/SSL_CONF_cmd.pod @@ -71,7 +71,7 @@ B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION>.  =item B<-no_renegotiation> -Disables all attempts at renegotiation in TLSv1.2 and earlier, same as setting +Disables all attempts at renegotiation in (D)TLSv1.2 and earlier, same as setting  B<SSL_OP_NO_RENEGOTIATION>.  =item B<-no_resumption_on_reneg> @@ -735,7 +735,7 @@ OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2012-2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2012-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/SSL_CTX_set_min_proto_version.pod b/doc/man3/SSL_CTX_set_min_proto_version.pod index 2adf9acce00a..a4a49d8549e6 100644 --- a/doc/man3/SSL_CTX_set_min_proto_version.pod +++ b/doc/man3/SSL_CTX_set_min_proto_version.pod @@ -31,9 +31,10 @@ L<SSL_CTX_set_options(3)> that also make it possible to disable  specific protocol versions.  Use these functions instead of disabling specific protocol versions. -Setting the minimum or maximum version to 0, will enable protocol +Setting the minimum or maximum version to 0 (default), will enable protocol  versions down to the lowest version, or up to the highest version -supported by the library, respectively. +supported by the library, respectively. The supported versions might be +controlled by system configuration.  Getters return 0 in case B<ctx> or B<ssl> have been configured to  automatically use the lowest or highest version supported by the library. @@ -64,7 +65,7 @@ were added in OpenSSL 1.1.1.  =head1 COPYRIGHT -Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/SSL_CTX_set_options.pod b/doc/man3/SSL_CTX_set_options.pod index 176f8d25fc31..93e7198166f7 100644 --- a/doc/man3/SSL_CTX_set_options.pod +++ b/doc/man3/SSL_CTX_set_options.pod @@ -241,7 +241,7 @@ Do not query the MTU. Only affects DTLS connections.  =item SSL_OP_NO_RENEGOTIATION -Disable all renegotiation in TLSv1.2 and earlier. Do not send HelloRequest +Disable all renegotiation in (D)TLSv1.2 and earlier. Do not send HelloRequest  messages, and ignore renegotiation requests via ClientHello.  =item SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION @@ -456,7 +456,7 @@ whether these macros are defined or not.  =head1 COPYRIGHT -Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/SSL_CTX_set_tmp_dh_callback.pod b/doc/man3/SSL_CTX_set_tmp_dh_callback.pod index 4799ada6844b..902cefdfa366 100644 --- a/doc/man3/SSL_CTX_set_tmp_dh_callback.pod +++ b/doc/man3/SSL_CTX_set_tmp_dh_callback.pod @@ -58,9 +58,11 @@ the actual key is newly generated during the negotiation.  Typically applications should use well known DH parameters that have built-in  support in OpenSSL. The macros SSL_CTX_set_dh_auto() and SSL_set_dh_auto()  configure OpenSSL to use the default built-in DH parameters for the B<SSL_CTX> -and B<SSL> objects respectively. Passing a value of 1 in the I<onoff> parameter -switches the feature on, and passing a value of 0 switches it off. The default -setting is off. +and B<SSL> objects respectively. Passing a value of 2 or 1 in the I<onoff> +parameter switches it on. If the I<onoff> parameter is set to 2, it will force +the DH key size to 1024 if the B<SSL_CTX> or B<SSL> security level +L<SSL_CTX_set_security_level(3)> is 0 or 1. Passing a value of 0 switches +it off. The default setting is off.  If "auto" DH parameters are switched on then the parameters will be selected to  be consistent with the size of the key associated with the server's certificate. @@ -112,7 +114,7 @@ L<openssl-ciphers(1)>, L<openssl-dhparam(1)>  =head1 COPYRIGHT -Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/SSL_SESSION_get0_hostname.pod b/doc/man3/SSL_SESSION_get0_hostname.pod index f560e7751d84..0140deee9a5e 100644 --- a/doc/man3/SSL_SESSION_get0_hostname.pod +++ b/doc/man3/SSL_SESSION_get0_hostname.pod @@ -23,11 +23,10 @@ SSL_SESSION_set1_alpn_selected  =head1 DESCRIPTION -SSL_SESSION_get0_hostname() retrieves the SNI value that was sent by the -client when the session was created if it was accepted by the server and TLSv1.2 -or below was negotiated. Otherwise NULL is returned. Note that in TLSv1.3 the -SNI hostname is negotiated with each handshake including resumption handshakes -and is therefore never associated with the session. +SSL_SESSION_get0_hostname() retrieves the Server Name Indication (SNI) value +that was sent by the client when the session was created if the server +acknowledged the client's SNI extension by including an empty SNI extension +in response. Otherwise NULL is returned.  The value returned is a pointer to memory maintained within B<s> and  should not be free'd. @@ -46,8 +45,7 @@ B<alpn>.  =head1 RETURN VALUES -SSL_SESSION_get0_hostname() returns either a string or NULL based on if there -is the SNI value sent by client. +SSL_SESSION_get0_hostname() returns the SNI string if available, or NULL if not.  SSL_SESSION_set1_hostname() returns 1 on success or 0 on error. @@ -67,7 +65,7 @@ SSL_SESSION_set1_alpn_selected() functions were added in OpenSSL 1.1.1.  =head1 COPYRIGHT -Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/SSL_key_update.pod b/doc/man3/SSL_key_update.pod index 6d5b42e0b166..5ce47b337387 100644 --- a/doc/man3/SSL_key_update.pod +++ b/doc/man3/SSL_key_update.pod @@ -53,7 +53,9 @@ such as SSL_read_ex() or SSL_write_ex() takes place on the connection a check  will be performed to confirm that it is a suitable time to start a  renegotiation. If so, then it will be initiated immediately. OpenSSL will not  attempt to resume any session associated with the connection in the new -handshake. +handshake. Note that some servers will respond to reneogitation attempts with +a "no_renegotiation" alert. An OpenSSL will immediately fail the connection in +this case.  When called from the client side, SSL_renegotiate_abbreviated() works in the  same was as SSL_renegotiate() except that OpenSSL will attempt to resume the @@ -101,7 +103,7 @@ OpenSSL 1.1.1.  =head1 COPYRIGHT -Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/X509_VERIFY_PARAM_set_flags.pod b/doc/man3/X509_VERIFY_PARAM_set_flags.pod index 4627206174a5..b06bedc2e7bc 100644 --- a/doc/man3/X509_VERIFY_PARAM_set_flags.pod +++ b/doc/man3/X509_VERIFY_PARAM_set_flags.pod @@ -248,8 +248,8 @@ ored together.  B<X509_V_FLAG_CRL_CHECK> enables CRL checking for the certificate chain leaf  certificate. An error occurs if a suitable CRL cannot be found. -B<X509_V_FLAG_CRL_CHECK_ALL> enables CRL checking for the entire certificate -chain. +B<X509_V_FLAG_CRL_CHECK_ALL> expands CRL checking to the entire certificate +chain if B<X509_V_FLAG_CRL_CHECK> has also been enabled, and is otherwise ignored.  B<X509_V_FLAG_IGNORE_CRITICAL> disables critical extension checking. By default  any unhandled critical extensions in certificates or (if checked) CRLs result @@ -407,7 +407,7 @@ The documentation was changed to align with the implementation.  =head1 COPYRIGHT -Copyright 2009-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2009-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man3/d2i_X509.pod b/doc/man3/d2i_X509.pod index c4b589dd8957..2d21b799a100 100644 --- a/doc/man3/d2i_X509.pod +++ b/doc/man3/d2i_X509.pod @@ -500,8 +500,9 @@ freed in the event of error and I<*a> is set to NULL.  B<i2d_I<TYPE>>() returns the number of bytes successfully encoded or a negative  value if an error occurs. -B<i2d_I<TYPE>_bio>() and B<i2d_I<TYPE>_fp>() return 1 for success and 0 if an -error occurs. +B<i2d_I<TYPE>_bio>() and B<i2d_I<TYPE>_fp>(), +as well as i2d_ASN1_bio_stream(), +return 1 for success and 0 if an error occurs.  =head1 EXAMPLES @@ -617,7 +618,7 @@ efficiency reasons.  =head1 COPYRIGHT -Copyright 1998-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 1998-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man7/EVP_PKEY-DSA.pod b/doc/man7/EVP_PKEY-DSA.pod index cdafc0edad5c..54619553f927 100644 --- a/doc/man7/EVP_PKEY-DSA.pod +++ b/doc/man7/EVP_PKEY-DSA.pod @@ -104,7 +104,7 @@ The following sections of FIPS186-4:  =head1 SEE ALSO  L<EVP_PKEY-FFC(7)>, -L<EVP_SIGNATURE-DSA(7)> +L<EVP_SIGNATURE-DSA(7)>,  L<EVP_PKEY(3)>,  L<provider-keymgmt(7)>,  L<EVP_KEYMGMT(3)>, @@ -113,7 +113,7 @@ L<OSSL_PROVIDER-FIPS(7)>  =head1 COPYRIGHT -Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man7/EVP_PKEY-FFC.pod b/doc/man7/EVP_PKEY-FFC.pod index 0b96bc24a614..a28bb84e0a36 100644 --- a/doc/man7/EVP_PKEY-FFC.pod +++ b/doc/man7/EVP_PKEY-FFC.pod @@ -213,7 +213,7 @@ The following sections of FIPS186-4:  L<EVP_PKEY-DSA(7)>,  L<EVP_PKEY-DH(7)>,  L<EVP_SIGNATURE-DSA(7)>, -L<EVP_KEYEXCH-DH(7)> +L<EVP_KEYEXCH-DH(7)>,  L<EVP_KEYMGMT(3)>,  L<EVP_PKEY(3)>,  L<provider-keymgmt(7)>, @@ -222,7 +222,7 @@ L<OSSL_PROVIDER-FIPS(7)>,  =head1 COPYRIGHT -Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man7/OSSL_PROVIDER-FIPS.pod b/doc/man7/OSSL_PROVIDER-FIPS.pod index 66165bdb0cc3..eb34a34a152c 100644 --- a/doc/man7/OSSL_PROVIDER-FIPS.pod +++ b/doc/man7/OSSL_PROVIDER-FIPS.pod @@ -421,6 +421,19 @@ validated versions alongside F<libcrypto> and F<libssl> compiled from any  release within the same major release series.  This flexibility enables  you to address bug fixes and CVEs that fall outside the FIPS boundary. +You can load the FIPS provider into multiple library contexts as any other +provider. However the following restriction applies. The FIPS provider cannot +be used by multiple copies of OpenSSL libcrypto in a single process. + +As the provider saves core callbacks to the libcrypto obtained in the +OSSL_provider_init() call to global data it will fail if subsequent +invocations of its OSSL_provider_init() function yield different addresses +of these callbacks than in the initial call. This happens when different +copies of libcrypto are present in the memory of the process and both try +to load the same FIPS provider. A workaround is to have a different copy +of the FIPS provider loaded for each of the libcrypto instances in the +process. +  =head1 SEE ALSO  L<openssl-fipsinstall(1)>, @@ -439,7 +452,7 @@ This functionality was added in OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man7/migration_guide.pod b/doc/man7/migration_guide.pod index e5ab29b95370..b223f856d17d 100644 --- a/doc/man7/migration_guide.pod +++ b/doc/man7/migration_guide.pod @@ -596,13 +596,13 @@ The code needs to be amended to look like this:  Support for TLSv1.3 has been added.  This has a number of implications for SSL/TLS applications. See the -L<TLS1.3 page|https://wiki.openssl.org/index.php/TLS1.3> for further details. +L<TLS1.3 page|https://github.com/openssl/openssl/wiki/TLS1.3> for further details.  =back  More details about the breaking changes between OpenSSL versions 1.0.2 and 1.1.0  can be found on the -L<OpenSSL 1.1.0 Changes page|https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes>. +L<OpenSSL 1.1.0 Changes page|https://github.com/openssl/openssl/wiki/OpenSSL_1.1.0_Changes>.  =head3 Upgrading from the OpenSSL 2.0 FIPS Object Module @@ -2484,7 +2484,7 @@ The migration guide was created for OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man7/provider-cipher.pod b/doc/man7/provider-cipher.pod index eaad3cf2ff02..c5d40a223acf 100644 --- a/doc/man7/provider-cipher.pod +++ b/doc/man7/provider-cipher.pod @@ -103,8 +103,8 @@ A cipher algorithm implementation may not implement all of these functions.  In order to be a consistent set of functions there must at least be a complete  set of "encrypt" functions, or a complete set of "decrypt" functions, or a  single "cipher" function. -In all cases both the OSSL_FUNC_cipher_newctx and OSSL_FUNC_cipher_freectx functions must be -present. +In all cases the OSSL_FUNC_cipher_get_params and both OSSL_FUNC_cipher_newctx +and OSSL_FUNC_cipher_freectx functions must be present.  All other functions are optional.  =head2 Context Management Functions @@ -241,7 +241,7 @@ The provider CIPHER interface was introduced in OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man7/provider-decoder.pod b/doc/man7/provider-decoder.pod index e968e661f7cf..d19deec4af5b 100644 --- a/doc/man7/provider-decoder.pod +++ b/doc/man7/provider-decoder.pod @@ -110,7 +110,9 @@ it decodes. For example, an implementation that decodes an RSA key  should be named "RSA". Likewise, an implementation that decodes DER data  from PEM input should be named "DER". -Properties can be used to further specify details about an implementation: +Properties, as defined in the L<OSSL_ALGORITHM(3)> array element of each +decoder implementation, can be used to further specify details about an +implementation:  =over 4 @@ -302,7 +304,7 @@ The DECODER interface was introduced in OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man7/provider-encoder.pod b/doc/man7/provider-encoder.pod index f3e9ce5b1632..dadd33f9b0f6 100644 --- a/doc/man7/provider-encoder.pod +++ b/doc/man7/provider-encoder.pod @@ -127,7 +127,9 @@ The name of an implementation should match the type of object it handles.  For example, an implementation that encodes an RSA key should be named "RSA".  Likewise, an implementation that further encodes DER should be named "DER". -Properties can be used to further specify details about an implementation: +Properties, as defined in the L<OSSL_ALGORITHM(3)> array element of each +decoder implementation, can be used to further specify details about an +implementation:  =over 4 @@ -321,7 +323,7 @@ The ENCODER interface was introduced in OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man7/provider-keymgmt.pod b/doc/man7/provider-keymgmt.pod index 498ad9c4e107..8596b696c69f 100644 --- a/doc/man7/provider-keymgmt.pod +++ b/doc/man7/provider-keymgmt.pod @@ -29,7 +29,7 @@ provider-keymgmt - The KEYMGMT library E<lt>-E<gt> provider functions   void OSSL_FUNC_keymgmt_gen_cleanup(void *genctx);   /* Key loading by object reference, also a constructor */ - void *OSSL_FUNC_keymgmt_load(const void *reference, size_t *reference_sz); + void *OSSL_FUNC_keymgmt_load(const void *reference, size_t reference_sz);   /* Key object information */   int OSSL_FUNC_keymgmt_get_params(void *keydata, OSSL_PARAM params[]); @@ -442,7 +442,7 @@ The KEYMGMT interface was introduced in OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy diff --git a/doc/man7/provider-signature.pod b/doc/man7/provider-signature.pod index 1a9859eac367..05040ee39914 100644 --- a/doc/man7/provider-signature.pod +++ b/doc/man7/provider-signature.pod @@ -284,7 +284,7 @@ should be written to I<*siglen>. If I<sig> is NULL then the maximum length of  the signature should be written to I<*siglen>.  OSSL_FUNC_signature_digest_sign() implements a "one shot" digest sign operation -previously started through OSSL_FUNC_signature_digeset_sign_init(). A previously +previously started through OSSL_FUNC_signature_digest_sign_init(). A previously  initialised signature context is passed in the I<ctx> parameter. The data to be  signed is in I<tbs> which should be I<tbslen> bytes long. Unless I<sig> is NULL,  the signature should be written to the location pointed to by the I<sig> @@ -294,7 +294,7 @@ length of the signature should be written to I<*siglen>.  =head2 Digest Verify Functions -OSSL_FUNC_signature_digeset_verify_init() initialises a context for verifying given a +OSSL_FUNC_signature_digest_verify_init() initialises a context for verifying given a  provider side verification context in the I<ctx> parameter, and a pointer to a  provider key object in the I<provkey> parameter.  The I<params>, if not NULL, should be set on the context in a manner similar to @@ -318,7 +318,7 @@ verification context is passed in the I<ctx> parameter. The signature to be  verified is in I<sig> which is I<siglen> bytes long.  OSSL_FUNC_signature_digest_verify() implements a "one shot" digest verify operation -previously started through OSSL_FUNC_signature_digeset_verify_init(). A previously +previously started through OSSL_FUNC_signature_digest_verify_init(). A previously  initialised verification context is passed in the I<ctx> parameter. The data to be  verified is in I<tbs> which should be I<tbslen> bytes long. The signature to be  verified is in I<sig> which is I<siglen> bytes long. @@ -360,8 +360,13 @@ The length of the "digest-size" parameter should not exceed that of a B<size_t>.  =item "algorithm-id" (B<OSSL_SIGNATURE_PARAM_ALGORITHM_ID>) <octet string> -Gets the DER encoded AlgorithmIdentifier that corresponds to the combination of -signature algorithm and digest algorithm for the signature operation. +Gets the DER-encoded AlgorithmIdentifier for the signature operation. +This typically corresponds to the combination of a digest algorithm +with a purely asymmetric signature algorithm, such as SHA256WithECDSA. + +The L<ASN1_item_sign_ctx(3)> relies on this operation and is used by +many other functions signing ASN.1 structures such as X.509 certificates, +certificate requests, and CRLs, as well as OCSP, CMP, and CMS messages.  =item "kat" (B<OSSL_SIGNATURE_PARAM_KAT>) <unsigned integer> @@ -421,7 +426,8 @@ All other functions should return 1 for success or 0 on error.  =head1 SEE ALSO -L<provider(7)> +L<provider(7)>, +L<ASN1_item_sign_ctx(3)>  =head1 HISTORY @@ -429,7 +435,7 @@ The provider SIGNATURE interface was introduced in OpenSSL 3.0.  =head1 COPYRIGHT -Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.  Licensed under the Apache License 2.0 (the "License").  You may not use  this file except in compliance with the License.  You can obtain a copy @@ -1,5 +1,5 @@  /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -126,17 +126,6 @@  #    define EACCES   13  #   endif  #   include <string.h> -#   ifdef _WIN64 -#    define strlen(s) _strlen31(s) -/* cut strings to 2GB */ -static __inline unsigned int _strlen31(const char *str) -{ -    unsigned int len = 0; -    while (*str && len < 0x80000000U) -        str++, len++; -    return len & 0x7FFFFFFF; -} -#   endif  #   include <malloc.h>  #   if defined(_MSC_VER) && !defined(_WIN32_WCE) && !defined(_DLL) && defined(stdin)  #    if _MSC_VER>=1300 && _MSC_VER<1600 diff --git a/fuzz/x509.c b/fuzz/x509.c index e2d2639164c0..b1e12cf901ca 100644 --- a/fuzz/x509.c +++ b/fuzz/x509.c @@ -1,5 +1,5 @@  /* - * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License");   * you may not use this file except in compliance with the License. @@ -78,9 +78,13 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len)      resp = d2i_OCSP_RESPONSE(NULL, &p, len);      store = X509_STORE_new(); +    if (store == NULL) +        goto err;      X509_STORE_add_cert(store, x509_2);      param = X509_VERIFY_PARAM_new(); +    if (param == NULL) +        goto err;      X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_NO_CHECK_TIME);      X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_X509_STRICT);      X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_PARTIAL_CHAIN); diff --git a/include/internal/constant_time.h b/include/internal/constant_time.h index 2b49afe1ea2a..3583344b4d86 100644 --- a/include/internal/constant_time.h +++ b/include/internal/constant_time.h @@ -1,5 +1,5 @@  /* - * Copyright 2014-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -296,6 +296,18 @@ static ossl_inline size_t value_barrier_s(size_t a)      return r;  } +/* Convenience method for unsigned char. */ +static ossl_inline unsigned char value_barrier_8(unsigned char a) +{ +#if !defined(OPENSSL_NO_ASM) && defined(__GNUC__) +    unsigned char r; +    __asm__("" : "=r"(r) : "0"(a)); +#else +    volatile unsigned char r = a; +#endif +    return r; +} +  static ossl_inline unsigned int constant_time_select(unsigned int mask,                                                       unsigned int a,                                                       unsigned int b) @@ -356,7 +368,7 @@ static ossl_inline void constant_time_cond_swap_32(uint32_t mask, uint32_t *a,  {      uint32_t xor = *a ^ *b; -    xor &= mask; +    xor &= value_barrier_32(mask);      *a ^= xor;      *b ^= xor;  } @@ -376,7 +388,7 @@ static ossl_inline void constant_time_cond_swap_64(uint64_t mask, uint64_t *a,  {      uint64_t xor = *a ^ *b; -    xor &= mask; +    xor &= value_barrier_64(mask);      *a ^= xor;      *b ^= xor;  } @@ -403,7 +415,7 @@ static ossl_inline void constant_time_cond_swap_buff(unsigned char mask,      for (i = 0; i < len; i++) {          tmp = a[i] ^ b[i]; -        tmp &= mask; +        tmp &= value_barrier_8(mask);          a[i] ^= tmp;          b[i] ^= tmp;      } diff --git a/include/openssl/opensslv.h.in b/include/openssl/opensslv.h.in index 3f47a2ac08f0..69b9caacf4dc 100644 --- a/include/openssl/opensslv.h.in +++ b/include/openssl/opensslv.h.in @@ -1,7 +1,7 @@  /*   * {- join("\n * ", @autowarntext) -}   * - * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -89,17 +89,12 @@ extern "C" {  # define OPENSSL_VERSION_TEXT "OpenSSL {- "$config{full_version} $config{release_date}" -}" -/* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */ -# ifdef OPENSSL_VERSION_PRE_RELEASE -#  define _OPENSSL_VERSION_PRE_RELEASE 0x0L -# else -#  define _OPENSSL_VERSION_PRE_RELEASE 0xfL -# endif +/* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PP0L */  # define OPENSSL_VERSION_NUMBER          \      ( (OPENSSL_VERSION_MAJOR<<28)        \        |(OPENSSL_VERSION_MINOR<<20)       \        |(OPENSSL_VERSION_PATCH<<4)        \ -      |_OPENSSL_VERSION_PRE_RELEASE ) +      |0x0L )  # ifdef  __cplusplus  } diff --git a/include/openssl/pem.h b/include/openssl/pem.h index 80940dfa969b..2909ca979a4e 100644 --- a/include/openssl/pem.h +++ b/include/openssl/pem.h @@ -1,5 +1,5 @@  /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -54,6 +54,8 @@ extern "C" {  # define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"  # define PEM_STRING_PARAMETERS   "PARAMETERS"  # define PEM_STRING_CMS          "CMS" +# define PEM_STRING_SM2PRIVATEKEY "SM2 PRIVATE KEY" +# define PEM_STRING_SM2PARAMETERS "SM2 PARAMETERS"  # define PEM_TYPE_ENCRYPTED      10  # define PEM_TYPE_MIC_ONLY       20 diff --git a/providers/decoders.inc b/providers/decoders.inc index 2772aad05da7..12e2104fb83f 100644 --- a/providers/decoders.inc +++ b/providers/decoders.inc @@ -1,5 +1,5 @@  /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -69,6 +69,7 @@ DECODER_w_structure("X448", der, SubjectPublicKeyInfo, x448, yes),  # ifndef OPENSSL_NO_SM2  DECODER_w_structure("SM2", der, PrivateKeyInfo, sm2, no),  DECODER_w_structure("SM2", der, SubjectPublicKeyInfo, sm2, no), +DECODER_w_structure("SM2", der, type_specific_no_pub, sm2, no),  # endif  #endif  DECODER_w_structure("RSA", der, PrivateKeyInfo, rsa, yes), diff --git a/providers/fips-sources.checksums b/providers/fips-sources.checksums index 1ab5d0348c6c..456db42ec1dc 100644 --- a/providers/fips-sources.checksums +++ b/providers/fips-sources.checksums @@ -10,7 +10,7 @@ a2466f18da5847c7d9fbced17524633c10ce024671a72f53f9c9c55b9b9923dd  crypto/aes/aes  88b6f8396cd9d86004743d5c3b0f72b7b8c3d5a2b00b0bbb761ba91ae5a7cdc8  crypto/aes/asm/aes-mips.pl  7ff9c96ef3d591d45d776fa4b244601ea0d9328e289aeab1e1b92436ce7d02ad  crypto/aes/asm/aes-parisc.pl  f1244cdeadcb4e48f35bc5df19d4cfaf07e0086ad951b84f07ff6966501faa5b  crypto/aes/asm/aes-ppc.pl -ecbfe826f4c514810c3ee20e265f4f621149694c298554b2682e5de4f029f14f  crypto/aes/asm/aes-s390x.pl +290ae2a09826d24e83763415a021e328d41a163f41cff8c9e3b882e973677f33  crypto/aes/asm/aes-s390x.pl  ee4e8cacef972942d2a89c1a83c984df9cad87c61a54383403c5c4864c403ba1  crypto/aes/asm/aes-sparcv9.pl  2b3b9ac56bf54334d053857a24bdb08592151e8a7a60b89b8195846b7f8ee7b5  crypto/aes/asm/aes-x86_64.pl  c56c324667b67d726e040d70379efba5b270e2937f403c1b5979018b836903c7  crypto/aes/asm/aesfx-sparcv9.pl @@ -197,9 +197,9 @@ e2705097cfab64e8d7eb2feba37c3f12b18aec74b135ad0c7f073efccf336d4c  crypto/ec/ecx_  62c994fd91dc4a5a1a81dfa9391d6eadae62d3549b2e1b22acb2e7c4cd278f27  crypto/evp/evp_fetch.c  ebe32b2895f7f9767710674352c8949efe93b4bbb5e7b71c27bb5d1822339b46  crypto/evp/evp_lib.c  78f07bf50b6999611a4e9414ab3a20b219b0ab29ca2bd05002d6919a3f67b8eb  crypto/evp/evp_local.h -117e679d49d2ae87e49d3c942ff0ce768959e8b9713f84a99025cabba462ccd5  crypto/evp/evp_rand.c +a801c0f785d2089d69872f0874bc91c2f90939839b5a1d76d33994eb5ced4754  crypto/evp/evp_rand.c  2a128617ec0178e9eeacbe41d75a5530755f41ea524cd124607543cf73456a0c  crypto/evp/evp_utils.c -ca8c6cfd30efd53f2e5d1f19bcf09a3a3d0dff6d8947c3943d07a3f4b354aa86  crypto/evp/exchange.c +cedb38e16de356c6d3fcd087801db059ab8b5a857b3687ad36ff3e75654cc142  crypto/evp/exchange.c  9e25042581b73e295c059c6217f3ecf809134d518eb79b1b67f34e3ca9145677  crypto/evp/kdf_lib.c  1d72f5506984df1df8606e8c7045f041cf517223e2e1b50c4da8ba8bf1c6c186  crypto/evp/kdf_meth.c  5179624b8e03615dc9caedc9ec16d094fa081495613dd552d71c2c39475bcd83  crypto/evp/kem.c @@ -211,7 +211,7 @@ e7e8eb5683cd3fbd409df888020dc353b65ac291361829cc4131d5bc86c9fcb3  crypto/evp/mac  546d83abecf8973e2d872102a03bde5a46552909fa9e7d1402e1464a27453801  crypto/evp/p_lib.c  3b4228b92eebd04616ecc3ee58684095313dd5ffd1b43cf698a7d6c202cb4622  crypto/evp/pmeth_check.c  1f0e9e94e9b0ad322956521b438b78d44cfcd8eb974e8921d05f9e21ba1c05cf  crypto/evp/pmeth_gn.c -76511fba789089a50ef87774817a5482c33633a76a94ecf7b6e8eb915585575d  crypto/evp/pmeth_lib.c +59af1ebff5870b531d1e007979ba59ced21c58a5fa481d2a8b24e9e1eb635bd5  crypto/evp/pmeth_lib.c  53058617c153a7676e7ca18c98c23df867a93087d67935907076f3c5bd65c15e  crypto/evp/signature.c  f2acfb82aac20251d05a9c252cc6c282bd44e43feac4ac2e0faf68b9a38aef57  crypto/ex_data.c  1c8389c5d49616d491978f0f2b2a54ba82d805ec41c8f75c67853216953cf46a  crypto/ffc/ffc_backend.c @@ -254,14 +254,14 @@ abba788a11469f5c01c766fdac64eccd4fb598b2d4d9a12efb086ae87009acb8  crypto/o_str.c  c698d5166d091d6bb6e9df3c211fe1cc916fd43a26ec844f28f547cd708f9c55  crypto/param_build.c  2a0f272dd553b698e8c6fa57962694ebd6064cb03fe26a60df529205568d315d  crypto/param_build_set.c  0e4a5388a92fabbe5a540176c0b4c5ce258b78dc9168ecc2e805352a06aaf0ba  crypto/params.c -4fda13f6af05d80b0ab89ec4f5813c274a21a9b4565be958a02d006236cef05c  crypto/params_dup.c +9121f614b65e471ddf944192015c8d19c34032629cfc284ebcc277469a9164dd  crypto/params_dup.c  b6cbfc8791b31587f32a3f9e4c117549793528ebddc34a361bad1ad8cf8d4c42  crypto/params_from_text.c  97cb7414dc2f165d5849ee3b46cdfff0afb067729435d9c01a747e0ca41e230c  crypto/ppccap.c  3ca43596a7528dec8ff9d1a3cd0d68b62640f84b1d6a8b5e4842cfd0be1133ad  crypto/ppccpuid.pl  b4d34272a0bd1fbe6562022bf7ea6259b6a5a021a48222d415be47ef5ef2a905  crypto/property/defn_cache.c -c3709986fd2ab18f3c6136d8dd7705a4538986aa789ceafe770c3a376db3c569  crypto/property/property.c +9b5fbefe6b18f665b44f79d1d08a977b484064a9fba46506ed8e812e581e9d97  crypto/property/property.c  66da4f28d408133fb544b14aeb9ad4913e7c5c67e2826e53f0dc5bf4d8fada26  crypto/property/property_local.h -b0b382ce829192d2537561cfb0fb5c7afb04305f321f7b3c91441b4ba99b9c92  crypto/property/property_parse.c +02ceadd33f54298eb4940cf0c00bea2b6d974d4707ea5e396369ab4d9cd0aac9  crypto/property/property_parse.c  a7cefda6a117550e2c76e0f307565ce1e11640b11ba10c80e469a837fd1212a3  crypto/property/property_query.c  065698c8d88a5facc0cbc02a3bd0c642c94687a8c5dd79901c942138b406067d  crypto/property/property_string.c  dcc44eba5d01dc248c37ec7b394d48660627c0fa4933d2b93993e1f2ac4b71da  crypto/provider_core.c @@ -344,11 +344,11 @@ c50c584c55e56347bb43aca4b796b5344d70daece3061f586b79c871c21f5d1a  crypto/sparse_  8da78169fa8c09dc3c29c9bf1602b22e88c5eac4815e274ba1864c166e31584b  crypto/stack/stack.c  7b4efa594d8d1f3ecbf4605cf54f72fb296a3b1d951bdc69e415aaa08f34e5c8  crypto/threads_lib.c  a41ae93a755e2ec89b3cb5b4932e2b508fdda92ace2e025a2650a6da0e9e972c  crypto/threads_none.c -3729e2bd36f945808b578e0d89fac0fcb3114e4fc9381614bcbd8a9869991716  crypto/threads_pthread.c +9cdcc15b140141d2646945d9b37c08ab55c31c83b7008a1f8faa55671bd27449  crypto/threads_pthread.c  f82715745b668297d71b66d05e6bfc3c817bf80bd967c0f33ca7ffbb6e347645  crypto/threads_win.c  fd6c27cf7c6b5449b17f2b725f4203c4c10207f1973db09fd41571efe5de08fd  crypto/x86_64cpuid.pl  bbec287bb9bf35379885f8f8998b7fd9e8fc22efee9e1b299109af0f33a7ee16  crypto/x86cpuid.pl -acbb841170d4d3eb91d969be1c0e4973b1babfd5fcd76440b0628f509f82fd76  e_os.h +4a61cecc1d1d547cb414404c73efe71cac8ab7885a03780a55c3ff8a74b1de26  e_os.h  249a0e58e9692920eddc1ada2ac772a0cfd749cfbf618f2f5da08280df545d8f  include/crypto/aes_platform.h  8c6f308c1ca774e6127e325c3b80511dbcdc99631f032694d8db53a5c02364ee  include/crypto/asn1_dsa.h  3bded0eaa7ccdebd0b4217b7fdb82676d5c0762a88aca462dbceaef851fafa99  include/crypto/bn.h @@ -373,7 +373,7 @@ f326212c978576c5346c89ae0336c2428594494b54054f6045b1f1038bfbc004  include/crypto  7676b02824b2d68df6bddeb251e9b8a8fa2e35a95dad9a7ebeca53f9ab8d2dad  include/crypto/sparse_array.h  7ad02c7de77304c3b298deeb038ab2550cf8b2bce03021994477c6c43dbcf86e  include/crypto/types.h  782a83d4e489fd865e2768a20bfa31e78c2071fd0ceeb9eb077276ae2bcc6590  include/internal/bio.h -8e984890c7c62cdd6356963f034831831f7167c65096cb4d23bc765d84d2c598  include/internal/constant_time.h +c64d5338564a30577c86347d99763f1a3321ec12a65c7d61298ea78a3f136a83  include/internal/constant_time.h  c5bb97f654984130c8b44c09a52395bce0b22985d5dbc9c4d9377d86283f11f8  include/internal/core.h  0b572801dfb8a41cc239e3439f8097a0ad11bbdf5d54811d10ceba3175cf2f17  include/internal/cryptlib.h  9571cfd3d5666749084b354a6d65adee443deeb5713a58c098c7b03bc69dbc63  include/internal/deprecated.h @@ -443,7 +443,7 @@ fd5c049ac6c3498750fa8f8dcbf88b2a31c02fa62dfe43a33d7b490fb86f61c8  include/openss  157797b450215f973eb10be96a04e58048ab9c131ad29427e80d0e37e230ed98  include/openssl/objects.h  d25537af264684dff033dd8ae62b0348f868fcfec4aa51fa8f07bcfa4bd807ad  include/openssl/objectserr.h  fe6acd42c3e90db31aaafc2236a7d30ebfa53c4c07ea4d8265064c7fcb951970  include/openssl/opensslconf.h -1bf52d136e94f727a96651c1f48ad040482f35dae152519ccd585efd410b92f0  include/openssl/opensslv.h.in +6c1a8837bbba633db2a8951ff29ccfe09e7d2a24a37ee2af90f2d897c190da9a  include/openssl/opensslv.h.in  767d9d7d5051c937a3ce8a268c702902fda93eeaa210a94dfde1f45c23277d20  include/openssl/param_build.h  30085f4d1b4934bb25ffe7aa9a30859966318a1b4d4dcea937c426e90e6e1984  include/openssl/params.h  097615b849375e2903967521f76c570512e5be47b8159fdbcd31e433f8a4cca7  include/openssl/prov_ssl.h @@ -500,7 +500,7 @@ abd5997bc33b681a4ab275978b92aebca0806a4a3f0c2f41dacf11b3b6f4e101  providers/fips  f822a03138e8b83ccaa910b89d72f31691da6778bf6638181f993ec7ae1167e3  providers/fips/self_test.h  d3c95c9c6cc4e3b1a5e4b2bfb2ae735a4109d763bcda7b1e9b8f9eb253f79820  providers/fips/self_test_data.inc  629f619ad055723e42624230c08430a3ef53e17ab405dc0fd35499e9ca4e389c  providers/fips/self_test_kats.c -99baeec10374301e90352ab637056104a8ea28a6880804f44c640d0c9ee16eba  providers/implementations/asymciphers/rsa_enc.c +a4c71215f53775a80a92433a8ad2b949cc54436c5d131286bbc9ec4e97e2e9d5  providers/implementations/asymciphers/rsa_enc.c  4db1826ecce8b60cb641bcd7a61430ec8cef73d2fe3cbc06aa33526afe1c954a  providers/implementations/ciphers/cipher_aes.c  6ba7d817081cf0d87ba7bfb38cd9d70e41505480bb8bc796ef896f68d4514ea6  providers/implementations/ciphers/cipher_aes.h  aef500281e7cd5a25a806a9bd45ec00a5b73984673202527dac5896fbcc9fa9c  providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c @@ -542,7 +542,7 @@ bb67eaa7a98494ca938726f9218213870fc97dd87b56bda950626cc794baf20b  providers/impl  c4b1cb143de15acc396ce2e03fdd165defd25ebc831de9cdfacf408ea883c666  providers/implementations/ciphers/ciphercommon_local.h  39b47b6ef9d71852964c26e07ef0e9b23f04c7493b1b16ba7c3dba7074b6b70d  providers/implementations/digests/digestcommon.c  80551b53302d95faea257df3edbdbd02d48427ce42da2c4335f998456400d057  providers/implementations/digests/sha2_prov.c -de342d04be6af69037922d5c97bdc40c0c27f6740636e72786a765d0d8ad9173  providers/implementations/digests/sha3_prov.c +52608810d317b4cfe358d5a668369f834f845bc5f82e475d7ecaae5ca0144293  providers/implementations/digests/sha3_prov.c  b5f94d597df72ca58486c59b2a70b4057d13f09528f861ed41a84b7125b54a82  providers/implementations/exchange/dh_exch.c  9c46dc0d859875fcc0bc3d61a7b610cd3520b1bf63718775c1124f54a1fe5f24  providers/implementations/exchange/ecdh_exch.c  9bf87b8429398a6465c7e9f749a33b84974303a458736b56f3359b30726d3969  providers/implementations/exchange/ecx_exch.c @@ -552,12 +552,12 @@ a9f5de1623221f327245957ec1dfd66a1914bff25adf4bcb81213c7955d19382  providers/impl  dd07797d61988fd4124cfb920616df672938da80649fac5977bfd061c981edc5  providers/implementations/include/prov/ciphercommon_ccm.h  0c1e99d70155402a790e4de65923228c8df8ad970741caccfe8b513837457d7f  providers/implementations/include/prov/ciphercommon_gcm.h  b9a61ce951c1904d8315b1bb26c0ab0aaadb47e71d4ead5df0a891608c728c4b  providers/implementations/include/prov/digestcommon.h -3e2558c36298cdb4fdaebe5a0cfa1dbbc78e0f60a9012f3a34e711cafb09c7b5  providers/implementations/include/prov/implementations.h +5f7ac2239579cf1ad503cf1644e8dae129179ff071abb1a1be1e0a4b69056469  providers/implementations/include/prov/implementations.h  5f09fc71874b00419d71646714f21ebbdcceda277463b6f77d3d3ea6946914e8  providers/implementations/include/prov/kdfexchange.h  c95ce5498e724b9b3d58e3c2f4723e7e3e4beb07f9bea9422e43182cbadb43af  providers/implementations/include/prov/macsignature.h  29d1a112b799e1f45fdf8bcee8361c2ed67428c250c1cdf408a9fbb7ebf4cce1  providers/implementations/include/prov/names.h  2187713b446d8b6d24ee986748b941ac3e24292c71e07ff9fb53a33021decdda  providers/implementations/include/prov/seeding.h -6091dd22e716fbe6c7c94524cdee6ad4432a572f2d3c4d360dcafafa3902d692  providers/implementations/kdfs/hkdf.c +9d84007b7d13c70ceef8709ba8c92bfffa894aabfe1802993f33f1268c18aab0  providers/implementations/kdfs/hkdf.c  a62e3af09f5af84dcf36f951ba4ac90ca1694adaf3747126186020b155f94186  providers/implementations/kdfs/kbkdf.c  e0644e727aacfea4da3cf2c4d2602d7ef0626ebb760b6467432ffd54d5fbb24d  providers/implementations/kdfs/pbkdf2.c  c0778565abff112c0c5257329a7750ec4605e62f26cc36851fa1fbee6e03c70c  providers/implementations/kdfs/pbkdf2.h @@ -571,21 +571,21 @@ abe2b0f3711eaa34846e155cffc9242e4051c45de896f747afd5ac9d87f637dc  providers/impl  9316fc619e8d8a1d841aa0936fc62c28eb2b4c60cc6c9b2d64b72f8641f28abb  providers/implementations/keymgmt/dsa_kmgmt.c  9bc88451d3ae110c7a108ee73d3b3b6bda801ec3494d2dfb9c9970b85c2d34fe  providers/implementations/keymgmt/ec_kmgmt.c  258ae17bb2dd87ed1511a8eb3fe99eed9b77f5c2f757215ff6b3d0e8791fc251  providers/implementations/keymgmt/ec_kmgmt_imexport.inc -d0c67b7fbddd51dcfebd96bf99794ca3bc437d50974ebcd56968fb8dd3627b0f  providers/implementations/keymgmt/ecx_kmgmt.c +5f76cf9d17e14f471f90ebadcd94fca654c806f4356b84d5b9363e8be4599bcb  providers/implementations/keymgmt/ecx_kmgmt.c  053a2be39a87f50b877ebdbbf799cf5faf8b2de33b04311d819d212ee1ea329b  providers/implementations/keymgmt/kdf_legacy_kmgmt.c -37e2f9f904eeabf94b1e4152b67ac236f872aa78dd7e47bf0de1b8f50ac19b6c  providers/implementations/keymgmt/mac_legacy_kmgmt.c +e0450f253ca54624587046edd28f071f55bf3088847dc8a4de79491079ad475d  providers/implementations/keymgmt/mac_legacy_kmgmt.c  19f22fc70a6321441e56d5bd4aab3d01d52d17069d4e4b5cefce0f411ecece75  providers/implementations/keymgmt/rsa_kmgmt.c  5eb96ea2df635cf79c5aeccae270fbe896b5e6384a5b3e4b187ce8c10fe8dfc7  providers/implementations/macs/cmac_prov.c  e69aa06f8f3c6f5a26702b9f44a844b8589b99dc0ee590953a29e8b9ef10acbe  providers/implementations/macs/gmac_prov.c -895c8dc7235b9ad5ff893be0293cbc245a5455e8850195ac7d446646e4ea71d0  providers/implementations/macs/hmac_prov.c +ba90013acb3a8725630cd71eda55ab735978930b73f2fd8f48a19800f365dfd3  providers/implementations/macs/hmac_prov.c  8640b63fd8325aaf8f7128d6cc448d9af448a65bf51a8978075467d33a67944e  providers/implementations/macs/kmac_prov.c  bf30274dd6b528ae913984775bd8f29c6c48c0ef06d464d0f738217727b7aa5c  providers/implementations/rands/crngt.c  f9457255fc57ef5739aa2584e535195e38cc947e31fd044d28d64c28c8a946ce  providers/implementations/rands/drbg.c -7e8fa6333845778474ed1313a66867512512372c9397f699a8f68fa6d5fc05fa  providers/implementations/rands/drbg_ctr.c +42e895fe255d90f9135eada30466811e3909ea4fd07fb968435dc5feee94ebf8  providers/implementations/rands/drbg_ctr.c  8337994f4bc95e421d6d2833bb4481ad9d84deb3913d0faec6e1791ea372a793  providers/implementations/rands/drbg_hash.c  1f040090f596f88cb64d6eb89109a8b75e66caee113708fb59335ad2547027fc  providers/implementations/rands/drbg_hmac.c  7a1b8516f891f25f3dc07ffe0455200f20d3a1f0345a917f00c7d9afe900bb0a  providers/implementations/rands/drbg_local.h -04339b66c10017229ef368cb48077f58a252ebfda9ab12b9f919e4149b1036ed  providers/implementations/rands/test_rng.c +66c0a91e23ae4275cc3f5daa8437d1c0addd10ca2e8aefab4573d606c5ba27ba  providers/implementations/rands/test_rng.c  cafb9e6f54ad15889fcebddac6df61336bff7d78936f7de3bb5aab8aee5728d2  providers/implementations/signature/dsa_sig.c  a30dc6308de0ca33406e7ce909f3bcf7580fb84d863b0976b275839f866258df  providers/implementations/signature/ecdsa_sig.c  09647b736980ac3c762f1e7c10cbfee78e2c6ab327ac62e5039968cea034ff3b  providers/implementations/signature/eddsa_sig.c diff --git a/providers/fips.checksum b/providers/fips.checksum index 0904f6a1029e..32b833e6e16e 100644 --- a/providers/fips.checksum +++ b/providers/fips.checksum @@ -1 +1 @@ -01b31117f96429fe4c8efbf7f4f10ef32efa2b11c69851fd227e4194db116b6f  providers/fips-sources.checksums +46b5dbc2fdaeae2a41830f026fddc5ec0c9b8c36936d420a7cf42aede2cb139c  providers/fips-sources.checksums diff --git a/providers/implementations/asymciphers/rsa_enc.c b/providers/implementations/asymciphers/rsa_enc.c index c8921acd6e61..8242546f61ae 100644 --- a/providers/implementations/asymciphers/rsa_enc.c +++ b/providers/implementations/asymciphers/rsa_enc.c @@ -1,5 +1,5 @@  /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -136,22 +136,27 @@ static int rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen,                         size_t outsize, const unsigned char *in, size_t inlen)  {      PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; +    size_t len = RSA_size(prsactx->rsa);      int ret;      if (!ossl_prov_is_running())          return 0; -    if (out == NULL) { -        size_t len = RSA_size(prsactx->rsa); +    if (len == 0) { +        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); +        return 0; +    } -        if (len == 0) { -            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); -            return 0; -        } +    if (out == NULL) {          *outlen = len;          return 1;      } +    if (outsize < len) { +        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); +        return 0; +    } +      if (prsactx->pad_mode == RSA_PKCS1_OAEP_PADDING) {          int rsasize = RSA_size(prsactx->rsa);          unsigned char *tbuf; diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc index 310f4470d6d4..d633ebd54470 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc @@ -1,5 +1,5 @@  /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -15,10 +15,8 @@  size_t armv8_aes_gcm_encrypt(const unsigned char *in, unsigned char *out, size_t len,                               const void *key, unsigned char ivec[16], u64 *Xi)  { -    size_t align_bytes = 0; -    align_bytes = len - len % 16; -      AES_KEY *aes_key = (AES_KEY *)key; +    size_t align_bytes = len - len % 16;      switch(aes_key->rounds) {          case 10: @@ -37,10 +35,8 @@ size_t armv8_aes_gcm_encrypt(const unsigned char *in, unsigned char *out, size_t  size_t armv8_aes_gcm_decrypt(const unsigned char *in, unsigned char *out, size_t len,                               const void *key, unsigned char ivec[16], u64 *Xi)  { -    size_t align_bytes = 0; -    align_bytes = len - len % 16; -      AES_KEY *aes_key = (AES_KEY *)key; +    size_t align_bytes = len - len % 16;      switch(aes_key->rounds) {          case 10: diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305.c b/providers/implementations/ciphers/cipher_chacha20_poly1305.c index 28ba0fee43d3..7fba6ab64f39 100644 --- a/providers/implementations/ciphers/cipher_chacha20_poly1305.c +++ b/providers/implementations/ciphers/cipher_chacha20_poly1305.c @@ -1,5 +1,5 @@  /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -32,7 +32,7 @@ static OSSL_FUNC_cipher_set_ctx_params_fn chacha20_poly1305_set_ctx_params;  static OSSL_FUNC_cipher_cipher_fn chacha20_poly1305_cipher;  static OSSL_FUNC_cipher_final_fn chacha20_poly1305_final;  static OSSL_FUNC_cipher_gettable_ctx_params_fn chacha20_poly1305_gettable_ctx_params; -#define chacha20_poly1305_settable_ctx_params ossl_cipher_aead_settable_ctx_params +static OSSL_FUNC_cipher_settable_ctx_params_fn chacha20_poly1305_settable_ctx_params;  #define chacha20_poly1305_gettable_params ossl_cipher_generic_gettable_params  #define chacha20_poly1305_update chacha20_poly1305_cipher @@ -158,6 +158,21 @@ static const OSSL_PARAM *chacha20_poly1305_gettable_ctx_params      return chacha20_poly1305_known_gettable_ctx_params;  } +static const OSSL_PARAM chacha20_poly1305_known_settable_ctx_params[] = { +    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), +    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), +    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), +    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0), +    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, NULL, 0), +    OSSL_PARAM_END +}; +static const OSSL_PARAM *chacha20_poly1305_settable_ctx_params( +        ossl_unused void *cctx, ossl_unused void *provctx +    ) +{ +    return chacha20_poly1305_known_settable_ctx_params; +} +  static int chacha20_poly1305_set_ctx_params(void *vctx,                                              const OSSL_PARAM params[])  { @@ -238,7 +253,6 @@ static int chacha20_poly1305_set_ctx_params(void *vctx,              return 0;          }      } -    /* ignore OSSL_CIPHER_PARAM_AEAD_MAC_KEY */      return 1;  } diff --git a/providers/implementations/digests/sha3_prov.c b/providers/implementations/digests/sha3_prov.c index 168825d47564..f6358e62562e 100644 --- a/providers/implementations/digests/sha3_prov.c +++ b/providers/implementations/digests/sha3_prov.c @@ -1,5 +1,5 @@  /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -19,7 +19,7 @@  #include "prov/implementations.h"  #define SHA3_FLAGS PROV_DIGEST_FLAG_ALGID_ABSENT -#define SHAKE_FLAGS PROV_DIGEST_FLAG_XOF +#define SHAKE_FLAGS (PROV_DIGEST_FLAG_XOF | PROV_DIGEST_FLAG_ALGID_ABSENT)  #define KMAC_FLAGS PROV_DIGEST_FLAG_XOF  /* diff --git a/providers/implementations/encode_decode/decode_der2key.c b/providers/implementations/encode_decode/decode_der2key.c index f2d9d8255648..075f90153607 100644 --- a/providers/implementations/encode_decode/decode_der2key.c +++ b/providers/implementations/encode_decode/decode_der2key.c @@ -1,5 +1,5 @@  /* - * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -806,6 +806,7 @@ MAKE_DECODER("ED448", ed448, ecx, SubjectPublicKeyInfo);  # ifndef OPENSSL_NO_SM2  MAKE_DECODER("SM2", sm2, ec, PrivateKeyInfo);  MAKE_DECODER("SM2", sm2, ec, SubjectPublicKeyInfo); +MAKE_DECODER("SM2", sm2, sm2, type_specific_no_pub);  # endif  #endif  MAKE_DECODER("RSA", rsa, rsa, PrivateKeyInfo); diff --git a/providers/implementations/encode_decode/decode_pem2der.c b/providers/implementations/encode_decode/decode_pem2der.c index bc937ffb9d27..ce21b6b80388 100644 --- a/providers/implementations/encode_decode/decode_pem2der.c +++ b/providers/implementations/encode_decode/decode_pem2der.c @@ -1,5 +1,5 @@  /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -119,6 +119,8 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,          { PEM_STRING_DSAPARAMS, OSSL_OBJECT_PKEY, "DSA", "type-specific" },          { PEM_STRING_ECPRIVATEKEY, OSSL_OBJECT_PKEY, "EC", "type-specific" },          { PEM_STRING_ECPARAMETERS, OSSL_OBJECT_PKEY, "EC", "type-specific" }, +        { PEM_STRING_SM2PRIVATEKEY, OSSL_OBJECT_PKEY, "SM2", "type-specific" }, +        { PEM_STRING_SM2PARAMETERS, OSSL_OBJECT_PKEY, "SM2", "type-specific" },          { PEM_STRING_RSA, OSSL_OBJECT_PKEY, "RSA", "type-specific" },          { PEM_STRING_RSA_PUBLIC, OSSL_OBJECT_PKEY, "RSA", "type-specific" }, diff --git a/providers/implementations/encode_decode/encode_key2text.c b/providers/implementations/encode_decode/encode_key2text.c index 637fcf6a1214..363031e83dbe 100644 --- a/providers/implementations/encode_decode/encode_key2text.c +++ b/providers/implementations/encode_decode/encode_key2text.c @@ -1,5 +1,5 @@  /* - * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -513,7 +513,8 @@ static int ec_to_text(BIO *out, const void *key, int selection)      else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)          type_label = "Public-Key";      else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) -        type_label = "EC-Parameters"; +        if (EC_GROUP_get_curve_name(group) != NID_sm2) +            type_label = "EC-Parameters";      if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {          const BIGNUM *priv_key = EC_KEY_get0_private_key(ec); @@ -539,8 +540,9 @@ static int ec_to_text(BIO *out, const void *key, int selection)              goto err;      } -    if (BIO_printf(out, "%s: (%d bit)\n", type_label, -                   EC_GROUP_order_bits(group)) <= 0) +    if (type_label != NULL +        && BIO_printf(out, "%s: (%d bit)\n", type_label, +                      EC_GROUP_order_bits(group)) <= 0)          goto err;      if (priv != NULL          && !print_labeled_buf(out, "priv:", priv, priv_len)) diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h index 3f6dd7ee16b6..6786ad691535 100644 --- a/providers/implementations/include/prov/implementations.h +++ b/providers/implementations/include/prov/implementations.h @@ -1,5 +1,5 @@  /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -498,6 +498,7 @@ extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ed448_decoder_functi  #ifndef OPENSSL_NO_SM2  extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_sm2_decoder_functions[];  extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_sm2_decoder_functions[]; +extern const OSSL_DISPATCH ossl_type_specific_no_pub_der_to_sm2_decoder_functions[];  #endif  extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_rsa_decoder_functions[]; diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c index 69ef565d04fc..1197a678e935 100644 --- a/providers/implementations/kdfs/hkdf.c +++ b/providers/implementations/kdfs/hkdf.c @@ -1,5 +1,5 @@  /* - * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -233,13 +233,11 @@ static int hkdf_common_set_ctx_params(KDF_HKDF *ctx, const OSSL_PARAM params[])      }      if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) { -        if (p->data_size != 0 && p->data != NULL) { -            OPENSSL_free(ctx->salt); -            ctx->salt = NULL; -            if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0, -                                             &ctx->salt_len)) -                return 0; -        } +        OPENSSL_free(ctx->salt); +        ctx->salt = NULL; +        if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0, +                                         &ctx->salt_len)) +            return 0;      }      return 1; diff --git a/providers/implementations/kdfs/krb5kdf.c b/providers/implementations/kdfs/krb5kdf.c index 8516a3f824af..fc7a3e600cc7 100644 --- a/providers/implementations/kdfs/krb5kdf.c +++ b/providers/implementations/kdfs/krb5kdf.c @@ -1,5 +1,5 @@  /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -329,7 +329,7 @@ static int cipher_init(EVP_CIPHER_CTX *ctx,  {      int klen, ret; -    ret = EVP_EncryptInit_ex(ctx, cipher, engine, key, NULL); +    ret = EVP_EncryptInit_ex(ctx, cipher, engine, NULL, NULL);      if (!ret)          goto out;      /* set the key len for the odd variable key len cipher */ @@ -341,6 +341,9 @@ static int cipher_init(EVP_CIPHER_CTX *ctx,              goto out;          }      } +    ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL); +    if (!ret) +        goto out;      /* we never want padding, either the length requested is a multiple of       * the cipher block size or we are passed a cipher that can cope with       * partial blocks via techniques like cipher text stealing */ diff --git a/providers/implementations/keymgmt/ecx_kmgmt.c b/providers/implementations/keymgmt/ecx_kmgmt.c index 94e62f755c20..d5dd01a314a2 100644 --- a/providers/implementations/keymgmt/ecx_kmgmt.c +++ b/providers/implementations/keymgmt/ecx_kmgmt.c @@ -1,5 +1,5 @@  /* - * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -344,7 +344,6 @@ static const OSSL_PARAM ecx_gettable_params[] = {      OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),      OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),      OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), -    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0),      OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),      ECX_KEY_TYPES(),      OSSL_PARAM_END @@ -354,6 +353,7 @@ static const OSSL_PARAM ed_gettable_params[] = {      OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),      OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),      OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), +    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0),      ECX_KEY_TYPES(),      OSSL_PARAM_END  }; @@ -485,6 +485,8 @@ static void *ecx_gen_init(void *provctx, int selection,          gctx->libctx = libctx;          gctx->type = type;          gctx->selection = selection; +    } else { +        return NULL;      }      if (!ecx_gen_set_params(gctx, params)) {          ecx_gen_cleanup(gctx); @@ -694,6 +696,9 @@ static void ecx_gen_cleanup(void *genctx)  {      struct ecx_gen_ctx *gctx = genctx; +    if (gctx == NULL) +        return; +      OPENSSL_free(gctx->propq);      OPENSSL_free(gctx);  } diff --git a/providers/implementations/keymgmt/mac_legacy_kmgmt.c b/providers/implementations/keymgmt/mac_legacy_kmgmt.c index b02a0a91c6f6..0b8cf9252c4b 100644 --- a/providers/implementations/keymgmt/mac_legacy_kmgmt.c +++ b/providers/implementations/keymgmt/mac_legacy_kmgmt.c @@ -527,6 +527,9 @@ static void mac_gen_cleanup(void *genctx)  {      struct mac_gen_ctx *gctx = genctx; +    if (gctx == NULL) +        return; +      OPENSSL_secure_clear_free(gctx->priv_key, gctx->priv_key_len);      ossl_prov_cipher_reset(&gctx->cipher);      OPENSSL_free(gctx); diff --git a/providers/implementations/macs/hmac_prov.c b/providers/implementations/macs/hmac_prov.c index 52ebb08b8f62..2dce0eb6b757 100644 --- a/providers/implementations/macs/hmac_prov.c +++ b/providers/implementations/macs/hmac_prov.c @@ -1,5 +1,5 @@  /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -94,7 +94,7 @@ static void hmac_free(void *vmacctx)      if (macctx != NULL) {          HMAC_CTX_free(macctx->ctx);          ossl_prov_digest_reset(&macctx->digest); -        OPENSSL_secure_clear_free(macctx->key, macctx->keylen); +        OPENSSL_clear_free(macctx->key, macctx->keylen);          OPENSSL_free(macctx);      }  } @@ -123,13 +123,13 @@ static void *hmac_dup(void *vsrc)          return NULL;      }      if (src->key != NULL) { -        /* There is no "secure" OPENSSL_memdup */ -        dst->key = OPENSSL_secure_malloc(src->keylen > 0 ? src->keylen : 1); +        dst->key = OPENSSL_malloc(src->keylen > 0 ? src->keylen : 1);          if (dst->key == NULL) {              hmac_free(dst);              return 0;          } -        memcpy(dst->key, src->key, src->keylen); +        if (src->keylen > 0) +            memcpy(dst->key, src->key, src->keylen);      }      return dst;  } @@ -154,12 +154,14 @@ static int hmac_setkey(struct hmac_data_st *macctx,      const EVP_MD *digest;      if (macctx->key != NULL) -        OPENSSL_secure_clear_free(macctx->key, macctx->keylen); +        OPENSSL_clear_free(macctx->key, macctx->keylen);      /* Keep a copy of the key in case we need it for TLS HMAC */ -    macctx->key = OPENSSL_secure_malloc(keylen > 0 ? keylen : 1); +    macctx->key = OPENSSL_malloc(keylen > 0 ? keylen : 1);      if (macctx->key == NULL)          return 0; -    memcpy(macctx->key, key, keylen); + +    if (keylen > 0) +        memcpy(macctx->key, key, keylen);      macctx->keylen = keylen;      digest = ossl_prov_digest_md(&macctx->digest); diff --git a/providers/implementations/rands/drbg_ctr.c b/providers/implementations/rands/drbg_ctr.c index 21fdce640816..269459c1cf09 100644 --- a/providers/implementations/rands/drbg_ctr.c +++ b/providers/implementations/rands/drbg_ctr.c @@ -1,5 +1,5 @@  /* - * Copyright 2011-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -20,6 +20,7 @@  #include "prov/providercommon.h"  #include "prov/provider_ctx.h"  #include "drbg_local.h" +#include "internal/cryptlib.h"  static OSSL_FUNC_rand_newctx_fn drbg_ctr_new_wrapper;  static OSSL_FUNC_rand_freectx_fn drbg_ctr_free; @@ -80,6 +81,8 @@ static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)       * are XORing. So just process however much input we have.       */      n = inlen < ctr->keylen ? inlen : ctr->keylen; +    if (!ossl_assert(n <= sizeof(ctr->K))) +        return;      for (i = 0; i < n; i++)          ctr->K[i] ^= in[i];      if (inlen <= ctr->keylen) diff --git a/providers/implementations/rands/test_rng.c b/providers/implementations/rands/test_rng.c index 4e7fed0fc7b1..e3b91368e80f 100644 --- a/providers/implementations/rands/test_rng.c +++ b/providers/implementations/rands/test_rng.c @@ -1,5 +1,5 @@  /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -125,16 +125,18 @@ static int test_rng_reseed(ossl_unused void *vtest,  static size_t test_rng_nonce(void *vtest, unsigned char *out,                               unsigned int strength,                               ossl_unused size_t min_noncelen, -                             ossl_unused size_t max_noncelen) +                             size_t max_noncelen)  {      PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest; +    size_t i;      if (t->nonce == NULL || strength > t->strength)          return 0; +    i = t->nonce_len > max_noncelen ? max_noncelen : t->nonce_len;      if (out != NULL) -        memcpy(out, t->nonce, t->nonce_len); -    return t->nonce_len; +        memcpy(out, t->nonce, i); +    return i;  }  static int test_rng_get_ctx_params(void *vtest, OSSL_PARAM params[]) diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c index 79de0219ec7b..3e5ec6aec4dd 100644 --- a/ssl/record/rec_layer_d1.c +++ b/ssl/record/rec_layer_d1.c @@ -1,5 +1,5 @@  /* - * Copyright 2005-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -606,6 +606,17 @@ int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,  #endif                  s->shutdown |= SSL_RECEIVED_SHUTDOWN;                  return 0; +            } else if (alert_descr == SSL_AD_NO_RENEGOTIATION) { +                /* +                 * This is a warning but we receive it if we requested +                 * renegotiation and the peer denied it. Terminate with a fatal +                 * alert because if the application tried to renegotiate it +                 * presumably had a good reason and expects it to succeed. In +                 * the future we might have a renegotiation where we don't care +                 * if the peer refused it where we carry on. +                 */ +                SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_RENEGOTIATION); +                return -1;              }          } else if (alert_level == SSL3_AL_FATAL) {              s->rwstate = SSL_NOTHING; diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index 779e998bb6ee..89ab1f4f1a44 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -1613,10 +1613,10 @@ int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,              /*               * This is a warning but we receive it if we requested               * renegotiation and the peer denied it. Terminate with a fatal -             * alert because if application tried to renegotiate it +             * alert because if the application tried to renegotiate it               * presumably had a good reason and expects it to succeed. In -             * future we might have a renegotiation where we don't care if -             * the peer refused it where we carry on. +             * the future we might have a renegotiation where we don't care +             * if the peer refused it where we carry on.               */              SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_RENEGOTIATION);              return -1; diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index bcfe57b46f08..7c76ae13db76 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved   * Copyright 2005 Nokia. All rights reserved.   * @@ -4820,7 +4820,10 @@ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret)      }      if (EVP_PKEY_derive(pctx, pms, &pmslen) <= 0) { -        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); +        /* +         * the public key was probably a weak key +         */ +        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE);          goto err;      } @@ -4923,7 +4926,7 @@ int ssl_encapsulate(SSL *s, EVP_PKEY *pubkey,      }      if (EVP_PKEY_encapsulate(pctx, ct, &ctlen, pms, &pmslen) <= 0) { -        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); +        SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE);          goto err;      } diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index 2e2d09a32ee4..a8d6df924bce 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved   *   * Licensed under the Apache License 2.0 (the "License").  You may not use @@ -812,16 +812,17 @@ static int add_uris_recursive(STACK_OF(X509_NAME) *stack,      OSSL_STORE_CTX *ctx = NULL;      X509 *x = NULL;      X509_NAME *xn = NULL; +    OSSL_STORE_INFO *info = NULL;      if ((ctx = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL)) == NULL)          goto err;      while (!OSSL_STORE_eof(ctx) && !OSSL_STORE_error(ctx)) { -        OSSL_STORE_INFO *info = OSSL_STORE_load(ctx); -        int infotype = info == 0 ? 0 : OSSL_STORE_INFO_get_type(info); +        int infotype; -        if (info == NULL) +        if ((info = OSSL_STORE_load(ctx)) == NULL)              continue; +        infotype = OSSL_STORE_INFO_get_type(info);          if (infotype == OSSL_STORE_INFO_NAME) {              /* @@ -846,6 +847,7 @@ static int add_uris_recursive(STACK_OF(X509_NAME) *stack,          }          OSSL_STORE_INFO_free(info); +        info = NULL;      }      ERR_clear_error(); @@ -853,6 +855,7 @@ static int add_uris_recursive(STACK_OF(X509_NAME) *stack,   err:      ok = 0; +    OSSL_STORE_INFO_free(info);   done:      OSSL_STORE_close(ctx); diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index ec937a321c30..72b6dae677e3 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   * Copyright 2005 Nokia. All rights reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use @@ -612,6 +612,8 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello)      SSL_TICKET_STATUS r;      if (SSL_IS_TLS13(s)) { +        SSL_SESSION_free(s->session); +        s->session = NULL;          /*           * By default we will send a new ticket. This can be overridden in the           * ticket processing. @@ -624,6 +626,7 @@ int ssl_get_prev_session(SSL *s, CLIENTHELLO_MSG *hello)                                          hello->pre_proc_exts, NULL, 0))              return -1; +        /* If we resumed, s->session will now be set */          ret = s->session;      } else {          /* sets s->ext.ticket_expected */ diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 72c00574be68..b8d55e144cfc 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -1,5 +1,5 @@  /* - * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -275,7 +275,13 @@ int tls_parse_ctos_sig_algs_cert(SSL *s, PACKET *pkt,          return 0;      } -    if (!s->hit && !tls1_save_sigalgs(s, &supported_sig_algs, 1)) { +    /* +     * We use this routine on both clients and servers, and when clients +     * get asked for PHA we need to always save the sigalgs regardless +     * of whether it was a resumption or not. +     */ +    if ((!s->server || (s->server && !s->hit)) +            && !tls1_save_sigalgs(s, &supported_sig_algs, 1)) {          SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);          return 0;      } @@ -294,7 +300,13 @@ int tls_parse_ctos_sig_algs(SSL *s, PACKET *pkt, unsigned int context, X509 *x,          return 0;      } -    if (!s->hit && !tls1_save_sigalgs(s, &supported_sig_algs, 0)) { +    /* +     * We use this routine on both clients and servers, and when clients +     * get asked for PHA we need to always save the sigalgs regardless +     * of whether it was a resumption or not. +     */ +    if ((!s->server || (s->server && !s->hit)) +            && !tls1_save_sigalgs(s, &supported_sig_algs, 0)) {          SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);          return 0;      } diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 6f0eaa5d6c0d..422d0428d465 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved   *   * Licensed under the Apache License 2.0 (the "License").  You may not use @@ -1967,23 +1967,24 @@ int ssl_choose_client_version(SSL *s, int version, RAW_EXTENSION *extensions)          real_max = ver_max;      /* Check for downgrades */ -    if (s->version == TLS1_2_VERSION && real_max > s->version) { -        if (memcmp(tls12downgrade, +    if (!SSL_IS_DTLS(s) && real_max > s->version) { +        /* Signal applies to all versions */ +        if (memcmp(tls11downgrade,                     s->s3.server_random + SSL3_RANDOM_SIZE -                                        - sizeof(tls12downgrade), -                   sizeof(tls12downgrade)) == 0) { +                   - sizeof(tls11downgrade), +                   sizeof(tls11downgrade)) == 0) {              s->version = origv;              SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,                       SSL_R_INAPPROPRIATE_FALLBACK);              return 0;          } -    } else if (!SSL_IS_DTLS(s) -               && s->version < TLS1_2_VERSION -               && real_max > s->version) { -        if (memcmp(tls11downgrade, -                   s->s3.server_random + SSL3_RANDOM_SIZE -                                        - sizeof(tls11downgrade), -                   sizeof(tls11downgrade)) == 0) { +        /* Only when accepting TLS1.3 */ +        if (real_max == TLS1_3_VERSION +            && memcmp(tls12downgrade, +                      s->s3.server_random + SSL3_RANDOM_SIZE +                      - sizeof(tls12downgrade), +                      sizeof(tls12downgrade)) == 0) { +              s->version = origv;              SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,                       SSL_R_INAPPROPRIATE_FALLBACK); diff --git a/test/bio_enc_test.c b/test/bio_enc_test.c index accb74e7df41..cf72b5e6a89d 100644 --- a/test/bio_enc_test.c +++ b/test/bio_enc_test.c @@ -1,5 +1,5 @@  /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -132,7 +132,17 @@ static int do_bio_cipher(const EVP_CIPHER* cipher, const unsigned char* key,      if (!TEST_ptr(mem))          goto err;      BIO_push(b, mem); +#if 0 +    /* +     * This is wrong to do, it always fails, and incorrectly ends up +     * calling `EVP_CipherFinal()` and setting ctx->finished = 1, ... +     * all of which are unwanted.  But just deleting this is less +     * instructive to future readers of the code.  Don't call BIO_flush +     * until you're done either reading or writing and want to finalise +     * the state. +     */      (void)BIO_flush(b); +#endif      memset(out, 0, sizeof(out));      len = BIO_read(b, out, sizeof(out));      BIO_free_all(b); @@ -250,6 +260,66 @@ static int test_bio_enc_chacha20_poly1305(int idx)  #  endif  # endif +static int test_bio_enc_eof_read_flush(void) +{ +    /* Length chosen to ensure base64 encoding employs padding */ +    const unsigned char pbuf[] = "Attack at dawn"; +    unsigned char cbuf[16];     /* At least as long as pbuf */ +    const EVP_CIPHER *cipher = EVP_aes_256_gcm(); +    EVP_CIPHER_CTX *ctx = NULL; +    BIO *mem = NULL, *b64 = NULL, *cbio = NULL; +    unsigned char tag[16]; +    size_t key_size, iv_size; +    int n, ret = 0; + +    memset(tag, 0, sizeof(tag)); +    if (!TEST_ptr(cipher) +        || !TEST_int_gt((key_size = EVP_CIPHER_key_length(cipher)), 0) +        || !TEST_int_gt((iv_size = EVP_CIPHER_iv_length(cipher)), 0) +        || !TEST_ptr(mem = BIO_new(BIO_s_mem())) +        || !TEST_ptr(b64 = BIO_new(BIO_f_base64())) +        || !TEST_ptr(cbio = BIO_new(BIO_f_cipher())) +        || !TEST_ptr(BIO_push(b64, mem)) +        || !TEST_ptr(BIO_push(cbio, b64)) +        || !TEST_int_gt(BIO_get_cipher_ctx(cbio, &ctx), 0) +        || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, KEY, IV, ENCRYPT)) +        || !TEST_int_gt(BIO_write(cbio, pbuf, sizeof(pbuf) - 1), 0) +        || !TEST_int_gt(BIO_flush(cbio), 0) +        || !TEST_int_gt(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, +                                            sizeof(tag), tag), 0)) +        goto end; +    BIO_free(cbio); +    BIO_free(b64); +    b64 = cbio = NULL; + +    BIO_set_mem_eof_return(mem, 0); +    BIO_set_flags(mem, BIO_FLAGS_NONCLEAR_RST); +    if (!TEST_int_gt(BIO_reset(mem), 0) +        || !TEST_ptr(b64 = BIO_new(BIO_f_base64())) +        || !TEST_ptr(cbio = BIO_new(BIO_f_cipher())) +        || !TEST_ptr(BIO_push(b64, mem)) +        || !TEST_ptr(BIO_push(cbio, b64)) +        || !TEST_int_gt(BIO_get_cipher_ctx(cbio, &ctx), 0) +        || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, KEY, IV, DECRYPT)) +        || !TEST_int_gt(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, +                                            sizeof(tag), tag), 0) +        || !TEST_int_gt((n = BIO_read(cbio, cbuf, sizeof(cbuf))), 0) +        || !TEST_true(BIO_get_cipher_status(cbio)) +        /* Evaluate both and report whether either or both failed */ +        || (!TEST_int_gt(BIO_flush(cbio), 0) + +            !TEST_true(BIO_get_cipher_status(cbio))) +        || !TEST_mem_eq(cbuf, n, pbuf, sizeof(pbuf) - 1)) +        goto end; + +    ret = 1; + + end: +    BIO_free(cbio); +    BIO_free(b64); +    BIO_free(mem); +    return ret; +} +  int setup_tests(void)  {      ADD_ALL_TESTS(test_bio_enc_aes_128_cbc, 2); @@ -262,5 +332,6 @@ int setup_tests(void)      ADD_ALL_TESTS(test_bio_enc_chacha20_poly1305, 2);  #  endif  # endif +    ADD_TEST(test_bio_enc_eof_read_flush);      return 1;  } diff --git a/test/bio_pw_callback_test.c b/test/bio_pw_callback_test.c new file mode 100644 index 000000000000..e11368454a8c --- /dev/null +++ b/test/bio_pw_callback_test.c @@ -0,0 +1,402 @@ +/* + * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License").  You may not use + * this file except in compliance with the License.  You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "testutil.h" + +#include <openssl/bio.h> +#include <openssl/pem.h> + +/* dummy data that needs to be passed to the callback */ +typedef struct CallbackData { +    char magic; +    int result; +} CALLBACK_DATA; + +/* constants */ +static const char weak_password[] = "weak_password"; +static const char a0a_password[] = "aaaaaaaa\0aaaaaaaa"; +static const char a0b_password[] = "aaaaaaaa\0bbbbbbbb"; +static const char cb_magic = 'p'; + +/* shared working data for all tests */ +static char *key_file = NULL; +static EVP_PKEY *original_pkey = NULL; + +/* the test performed by the callback */ +typedef enum CallbackTest { +    CB_TEST_NEGATIVE = 0, +    CB_TEST_ZERO_LENGTH, +    CB_TEST_WEAK, +    CB_TEST_16ZERO, +    CB_TEST_A0A, +    CB_TEST_A0B, +    CB_TEST_MATCH_SIZE, +    CB_TEST_EXCEED_SIZE +} CALLBACK_TEST; +static CALLBACK_TEST callback_test = CB_TEST_NEGATIVE; + +typedef enum KeyEncoding { +    KE_PEM = 0, +    KE_PKCS8 +} KEY_ENCODING; + +typedef enum ExpectedResult { +    ER_FAILURE = 0, +    ER_SUCCESS +} EXPECTED_RESULT; + +typedef enum OPTION_choice { +    OPT_ERR = -1, +    OPT_EOF = 0, +    OPT_KEY_FILE, +    OPT_TEST_ENUM +} OPTION_CHOICE; + +const OPTIONS *test_get_options(void) +{ +    static const OPTIONS test_options[] = { +        OPT_TEST_OPTIONS_DEFAULT_USAGE, +        { "keyfile", OPT_KEY_FILE, '<', +          "The PEM file with the encrypted key to load" }, +        { NULL } +    }; +    return test_options; +} + +static int callback_copy_password(char *buf, int size) +{ +    int ret = -1; + +    switch (callback_test) { +    case CB_TEST_NEGATIVE: +        break; +    case CB_TEST_ZERO_LENGTH: +        ret = 0; +        break; +    case CB_TEST_WEAK: +        ret = sizeof(weak_password) - 1; +        memcpy(buf, weak_password, ret); +        break; +    case CB_TEST_16ZERO: +        memset(buf, 0, 16); +        ret = 16; +        break; +    case CB_TEST_A0A: +        ret = sizeof(a0a_password) - 1; +        memcpy(buf, a0a_password, ret); +        break; +    case CB_TEST_A0B: +        ret = sizeof(a0b_password) - 1; +        memcpy(buf, a0b_password, ret); +        break; +    case CB_TEST_MATCH_SIZE: +        memset(buf, 'e', size); +        ret = size; +        break; +    case CB_TEST_EXCEED_SIZE: +        memset(buf, 'e', size); +        ret = 1000000; +        break; +    } +    return ret; +} + +static int read_callback(char *buf, int size, int rwflag, void *u) +{ +    CALLBACK_DATA *cb_data = (CALLBACK_DATA *)u; +    int ret = -1; + +    /* basic verification of the received data */ +    if (!TEST_ptr(cb_data)) +        goto err; +    if (!TEST_char_eq(cb_data->magic, cb_magic)) +        goto err; +    if (!TEST_ptr(buf)) +        goto err; +    if (!TEST_int_gt(size, 0)) +        goto err; +    if (!TEST_int_eq(rwflag, 0)) +        goto err; +    ret = callback_copy_password(buf, size); +    cb_data->result = 1; +err: +    return ret; +} + +static int write_callback(char *buf, int size, int rwflag, void *u) +{ +    CALLBACK_DATA *cb_data = (CALLBACK_DATA *)u; +    int ret = -1; + +    /* basic verification of the received data */ +    if (!TEST_ptr(cb_data)) +        goto err; +    if (!TEST_char_eq(cb_data->magic, cb_magic)) +        goto err; +    if (!TEST_ptr(buf)) +        goto err; +    if (!TEST_int_gt(size, 0)) +        goto err; +    if (!TEST_int_eq(rwflag, 1)) +        goto err; +    ret = callback_copy_password(buf, size); +    cb_data->result = 1; +err: +    return ret; +} + +static int re_encrypt_key(char **enc_data, int *enc_data_size, +                          KEY_ENCODING key_encoding) +{ +    CALLBACK_DATA cb_data; +    int w_ret = 0; +    BUF_MEM *bptr = NULL; +    BIO *bio = NULL; +    int ret = 0; + +    if (!TEST_ptr(enc_data)) +        goto err; +    if (!TEST_ptr(enc_data_size)) +        goto err; +    if (!TEST_ptr(bio = BIO_new(BIO_s_mem()))) +        goto err; +    cb_data.magic = cb_magic; +    cb_data.result = 0; +    switch (key_encoding) { +    case KE_PEM: +        w_ret = PEM_write_bio_PrivateKey(bio, original_pkey, EVP_aes_256_cbc(), +                                         NULL, 0, write_callback, &cb_data); +        break; +    case KE_PKCS8: +        w_ret = i2d_PKCS8PrivateKey_bio(bio, original_pkey, EVP_aes_256_cbc(), +                                        NULL, 0, write_callback, &cb_data); +        break; +    } +    if (!TEST_int_ne(w_ret, 0)) +        goto err; +    if (!TEST_char_eq(cb_data.magic, cb_magic)) +        goto err; +    if (!TEST_int_eq(cb_data.result, 1)) +        goto err; +    *enc_data_size = BIO_get_mem_data(bio, enc_data); +    BIO_get_mem_ptr(bio, &bptr); +    if (!BIO_set_close(bio, BIO_NOCLOSE)) +        goto err; +    bptr->data = NULL; +    ret = 1; +err: +    BUF_MEM_free(bptr); +    BIO_free(bio); +    return ret; +} + +static int decrypt_key(char *enc_data, int enc_data_size, +                       KEY_ENCODING key_encoding, +                       EXPECTED_RESULT expected_result) +{ +    CALLBACK_DATA cb_data; +    EVP_PKEY *r_ret = NULL; +    BIO *bio = NULL; +    EVP_PKEY *pkey = NULL; +    int ret = 0; + +    if (!TEST_ptr(bio = BIO_new_mem_buf(enc_data, enc_data_size))) +        goto err; +    cb_data.magic = cb_magic; +    cb_data.result = 0; +    switch (key_encoding) { +    case KE_PEM: +        r_ret = PEM_read_bio_PrivateKey(bio, &pkey, read_callback, &cb_data); +        break; +    case KE_PKCS8: +        r_ret = d2i_PKCS8PrivateKey_bio(bio, &pkey, read_callback, &cb_data); +        break; +    } +    if (expected_result == ER_SUCCESS) { +        if (!TEST_ptr(r_ret)) +            goto err; +    } else { +        if (!TEST_ptr_null(r_ret)) +            goto err; +    } +    if (!TEST_char_eq(cb_data.magic, cb_magic)) +        goto err; +    if (!TEST_int_eq(cb_data.result, 1)) +        goto err; +    ret = 1; +err: +    EVP_PKEY_free(pkey); +    BIO_free(bio); +    return ret; +} + +static int full_cycle_test(KEY_ENCODING key_encoding, CALLBACK_TEST write_test, +                           CALLBACK_TEST read_test, +                           EXPECTED_RESULT expected_read_result) +{ +    char *enc_data = NULL; +    int enc_data_size = 0; +    int ret = 0; + +    callback_test = write_test; +    if (!re_encrypt_key(&enc_data, &enc_data_size, key_encoding)) +        goto err; +    callback_test = read_test; +    if (!decrypt_key(enc_data, enc_data_size, key_encoding, +                     expected_read_result)) +        goto err; +    ret = 1; +err: +    OPENSSL_free(enc_data); +    return ret; +} + +static int test_pem_negative(void) +{ +    return full_cycle_test(KE_PEM, CB_TEST_WEAK, CB_TEST_NEGATIVE, ER_FAILURE); +} + +static int test_pem_zero_length(void) +{ +    return full_cycle_test(KE_PEM, CB_TEST_ZERO_LENGTH, CB_TEST_ZERO_LENGTH, +                           ER_SUCCESS); +} + +static int test_pem_weak(void) +{ +    return full_cycle_test(KE_PEM, CB_TEST_WEAK, CB_TEST_WEAK, ER_SUCCESS); +} + +static int test_pem_16zero(void) +{ +    return full_cycle_test(KE_PEM, CB_TEST_16ZERO, CB_TEST_16ZERO, ER_SUCCESS); +} + +static int test_pem_a0a(void) +{ +    return full_cycle_test(KE_PEM, CB_TEST_A0A, CB_TEST_A0A, ER_SUCCESS); +} + +static int test_pem_a0a_a0b(void) +{ +    return full_cycle_test(KE_PEM, CB_TEST_A0A, CB_TEST_A0B, ER_FAILURE); +} + +static int test_pem_match_size(void) +{ +    return full_cycle_test(KE_PEM, CB_TEST_MATCH_SIZE, CB_TEST_MATCH_SIZE, +                           ER_SUCCESS); +} + +static int test_pem_exceed_size(void) +{ +    return full_cycle_test(KE_PEM, CB_TEST_MATCH_SIZE, CB_TEST_EXCEED_SIZE, +                           ER_FAILURE); +} + +static int test_pkcs8_negative(void) +{ +    return full_cycle_test(KE_PKCS8, CB_TEST_WEAK, CB_TEST_NEGATIVE, ER_FAILURE); +} + +static int test_pkcs8_zero_length(void) +{ +    return full_cycle_test(KE_PKCS8, CB_TEST_ZERO_LENGTH, CB_TEST_ZERO_LENGTH, +                           ER_SUCCESS); +} + +static int test_pkcs8_weak(void) +{ +    return full_cycle_test(KE_PKCS8, CB_TEST_WEAK, CB_TEST_WEAK, ER_SUCCESS); +} + +static int test_pkcs8_16zero(void) +{ +    return full_cycle_test(KE_PKCS8, CB_TEST_16ZERO, CB_TEST_16ZERO, +                           ER_SUCCESS); +} + +static int test_pkcs8_a0a(void) +{ +    return full_cycle_test(KE_PKCS8, CB_TEST_A0A, CB_TEST_A0A, ER_SUCCESS); +} + +static int test_pkcs8_a0a_a0b(void) +{ +    return full_cycle_test(KE_PKCS8, CB_TEST_A0A, CB_TEST_A0B, ER_FAILURE); +} + +static int test_pkcs8_match_size(void) +{ +    return full_cycle_test(KE_PKCS8, CB_TEST_MATCH_SIZE, CB_TEST_MATCH_SIZE, +                           ER_SUCCESS); +} + +static int test_pkcs8_exceed_size(void) +{ +    return full_cycle_test(KE_PKCS8, CB_TEST_MATCH_SIZE, CB_TEST_EXCEED_SIZE, +                           ER_FAILURE); +} + +static int callback_original_pw(char *buf, int size, int rwflag, void *u) +{ +    memcpy(buf, weak_password, sizeof(weak_password) - 1); +    return sizeof(weak_password) - 1; +} + +int setup_tests(void) +{ +    OPTION_CHOICE o; +    BIO *bio = NULL; + +    while ((o = opt_next()) != OPT_EOF) { +        switch (o) { +        case OPT_KEY_FILE: +            key_file = opt_arg(); +            break; +        case OPT_TEST_CASES: +            break; +        default: +        case OPT_ERR: +            return 0; +        } +    } + +    /* read the original key */ +    if (!TEST_ptr(bio = BIO_new_file(key_file, "r"))) +        return 0; +    if (!TEST_ptr(PEM_read_bio_PrivateKey(bio, &original_pkey, +                                          callback_original_pw, NULL))) +        return 0; +    BIO_free(bio); + +    /* add all tests */ +    ADD_TEST(test_pem_negative); +    ADD_TEST(test_pem_zero_length); +    ADD_TEST(test_pem_weak); +    ADD_TEST(test_pem_16zero); +    ADD_TEST(test_pem_a0a); +    ADD_TEST(test_pem_a0a_a0b); +    ADD_TEST(test_pem_match_size); +    ADD_TEST(test_pem_exceed_size); +    ADD_TEST(test_pkcs8_negative); +    ADD_TEST(test_pkcs8_zero_length); +    ADD_TEST(test_pkcs8_weak); +    ADD_TEST(test_pkcs8_16zero); +    ADD_TEST(test_pkcs8_a0a); +    ADD_TEST(test_pkcs8_a0a_a0b); +    ADD_TEST(test_pkcs8_match_size); +    ADD_TEST(test_pkcs8_exceed_size); +    return 1; +} + +void cleanup_tests(void) +{ +    EVP_PKEY_free(original_pkey); +} diff --git a/test/bioprinttest.c b/test/bioprinttest.c index 04d1613c6cf4..46d2a3e644a2 100644 --- a/test/bioprinttest.c +++ b/test/bioprinttest.c @@ -1,5 +1,5 @@  /* - * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -20,90 +20,97 @@  static int justprint = 0; -static char *fpexpected[][10][5] = { +static char *fpexpected[][11][5] = {      { -    /*  00 */ { "0.0000e+00", "0.0000", "0", "0.0000E+00", "0" }, -    /*  01 */ { "6.7000e-01", "0.6700", "0.67", "6.7000E-01", "0.67" }, -    /*  02 */ { "6.6667e-01", "0.6667", "0.6667", "6.6667E-01", "0.6667" }, -    /*  03 */ { "6.6667e-04", "0.0007", "0.0006667", "6.6667E-04", "0.0006667" }, -    /*  04 */ { "6.6667e-05", "0.0001", "6.667e-05", "6.6667E-05", "6.667E-05" }, -    /*  05 */ { "6.6667e+00", "6.6667", "6.667", "6.6667E+00", "6.667" }, -    /*  06 */ { "6.6667e+01", "66.6667", "66.67", "6.6667E+01", "66.67" }, -    /*  07 */ { "6.6667e+02", "666.6667", "666.7", "6.6667E+02", "666.7" }, -    /*  08 */ { "6.6667e+03", "6666.6667", "6667", "6.6667E+03", "6667" }, -    /*  09 */ { "6.6667e+04", "66666.6667", "6.667e+04", "6.6667E+04", "6.667E+04" }, +        /*  0.00 */ { "0.0000e+00", "0.0000", "0", "0.0000E+00", "0" }, +        /*  0.01 */ { "6.7000e-01", "0.6700", "0.67", "6.7000E-01", "0.67" }, +        /*  0.02 */ { "6.6667e-01", "0.6667", "0.6667", "6.6667E-01", "0.6667" }, +        /*  0.03 */ { "6.6667e-04", "0.0007", "0.0006667", "6.6667E-04", "0.0006667" }, +        /*  0.04 */ { "6.6667e-05", "0.0001", "6.667e-05", "6.6667E-05", "6.667E-05" }, +        /*  0.05 */ { "6.6667e+00", "6.6667", "6.667", "6.6667E+00", "6.667" }, +        /*  0.06 */ { "6.6667e+01", "66.6667", "66.67", "6.6667E+01", "66.67" }, +        /*  0.07 */ { "6.6667e+02", "666.6667", "666.7", "6.6667E+02", "666.7" }, +        /*  0.08 */ { "6.6667e+03", "6666.6667", "6667", "6.6667E+03", "6667" }, +        /*  0.09 */ { "6.6667e+04", "66666.6667", "6.667e+04", "6.6667E+04", "6.667E+04" }, +        /*  0.10 */ { "-6.6667e+04", "-66666.6667", "-6.667e+04", "-6.6667E+04", "-6.667E+04" },      },      { -    /*  10 */ { "0.00000e+00", "0.00000", "0", "0.00000E+00", "0" }, -    /*  11 */ { "6.70000e-01", "0.67000", "0.67", "6.70000E-01", "0.67" }, -    /*  12 */ { "6.66667e-01", "0.66667", "0.66667", "6.66667E-01", "0.66667" }, -    /*  13 */ { "6.66667e-04", "0.00067", "0.00066667", "6.66667E-04", "0.00066667" }, -    /*  14 */ { "6.66667e-05", "0.00007", "6.6667e-05", "6.66667E-05", "6.6667E-05" }, -    /*  15 */ { "6.66667e+00", "6.66667", "6.6667", "6.66667E+00", "6.6667" }, -    /*  16 */ { "6.66667e+01", "66.66667", "66.667", "6.66667E+01", "66.667" }, -    /*  17 */ { "6.66667e+02", "666.66667", "666.67", "6.66667E+02", "666.67" }, -    /*  18 */ { "6.66667e+03", "6666.66667", "6666.7", "6.66667E+03", "6666.7" }, -    /*  19 */ { "6.66667e+04", "66666.66667", "66667", "6.66667E+04", "66667" }, +        /*  1.00 */ { "0.00000e+00", "0.00000", "0", "0.00000E+00", "0" }, +        /*  1.01 */ { "6.70000e-01", "0.67000", "0.67", "6.70000E-01", "0.67" }, +        /*  1.02 */ { "6.66667e-01", "0.66667", "0.66667", "6.66667E-01", "0.66667" }, +        /*  1.03 */ { "6.66667e-04", "0.00067", "0.00066667", "6.66667E-04", "0.00066667" }, +        /*  1.04 */ { "6.66667e-05", "0.00007", "6.6667e-05", "6.66667E-05", "6.6667E-05" }, +        /*  1.05 */ { "6.66667e+00", "6.66667", "6.6667", "6.66667E+00", "6.6667" }, +        /*  1.06 */ { "6.66667e+01", "66.66667", "66.667", "6.66667E+01", "66.667" }, +        /*  1.07 */ { "6.66667e+02", "666.66667", "666.67", "6.66667E+02", "666.67" }, +        /*  1.08 */ { "6.66667e+03", "6666.66667", "6666.7", "6.66667E+03", "6666.7" }, +        /*  1.09 */ { "6.66667e+04", "66666.66667", "66667", "6.66667E+04", "66667" }, +        /*  1.10 */ { "-6.66667e+04", "-66666.66667", "-66667", "-6.66667E+04", "-66667" },      },      { -    /*  20 */ { "  0.0000e+00", "      0.0000", "           0", "  0.0000E+00", "           0" }, -    /*  21 */ { "  6.7000e-01", "      0.6700", "        0.67", "  6.7000E-01", "        0.67" }, -    /*  22 */ { "  6.6667e-01", "      0.6667", "      0.6667", "  6.6667E-01", "      0.6667" }, -    /*  23 */ { "  6.6667e-04", "      0.0007", "   0.0006667", "  6.6667E-04", "   0.0006667" }, -    /*  24 */ { "  6.6667e-05", "      0.0001", "   6.667e-05", "  6.6667E-05", "   6.667E-05" }, -    /*  25 */ { "  6.6667e+00", "      6.6667", "       6.667", "  6.6667E+00", "       6.667" }, -    /*  26 */ { "  6.6667e+01", "     66.6667", "       66.67", "  6.6667E+01", "       66.67" }, -    /*  27 */ { "  6.6667e+02", "    666.6667", "       666.7", "  6.6667E+02", "       666.7" }, -    /*  28 */ { "  6.6667e+03", "   6666.6667", "        6667", "  6.6667E+03", "        6667" }, -    /*  29 */ { "  6.6667e+04", "  66666.6667", "   6.667e+04", "  6.6667E+04", "   6.667E+04" }, +        /*  2.00 */ { "  0.0000e+00", "      0.0000", "           0", "  0.0000E+00", "           0" }, +        /*  2.01 */ { "  6.7000e-01", "      0.6700", "        0.67", "  6.7000E-01", "        0.67" }, +        /*  2.02 */ { "  6.6667e-01", "      0.6667", "      0.6667", "  6.6667E-01", "      0.6667" }, +        /*  2.03 */ { "  6.6667e-04", "      0.0007", "   0.0006667", "  6.6667E-04", "   0.0006667" }, +        /*  2.04 */ { "  6.6667e-05", "      0.0001", "   6.667e-05", "  6.6667E-05", "   6.667E-05" }, +        /*  2.05 */ { "  6.6667e+00", "      6.6667", "       6.667", "  6.6667E+00", "       6.667" }, +        /*  2.06 */ { "  6.6667e+01", "     66.6667", "       66.67", "  6.6667E+01", "       66.67" }, +        /*  2.07 */ { "  6.6667e+02", "    666.6667", "       666.7", "  6.6667E+02", "       666.7" }, +        /*  2.08 */ { "  6.6667e+03", "   6666.6667", "        6667", "  6.6667E+03", "        6667" }, +        /*  2.09 */ { "  6.6667e+04", "  66666.6667", "   6.667e+04", "  6.6667E+04", "   6.667E+04" }, +        /*  2.10 */ { " -6.6667e+04", " -66666.6667", "  -6.667e+04", " -6.6667E+04", "  -6.667E+04" },      },      { -    /*  30 */ { " 0.00000e+00", "     0.00000", "           0", " 0.00000E+00", "           0" }, -    /*  31 */ { " 6.70000e-01", "     0.67000", "        0.67", " 6.70000E-01", "        0.67" }, -    /*  32 */ { " 6.66667e-01", "     0.66667", "     0.66667", " 6.66667E-01", "     0.66667" }, -    /*  33 */ { " 6.66667e-04", "     0.00067", "  0.00066667", " 6.66667E-04", "  0.00066667" }, -    /*  34 */ { " 6.66667e-05", "     0.00007", "  6.6667e-05", " 6.66667E-05", "  6.6667E-05" }, -    /*  35 */ { " 6.66667e+00", "     6.66667", "      6.6667", " 6.66667E+00", "      6.6667" }, -    /*  36 */ { " 6.66667e+01", "    66.66667", "      66.667", " 6.66667E+01", "      66.667" }, -    /*  37 */ { " 6.66667e+02", "   666.66667", "      666.67", " 6.66667E+02", "      666.67" }, -    /*  38 */ { " 6.66667e+03", "  6666.66667", "      6666.7", " 6.66667E+03", "      6666.7" }, -    /*  39 */ { " 6.66667e+04", " 66666.66667", "       66667", " 6.66667E+04", "       66667" }, +        /*  3.00 */ { " 0.00000e+00", "     0.00000", "           0", " 0.00000E+00", "           0" }, +        /*  3.01 */ { " 6.70000e-01", "     0.67000", "        0.67", " 6.70000E-01", "        0.67" }, +        /*  3.02 */ { " 6.66667e-01", "     0.66667", "     0.66667", " 6.66667E-01", "     0.66667" }, +        /*  3.03 */ { " 6.66667e-04", "     0.00067", "  0.00066667", " 6.66667E-04", "  0.00066667" }, +        /*  3.04 */ { " 6.66667e-05", "     0.00007", "  6.6667e-05", " 6.66667E-05", "  6.6667E-05" }, +        /*  3.05 */ { " 6.66667e+00", "     6.66667", "      6.6667", " 6.66667E+00", "      6.6667" }, +        /*  3.06 */ { " 6.66667e+01", "    66.66667", "      66.667", " 6.66667E+01", "      66.667" }, +        /*  3.07 */ { " 6.66667e+02", "   666.66667", "      666.67", " 6.66667E+02", "      666.67" }, +        /*  3.08 */ { " 6.66667e+03", "  6666.66667", "      6666.7", " 6.66667E+03", "      6666.7" }, +        /*  3.09 */ { " 6.66667e+04", " 66666.66667", "       66667", " 6.66667E+04", "       66667" }, +        /*  3.10 */ { "-6.66667e+04", "-66666.66667", "      -66667", "-6.66667E+04", "      -66667" },      },      { -    /*  40 */ { "0e+00", "0", "0", "0E+00", "0" }, -    /*  41 */ { "7e-01", "1", "0.7", "7E-01", "0.7" }, -    /*  42 */ { "7e-01", "1", "0.7", "7E-01", "0.7" }, -    /*  43 */ { "7e-04", "0", "0.0007", "7E-04", "0.0007" }, -    /*  44 */ { "7e-05", "0", "7e-05", "7E-05", "7E-05" }, -    /*  45 */ { "7e+00", "7", "7", "7E+00", "7" }, -    /*  46 */ { "7e+01", "67", "7e+01", "7E+01", "7E+01" }, -    /*  47 */ { "7e+02", "667", "7e+02", "7E+02", "7E+02" }, -    /*  48 */ { "7e+03", "6667", "7e+03", "7E+03", "7E+03" }, -    /*  49 */ { "7e+04", "66667", "7e+04", "7E+04", "7E+04" }, +        /*  4.00 */ { "0e+00", "0", "0", "0E+00", "0" }, +        /*  4.01 */ { "7e-01", "1", "0.7", "7E-01", "0.7" }, +        /*  4.02 */ { "7e-01", "1", "0.7", "7E-01", "0.7" }, +        /*  4.03 */ { "7e-04", "0", "0.0007", "7E-04", "0.0007" }, +        /*  4.04 */ { "7e-05", "0", "7e-05", "7E-05", "7E-05" }, +        /*  4.05 */ { "7e+00", "7", "7", "7E+00", "7" }, +        /*  4.06 */ { "7e+01", "67", "7e+01", "7E+01", "7E+01" }, +        /*  4.07 */ { "7e+02", "667", "7e+02", "7E+02", "7E+02" }, +        /*  4.08 */ { "7e+03", "6667", "7e+03", "7E+03", "7E+03" }, +        /*  4.09 */ { "7e+04", "66667", "7e+04", "7E+04", "7E+04" }, +        /*  4.10 */ { "-7e+04", "-66667", "-7e+04", "-7E+04", "-7E+04" },      },      { -    /*  50 */ { "0.000000e+00", "0.000000", "0", "0.000000E+00", "0" }, -    /*  51 */ { "6.700000e-01", "0.670000", "0.67", "6.700000E-01", "0.67" }, -    /*  52 */ { "6.666667e-01", "0.666667", "0.666667", "6.666667E-01", "0.666667" }, -    /*  53 */ { "6.666667e-04", "0.000667", "0.000666667", "6.666667E-04", "0.000666667" }, -    /*  54 */ { "6.666667e-05", "0.000067", "6.66667e-05", "6.666667E-05", "6.66667E-05" }, -    /*  55 */ { "6.666667e+00", "6.666667", "6.66667", "6.666667E+00", "6.66667" }, -    /*  56 */ { "6.666667e+01", "66.666667", "66.6667", "6.666667E+01", "66.6667" }, -    /*  57 */ { "6.666667e+02", "666.666667", "666.667", "6.666667E+02", "666.667" }, -    /*  58 */ { "6.666667e+03", "6666.666667", "6666.67", "6.666667E+03", "6666.67" }, -    /*  59 */ { "6.666667e+04", "66666.666667", "66666.7", "6.666667E+04", "66666.7" }, +        /*  5.00 */ { "0.000000e+00", "0.000000", "0", "0.000000E+00", "0" }, +        /*  5.01 */ { "6.700000e-01", "0.670000", "0.67", "6.700000E-01", "0.67" }, +        /*  5.02 */ { "6.666667e-01", "0.666667", "0.666667", "6.666667E-01", "0.666667" }, +        /*  5.03 */ { "6.666667e-04", "0.000667", "0.000666667", "6.666667E-04", "0.000666667" }, +        /*  5.04 */ { "6.666667e-05", "0.000067", "6.66667e-05", "6.666667E-05", "6.66667E-05" }, +        /*  5.05 */ { "6.666667e+00", "6.666667", "6.66667", "6.666667E+00", "6.66667" }, +        /*  5.06 */ { "6.666667e+01", "66.666667", "66.6667", "6.666667E+01", "66.6667" }, +        /*  5.07 */ { "6.666667e+02", "666.666667", "666.667", "6.666667E+02", "666.667" }, +        /*  5.08 */ { "6.666667e+03", "6666.666667", "6666.67", "6.666667E+03", "6666.67" }, +        /*  5.09 */ { "6.666667e+04", "66666.666667", "66666.7", "6.666667E+04", "66666.7" }, +        /*  5.10 */ { "-6.666667e+04", "-66666.666667", "-66666.7", "-6.666667E+04", "-66666.7" },      },      { -    /*  60 */ { "0.0000e+00", "000.0000", "00000000", "0.0000E+00", "00000000" }, -    /*  61 */ { "6.7000e-01", "000.6700", "00000.67", "6.7000E-01", "00000.67" }, -    /*  62 */ { "6.6667e-01", "000.6667", "000.6667", "6.6667E-01", "000.6667" }, -    /*  63 */ { "6.6667e-04", "000.0007", "0.0006667", "6.6667E-04", "0.0006667" }, -    /*  64 */ { "6.6667e-05", "000.0001", "6.667e-05", "6.6667E-05", "6.667E-05" }, -    /*  65 */ { "6.6667e+00", "006.6667", "0006.667", "6.6667E+00", "0006.667" }, -    /*  66 */ { "6.6667e+01", "066.6667", "00066.67", "6.6667E+01", "00066.67" }, -    /*  67 */ { "6.6667e+02", "666.6667", "000666.7", "6.6667E+02", "000666.7" }, -    /*  68 */ { "6.6667e+03", "6666.6667", "00006667", "6.6667E+03", "00006667" }, -    /*  69 */ { "6.6667e+04", "66666.6667", "6.667e+04", "6.6667E+04", "6.667E+04" }, +        /*  6.00 */ { "0.0000e+00", "000.0000", "00000000", "0.0000E+00", "00000000" }, +        /*  6.01 */ { "6.7000e-01", "000.6700", "00000.67", "6.7000E-01", "00000.67" }, +        /*  6.02 */ { "6.6667e-01", "000.6667", "000.6667", "6.6667E-01", "000.6667" }, +        /*  6.03 */ { "6.6667e-04", "000.0007", "0.0006667", "6.6667E-04", "0.0006667" }, +        /*  6.04 */ { "6.6667e-05", "000.0001", "6.667e-05", "6.6667E-05", "6.667E-05" }, +        /*  6.05 */ { "6.6667e+00", "006.6667", "0006.667", "6.6667E+00", "0006.667" }, +        /*  6.06 */ { "6.6667e+01", "066.6667", "00066.67", "6.6667E+01", "00066.67" }, +        /*  6.07 */ { "6.6667e+02", "666.6667", "000666.7", "6.6667E+02", "000666.7" }, +        /*  6.08 */ { "6.6667e+03", "6666.6667", "00006667", "6.6667E+03", "00006667" }, +        /*  6.09 */ { "6.6667e+04", "66666.6667", "6.667e+04", "6.6667E+04", "6.667E+04" }, +        /*  6.10 */ { "-6.6667e+04", "-66666.6667", "-6.667e+04", "-6.6667E+04", "-6.667E+04" },      },  }; @@ -204,7 +211,7 @@ static int dofptest(int test, int sub, double val, const char *width, int prec)          if (justprint) {              if (i == 0) -                printf("    /*  %d%d */ { \"%s\"", test, sub, result); +                printf("    /*  %d.%02d */ { \"%s\"", test, sub, result);              else                  printf(", \"%s\"", result);          } else if (!TEST_str_eq(fpexpected[test][sub][i], result)) { @@ -235,7 +242,8 @@ static int test_fp(int i)          && TEST_true(dofptest(i, t++, 66.0 + frac, pwp->w, pwp->p))          && TEST_true(dofptest(i, t++, 666.0 + frac, pwp->w, pwp->p))          && TEST_true(dofptest(i, t++, 6666.0 + frac, pwp->w, pwp->p)) -        && TEST_true(dofptest(i, t++, 66666.0 + frac, pwp->w, pwp->p)); +        && TEST_true(dofptest(i, t++, 66666.0 + frac, pwp->w, pwp->p)) +        && TEST_true(dofptest(i, t++, -66666.0 - frac, pwp->w, pwp->p));      if (justprint)          printf("    },\n");      return r; diff --git a/test/dhtest.c b/test/dhtest.c index 000dd5b69805..a49cb6cb5f84 100644 --- a/test/dhtest.c +++ b/test/dhtest.c @@ -1,5 +1,5 @@  /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -208,17 +208,17 @@ static int dh_test(void)      alen = DH_size(a);      if (!TEST_ptr(abuf = OPENSSL_malloc(alen)) -            || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1)) +            || !TEST_int_gt((aout = DH_compute_key(abuf, bpub_key, a)), 0))          goto err3;      blen = DH_size(b);      if (!TEST_ptr(bbuf = OPENSSL_malloc(blen)) -            || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1)) +            || !TEST_int_gt((bout = DH_compute_key(bbuf, apub_key, b)), 0))          goto err3;      clen = DH_size(c);      if (!TEST_ptr(cbuf = OPENSSL_malloc(clen)) -            || !TEST_true((cout = DH_compute_key(cbuf, apub_key, c)) != -1)) +            || !TEST_int_gt((cout = DH_compute_key(cbuf, apub_key, c)), 0))          goto err3;      if (!TEST_true(aout >= 20) @@ -694,12 +694,12 @@ static int rfc7919_test(void)      alen = DH_size(a);      if (!TEST_int_gt(alen, 0) || !TEST_ptr(abuf = OPENSSL_malloc(alen)) -            || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1)) +            || !TEST_int_gt((aout = DH_compute_key(abuf, bpub_key, a)), 0))          goto err;      blen = DH_size(b);      if (!TEST_int_gt(blen, 0) || !TEST_ptr(bbuf = OPENSSL_malloc(blen)) -            || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1)) +            || !TEST_int_gt((bout = DH_compute_key(bbuf, apub_key, b)), 0))          goto err;      if (!TEST_true(aout >= 20) diff --git a/test/ectest.c b/test/ectest.c index 946973c2f4d9..061aec97f42c 100644 --- a/test/ectest.c +++ b/test/ectest.c @@ -1,5 +1,5 @@  /* - * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.   * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved   *   * Licensed under the Apache License 2.0 (the "License").  You may not use @@ -2707,7 +2707,7 @@ static int custom_params_test(int id)      int is_prime = 0;      EC_KEY *eckey1 = NULL, *eckey2 = NULL;      EVP_PKEY *pkey1 = NULL, *pkey2 = NULL; -    EVP_PKEY_CTX *pctx1 = NULL, *pctx2 = NULL; +    EVP_PKEY_CTX *pctx1 = NULL, *pctx2 = NULL, *dctx = NULL;      size_t sslen, t;      unsigned char *pub1 = NULL , *pub2 = NULL;      OSSL_PARAM_BLD *param_bld = NULL; @@ -2930,11 +2930,12 @@ static int custom_params_test(int id)      EVP_PKEY_CTX_free(pctx1);      if (!TEST_ptr(pctx1 = EVP_PKEY_CTX_new(pkey1, NULL))              || !TEST_int_eq(EVP_PKEY_derive_init(pctx1), 1) -            || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx1, pkey2), 1) -            || !TEST_int_eq(EVP_PKEY_derive(pctx1, NULL, &t), 1) +            || !TEST_ptr(dctx = EVP_PKEY_CTX_dup(pctx1)) +            || !TEST_int_eq(EVP_PKEY_derive_set_peer_ex(dctx, pkey2, 1), 1) +            || !TEST_int_eq(EVP_PKEY_derive(dctx, NULL, &t), 1)              || !TEST_int_gt(bsize, t)              || !TEST_int_le(sslen, t) -            || !TEST_int_eq(EVP_PKEY_derive(pctx1, buf1, &t), 1) +            || !TEST_int_eq(EVP_PKEY_derive(dctx, buf1, &t), 1)              /* compare with previous result */              || !TEST_mem_eq(buf1, t, buf2, sslen))          goto err; @@ -2962,6 +2963,7 @@ static int custom_params_test(int id)      EVP_PKEY_free(pkey2);      EVP_PKEY_CTX_free(pctx1);      EVP_PKEY_CTX_free(pctx2); +    EVP_PKEY_CTX_free(dctx);      return ret;  } diff --git a/test/endecode_test.c b/test/endecode_test.c index 0611d94216f0..b34659529e2c 100644 --- a/test/endecode_test.c +++ b/test/endecode_test.c @@ -1,5 +1,5 @@  /* - * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -1241,6 +1241,28 @@ static int create_ec_explicit_trinomial_params(OSSL_PARAM_BLD *bld)      return do_create_ec_explicit_trinomial_params(bld, gen2, sizeof(gen2));  }  # endif /* OPENSSL_NO_EC2M */ + +/* + * Test that multiple calls to OSSL_ENCODER_to_data() do not cause side effects + */ +static int ec_encode_to_data_multi(void) +{ +    int ret; +    OSSL_ENCODER_CTX *ectx = NULL; +    EVP_PKEY *key = NULL; +    uint8_t *enc = NULL; +    size_t enc_len = 0; + +    ret = TEST_ptr(key = EVP_PKEY_Q_keygen(testctx, "", "EC", "P-256")) +        && TEST_ptr(ectx = OSSL_ENCODER_CTX_new_for_pkey(key, EVP_PKEY_KEYPAIR, +                                                         "DER", NULL, NULL)) +        && TEST_int_eq(OSSL_ENCODER_to_data(ectx, NULL, &enc_len), 1) +        && TEST_int_eq(OSSL_ENCODER_to_data(ectx, &enc, &enc_len), 1); +    OPENSSL_free(enc); +    EVP_PKEY_free(key); +    OSSL_ENCODER_CTX_free(ectx); +    return ret; +}  #endif /* OPENSSL_NO_EC */  typedef enum OPTION_choice { @@ -1421,6 +1443,7 @@ int setup_tests(void)  # endif  #endif  #ifndef OPENSSL_NO_EC +        ADD_TEST(ec_encode_to_data_multi);          ADD_TEST_SUITE(EC);          ADD_TEST_SUITE_PARAMS(EC);          ADD_TEST_SUITE_LEGACY(EC); diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c index c5fbbf8a8309..b783ee45182d 100644 --- a/test/evp_extra_test.c +++ b/test/evp_extra_test.c @@ -1,5 +1,5 @@  /* - * Copyright 2015-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -716,7 +716,9 @@ static EVP_PKEY *make_key_fromdata(char *keytype, OSSL_PARAM *params)      if (!TEST_ptr(pctx = EVP_PKEY_CTX_new_from_name(testctx, keytype, testpropq)))          goto err; -    if (!TEST_int_gt(EVP_PKEY_fromdata_init(pctx), 0) +    /* Check that premature EVP_PKEY_CTX_set_params() fails gracefully */ +    if (!TEST_int_eq(EVP_PKEY_CTX_set_params(pctx, params), 0) +        || !TEST_int_gt(EVP_PKEY_fromdata_init(pctx), 0)          || !TEST_int_gt(EVP_PKEY_fromdata(pctx, &tmp_pkey, EVP_PKEY_KEYPAIR,                                            params), 0))          goto err; @@ -2594,6 +2596,7 @@ static int test_empty_salt_info_HKDF(void)      size_t outlen;      int ret = 0;      unsigned char salt[] = ""; +    unsigned char fake[] = "0123456789";      unsigned char key[] = "012345678901234567890123456789";      unsigned char info[] = "";      const unsigned char expected[] = { @@ -2610,6 +2613,8 @@ static int test_empty_salt_info_HKDF(void)      if (!TEST_int_gt(EVP_PKEY_derive_init(pctx), 0)              || !TEST_int_gt(EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()), 0) +            || !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_salt(pctx, fake, +                                                        sizeof(fake) - 1), 0)              || !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt,                                                          sizeof(salt) - 1), 0)              || !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_key(pctx, key, @@ -3005,6 +3010,48 @@ static int test_RSA_OAEP_set_null_label(void)      return ret;  } +static int test_RSA_encrypt(void) +{ +    int ret = 0; +    EVP_PKEY *pkey = NULL; +    EVP_PKEY_CTX *pctx = NULL; +    unsigned char *cbuf = NULL, *pbuf = NULL; +    size_t clen = 0, plen = 0; + +    if (!TEST_ptr(pkey = load_example_rsa_key()) +        || !TEST_ptr(pctx = EVP_PKEY_CTX_new_from_pkey(testctx, +                                                       pkey, testpropq)) +        || !TEST_int_gt(EVP_PKEY_encrypt_init(pctx), 0) +        || !TEST_int_gt(EVP_PKEY_encrypt(pctx, cbuf, &clen, kMsg, sizeof(kMsg)), 0) +        || !TEST_ptr(cbuf = OPENSSL_malloc(clen)) +        || !TEST_int_gt(EVP_PKEY_encrypt(pctx, cbuf, &clen, kMsg, sizeof(kMsg)), 0)) +        goto done; + +    /* Require failure when the output buffer is too small */ +    plen = clen - 1; +    if (!TEST_int_le(EVP_PKEY_encrypt(pctx, cbuf, &plen, kMsg, sizeof(kMsg)), 0)) +        goto done; +    /* flush error stack */ +    TEST_openssl_errors(); + +    /* Check decryption of encrypted result */ +    if (!TEST_int_gt(EVP_PKEY_decrypt_init(pctx), 0) +        || !TEST_int_gt(EVP_PKEY_decrypt(pctx, pbuf, &plen, cbuf, clen), 0) +        || !TEST_ptr(pbuf = OPENSSL_malloc(plen)) +        || !TEST_int_gt(EVP_PKEY_decrypt(pctx, pbuf, &plen, cbuf, clen), 0) +        || !TEST_mem_eq(pbuf, plen, kMsg, sizeof(kMsg)) +        || !TEST_int_gt(EVP_PKEY_encrypt_init(pctx), 0)) +        goto done; + +    ret = 1; +done: +    EVP_PKEY_CTX_free(pctx); +    EVP_PKEY_free(pkey); +    OPENSSL_free(cbuf); +    OPENSSL_free(pbuf); +    return ret; +} +  #if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)  static int test_decrypt_null_chunks(void)  { @@ -5459,6 +5506,7 @@ int setup_tests(void)      ADD_TEST(test_RSA_get_set_params);      ADD_TEST(test_RSA_OAEP_set_get_params);      ADD_TEST(test_RSA_OAEP_set_null_label); +    ADD_TEST(test_RSA_encrypt);  #if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)      ADD_TEST(test_decrypt_null_chunks);  #endif diff --git a/test/evp_libctx_test.c b/test/evp_libctx_test.c index fd114a118cb2..1a4b398643d8 100644 --- a/test/evp_libctx_test.c +++ b/test/evp_libctx_test.c @@ -1,5 +1,5 @@  /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -38,6 +38,8 @@ static OSSL_LIB_CTX *libctx = NULL;  static OSSL_PROVIDER *nullprov = NULL;  static OSSL_PROVIDER *libprov = NULL;  static STACK_OF(OPENSSL_STRING) *cipher_names = NULL; +static int is_fips = 0; +static int is_fips_lt_3_5 = 0;  typedef enum OPTION_choice {      OPT_ERR = -1, @@ -631,9 +633,10 @@ static int kem_rsa_params(void)          && TEST_int_eq(EVP_PKEY_decapsulate(pubctx, secret, &secretlen, ct,                                              sizeof(ct)), 0)          && TEST_uchar_eq(secret[0], 0) -        /* Test encapsulate fails if the mode is not set */ +        /* Unless newer FIPS, test encapsulate fails when the mode is not set. */          && TEST_int_eq(EVP_PKEY_encapsulate_init(pubctx, NULL), 1) -        && TEST_int_eq(EVP_PKEY_encapsulate(pubctx, ct, &ctlen, secret, &secretlen), -2) +        && (!is_fips_lt_3_5 || +            TEST_int_eq(EVP_PKEY_encapsulate(pubctx, ct, &ctlen, secret, &secretlen), -2))          /* Test setting a bad kem ops fail */          && TEST_int_eq(EVP_PKEY_CTX_set_kem_op(pubctx, "RSA"), 0)          && TEST_int_eq(EVP_PKEY_CTX_set_kem_op(pubctx, NULL), 0) @@ -743,8 +746,14 @@ int setup_tests(void)      if (!test_get_libctx(&libctx, &nullprov, config_file, &libprov, prov_name))          return 0; +    if (strcmp(prov_name, "fips") == 0) +        is_fips = 1; + +    is_fips_lt_3_5 = is_fips && fips_provider_version_lt(libctx, 3, 5, 0); +  #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DH) -    ADD_ALL_TESTS(test_dsa_param_keygen, 3 * 3 * 3); +    if (!is_fips || fips_provider_version_lt(libctx, 3, 4, 0)) +        ADD_ALL_TESTS(test_dsa_param_keygen, 3 * 3 * 3);  #endif  #ifndef OPENSSL_NO_DH      ADD_ALL_TESTS(test_dh_safeprime_param_keygen, 3 * 3 * 3); diff --git a/test/evp_pkey_provided_test.c b/test/evp_pkey_provided_test.c index 688a8c1c5e55..5c4920d0720e 100644 --- a/test/evp_pkey_provided_test.c +++ b/test/evp_pkey_provided_test.c @@ -1,5 +1,5 @@  /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -1782,6 +1782,53 @@ err:      return ret;  } +static const char *name_dup_algs[] = { +#ifndef OPENSSL_NO_ECX +    "ED25519", +#endif +#ifndef OPENSSL_NO_ML_KEM +    "ML-KEM-512", +#endif +#ifndef OPENSSL_NO_ML_DSA +    "ML-DSA-44", +#endif +    NULL +}; + +static int test_name_dup(int idx) +{ +    const char *alg = name_dup_algs[idx]; +    EVP_PKEY *key = NULL; +    EVP_PKEY_CTX *factory = NULL, *ctx = NULL; +    int i, ret = 0; + +    if (alg == NULL +        || (factory = EVP_PKEY_CTX_new_from_name(NULL, alg, NULL)) == NULL) +        return 1; +    TEST_info("Testing fresh context dup for: %s", alg); + +    /* Run twice to check that *repeated* use works */ +    for (i = 0; i < 2; ++i) { +        EVP_PKEY_CTX_free(ctx); +        EVP_PKEY_free(key); +        key = NULL; +        if (!TEST_ptr(ctx = EVP_PKEY_CTX_dup(factory)) +            || !TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0) +            || !TEST_int_gt(EVP_PKEY_keygen(ctx, &key), 0)) { +            ERR_print_errors(bio_err); +            goto end; +        } +    } +    ret = 1; + + end: +    EVP_PKEY_CTX_free(factory); +    EVP_PKEY_CTX_free(ctx); +    EVP_PKEY_free(key); + +    return ret; +} +  int setup_tests(void)  {      if (!test_skip_common_options()) { @@ -1793,6 +1840,7 @@ int setup_tests(void)          return 0;      ADD_TEST(test_evp_pkey_ctx_dup_kdf_fail); +    ADD_ALL_TESTS(test_name_dup, OSSL_NELEM(name_dup_algs));      ADD_TEST(test_evp_pkey_get_bn_param_large);      ADD_TEST(test_fromdata_rsa);  #ifndef OPENSSL_NO_DH diff --git a/test/evp_test.c b/test/evp_test.c index 2701040dabe7..020a5d55013e 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -1,5 +1,5 @@  /* - * Copyright 2015-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -352,8 +352,10 @@ static int digest_test_init(EVP_TEST *t, const char *alg)      if ((digest = fetched_digest = EVP_MD_fetch(libctx, alg, NULL)) == NULL          && (digest = EVP_get_digestbyname(alg)) == NULL)          return 0; -    if (!TEST_ptr(mdat = OPENSSL_zalloc(sizeof(*mdat)))) +    if (!TEST_ptr(mdat = OPENSSL_zalloc(sizeof(*mdat)))) { +        EVP_MD_free(fetched_digest);          return 0; +    }      t->data = mdat;      mdat->digest = digest;      mdat->fetched_digest = fetched_digest; @@ -3960,7 +3962,9 @@ static int run_file_tests(int i)      clear_test(t);      free_key_list(public_keys); +    public_keys = NULL;      free_key_list(private_keys); +    private_keys = NULL;      BIO_free(t->s.key);      c = t->s.errors;      OPENSSL_free(t); diff --git a/test/fake_rsaprov.c b/test/fake_rsaprov.c index be08bfd39981..12698a95a704 100644 --- a/test/fake_rsaprov.c +++ b/test/fake_rsaprov.c @@ -1,5 +1,5 @@  /* - * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License");   * you may not use this file except in compliance with the License. @@ -31,6 +31,8 @@ static int imptypes_selection;  static int exptypes_selection;  static int query_id; +unsigned fake_rsa_query_operation_name = 0; +  struct fake_rsa_keydata {      int selection;      int status; @@ -71,7 +73,7 @@ static const char *fake_rsa_keymgmt_query(int id)      /* record global for checking */      query_id = id; -    return "RSA"; +    return fake_rsa_query_operation_name ? NULL: "RSA";  }  static int fake_rsa_keymgmt_import(void *keydata, int selection, diff --git a/test/fake_rsaprov.h b/test/fake_rsaprov.h index 190c46a285c0..841b5f4c4e97 100644 --- a/test/fake_rsaprov.h +++ b/test/fake_rsaprov.h @@ -1,5 +1,5 @@  /* - * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -12,4 +12,13 @@  /* Fake RSA provider implementation */  OSSL_PROVIDER *fake_rsa_start(OSSL_LIB_CTX *libctx);  void fake_rsa_finish(OSSL_PROVIDER *p); +  OSSL_PARAM *fake_rsa_key_params(int priv); + +/* + * When fake_rsa_query_operation_name is set to a non-zero value, + * query_operation_name() will return NULL. + * + * By default, it is 0, in which case query_operation_name() will return "RSA". + */ +extern unsigned fake_rsa_query_operation_name; diff --git a/test/nocache-and-default.cnf b/test/nocache-and-default.cnf new file mode 100644 index 000000000000..cf5ca8d11415 --- /dev/null +++ b/test/nocache-and-default.cnf @@ -0,0 +1,18 @@ +openssl_conf = openssl_init + +# Comment out the next line to ignore configuration errors +config_diagnostics = 1 + +[openssl_init] +providers = provider_sect + +[provider_sect] +test    = test_sect +default = default_sect + +[test_sect] +module = ../test/p_test.so +activate = true + +[default_sect] +activate = true diff --git a/test/params_api_test.c b/test/params_api_test.c index 48e2f8920aa2..9c68825de216 100644 --- a/test/params_api_test.c +++ b/test/params_api_test.c @@ -1,5 +1,5 @@  /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.   * Copyright (c) 2019, Oracle and/or its affiliates.  All rights reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use @@ -692,6 +692,33 @@ static int test_param_copy_null(void)      OSSL_PARAM_free(cp1);      return ret;  } +static int test_param_merge(void) +{ +    int val, ret; +    int values[] = {1, 2, 3, 4}; +    OSSL_PARAM *p = NULL, *cp = NULL; +    OSSL_PARAM param[3], param1[3]; + +    param[0] = OSSL_PARAM_construct_int("diff1", &values[0]); +    param[1] = OSSL_PARAM_construct_int("same", &values[1]); +    param[2] = OSSL_PARAM_construct_end(); +    param1[0] = OSSL_PARAM_construct_int("diff2", &values[2]); +    param1[1] = OSSL_PARAM_construct_int("same", &values[3]); +    param1[2] = OSSL_PARAM_construct_end(); + +    ret = TEST_ptr(p = OSSL_PARAM_merge(param, param1)) +        && TEST_ptr(cp = OSSL_PARAM_locate(p, "diff1")) +        && TEST_true(OSSL_PARAM_get_int(p, &val)) +        && TEST_int_eq(val, values[0]) +        && TEST_ptr(cp = OSSL_PARAM_locate(p, "diff2")) +        && TEST_true(OSSL_PARAM_get_int(cp, &val)) +        && TEST_int_eq(val, values[2]) +        && TEST_ptr(cp = OSSL_PARAM_locate(p, "same")) +        && TEST_true(OSSL_PARAM_get_int(cp, &val)) +        && TEST_int_eq(val, values[3]); +    OSSL_PARAM_free(p); +    return ret; +}  int setup_tests(void)  { @@ -710,5 +737,6 @@ int setup_tests(void)      ADD_ALL_TESTS(test_param_construct, 4);      ADD_TEST(test_param_modified);      ADD_TEST(test_param_copy_null); +    ADD_TEST(test_param_merge);      return 1;  } diff --git a/test/property_test.c b/test/property_test.c index 1f1171ad90a6..f3fd0291b980 100644 --- a/test/property_test.c +++ b/test/property_test.c @@ -665,6 +665,22 @@ static int test_property_list_to_string(int i)      return ret;  } +static int test_property_list_to_string_bounds(void) +{ +    OSSL_PROPERTY_LIST *pl = NULL; +    char buf[16]; +    int ret = 0; + +    if (!TEST_ptr(pl = ossl_parse_query(NULL, "provider='$1'", 1))) +        goto err; +    if (!TEST_size_t_eq(ossl_property_list_to_string(NULL, pl, buf, 10), 14)) +        goto err; +    ret = 1; + err: +    ossl_property_free(pl); +    return ret; +} +  int setup_tests(void)  {      ADD_TEST(test_property_string); @@ -679,5 +695,6 @@ int setup_tests(void)      ADD_TEST(test_query_cache_stochastic);      ADD_TEST(test_fips_mode);      ADD_ALL_TESTS(test_property_list_to_string, OSSL_NELEM(to_string_tests)); +    ADD_TEST(test_property_list_to_string_bounds);      return 1;  } diff --git a/test/provider_pkey_test.c b/test/provider_pkey_test.c index 249e9babcfa8..3d5f29756f59 100644 --- a/test/provider_pkey_test.c +++ b/test/provider_pkey_test.c @@ -1,5 +1,5 @@  /* - * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -237,6 +237,77 @@ end:      return ret;  } +static int test_pkey_can_sign(void) +{ +    OSSL_PROVIDER *fake_rsa = NULL; +    EVP_PKEY *pkey_fake = NULL; +    EVP_PKEY_CTX *ctx = NULL; +    OSSL_PARAM *params = NULL; +    int ret = 0; + +    if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) +        return 0; + +    /* +     * Ensure other tests did not forget to reset fake_rsa_query_operation_name +     * to its default value: 0 +     */ +    if (!TEST_int_eq(fake_rsa_query_operation_name, 0)) +        goto end; + +    if (!TEST_ptr(params = fake_rsa_key_params(0)) +        || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", +                                                      "provider=fake-rsa")) +        || !TEST_true(EVP_PKEY_fromdata_init(ctx)) +        || !TEST_true(EVP_PKEY_fromdata(ctx, &pkey_fake, EVP_PKEY_PUBLIC_KEY, +                                        params)) +        || !TEST_true(EVP_PKEY_can_sign(pkey_fake)) +        || !TEST_ptr(pkey_fake)) +        goto end; + +    EVP_PKEY_CTX_free(ctx); +    ctx = NULL; +    EVP_PKEY_free(pkey_fake); +    pkey_fake = NULL; +    OSSL_PARAM_free(params); +    params = NULL; + +    /* +     * Documented behavior for OSSL_FUNC_keymgmt_query_operation_name() +     * allows it to return NULL, in which case the fallback should be to use +     * EVP_KEYMGMT_get0_name(). That is exactly the thing we are testing here. +     */ +    fake_rsa_query_operation_name = 1; + +    if (!TEST_ptr(params = fake_rsa_key_params(0)) +        || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", +                                                      "provider=fake-rsa")) +        || !TEST_true(EVP_PKEY_fromdata_init(ctx)) +        || !TEST_true(EVP_PKEY_fromdata(ctx, &pkey_fake, EVP_PKEY_PUBLIC_KEY, +                                        params)) +        || !TEST_true(EVP_PKEY_can_sign(pkey_fake)) +        || !TEST_ptr(pkey_fake)) +        goto end; + +    EVP_PKEY_CTX_free(ctx); +    ctx = NULL; +    EVP_PKEY_free(pkey_fake); +    pkey_fake = NULL; +    OSSL_PARAM_free(params); +    params = NULL; + +    ret = 1; +end: + +    EVP_PKEY_CTX_free(ctx); +    EVP_PKEY_free(pkey_fake); +    OSSL_PARAM_free(params); +    fake_rsa_query_operation_name = 0; + +    fake_rsa_finish(fake_rsa); +    return ret; +} +  static int test_pkey_store(int idx)  {      OSSL_PROVIDER *deflt = NULL; @@ -297,6 +368,7 @@ int setup_tests(void)      ADD_TEST(test_pkey_sig);      ADD_TEST(test_alternative_keygen_init);      ADD_TEST(test_pkey_eq); +    ADD_TEST(test_pkey_can_sign);      ADD_ALL_TESTS(test_pkey_store, 2);      return 1; diff --git a/test/rand_test.c b/test/rand_test.c index c6cf32610eb3..7d7af4c6bf40 100644 --- a/test/rand_test.c +++ b/test/rand_test.c @@ -1,5 +1,5 @@  /* - * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the >License>).  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -19,6 +19,7 @@ static int test_rand(void)      OSSL_PARAM params[2], *p = params;      unsigned char entropy1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };      unsigned char entropy2[] = { 0xff, 0xfe, 0xfd }; +    unsigned char nonce[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };      unsigned char outbuf[3];      *p++ = OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY, @@ -41,6 +42,14 @@ static int test_rand(void)              || !TEST_int_gt(RAND_priv_bytes(outbuf, sizeof(outbuf)), 0)              || !TEST_mem_eq(outbuf, sizeof(outbuf), entropy2, sizeof(outbuf)))          return 0; + +    *params = OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_NONCE, +                                                nonce, sizeof(nonce)); +    if (!TEST_true(EVP_RAND_CTX_set_params(privctx, params)) +            || !TEST_true(EVP_RAND_nonce(privctx, outbuf, sizeof(outbuf))) +            || !TEST_mem_eq(outbuf, sizeof(outbuf), nonce, sizeof(outbuf))) +        return 0; +      return 1;  } diff --git a/test/recipes/15-test_ec.t b/test/recipes/15-test_ec.t index 0638d626e744..b010a43ee384 100644 --- a/test/recipes/15-test_ec.t +++ b/test/recipes/15-test_ec.t @@ -1,5 +1,5 @@  #! /usr/bin/env perl -# Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved.  #  # Licensed under the Apache License 2.0 (the "License").  You may not use  # this file except in compliance with the License.  You can obtain a copy @@ -18,7 +18,7 @@ setup("test_ec");  plan skip_all => 'EC is not supported in this build' if disabled('ec'); -plan tests => 15; +plan tests => 16;  my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0); @@ -33,6 +33,16 @@ subtest 'EC conversions -- private key' => sub {      tconversion( -type => 'ec', -prefix => 'ec-priv',                   -in => srctop_file("test","testec-p256.pem") );  }; + +SKIP: { +    skip "SM2 is not supported by this OpenSSL build", 1 +        if disabled("sm2"); +    subtest 'EC conversions -- private key' => sub { +        tconversion( -type => 'ec', -prefix => 'sm2-priv', +                     -in => srctop_file("test","testec-sm2.pem") ); +    }; +} +  subtest 'EC conversions -- private key PKCS#8' => sub {      tconversion( -type => 'ec', -prefix => 'ec-pkcs8',                   -in => srctop_file("test","testec-p256.pem"), diff --git a/test/recipes/15-test_ecparam.t b/test/recipes/15-test_ecparam.t index 37bf620f35ee..feb16904f2df 100644 --- a/test/recipes/15-test_ecparam.t +++ b/test/recipes/15-test_ecparam.t @@ -1,5 +1,5 @@  #! /usr/bin/env perl -# Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved.  #  # Licensed under the Apache License 2.0 (the "License").  You may not use  # this file except in compliance with the License.  You can obtain a copy @@ -25,6 +25,10 @@ my @valid = glob(data_file("valid", "*.pem"));  my @noncanon = glob(data_file("noncanon", "*.pem"));  my @invalid = glob(data_file("invalid", "*.pem")); +if (disabled("sm2")) { +    @valid = grep { !/sm2-.*\.pem/} @valid; +} +  plan tests => 12;  sub checkload { diff --git a/test/recipes/15-test_ecparam_data/valid/sm2-explicit.pem b/test/recipes/15-test_ecparam_data/valid/sm2-explicit.pem new file mode 100644 index 000000000000..bd07654ea457 --- /dev/null +++ b/test/recipes/15-test_ecparam_data/valid/sm2-explicit.pem @@ -0,0 +1,7 @@ +-----BEGIN SM2 PARAMETERS----- +MIHgAgEBMCwGByqGSM49AQECIQD////+/////////////////////wAAAAD///// +/////zBEBCD////+/////////////////////wAAAAD//////////AQgKOn6np2f +XjRNWp5Lz2UJp/OXifUVq4+S3by9QU2UDpMEQQQyxK4sHxmBGV+ZBEZqOcmUj+ML +v/JmC+FxWkWJM0x0x7w3NqL09necWb3O42tpIVPQqYd8xipHQALfMuUhOfCgAiEA +/////v///////////////3ID32shxgUrU7v0CTnVQSMCAQE= +-----END SM2 PARAMETERS----- diff --git a/test/recipes/15-test_ecparam_data/valid/sm2-named.pem b/test/recipes/15-test_ecparam_data/valid/sm2-named.pem new file mode 100644 index 000000000000..d6e280f6c25e --- /dev/null +++ b/test/recipes/15-test_ecparam_data/valid/sm2-named.pem @@ -0,0 +1,3 @@ +-----BEGIN SM2 PARAMETERS----- +BggqgRzPVQGCLQ== +-----END SM2 PARAMETERS----- diff --git a/test/recipes/20-test_nocache.t b/test/recipes/20-test_nocache.t new file mode 100644 index 000000000000..f7a956ee05ef --- /dev/null +++ b/test/recipes/20-test_nocache.t @@ -0,0 +1,34 @@ +#! /usr/bin/env perl +# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License").  You may not use +# this file except in compliance with the License.  You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use OpenSSL::Test qw/:DEFAULT bldtop_file srctop_file bldtop_dir with/; +use OpenSSL::Test::Utils; + +setup("test_nocache"); + +plan tests => 4; + +ok(run(app(["openssl", "list", "-mac-algorithms"], +        stdout => "listout.txt")), +"List mac algorithms - default configuration"); +open DATA, "listout.txt"; +my @match = grep /MAC/, <DATA>; +close DATA; +ok(scalar @match > 1 ? 1 : 0, "Several algorithms are listed - default configuration"); + +$ENV{OPENSSL_CONF} = bldtop_file("test", "nocache-and-default.cnf"); +ok(run(app(["openssl", "list", "-mac-algorithms"], +        stdout => "listout.txt")), +"List mac algorithms"); +open DATA, "listout.txt"; +my @match = grep /MAC/, <DATA>; +close DATA; +ok(scalar @match > 1 ? 1 : 0, "Several algorithms are listed - nocache-and-default"); diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t index 7fa14d9daa8b..19c528f0b89a 100644 --- a/test/recipes/25-test_verify.t +++ b/test/recipes/25-test_verify.t @@ -1,5 +1,5 @@  #! /usr/bin/env perl -# Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved.  #  # Licensed under the Apache License 2.0 (the "License").  You may not use  # this file except in compliance with the License.  You can obtain a copy @@ -10,6 +10,7 @@  use strict;  use warnings; +use Cwd qw(abs_path);  use File::Spec::Functions qw/canonpath/;  use File::Copy;  use OpenSSL::Test qw/:DEFAULT srctop_file bldtop_dir ok_nofips with/; @@ -17,19 +18,19 @@ use OpenSSL::Test::Utils;  setup("test_verify"); +my @certspath = qw(test certs);  sub verify {      my ($cert, $purpose, $trusted, $untrusted, @opts) = @_; -    my @path = qw(test certs);      my @args = qw(openssl verify -auth_level 1);      push(@args, "-purpose", $purpose) if $purpose ne "";      push(@args, @opts); -    for (@$trusted) { push(@args, "-trusted", srctop_file(@path, "$_.pem")) } -    for (@$untrusted) { push(@args, "-untrusted", srctop_file(@path, "$_.pem")) } -    push(@args, srctop_file(@path, "$cert.pem")); +    for (@$trusted) { push(@args, "-trusted", srctop_file(@certspath, "$_.pem")) } +    for (@$untrusted) { push(@args, "-untrusted", srctop_file(@certspath, "$_.pem")) } +    push(@args, srctop_file(@certspath, "$cert.pem"));      run(app([@args]));  } -plan tests => 166; +plan tests => 175;  # Canonical success  ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]), @@ -527,3 +528,32 @@ ok(!verify("ee-cert-policies-bad", "", ["root-cert"], ["ca-pol-cert"],             "-policy_check", "-policy", "1.3.6.1.4.1.16604.998855.1",             "-explicit_policy"),     "Bad certificate policy"); + +# CAstore option +my $rootcertname = "root-cert"; +my $rootcert = srctop_file(@certspath, "${rootcertname}.pem"); +sub vfy_root { verify($rootcertname, "", [], [], @_) } +ok(vfy_root("-CAfile", $rootcert), "CAfile"); +ok(vfy_root("-CAstore", $rootcert), "CAstore"); +ok(vfy_root("-CAstore", $rootcert, "-CAfile", $rootcert), "CAfile and existing CAstore"); +ok(!vfy_root("-CAstore", "non-existing", "-CAfile", $rootcert), "CAfile and non-existing CAstore"); + +SKIP: { +    skip "file names with colons aren't supported on Windows and VMS", 1 +        if $^O =~ /^(MSWin32|VMS)$/; +    my $foo_file = "foo:cert.pem"; +    copy($rootcert, $foo_file); +    ok(vfy_root("-CAstore", $foo_file), "CAstore foo:file"); +} +my $foo_file = "cert.pem"; +copy($rootcert, $foo_file); +ok(vfy_root("-CAstore", $foo_file), "CAstore file"); +my $abs_cert = abs_path($rootcert); +# Windows file: URIs should have a path part starting with a slash, i.e. +# file://authority/C:/what/ever/foo.pem and file:///C:/what/ever/foo.pem +# file://C:/what/ever/foo.pem is non-standard and may not be accepted. +# See RFC 8089 for details. +$abs_cert = "/" . $abs_cert if ($^O eq "MSWin32"); +ok(vfy_root("-CAstore", "file://".$abs_cert), "CAstore file:///path"); +ok(vfy_root("-CAstore", "file://localhost".$abs_cert), "CAstore file://localhost/path"); +ok(!vfy_root("-CAstore", "file://otherhost".$abs_cert), "CAstore file://otherhost/path"); diff --git a/test/recipes/30-test_evp_data/evpkdf_krb5.txt b/test/recipes/30-test_evp_data/evpkdf_krb5.txt index d8f6aa72a175..e2de4754fa74 100644 --- a/test/recipes/30-test_evp_data/evpkdf_krb5.txt +++ b/test/recipes/30-test_evp_data/evpkdf_krb5.txt @@ -1,5 +1,5 @@  # -# Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved.  #  # Licensed under the Apache License 2.0 (the "License").  You may not use  # this file except in compliance with the License.  You can obtain a copy @@ -129,3 +129,11 @@ Ctrl.cipher = cipher:DES-EDE3-CBC  Ctrl.hexkey = hexkey:dce06b1f64c857a11c3db57c51899b2cc1791008ce973b92  Ctrl.hexconstant = hexconstant:0000000155  Output = 935079d14490a75c3093c4a6e8c3b049c71e6ee705 + +#Erroneous key size for the cipher as XTS has double key size +KDF = KRB5KDF +Ctrl.cipher = cipher:AES-256-XTS +Ctrl.hexkey = hexkey:FE697B52BC0D3CE14432BA036A92E65BBB52280990A2FA27883998D72AF30161 +Ctrl.hexconstant = hexconstant:0000000255 +Output = 97151B4C76945063E2EB0529DC067D97D7BBA90776D8126D91F34F3101AEA8BA +Result = KDF_DERIVE_ERROR diff --git a/test/recipes/61-test_bio_pw_callback.t b/test/recipes/61-test_bio_pw_callback.t new file mode 100644 index 000000000000..4cb1db1f589f --- /dev/null +++ b/test/recipes/61-test_bio_pw_callback.t @@ -0,0 +1,20 @@ +#! /usr/bin/env perl +# Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License").  You may not use +# this file except in compliance with the License.  You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use OpenSSL::Test qw(:DEFAULT data_file); + +setup('test_bio_pw_callback'); + +plan tests => 1; + +my $private_key_path = data_file("private_key.pem"); +ok(run(test(["bio_pw_callback_test", "-keyfile", $private_key_path])), +   "Running bio_pw_callback_test"); diff --git a/test/recipes/61-test_bio_pw_callback_data/private_key.pem b/test/recipes/61-test_bio_pw_callback_data/private_key.pem new file mode 100644 index 000000000000..f9c9ae5dbc4a --- /dev/null +++ b/test/recipes/61-test_bio_pw_callback_data/private_key.pem @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQmftpln/ZNiEznncq ++u0FuwICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEBO5TGcD0mGTfRS8 +HgafEXYEggTQOasEXPm4ChGPzfXACYhaAtMFnfL9qpI1S30bHMUHsWuXLZDFPNty +7KNKWr35woaq3XFEeul7onszcBBRrRwPkTqOifuv/J01s7oS0uC6jwbvSkAFNjHe +jkgvMMQA3y7nwZ2wSwVjO2K91qasTjNivus3ZaCvGqGpgNckEXILPZJEdWteWP+1 +SN9zLxxeHwgt5SrMfylrTghLB8b119/uq4GnOYHZdhMbp4YmneuGqvlZ7nle7qLY +33tuM5deajk9hINLfbYWGwURaOZ+r++Rvrz4OxISfe70uXT+2fcSZPVkNT5a6B5T +9rCwdF69W/+3au50gfc2VEF/xZBajxLI0PBpMSpxNE3a5/3YLKXAs+z0YJdQKNhN +U+SpOUv8D2GraJVfP7MddO2JvETh8w7tGN/a8qSw07Z91SE3Vfuq0l5PheC/vXJq +/xxU3YSbZC7LCSZn1aXBlj9KbTh2o1ARzdJsVYo1xY2OIFtFpncOjQDuaAmsNcZE +CuB9FUcBwwO/bjooIkv4lJU+DWDxrCR7Si8PZ4hHgXCXXKiXA20SBccUYm0Z4HR3 +i2tm9UTwAuCy1BF7hRmPLIyvlgtlKh2V9Cre5j86GoKTmPh/q5DHdSmNAM8Aakct +GdQgscOXRmHq7/1nec28wEhlbqVyYJ45MZbWhBTrycMru/ch9+ZnsIgPXLfbBA+P +6GHK1DF+onKZtMkH0SNMU3X1arlJKRreVQsvkbgL7aw3mI0veYa4/tJUf7hbkPpA +LArQU5wQ+A9mzC+tYMfz3mrIE05FrpYkHRxiB/odeNvCTMR7DhGoghhnYUN/gSSN +qH5EBG2hQ/pJ5ZSawE+P9+vCLlvcc4n00zgi0s3rMN2AntPZoI3sWKZcbbgJoOIH +cbAmBAKCIiwmlPmI0hjEAIXRBixJzHVGNowuSc3jy5pIiSjmDESnARl+n5imqI3D +po9OuCHpo4nRLcAX0GrJqqKxUG+R1A8g/AooIGEPQgkXk/4v9gwd4aBvwT4YxR44 +onAXdyBMM0T8C+8dUmT6OPvU5w6JHFidJfhBgJhDIdj9JM+wWdr1CW94todjEyKY +Xe3NRG1bGbcN6HBVwbe4UZ39A9p4kKGyiXexlsD+DvFxwaGvSy2rp0lLabz19Kkr +fnLU1Ugb38AnEYTGYJMB9nO19lHW62Mk6+9ky42x8X9vBn81Nif/c0kmvEKsZEfw +UM7m0fIWTZOWSH01DGIXqCoCk7vJ1CSm0wUsAvyKFLm1qnM5eJJNMlBbayDDBsnU +Jj9hx7GWjujVKFwFngUOoFpmFWB72bqeBWenaQJhIVydQa1rolny0TECJIkFOsUK +Wa0y52V4h68Ig5G5p2WHG0RlEVtmcgzSoL1mLE5UdOYaH5oB7nTVM+Z0b8HJFrYc +7Xhym8uNq6UHc4Ae6TT8EA3lA3fDttedKzWxlBFXqX9behl2uBnPzCl3cS2G2Uek +xtexjecZINP8L5i6eIL7bPoVMF5CUsUhIWFA0gzIovRBRvVS91HnTrIDLvqF8YgQ +ToctUU/vS8r3x2/TIR60UBvW0vkoFa+lfzHtsxBnT1nMBZNeeHOCM8QtboyI9Ir9 +UkJbTO+QpJQ5A3ELharpcqr7iywDOnLSV9LZSUZr934zOrRl2oAXx/0= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/test/recipes/70-test_tls13downgrade.t b/test/recipes/70-test_tls13downgrade.t index 9e10a9c9c4ca..f40bd5f7036b 100644 --- a/test/recipes/70-test_tls13downgrade.t +++ b/test/recipes/70-test_tls13downgrade.t @@ -1,5 +1,5 @@  #! /usr/bin/env perl -# Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved.  #  # Licensed under the Apache License 2.0 (the "License").  You may not use  # this file except in compliance with the License.  You can obtain a copy @@ -24,9 +24,8 @@ plan skip_all => "$test_name needs the sock feature enabled"      if disabled("sock");  plan skip_all => "$test_name needs TLS1.3 and TLS1.2 enabled" -    if disabled("tls1_3") -       || (disabled("ec") && disabled("dh")) -       || disabled("tls1_2"); +    if disabled("tls1_3") || disabled("tls1_2") +        || (disabled("ec") && disabled("dh"));  $ENV{OPENSSL_ia32cap} = '~0x200000200000000'; @@ -41,89 +40,150 @@ use constant {      DOWNGRADE_TO_TLS_1_2 => 0,      DOWNGRADE_TO_TLS_1_1 => 1,      FALLBACK_FROM_TLS_1_3 => 2, +    DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL => 3, +    DOWNGRADE_TO_TLS_1_1_WITH_TLS_1_2_SIGNAL => 4,  };  #Test 1: Downgrade from TLSv1.3 to TLSv1.2  $proxy->filter(\&downgrade_filter);  my $testtype = DOWNGRADE_TO_TLS_1_2;  $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 6; -ok(TLSProxy::Message->fail(), "Downgrade TLSv1.3 to TLSv1.2"); +plan tests => 8; +ok(is_illegal_parameter_client_alert(), "Downgrade TLSv1.3 to TLSv1.2"); -#Test 2: Downgrade from TLSv1.3 to TLSv1.1 +#Test 2: Downgrade from TLSv1.3 to TLSv1.2 (server sends TLSv1.1 signal)  $proxy->clear(); -$testtype = DOWNGRADE_TO_TLS_1_1; +$testtype = DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL;  $proxy->start(); -ok(TLSProxy::Message->fail(), "Downgrade TLSv1.3 to TLSv1.1"); +ok(is_illegal_parameter_client_alert(), +   "Downgrade from TLSv1.3 to TLSv1.2 (server sends TLSv1.1 signal)"); -#Test 3: Downgrade from TLSv1.2 to TLSv1.1 -$proxy->clear(); -$proxy->clientflags("-no_tls1_3"); -$proxy->serverflags("-no_tls1_3"); -$proxy->start(); -ok(TLSProxy::Message->fail(), "Downgrade TLSv1.2 to TLSv1.1"); - -#Test 4: Client falls back from TLSv1.3 (server does not support the fallback +#Test 3: Client falls back from TLSv1.3 (server does not support the fallback  #        SCSV)  $proxy->clear();  $testtype = FALLBACK_FROM_TLS_1_3;  $proxy->clientflags("-fallback_scsv -no_tls1_3");  $proxy->start(); -my $alert = TLSProxy::Message->alert(); -ok(TLSProxy::Message->fail() -   && !$alert->server() -   && $alert->description() == TLSProxy::Message::AL_DESC_ILLEGAL_PARAMETER, -   "Fallback from TLSv1.3"); +ok(is_illegal_parameter_client_alert(), "Fallback from TLSv1.3");  SKIP: { -    skip "TLSv1.1 disabled", 2 if disabled("tls1_1"); -    #Test 5: A client side protocol "hole" should not be detected as a downgrade +    skip "TLSv1.1 disabled", 5 if disabled("tls1_1"); + +    my $client_flags = "-min_protocol TLSv1.1 -cipher DEFAULT:\@SECLEVEL=0"; +    my $server_flags = "-min_protocol TLSv1.1"; +    my $ciphers = "AES128-SHA:\@SECLEVEL=0"; + +    #Test 4: Downgrade from TLSv1.3 to TLSv1.1 +    $proxy->clear(); +    $testtype = DOWNGRADE_TO_TLS_1_1; +    $proxy->clientflags($client_flags); +    $proxy->serverflags($server_flags); +    $proxy->ciphers($ciphers); +    $proxy->start(); +    ok(is_illegal_parameter_client_alert(), "Downgrade TLSv1.3 to TLSv1.1"); + +    #Test 5: Downgrade from TLSv1.3 to TLSv1.1 (server sends TLSv1.2 signal) +    $proxy->clear(); +    $testtype = DOWNGRADE_TO_TLS_1_1_WITH_TLS_1_2_SIGNAL; +    $proxy->clientflags($client_flags); +    $proxy->serverflags($server_flags); +    $proxy->ciphers($ciphers); +    $proxy->start(); +    ok(is_illegal_parameter_client_alert(), +       "Downgrade TLSv1.3 to TLSv1.1 (server sends TLSv1.2 signal)"); + +    #Test 6: Downgrade from TLSv1.2 to TLSv1.1 +    $proxy->clear(); +    $testtype = DOWNGRADE_TO_TLS_1_1; +    $proxy->clientflags($client_flags." -max_protocol TLSv1.2"); +    $proxy->serverflags($server_flags." -max_protocol TLSv1.2"); +    $proxy->ciphers($ciphers); +    $proxy->start(); +    ok(is_illegal_parameter_client_alert(), "Downgrade TLSv1.2 to TLSv1.1"); + +    #Test 7: A client side protocol "hole" should not be detected as a downgrade      $proxy->clear();      $proxy->filter(undef); -    $proxy->clientflags("-no_tls1_2"); -    $proxy->ciphers("AES128-SHA:\@SECLEVEL=0"); +    $proxy->clientflags($client_flags." -no_tls1_2"); +    $proxy->serverflags($server_flags); +    $proxy->ciphers($ciphers);      $proxy->start();      ok(TLSProxy::Message->success(), "TLSv1.2 client-side protocol hole"); -    #Test 6: A server side protocol "hole" should not be detected as a downgrade +    #Test 8: A server side protocol "hole" should not be detected as a downgrade      $proxy->clear();      $proxy->filter(undef); -    $proxy->serverflags("-no_tls1_2"); +    $proxy->clientflags($client_flags); +    $proxy->serverflags($server_flags." -no_tls1_2"); +    $proxy->ciphers($ciphers);      $proxy->start();      ok(TLSProxy::Message->success(), "TLSv1.2 server-side protocol hole");  } +# Validate that the exchange fails with an illegal parameter alert from +#  the client +sub is_illegal_parameter_client_alert +{ +    return 0 unless TLSProxy::Message->fail(); +    my $alert = TLSProxy::Message->alert(); +    return 1 if !$alert->server() +                && $alert->description() +                   == TLSProxy::Message::AL_DESC_ILLEGAL_PARAMETER; +    return 0; +} +  sub downgrade_filter  {      my $proxy = shift; -    # We're only interested in the initial ClientHello -    if ($proxy->flight != 0) { +    # We're only interested in the initial ClientHello and ServerHello +    if ($proxy->flight > 1) {          return;      } -    my $message = ${$proxy->message_list}[0]; - -    my $ext; -    if ($testtype == FALLBACK_FROM_TLS_1_3) { -        #The default ciphersuite we use for TLSv1.2 without any SCSV -        my @ciphersuites = (TLSProxy::Message::CIPHER_RSA_WITH_AES_128_CBC_SHA); -        $message->ciphersuite_len(2 * scalar @ciphersuites); -        $message->ciphersuites(\@ciphersuites); -    } else { -        if ($testtype == DOWNGRADE_TO_TLS_1_2) { -            $ext = pack "C3", -                0x02, # Length -                0x03, 0x03; #TLSv1.2 -        } else { -            $ext = pack "C3", -                0x02, # Length -                0x03, 0x02; #TLSv1.1 +    my $message = ${$proxy->message_list}[$proxy->flight]; + +    # ServerHello +    if ($proxy->flight == 1 && defined($message)) { +        # Update the last byte of the downgrade signal +        if ($testtype == DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL) { +            $message->random(substr($message->random, 0, 31) . "\0"); +            $message->repack(); +        } elsif ($testtype == DOWNGRADE_TO_TLS_1_1_WITH_TLS_1_2_SIGNAL) { +            $message->random(substr($message->random, 0, 31) . "\1"); +            $message->repack();          } -        $message->set_extension(TLSProxy::Message::EXT_SUPPORTED_VERSIONS, $ext); +        return;      } -    $message->repack(); +    # ClientHello +    if ($proxy->flight == 0) { +        my $ext; +        if ($testtype == FALLBACK_FROM_TLS_1_3) { +            #The default ciphersuite we use for TLSv1.2 without any SCSV +            my @ciphersuites = (TLSProxy::Message::CIPHER_RSA_WITH_AES_128_CBC_SHA); +            $message->ciphersuite_len(2 * scalar @ciphersuites); +            $message->ciphersuites(\@ciphersuites); +        } +        else { +            if ($testtype == DOWNGRADE_TO_TLS_1_2 +                || $testtype == DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL) { +                $ext = pack "C3", +                    0x02,       # Length +                    0x03, 0x03; #TLSv1.2 +            } +            else { +                $ext = pack "C3", +                    0x02,       # Length +                    0x03, 0x02; #TLSv1.1 +            } + +            $message->set_extension(TLSProxy::Message::EXT_SUPPORTED_VERSIONS, +                                    $ext); +        } + +        $message->repack(); +    }  } diff --git a/test/recipes/80-test_ca.t b/test/recipes/80-test_ca.t index eb025f4d591f..c477df3929e7 100644 --- a/test/recipes/80-test_ca.t +++ b/test/recipes/80-test_ca.t @@ -1,5 +1,5 @@  #! /usr/bin/env perl -# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved.  #  # Licensed under the Apache License 2.0 (the "License").  You may not use  # this file except in compliance with the License.  You can obtain a copy @@ -21,9 +21,7 @@ setup("test_ca");  $ENV{OPENSSL} = cmdstr(app(["openssl"]), display => 1);  my $cnf = srctop_file("test","ca-and-certs.cnf"); -my $std_openssl_cnf = '"' -    . srctop_file("apps", $^O eq "VMS" ? "openssl-vms.cnf" : "openssl.cnf") -    . '"'; +my $std_openssl_cnf = srctop_file("apps", $^O eq "VMS" ? "openssl-vms.cnf" : "openssl.cnf");  rmtree("demoCA", { safe => 0 }); @@ -33,14 +31,14 @@ plan tests => 15;       $ENV{OPENSSL_CONFIG} = qq(-config "$cnf");       skip "failed creating CA structure", 4           if !ok(run(perlapp(["CA.pl","-newca", -                             "-extra-req", "-key $cakey"], stdin => undef)), +                             "-extra-req", qq{-key "$cakey"}], stdin => undef)),                  'creating CA structure');       my $eekey = srctop_file("test", "certs", "ee-key.pem");       $ENV{OPENSSL_CONFIG} = qq(-config "$cnf");       skip "failed creating new certificate request", 3           if !ok(run(perlapp(["CA.pl","-newreq", -                             '-extra-req', "-outform DER -section userreq -key $eekey"])), +                             '-extra-req', qq{-outform DER -section userreq -key "$eekey"}])),                  'creating certificate request');       $ENV{OPENSSL_CONFIG} = qq(-rand_serial -inform DER -config "$std_openssl_cnf");       skip "failed to sign certificate request", 2 @@ -55,7 +53,8 @@ plan tests => 15;       my $eekey2 = srctop_file("test", "certs", "ee-key-3072.pem");       $ENV{OPENSSL_CONFIG} = qq(-config "$cnf"); -     ok(run(perlapp(["CA.pl", "-precert", '-extra-req', "-section userreq -key $eekey2"], stderr => undef)), +     ok(run(perlapp(["CA.pl", "-precert", +                     '-extra-req', qq{-section userreq -key "$eekey2"}], stderr => undef)),          'creating new pre-certificate');  } diff --git a/test/recipes/80-test_cmp_http.t b/test/recipes/80-test_cmp_http.t index c704cc758e91..8ea33d90c09f 100644 --- a/test/recipes/80-test_cmp_http.t +++ b/test/recipes/80-test_cmp_http.t @@ -274,6 +274,7 @@ sub start_mock_server {      print "Pid is: $pid\n";      if ($server_port == 0) {          # Find out the actual server port +        my $pid0 = $pid;          while (<$server_fh>) {              print "Server output: $_";              next if m/using section/; @@ -281,6 +282,11 @@ sub start_mock_server {              ($server_port, $pid) = ($1, $2) if /^ACCEPT\s.*:(\d+) PID=(\d+)$/;              last; # Do not loop further to prevent hangs on server misbehavior          } +        if ($pid0 != $pid) { +            # kill the shell process +            kill('KILL', $pid0); +            waitpid($pid0, 0); +        }      }      unless ($server_port > 0) {          stop_mock_server($pid); diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t index 0e8b0259f1c2..8c58152759e7 100644 --- a/test/recipes/80-test_cms.t +++ b/test/recipes/80-test_cms.t @@ -83,6 +83,15 @@ my @smime_pkcs7_tests = (        \&final_compare      ], +    [ "signed text content DER format, RSA key", +      [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach", +        "-certfile", $smroot, "-signer", $smrsa1, "-text", +        "-out", "{output}.cms" ], +      [ "{cmd2}",  @prov, "-verify", "-in", "{output}.cms", "-inform", "DER", +        "-text", "-CAfile", $smroot, "-out", "{output}.txt" ], +      \&final_compare +    ], +      [ "signed detached content DER format, RSA key",        [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",          "-signer", $smrsa1, "-out", "{output}.cms" ], @@ -216,6 +225,14 @@ my @smime_pkcs7_tests = (        \&final_compare      ], +    [ "enveloped text content streaming S/MIME format, DES, 1 recipient", +      [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont, +        "-stream", "-text", "-out", "{output}.cms", $smrsa1 ], +      [ "{cmd2}", @defaultprov, "-decrypt", "-recip", $smrsa1, +        "-in", "{output}.cms", "-text", "-out", "{output}.txt" ], +      \&final_compare +    ], +      [ "enveloped content test streaming S/MIME format, DES, 3 recipients, 3rd used",        [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,          "-stream", "-out", "{output}.cms", @@ -347,6 +364,16 @@ my @smime_cms_tests = (        \&final_compare      ], +    [ "enveloped content test streaming PEM format, AES-128-CBC cipher, password", +      [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes128", +        "-stream", "-out", "{output}.cms", +        "-pwri_password", "test" ], +      [ "{cmd2}", @prov, "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt", +        "-inform", "PEM", +        "-pwri_password", "test" ], +      \&final_compare +    ], +      [ "data content test streaming PEM format",        [ "{cmd1}", @prov, "-data_create", "-in", $smcont, "-outform", "PEM",          "-nodetach", "-stream", "-out", "{output}.cms" ], diff --git a/test/recipes/90-test_store_cases.t b/test/recipes/90-test_store_cases.t index 05b00e6b4eb1..5915a1b76a53 100644 --- a/test/recipes/90-test_store_cases.t +++ b/test/recipes/90-test_store_cases.t @@ -1,5 +1,5 @@  #! /usr/bin/env perl -# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved.  #  # Licensed under the Apache License 2.0 (the "License").  You may not use  # this file except in compliance with the License.  You can obtain a copy @@ -18,9 +18,10 @@ use OpenSSL::Test::Utils;  my $test_name = "test_store_cases";  setup($test_name); -plan tests => 2; +plan tests => 3;  my $stderr; +my @stdout;  # The case of the garbage PKCS#12 DER file where a passphrase was  # prompted for.  That should not have happened. @@ -34,3 +35,24 @@ open DATA, $stderr;  close DATA;  ok(scalar @match > 0 ? 0 : 1,     "checking that storeutl didn't ask for a passphrase"); + + SKIP: { +     skip "The objects in test-BER.p12 contain EC keys, which is disabled in this build", 1 +         if disabled("ec"); +     skip "test-BER.p12 has contents encrypted with DES-EDE3-CBC, which is disabled in this build", 1 +         if disabled("des"); + +     # The case with a BER-encoded PKCS#12 file, using infinite + EOC +     # constructs.  There was a bug with those in OpenSSL 3.0 and newer, +     # where OSSL_STORE_load() (and by consequence, 'openssl storeutl') +     # only extracted the first available object from that file and +     # ignored the rest. +     # Our test file has a total of four objects, and this should be +     # reflected in the total that 'openssl storeutl' outputs +     @stdout = run(app(['openssl', 'storeutl', '-passin', 'pass:12345', +                        data_file('test-BER.p12')]), +                   capture => 1); +     @stdout = map { my $x = $_; $x =~ s/\R$//; $x } @stdout; # Better chomp +     ok((grep { $_ eq 'Total found: 4' } @stdout), +        "Checking that 'openssl storeutl' with test-BER.p12 returns 4 objects"); +} diff --git a/test/recipes/90-test_store_cases_data/test-BER.p12 b/test/recipes/90-test_store_cases_data/test-BER.p12Binary files differ new file mode 100644 index 000000000000..256e697bac1a --- /dev/null +++ b/test/recipes/90-test_store_cases_data/test-BER.p12 diff --git a/test/recipes/90-test_threads_data/store/8489a545.0 b/test/recipes/90-test_threads_data/store/8489a545.0 new file mode 100644 index 000000000000..7fd65dfe924b --- /dev/null +++ b/test/recipes/90-test_threads_data/store/8489a545.0 @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFjCCAf6gAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290 +IENBMCAXDTIwMTIxMjIwMTEzN1oYDzIxMjAxMjEzMjAxMTM3WjASMRAwDgYDVQQD +DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4eYA9Qa8 +oEY4eQ8/HnEZE20C3yubdmv8rLAh7daRCEI7pWM17FJboKJKxdYAlAOXWj25ZyjS +feMhXKTtxjyNjoTRnVTDPdl0opZ2Z3H5xhpQd7P9eO5b4OOMiSPCmiLsPtQ3ngfN +wCtVERc6NEIcaQ06GLDtFZRexv2eh8Yc55QaksBfBcFzQ+UD3gmRySTO2I6Lfi7g +MUjRhipqVSZ66As2Tpex4KTJ2lxpSwOACFaDox+yKrjBTP7FsU3UwAGq7b7OJb3u +aa32B81uK6GJVPVo65gJ7clgZsszYkoDsGjWDqtfwTVVfv1G7rrr3Laio+2Ff3ff +tWgiQ35mJCOvxQIDAQABo3UwczAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB +BjAdBgNVHQ4EFgQUjvUlrx6ba4Q9fICayVOcTXL3o1IwHwYDVR0jBBgwFoAUjvUl +rx6ba4Q9fICayVOcTXL3o1IwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcN +AQELBQADggEBABWUjaqtkdRDhVAJZTxkJVgohjRrBwp86Y0JZWdCDua/sErmEaGu +nQVxWWFWIgu6sb8tyQo3/7dBIQl3Rpij9bsgKhToO1OzoG3Oi3d0+zRDHfY6xNrj +TUE00FeLHGNWsgZSIvu99DrGApT/+uPdWfJgMu5szillqW+4hcCUPLjG9ekVNt1s +KhdEklo6PrP6eMbm6s22EIVUxqGE6xxAmrvyhlY1zJH9BJ23Ps+xabjG6OeMRZzT +0F/fU7XIFieSO7rqUcjgo1eYc3ghsDxNUJ6TPBgv5z4SPnstoOBj59rjpJ7Qkpyd +L17VfEadezat37Cpeha7vGDduCsyMfN4kiw= +-----END CERTIFICATE----- diff --git a/test/sslapitest.c b/test/sslapitest.c index 368b15f22b72..a26b78907424 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -11127,6 +11127,79 @@ static int test_alpn(int idx)      return testresult;  } +static int test_no_renegotiation(int idx) +{ +    SSL_CTX *sctx = NULL, *cctx = NULL; +    SSL *serverssl = NULL, *clientssl = NULL; +    int testresult = 0, ret; +    int max_proto; +    const SSL_METHOD *sm, *cm; +    unsigned char buf[5]; + +    if (idx == 0) { +#ifndef OPENSSL_NO_TLS1_2 +        max_proto = TLS1_2_VERSION; +        sm = TLS_server_method(); +        cm = TLS_client_method(); +#else +        return TEST_skip("TLSv1.2 is disabled in this build"); +#endif +    } else { +#ifndef OPENSSL_NO_DTLS1_2 +        max_proto = DTLS1_2_VERSION; +        sm = DTLS_server_method(); +        cm = DTLS_client_method(); +#else +        return TEST_skip("DTLSv1.2 is disabled in this build"); +#endif +    } +    if (!TEST_true(create_ssl_ctx_pair(libctx, sm, cm, 0, max_proto, +                                       &sctx, &cctx, cert, privkey))) +        goto end; + +    SSL_CTX_set_options(sctx, SSL_OP_NO_RENEGOTIATION); + +    if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, +                                      NULL))) +        goto end; + +    if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) +        goto end; + +    if (!TEST_true(SSL_renegotiate(clientssl)) +            || !TEST_int_le(ret = SSL_connect(clientssl), 0) +            || !TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_WANT_READ)) +        goto end; + +    /* +     * We've not sent any application data, so we expect this to fail. It should +     * also read the renegotiation attempt, and send back a no_renegotiation +     * warning alert because we have renegotiation disabled. +     */ +    if (!TEST_int_le(ret = SSL_read(serverssl, buf, sizeof(buf)), 0)) +        goto end; +    if (!TEST_int_eq(SSL_get_error(serverssl, ret), SSL_ERROR_WANT_READ)) +        goto end; + +    /* +     * The client should now see the no_renegotiation warning and fail the +     * connection +     */ +    if (!TEST_int_le(ret = SSL_connect(clientssl), 0) +            || !TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_SSL) +            || !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), SSL_R_NO_RENEGOTIATION)) +        goto end; + +    testresult = 1; + end: +    SSL_free(serverssl); +    SSL_free(clientssl); +    SSL_CTX_free(sctx); +    SSL_CTX_free(cctx); + +    return testresult; +} +  OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config dhfile\n")  int setup_tests(void) @@ -11408,6 +11481,7 @@ int setup_tests(void)      ADD_ALL_TESTS(test_npn, 5);  #endif      ADD_ALL_TESTS(test_alpn, 4); +    ADD_ALL_TESTS(test_no_renegotiation, 2);      return 1;   err: diff --git a/test/testec-sm2.pem b/test/testec-sm2.pem new file mode 100644 index 000000000000..30e25613b38e --- /dev/null +++ b/test/testec-sm2.pem @@ -0,0 +1,5 @@ +-----BEGIN SM2 PRIVATE KEY----- +MHcCAQEEIKPB7gEYKGAwAkz0MfGwQm0BXclgzvSTxQG9bm4RCAxXoAoGCCqBHM9V +AYItoUQDQgAE+FuibOpfjVfj716O3LglhK4HzjUR82mgn8kTZinQsEafw3FFZzZJ +vwHIGHUsSKxVTRIEs+BICQDBg99OA3VU/Q== +-----END SM2 PRIVATE KEY----- diff --git a/test/testutil/testutil_init.c b/test/testutil/testutil_init.c index 87013694c29e..64224186e477 100644 --- a/test/testutil/testutil_init.c +++ b/test/testutil/testutil_init.c @@ -1,5 +1,5 @@  /* - * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -92,6 +92,7 @@ static void setup_trace_category(int category)                  "warning: unable to setup trace callback for category '%s'.\n",                  OSSL_trace_get_category_name(category)); +        OPENSSL_free(trace_data);          OSSL_trace_set_callback(category, NULL, NULL);          BIO_free_all(channel);      } diff --git a/test/threadstest.c b/test/threadstest.c index 046a9eb80239..0a712c84d914 100644 --- a/test/threadstest.c +++ b/test/threadstest.c @@ -1,5 +1,5 @@  /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -30,6 +30,7 @@  static int do_fips = 0;  static char *privkey; +static char *storedir;  static char *config_file = NULL;  static int multidefault_run = 0;  static const char *default_provider[] = { "default", NULL }; @@ -582,7 +583,6 @@ static int test_multi_default(void)  {      thread_t thread1, thread2;      int testresult = 0; -    OSSL_PROVIDER *prov = NULL;      /* Avoid running this test twice */      if (multidefault_run) { @@ -593,9 +593,6 @@ static int test_multi_default(void)      multi_success = 1;      multi_libctx = NULL; -    prov = OSSL_PROVIDER_load(multi_libctx, "default"); -    if (!TEST_ptr(prov)) -        goto err;      if (!TEST_true(run_thread(&thread1, thread_multi_simple_fetch))              || !TEST_true(run_thread(&thread2, thread_multi_simple_fetch))) @@ -611,7 +608,6 @@ static int test_multi_default(void)      testresult = 1;   err: -    OSSL_PROVIDER_unload(prov);      return testresult;  } @@ -663,6 +659,62 @@ static int test_lib_ctx_load_config(void)                             1, default_provider);  } +static X509_STORE *store = NULL; + +static void test_x509_store_by_subject(void) +{ +    X509_STORE_CTX *ctx; +    X509_OBJECT *obj = NULL; +    X509_NAME *name = NULL; +    int success = 0; + +    ctx = X509_STORE_CTX_new(); +    if (!TEST_ptr(ctx)) +        goto err; + +    if (!TEST_true(X509_STORE_CTX_init(ctx, store, NULL, NULL))) +        goto err; + +    name = X509_NAME_new(); +    if (!TEST_ptr(name)) +        goto err; +    if (!TEST_true(X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, +                                              (unsigned char *)"Root CA", +                                              -1, -1, 0))) +        goto err; +    obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, name); +    if (!TEST_ptr(obj)) +        goto err; + +    success = 1; + err: +    X509_OBJECT_free(obj); +    X509_STORE_CTX_free(ctx); +    X509_NAME_free(name); +    if (!success) +        multi_success = 0; +} + +/* Test accessing an X509_STORE from multiple threads */ +static int test_x509_store(void) +{ +    int ret = 0; + +    store = X509_STORE_new(); +    if (!TEST_ptr(store)) +        return 0; +    if (!TEST_true(X509_STORE_load_store(store, storedir))) +        goto err; + +    ret = thread_run_test(&test_x509_store_by_subject, MAXIMUM_THREADS, +                          &test_x509_store_by_subject, 0, NULL); + + err: +    X509_STORE_free(store); +    store = NULL; +    return ret; +} +  typedef enum OPTION_choice {      OPT_ERR = -1,      OPT_EOF = 0, @@ -709,20 +761,24 @@ int setup_tests(void)      if (!TEST_ptr(privkey))          return 0; +    storedir = test_mk_file_path(datadir, "store"); +      /* Keep first to validate auto creation of default library context */      ADD_TEST(test_multi_default); -      ADD_TEST(test_lock);      ADD_TEST(test_once);      ADD_TEST(test_thread_local);      ADD_TEST(test_atomic);      ADD_TEST(test_multi_load); +      ADD_ALL_TESTS(test_multi, 6);      ADD_TEST(test_lib_ctx_load_config); +    ADD_TEST(test_x509_store);      return 1;  }  void cleanup_tests(void)  {      OPENSSL_free(privkey); +    OPENSSL_free(storedir);  } diff --git a/test/tls-provider.c b/test/tls-provider.c index 7375792c3125..52b1f3709d61 100644 --- a/test/tls-provider.c +++ b/test/tls-provider.c @@ -1,5 +1,5 @@  /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.   *   * Licensed under the Apache License 2.0 (the "License").  You may not use   * this file except in compliance with the License.  You can obtain a copy @@ -594,9 +594,10 @@ static void *xor_gen_init(void *provctx, int selection,                        | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)) == 0)          return NULL; -    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) -        gctx->selection = selection; +    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) == NULL) +        return NULL; +    gctx->selection = selection;      /* Our provctx is really just an OSSL_LIB_CTX */      gctx->libctx = (OSSL_LIB_CTX *)provctx; diff --git a/tools/c_rehash.in b/tools/c_rehash.in index 343cdc1e7575..c056001ea378 100644 --- a/tools/c_rehash.in +++ b/tools/c_rehash.in @@ -1,7 +1,7 @@  #!{- $config{HASHBANGPERL} -}  {- use OpenSSL::Util; -}  # {- join("\n# ", @autowarntext) -} -# Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved.  #  # Licensed under the Apache License 2.0 (the "License").  You may not use  # this file except in compliance with the License.  You can obtain a copy @@ -63,10 +63,10 @@ if (defined(&Cwd::getcwd)) {  my $path_delim = ($pwd =~ /^[a-z]\:/i) ? ';' : ':';  $ENV{PATH} = "$prefix/bin" . ($ENV{PATH} ? $path_delim . $ENV{PATH} : ""); -if (! -x $openssl) { +if (!(-f $openssl && -x $openssl)) {      my $found = 0;      foreach (split /$path_delim/, $ENV{PATH}) { -        if (-x "$_/$openssl") { +        if (-f "$_/$openssl" && -x "$_/$openssl") {              $found = 1;              $openssl = "$_/$openssl";              last; @@ -88,7 +88,7 @@ if (@ARGV) {  if (-d $dirlist[0]) {      chdir $dirlist[0]; -    $openssl="$pwd/$openssl" if (!-x $openssl); +    $openssl="$pwd/$openssl" if (!(-f $openssl && -x $openssl));      chdir $pwd;  } diff --git a/util/wrap.pl.in b/util/wrap.pl.in index 5126513d4c3e..436ec12fcf06 100644 --- a/util/wrap.pl.in +++ b/util/wrap.pl.in @@ -18,6 +18,38 @@ BEGIN {      OpenSSL::Util->import();  } +sub quote_cmd_win32 { +    my $cmd = ""; + +    foreach my $arg (@_) { +        if ($arg =~ m{\A[\w,-./@]+\z}) { +            $cmd .= $arg . q{ };; +        } else { +            $cmd .= q{"} . quote_arg_win32($arg) . q{" }; +        } +    } +    return substr($cmd, 0, -1); +} + +sub quote_arg_win32 { +    my ($arg) = @_; +    my $val = ""; + +    pos($arg) = 0; +    while (1) { +        return $val if (pos($arg) == length($arg)); +        if ($arg =~ m{\G((?:(?>[\\]*)[^"\\]+)+)}ogc) { +            $val .= $1; +        } elsif ($arg =~ m{\G"}ogc) { +            $val .= qq{\\"}; +        } elsif ($arg =~ m{\G((?>[\\]+)(?="|\z))}ogc) { +            $val .= qq{\\} x (2 * length($1)); +        } else { +            die sprintf("Internal error quoting: '%s'\n", $arg); +        } +    } +} +  my $there = canonpath(catdir(dirname($0), updir()));  my $std_engines = catdir($there, 'engines');  my $std_providers = catdir($there, 'providers'); @@ -60,7 +92,12 @@ if ($^O eq 'VMS') {  # The exec() statement on MSWin32 doesn't seem to give back the exit code  # from the call, so we resort to using system() instead. -my $waitcode = system @cmd; +my $waitcode; +if ($^O eq 'MSWin32') { +    $waitcode = system(quote_cmd_win32(@cmd)); +} else { +    $waitcode = system @cmd; +}  # According to documentation, -1 means that system() couldn't run the command,  # otherwise, the value is similar to the Unix wait() status value | 
