浏览代码

OpenSSL 3.2.0

Source commit: 783d483915f32b104c5faced51deec41fc326ce4
Martin Prikryl 1 年之前
父节点
当前提交
513d92a184
共有 100 个文件被更改,包括 5274 次插入2025 次删除
  1. 483 27
      libs/openssl/CHANGES.md
  2. 46 6
      libs/openssl/Configurations/00-base-templates.conf
  3. 122 16
      libs/openssl/Configurations/10-main.conf
  4. 29 4
      libs/openssl/Configurations/15-ios.conf
  5. 15 2
      libs/openssl/Configurations/50-nonstop.conf
  6. 37 0
      libs/openssl/Configurations/50-win-hybridcrt.conf
  7. 4 5
      libs/openssl/Configurations/50-win-onecore.conf
  8. 7 0
      libs/openssl/Configurations/README.md
  9. 87 17
      libs/openssl/Configurations/descrip.mms.tmpl
  10. 7 1
      libs/openssl/Configurations/shared-info.pl
  11. 139 61
      libs/openssl/Configurations/unix-Makefile.tmpl
  12. 42 10
      libs/openssl/Configurations/windows-makefile.tmpl
  13. 122 19
      libs/openssl/Configure
  14. 144 27
      libs/openssl/INSTALL.md
  15. 100 2
      libs/openssl/NEWS.md
  16. 8 0
      libs/openssl/NOTES-WINDOWS.md
  17. 1 1
      libs/openssl/README-FIPS.md
  18. 2 2
      libs/openssl/README-PROVIDERS.md
  19. 80 0
      libs/openssl/README-QUIC.md
  20. 59 12
      libs/openssl/README.md
  21. 3 3
      libs/openssl/VERSION.dat
  22. 8 6
      libs/openssl/apps/CA.pl.in
  23. 9 10
      libs/openssl/apps/asn1parse.c
  24. 58 88
      libs/openssl/apps/ca.c
  25. 2 3
      libs/openssl/apps/ciphers.c
  26. 264 180
      libs/openssl/apps/cmp.c
  27. 51 17
      libs/openssl/apps/cms.c
  28. 5 7
      libs/openssl/apps/crl.c
  29. 1 2
      libs/openssl/apps/crl2pkcs7.c
  30. 3 2
      libs/openssl/apps/dgst.c
  31. 18 18
      libs/openssl/apps/dhparam.c
  32. 6 10
      libs/openssl/apps/dsa.c
  33. 25 30
      libs/openssl/apps/dsaparam.c
  34. 6 10
      libs/openssl/apps/ec.c
  35. 11 4
      libs/openssl/apps/ecparam.c
  36. 108 29
      libs/openssl/apps/enc.c
  37. 1 1
      libs/openssl/apps/engine.c
  38. 7 5
      libs/openssl/apps/fipsinstall.c
  39. 10 8
      libs/openssl/apps/gendsa.c
  40. 82 39
      libs/openssl/apps/genpkey.c
  41. 11 31
      libs/openssl/apps/genrsa.c
  42. 30 24
      libs/openssl/apps/include/apps.h
  43. 4 0
      libs/openssl/apps/include/cmp_mock_srv.h
  44. 1 1
      libs/openssl/apps/include/engine_loader.h
  45. 1 1
      libs/openssl/apps/include/function.h
  46. 11 27
      libs/openssl/apps/include/http_server.h
  47. 50 0
      libs/openssl/apps/include/log.h
  48. 62 25
      libs/openssl/apps/include/opt.h
  49. 6 4
      libs/openssl/apps/include/s_apps.h
  50. 1 1
      libs/openssl/apps/info.c
  51. 1 1
      libs/openssl/apps/lib/app_libctx.c
  52. 4 6
      libs/openssl/apps/lib/app_rand.c
  53. 277 213
      libs/openssl/apps/lib/apps.c
  54. 25 0
      libs/openssl/apps/lib/apps_opt_printf.c
  55. 2 2
      libs/openssl/apps/lib/build.info
  56. 101 50
      libs/openssl/apps/lib/cmp_mock_srv.c
  57. 1 3
      libs/openssl/apps/lib/engine_loader.c
  58. 170 153
      libs/openssl/apps/lib/http_server.c
  59. 108 0
      libs/openssl/apps/lib/log.c
  60. 1 1
      libs/openssl/apps/lib/names.c
  61. 146 69
      libs/openssl/apps/lib/opt.c
  62. 91 17
      libs/openssl/apps/lib/s_cb.c
  63. 57 18
      libs/openssl/apps/lib/s_socket.c
  64. 2 2
      libs/openssl/apps/lib/tlssrp_depr.c
  65. 7 7
      libs/openssl/apps/lib/vms_term_sock.c
  66. 102 36
      libs/openssl/apps/list.c
  67. 4 5
      libs/openssl/apps/mac.c
  68. 1 2
      libs/openssl/apps/nseq.c
  69. 32 26
      libs/openssl/apps/ocsp.c
  70. 2 2
      libs/openssl/apps/openssl-vms.cnf
  71. 23 15
      libs/openssl/apps/openssl.c
  72. 2 2
      libs/openssl/apps/openssl.cnf
  73. 1 1
      libs/openssl/apps/passwd.c
  74. 94 29
      libs/openssl/apps/pkcs12.c
  75. 11 7
      libs/openssl/apps/pkcs7.c
  76. 16 7
      libs/openssl/apps/pkcs8.c
  77. 4 6
      libs/openssl/apps/pkey.c
  78. 2 3
      libs/openssl/apps/pkeyparam.c
  79. 5 6
      libs/openssl/apps/pkeyutl.c
  80. 25 10
      libs/openssl/apps/prime.c
  81. 4 6
      libs/openssl/apps/progs.pl
  82. 10 9
      libs/openssl/apps/rand.c
  83. 18 15
      libs/openssl/apps/rehash.c
  84. 131 190
      libs/openssl/apps/req.c
  85. 6 8
      libs/openssl/apps/rsa.c
  86. 4 5
      libs/openssl/apps/rsautl.c
  87. 566 58
      libs/openssl/apps/s_client.c
  88. 125 33
      libs/openssl/apps/s_server.c
  89. 1 2
      libs/openssl/apps/s_time.c
  90. 1 2
      libs/openssl/apps/sess_id.c
  91. 45 14
      libs/openssl/apps/smime.c
  92. 547 91
      libs/openssl/apps/speed.c
  93. 6 6
      libs/openssl/apps/spkac.c
  94. 7 8
      libs/openssl/apps/storeutl.c
  95. 14 11
      libs/openssl/apps/ts.c
  96. 1 1
      libs/openssl/apps/tsget.in
  97. 3 3
      libs/openssl/apps/verify.c
  98. 1 2
      libs/openssl/apps/version.c
  99. 68 63
      libs/openssl/apps/x509.c
  100. 10 1
      libs/openssl/build.info

+ 483 - 27
libs/openssl/CHANGES.md

@@ -1,15 +1,18 @@
 OpenSSL CHANGES
 ===============
 
-This is a high-level summary of the most important changes.
-For a full list of changes, see the [git commit log][log] and
-pick the appropriate release branch.
+This is a detailed breakdown of significant changes. For a high-level overview
+of changes in each release, see [NEWS.md](./NEWS.md).
+
+For a full list of changes, see the [git commit log][log] and pick the
+appropriate release branch.
 
   [log]: https://github.com/openssl/openssl/commits/
 
 OpenSSL Releases
 ----------------
 
+ - [OpenSSL 3.2](#openssl-32)
  - [OpenSSL 3.1](#openssl-31)
  - [OpenSSL 3.0](#openssl-30)
  - [OpenSSL 1.1.1](#openssl-111)
@@ -19,9 +22,477 @@ OpenSSL Releases
  - [OpenSSL 1.0.0](#openssl-100)
  - [OpenSSL 0.9.x](#openssl-09x)
 
+OpenSSL 3.2
+-----------
+
+### Changes between 3.1 and 3.2.0 [23 Nov 2023]
+
+ * The BLAKE2b hash algorithm supports a configurable output length
+   by setting the "size" parameter.
+
+   *Čestmír Kalina and Tomáš Mráz*
+
+ * Enable extra Arm64 optimization on Windows for GHASH, RAND and AES.
+
+   *Evgeny Karpov*
+
+ * Added a function to delete objects from store by URI - OSSL_STORE_delete()
+   and the corresponding provider-storemgmt API function
+   OSSL_FUNC_store_delete().
+
+   *Dmitry Belyavskiy*
+
+ * Added OSSL_FUNC_store_open_ex() provider-storemgmt API function to pass
+   a passphrase callback when opening a store.
+
+   *Simo Sorce*
+
+ * Changed the default salt length used by PBES2 KDF's (PBKDF2 and scrypt)
+   from 8 bytes to 16 bytes.
+   The PKCS5 (RFC 8018) standard uses a 64 bit salt length for PBE, and
+   recommends a minimum of 64 bits for PBES2. For FIPS compliance PBKDF2
+   requires a salt length of 128 bits. This affects OpenSSL command line
+   applications such as "genrsa" and "pkcs8" and API's such as
+   PEM_write_bio_PrivateKey() that are reliant on the default value.
+   The additional commandline option 'saltlen' has been added to the
+   OpenSSL command line applications for "pkcs8" and "enc" to allow the
+   salt length to be set to a non default value.
+
+   *Shane Lontis*
+
+ * Changed the default value of the `ess_cert_id_alg` configuration
+   option which is used to calculate the TSA's public key certificate
+   identifier. The default algorithm is updated to be sha256 instead
+   of sha1.
+
+   *Małgorzata Olszówka*
+
+ * Added optimization for SM2 algorithm on aarch64. It uses a huge precomputed
+   table for point multiplication of the base point, which increases the size of
+   libcrypto from 4.4 MB to 4.9 MB. A new configure option `no-sm2-precomp` has
+   been added to disable the precomputed table.
+
+   *Xu Yizhou*
+
+ * Added client side support for QUIC
+
+   *Hugo Landau, Matt Caswell, Paul Dale, Tomáš Mráz, Richard Levitte*
+
+ * Added multiple tutorials on the OpenSSL library and in particular
+   on writing various clients (using TLS and QUIC protocols) with libssl.
+
+   *Matt Caswell*
+
+ * Added secp384r1 implementation using Solinas' reduction to improve
+   speed of the NIST P-384 elliptic curve. To enable the implementation
+   the build option `enable-ec_nistp_64_gcc_128` must be used.
+
+   *Rohan McLure*
+
+ * Improved RFC7468 compliance of the asn1parse command.
+
+   *Matthias St. Pierre*
+
+ * Added SHA256/192 algorithm support.
+
+   *Fergus Dall*
+
+ * Added support for securely getting root CA certificate update in
+   CMP.
+
+   *David von Oheimb*
+
+ * Improved contention on global write locks by using more read locks where
+   appropriate.
+
+   *Matt Caswell*
+
+ * Improved performance of OSSL_PARAM lookups in performance critical
+   provider functions.
+
+   *Paul Dale*
+
+ * Added the SSL_get0_group_name() function to provide access to the
+   name of the group used for the TLS key exchange.
+
+   *Alex Bozarth*
+
+ * Provide a new configure option `no-http` that can be used to disable the
+   HTTP support. Provide new configure options `no-apps` and `no-docs` to
+   disable building the openssl command line application and the documentation.
+
+   *Vladimír Kotal*
+
+ * Provide a new configure option `no-ecx` that can be used to disable the
+   X25519, X448, and EdDSA support.
+
+   *Yi Li*
+
+ * When multiple OSSL_KDF_PARAM_INFO parameters are passed to
+   the EVP_KDF_CTX_set_params() function they are now concatenated not just
+   for the HKDF algorithm but also for SSKDF and X9.63 KDF algorithms.
+
+   *Paul Dale*
+
+ * Added OSSL_FUNC_keymgmt_im/export_types_ex() provider functions that get
+   the provider context as a parameter.
+
+   *Ingo Franzki*
+
+ * TLS round-trip time calculation was added by a Brigham Young University
+   Capstone team partnering with Sandia National Laboratories. A new function
+   in ssl_lib titled SSL_get_handshake_rtt will calculate and retrieve this
+   value.
+
+   *Jairus Christensen*
+
+ * Added the "-quic" option to s_client to enable connectivity to QUIC servers.
+   QUIC requires the use of ALPN, so this must be specified via the "-alpn"
+   option. Use of the "advanced" s_client command command via the "-adv" option
+   is recommended.
+
+   *Matt Caswell*
+
+ * Added an "advanced" command mode to s_client. Use this with the "-adv"
+   option. The old "basic" command mode recognises certain letters that must
+   always appear at the start of a line and cannot be escaped. The advanced
+   command mode enables commands to be entered anywhere and there is an
+   escaping mechanism. After starting s_client with "-adv" type "{help}"
+   to show a list of available commands.
+
+   *Matt Caswell*
+
+ * Add Raw Public Key (RFC7250) support. Authentication is supported
+   by matching keys against either local policy (TLSA records synthesised
+   from the expected keys) or DANE (TLSA records obtained by the
+   application from DNS). TLSA records will also match the same key in
+   the server certificate, should RPK use not happen to be negotiated.
+
+   *Todd Short*
+
+ * Added support for modular exponentiation and CRT offloading for the
+   S390x architecture.
+
+   *Juergen Christ*
+
+ * Added further assembler code for the RISC-V architecture.
+
+   *Christoph Müllner*
+
+ * Added EC_GROUP_to_params() which creates an OSSL_PARAM array
+   from a given EC_GROUP.
+
+   *Oliver Mihatsch*
+
+ * Improved support for non-default library contexts and property queries
+   when parsing PKCS#12 files.
+
+   *Shane Lontis*
+
+ * Implemented support for all five instances of EdDSA from RFC8032:
+   Ed25519, Ed25519ctx, Ed25519ph, Ed448, and Ed448ph.
+   The streaming is not yet supported for the HashEdDSA variants
+   (Ed25519ph and Ed448ph).
+
+   *James Muir*
+
+ * Added SM4 optimization for ARM processors using ASIMD and AES HW
+   instructions.
+
+   *Xu Yizhou*
+
+ * Implemented SM4-XTS support.
+
+   *Xu Yizhou*
+
+ * Added platform-agnostic OSSL_sleep() function.
+
+   *Richard Levitte*
+
+ * Implemented deterministic ECDSA signatures (RFC6979) support.
+
+   *Shane Lontis*
+
+ * Implemented AES-GCM-SIV (RFC8452) support.
+
+   *Todd Short*
+
+ * Added support for pluggable (provider-based) TLS signature algorithms.
+   This enables TLS 1.3 authentication operations with algorithms embedded
+   in providers not included by default in OpenSSL. In combination with
+   the already available pluggable KEM and X.509 support, this enables
+   for example suitable providers to deliver post-quantum or quantum-safe
+   cryptography to OpenSSL users.
+
+   *Michael Baentsch*
+
+ * Added support for pluggable (provider-based) CMS signature algorithms.
+   This enables CMS sign and verify operations with algorithms embedded
+   in providers not included by default in OpenSSL.
+
+   *Michael Baentsch*
+
+ * Added support for Hybrid Public Key Encryption (HPKE) as defined
+   in RFC9180. HPKE is required for TLS Encrypted ClientHello (ECH),
+   Message Layer Security (MLS) and other IETF specifications.
+   HPKE can also be used by other applications that require
+   encrypting "to" an ECDH public key. External APIs are defined in
+   include/openssl/hpke.h and documented in doc/man3/OSSL_HPKE_CTX_new.pod
+
+   *Stephen Farrell*
+
+ * Implemented HPKE DHKEM support in providers used by HPKE (RFC9180)
+   API.
+
+   *Shane Lontis*
+
+ * Add support for certificate compression (RFC8879), including
+   library support for Brotli and Zstandard compression.
+
+   *Todd Short*
+
+ * Add the ability to add custom attributes to PKCS12 files. Add a new API
+   PKCS12_create_ex2, identical to the existing PKCS12_create_ex but allows
+   for a user specified callback and optional argument.
+   Added a new PKCS12_SAFEBAG_set0_attr, which allows for a new attr to be
+   added to the existing STACK_OF attrs.
+
+   *Graham Woodward*
+
+ * Major refactor of the libssl record layer.
+
+   *Matt Caswell*
+
+ * Add a mac salt length option for the pkcs12 command.
+
+   *Xinping Chen*
+
+ * Add more SRTP protection profiles from RFC8723 and RFC8269.
+
+   *Kijin Kim*
+
+ * Extended Kernel TLS (KTLS) to support TLS 1.3 receive offload.
+
+   *Daiki Ueno, John Baldwin and Dmitry Podgorny*
+
+ * Add support for TCP Fast Open (RFC7413) to macOS, Linux, and FreeBSD where
+   supported and enabled.
+
+   *Todd Short*
+
+ * Add ciphersuites based on DHE_PSK (RFC 4279) and ECDHE_PSK (RFC 5489)
+   to the list of ciphersuites providing Perfect Forward Secrecy as
+   required by SECLEVEL >= 3.
+
+   *Dmitry Belyavskiy, Nicola Tuveri*
+
+ * Add new SSL APIs to aid in efficiently implementing TLS/SSL fingerprinting.
+   The SSL_CTRL_GET_IANA_GROUPS control code, exposed as the
+   SSL_get0_iana_groups() function-like macro, retrieves the list of
+   supported groups sent by the peer.
+   The function SSL_client_hello_get_extension_order() populates
+   a caller-supplied array with the list of extension types present in the
+   ClientHello, in order of appearance.
+
+   *Phus Lu*
+
+ * Fixed PEM_write_bio_PKCS8PrivateKey() and PEM_write_bio_PKCS8PrivateKey_nid()
+   to make it possible to use empty passphrase strings.
+
+   *Darshan Sen*
+
+ * The PKCS12_parse() function now supports MAC-less PKCS12 files.
+
+   *Daniel Fiala*
+
+ * Added ASYNC_set_mem_functions() and ASYNC_get_mem_functions() calls to be able
+   to change functions used for allocating the memory of asynchronous call stack.
+
+   *Arran Cudbard-Bell*
+
+ * Added support for signed BIGNUMs in the OSSL_PARAM APIs.
+
+   *Richard Levitte*
+
+ * A failure exit code is returned when using the openssl x509 command to check
+   certificate attributes and the checks fail.
+
+   *Rami Khaldi*
+
+ * The default SSL/TLS security level has been changed from 1 to 2. RSA,
+   DSA and DH keys of 1024 bits and above and less than 2048 bits and ECC keys
+   of 160 bits and above and less than 224 bits were previously accepted by
+   default but are now no longer allowed. By default TLS compression was
+   already disabled in previous OpenSSL versions. At security level 2 it cannot
+   be enabled.
+
+   *Matt Caswell*
+
+ * The SSL_CTX_set_cipher_list family functions now accept ciphers using their
+   IANA standard names.
+
+   *Erik Lax*
+
+ * The PVK key derivation function has been moved from b2i_PVK_bio_ex() into
+   the legacy crypto provider as an EVP_KDF. Applications requiring this KDF
+   will need to load the legacy crypto provider.
+
+   *Paul Dale*
+
+ * CCM8 cipher suites in TLS have been downgraded to security level zero
+   because they use a short authentication tag which lowers their strength.
+
+   *Paul Dale*
+
+ * Subject or issuer names in X.509 objects are now displayed as UTF-8 strings
+   by default.
+
+   *Dmitry Belyavskiy*
+
+ * Add X.509 certificate codeSigning purpose and related checks on key usage and
+   extended key usage of the leaf certificate according to the CA/Browser Forum.
+
+   * Lutz Jänicke*
+
+ * The `x509`, `ca`, and `req` apps now produce X.509 v3 certificates.
+   The `-x509v1` option of `req` prefers generation of X.509 v1 certificates.
+   `X509_sign()` and `X509_sign_ctx()` make sure that the certificate has
+   X.509 version 3 if the certificate information includes X.509 extensions.
+
+   *David von Oheimb*
+
+ * Fix and extend certificate handling and the apps `x509`, `verify` etc.
+   such as adding a trace facility for debugging certificate chain building.
+
+   *David von Oheimb*
+
+ * Various fixes and extensions to the CMP+CRMF implementation and the `cmp` app
+   in particular supporting requests for central key generation, generalized
+   polling, and various types of genm/genp exchanges defined in CMP Updates.
+
+   *David von Oheimb*
+
+ * Fixes and extensions to the HTTP client and to the HTTP server in `apps/`
+   like correcting the TLS and proxy support and adding tracing for debugging.
+
+   *David von Oheimb*
+
+ * Extended the CMS API for handling `CMS_SignedData` and `CMS_EnvelopedData`.
+
+   *David von Oheimb*
+
+ * `CMS_add0_cert()` and `CMS_add1_cert()` no longer throw an error if
+   a certificate to be added is already present. `CMS_sign_ex()` and
+   `CMS_sign()` now ignore any duplicate certificates in their `certs` argument
+   and no longer throw an error for them.
+
+   *David von Oheimb*
+
+ * Fixed and extended `util/check-format.pl` for checking adherence to the
+   coding style <https://www.openssl.org/policies/technical/coding-style.html>.
+   The checks are meanwhile more complete and yield fewer false positives.
+
+   *David von Oheimb*
+
+ * Added BIO_s_dgram_pair() and BIO_s_dgram_mem() that provide memory-based
+   BIOs with datagram semantics and support for BIO_sendmmsg() and BIO_recvmmsg()
+   calls. They can be used as the transport BIOs for QUIC.
+
+   *Hugo Landau, Matt Caswell and Tomáš Mráz*
+
+ * Add new BIO_sendmmsg() and BIO_recvmmsg() BIO methods which allow
+   sending and receiving multiple messages in a single call. An implementation
+   is provided for BIO_dgram. For further details, see BIO_sendmmsg(3).
+
+   *Hugo Landau*
+
+ * Support for loading root certificates from the Windows certificate store
+   has been added. The support is in the form of a store which recognises the
+   URI string of `org.openssl.winstore://`. This URI scheme currently takes no
+   arguments. This store is built by default and can be disabled using the new
+   compile-time option `no-winstore`. This store is not currently used by
+   default and must be loaded explicitly using the above store URI. It is
+   expected to be loaded by default in the future.
+
+   *Hugo Landau*
+
+ * Enable KTLS with the TLS 1.3 CCM mode ciphersuites. Note that some linux
+   kernel versions that support KTLS have a known bug in CCM processing. That
+   has been fixed in stable releases starting from 5.4.164, 5.10.84, 5.15.7,
+   and all releases since 5.16. KTLS with CCM ciphersuites should be only used
+   on these releases.
+
+   *Tianjia Zhang*
+
+ * Added `-ktls` option to `s_server` and `s_client` commands to enable the
+   KTLS support.
+
+   *Tianjia Zhang*
+
+ * Zerocopy KTLS sendfile() support on Linux.
+
+   *Maxim Mikityanskiy*
+
+ * The OBJ_ calls are now thread safe using a global lock.
+
+   *Paul Dale*
+
+ * New parameter `-digest` for openssl cms command allowing signing
+   pre-computed digests and new CMS API functions supporting that
+   functionality.
+
+   *Viktor Söderqvist*
+
+ * OPENSSL_malloc() and other allocation functions now raise errors on
+   allocation failures. The callers do not need to explicitly raise errors
+   unless they want to for tracing purposes.
+
+   *David von Oheimb*
+
+ * Added and enabled by default implicit rejection in RSA PKCS#1 v1.5
+   decryption as a protection against Bleichenbacher-like attacks.
+   The RSA decryption API will now return a randomly generated deterministic
+   message instead of an error in case it detects an error when checking
+   padding during PKCS#1 v1.5 decryption. This is a general protection against
+   issues like CVE-2020-25659 and CVE-2020-25657. This protection can be
+   disabled by calling
+   `EVP_PKEY_CTX_ctrl_str(ctx, "rsa_pkcs1_implicit_rejection". "0")`
+   on the RSA decryption context.
+
+   *Hubert Kario*
+
+ * Added support for Brainpool curves in TLS-1.3.
+
+   *Bernd Edlinger and Matt Caswell*
+
+ * Added OpenBSD specific build targets.
+
+   *David Carlier*
+
+ * Support for Argon2d, Argon2i, Argon2id KDFs has been added along with
+   a basic thread pool implementation for select platforms.
+
+   *Čestmír Kalina*
+
 OpenSSL 3.1
 -----------
 
+### Changes between 3.1.4 and 3.1.5 [xx XXX xxxx]
+
+ * Fix excessive time spent in DH check / generation with large Q parameter
+   value.
+
+   Applications that use the functions DH_generate_key() to generate an
+   X9.42 DH key may experience long delays. Likewise, applications that use
+   DH_check_pub_key(), DH_check_pub_key_ex() or EVP_PKEY_public_check()
+   to check an X9.42 DH key or X9.42 DH parameters may experience long delays.
+   Where the key or parameters that are being checked have been obtained from
+   an untrusted source this may lead to a Denial of Service.
+
+   ([CVE-2023-5678])
+
+   *Richard Levitte*
+
 ### Changes between 3.1.3 and 3.1.4 [24 Oct 2023]
 
  * Fix incorrect key and IV resizing issues when calling EVP_EncryptInit_ex2(),
@@ -459,24 +930,6 @@ breaking changes, and mappings for the large list of deprecated functions.
 
    *Nicola Tuveri*
 
- * Fixed a type confusion vulnerability relating to X.400 address processing
-   inside an X.509 GeneralName. X.400 addresses were parsed as an `ASN1_STRING`
-   but subsequently interpreted by `GENERAL_NAME_cmp` as an `ASN1_TYPE`. This
-   vulnerability may allow an attacker who can provide a certificate chain and
-   CRL (neither of which need have a valid signature) to pass arbitrary pointers
-   to a `memcmp` call, creating a possible read primitive, subject to some
-   constraints. Refer to the advisory for more information. Thanks to David
-   Benjamin for discovering this issue. ([CVE-2023-0286])
-
-   This issue has been fixed by changing the public header file definition of
-   `GENERAL_NAME` so that `x400Address` reflects the implementation. It was not
-   possible for any existing application to successfully use the existing
-   definition; however, if any application references the `x400Address` field
-   (e.g. in dead code), note that the type of this field has changed. There is
-   no ABI change.
-
-   *Hugo Landau*
-
 ### Changes between 3.0.6 and 3.0.7 [1 Nov 2022]
 
  * Fixed two buffer overflows in punycode decoding functions.
@@ -934,7 +1387,7 @@ breaking changes, and mappings for the large list of deprecated functions.
 
    *Richard Levitte*
 
-### Changes between 1.1.1 and 3.0.0 [7 sep 2021]
+### Changes between 1.1.1 and 3.0.0 [7 Sep 2021]
 
  * TLS_MAX_VERSION, DTLS_MAX_VERSION and DTLS_MIN_VERSION constants are now
    deprecated.
@@ -1731,7 +2184,7 @@ breaking changes, and mappings for the large list of deprecated functions.
    3-prime RSA1536, and DSA1024 as a result of this defect would be very
    difficult to perform and are not believed likely. Attacks against DH512
    are considered just feasible. However, for an attack the target would
-   have to re-use the DH512 private key, which is not recommended anyway.
+   have to reuse the DH512 private key, which is not recommended anyway.
    Also applications directly using the low-level API BN_mod_exp may be
    affected if they use BN_FLG_CONSTTIME.
    ([CVE-2019-1551])
@@ -2359,7 +2812,9 @@ breaking changes, and mappings for the large list of deprecated functions.
 OpenSSL 1.1.1
 -------------
 
-### Changes between 1.1.1l and 1.1.1m [xx XXX xxxx]
+### Changes between 1.1.1m and 1.1.1n [xx XXX xxxx]
+
+### Changes between 1.1.1l and 1.1.1m [14 Dec 2021]
 
  * Avoid loading of a dynamic engine twice.
 
@@ -7321,7 +7776,7 @@ OpenSSL 1.0.1
 
  * Alternate chains certificate forgery
 
-   During certificate verfification, OpenSSL will attempt to find an
+   During certificate verification, OpenSSL will attempt to find an
    alternative certificate chain if the first attempt to build such a chain
    fails. An error in the implementation of this logic can mean that an
    attacker could cause certain checks on untrusted certificates to be
@@ -8680,7 +9135,7 @@ OpenSSL 1.0.0
 
    3. Check DSA/ECDSA signatures use DER.
 
-   Reencode DSA/ECDSA signatures and compare with the original received
+   Re-encode DSA/ECDSA signatures and compare with the original received
    signature. Return an error if there is a mismatch.
 
    This will reject various cases including garbage after signature
@@ -8727,7 +9182,7 @@ OpenSSL 1.0.0
 
  * Add additional DigestInfo checks.
 
-   Reencode DigestInto in DER and check against the original when
+   Re-encode DigestInto in DER and check against the original when
    verifying RSA signature: this will reject any improperly encoded
    DigestInfo structures.
 
@@ -19864,6 +20319,7 @@ ndif
 
 <!-- Links -->
 
+[CVE-2023-5678]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-5678
 [CVE-2023-5363]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-5363
 [CVE-2023-4807]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-4807
 [CVE-2023-3817]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-3817

+ 46 - 6
libs/openssl/Configurations/00-base-templates.conf

@@ -48,15 +48,23 @@ my %targets=(
 	defines		=>
 	    sub {
                 my @defs = ( 'OPENSSL_BUILDING_OPENSSL' );
+                push @defs, "BROTLI" unless $disabled{brotli};
+                push @defs, "BROTLI_SHARED" unless $disabled{"brotli-dynamic"};
                 push @defs, "ZLIB" unless $disabled{zlib};
                 push @defs, "ZLIB_SHARED" unless $disabled{"zlib-dynamic"};
+                push @defs, "ZSTD" unless $disabled{zstd};
+                push @defs, "ZSTD_SHARED" unless $disabled{"zstd-dynamic"};
                 return [ @defs ];
             },
         includes        =>
             sub {
                 my @incs = ();
+                push @incs, $withargs{brotli_include}
+                    if !$disabled{brotli} && $withargs{brotli_include};
                 push @incs, $withargs{zlib_include}
                     if !$disabled{zlib} && $withargs{zlib_include};
+                push @incs, $withargs{zstd_include}
+                    if !$disabled{zstd} && $withargs{zstd_include};
                 return [ @incs ];
             },
     },
@@ -69,11 +77,26 @@ my %targets=(
         ARFLAGS         => "qc",
         CC              => "cc",
         lflags          =>
-            sub { $withargs{zlib_lib} ? "-L".$withargs{zlib_lib} : () },
+            sub {
+                my @libs = ();
+                push(@libs, "-L".$withargs{zlib_lib}) if $withargs{zlib_lib};
+                push(@libs, "-L".$withargs{brotli_lib}) if $withargs{brotli_lib};
+                push(@libs, "-L".$withargs{zstd_lib}) if $withargs{zstd_lib};
+                return join(" ", @libs);
+            },
         ex_libs         =>
-            sub { !defined($disabled{zlib})
-                  && defined($disabled{"zlib-dynamic"})
-                  ? "-lz" : () },
+            sub {
+                my @libs = ();
+                push(@libs, "-lz") if !defined($disabled{zlib}) && defined($disabled{"zlib-dynamic"});
+                if (!defined($disabled{brotli}) && defined($disabled{"brotli-dynamic"})) {
+                    push(@libs, "-lbrotlienc");
+                    push(@libs, "-lbrotlidec");
+                    push(@libs, "-lbrotlicommon");
+                    push(@libs, "-lm");
+                }
+                push(@libs, "-lzstd") if !defined($disabled{zstd}) && defined($disabled{"zstd-dynamic"});
+                return join(" ", @libs);
+            },
         HASHBANGPERL    => "/usr/bin/env perl", # Only Unix actually cares
         RANLIB          => sub { which("$config{cross_compile_prefix}ranlib")
                                      ? "ranlib" : "" },
@@ -100,12 +123,29 @@ my %targets=(
             },
         ex_libs         =>
             sub {
+                my @libs = ();
                 unless ($disabled{zlib}) {
                     if (defined($disabled{"zlib-dynamic"})) {
-                        return $withargs{zlib_lib} // "ZLIB1";
+                        push(@libs, $withargs{zlib_lib} // "ZLIB1");
+                    }
+                }
+                unless ($disabled{zstd}) {
+                    if (defined($disabled{"zstd-dynamic"})) {
+                        push(@libs, $withargs{zstd_lib} // "libzstd");
+                    }
+                }
+                unless ($disabled{brotli}) {
+                    if (defined($disabled{"brotli-dynamic"})) {
+                        my $path = "";
+                        if (defined($withargs{brotli_lib})) {
+                            $path = $withargs{brotli_lib} . "\\";
+                        }
+                        push(@libs, $path . "brotlicommon.lib");
+                        push(@libs, $path . "brotlidec.lib");
+                        push(@libs, $path . "brotlienc.lib");
                     }
                 }
-                return ();
+                return join(" ", @libs);
             },
 
         MT              => "mt",

+ 122 - 16
libs/openssl/Configurations/10-main.conf

@@ -242,9 +242,7 @@ my %targets = (
         CFLAGS           => add_before(picker(default => "-Wall",
                                               debug   => "-O0 -g",
                                               release => "-O3 -fomit-frame-pointer")),
-        cflags           => add(threads("-pthread")),
         lib_cppflags     => add("-DL_ENDIAN"),
-        ex_libs          => add(threads("-pthread")),
         bn_ops           => "BN_LLONG",
         shared_cflag     => "-fPIC",
         shared_ldflag    => add_before("-shared -static-libgcc"),
@@ -265,9 +263,8 @@ my %targets = (
         CFLAGS           => add_before(picker(default => "-Wall",
                                               debug   => "-O0 -g",
                                               release => "-O3")),
-        cflags           => add_before("-m64", threads("-pthread")),
+        cflags           => add("-m64"),
         lib_cppflags     => add("-DL_ENDIAN"),
-        ex_libs          => add(threads("-pthread")),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
         asm_arch         => 'x86_64',
         perlasm_scheme   => "elf",
@@ -299,7 +296,6 @@ my %targets = (
         lib_cppflags     => add("-DL_ENDIAN"),
         thread_scheme    => "pthreads",
         lflags           => add(threads("-mt")),
-        ex_libs          => add(threads("-lpthread")),
         bn_ops           => "SIXTY_FOUR_BIT_LONG",
         asm_arch         => 'x86_64',
         perlasm_scheme   => "elf",
@@ -315,9 +311,7 @@ my %targets = (
         CFLAGS           => add_before(picker(default => "-Wall",
                                               debug   => "-O0 -g",
                                               release => "-O3")),
-        cflags           => add(threads("-pthread")),
         lib_cppflags     => add("-DB_ENDIAN -DBN_DIV2W"),
-        ex_libs          => add(threads("-pthread")),
         bn_ops           => "BN_LLONG RC4_CHAR",
         shared_cflag     => "-fPIC",
         shared_ldflag    => add_before("-shared -static-libgcc"),
@@ -356,7 +350,6 @@ my %targets = (
         cppflags         => add(threads("-D_REENTRANT")),
         lib_cppflags     => add("-DB_ENDIAN -DBN_DIV2W"),
         lflags           => add(threads("-mt")),
-        ex_libs          => add(threads("-lpthread")),
         bn_ops           => "BN_LLONG RC4_CHAR",
         shared_cflag     => "-KPIC",
         shared_ldflag    => add_before("-G -dy -z text"),
@@ -823,12 +816,12 @@ my %targets = (
     },
 
     "linux32-riscv32" => {
-        inherit_from     => [ "linux-generic32"],
+        inherit_from     => [ "linux-latomic" ],
         perlasm_scheme   => "linux32",
         asm_arch         => 'riscv32',
     },
 
-    # loongarch64 below refers to contemporary LoongArch Architecture
+    # loongarch64 below refers to contemporary LOONGARCH Architecture
     # specifications,
     "linux64-loongarch64" => {
         inherit_from     => [ "linux-generic64"],
@@ -871,6 +864,10 @@ my %targets = (
         asm_arch         => 'x86',
         perlasm_scheme   => "elf",
     },
+    "linux-x86-latomic" => {
+        inherit_from     => [ "linux-x86" ],
+        ex_libs          => add(threads("-latomic")),
+    },
     "linux-x86-clang" => {
         inherit_from     => [ "linux-x86" ],
         CC               => "clang",
@@ -1178,6 +1175,81 @@ my %targets = (
         shared_target    => "bsd-gcc-shared",
         shared_cflag     => "-fPIC",
     },
+#### *BSD-nodef
+    "BSD-nodef-generic32" => {
+        # As for thread cflag. Idea is to maintain "collective" set of
+        # flags, which would cover all BSD flavors. -pthread applies
+        # to them all, but is treated differently. OpenBSD expands is
+        # as -D_POSIX_THREAD -lc_r, which is sufficient. FreeBSD 4.x
+        # expands it as -lc_r, which has to be accompanied by explicit
+        # -D_THREAD_SAFE and sometimes -D_REENTRANT. FreeBSD 5.x
+        # expands it as -lc_r, which seems to be sufficient?
+        inherit_from     => [ "BASE_unix" ],
+        CC               => "cc",
+        CFLAGS           => picker(default => "-Wall",
+                                   debug   => "-O0 -g",
+                                   release => "-O3"),
+        cflags           => threads("-pthread"),
+        cppflags         => threads("-D_THREAD_SAFE -D_REENTRANT"),
+        ex_libs          => add(threads("-pthread")),
+        enable           => add("devcryptoeng"),
+        bn_ops           => "BN_LLONG",
+        thread_scheme    => "pthreads",
+        dso_scheme       => "dlfcn",
+        shared_target    => "bsd-gcc-nodef-shared",
+        shared_cflag     => "-fPIC",
+    },
+    "BSD-nodef-generic64" => {
+        inherit_from     => [ "BSD-nodef-generic32" ],
+        bn_ops           => "SIXTY_FOUR_BIT_LONG",
+    },
+
+    "BSD-nodef-x86" => {
+        inherit_from     => [ "BSD-nodef-generic32" ],
+        CFLAGS           => add(picker(release => "-fomit-frame-pointer")),
+        lib_cppflags     => add("-DL_ENDIAN"),
+        bn_ops           => "BN_LLONG",
+        asm_arch         => 'x86',
+        perlasm_scheme   => "a.out",
+    },
+    "BSD-nodef-x86-elf" => {
+        inherit_from     => [ "BSD-nodef-x86" ],
+        perlasm_scheme   => "elf",
+    },
+
+    "BSD-nodef-sparcv8" => {
+        inherit_from     => [ "BSD-nodef-generic32" ],
+        cflags           => add("-mcpu=v8"),
+        lib_cppflags     => add("-DB_ENDIAN"),
+        asm_arch         => 'sparcv8',
+        perlasm_scheme   => 'void',
+    },
+    "BSD-nodef-sparc64" => {
+        # -DMD32_REG_T=int doesn't actually belong in sparc64 target, it
+        # simply *happens* to work around a compiler bug in gcc 3.3.3,
+        # triggered by RIPEMD160 code.
+        inherit_from     => [ "BSD-nodef-generic64" ],
+        lib_cppflags     => add("-DB_ENDIAN -DMD32_REG_T=int"),
+        bn_ops           => "BN_LLONG",
+        asm_arch         => 'sparcv9',
+        perlasm_scheme   => 'void',
+    },
+
+    "BSD-nodef-ia64" => {
+        inherit_from     => [ "BSD-nodef-generic64" ],
+        lib_cppflags     => add("-DL_ENDIAN"),
+        bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        asm_arch         => 'ia64',
+        perlasm_scheme   => 'void',
+    },
+
+    "BSD-nodef-x86_64" => {
+        inherit_from     => [ "BSD-nodef-generic64" ],
+        lib_cppflags     => add("-DL_ENDIAN"),
+        bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        asm_arch         => 'x86_64',
+        perlasm_scheme   => "elf",
+    },
 
 #### SCO/Caldera targets.
 #
@@ -1652,6 +1724,7 @@ my %targets = (
         CFLAGS           => picker(default => "-Wall",
                                    debug   => "-g -O0",
                                    release => "-O3"),
+        ex_libs          => add("-lcrypt32"),
         lib_cppflags     => "-DTERMIOS -DL_ENDIAN",
         sys_id           => "CYGWIN",
         thread_scheme    => "pthread",
@@ -1765,20 +1838,53 @@ my %targets = (
     },
 
 ##### GNU Hurd
-    "hurd-x86" => {
+    "hurd-generic32" => {
         inherit_from     => [ "BASE_unix" ],
         CC               => "gcc",
-        CFLAGS           => "-O3 -fomit-frame-pointer -Wall",
+        CXX              => "g++",
+        CFLAGS           => picker(default => "-Wall",
+                                   debug   => "-O0 -g",
+                                   release => "-O3"),
+        CXXFLAGS         => picker(default => "-Wall",
+                                   debug   => "-O0 -g",
+                                   release => "-O3"),
         cflags           => threads("-pthread"),
-        lib_cppflags     => "-DL_ENDIAN",
+        cxxflags         => combine("-std=c++11", threads("-pthread")),
         ex_libs          => add("-ldl", threads("-pthread")),
-        bn_ops           => "BN_LLONG",
-        asm_arch         => 'x86',
-        perlasm_scheme   => 'elf',
+        bn_ops           => "BN_LLONG RC4_CHAR",
         thread_scheme    => "pthreads",
         dso_scheme       => "dlfcn",
         shared_target    => "linux-shared",
         shared_cflag     => "-fPIC",
+        shared_ldflag    => sub { $disabled{pinshared} ? () : "-Wl,-znodelete" },
+    },
+
+    "hurd-generic64" => {
+        inherit_from     => [ "hurd-generic32" ],
+        bn_ops           => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
+    },
+
+    #### X86 / X86_64 targets
+    "hurd-x86" => {
+        inherit_from     => [ "hurd-generic32" ],
+        CFLAGS           => add(picker(release => "-fomit-frame-pointer")),
+        cflags           => add("-m32"),
+        cxxflags         => add("-m32"),
+        lib_cppflags     => add("-DL_ENDIAN"),
+        bn_ops           => "BN_LLONG",
+        asm_arch         => 'x86',
+        perlasm_scheme   => 'elf',
+    },
+
+    "hurd-x86_64" => {
+        inherit_from     => [ "hurd-generic64" ],
+        cflags           => add("-m64"),
+        cxxflags         => add("-m64"),
+        lib_cppflags     => add("-DL_ENDIAN"),
+        bn_ops           => "SIXTY_FOUR_BIT_LONG",
+        asm_arch         => 'x86_64',
+        perlasm_scheme   => 'elf',
+        multilib         => "64",
     },
 
 ##### VxWorks for various targets

+ 29 - 4
libs/openssl/Configurations/15-ios.conf

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

+ 15 - 2
libs/openssl/Configurations/50-nonstop.conf

@@ -14,6 +14,7 @@
                                 '_XOPEN_SOURCE',
                                 '_XOPEN_SOURCE_EXTENDED=1',
                                 '_TANDEM_SOURCE',
+                                '__NSK_OPTIONAL_TYPES__',
                                 'B_ENDIAN'),
         perl             => '/usr/bin/perl',
         shared_target    => 'nonstop-shared',
@@ -171,8 +172,10 @@
     },
     'nonstop-model-spt' => {
         template         => 1,
+        cflags           => add('-Wnowarn=140'),
         defines          => ['_SPT_MODEL_',
-                             '_REENTRANT', '_ENABLE_FLOSS_THREADS'],
+                             'SPT_THREAD_AWARE_NONBLOCK',
+                             '_REENTRANT'],
         ex_libs          => '-lspt',
     },
 
@@ -181,7 +184,7 @@
     # disable threads.
     'nonstop-model-floss' => {
         template         => 1,
-        defines          => ['OPENSSL_TANDEM_FLOSS'],
+        defines          => ['OPENSSL_TANDEM_FLOSS', '_ENABLE_FLOSS_THREADS'],
         includes         => ['/usr/local/include'],
         ex_libs          => '-lfloss',
     },
@@ -202,6 +205,7 @@
                               'nonstop-efloat-x86_64',
                               'nonstop-model-put' ],
         multilib         => '-put',
+        multibin         => '-put',
     },
     'nonstop-nsx_64' => {
         inherit_from     => [ 'nonstop-common',
@@ -209,6 +213,7 @@
                               'nonstop-lp64-x86_64',
                               'nonstop-efloat-x86_64' ],
         multilib         => '64',
+        multibin         => '64',
         disable          => ['threads'],
     },
     'nonstop-nsx_64_put' => {
@@ -218,6 +223,7 @@
                               'nonstop-efloat-x86_64',
                               'nonstop-model-put' ],
         multilib         => '64-put',
+        multibin         => '64-put',
     },
     'nonstop-nsx_spt' => {
         inherit_from     => [ 'nonstop-common',
@@ -226,6 +232,7 @@
                               'nonstop-efloat-x86_64',
                               'nonstop-model-spt' ],
         multilib         => '-spt',
+        multibin         => '-spt',
     },
     'nonstop-nsx_spt_floss' => {
         inherit_from     => [ 'nonstop-common',
@@ -235,6 +242,7 @@
                               'nonstop-model-floss',
                               'nonstop-model-spt'],
         multilib         => '-spt',
+        multibin         => '-spt',
     },
     'nonstop-nsx_g' => {
         inherit_from     => [ 'nonstop-common',
@@ -265,6 +273,7 @@
                               'nonstop-efloat-itanium',
                               'nonstop-model-put' ],
         multilib         => '-put',
+        multibin         => '-put',
     },
     'nonstop-nse_64' => {
         inherit_from     => [ 'nonstop-common',
@@ -272,6 +281,7 @@
                               'nonstop-lp64-itanium',
                               'nonstop-efloat-itanium' ],
         multilib         => '64',
+        multibin         => '64',
         disable          => ['threads'],
     },
     'nonstop-nse_64_put' => {
@@ -281,6 +291,7 @@
                               'nonstop-efloat-itanium',
                               'nonstop-model-put' ],
         multilib         => '64-put',
+        multibin         => '64-put',
     },
     'nonstop-nse_spt' => {
         inherit_from     => [ 'nonstop-common',
@@ -289,6 +300,7 @@
                               'nonstop-efloat-itanium',
                               'nonstop-model-spt' ],
         multilib         => '-spt',
+        multibin         => '-spt',
     },
     'nonstop-nse_spt_floss' => {
         inherit_from     => [ 'nonstop-common',
@@ -297,6 +309,7 @@
                               'nonstop-efloat-itanium',
                               'nonstop-model-floss', 'nonstop-model-spt' ],
         multilib         => '-spt',
+        multibin         => '-spt',
     },
     'nonstop-nse_g' => {
         inherit_from     => [ 'nonstop-common',

+ 37 - 0
libs/openssl/Configurations/50-win-hybridcrt.conf

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

+ 4 - 5
libs/openssl/Configurations/50-win-onecore.conf

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

+ 7 - 0
libs/openssl/Configurations/README.md

@@ -203,6 +203,13 @@ In each table entry, the following keys are significant:
                            to have the different variants in different
                            directories.
 
+        multibin        => On systems that support having multiple
+                           implementations of a library and binaries
+                           (typically a 32-bit and a 64-bit variant),
+                           this is used to have the different variants
+                           in different binary directories. This setting
+                           works in conjunction with multilib.
+
         bn_ops          => Building options (was just bignum options in
                            the earlier history of this option, hence the
                            name). This is a string of words that describe

+ 87 - 17
libs/openssl/Configurations/descrip.mms.tmpl

@@ -205,13 +205,16 @@
                @cnf_ldflags, '$(LDFLAGS)');
   our $bin_ex_libs = join('', @cnf_ex_libs, '$(EX_LIBS)');
 
-  # This is a horrible hack, but is needed because recursive inclusion of files
-  # in different directories does not work well with VMS C.  We try to help by
-  # specifying extra relative directories.  They must always be in Unix format,
-  # relative to the directory where the .c file is located.  The logic is that
-  # any inclusion, merged with one of these relative directories, will find the
-  # requested inclusion file.
-  foreach (grep /\[\.crypto\.async\.arch\].*\.o$/, keys %{$unified_info{sources}}) {
+  # These are horrible hacks, but are needed because recursive inclusion of
+  # files in different directories does not work well with VMS C.  We try to
+  # help by specifying extra relative directories.  They must always be in Unix
+  # format, relative to the directory where the .c file is located.  The logic
+  # is that any inclusion, merged with one of these relative directories, will
+  # find the requested inclusion file.
+  # In the regexps, it's advisable to always start the file name with .*?, as
+  # the C source to OBJ file translation adds stuff at the beginning of the,
+  # name, such as [.ssl]bio_ssl.c -> [.ssl]libssl-shlib-bio_ssl.OBJ
+  foreach (grep /\[\.crypto\.async\.arch\].*?\.o$/, keys %{$unified_info{sources}}) {
       my $obj = platform->obj($_);
       push @{$unified_info{includes_extra}->{$obj}}, qw(../);
   }
@@ -223,7 +226,20 @@
       my $obj = platform->obj($_);
       push @{$unified_info{includes_extra}->{$obj}}, qw(../);
   }
-  foreach (grep /\[\.ssl\.(?:record|statem)\].*?\.o$/, keys %{$unified_info{sources}}) {
+  foreach (grep /\[\.ssl\].*?\.o$/, keys %{$unified_info{sources}}) {
+      my $obj = platform->obj($_);
+      # Most of the files in [.ssl] include "ssl_local.h" which includes things
+      # like "record/record.h".  Adding "./" as an inclusion directory helps
+      # making this sort of header from these directories.
+      push @{$unified_info{includes_extra}->{$obj}}, qw(./);
+
+      # Additionally, an increasing amount of files in [.ssl] include
+      # "quic/quic_local.h", which in turn includes "../ssl_local.h".  Adding
+      # "./quic" as an inclusion directory helps making this sort of header
+      # from these directories.
+      push @{$unified_info{includes_extra}->{$obj}}, qw(./quic);
+  }
+  foreach (grep /\[\.ssl\.(?:quic|record|statem)\].*?\.o$/, keys %{$unified_info{sources}}) {
       my $obj = platform->obj($_);
       # Most of the files in [.ssl.record] and [.ssl.statem] include
       # "../ssl_local.h", which includes things like "record/record.h".
@@ -232,13 +248,35 @@
       push @{$unified_info{includes_extra}->{$obj}}, qw(../);
 
   }
+  foreach (grep /\[\.ssl\.record\.methods\].*?\.o$/, keys %{$unified_info{sources}}) {
+      my $obj = platform->obj($_);
+      # Most of the files in [.ssl.record.methods] include "../../ssl_local.h"
+      # which includes things like "record/record.h".  Adding "../../" as an
+      # inclusion directory helps making this sort of header from these
+      # directories.  But this gets worse; through a series of inclusions,
+      # all of them based on the relative directory of the object file, there's
+      # a need to deal with an inclusion of "../ssl_local.h" as well.
+      push @{$unified_info{includes_extra}->{$obj}}, qw(../../), qw(../);
+  }
   foreach (grep /\[\.test\].*?\.o$/, keys %{$unified_info{sources}}) {
       my $obj = platform->obj($_);
       push @{$unified_info{includes_extra}->{$obj}}, qw(../ssl ./helpers);
+      # Some of the sources in [.test] also include headers like
+      # "../ssl/record/methods/recmethod_local.h", which in turn might include
+      # "../../ssl_local.h", so these object files need yet another hack.
+      # We could make this specific to just the object files that are affected
+      # directly, but that would end up with more whack-a-mole of this sort, so
+      # nah, we do it broadly.
+      push @{$unified_info{includes_extra}->{$obj}}, qw(../ssl/record/methods);
+      # Similarly, some include "../ssl/ssl_local.h", and somewhere down the
+      # line, "quic/quic_local.h" gets included, which includes "../ssl_local.h"
+      # The problem is fixed by adding ../ssl/quic too.
+      push @{$unified_info{includes_extra}->{$obj}}, qw(../ssl/quic);
   }
   foreach (grep /\[\.test\.helpers\].*?\.o$/, keys %{$unified_info{sources}}) {
       my $obj = platform->obj($_);
-      push @{$unified_info{includes_extra}->{$obj}}, qw(../../ssl);
+      push @{$unified_info{includes_extra}->{$obj}},
+          qw(../../ssl ../../ssl/quic);
   }
 
   # This makes sure things get built in the order they need
@@ -436,7 +474,7 @@ NODEBUG=@
         $(NODEBUG) ! Set up logical names for the libraries, so LINK and
         $(NODEBUG) ! running programs can use them.
         $(NODEBUG) !
-        $(NODEBUG) {- join("\n\t\$(NODEBUG) ", map { "DEFINE ".uc($_)." 'F\$ENV(\"DEFAULT\")'".uc($_)."\$(SHLIB_EXT)" } @shlibs) || "!" -}
+        $(NODEBUG) {- join("\n\t\$(NODEBUG) ", map { "DEFINE ".uc($_)." 'F\$ENV(\"DEFAULT\")'".uc($_).".EXE" } @shlibs) || "!" -}
 
 .LAST :
         $(NODEBUG) {- join("\n\t\$(NODEBUG) ", map { "DEASSIGN ".uc($_) } @shlibs) || "!" -}
@@ -1027,16 +1065,48 @@ EOF
           my $dofile = abs2rel(rel2abs(catfile($config{sourcedir},
                                                "util", "dofile.pl")),
                                rel2abs($config{builddir}));
-          my @perlmodules = ( 'configdata.pm',
-                              grep { $_ =~ m|\.pm$| } @{$args{deps}} );
-          my %perlmoduleincs = map { '"-I'.dirname($_).'"' => 1 } @perlmodules;
+          my @perlmodules = ();
+          my %perlmoduleincs = ();
+          my %perlmoduledeps = ();
+          foreach my $x (('configdata.pm', @{$args{deps}})) {
+              # Compute (i)nclusion directory, (m)odule name and (d)ependency
+              my $i, $m, $d;
+              if ($x =~ /\|/) {
+                  $i = $`;
+                  $d = $';
+
+                  # Massage the module part to become a real perl module spec
+                  $m = $d;
+                  $m =~ s|\.pm$||;
+                  # Directory specs are :: in perl package names
+                  $m =~ s|/|::|g;
+
+                  # Full file name of the dependency
+                  $d = catfile($i, $d) if $i;
+              } elsif ($x =~ /\.pm$/) {
+                  $i = dirname($x);
+                  $m = basename($x, '.pm');
+                  $d = $x;
+              } else {
+                  # All other dependencies are simply collected
+                  $d = $x;
+              }
+              push @perlmodules, '"-M'.$m.'"' if $m;
+              $perlmoduledeps{$d} = 1;
+              $perlmoduleincs{'"-I'.$i.'"'} = 1 if $i;
+          }
+
           my @decc_include_data
               = make_decc_include_files(dirname($args{src}), dirname($gen0));
           my $decc_include_scripture = pop @decc_include_data;
-          $deps = join(' ', $deps, @decc_include_data,
-                            compute_platform_depends(@perlmodules));
-          @perlmodules = map { '"-M'.basename($_, '.pm').'"' } @perlmodules;
-          my $perlmodules = join(' ', '', sort keys %perlmoduleincs, @perlmodules);
+          # Because of the special treatment of dependencies, we need to
+          # recompute $deps completely
+          my $deps
+              = join(" ", @decc_include_data,
+                          compute_platform_depends(@{$args{generator_deps}},
+                                                   sort keys %perlmoduledeps));
+          my $perlmodules = join(' ', '', ( sort keys %perlmoduleincs ), @perlmodules);
+
 
           return <<"EOF";
 $args{src} : $gen0 $deps

+ 7 - 1
libs/openssl/Configurations/shared-info.pl

@@ -1,6 +1,6 @@
 #! /usr/bin/env perl
 # -*- mode: perl; -*-
-# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the Apache License 2.0 (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -40,6 +40,12 @@ my %shared_info;
         };
     },
     'bsd-gcc-shared' => sub { return $shared_info{'linux-shared'}; },
+    'bsd-gcc-nodef-shared' => sub { 
+        return {
+            %{$shared_info{'gnu-shared'}},
+            shared_defflags     => '-Wl,--version-script=',
+        };
+    },
     'darwin-shared' => {
         module_ldflags        => '-bundle',
         shared_ldflag         => '-dynamiclib -current_version $(SHLIB_VERSION_NUMBER) -compatibility_version $(SHLIB_VERSION_NUMBER)',

+ 139 - 61
libs/openssl/Configurations/unix-Makefile.tmpl

@@ -20,8 +20,9 @@
      # to. You're welcome.
      sub dependmagic {
          my $target = shift;
+         my $help = shift;
 
-         return "$target: build_generated\n\t\$(MAKE) depend && \$(MAKE) _$target\n_$target";
+         return "$target: build_generated ## $help\n\t\$(MAKE) depend && \$(MAKE) _$target\n_$target";
      }
 
      our $COLUMNS = $ENV{COLUMNS};
@@ -311,6 +312,14 @@ MODULESDIR=$(libdir)/ossl-modules
 # libraries and applications
 LIBRPATH=$(libdir)
 
+BINDIR={- our $bindir = $config{bindir};
+          unless ($bindir) {
+              $bindir = "bin$target{multibin}";
+          }
+          file_name_is_absolute($bindir) ? "" : $bindir -}
+bindir={- file_name_is_absolute($bindir)
+          ? $bindir : '$(INSTALLTOP)/$(BINDIR)' -}
+
 MANDIR=$(INSTALLTOP)/share/man
 DOCDIR=$(INSTALLTOP)/share/doc/$(BASENAME)
 HTMLDIR=$(DOCDIR)/html
@@ -496,15 +505,20 @@ LANG=C
 
 # The main targets ###################################################
 
-{- dependmagic('build_sw'); -}: build_libs_nodep build_modules_nodep build_programs_nodep link-utils
-{- dependmagic('build_libs'); -}: build_libs_nodep
-{- dependmagic('build_modules'); -}: build_modules_nodep
-{- dependmagic('build_programs'); -}: build_programs_nodep
+##@ Software
+
+{- dependmagic('build_sw', 'Build all the software (default target)'); -}: build_libs_nodep build_modules_nodep build_programs_nodep link-utils
+{- dependmagic('build_libs', 'Build the libraries libssl and libcrypto'); -}: build_libs_nodep
+{- dependmagic('build_modules', 'Build the modules (i.e. providers and engines)'); -}: build_modules_nodep
+{- dependmagic('build_programs', 'Build the openssl executables and scripts'); -}: build_programs_nodep
+
+all: build_sw {- "build_docs" if !$disabled{docs}; -} ## Build software and documentation
 
+##@ Documentation
 build_generated_pods: $(GENERATED_PODS)
-build_docs: build_man_docs build_html_docs
-build_man_docs: $(MANDOCS1) $(MANDOCS3) $(MANDOCS5) $(MANDOCS7)
-build_html_docs: $(HTMLDOCS1) $(HTMLDOCS3) $(HTMLDOCS5) $(HTMLDOCS7)
+build_docs: build_man_docs build_html_docs ## Create documentation
+build_man_docs: $(MANDOCS1) $(MANDOCS3) $(MANDOCS5) $(MANDOCS7) ## Create manpages
+build_html_docs: $(HTMLDOCS1) $(HTMLDOCS3) $(HTMLDOCS5) $(HTMLDOCS7) ## Create HTML documentation
 
 build_generated: $(GENERATED_MANDATORY)
 build_libs_nodep: libcrypto.pc libssl.pc openssl.pc
@@ -523,10 +537,14 @@ build_all_generated: $(GENERATED_MANDATORY) $(GENERATED) build_docs
 	@echo "         then make will fail..."
 	@ : {- output_on() if $disabled{makedepend}; "" -}
 
-all: build_sw build_docs
+##@ Help
+.PHONY: help
+help: ## Show this help screen
+	@$(PERL) $(SRCDIR)/util/help.pl $(BLDDIR)/Makefile
 
-test: tests
-{- dependmagic('tests'); -}: build_programs_nodep build_modules_nodep link-utils run_tests
+##@ Testing
+test: tests ## Run tests (alias of "tests")
+{- dependmagic('tests', 'Run tests'); -}: build_programs_nodep build_modules_nodep link-utils run_tests
 run_tests:
 	@ : {- output_off() if $disabled{tests}; "" -}
 	( SRCTOP=$(SRCDIR) \
@@ -539,16 +557,14 @@ run_tests:
 	@echo "Tests are not supported with your chosen Configure options"
 	@ : {- output_on() if !$disabled{tests}; "" -}
 
-list-tests:
+list-tests: ## List available tests that can be invoked via "make test TESTS=<name>"
 	@ : {- output_off() if $disabled{tests}; "" -}
 	$(MAKE) run_tests TESTS=list
 	@ : {- if ($disabled{tests}) { output_on(); } else { output_off(); } "" -}
 	@echo "Tests are not supported with your chosen Configure options"
 	@ : {- output_on() if !$disabled{tests}; "" -}
 
-install: install_sw install_ssldirs install_docs {- $disabled{fips} ? "" : "install_fips" -}
-
-uninstall: uninstall_docs uninstall_sw {- $disabled{fips} ? "" : "uninstall_fips" -}
+##@ Workspace cleaning
 
 libclean:
 	@set -e; for s in $(SHLIB_INFO); do \
@@ -573,7 +589,7 @@ libclean:
 	$(RM) $(LIBS)
 	$(RM) *{- platform->defext() -}
 
-clean: libclean
+clean: libclean ## Clean the workspace, keep the configuration
 	$(RM) $(HTMLDOCS1)
 	$(RM) $(HTMLDOCS3)
 	$(RM) $(HTMLDOCS5)
@@ -593,7 +609,7 @@ clean: libclean
 	$(RM) openssl.pc libcrypto.pc libssl.pc
 	-find . -type l \! -name '.*' -exec $(RM) {} \;
 
-distclean: clean
+distclean: clean ## Clean and remove the configuration
 	$(RM) include/openssl/configuration.h
 	$(RM) configdata.pm
 	$(RM) Makefile
@@ -606,14 +622,19 @@ depend: Makefile
 	@: {- output_on() if $disabled{makedepend}; "" -}
 
 # Install helper targets #############################################
+##@ Installation
+
+install: install_sw install_ssldirs {- "install_docs" if !$disabled{docs}; -} {- $disabled{fips} ? "" : "install_fips" -} ## Install software and documentation, create OpenSSL directories
+
+uninstall: {- "uninstall_docs" if !$disabled{docs}; -} uninstall_sw {- $disabled{fips} ? "" : "uninstall_fips" -} ## Uninstall software and documentation
 
-install_sw: install_dev install_engines install_modules install_runtime
+install_sw: install_dev install_engines install_modules install_runtime ## Install just the software and libraries
 
-uninstall_sw: uninstall_runtime uninstall_modules uninstall_engines uninstall_dev
+uninstall_sw: uninstall_runtime uninstall_modules uninstall_engines uninstall_dev ## Uninstall the software and libraries
 
-install_docs: install_man_docs install_html_docs
+install_docs: install_man_docs install_html_docs ## Install manpages and HTML documentation
 
-uninstall_docs: uninstall_man_docs uninstall_html_docs
+uninstall_docs: uninstall_man_docs uninstall_html_docs ## Uninstall manpages and HTML documentation
 	$(RM) -r "$(DESTDIR)$(DOCDIR)"
 
 {- output_off() if $disabled{fips}; "" -}
@@ -871,18 +892,18 @@ install_runtime_libs: build_libs
 	@ : {- output_off() if windowsdll(); "" -}
 	@$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(libdir)"
 	@ : {- output_on() if windowsdll(); output_off() unless windowsdll(); "" -}
-	@$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(INSTALLTOP)/bin"
+	@$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(bindir)/"
 	@ : {- output_on() unless windowsdll(); "" -}
 	@$(ECHO) "*** Installing runtime libraries"
 	@set -e; for s in dummy $(INSTALL_SHLIBS); do \
 		if [ "$$s" = "dummy" ]; then continue; fi; \
 		fn=`basename $$s`; \
 		: {- output_off() unless windowsdll(); "" -}; \
-		$(ECHO) "install $$s -> $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
-		cp $$s "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new"; \
-		chmod 755 "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new"; \
-		mv -f "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new" \
-		      "$(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
+		$(ECHO) "install $$s -> $(DESTDIR)$(bindir)/$$fn"; \
+		cp $$s "$(DESTDIR)$(bindir)/$$fn.new"; \
+		chmod 755 "$(DESTDIR)$(bindir)/$$fn.new"; \
+		mv -f "$(DESTDIR)$(bindir)/$$fn.new" \
+		      "$(DESTDIR)$(bindir)/$$fn"; \
 		: {- output_on() unless windowsdll(); "" -}{- output_off() if windowsdll(); "" -}; \
 		$(ECHO) "install $$s -> $(DESTDIR)$(libdir)/$$fn"; \
 		cp $$s "$(DESTDIR)$(libdir)/$$fn.new"; \
@@ -894,25 +915,25 @@ install_runtime_libs: build_libs
 
 install_programs: install_runtime_libs build_programs
 	@[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1)
-	@$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(INSTALLTOP)/bin"
+	@$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(bindir)"
 	@$(ECHO) "*** Installing runtime programs"
 	@set -e; for x in dummy $(INSTALL_PROGRAMS); do \
 		if [ "$$x" = "dummy" ]; then continue; fi; \
 		fn=`basename $$x`; \
-		$(ECHO) "install $$x -> $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
-		cp $$x "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new"; \
-		chmod 755 "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new"; \
-		mv -f "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new" \
-		      "$(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
+		$(ECHO) "install $$x -> $(DESTDIR)$(bindir)/$$fn"; \
+		cp $$x "$(DESTDIR)$(bindir)/$$fn.new"; \
+		chmod 755 "$(DESTDIR)$(bindir)/$$fn.new"; \
+		mv -f "$(DESTDIR)$(bindir)/$$fn.new" \
+		      "$(DESTDIR)$(bindir)/$$fn"; \
 	done
 	@set -e; for x in dummy $(BIN_SCRIPTS); do \
 		if [ "$$x" = "dummy" ]; then continue; fi; \
 		fn=`basename $$x`; \
-		$(ECHO) "install $$x -> $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
-		cp $$x "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new"; \
-		chmod 755 "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new"; \
-		mv -f "$(DESTDIR)$(INSTALLTOP)/bin/$$fn.new" \
-		      "$(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
+		$(ECHO) "install $$x -> $(DESTDIR)$(bindir)/$$fn"; \
+		cp $$x "$(DESTDIR)$(bindir)/$$fn.new"; \
+		chmod 755 "$(DESTDIR)$(bindir)/$$fn.new"; \
+		mv -f "$(DESTDIR)$(bindir)/$$fn.new" \
+		      "$(DESTDIR)$(bindir)/$$fn"; \
 	done
 
 uninstall_runtime: uninstall_programs uninstall_runtime_libs
@@ -923,17 +944,17 @@ uninstall_programs:
 	do  \
 		if [ "$$x" = "dummy" ]; then continue; fi; \
 		fn=`basename $$x`; \
-		$(ECHO) "$(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
-		$(RM) "$(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
+		$(ECHO) "$(RM) $(DESTDIR)$(bindir)/$$fn"; \
+		$(RM) "$(DESTDIR)$(bindir)/$$fn"; \
 	done;
 	@set -e; for x in dummy $(BIN_SCRIPTS); \
 	do  \
 		if [ "$$x" = "dummy" ]; then continue; fi; \
 		fn=`basename $$x`; \
-		$(ECHO) "$(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
-		$(RM) "$(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
+		$(ECHO) "$(RM) $(DESTDIR)$(bindir)/$$fn"; \
+		$(RM) "$(DESTDIR)$(bindir)/$$fn"; \
 	done
-	-$(RMDIR) "$(DESTDIR)$(INSTALLTOP)/bin"
+	-$(RMDIR) "$(DESTDIR)$(bindir)"
 
 uninstall_runtime_libs:
 	@$(ECHO) "*** Uninstalling runtime libraries"
@@ -941,8 +962,8 @@ uninstall_runtime_libs:
 	@set -e; for s in dummy $(INSTALL_SHLIBS); do \
 		if [ "$$s" = "dummy" ]; then continue; fi; \
 		fn=`basename $$s`; \
-		$(ECHO) "$(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
-		$(RM) "$(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
+		$(ECHO) "$(RM) $(DESTDIR)$(bindir)/$$fn"; \
+		$(RM) "$(DESTDIR)$(bindir)/$$fn"; \
 	done
 	@ : {- output_on() unless windowsdll(); "" -}
 
@@ -1100,18 +1121,22 @@ uninstall_image_docs:
 	done
 
 # Developer targets (note: these are only available on Unix) #########
+##@ Code maintenance
 
 # It's important that generate_buildinfo comes after ordinals, as ordinals
 # is sensitive to build.info changes.
-update: generate errors ordinals generate_buildinfo
+update: generate errors ordinals generate_buildinfo ## Update errors, ordinals and build info
 
+.PHONY: generate generate_apps generate_crypto_bn generate_crypto_objects \
+          generate_crypto_conf generate_crypto_asn1 generate_fuzz_oids
 generate: generate_apps generate_crypto_bn generate_crypto_objects \
           generate_crypto_conf generate_crypto_asn1 generate_fuzz_oids
 
+.PHONY: generate_buildinfo generate_doc_buildinfo
 generate_buildinfo: generate_doc_buildinfo
 
 .PHONY: doc-nits md-nits
-doc-nits: build_generated_pods
+doc-nits: build_generated_pods ## Evaluate OpenSSL documentation
 	$(PERL) $(SRCDIR)/util/find-doc-nits -c -n -l -e
 
 # This uses "mdl", the markdownlint application, which is written in ruby.
@@ -1120,15 +1145,23 @@ doc-nits: build_generated_pods
 # Another option is at https://snapcraft.io/install/mdl/debian
 # Finally, there's a Node.js version, which we haven't tried, that
 # can be found at https://github.com/DavidAnson/markdownlint
-md-nits:
-	mdl -s util/markdownlint.rb .
+md-nits: ## Evaluate markdown files via "mdl"
+	mdl -s $(SRCDIR)/util/markdownlint.rb .
 
 # Test coverage is a good idea for the future
 #coverage: $(PROGRAMS) $(TESTPROGRAMS)
 #	...
 
-lint:
-	lint -DLINT $(INCLUDES) $(SRCS)
+.PHONY: lint
+lint: ## Evaluate C code via "splint"
+	@( cd $(SRCDIR); \
+           echo splint -DLINT -posixlib -preproc -D__gnuc_va_list=void \
+	   -I. -Iinclude -Iapps/include $(CRYPTOHEADERS) $(SSLHEADERS) $(SRCS) )
+
+.PHONY: check-format
+check-format: ## Evaluate C code according to OpenSSL coding standards
+	( cd $(SRCDIR); $(PERL) util/check-format.pl \
+			$(SRCS) \$(CRYPTOHEADERS) $(SSLHEADERS) )
 
 generate_apps:
 	( cd $(SRCDIR); $(PERL) VMS/VMSify-conf.pl \
@@ -1231,7 +1264,7 @@ providers/fips.module.sources.new: configdata.pm
 		   crypto/*cap.c; do \
 	    echo "$$x"; \
 	  done \
-	) | sort | uniq > providers/fips.module.sources.new
+	) | grep -v sm2p256 | sort | uniq > providers/fips.module.sources.new
 	rm -rf sources-tmp
 
 # Set to -force to force a rebuild
@@ -1258,6 +1291,7 @@ errors:
            include/openssl/tls1.h
            include/openssl/dtls1.h
            include/openssl/srtp.h
+           include/openssl/quic.h
            include/openssl/sslerr_legacy.h );
    my @cryptoheaders_tmpl =
        qw( include/internal/dso.h
@@ -1268,7 +1302,8 @@ errors:
            include/internal/asn1.h
            include/internal/sslconf.h );
    my @cryptoskipheaders = ( @sslheaders_tmpl,
-       qw( include/openssl/conf_api.h
+       qw( include/openssl/asn1_mac.h
+           include/openssl/conf_api.h
            include/openssl/ebcdic.h
            include/openssl/opensslconf.h
            include/openssl/symhacks.h ) );
@@ -1303,6 +1338,14 @@ errors:
    }
    "";
 -}
+SRCS={-
+sub uniq { my %seen; grep !$seen{$_}++, @_; }
+sub flat(@) { return map { ref eq 'ARRAY' ? @$_ : $_ } @_; }
+join(" \\\n" . ' ' x 5, fill_lines(" ", $COLUMNS - 5,
+     uniq(grep /\.(c|cc|cpp)$/,
+          flat (map { $unified_info{sources}->{$_} }
+                (sort keys %{$unified_info{sources}})))))
+-}
 CRYPTOHEADERS={- join(" \\\n" . ' ' x 14,
                       fill_lines(" ", $COLUMNS - 14, sort keys %cryptoheaders)) -}
 SSLHEADERS={- join(" \\\n" . ' ' x 11,
@@ -1320,22 +1363,25 @@ renumber: build_generated
                 --renumber \
                 $(SSLHEADERS)
 
-ordinals: build_generated
+$(SRCDIR)/util/libcrypto.num: $(CRYPTOHEADERS) $(SRCDIR)/include/openssl/symhacks.h
 	$(PERL) $(SRCDIR)/util/mknum.pl --version $(VERSION_NUMBER) --no-warnings \
                 --ordinals $(SRCDIR)/util/libcrypto.num \
                 --symhacks $(SRCDIR)/include/openssl/symhacks.h \
                 $(CRYPTOHEADERS)
+$(SRCDIR)/util/libssl.num: $(SSLHEADERS) $(SRCDIR)/include/openssl/symhacks.h
 	$(PERL) $(SRCDIR)/util/mknum.pl --version $(VERSION_NUMBER) --no-warnings \
                 --ordinals $(SRCDIR)/util/libssl.num \
                 --symhacks $(SRCDIR)/include/openssl/symhacks.h \
                 $(SSLHEADERS)
+.PHONY: ordinals
+ordinals: build_generated $(SRCDIR)/util/libcrypto.num $(SRCDIR)/util/libssl.num
 
 test_ordinals:
 	$(MAKE) run_tests TESTS=test_ordinals
 
 tags TAGS: FORCE
 	rm -f TAGS tags
-	-ctags -R .
+	-( cd $(SRCDIR); util/ctags.sh )
 	-etags `find . -name '*.[ch]' -o -name '*.pm'`
 
 providers/fips.checksum.new: providers/fips.module.sources.new
@@ -1595,12 +1641,44 @@ EOF
           my $dofile = abs2rel(rel2abs(catfile($config{sourcedir},
                                                "util", "dofile.pl")),
                                rel2abs($config{builddir}));
-          my @perlmodules = ( 'configdata.pm',
-                              grep { $_ =~ m|\.pm$| } @{$args{deps}} );
-          my %perlmoduleincs = map { '"-I'.dirname($_).'"' => 1 } @perlmodules;
-          $deps = join(' ', $deps, compute_platform_depends(@perlmodules));
-          @perlmodules = map { "-M".basename($_, '.pm') } @perlmodules;
-          my $perlmodules = join(' ', '', sort keys %perlmoduleincs, @perlmodules);
+          my @perlmodules = ();
+          my %perlmoduleincs = ();
+          my %perlmoduledeps = ();
+          foreach my $x (('configdata.pm', @{$args{deps}})) {
+              # Compute (i)nclusion directory, (m)odule name and (d)ependency
+              my $i, $m, $d;
+              if ($x =~ /\|/) {
+                  $i = $`;
+                  $d = $';
+
+                  # Massage the module part to become a real perl module spec
+                  $m = $d;
+                  $m =~ s|\.pm$||;
+                  # Directory specs are :: in perl package names
+                  $m =~ s|/|::|g;
+
+                  # Full file name of the dependency
+                  $d = catfile($i, $d) if $i;
+              } elsif ($x =~ /\.pm$/) {
+                  $i = dirname($x);
+                  $m = basename($x, '.pm');
+                  $d = $x;
+              } else {
+                  # All other dependencies are simply collected
+                  $d = $x;
+              }
+              push @perlmodules, '"-M'.$m.'"' if $m;
+              $perlmoduledeps{$d} = 1;
+              $perlmoduleincs{'"-I'.$i.'"'} = 1 if $i;
+          }
+
+          # Because of the special treatment of dependencies, we need to
+          # recompute $deps completely
+          my $deps
+              = join(" ", compute_platform_depends(@{$args{generator_deps}},
+                                                   sort keys %perlmoduledeps));
+          my $perlmodules = join(' ', '', ( sort keys %perlmoduleincs ), @perlmodules);
+
           return <<"EOF";
 $args{src}: $gen0 $deps
 	\$(PERL)$perlmodules "$dofile" "-o$target{build_file}" $gen0$gen_args > \$@

+ 42 - 10
libs/openssl/Configurations/windows-makefile.tmpl

@@ -294,7 +294,7 @@ RCOUTFLAG={- $target{rcoutflag} -}$(OSSL_EMPTY)
 
 CNF_ASFLAGS={- join(' ', $target{asflags} || (),
                          @{$config{asflags}}) -}
-CNF_CPPFLAGS={- our $cppfags2 =
+CNF_CPPFLAGS={- our $cppflags2 =
                     join(' ', $target{cppflags} || (),
                               (map { '-D'.quotify1($_) } @{$target{defines}},
                                                          @{$config{defines}}),
@@ -436,7 +436,7 @@ build_all_generated: $(GENERATED_MANDATORY) $(GENERATED) build_docs
 	@$(ECHO) "         then make will fail..."
 	@{- output_on() if $disabled{makedepend}; "\@rem" -}
 
-all: build_sw build_docs
+all: build_sw {- "build_docs" if !$disabled{docs}; -}
 
 test: tests
 {- dependmagic('tests'); -}: build_programs_nodep build_modules_nodep copy-utils
@@ -453,9 +453,9 @@ list-tests:
 	@$(ECHO) "Tests are not supported with your chosen Configure options"
 	@{- output_on() if !$disabled{tests}; "\@rem" -}
 
-install: install_sw install_ssldirs install_docs {- $disabled{fips} ? "" : "install_fips" -}
+install: install_sw install_ssldirs {- "install_docs" if !$disabled{docs}; -} {- $disabled{fips} ? "" : "install_fips" -}
 
-uninstall: uninstall_docs uninstall_sw {- $disabled{fips} ? "" : "uninstall_fips" -}
+uninstall: {- "uninstall_docs" if !$disabled{docs}; -} uninstall_sw {- $disabled{fips} ? "" : "uninstall_fips" -}
 
 libclean:
 	"$(PERL)" -e "map { m/(.*)\.dll$$/; unlink glob """{.,apps,test,fuzz}/$$1.*"""; } @ARGV" $(SHLIBS)
@@ -790,12 +790,44 @@ EOF
           my $dofile = abs2rel(rel2abs(catfile($config{sourcedir},
                                                "util", "dofile.pl")),
                                rel2abs($config{builddir}));
-          my @perlmodules = ( 'configdata.pm',
-                              grep { $_ =~ m|\.pm$| } @{$args{deps}} );
-          my %perlmoduleincs = map { '"-I'.dirname($_).'"' => 1 } @perlmodules;
-          $deps = join(' ', $deps, compute_platform_depends(@perlmodules));
-          @perlmodules = map { "-M".basename($_, '.pm') } @perlmodules;
-          my $perlmodules = join(' ', '', sort keys %perlmoduleincs, @perlmodules);
+          my @perlmodules = ();
+          my %perlmoduleincs = ();
+          my %perlmoduledeps = ();
+          foreach my $x (('configdata.pm', @{$args{deps}})) {
+              # Compute (i)nclusion directory, (m)odule name and (d)ependency
+              my $i, $m, $d;
+              if ($x =~ /\|/) {
+                  $i = $`;
+                  $d = $';
+
+                  # Massage the module part to become a real perl module spec
+                  $m = $d;
+                  $m =~ s|\.pm$||;
+                  # Directory specs are :: in perl package names
+                  $m =~ s|/|::|g;
+
+                  # Full file name of the dependency
+                  $d = catfile($i, $d) if $i;
+              } elsif ($x =~ /\.pm$/) {
+                  $i = dirname($x);
+                  $m = basename($x, '.pm');
+                  $d = $x;
+              } else {
+                  # All other dependencies are simply collected
+                  $d = $x;
+              }
+              push @perlmodules, '"-M'.$m.'"' if $m;
+              $perlmoduledeps{$d} = 1;
+              $perlmoduleincs{'"-I'.$i.'"'} = 1 if $i;
+          }
+
+          # Because of the special treatment of dependencies, we need to
+          # recompute $deps completely
+          my $deps
+              = join(" ", compute_platform_depends(@{$args{generator_deps}},
+                                                   sort keys %perlmoduledeps));
+          my $perlmodules = join(' ', '', ( sort keys %perlmoduleincs ), @perlmodules);
+
           return <<"EOF";
 $args{src}: "$gen0" $deps
 	"\$(PERL)"$perlmodules "$dofile" "-o$target{build_file}" "$gen0"$gen_args > \$@

+ 122 - 19
libs/openssl/Configure

@@ -27,7 +27,7 @@ use OpenSSL::config;
 my $orig_death_handler = $SIG{__DIE__};
 $SIG{__DIE__} = \&death_handler;
 
-my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
+my $usage="Usage: Configure [no-<feature> ...] [enable-<feature> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]thread-pool] [[no-]default-thread-pool] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
 
 my $banner = <<"EOF";
 
@@ -81,6 +81,10 @@ EOF
 # [no-]threads  [don't] try to create a library that is suitable for
 #               multithreaded applications (default is "threads" if we
 #               know how to do it)
+# [no-]thread-pool
+#               [don't] allow thread pool functionality
+# [no-]default-thread-pool
+#               [don't] allow default thread pool functionality
 # [no-]shared   [don't] try to create shared libraries when supported.
 # [no-]pic      [don't] try to build position independent code when supported.
 #               If disabled, it also disables shared and dynamic-engine.
@@ -88,8 +92,9 @@ EOF
 # no-egd        do not compile support for the entropy-gathering daemon APIs
 # [no-]zlib     [don't] compile support for zlib compression.
 # zlib-dynamic  Like "zlib", but the zlib library is expected to be a shared
-#               library and will be loaded in run-time by the OpenSSL library.
+#               library and will be loaded at run-time by the OpenSSL library.
 # sctp          include SCTP support
+# no-quic       disable QUIC support
 # no-uplink     Don't build support for UPLINK interface.
 # enable-weak-ssl-ciphers
 #               Enable weak ciphers that are disabled by default.
@@ -161,7 +166,8 @@ my @gcc_devteam_warn = qw(
     -Wsign-compare
     -Wshadow
     -Wformat
-    -Wtype-limits
+    -Wno-type-limits
+    -Wno-tautological-constant-out-of-range-compare
     -Wundef
     -Werror
     -Wmissing-prototypes
@@ -182,6 +188,7 @@ my @clang_devteam_warn = qw(
     -Wno-parentheses-equality
     -Wno-language-extension-token
     -Wno-extended-offsetof
+    -Wno-missing-braces
     -Wconditional-uninitialized
     -Wincompatible-pointer-types-discards-qualifiers
     -Wmissing-variable-declarations
@@ -401,6 +408,8 @@ my @dtls = qw(dtls1 dtls1_2);
 my @disablables = (
     "acvp-tests",
     "afalgeng",
+    "apps",
+    "argon2",
     "aria",
     "asan",
     "asm",
@@ -410,11 +419,14 @@ my @disablables = (
     "autoload-config",
     "bf",
     "blake2",
+    "brotli",
+    "brotli-dynamic",
     "buildtest-c++",
     "bulk",
     "cached-fetch",
     "camellia",
     "capieng",
+    "winstore",
     "cast",
     "chacha",
     "cmac",
@@ -423,11 +435,13 @@ my @disablables = (
     "comp",
     "crypto-mdebug",
     "ct",
+    "default-thread-pool",
     "deprecated",
     "des",
     "devcryptoeng",
     "dgram",
     "dh",
+    "docs",
     "dsa",
     "dso",
     "dtls",
@@ -437,6 +451,7 @@ my @disablables = (
     "ec_nistp_64_gcc_128",
     "ecdh",
     "ecdsa",
+    "ecx",
     "egd",
     "engine",
     "err",
@@ -447,6 +462,7 @@ my @disablables = (
     "fuzz-afl",
     "fuzz-libfuzzer",
     "gost",
+    "http",
     "idea",
     "ktls",
     "legacy",
@@ -467,6 +483,7 @@ my @disablables = (
     "poly1305",
     "posix-io",
     "psk",
+    "quic",
     "rc2",
     "rc4",
     "rc5",
@@ -481,6 +498,7 @@ my @disablables = (
     "siphash",
     "siv",
     "sm2",
+    "sm2-precomp",
     "sm3",
     "sm4",
     "sock",
@@ -492,6 +510,8 @@ my @disablables = (
     "static-engine",
     "stdio",
     "tests",
+    "tfo",
+    "thread-pool",
     "threads",
     "tls",
     "trace",
@@ -504,6 +524,8 @@ my @disablables = (
     "whirlpool",
     "zlib",
     "zlib-dynamic",
+    "zstd",
+    "zstd-dynamic",
     );
 foreach my $proto ((@tls, @dtls))
         {
@@ -535,6 +557,8 @@ my %deprecated_disablables = (
 our %disabled = ( # "what"         => "comment"
                   "fips"                => "default",
                   "asan"                => "default",
+                  "brotli"              => "default",
+                  "brotli-dynamic"      => "default",
                   "buildtest-c++"       => "default",
                   "crypto-mdebug"       => "default",
                   "crypto-mdebug-backtrace" => "default",
@@ -551,12 +575,15 @@ our %disabled = ( # "what"         => "comment"
                   "sctp"                => "default",
                   "ssl3"                => "default",
                   "ssl3-method"         => "default",
+                  "tfo"                 => "default",
                   "trace"               => "default",
                   "ubsan"               => "default",
                   "unit-test"           => "default",
                   "weak-ssl-ciphers"    => "default",
                   "zlib"                => "default",
                   "zlib-dynamic"        => "default",
+                  "zstd"                => "default",
+                  "zstd-dynamic"        => "default",
                 );
 
 # Note: => pair form used for aesthetics, not to truly make a hash table
@@ -576,6 +603,7 @@ my @disable_cascades = (
                              "seed", "siphash", "siv",
                              "sm3", "sm4", "srp",
                              "srtp", "ssl3-method", "ssl-trace",
+                             "tfo",
                              "ts", "ui-console", "whirlpool",
                              "fips-securitychecks" ],
     sub { $config{processor} eq "386" }
@@ -583,10 +611,12 @@ my @disable_cascades = (
     "ssl"               => [ "ssl3" ],
     "ssl3-method"       => [ "ssl3" ],
     "zlib"              => [ "zlib-dynamic" ],
+    "brotli"            => [ "brotli-dynamic" ],
+    "zstd"              => [ "zstd-dynamic" ],
     "des"               => [ "mdc2" ],
-    "ec"                => [ "ec2m", "ecdsa", "ecdh", "sm2", "gost" ],
-    "dgram"             => [ "dtls", "sctp" ],
-    "sock"              => [ "dgram" ],
+    "ec"                => [ "ec2m", "ecdsa", "ecdh", "sm2", "gost", "ecx" ],
+    "dgram"             => [ "dtls", "quic", "sctp" ],
+    "sock"              => [ "dgram", "tfo" ],
     "dtls"              => [ @dtls ],
     sub { 0 == scalar grep { !$disabled{$_} } @dtls }
                         => [ "dtls" ],
@@ -594,6 +624,7 @@ my @disable_cascades = (
     "tls"               => [ @tls ],
     sub { 0 == scalar grep { !$disabled{$_} } @tls }
                         => [ "tls" ],
+    "tls1_3"            => [ "quic" ],
 
     "crypto-mdebug"     => [ "crypto-mdebug-backtrace" ],
 
@@ -625,7 +656,7 @@ my @disable_cascades = (
     "stdio"             => [ "apps", "capieng", "egd" ],
     "apps"              => [ "tests" ],
     "tests"             => [ "external-tests" ],
-    "comp"              => [ "zlib" ],
+    "comp"              => [ "zlib", "brotli", "zstd" ],
     "sm3"               => [ "sm2" ],
     sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
 
@@ -638,7 +669,14 @@ my @disable_cascades = (
 
     "fips"              => [ "fips-securitychecks", "acvp-tests" ],
 
-    "deprecated-3.0"    => [ "engine", "srp" ]
+    "threads"           => [ "thread-pool" ],
+    "thread-pool"       => [ "default-thread-pool" ],
+
+    "blake2"            => [ "argon2" ],
+
+    "deprecated-3.0"    => [ "engine", "srp" ],
+
+    "http"              => [ "ocsp" ]
     );
 
 # Avoid protocol support holes.  Also disable all versions below N, if version
@@ -707,6 +745,7 @@ my @user_crossable = qw ( AR AS CC CXX CPP LD MT RANLIB RC );
 # input, as opposed to the VAR=string option that override the corresponding
 # config target attributes
 my %useradd = (
+    ASFLAGS     => [],
     CPPDEFINES  => [],
     CPPINCLUDES => [],
     CPPFLAGS    => [],
@@ -883,6 +922,14 @@ while (@argvcopy)
                         {
                         delete $disabled{"zlib"};
                         }
+                elsif ($1 eq "brotli-dynamic")
+                        {
+                        delete $disabled{"brotli"};
+                        }
+                elsif ($1 eq "zstd-dynamic")
+                        {
+                        delete $disabled{"zstd"};
+                        }
                 my $algo = $1;
                 delete $disabled{$algo};
 
@@ -933,8 +980,6 @@ while (@argvcopy)
                 if (/^--prefix=(.*)$/)
                         {
                         $config{prefix}=$1;
-                        die "Directory given with --prefix MUST be absolute\n"
-                                unless file_name_is_absolute($config{prefix});
                         }
                 elsif (/^--api=(.*)$/)
                         {
@@ -959,6 +1004,22 @@ while (@argvcopy)
                         {
                         $withargs{zlib_include}=$1;
                         }
+                elsif (/^--with-brotli-lib=(.*)$/)
+                        {
+                        $withargs{brotli_lib}=$1;
+                        }
+                elsif (/^--with-brotli-include=(.*)$/)
+                        {
+                        $withargs{brotli_include}=$1;
+                        }
+                elsif (/^--with-zstd-lib=(.*)$/)
+                        {
+                        $withargs{zstd_lib}=$1;
+                        }
+                elsif (/^--with-zstd-include=(.*)$/)
+                        {
+                        $withargs{zstd_include}=$1;
+                        }
                 elsif (/^--with-fuzzer-lib=(.*)$/)
                         {
                         $withargs{fuzzer_lib}=$1;
@@ -1377,6 +1438,11 @@ foreach (keys %useradd) {
 # At this point, we can forget everything about %user and %useradd,
 # because it's now all been merged into the corresponding $config entry
 
+if ($config{prefix} && !$config{CROSS_COMPILE}) {
+    die "Directory given with --prefix MUST be absolute\n"
+        unless file_name_is_absolute($config{prefix});
+}
+
 if (grep { $_ =~ /(?:^|\s)-static(?:\s|$)/ } @{$config{LDFLAGS}}) {
     disable('static', 'pic', 'threads');
 }
@@ -1714,6 +1780,12 @@ unless ($disabled{ktls}) {
     }
 }
 
+unless ($disabled{winstore}) {
+    unless ($target =~ /^(?:Cygwin|mingw|VC-|BC-)/) {
+        disable('not-windows', 'winstore');
+    }
+}
+
 push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls});
 
 # Get the extra flags used when building shared libraries and modules.  We
@@ -1785,7 +1857,7 @@ foreach my $what (sort keys %disabled) {
 
     if (!grep { $what eq $_ } ( 'buildtest-c++', 'fips', 'threads', 'shared',
                                 'module', 'pic', 'dynamic-engine', 'makedepend',
-                                'zlib-dynamic', 'zlib', 'sse2', 'legacy' )) {
+                                'sse2', 'legacy' )) {
         (my $WHAT = uc $what) =~ s|-|_|g;
         my $skipdir = $what;
 
@@ -2374,17 +2446,39 @@ EOF
             } elsif ($dest eq '') {
                 $ddest = '';
             } else {
-                $ddest = cleanfile($sourced, $_, $blddir);
+                $ddest = cleanfile($sourced, $dest, $blddir);
 
                 # If the destination doesn't exist in source, it can only be
                 # a generated file in the build tree.
                 if ($ddest eq $src_configdata || ! -f $ddest) {
-                    $ddest = cleanfile($buildd, $_, $blddir);
+                    $ddest = cleanfile($buildd, $dest, $blddir);
                 }
             }
-            foreach (@{$depends{$dest}}) {
-                my $d = cleanfile($sourced, $_, $blddir);
-                my $d2 = cleanfile($buildd, $_, $blddir);
+            foreach my $f (@{$depends{$dest}}) {
+                # If the dependency destination is generated, dependencies
+                # may have an extra syntax to separate the intended inclusion
+                # directory from the module to be loaded: a | instead of a
+                # / as directory separator.
+                # Do note that this has to be handled in the build file
+                # template as well.
+                # $i = inclusion path in source directory
+                # $i2 = inclusion path in build directory
+                # $m = module path (within the inclusion path)
+                # $i = full module path in source directory
+                # $i2 = full module path in build directory
+                my $i; my $i2; my $m; my $d; my $d2;
+                if ($unified_info{generate}->{$ddest}
+                    && $f =~ m/^(.*?)\|(.*)$/) {
+                    $i = $1;
+                    $m = $2;
+                    $i = cleanfile($sourced, $i, $blddir);
+                    $i2 = cleanfile($buildd, $i, $blddir);
+                    $d = cleanfile($sourced, "$i/$m", $blddir);
+                    $d2 = cleanfile($buildd, "$i/$m", $blddir);
+                } else {
+                    $d = cleanfile($sourced, $f, $blddir);
+                    $d2 = cleanfile($buildd, $f, $blddir);
+                }
 
                 # If we know it's generated, or assume it is because we can't
                 # find it in the source tree, we set file we depend on to be
@@ -2394,13 +2488,20 @@ EOF
                         keys %{$unified_info{generate}})
                     || ! -f $d) {
                     $d = $d2;
+                    $i = $i2;
+                }
+                if ($i) {
+                    # Put together the computed inclusion dir with the
+                    # original module name.  Do note that we conserve the
+                    # Unixly path syntax for the module path.
+                    $d = "$i|$m";
                 }
                 $unified_info{depends}->{$ddest}->{$d} = 1;
 
                 # Fix up associated attributes
                 $unified_info{attributes}->{depends}->{$ddest}->{$d} =
-                    $attributes{depends}->{$dest}->{$_}
-                    if defined $attributes{depends}->{$dest}->{$_};
+                    $attributes{depends}->{$dest}->{$f}
+                    if defined $attributes{depends}->{$dest}->{$f};
             }
         }
 
@@ -2570,7 +2671,9 @@ EOF
         next if $dest eq "";
         foreach my $d (keys %{$unified_info{depends}->{$dest}}) {
             next unless $d =~ /\.(h|pm)$/;
-            my $i = dirname($d);
+            # Take into account when a dependency uses the inclusion|module
+            # syntax
+            my $i = $d =~ m/\|/ ? $` : dirname($d);
             my $spot =
                 $d eq "configdata.pm" || defined($unified_info{generate}->{$d})
                 ? 'build' : 'source';

+ 144 - 27
libs/openssl/INSTALL.md

@@ -19,7 +19,7 @@ Table of Contents
    - [Build Type](#build-type)
    - [Directories](#directories)
    - [Compiler Warnings](#compiler-warnings)
-   - [ZLib Flags](#zlib-flags)
+   - [Compression Algorithm Flags](#compression-algorithm-flags)
    - [Seeding the Random Generator](#seeding-the-random-generator)
    - [Setting the FIPS HMAC key](#setting-the-FIPS-HMAC-key)
    - [Enable and Disable Features](#enable-and-disable-features)
@@ -120,21 +120,11 @@ represents one of the four commands
 Arguments
 ---------
 
-**Mandatory arguments** are enclosed in double curly braces.
-A simple example would be
+**Optional Arguments** are enclosed in square brackets.
 
-    $ type {{ filename }}
+    [option...]
 
-which is to be understood to use the command `type` on some file name
-determined by the user.
-
-**Optional Arguments** are enclosed in double square brackets.
-
-    [[ options ]]
-
-Note that the notation assumes spaces around `{`, `}`, `[`, `]`, `{{`, `}}` and
-`[[`, `]]`.  This is to differentiate from OpenVMS directory
-specifications, which also use [ and ], but without spaces.
+A trailing ellipsis means that more than one could be specified.
 
 Quick Installation Guide
 ========================
@@ -177,8 +167,9 @@ issue the following commands to build OpenSSL.
 As mentioned in the [Choices](#choices) section, you need to pick one
 of the four Configure targets in the first command.
 
-Most likely you will be using the `VC-WIN64A` target for 64bit Windows
-binaries (AMD64) or `VC-WIN32` for 32bit Windows binaries (X86).
+Most likely you will be using the `VC-WIN64A`/`VC-WIN64A-HYBRIDCRT` target for
+64bit Windows binaries (AMD64) or `VC-WIN32`/`VC-WIN32-HYBRIDCRT` for 32bit
+Windows binaries (X86).
 The other two options are `VC-WIN64I` (Intel IA64, Itanium) and
 `VC-CE` (Windows CE) are rather uncommon nowadays.
 
@@ -391,8 +382,39 @@ for OpenSSL development.  It only works when using gcc or clang as the compiler.
 If you are developing a patch for OpenSSL then it is recommended that you use
 this option where possible.
 
-ZLib Flags
-----------
+Compression Algorithm Flags
+---------------------------
+
+### with-brotli-include
+
+    --with-brotli-include=DIR
+
+The directory for the location of the brotli include files (i.e. the location
+of the **brotli** include directory).  This option is only necessary if
+[enable-brotli](#enable-brotli) is used and the include files are not already
+on the system include path.
+
+### with-brotli-lib
+
+    --with-brotli-lib=LIB
+
+**On Unix**: this is the directory containing the brotli libraries.
+If not provided, the system library path will be used.
+
+The names of the libraries are:
+
+* libbrotlicommon.a or libbrotlicommon.so
+* libbrotlidec.a or libbrotlidec.so
+* libbrotlienc.a or libbrotlienc.so
+
+**On Windows:** this is the directory containing the brotli libraries.
+If not provided, the system library path will be used.
+
+The names of the libraries are:
+
+* brotlicommon.lib
+* brotlidec.lib
+* brotlienc.lib
 
 ### with-zlib-include
 
@@ -418,6 +440,32 @@ then this flag is optional and defaults to `ZLIB1` if not provided.
 This flag is optional and if not provided then `GNV$LIBZSHR`, `GNV$LIBZSHR32`
 or `GNV$LIBZSHR64` is used by default depending on the pointer size chosen.
 
+### with-zstd-include
+
+    --with-zstd-include=DIR
+
+The directory for the location of the Zstd include file. This option is only
+necessary if [enable-std](#enable-zstd) is used and the include file is not
+already on the system include path.
+
+OpenSSL requires Zstd 1.4 or greater. The Linux kernel source contains a
+*zstd.h* file that is not compatible with the 1.4.x Zstd distribution, the
+compilation will generate an error if the Linux *zstd.h* is included before
+(or instead of) the Zstd distribution header.
+
+### with-zstd-lib
+
+    --with-zstd-lib=LIB
+
+**On Unix**: this is the directory containing the Zstd library.
+If not provided the system library path will be used.
+
+**On Windows:** this is the filename of the Zstd library (with or
+without a path).  This flag must be provided if the
+[enable-zstd-dynamic](#enable-zstd-dynamic) option is not also used.
+If `zstd-dynamic` is used then this flag is optional and defaults
+to `LIBZSTD` if not provided.
+
 Seeding the Random Generator
 ----------------------------
 
@@ -535,6 +583,11 @@ access to algorithm internals that are not normally accessible.
 Additional information related to ACVP can be found at
 <https://github.com/usnistgov/ACVP>.
 
+### no-apps
+
+Do not build apps, e.g. the openssl program. This is handy for minimization.
+This option also disables tests.
+
 ### no-asm
 
 Do not use assembler code.
@@ -565,6 +618,17 @@ Typically OpenSSL will automatically load human readable error strings.  For a
 statically linked application this may be undesirable if small executable size
 is an objective.
 
+### enable-brotli
+
+Build with support for brotli compression/decompression.
+
+### enable-brotli-dynamic
+
+Like the enable-brotli option, but has OpenSSL load the brotli library dynamically
+when needed.
+
+This is only supported on systems where loading of shared libraries is supported.
+
 ### no-autoload-config
 
 Don't automatically load the default `openssl.cnf` file.
@@ -652,6 +716,10 @@ Don't build support for datagram based BIOs.
 
 Selecting this option will also force the disabling of DTLS.
 
+### no-docs
+
+Don't build and install documentation, i.e. manual pages in various forms.
+
 ### no-dso
 
 Don't build support for loading Dynamic Shared Objects (DSO)
@@ -747,6 +815,10 @@ Note that if this feature is enabled then GOST ciphersuites are only available
 if the GOST algorithms are also available through loading an externally supplied
 engine.
 
+### no-http
+
+Disable HTTP support.
+
 ### no-legacy
 
 Don't build the legacy provider.
@@ -842,6 +914,10 @@ Do not create shared libraries, only static ones.
 
 See [Notes on shared libraries](#notes-on-shared-libraries) below.
 
+### no-sm2-precomp
+
+Disable using the SM2 precomputed table on aarch64 to make the library smaller.
+
 ### no-sock
 
 Don't build support for socket BIOs.
@@ -895,6 +971,14 @@ tests also use the command line applications, the tests will also be skipped.
 
 Don't build test programs or run any tests.
 
+### enable-tfo
+
+Build with support for TCP Fast Open (RFC7413). Supported on Linux, macOS and FreeBSD.
+
+### no-quic
+
+Don't build with QUIC support.
+
 ### no-threads
 
 Don't build with support for multi-threaded applications.
@@ -907,6 +991,27 @@ will usually require additional system-dependent options!
 
 See [Notes on multi-threading](#notes-on-multi-threading) below.
 
+### no-thread-pool
+
+Don't build with support for thread pool functionality.
+
+### thread-pool
+
+Build with thread pool functionality. If enabled, OpenSSL algorithms may
+use the thread pool to perform parallel computation. This option in itself
+does not enable OpenSSL to spawn new threads. Currently the only supported
+thread pool mechanism is the default thread pool.
+
+### no-default-thread-pool
+
+Don't build with support for default thread pool functionality.
+
+### default-thread-pool
+
+Build with default thread pool functionality. If enabled, OpenSSL may create
+and manage threads up to a maximum number of threads authorized by the
+application. Supported on POSIX compliant platforms and Windows.
+
 ### enable-trace
 
 Build with support for the integrated tracing api.
@@ -959,6 +1064,17 @@ when needed.
 
 This is only supported on systems where loading of shared libraries is supported.
 
+### enable-zstd
+
+Build with support for Zstd compression/decompression.
+
+### enable-zstd-dynamic
+
+Like the enable-zstd option, but has OpenSSL load the Zstd library dynamically
+when needed.
+
+This is only supported on systems where loading of shared libraries is supported.
+
 ### 386
 
 In 32-bit x86 builds, use the 80386 instruction set only in assembly modules
@@ -1163,15 +1279,15 @@ the same.
 
 #### Unix / Linux / macOS
 
-    $ ./Configure [[ options ]]
+    $ ./Configure [options...]
 
 #### OpenVMS
 
-    $ perl Configure [[ options ]]
+    $ perl Configure [options...]
 
 #### Windows
 
-    $ perl Configure [[ options ]]
+    $ perl Configure [options...]
 
 ### Manual Configuration
 
@@ -1193,12 +1309,13 @@ When you have identified your system (and if necessary compiler) use this
 name as the argument to `Configure`.  For example, a `linux-elf` user would
 run:
 
-    $ ./Configure linux-elf [[ options ]]
+    $ ./Configure linux-elf [options...]
 
 ### Creating your own Configuration
 
 If your system isn't listed, you will have to create a configuration
-file named `Configurations/{{ something }}.conf` and add the correct
+file named `Configurations/YOURFILENAME.conf` (replace `YOURFILENAME`
+with a filename of your choosing) and add the correct
 configuration for your system.  See the available configs as examples
 and read [Configurations/README.md](Configurations/README.md) and
 [Configurations/README-design.md](Configurations/README-design.md)
@@ -1230,21 +1347,21 @@ directory and invoking the configuration commands from there.
 
     $ mkdir /var/tmp/openssl-build
     $ cd /var/tmp/openssl-build
-    $ /PATH/TO/OPENSSL/SOURCE/Configure [[ options ]]
+    $ /PATH/TO/OPENSSL/SOURCE/Configure [options...]
 
 #### OpenVMS example
 
     $ set default sys$login:
     $ create/dir [.tmp.openssl-build]
     $ set default [.tmp.openssl-build]
-    $ perl D:[PATH.TO.OPENSSL.SOURCE]Configure [[ options ]]
+    $ perl D:[PATH.TO.OPENSSL.SOURCE]Configure [options...]
 
 #### Windows example
 
     $ C:
     $ mkdir \temp-openssl
     $ cd \temp-openssl
-    $ perl d:\PATH\TO\OPENSSL\SOURCE\Configure [[ options ]]
+    $ perl d:\PATH\TO\OPENSSL\SOURCE\Configure [options...]
 
 Paths can be relative just as well as absolute.  `Configure` will do its best
 to translate them to relative paths whenever possible.
@@ -1465,7 +1582,7 @@ over the build process.  Typically these should be defined prior to running
 
     PERL
                    The name of the Perl executable to use when building OpenSSL.
-                   Only needed if builing should use a different Perl executable
+                   Only needed if building should use a different Perl executable
                    than what is used to run the Configure script.
 
     RANLIB

+ 100 - 2
libs/openssl/NEWS.md

@@ -7,6 +7,7 @@ release. For more details please read the CHANGES file.
 OpenSSL Releases
 ----------------
 
+ - [OpenSSL 3.2](#openssl-32)
  - [OpenSSL 3.1](#openssl-31)
  - [OpenSSL 3.0](#openssl-30)
  - [OpenSSL 1.1.1](#openssl-111)
@@ -16,9 +17,101 @@ OpenSSL Releases
  - [OpenSSL 1.0.0](#openssl-100)
  - [OpenSSL 0.9.x](#openssl-09x)
 
+OpenSSL 3.2
+-----------
+
+### Major changes between OpenSSL 3.1 and OpenSSL 3.2.0 [23 Nov 2023]
+
+OpenSSL 3.2.0 is a feature release adding significant new functionality to
+OpenSSL.
+
+This release incorporates the following potentially significant or incompatible
+changes:
+
+  * The default SSL/TLS security level has been changed from 1 to 2.
+
+  * The `x509`, `ca`, and `req` apps now always produce X.509v3 certificates.
+
+  * Subject or issuer names in X.509 objects are now displayed as UTF-8 strings
+    by default.
+
+This release adds the following new features:
+
+  * Support for client side QUIC, including support for
+    multiple streams (RFC 9000)
+
+  * Support for Ed25519ctx, Ed25519ph and Ed448ph in addition
+    to existing support for Ed25519 and Ed448 (RFC 8032)
+
+  * Support for deterministic ECDSA signatures (RFC 6979)
+
+  * Support for AES-GCM-SIV, a nonce-misuse-resistant AEAD (RFC 8452)
+
+  * Support for the Argon2 KDF, along with supporting thread pool
+    functionality (RFC 9106)
+
+  * Support for Hybrid Public Key Encryption (HPKE) (RFC 9180)
+
+  * Support for SM4-XTS
+
+  * Support for Brainpool curves in TLS 1.3
+
+  * Support for TLS Raw Public Keys (RFC 7250)
+
+  * Support for TCP Fast Open on Linux, macOS and FreeBSD,
+    where enabled and supported (RFC 7413)
+
+  * Support for TLS certificate compression, including library
+    support for zlib, Brotli and zstd (RFC 8879)
+
+  * Support for provider-based pluggable signature algorithms
+    in TLS 1.3 with supporting CMS and X.509 functionality
+
+    With a suitable provider this enables the use of post-quantum/quantum-safe
+    cryptography.
+
+  * Support for using the Windows system certificate store as a source of
+    trusted root certificates
+
+    This is not yet enabled by default and must be activated using an
+    environment variable. This is likely to become enabled by default
+    in a future feature release.
+
+  * Support for using the IANA standard names in TLS ciphersuite configuration
+
+  * Multiple new features and improvements to CMP protocol support
+
+The following known issues are present in this release and will be rectified
+in a future release:
+
+  * Provider-based signature algorithms cannot be configured using the
+    SignatureAlgorithms configuration file parameter (#22761)
+
+This release incorporates the following documentation enhancements:
+
+  * Added multiple tutorials on the OpenSSL library and in particular
+    on writing various clients (using TLS and QUIC protocols) with libssl
+
+    See [OpenSSL Guide].
+
+A more detailed list of changes in this release can be found in the
+[CHANGES.md] file.
+
+Users interested in using the new QUIC functionality are encouraged to read the
+[README file for QUIC][README-QUIC.md], which provides links to relevant
+documentation and example code.
+
+As always, bug reports and issues relating to OpenSSL can be [filed on our issue
+tracker][issue tracker].
+
 OpenSSL 3.1
 -----------
 
+### Major changes between OpenSSL 3.1.4 and OpenSSL 3.1.5 [under development]
+
+  * Fix excessive time spent in DH check / generation with large Q parameter
+    value ([CVE-2023-5678])
+
 ### Major changes between OpenSSL 3.1.3 and OpenSSL 3.1.4 [24 Oct 2023]
 
   * Mitigate incorrect resize handling for symmetric cipher keys and IVs.
@@ -107,7 +200,7 @@ OpenSSL 3.0
   * Fixed a bug where the RC4-MD5 ciphersuite incorrectly used the
     AAD data as the MAC key ([CVE-2022-1434])
   * Fix a bug in the OPENSSL_LH_flush() function that breaks reuse of the memory
-    occuppied by the removed hash table entries ([CVE-2022-1473])
+    occupied by the removed hash table entries ([CVE-2022-1473])
 
 ### Major changes between OpenSSL 3.0.1 and OpenSSL 3.0.2 [15 Mar 2022]
 
@@ -1453,7 +1546,7 @@ OpenSSL 0.9.x
   * Overhauled Win32 builds
   * Cleanups and fixes to the Big Number (BN) library
   * Support for ASN.1 GeneralizedTime
-  * Splitted ASN.1 SETs from SEQUENCEs
+  * Split ASN.1 SETs from SEQUENCEs
   * ASN1 and PEM support for Netscape Certificate Sequences
   * Overhauled Perl interface
   * Lots of source tree cleanups.
@@ -1474,6 +1567,7 @@ OpenSSL 0.9.x
 
 <!-- Links -->
 
+[CVE-2023-5678]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-5678
 [CVE-2023-5363]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-5363
 [CVE-2023-4807]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-4807
 [CVE-2023-3817]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-3817
@@ -1638,3 +1732,7 @@ OpenSSL 0.9.x
 [CVE-2006-2940]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-2940
 [CVE-2006-2937]: https://www.openssl.org/news/vulnerabilities.html#CVE-2006-2937
 [CVE-2005-2969]: https://www.openssl.org/news/vulnerabilities.html#CVE-2005-2969
+[OpenSSL Guide]: https://www.openssl.org/docs/manmaster/man7/ossl-guide-introduction.html
+[CHANGES.md]: ./CHANGES.md
+[README-QUIC.md]: ./README-QUIC.md
+[issue tracker]: https://github.com/openssl/openssl/issues

+ 8 - 0
libs/openssl/NOTES-WINDOWS.md

@@ -77,6 +77,14 @@ Quick start
     - `perl Configure VC-WIN64A`    if you want 64-bit OpenSSL or
     - `perl Configure VC-WIN64-ARM` if you want Windows on Arm (win-arm64)
        OpenSSL or
+    - `perl Configure VC-WIN64-CLANGASM-ARM` if you want Windows on Arm (win-arm64)
+       OpenSSL with assembly support using clang-cl as assembler or
+    - `perl Configure VC-CLANG-WIN64-CLANGASM-ARM` if you want Windows on Arm (win-arm64)
+       OpenSSL using clang-cl as both compiler and assembler or
+    - `perl Configure VC-WIN32-HYBRIDCRT` if you want 32-bit OpenSSL dependent
+       on the Universal CRT or
+    - `perl Configure VC-WIN64A-HYBRIDCRT` if you want 64-bit OpenSSL dependent
+       on the Universal CRT or
     - `perl Configure`              to let Configure figure out the platform
 
  6. `nmake`

+ 1 - 1
libs/openssl/README-FIPS.md

@@ -165,4 +165,4 @@ Using the FIPS Module in applications
 Documentation about using the FIPS module is available on the [fips_module(7)]
 manual page.
 
- [fips_module(7)]: https://www.openssl.org/docs/man3.0/man7/fips_module.html
+ [fips_module(7)]: https://www.openssl.org/docs/manmaster/man7/fips_module.html

+ 2 - 2
libs/openssl/README-PROVIDERS.md

@@ -20,7 +20,7 @@ distribute their own providers which can be added to OpenSSL dynamically.
 Documentation about writing providers is available on the [provider(7)]
 manual page.
 
- [provider(7)]: https://www.openssl.org/docs/man3.0/man7/provider.html
+ [provider(7)]: https://www.openssl.org/docs/manmaster/man7/provider.html
 
 The Default Provider
 --------------------
@@ -88,7 +88,7 @@ Providers to be loaded can be specified in the OpenSSL config file.
 See the [config(5)] manual page for information about how to configure
 providers via the config file, and how to automatically activate them.
 
- [config(5)]: https://www.openssl.org/docs/man3.0/man5/config.html
+ [config(5)]: https://www.openssl.org/docs/manmaster/man5/config.html
 
 The following is a minimal config file example to load and activate both
 the legacy and the default provider in the default library context.

+ 80 - 0
libs/openssl/README-QUIC.md

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

+ 59 - 12
libs/openssl/README.md

@@ -7,10 +7,12 @@ Welcome to the OpenSSL Project
 [![appveyor badge]][appveyor jobs]
 
 OpenSSL is a robust, commercial-grade, full-featured Open Source Toolkit
-for the Transport Layer Security (TLS) protocol formerly known as the
-Secure Sockets Layer (SSL) protocol. The protocol implementation is based
-on a full-strength general purpose cryptographic library, which can also
-be used stand-alone.
+for the TLS (formerly SSL), DTLS and QUIC (currently client side only)
+protocols.
+
+The protocol implementations are based on a full-strength general purpose
+cryptographic library, which can also be used stand-alone. Also included is a
+cryptographic module validated to conform with FIPS standards.
 
 OpenSSL is descended from the SSLeay library developed by Eric A. Young
 and Tim J. Hudson.
@@ -35,7 +37,9 @@ Overview
 The OpenSSL toolkit includes:
 
 - **libssl**
-  an implementation of all TLS protocol versions up to TLSv1.3 ([RFC 8446]).
+  an implementation of all TLS protocol versions up to TLSv1.3 ([RFC 8446]),
+  DTLS protocol versions up to DTLSv1.2 ([RFC 6347]) and
+  the QUIC (currently client side only) version 1 protocol ([RFC 9000]).
 
 - **libcrypto**
   a full-strength general purpose cryptographic library. It constitutes the
@@ -48,7 +52,8 @@ The OpenSSL toolkit includes:
   - creation of X.509 certificates, CSRs and CRLs
   - calculation of message digests
   - encryption and decryption
-  - SSL/TLS client and server tests
+  - SSL/TLS/DTLS and client and server tests
+  - QUIC client tests
   - handling of S/MIME signed or encrypted mail
   - and more...
 
@@ -67,6 +72,10 @@ of the OpenSSL toolkit are available. In particular, on Linux and other
 Unix operating systems, it is normally recommended to link against the
 precompiled shared libraries provided by the distributor or vendor.
 
+We also maintain a list of third parties that produce OpenSSL binaries for
+various Operating Systems (including Windows) on the [Binaries] page on our
+wiki.
+
 For Testing and Development
 ---------------------------
 
@@ -113,12 +122,29 @@ document.
  * [Notes on Perl](NOTES-PERL.md)
  * [Notes on Valgrind](NOTES-VALGRIND.md)
 
-Specific notes on upgrading to OpenSSL 3.0 from previous versions can be found
-in the [migration_guide(7ossl)] manual page.
+Specific notes on upgrading to OpenSSL 3.x from previous versions can be found
+in the [ossl-guide-migration(7ossl)] manual page.
 
 Documentation
 =============
 
+README Files
+------------
+
+There are some README.md files in the top level of the source distribution
+containing additional information on specific topics.
+
+ * [Information about the OpenSSL QUIC protocol implementation](README-QUIC.md)
+ * [Information about the OpenSSL Provider architecture](README-PROVIDERS.md)
+ * [Information about using the OpenSSL FIPS validated module](README-FIPS.md)
+ * [Information about the legacy OpenSSL Engine architecture](README-ENGINES.md)
+
+The OpenSSL Guide
+-----------------
+
+There are some tutorial and introductory pages on some important OpenSSL topics
+within the [OpenSSL Guide].
+
 Manual Pages
 ------------
 
@@ -127,7 +153,14 @@ available online.
 
 - [OpenSSL master](https://www.openssl.org/docs/manmaster)
 - [OpenSSL 3.0](https://www.openssl.org/docs/man3.0)
-- [OpenSSL 1.1.1](https://www.openssl.org/docs/man1.1.1)
+- [OpenSSL 3.1](https://www.openssl.org/docs/man3.1)
+- [OpenSSL 3.2](https://www.openssl.org/docs/man3.2)
+
+Demos
+-----
+
+The are numerous source code demos for using various OpenSSL capabilities in the
+[demos subfolder](./demos).
 
 Wiki
 ----
@@ -166,7 +199,7 @@ attempting to develop or distribute cryptographic code.
 Copyright
 =========
 
-Copyright (c) 1998-2023 The OpenSSL Project
+Copyright (c) 1998-2023 The OpenSSL Project Authors
 
 Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
 
@@ -194,13 +227,27 @@ All rights reserved.
     <https://wiki.openssl.org>
     "OpenSSL Wiki"
 
-[migration_guide(7ossl)]:
-    <https://www.openssl.org/docs/man3.0/man7/migration_guide.html>
+[ossl-guide-migration(7ossl)]:
+    <https://www.openssl.org/docs/manmaster/man7/ossl-guide-migration.html>
     "OpenSSL Migration Guide"
 
 [RFC 8446]:
      <https://tools.ietf.org/html/rfc8446>
 
+[RFC 6347]:
+     <https://tools.ietf.org/html/rfc6347>
+
+[RFC 9000]:
+     <https://tools.ietf.org/html/rfc9000>
+
+[Binaries]:
+    <https://wiki.openssl.org/index.php/Binaries>
+    "List of third party OpenSSL binaries"
+
+[OpenSSL Guide]:
+    <https://www.openssl.org/docs/manmaster/man7/ossl-guide-introduction.html>
+    "An introduction to OpenSSL"
+
 <!-- Logos and Badges -->
 
 [openssl logo]:

+ 3 - 3
libs/openssl/VERSION.dat

@@ -1,7 +1,7 @@
 MAJOR=3
-MINOR=1
-PATCH=4
+MINOR=2
+PATCH=0
 PRE_RELEASE_TAG=
 BUILD_METADATA=
-RELEASE_DATE="24 Oct 2023"
+RELEASE_DATE="23 Nov 2023"
 SHLIB_VERSION=3

+ 8 - 6
libs/openssl/apps/CA.pl.in

@@ -36,6 +36,8 @@ my $CACERT = "cacert.pem";
 my $CACRL = "crl.pem";
 my $DAYS = "-days 365";
 my $CADAYS = "-days 1095";	# 3 years
+my $EXTENSIONS = "-extensions v3_ca";
+my $POLICY = "-policy policy_anything";
 my $NEWKEY = "newkey.pem";
 my $NEWREQ = "newreq.pem";
 my $NEWCERT = "newcert.pem";
@@ -179,7 +181,7 @@ if ($WHAT eq '-newcert' ) {
         $RET = run("$CA -create_serial"
                 . " -out ${CATOP}/$CACERT $CADAYS -batch"
                 . " -keyfile ${CATOP}/private/$CAKEY -selfsign"
-                . " -extensions v3_ca"
+                . " $EXTENSIONS"
                 . " -infiles ${CATOP}/$CAREQ $EXTRA{ca}") if $RET == 0;
         print "CA certificate is in ${CATOP}/$CACERT\n" if $RET == 0;
     }
@@ -191,19 +193,19 @@ if ($WHAT eq '-newcert' ) {
             . " -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"
+    $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"
+    $RET = run("$CA $POLICY -out $NEWCERT"
             .  "-infiles tmp.pem $EXTRA{ca}") if $RET == 0;
     print "Signed certificate is in $NEWCERT\n" if $RET == 0;
 } elsif ($WHAT eq '-verify' ) {

+ 9 - 10
libs/openssl/apps/asn1parse.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -32,7 +32,7 @@ const OPTIONS asn1parse_options[] = {
     {"oid", OPT_OID, '<', "file of extra oid definitions"},
 
     OPT_SECTION("I/O"),
-    {"inform", OPT_INFORM, 'F', "input format - one of DER PEM"},
+    {"inform", OPT_INFORM, 'A', "input format - one of DER PEM B64"},
     {"in", OPT_IN, '<', "input file"},
     {"out", OPT_OUT, '>', "output file (output format is always DER)"},
     {"noout", OPT_NOOUT, 0, "do not produce any output"},
@@ -44,7 +44,7 @@ const OPTIONS asn1parse_options[] = {
     {OPT_MORE_STR, 0, 0, "into multiple ASN1 blob wrappings"},
     {"genconf", OPT_GENCONF, 's', "file to generate ASN1 structure from"},
     {"strictpem", OPT_STRICTPEM, 0,
-     "do not attempt base64 decode outside PEM markers"},
+     "equivalent to '-inform pem' (obsolete)"},
     {"item", OPT_ITEM, 's', "item to parse and print"},
     {OPT_MORE_STR, 0, 0, "(-inform  will be ignored)"},
 
@@ -69,7 +69,7 @@ int asn1parse_main(int argc, char **argv)
     unsigned char *str = NULL;
     char *name = NULL, *header = NULL, *prog;
     const unsigned char *ctmpbuf;
-    int indent = 0, noout = 0, dump = 0, strictpem = 0, informat = FORMAT_PEM;
+    int indent = 0, noout = 0, dump = 0, informat = FORMAT_PEM;
     int offset = 0, ret = 1, i, j;
     long num, tmplen;
     unsigned char *tmpbuf;
@@ -96,7 +96,7 @@ int asn1parse_main(int argc, char **argv)
             ret = 0;
             goto end;
         case OPT_INFORM:
-            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
+            if (!opt_format(opt_arg(), OPT_FMT_ASN1, &informat))
                 goto opthelp;
             break;
         case OPT_IN:
@@ -136,7 +136,7 @@ int asn1parse_main(int argc, char **argv)
             genconf = opt_arg();
             break;
         case OPT_STRICTPEM:
-            strictpem = 1;
+            /* accepted for backward compatibility */
             informat = FORMAT_PEM;
             break;
         case OPT_ITEM:
@@ -159,8 +159,7 @@ int asn1parse_main(int argc, char **argv)
     }
 
     /* No extra args. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     if (oidfile != NULL) {
@@ -179,7 +178,7 @@ int asn1parse_main(int argc, char **argv)
 
     if ((buf = BUF_MEM_new()) == NULL)
         goto end;
-    if (strictpem) {
+    if (informat == FORMAT_PEM) {
         if (PEM_read_bio(in, &name, &header, &str, &num) != 1) {
             BIO_printf(bio_err, "Error reading PEM file\n");
             ERR_print_errors(bio_err);
@@ -199,7 +198,7 @@ int asn1parse_main(int argc, char **argv)
             }
         } else {
 
-            if (informat == FORMAT_PEM) {
+            if (informat == FORMAT_BASE64) {
                 BIO *tmp;
 
                 if ((b64 = BIO_new(BIO_f_base64())) == NULL)

+ 58 - 88
libs/openssl/apps/ca.c

@@ -129,7 +129,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
                    CONF *conf, unsigned long certopt, unsigned long nameopt,
                    int default_op, int ext_copy, int selfsign, unsigned long dateopt);
 static int get_certificate_status(const char *ser_status, CA_DB *db);
-static int do_updatedb(CA_DB *db);
 static int check_time_format(const char *str);
 static int do_revoke(X509 *x509, CA_DB *db, REVINFO_TYPE rev_type,
                      const char *extval);
@@ -154,7 +153,7 @@ typedef enum OPTION_choice {
     OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC,
     OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID,
     OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS,
-    OPT_RAND_SERIAL,
+    OPT_RAND_SERIAL, OPT_QUIET,
     OPT_R_ENUM, OPT_PROV_ENUM,
     /* Do not change the order here; see related case statements below */
     OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, OPT_CRL_CA_COMPROMISE
@@ -166,9 +165,11 @@ const OPTIONS ca_options[] = {
     OPT_SECTION("General"),
     {"help", OPT_HELP, '-', "Display this summary"},
     {"verbose", OPT_VERBOSE, '-', "Verbose output during processing"},
+    {"quiet", OPT_QUIET, '-', "Terse output during processing"},
     {"outdir", OPT_OUTDIR, '/', "Where to put output cert"},
     {"in", OPT_IN, '<', "The input cert request(s)"},
-    {"inform", OPT_INFORM, 'F', "CSR input format (DER or PEM); default PEM"},
+    {"inform", OPT_INFORM, 'F',
+     "CSR input format to use (PEM or DER; by default try PEM first)"},
     {"infiles", OPT_INFILES, '-', "The last argument, requests to process"},
     {"out", OPT_OUT, '>', "Where to put the output file(s)"},
     {"dateopt", OPT_DATEOPT, 's', "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."},
@@ -332,6 +333,9 @@ opthelp:
         case OPT_VERBOSE:
             verbose = 1;
             break;
+        case OPT_QUIET:
+            verbose = 0;
+            break;
         case OPT_CONFIG:
             configfile = opt_arg();
             break;
@@ -510,9 +514,7 @@ end_of_options:
         && (section = lookup_conf(conf, BASE_SECTION, ENV_DEFAULT_CA)) == NULL)
         goto end;
 
-    p = NCONF_get_string(conf, NULL, "oid_file");
-    if (p == NULL)
-        ERR_clear_error();
+    p = app_conf_try_string(conf, NULL, "oid_file");
     if (p != NULL) {
         BIO *oid_bio = BIO_new_file(p, "r");
 
@@ -530,29 +532,22 @@ end_of_options:
     if (!app_RAND_load())
         goto end;
 
-    f = NCONF_get_string(conf, section, STRING_MASK);
-    if (f == NULL)
-        ERR_clear_error();
-
+    f = app_conf_try_string(conf, section, STRING_MASK);
     if (f != NULL && !ASN1_STRING_set_default_mask_asc(f)) {
         BIO_printf(bio_err, "Invalid global string mask setting %s\n", f);
         goto end;
     }
 
     if (chtype != MBSTRING_UTF8) {
-        f = NCONF_get_string(conf, section, UTF8_IN);
-        if (f == NULL)
-            ERR_clear_error();
-        else if (strcmp(f, "yes") == 0)
+        f = app_conf_try_string(conf, section, UTF8_IN);
+        if (f != NULL && strcmp(f, "yes") == 0)
             chtype = MBSTRING_UTF8;
     }
 
     db_attr.unique_subject = 1;
-    p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT);
+    p = app_conf_try_string(conf, section, ENV_UNIQUE_SUBJECT);
     if (p != NULL)
         db_attr.unique_subject = parse_yesno(p, 1);
-    else
-        ERR_clear_error();
 
     /*****************************************************************/
     /* report status of cert with serial number given on command line */
@@ -615,21 +610,14 @@ end_of_options:
     if (!selfsign)
         x509p = x509;
 
-    f = NCONF_get_string(conf, BASE_SECTION, ENV_PRESERVE);
-    if (f == NULL)
-        ERR_clear_error();
-    if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
+    f = app_conf_try_string(conf, BASE_SECTION, ENV_PRESERVE);
+    if (f != NULL && (*f == 'y' || *f == 'Y'))
         preserve = 1;
-    f = NCONF_get_string(conf, BASE_SECTION, ENV_MSIE_HACK);
-    if (f == NULL)
-        ERR_clear_error();
-    if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
+    f = app_conf_try_string(conf, BASE_SECTION, ENV_MSIE_HACK);
+    if (f != NULL && (*f == 'y' || *f == 'Y'))
         msie_hack = 1;
 
-    f = NCONF_get_string(conf, section, ENV_NAMEOPT);
-
-    if (f == NULL)
-        ERR_clear_error();
+    f = app_conf_try_string(conf, section, ENV_NAMEOPT);
     if (f != NULL) {
         if (!set_nameopt(f)) {
             BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
@@ -638,27 +626,21 @@ end_of_options:
         default_op = 0;
     }
 
-    f = NCONF_get_string(conf, section, ENV_CERTOPT);
-
+    f = app_conf_try_string(conf, section, ENV_CERTOPT);
     if (f != NULL) {
         if (!set_cert_ex(&certopt, f)) {
             BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
             goto end;
         }
         default_op = 0;
-    } else {
-        ERR_clear_error();
     }
 
-    f = NCONF_get_string(conf, section, ENV_EXTCOPY);
-
+    f = app_conf_try_string(conf, section, ENV_EXTCOPY);
     if (f != NULL) {
         if (!set_ext_copy(&ext_copy, f)) {
             BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
             goto end;
         }
-    } else {
-        ERR_clear_error();
     }
 
     /*****************************************************************/
@@ -753,7 +735,7 @@ end_of_options:
         if (verbose)
             BIO_printf(bio_err, "Updating %s ...\n", dbfile);
 
-        i = do_updatedb(db);
+        i = do_updatedb(db, NULL);
         if (i == -1) {
             BIO_printf(bio_err, "Malloc failure\n");
             goto end;
@@ -786,11 +768,10 @@ end_of_options:
 
         /* We can have sections in the ext file */
         if (extensions == NULL) {
-            extensions = NCONF_get_string(extfile_conf, "default", "extensions");
-            if (extensions == NULL) {
-                ERR_clear_error();
+            extensions =
+                app_conf_try_string(extfile_conf, "default", "extensions");
+            if (extensions == NULL)
                 extensions = "default";
-            }
         }
     }
 
@@ -832,9 +813,8 @@ end_of_options:
         if (email_dn == 1) {
             char *tmp_email_dn = NULL;
 
-            tmp_email_dn = NCONF_get_string(conf, section, ENV_DEFAULT_EMAIL_DN);
-            if (tmp_email_dn == NULL)
-                ERR_clear_error();
+            tmp_email_dn =
+                app_conf_try_string(conf, section, ENV_DEFAULT_EMAIL_DN);
             if (tmp_email_dn != NULL && strcmp(tmp_email_dn, "no") == 0)
                 email_dn = 0;
         }
@@ -847,10 +827,9 @@ end_of_options:
         if (verbose)
             BIO_printf(bio_err, "policy is %s\n", policy);
 
-        if (NCONF_get_string(conf, section, ENV_RAND_SERIAL) != NULL) {
+        if (app_conf_try_string(conf, section, ENV_RAND_SERIAL) != NULL) {
             rand_ser = 1;
         } else {
-            ERR_clear_error();
             serialfile = lookup_conf(conf, section, ENV_SERIAL);
             if (serialfile == NULL)
                 goto end;
@@ -874,11 +853,8 @@ end_of_options:
              * no '-extfile' option, so we look for extensions in the main
              * configuration file
              */
-            if (extensions == NULL) {
-                extensions = NCONF_get_string(conf, section, ENV_EXTENSIONS);
-                if (extensions == NULL)
-                    ERR_clear_error();
-            }
+            if (extensions == NULL)
+                extensions = app_conf_try_string(conf, section, ENV_EXTENSIONS);
             if (extensions != NULL) {
                 /* Check syntax of config file section */
                 X509V3_CTX ctx;
@@ -895,11 +871,9 @@ end_of_options:
             }
         }
 
-        if (startdate == NULL) {
-            startdate = NCONF_get_string(conf, section, ENV_DEFAULT_STARTDATE);
-            if (startdate == NULL)
-                ERR_clear_error();
-        }
+        if (startdate == NULL)
+            startdate =
+                app_conf_try_string(conf, section, ENV_DEFAULT_STARTDATE);
         if (startdate != NULL && !ASN1_TIME_set_string_X509(NULL, startdate)) {
             BIO_printf(bio_err,
                        "start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
@@ -908,11 +882,8 @@ end_of_options:
         if (startdate == NULL)
             startdate = "today";
 
-        if (enddate == NULL) {
-            enddate = NCONF_get_string(conf, section, ENV_DEFAULT_ENDDATE);
-            if (enddate == NULL)
-                ERR_clear_error();
-        }
+        if (enddate == NULL)
+            enddate = app_conf_try_string(conf, section, ENV_DEFAULT_ENDDATE);
         if (enddate != NULL && !ASN1_TIME_set_string_X509(NULL, enddate)) {
             BIO_printf(bio_err,
                        "end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
@@ -920,10 +891,8 @@ end_of_options:
         }
 
         if (days == 0) {
-            if (!NCONF_get_number(conf, section, ENV_DEFAULT_DAYS, &days)) {
-                ERR_clear_error();
+            if (!app_conf_try_number(conf, section, ENV_DEFAULT_DAYS, &days))
                 days = 0;
-            }
         }
         if (enddate == NULL && days == 0) {
             BIO_printf(bio_err, "cannot lookup how many days to certify for\n");
@@ -1156,11 +1125,9 @@ end_of_options:
     /*****************************************************************/
     if (gencrl) {
         int crl_v2 = 0;
-        if (crl_ext == NULL) {
-            crl_ext = NCONF_get_string(conf, section, ENV_CRLEXT);
-            if (crl_ext == NULL)
-                ERR_clear_error();
-        }
+
+        if (crl_ext == NULL)
+            crl_ext = app_conf_try_string(conf, section, ENV_CRLEXT);
         if (crl_ext != NULL) {
             /* Check syntax of file */
             X509V3_CTX ctx;
@@ -1175,28 +1142,22 @@ end_of_options:
             }
         }
 
-        crlnumberfile = NCONF_get_string(conf, section, ENV_CRLNUMBER);
+        crlnumberfile = app_conf_try_string(conf, section, ENV_CRLNUMBER);
         if (crlnumberfile != NULL) {
             if ((crlnumber = load_serial(crlnumberfile, NULL, 0, NULL))
                 == NULL) {
                 BIO_printf(bio_err, "error while loading CRL number\n");
                 goto end;
             }
-        } else {
-            ERR_clear_error();
         }
 
         if (!crldays && !crlhours && !crlsec) {
-            if (!NCONF_get_number(conf, section,
-                                  ENV_DEFAULT_CRL_DAYS, &crldays)) {
-                ERR_clear_error();
+            if (!app_conf_try_number(conf, section,
+                                  ENV_DEFAULT_CRL_DAYS, &crldays))
                 crldays = 0;
-            }
-            if (!NCONF_get_number(conf, section,
-                                  ENV_DEFAULT_CRL_HOURS, &crlhours)) {
-                ERR_clear_error();
+            if (!app_conf_try_number(conf, section,
+                                  ENV_DEFAULT_CRL_HOURS, &crlhours))
                 crlhours = 0;
-            }
         }
         if ((crl_nextupdate == NULL) &&
                 (crldays == 0) && (crlhours == 0) && (crlsec == 0)) {
@@ -1347,7 +1308,7 @@ end_of_options:
     BIO_free_all(Sout);
     BIO_free_all(out);
     BIO_free_all(in);
-    sk_X509_pop_free(cert_sk, X509_free);
+    OSSL_STACK_OF_X509_free(cert_sk);
 
     cleanse(passin);
     if (free_passin)
@@ -1391,7 +1352,7 @@ static int certify(X509 **xret, const char *infile, int informat,
     EVP_PKEY *pktmp = NULL;
     int ok = -1, i;
 
-    req = load_csr(infile, informat, "certificate request");
+    req = load_csr_autofmt(infile, informat, vfyopts, "certificate request");
     if (req == NULL)
         goto end;
     if ((pktmp = X509_REQ_get0_pubkey(req)) == NULL) {
@@ -1731,7 +1692,16 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
 
     /* Initialize the context structure */
     X509V3_set_ctx(&ext_ctx, selfsign ? ret : x509,
-                   ret, req, NULL, X509V3_CTX_REPLACE);
+                   ret, NULL /* no need to give req, needed info is in ret */,
+                   NULL, X509V3_CTX_REPLACE);
+    /* prepare fallback for AKID, but only if issuer cert equals subject cert */
+    if (selfsign) {
+        if (!X509V3_set_issuer_pkey(&ext_ctx, pkey))
+            goto end;
+        if (!cert_matches_key(ret, pkey))
+            BIO_printf(bio_err,
+                       "Warning: Signature key and public key of cert do not match\n");
+    }
 
     /* Lets add the extensions, if there are any */
     if (ext_sect) {
@@ -1868,7 +1838,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
             p = "Valid";
         else
             p = "\ninvalid type, Database error\n";
-        BIO_printf(bio_err, "Type          :%s\n", p);;
+        BIO_printf(bio_err, "Type          :%s\n", p);
         if (rrow[DB_type][0] == DB_TYPE_REV) {
             p = rrow[DB_exp_date];
             if (p == NULL)
@@ -1933,7 +1903,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
         !EVP_PKEY_missing_parameters(pkey))
         EVP_PKEY_copy_parameters(pktmp, pkey);
 
-    if (!do_X509_sign(ret, pkey, dgst, sigopts, &ext_ctx))
+    if (!do_X509_sign(ret, 0, pkey, dgst, sigopts, &ext_ctx))
         goto end;
 
     /* We now just add it to the database as DB_TYPE_VAL('V') */
@@ -2299,7 +2269,7 @@ static int get_certificate_status(const char *serial, CA_DB *db)
     return ok;
 }
 
-static int do_updatedb(CA_DB *db)
+int do_updatedb(CA_DB *db, time_t *now)
 {
     ASN1_TIME *a_tm = NULL;
     int i, cnt = 0;
@@ -2310,7 +2280,7 @@ static int do_updatedb(CA_DB *db)
         return -1;
 
     /* get actual time */
-    if (X509_gmtime_adj(a_tm, 0) == NULL) {
+    if (X509_time_adj(a_tm, 0, now) == NULL) {
         ASN1_TIME_free(a_tm);
         return -1;
     }

+ 2 - 3
libs/openssl/apps/ciphers.c

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

文件差异内容过多而无法显示
+ 264 - 180
libs/openssl/apps/cmp.c


+ 51 - 17
libs/openssl/apps/cms.c

@@ -66,7 +66,7 @@ typedef enum OPTION_choice {
     OPT_DECRYPT, OPT_SIGN, OPT_CADES, OPT_SIGN_RECEIPT, OPT_RESIGN,
     OPT_VERIFY, OPT_VERIFY_RETCODE, OPT_VERIFY_RECEIPT,
     OPT_CMSOUT, OPT_DATA_OUT, OPT_DATA_CREATE, OPT_DIGEST_VERIFY,
-    OPT_DIGEST_CREATE, OPT_COMPRESS, OPT_UNCOMPRESS,
+    OPT_DIGEST, OPT_DIGEST_CREATE, OPT_COMPRESS, OPT_UNCOMPRESS,
     OPT_ED_DECRYPT, OPT_ED_ENCRYPT, OPT_DEBUG_DECRYPT, OPT_TEXT,
     OPT_ASCIICRLF, OPT_NOINTERN, OPT_NOVERIFY, OPT_NOCERTS,
     OPT_NOATTR, OPT_NODETACH, OPT_NOSMIMECAP, OPT_BINARY, OPT_KEYID,
@@ -106,6 +106,7 @@ const OPTIONS cms_options[] = {
      "Generate a signed receipt for a message"},
     {"verify_receipt", OPT_VERIFY_RECEIPT, '<',
      "Verify receipts; exit if receipt signatures do not verify"},
+    {"digest", OPT_DIGEST, 's', "Sign a pre-computed digest in hex notation"},
     {"digest_create", OPT_DIGEST_CREATE, '-',
      "Create a CMS \"DigestedData\" object"},
     {"digest_verify", OPT_DIGEST_VERIFY, '-',
@@ -293,6 +294,9 @@ int cms_main(int argc, char **argv)
     const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL;
     char *certsoutfile = NULL, *digestname = NULL, *wrapname = NULL;
     int noCAfile = 0, noCApath = 0, noCAstore = 0;
+    char *digesthex = NULL;
+    unsigned char *digestbin = NULL;
+    long digestlen = 0;
     char *infile = NULL, *outfile = NULL, *rctfile = NULL;
     char *passinarg = NULL, *passin = NULL, *signerfile = NULL;
     char *originatorfile = NULL, *recipfile = NULL, *ciphername = NULL;
@@ -314,6 +318,7 @@ int cms_main(int argc, char **argv)
     if (encerts == NULL || vpm == NULL)
         goto end;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, cms_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -366,6 +371,9 @@ int cms_main(int argc, char **argv)
         case OPT_DIGEST_CREATE:
             operation = SMIME_DIGEST_CREATE;
             break;
+        case OPT_DIGEST:
+            digesthex = opt_arg();
+            break;
         case OPT_DIGEST_VERIFY:
             operation = SMIME_DIGEST_VERIFY;
             break;
@@ -697,10 +705,8 @@ int cms_main(int argc, char **argv)
         if (!opt_md(digestname, &sign_md))
             goto end;
     }
-    if (ciphername != NULL) {
-        if (!opt_cipher_any(ciphername, &cipher))
-            goto end;
-    }
+    if (!opt_cipher_any(ciphername, &cipher))
+        goto end;
     if (wrapname != NULL) {
         if (!opt_cipher_any(wrapname, &wrap_cipher))
             goto end;
@@ -883,10 +889,31 @@ int cms_main(int argc, char **argv)
             goto end;
     }
 
-    in = bio_open_default(infile, 'r',
-                          binary_files ? FORMAT_BINARY : informat);
-    if (in == NULL)
-        goto end;
+    if (digesthex != NULL) {
+        if (operation != SMIME_SIGN) {
+            BIO_printf(bio_err,
+                       "Cannot use -digest for non-signing operation\n");
+            goto end;
+        }
+        if (infile != NULL
+            || (flags & CMS_DETACHED) == 0
+            || (flags & CMS_STREAM) != 0) {
+            BIO_printf(bio_err,
+                       "Cannot use -digest when -in, -nodetach or streaming is used\n");
+            goto end;
+        }
+        digestbin = OPENSSL_hexstr2buf(digesthex, &digestlen);
+        if (digestbin == NULL) {
+            BIO_printf(bio_err,
+                       "Invalid hex value after -digest\n");
+            goto end;
+        }
+    } else {
+        in = bio_open_default(infile, 'r',
+                              binary_files ? FORMAT_BINARY : informat);
+        if (in == NULL)
+            goto end;
+    }
 
     if (operation & SMIME_IP) {
         cms = load_content_info(informat, in, flags, &indata, "SMIME");
@@ -908,7 +935,7 @@ int cms_main(int argc, char **argv)
                 ret = 5;
                 goto end;
             }
-            sk_X509_pop_free(allcerts, X509_free);
+            OSSL_STACK_OF_X509_free(allcerts);
         }
     }
 
@@ -987,7 +1014,8 @@ int cms_main(int argc, char **argv)
                     && wrap_cipher != NULL) {
                 EVP_CIPHER_CTX *wctx;
                 wctx = CMS_RecipientInfo_kari_get0_ctx(ri);
-                EVP_EncryptInit_ex(wctx, wrap_cipher, NULL, NULL, NULL);
+                if (EVP_EncryptInit_ex(wctx, wrap_cipher, NULL, NULL, NULL) != 1)
+                    goto end;
             }
         }
 
@@ -1035,12 +1063,12 @@ int cms_main(int argc, char **argv)
     } else if (operation & SMIME_SIGNERS) {
         int i;
         /*
-         * If detached data content we enable streaming if S/MIME output
-         * format.
+         * If detached data content and not signing pre-computed digest, we
+         * enable streaming if S/MIME output format.
          */
         if (operation == SMIME_SIGN) {
 
-            if (flags & CMS_DETACHED) {
+            if ((flags & CMS_DETACHED) != 0 && digestbin == NULL) {
                 if (outformat == FORMAT_SMIME)
                     flags |= CMS_STREAM;
             }
@@ -1101,7 +1129,12 @@ int cms_main(int argc, char **argv)
             key = NULL;
         }
         /* If not streaming or resigning finalize structure */
-        if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM)) {
+        if (operation == SMIME_SIGN && digestbin != NULL
+            && (flags & CMS_STREAM) == 0) {
+            /* Use pre-computed digest instead of content */
+            if (!CMS_final_digest(cms, digestbin, digestlen, NULL, flags))
+                goto end;
+        } else if (operation == SMIME_SIGN && (flags & CMS_STREAM) == 0) {
             if (!CMS_final(cms, in, NULL, flags))
                 goto end;
         }
@@ -1236,8 +1269,8 @@ int cms_main(int argc, char **argv)
  end:
     if (ret)
         ERR_print_errors(bio_err);
-    sk_X509_pop_free(encerts, X509_free);
-    sk_X509_pop_free(other, X509_free);
+    OSSL_STACK_OF_X509_free(encerts);
+    OSSL_STACK_OF_X509_free(other);
     X509_VERIFY_PARAM_free(vpm);
     sk_OPENSSL_STRING_free(sksigners);
     sk_OPENSSL_STRING_free(skkeys);
@@ -1270,6 +1303,7 @@ int cms_main(int argc, char **argv)
     BIO_free(in);
     BIO_free(indata);
     BIO_free_all(out);
+    OPENSSL_free(digestbin);
     OPENSSL_free(passin);
     NCONF_free(conf);
     return ret;

+ 5 - 7
libs/openssl/apps/crl.c

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

+ 1 - 2
libs/openssl/apps/crl2pkcs7.c

@@ -104,8 +104,7 @@ int crl2pkcs7_main(int argc, char **argv)
     }
 
     /* No remaining args. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     if (!nocrl) {

+ 3 - 2
libs/openssl/apps/dgst.c

@@ -117,6 +117,7 @@ int dgst_main(int argc, char **argv)
     if (md != NULL)
         digestname = argv[0];
 
+    opt_set_unknown_name("digest");
     prog = opt_init(argc, argv, dgst_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -514,7 +515,7 @@ static void show_digests(const OBJ_NAME *name, void *arg)
  * in the '*sum' checksum programs. This aims to preserve backward
  * compatibility.
  */
-static const char *newline_escape_filename(const char *file, int * backslash)
+static const char *newline_escape_filename(const char *file, int *backslash)
 {
     size_t i, e = 0, length = strlen(file), newline_count = 0, mem_len = 0;
     char *file_cpy = NULL;
@@ -527,7 +528,7 @@ static const char *newline_escape_filename(const char *file, int * backslash)
     file_cpy = app_malloc(mem_len, file);
     i = 0;
 
-    while(e < length) {
+    while (e < length) {
         const char c = file[e];
         if (c == '\n') {
             file_cpy[i++] = '\\';

+ 18 - 18
libs/openssl/apps/dhparam.c

@@ -31,13 +31,14 @@
 #define DEFBITS 2048
 
 static EVP_PKEY *dsa_to_dh(EVP_PKEY *dh);
-static int gendh_cb(EVP_PKEY_CTX *ctx);
+
+static int verbose = 1;
 
 typedef enum OPTION_choice {
     OPT_COMMON,
     OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT,
     OPT_ENGINE, OPT_CHECK, OPT_TEXT, OPT_NOOUT,
-    OPT_DSAPARAM, OPT_2, OPT_3, OPT_5,
+    OPT_DSAPARAM, OPT_2, OPT_3, OPT_5, OPT_VERBOSE, OPT_QUIET,
     OPT_R_ENUM, OPT_PROV_ENUM
 } OPTION_CHOICE;
 
@@ -67,6 +68,8 @@ const OPTIONS dhparam_options[] = {
     {"2", OPT_2, '-', "Generate parameters using 2 as the generator value"},
     {"3", OPT_3, '-', "Generate parameters using 3 as the generator value"},
     {"5", OPT_5, '-', "Generate parameters using 5 as the generator value"},
+    {"verbose", OPT_VERBOSE, '-', "Verbose output"},
+    {"quiet", OPT_QUIET, '-', "Terse output"},
 
     OPT_R_OPTIONS,
     OPT_PROV_OPTIONS,
@@ -138,6 +141,12 @@ int dhparam_main(int argc, char **argv)
         case OPT_NOOUT:
             noout = 1;
             break;
+        case OPT_VERBOSE:
+            verbose = 1;
+            break;
+        case OPT_QUIET:
+            verbose = 0;
+            break;
         case OPT_R_CASES:
             if (!opt_rand(o))
                 goto end;
@@ -155,7 +164,7 @@ int dhparam_main(int argc, char **argv)
     if (argc == 1) {
         if (!opt_int(argv[0], &num) || num <= 0)
             goto opthelp;
-    } else if (argc != 0) {
+    } else if (!opt_check_rest_arg(NULL)) {
         goto opthelp;
     }
     if (!app_RAND_load())
@@ -192,11 +201,13 @@ int dhparam_main(int argc, char **argv)
                         alg);
             goto end;
         }
-        EVP_PKEY_CTX_set_cb(ctx, gendh_cb);
         EVP_PKEY_CTX_set_app_data(ctx, bio_err);
-        BIO_printf(bio_err,
-                    "Generating %s parameters, %d bit long %sprime\n",
-                    alg, num, dsaparam ? "" : "safe ");
+        if (verbose) {
+            EVP_PKEY_CTX_set_cb(ctx, progress_cb);
+            BIO_printf(bio_err,
+                        "Generating %s parameters, %d bit long %sprime\n",
+                        alg, num, dsaparam ? "" : "safe ");
+        }
 
         if (EVP_PKEY_paramgen_init(ctx) <= 0) {
             BIO_printf(bio_err,
@@ -405,14 +416,3 @@ static EVP_PKEY *dsa_to_dh(EVP_PKEY *dh)
     return pkey;
 }
 
-static int gendh_cb(EVP_PKEY_CTX *ctx)
-{
-    int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
-    BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
-    static const char symbols[] = ".+*\n";
-    char c = (p >= 0 && (size_t)p < sizeof(symbols) - 1) ? symbols[p] : '?';
-
-    BIO_write(b, &c, 1);
-    (void)BIO_flush(b);
-    return 1;
-}

+ 6 - 10
libs/openssl/apps/dsa.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -92,6 +92,7 @@ int dsa_main(int argc, char **argv)
     int selection = 0;
     OSSL_ENCODER_CTX *ectx = NULL;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, dsa_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -161,17 +162,12 @@ int dsa_main(int argc, char **argv)
     }
 
     /* No extra args. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
-    if (ciphername != NULL) {
-        if (!opt_cipher(ciphername, &enc))
-            goto end;
-    }
-    private = pubin || pubout ? 0 : 1;
-    if (text && !pubin)
-        private = 1;
+    if (!opt_cipher(ciphername, &enc))
+        goto end;
+    private = !pubin && (!pubout || text);
 
     if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
         BIO_printf(bio_err, "Error getting passwords\n");

+ 25 - 30
libs/openssl/apps/dsaparam.c

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

+ 6 - 10
libs/openssl/apps/ec.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -80,6 +80,7 @@ int ec_main(int argc, char **argv)
     char *point_format = NULL;
     int no_public = 0;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, ec_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -157,17 +158,12 @@ int ec_main(int argc, char **argv)
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
-    if (ciphername != NULL) {
-        if (!opt_cipher(ciphername, &enc))
-            goto opthelp;
-    }
-    private = param_out || pubin || pubout ? 0 : 1;
-    if (text && !pubin)
-        private = 1;
+    if (!opt_cipher(ciphername, &enc))
+        goto opthelp;
+    private = !pubin && (text || (!param_out && !pubout));
 
     if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
         BIO_printf(bio_err, "Error getting passwords\n");

+ 11 - 4
libs/openssl/apps/ecparam.c

@@ -186,8 +186,7 @@ int ecparam_main(int argc, char **argv)
     }
 
     /* No extra args. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     if (!app_RAND_load())
@@ -243,9 +242,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,

+ 108 - 29
libs/openssl/apps/enc.c

@@ -49,7 +49,7 @@ typedef enum OPTION_choice {
     OPT_NOPAD, OPT_SALT, OPT_NOSALT, OPT_DEBUG, OPT_UPPER_P, OPT_UPPER_A,
     OPT_A, OPT_Z, OPT_BUFSIZE, OPT_K, OPT_KFILE, OPT_UPPER_K, OPT_NONE,
     OPT_UPPER_S, OPT_IV, OPT_MD, OPT_ITER, OPT_PBKDF2, OPT_CIPHER,
-    OPT_R_ENUM, OPT_PROV_ENUM
+    OPT_SALTLEN, OPT_R_ENUM, OPT_PROV_ENUM
 } OPTION_CHOICE;
 
 const OPTIONS enc_options[] = {
@@ -100,7 +100,9 @@ const OPTIONS enc_options[] = {
     {OPT_MORE_STR, 0, 0,
      "Use -iter to change the iteration count from " STR(PBKDF2_ITER_DEFAULT)},
     {"none", OPT_NONE, '-', "Don't encrypt"},
-#ifdef ZLIB
+    {"saltlen", OPT_SALTLEN, 'p', "Specify the PBKDF2 salt length (in bytes)"},
+    {OPT_MORE_STR, 0, 0, "Default: 16"},
+#ifndef OPENSSL_NO_ZLIB
     {"z", OPT_Z, '-', "Compress or decompress encrypted data using zlib"},
 #endif
     {"", OPT_CIPHER, '-', "Any supported cipher"},
@@ -132,26 +134,42 @@ int enc_main(int argc, char **argv)
     int base64 = 0, informat = FORMAT_BINARY, outformat = FORMAT_BINARY;
     int ret = 1, inl, nopad = 0;
     unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
-    unsigned char *buff = NULL, salt[PKCS5_SALT_LEN];
+    unsigned char *buff = NULL, salt[EVP_MAX_IV_LENGTH];
+    int saltlen = 0;
     int pbkdf2 = 0;
     int iter = 0;
     long n;
+    int streamable = 1;
+    int wrap = 0;
     struct doall_enc_ciphers dec;
-#ifdef ZLIB
+#ifndef OPENSSL_NO_ZLIB
     int do_zlib = 0;
     BIO *bzl = NULL;
 #endif
+    int do_brotli = 0;
+    BIO *bbrot = NULL;
+    int do_zstd = 0;
+    BIO *bzstd = NULL;
 
     /* first check the command name */
     if (strcmp(argv[0], "base64") == 0)
         base64 = 1;
-#ifdef ZLIB
+#ifndef OPENSSL_NO_ZLIB
     else if (strcmp(argv[0], "zlib") == 0)
         do_zlib = 1;
+#endif
+#ifndef OPENSSL_NO_BROTLI
+    else if (strcmp(argv[0], "brotli") == 0)
+        do_brotli = 1;
+#endif
+#ifndef OPENSSL_NO_ZSTD
+    else if (strcmp(argv[0], "zstd") == 0)
+        do_zstd = 1;
 #endif
     else if (strcmp(argv[0], "enc") != 0)
         ciphername = argv[0];
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, enc_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -219,7 +237,7 @@ int enc_main(int argc, char **argv)
             base64 = 1;
             break;
         case OPT_Z:
-#ifdef ZLIB
+#ifndef OPENSSL_NO_ZLIB
             do_zlib = 1;
 #endif
             break;
@@ -278,6 +296,12 @@ int enc_main(int argc, char **argv)
             iter = opt_int_arg();
             pbkdf2 = 1;
             break;
+        case OPT_SALTLEN:
+            if (!opt_int(opt_arg(), &saltlen))
+                goto opthelp;
+            if (saltlen > (int)sizeof(salt))
+                saltlen = (int)sizeof(salt);
+            break;
         case OPT_PBKDF2:
             pbkdf2 = 1;
             if (iter == 0)    /* do not overwrite a chosen value */
@@ -298,16 +322,19 @@ int enc_main(int argc, char **argv)
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
     if (!app_RAND_load())
         goto end;
+    if (saltlen == 0 || pbkdf2 == 0)
+        saltlen = PKCS5_SALT_LEN;
 
     /* Get the cipher name, either from progname (if set) or flag. */
-    if (ciphername != NULL) {
-        if (!opt_cipher(ciphername, &cipher))
-            goto opthelp;
+    if (!opt_cipher(ciphername, &cipher))
+        goto opthelp;
+    if (cipher && (EVP_CIPHER_mode(cipher) == EVP_CIPH_WRAP_MODE)) {
+        wrap = 1;
+        streamable = 0;
     }
     if (digestname != NULL) {
         if (!opt_md(digestname, &dgst))
@@ -325,20 +352,30 @@ int enc_main(int argc, char **argv)
     if (verbose)
         BIO_printf(bio_err, "bufsize=%d\n", bsize);
 
-#ifdef ZLIB
-    if (!do_zlib)
+#ifndef OPENSSL_NO_ZLIB
+    if (do_zlib)
+        base64 = 0;
 #endif
-        if (base64) {
-            if (enc)
-                outformat = FORMAT_BASE64;
-            else
-                informat = FORMAT_BASE64;
-        }
+    if (do_brotli)
+        base64 = 0;
+    if (do_zstd)
+        base64 = 0;
+
+    if (base64) {
+        if (enc)
+            outformat = FORMAT_BASE64;
+        else
+            informat = FORMAT_BASE64;
+    }
 
     strbuf = app_malloc(SIZE, "strbuf");
     buff = app_malloc(EVP_ENCODE_LENGTH(bsize), "evp buffer");
 
     if (infile == NULL) {
+        if (!streamable && printkey != 2) {  /* if just print key and exit, it's ok */
+            BIO_printf(bio_err, "Unstreamable cipher mode\n");
+            goto end;
+        }
         in = dup_bio_in(informat);
     } else {
         in = bio_open_default(infile, 'r', informat);
@@ -399,7 +436,8 @@ int enc_main(int argc, char **argv)
     rbio = in;
     wbio = out;
 
-#ifdef ZLIB
+#ifndef OPENSSL_NO_COMP
+# ifndef OPENSSL_NO_ZLIB
     if (do_zlib) {
         if ((bzl = BIO_new(BIO_f_zlib())) == NULL)
             goto end;
@@ -412,6 +450,33 @@ int enc_main(int argc, char **argv)
         else
             rbio = BIO_push(bzl, rbio);
     }
+# endif
+
+    if (do_brotli) {
+        if ((bbrot = BIO_new(BIO_f_brotli())) == NULL)
+            goto end;
+        if (debug) {
+            BIO_set_callback_ex(bbrot, BIO_debug_callback_ex);
+            BIO_set_callback_arg(bbrot, (char *)bio_err);
+        }
+        if (enc)
+            wbio = BIO_push(bbrot, wbio);
+        else
+            rbio = BIO_push(bbrot, rbio);
+    }
+
+    if (do_zstd) {
+        if ((bzstd = BIO_new(BIO_f_zstd())) == NULL)
+            goto end;
+        if (debug) {
+            BIO_set_callback_ex(bzstd, BIO_debug_callback_ex);
+            BIO_set_callback_arg(bzstd, (char *)bio_err);
+        }
+        if (enc)
+            wbio = BIO_push(bzstd, wbio);
+        else
+            rbio = BIO_push(bzstd, rbio);
+    }
 #endif
 
     if (base64) {
@@ -442,13 +507,13 @@ int enc_main(int argc, char **argv)
             if (nosalt) {
                 sptr = NULL;
             } else {
-                if (hsalt != NULL && !set_hex(hsalt, salt, sizeof(salt))) {
+                if (hsalt != NULL && !set_hex(hsalt, salt, saltlen)) {
                     BIO_printf(bio_err, "invalid hex salt value\n");
                     goto end;
                 }
                 if (enc) {  /* encryption */
                     if (hsalt == NULL) {
-                        if (RAND_bytes(salt, sizeof(salt)) <= 0) {
+                        if (RAND_bytes(salt, saltlen) <= 0) {
                             BIO_printf(bio_err, "RAND_bytes failed\n");
                             goto end;
                         }
@@ -461,7 +526,7 @@ int enc_main(int argc, char **argv)
                                           sizeof(magic) - 1) != sizeof(magic) - 1
                                 || BIO_write(wbio,
                                              (char *)salt,
-                                             sizeof(salt)) != sizeof(salt))) {
+                                             saltlen) != saltlen)) {
                             BIO_printf(bio_err, "error writing output file\n");
                             goto end;
                         }
@@ -474,7 +539,7 @@ int enc_main(int argc, char **argv)
                         }
                         if (memcmp(mbuf, magic, sizeof(mbuf)) == 0) { /* file IS salted */
                             if (BIO_read(rbio, salt,
-                                         sizeof(salt)) != sizeof(salt)) {
+                                         saltlen) != saltlen) {
                                 BIO_printf(bio_err, "error reading input file\n");
                                 goto end;
                             }
@@ -496,7 +561,8 @@ int enc_main(int argc, char **argv)
                 int iklen = EVP_CIPHER_get_key_length(cipher);
                 int ivlen = EVP_CIPHER_get_iv_length(cipher);
                 /* not needed if HASH_UPDATE() is fixed : */
-                int islen = (sptr != NULL ? sizeof(salt) : 0);
+                int islen = (sptr != NULL ? saltlen : 0);
+
                 if (!PKCS5_PBKDF2_HMAC(str, str_len, sptr, islen,
                                        iter, dgst, iklen+ivlen, tmpkeyiv)) {
                     BIO_printf(bio_err, "PKCS5_PBKDF2_HMAC failed\n");
@@ -535,7 +601,8 @@ int enc_main(int argc, char **argv)
             }
         }
         if ((hiv == NULL) && (str == NULL)
-            && EVP_CIPHER_get_iv_length(cipher) != 0) {
+            && EVP_CIPHER_get_iv_length(cipher) != 0
+            && wrap == 0) {
             /*
              * No IV was explicitly set and no IV was generated.
              * Hence the IV is undefined, making correct decryption impossible.
@@ -562,6 +629,9 @@ int enc_main(int argc, char **argv)
 
         BIO_get_cipher_ctx(benc, &ctx);
 
+        if (wrap == 1)
+            EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
+
         if (!EVP_CipherInit_ex(ctx, cipher, e, NULL, NULL, enc)) {
             BIO_printf(bio_err, "Error setting cipher %s\n",
                        EVP_CIPHER_get0_name(cipher));
@@ -572,7 +642,8 @@ int enc_main(int argc, char **argv)
         if (nopad)
             EVP_CIPHER_CTX_set_padding(ctx, 0);
 
-        if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) {
+        if (!EVP_CipherInit_ex(ctx, NULL, NULL, key,
+                               (hiv == NULL && wrap == 1 ? NULL : iv), enc)) {
             BIO_printf(bio_err, "Error setting cipher %s\n",
                        EVP_CIPHER_get0_name(cipher));
             ERR_print_errors(bio_err);
@@ -587,7 +658,7 @@ int enc_main(int argc, char **argv)
         if (printkey) {
             if (!nosalt) {
                 printf("salt=");
-                for (i = 0; i < (int)sizeof(salt); i++)
+                for (i = 0; i < (int)saltlen; i++)
                     printf("%02X", salt[i]);
                 printf("\n");
             }
@@ -618,10 +689,16 @@ int enc_main(int argc, char **argv)
         inl = BIO_read(rbio, (char *)buff, bsize);
         if (inl <= 0)
             break;
+        if (!streamable && !BIO_eof(rbio)) {    /* do not output data */
+            BIO_printf(bio_err, "Unstreamable cipher mode\n");
+            goto end;
+        }
         if (BIO_write(wbio, (char *)buff, inl) != inl) {
             BIO_printf(bio_err, "error writing output file\n");
             goto end;
         }
+        if (!streamable)
+            break;
     }
     if (!BIO_flush(wbio)) {
         if (enc)
@@ -646,9 +723,11 @@ int enc_main(int argc, char **argv)
     BIO_free(b64);
     EVP_MD_free(dgst);
     EVP_CIPHER_free(cipher);
-#ifdef ZLIB
+#ifndef OPENSSL_NO_ZLIB
     BIO_free(bzl);
 #endif
+    BIO_free(bbrot);
+    BIO_free(bzstd);
     release_engine(e);
     OPENSSL_free(pass);
     return ret;

+ 1 - 1
libs/openssl/apps/engine.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy

+ 7 - 5
libs/openssl/apps/fipsinstall.c

@@ -7,7 +7,6 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include <string.h>
 #include <openssl/evp.h>
 #include <openssl/err.h>
 #include <openssl/provider.h>
@@ -446,9 +445,9 @@ opthelp:
         case OPT_MACOPT:
             if (!sk_OPENSSL_STRING_push(opts, opt_arg()))
                 goto opthelp;
-            if (strncmp(opt_arg(), "hexkey:", 7) == 0)
+            if (HAS_PREFIX(opt_arg(), "hexkey:"))
                 gotkey = 1;
-            else if (strncmp(opt_arg(), "digest:", 7) == 0)
+            else if (HAS_PREFIX(opt_arg(), "digest:"))
                 gotdigest = 1;
             break;
         case OPT_VERIFY:
@@ -466,9 +465,12 @@ opthelp:
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0 || (verify && in_fname == NULL))
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
+    if (verify && in_fname == NULL) {
+        BIO_printf(bio_err, "Missing -in option for -verify\n");
+        goto opthelp;
+    }
 
     if (parent_config != NULL) {
         /* Test that a parent config can load the module */

+ 10 - 8
libs/openssl/apps/gendsa.c

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

+ 82 - 39
libs/openssl/apps/genpkey.c

@@ -15,17 +15,15 @@
 #include <openssl/err.h>
 #include <openssl/evp.h>
 
-static int quiet;
+static int verbose = 1;
 
 static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e,
                             OSSL_LIB_CTX *libctx, const char *propq);
-static int genpkey_cb(EVP_PKEY_CTX *ctx);
-
 typedef enum OPTION_choice {
     OPT_COMMON,
     OPT_ENGINE, OPT_OUTFORM, OPT_OUT, OPT_PASS, OPT_PARAMFILE,
     OPT_ALGORITHM, OPT_PKEYOPT, OPT_GENPARAM, OPT_TEXT, OPT_CIPHER,
-    OPT_QUIET, OPT_CONFIG,
+    OPT_VERBOSE, OPT_QUIET, OPT_CONFIG, OPT_OUTPUBKEY,
     OPT_PROV_ENUM
 } OPTION_CHOICE;
 
@@ -37,17 +35,19 @@ const OPTIONS genpkey_options[] = {
 #endif
     {"paramfile", OPT_PARAMFILE, '<', "Parameters file"},
     {"algorithm", OPT_ALGORITHM, 's', "The public key algorithm"},
+    {"verbose", OPT_VERBOSE, '-', "Output status while generating keys"},
     {"quiet", OPT_QUIET, '-', "Do not output status while generating keys"},
     {"pkeyopt", OPT_PKEYOPT, 's',
      "Set the public key algorithm option as opt:value"},
      OPT_CONFIG_OPTION,
 
     OPT_SECTION("Output"),
-    {"out", OPT_OUT, '>', "Output file"},
+    {"out", OPT_OUT, '>', "Output (private key) file"},
+    {"outpubkey", OPT_OUTPUBKEY, '>', "Output public key file"},
     {"outform", OPT_OUTFORM, 'F', "output format (DER or PEM)"},
     {"pass", OPT_PASS, 's', "Output file pass phrase source"},
     {"genparam", OPT_GENPARAM, '-', "Generate parameters, not key"},
-    {"text", OPT_TEXT, '-', "Print the in text"},
+    {"text", OPT_TEXT, '-', "Print the private key in text"},
     {"", OPT_CIPHER, '-', "Cipher to use to encrypt the key"},
 
     OPT_PROV_OPTIONS,
@@ -58,14 +58,59 @@ const OPTIONS genpkey_options[] = {
     {NULL}
 };
 
+static const char *param_datatype_2name(unsigned int type, int *ishex)
+{
+    *ishex = 0;
+
+    switch (type) {
+    case OSSL_PARAM_INTEGER: return "int";
+    case OSSL_PARAM_UNSIGNED_INTEGER: return "uint";
+    case OSSL_PARAM_REAL: return "float";
+    case OSSL_PARAM_OCTET_STRING: *ishex = 1; return "string";
+    case OSSL_PARAM_UTF8_STRING: return "string";
+    default:
+        return NULL;
+    }
+}
+
+static void show_gen_pkeyopt(const char *algname, OSSL_LIB_CTX *libctx, const char *propq)
+{
+    EVP_PKEY_CTX *ctx = NULL;
+    const OSSL_PARAM *params;
+    int i, ishex = 0;
+
+    if (algname == NULL)
+        return;
+    ctx = EVP_PKEY_CTX_new_from_name(libctx, algname, propq);
+    if (ctx == NULL)
+        return;
+
+    if (EVP_PKEY_keygen_init(ctx) <= 0)
+        goto cleanup;
+    params = EVP_PKEY_CTX_settable_params(ctx);
+    if (params == NULL)
+        goto cleanup;
+
+    BIO_printf(bio_err, "\nThe possible -pkeyopt arguments are:\n");
+    for (i = 0; params[i].key != NULL; ++i) {
+        const char *name = param_datatype_2name(params[i].data_type, &ishex);
+
+        if (name != NULL)
+            BIO_printf(bio_err, "    %s%s:%s\n", ishex ? "hex" : "", params[i].key, name);
+    }
+cleanup:
+    EVP_PKEY_CTX_free(ctx);
+}
+
 int genpkey_main(int argc, char **argv)
 {
     CONF *conf = NULL;
-    BIO *in = NULL, *out = NULL;
+    BIO *in = NULL, *out = NULL, *outpubkey = NULL;
     ENGINE *e = NULL;
     EVP_PKEY *pkey = NULL;
     EVP_PKEY_CTX *ctx = NULL;
     char *outfile = NULL, *passarg = NULL, *pass = NULL, *prog, *p;
+    char *outpubkeyfile = NULL;
     const char *ciphername = NULL, *paramfile = NULL, *algname = NULL;
     EVP_CIPHER *cipher = NULL;
     OPTION_CHOICE o;
@@ -74,6 +119,7 @@ int genpkey_main(int argc, char **argv)
     OSSL_LIB_CTX *libctx = app_get0_libctx();
     STACK_OF(OPENSSL_STRING) *keyopt = NULL;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, genpkey_options);
     keyopt = sk_OPENSSL_STRING_new_null();
     if (keyopt == NULL)
@@ -88,6 +134,7 @@ int genpkey_main(int argc, char **argv)
         case OPT_HELP:
             ret = 0;
             opt_help(genpkey_options);
+            show_gen_pkeyopt(algname, libctx, app_get0_propq());
             goto end;
         case OPT_OUTFORM:
             if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
@@ -96,6 +143,9 @@ int genpkey_main(int argc, char **argv)
         case OPT_OUT:
             outfile = opt_arg();
             break;
+        case OPT_OUTPUBKEY:
+            outpubkeyfile = opt_arg();
+            break;
         case OPT_PASS:
             passarg = opt_arg();
             break;
@@ -115,7 +165,10 @@ int genpkey_main(int argc, char **argv)
                 goto end;
             break;
         case OPT_QUIET:
-            quiet = 1;
+            verbose = 0;
+            break;
+        case OPT_VERBOSE:
+            verbose = 1;
             break;
         case OPT_GENPARAM:
             do_param = 1;
@@ -139,8 +192,7 @@ int genpkey_main(int argc, char **argv)
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     /* Fetch cipher, etc. */
@@ -163,9 +215,12 @@ int genpkey_main(int argc, char **argv)
             goto end;
         }
     }
-    if (ciphername != NULL)
-        if (!opt_cipher(ciphername, &cipher) || do_param == 1)
-            goto opthelp;
+    if (!opt_cipher(ciphername, &cipher))
+        goto opthelp;
+    if (ciphername != NULL && do_param == 1) {
+        BIO_printf(bio_err, "Cannot use cipher with -genparam option\n");
+        goto opthelp;
+    }
 
     private = do_param ? 0 : 1;
 
@@ -178,7 +233,14 @@ int genpkey_main(int argc, char **argv)
     if (out == NULL)
         goto end;
 
-    EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
+    if (outpubkeyfile != NULL) {
+        outpubkey = bio_open_owner(outpubkeyfile, outformat, private);
+        if (outpubkey == NULL)
+            goto end;
+    }
+
+    if (verbose)
+        EVP_PKEY_CTX_set_cb(ctx, progress_cb);
     EVP_PKEY_CTX_set_app_data(ctx, bio_err);
 
     pkey = do_param ? app_paramgen(ctx, algname)
@@ -191,9 +253,13 @@ int genpkey_main(int argc, char **argv)
     } else if (outformat == FORMAT_PEM) {
         assert(private);
         rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, pass);
+        if (rv > 0 && outpubkey != NULL)
+           rv = PEM_write_bio_PUBKEY(outpubkey, pkey);
     } else if (outformat == FORMAT_ASN1) {
         assert(private);
         rv = i2d_PrivateKey_bio(out, pkey);
+        if (rv > 0 && outpubkey != NULL)
+           rv = i2d_PUBKEY_bio(outpubkey, pkey);
     } else {
         BIO_printf(bio_err, "Bad format specified for key\n");
         goto end;
@@ -202,7 +268,7 @@ int genpkey_main(int argc, char **argv)
     ret = 0;
 
     if (rv <= 0) {
-        BIO_puts(bio_err, "Error writing key\n");
+        BIO_puts(bio_err, "Error writing key(s)\n");
         ret = 1;
     }
 
@@ -226,6 +292,7 @@ int genpkey_main(int argc, char **argv)
     EVP_PKEY_CTX_free(ctx);
     EVP_CIPHER_free(cipher);
     BIO_free_all(out);
+    BIO_free_all(outpubkey);
     BIO_free(in);
     release_engine(e);
     OPENSSL_free(pass);
@@ -318,27 +385,3 @@ int init_gen_str(EVP_PKEY_CTX **pctx,
 
 }
 
-static int genpkey_cb(EVP_PKEY_CTX *ctx)
-{
-    char c = '*';
-    BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
-
-    if (quiet)
-        return 1;
-
-    switch (EVP_PKEY_CTX_get_keygen_info(ctx, 0)) {
-    case 0:
-        c = '.';
-        break;
-    case 1:
-        c = '+';
-        break;
-    case 3:
-        c = '\n';
-        break;
-    }
-
-    BIO_write(b, &c, 1);
-    (void)BIO_flush(b);
-    return 1;
-}

+ 11 - 31
libs/openssl/apps/genrsa.c

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

+ 30 - 24
libs/openssl/apps/include/apps.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -11,9 +11,9 @@
 # define OSSL_APPS_H
 
 # include "internal/e_os.h" /* struct timeval for DTLS */
+# include "internal/common.h" /* for HAS_PREFIX */
 # include "internal/nelem.h"
 # include "internal/sockets.h" /* for openssl_fdset() */
-# include "internal/cryptlib.h"  /* ossl_assert() */
 # include <assert.h>
 
 # include <stdarg.h>
@@ -65,9 +65,12 @@ BIO *dup_bio_err(int format);
 BIO *bio_open_owner(const char *filename, int format, int private);
 BIO *bio_open_default(const char *filename, char mode, int format);
 BIO *bio_open_default_quiet(const char *filename, char mode, int format);
+char *app_conf_try_string(const CONF *cnf, const char *group, const char *name);
+int app_conf_try_number(const CONF *conf, const char *group, const char *name,
+                        long *result);
 CONF *app_load_config_bio(BIO *in, const char *filename);
-#define app_load_config(filename) app_load_config_internal(filename, 0)
-#define app_load_config_quiet(filename) app_load_config_internal(filename, 1)
+# define app_load_config(filename) app_load_config_internal(filename, 0)
+# define app_load_config_quiet(filename) app_load_config_internal(filename, 1)
 CONF *app_load_config_internal(const char *filename, int quiet);
 CONF *app_load_config_verbose(const char *filename, int verbose);
 int app_load_modules(const CONF *config);
@@ -94,10 +97,13 @@ typedef struct args_st {
 /* We need both wrap and the "real" function because libcrypto uses both. */
 int wrap_password_callback(char *buf, int bufsiz, int verify, void *cb_data);
 
+/* progress callback for dsaparam, dhparam, req, genpkey, etc. */
+int progress_cb(EVP_PKEY_CTX *ctx);
+
 int chopup_args(ARGS *arg, char *buf);
 void dump_cert_text(BIO *out, X509 *x);
 void print_name(BIO *out, const char *title, const X509_NAME *nm);
-void print_bignum_var(BIO *, const BIGNUM *, const char*,
+void print_bignum_var(BIO *, const BIGNUM *, const char *,
                       int, unsigned char *);
 void print_array(BIO *, const char *, int, const unsigned char *);
 int set_nameopt(const char *arg);
@@ -111,15 +117,18 @@ char *get_passwd(const char *pass, const char *desc);
 int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2);
 int add_oid_section(CONF *conf);
 X509_REQ *load_csr(const char *file, int format, const char *desc);
+X509_REQ *load_csr_autofmt(const char *infile, int format,
+                           STACK_OF(OPENSSL_STRING) *vfyopts, const char *desc);
 X509 *load_cert_pass(const char *uri, int format, int maybe_stdin,
                      const char *pass, const char *desc);
-#define load_cert(uri, format, desc) load_cert_pass(uri, format, 1, NULL, desc)
+# define load_cert(uri, format, desc) load_cert_pass(uri, format, 1, NULL, desc)
 X509_CRL *load_crl(const char *uri, int format, int maybe_stdin,
                    const char *desc);
 void cleanse(char *str);
 void clear_free(char *str);
 EVP_PKEY *load_key(const char *uri, int format, int maybe_stdin,
                    const char *pass, ENGINE *e, const char *desc);
+/* first try reading public key, on failure resort to loading private key */
 EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin,
                       const char *pass, ENGINE *e, const char *desc);
 EVP_PKEY *load_keyparams(const char *uri, int format, int maybe_stdin,
@@ -141,15 +150,11 @@ int load_certs(const char *uri, int maybe_stdin, STACK_OF(X509) **certs,
 int load_crls(const char *uri, STACK_OF(X509_CRL) **crls,
               const char *pass, const char *desc);
 int load_key_certs_crls(const char *uri, int format, int maybe_stdin,
-                        const char *pass, const char *desc,
+                        const char *pass, const char *desc, int quiet,
                         EVP_PKEY **ppkey, EVP_PKEY **ppubkey,
                         EVP_PKEY **pparams,
                         X509 **pcert, STACK_OF(X509) **pcerts,
                         X509_CRL **pcrl, STACK_OF(X509_CRL) **pcrls);
-int load_key_cert_crl(const char *uri, int format, int maybe_stdin,
-                      const char *pass, const char *desc,
-                      EVP_PKEY **ppkey, EVP_PKEY **ppubkey,
-                      X509 **pcert, X509_CRL **pcrl);
 X509_STORE *setup_verify(const char *CAfile, int noCAfile,
                          const char *CApath, int noCApath,
                          const char *CAstore, int noCAstore);
@@ -195,10 +200,9 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
 # define DB_type         0
 # define DB_exp_date     1
 # define DB_rev_date     2
-# define DB_serial       3      /* index - unique */
+# define DB_serial       3 /* index - unique */
 # define DB_file         4
-# define DB_name         5      /* index - unique when active and not
-                                 * disabled */
+# define DB_name         5 /* index - unique when active and not disabled */
 # define DB_NUMBER       6
 
 # define DB_TYPE_REV     'R'    /* Revoked  */
@@ -218,6 +222,8 @@ typedef struct ca_db_st {
 # endif
 } CA_DB;
 
+extern int do_updatedb(CA_DB *db, time_t *now);
+
 void app_bail_out(char *fmt, ...);
 void *app_malloc(size_t sz, const char *what);
 
@@ -237,8 +243,8 @@ int rotate_index(const char *dbfile, const char *new_suffix,
                  const char *old_suffix);
 void free_index(CA_DB *db);
 # define index_name_cmp_noconst(a, b) \
-        index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \
-        (const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b))
+    index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \
+                   (const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b))
 int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b);
 int parse_yesno(const char *str, int def);
 
@@ -252,7 +258,8 @@ int x509_req_ctrl_string(X509_REQ *x, const char *value);
 int init_gen_str(EVP_PKEY_CTX **pctx,
                  const char *algname, ENGINE *e, int do_param,
                  OSSL_LIB_CTX *libctx, const char *propq);
-int do_X509_sign(X509 *x, EVP_PKEY *pkey, const char *md,
+int cert_matches_key(const X509 *cert, const EVP_PKEY *pkey);
+int do_X509_sign(X509 *x, int force_v1, EVP_PKEY *pkey, const char *md,
                  STACK_OF(OPENSSL_STRING) *sigopts, X509V3_CTX *ext_ctx);
 int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts);
 int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const char *md,
@@ -264,12 +271,11 @@ int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const char *md,
 
 extern char *psk_key;
 
-
 unsigned char *next_protos_parse(size_t *outlen, const char *in);
 
-void print_cert_checks(BIO *bio, X509 *x,
-                       const char *checkhost,
-                       const char *checkemail, const char *checkip);
+int check_cert_attributes(BIO *bio, X509 *x,
+                          const char *checkhost, const char *checkemail,
+                          const char *checkip, int print);
 
 void store_setup_crl_download(X509_STORE *st);
 
@@ -303,16 +309,16 @@ ASN1_VALUE *app_http_post_asn1(const char *host, const char *port,
 # define EXT_COPY_ADD    1
 # define EXT_COPY_ALL    2
 
-# define NETSCAPE_CERT_HDR       "certificate"
+# define NETSCAPE_CERT_HDR "certificate"
 
-# define APP_PASS_LEN    1024
+# define APP_PASS_LEN 1024
 
 /*
  * IETF RFC 5280 says serial number must be <= 20 bytes. Use 159 bits
  * so that the first bit will never be one, so that the DER encoding
  * rules won't force a leading octet.
  */
-# define SERIAL_RAND_BITS        159
+# define SERIAL_RAND_BITS 159
 
 int app_isdir(const char *);
 int app_access(const char *, int flag);

+ 4 - 0
libs/openssl/apps/include/cmp_mock_srv.h

@@ -20,11 +20,15 @@ OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx,
                                         const char *propq);
 void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx);
 
+int ossl_cmp_mock_srv_set1_refCert(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
 int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
 int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
                                     STACK_OF(X509) *chain);
 int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx,
                                      STACK_OF(X509) *caPubs);
+int ossl_cmp_mock_srv_set1_newWithNew(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
+int ossl_cmp_mock_srv_set1_newWithOld(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
+int ossl_cmp_mock_srv_set1_oldWithNew(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert);
 int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status,
                                      int fail_info, const char *text);
 int ossl_cmp_mock_srv_set_sendError(OSSL_CMP_SRV_CTX *srv_ctx, int bodytype);

+ 1 - 1
libs/openssl/apps/include/engine_loader.h

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

+ 1 - 1
libs/openssl/apps/include/function.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy

+ 11 - 27
libs/openssl/apps/include/http_server.h

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

+ 50 - 0
libs/openssl/apps/include/log.h

@@ -0,0 +1,50 @@
+/*
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef OSSL_APPS_LOG_H
+# define OSSL_APPS_LOG_H
+
+# include <openssl/bio.h>
+# if !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_WINDOWS) \
+    && !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_POSIX_IO)
+#  include <syslog.h>
+# else
+#  define LOG_EMERG   0
+#  define LOG_ALERT   1
+#  define LOG_CRIT    2
+#  define LOG_ERR     3
+#  define LOG_WARNING 4
+#  define LOG_NOTICE  5
+#  define LOG_INFO    6
+#  define LOG_DEBUG   7
+# endif
+
+# undef LOG_TRACE
+# define LOG_TRACE (LOG_DEBUG + 1)
+
+int log_set_verbosity(const char *prog, int level);
+int log_get_verbosity(void);
+
+/*-
+ * Output a message using the trace API with the given category
+ * if the category is >= 0 and tracing is enabled.
+ * Log the message to syslog if multi-threaded HTTP_DAEMON, else to bio_err
+ * if the verbosity is sufficient for the given level of severity.
+ * Yet cannot do both types of output in strict ANSI mode.
+ * category: trace category as defined in trace.h, or -1
+ * prog: the name of the current app, or NULL
+ * level: the severity of the message, e.g., LOG_ERR
+ * fmt: message format, which should not include a trailing newline
+ * ...: potential extra parameters like with printf()
+ * returns nothing
+ */
+void trace_log_message(int category,
+                       const char *prog, int level, const char *fmt, ...);
+
+#endif /* OSSL_APPS_LOG_H */

+ 62 - 25
libs/openssl/apps/include/opt.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -163,7 +163,11 @@
         OPT_S_CURVES, OPT_S_NAMEDCURVE, OPT_S_CIPHER, OPT_S_CIPHERSUITES, \
         OPT_S_RECORD_PADDING, OPT_S_DEBUGBROKE, OPT_S_COMP, \
         OPT_S_MINPROTO, OPT_S_MAXPROTO, \
-        OPT_S_NO_RENEGOTIATION, OPT_S_NO_MIDDLEBOX, OPT_S_NO_ETM, OPT_S__LAST
+        OPT_S_NO_RENEGOTIATION, OPT_S_NO_MIDDLEBOX, OPT_S_NO_ETM, \
+        OPT_S_NO_EMS, \
+        OPT_S_NO_TX_CERT_COMP, \
+        OPT_S_NO_RX_CERT_COMP, \
+        OPT_S__LAST
 
 # define OPT_S_OPTIONS \
         OPT_SECTION("TLS/SSL"), \
@@ -175,6 +179,8 @@
         {"bugs", OPT_S_BUGS, '-', "Turn on SSL bug compatibility"}, \
         {"no_comp", OPT_S_NO_COMP, '-', "Disable SSL/TLS compression (default)" }, \
         {"comp", OPT_S_COMP, '-', "Use SSL/TLS-level compression" }, \
+        {"no_tx_cert_comp", OPT_S_NO_TX_CERT_COMP, '-', "Disable sending TLSv1.3 compressed certificates" }, \
+        {"no_rx_cert_comp", OPT_S_NO_RX_CERT_COMP, '-', "Disable receiving TLSv1.3 compressed certificates" }, \
         {"no_ticket", OPT_S_NOTICKET, '-', \
             "Disable use of TLS session tickets"}, \
         {"serverpref", OPT_S_SERVERPREF, '-', "Use server's cipher preferences"}, \
@@ -218,7 +224,9 @@
         {"no_middlebox", OPT_S_NO_MIDDLEBOX, '-', \
             "Disable TLSv1.3 middlebox compat mode" }, \
         {"no_etm", OPT_S_NO_ETM, '-', \
-            "Disable Encrypt-then-Mac extension"}
+            "Disable Encrypt-then-Mac extension"}, \
+        {"no_ems", OPT_S_NO_EMS, '-', \
+            "Disable Extended master secret extension"}
 
 # define OPT_S_CASES \
         OPT_S__FIRST: case OPT_S__LAST: break; \
@@ -230,6 +238,8 @@
         case OPT_S_BUGS: \
         case OPT_S_NO_COMP: \
         case OPT_S_COMP: \
+        case OPT_S_NO_TX_CERT_COMP: \
+        case OPT_S_NO_RX_CERT_COMP: \
         case OPT_S_NOTICKET: \
         case OPT_S_SERVERPREF: \
         case OPT_S_LEGACYRENEG: \
@@ -253,7 +263,8 @@
         case OPT_S_MAXPROTO: \
         case OPT_S_DEBUGBROKE: \
         case OPT_S_NO_MIDDLEBOX: \
-        case OPT_S_NO_ETM
+        case OPT_S_NO_ETM: \
+        case OPT_S_NO_EMS
 
 #define IS_NO_PROT_FLAG(o) \
  (o == OPT_S_NOSSL3 || o == OPT_S_NOTLS1 || o == OPT_S_NOTLS1_1 \
@@ -308,11 +319,28 @@ extern const char OPT_PARAM_STR[];
 typedef struct options_st {
     const char *name;
     int retval;
-    /*
-     * value type: - no value (also the value zero), n number, p positive
-     * number, u unsigned, l long, s string, < input file, > output file,
-     * f any format, F der/pem format, E der/pem/engine format identifier.
-     * l, n and u include zero; p does not.
+    /*-
+     * value type:
+     *
+     *   '-' no value (also the value zero)
+     *   'n' number (type 'int')
+     *   'p' positive number (type 'int')
+     *   'u' unsigned number (type 'unsigned long')
+     *   'l' number (type 'unsigned long')
+     *   'M' number (type 'intmax_t')
+     *   'U' unsigned number (type 'uintmax_t')
+     *   's' string
+     *   '<' input file
+     *   '>' output file
+     *   '/' directory
+     *   'f' any format                    [OPT_FMT_ANY]
+     *   'F' der/pem format                [OPT_FMT_PEMDER]
+     *   'A' any ASN1, der/pem/b64 format  [OPT_FMT_ASN1]
+     *   'E' der/pem/engine format         [OPT_FMT_PDE]
+     *   'c' pem/der/smime format          [OPT_FMT_PDS]
+     *
+     * The 'l', 'n' and 'u' value types include the values zero,
+     * the 'p' value type does not.
      */
     int valtype;
     const char *helpstr;
@@ -332,46 +360,54 @@ typedef struct string_int_pair_st {
 } OPT_PAIR, STRINT_PAIR;
 
 /* Flags to pass into opt_format; see FORMAT_xxx, below. */
-# define OPT_FMT_PEMDER          (1L <<  1)
-# define OPT_FMT_PKCS12          (1L <<  2)
-# define OPT_FMT_SMIME           (1L <<  3)
-# define OPT_FMT_ENGINE          (1L <<  4)
-# define OPT_FMT_MSBLOB          (1L <<  5)
-/* (1L <<  6) was OPT_FMT_NETSCAPE, but wasn't used */
-# define OPT_FMT_NSS             (1L <<  7)
-# define OPT_FMT_TEXT            (1L <<  8)
-# define OPT_FMT_HTTP            (1L <<  9)
-# define OPT_FMT_PVK             (1L << 10)
+# define OPT_FMT_PEM             (1L <<  1)
+# define OPT_FMT_DER             (1L <<  2)
+# define OPT_FMT_B64             (1L <<  3)
+# define OPT_FMT_PKCS12          (1L <<  4)
+# define OPT_FMT_SMIME           (1L <<  5)
+# define OPT_FMT_ENGINE          (1L <<  6)
+# define OPT_FMT_MSBLOB          (1L <<  7)
+# define OPT_FMT_NSS             (1L <<  8)
+# define OPT_FMT_TEXT            (1L <<  9)
+# define OPT_FMT_HTTP            (1L << 10)
+# define OPT_FMT_PVK             (1L << 11)
+
+# define OPT_FMT_PEMDER  (OPT_FMT_PEM | OPT_FMT_DER)
+# define OPT_FMT_ASN1    (OPT_FMT_PEM | OPT_FMT_DER | OPT_FMT_B64)
 # define OPT_FMT_PDE     (OPT_FMT_PEMDER | OPT_FMT_ENGINE)
 # define OPT_FMT_PDS     (OPT_FMT_PEMDER | OPT_FMT_SMIME)
 # define OPT_FMT_ANY     ( \
-        OPT_FMT_PEMDER | OPT_FMT_PKCS12 | OPT_FMT_SMIME | \
-        OPT_FMT_ENGINE | OPT_FMT_MSBLOB | OPT_FMT_NSS   | \
-        OPT_FMT_TEXT   | OPT_FMT_HTTP   | OPT_FMT_PVK)
+        OPT_FMT_PEM | OPT_FMT_DER | OPT_FMT_B64 | \
+        OPT_FMT_PKCS12 | OPT_FMT_SMIME |                     \
+        OPT_FMT_ENGINE | OPT_FMT_MSBLOB | OPT_FMT_NSS | \
+        OPT_FMT_TEXT | OPT_FMT_HTTP | OPT_FMT_PVK)
 
 /* Divide options into sections when displaying usage */
 #define OPT_SECTION(sec) { OPT_SECTION_STR, 1, '-', sec " options:\n" }
 #define OPT_PARAMETERS() { OPT_PARAM_STR, 1, '-', "Parameters:\n" }
 
 const char *opt_path_end(const char *filename);
-char *opt_init(int ac, char **av, const OPTIONS * o);
+char *opt_init(int ac, char **av, const OPTIONS *o);
 char *opt_progname(const char *argv0);
 char *opt_appname(const char *argv0);
 char *opt_getprog(void);
-void opt_help(const OPTIONS * list);
+void opt_help(const OPTIONS *list);
 
 void opt_begin(void);
 int opt_next(void);
 char *opt_flag(void);
 char *opt_arg(void);
 char *opt_unknown(void);
+void reset_unknown(void);
 int opt_cipher(const char *name, EVP_CIPHER **cipherp);
 int opt_cipher_any(const char *name, EVP_CIPHER **cipherp);
 int opt_cipher_silent(const char *name, EVP_CIPHER **cipherp);
+int opt_check_md(const char *name);
 int opt_md(const char *name, EVP_MD **mdp);
 int opt_md_silent(const char *name, EVP_MD **mdp);
 
 int opt_int(const char *arg, int *result);
+void opt_set_unknown_name(const char *name);
 int opt_int_arg(void);
 int opt_long(const char *arg, long *result);
 int opt_ulong(const char *arg, unsigned long *result);
@@ -383,7 +419,7 @@ int opt_format(const char *s, unsigned long flags, int *result);
 void print_format_error(int format, unsigned long flags);
 int opt_printf_stderr(const char *fmt, ...);
 int opt_string(const char *name, const char **options);
-int opt_pair(const char *arg, const OPT_PAIR * pairs, int *result);
+int opt_pair(const char *arg, const OPT_PAIR *pairs, int *result);
 
 int opt_verify(int i, X509_VERIFY_PARAM *vpm);
 int opt_rand(int i);
@@ -392,6 +428,7 @@ int opt_provider_option_given(void);
 
 char **opt_rest(void);
 int opt_num_rest(void);
+int opt_check_rest_arg(const char *expected);
 
 /* Returns non-zero if legacy paths are still available */
 int opt_legacy_okay(void);

+ 6 - 4
libs/openssl/apps/include/s_apps.h

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -19,11 +19,12 @@
     (SSL_is_dtls(s) || (SSL_version(s) < TLS1_3_VERSION))
 
 typedef int (*do_server_cb)(int s, int stype, int prot, unsigned char *context);
+void get_sock_info_address(int asock, char **hostname, char **service);
 int report_server_accept(BIO *out, int asock, int with_address, int with_pid);
 int do_server(int *accept_sock, const char *host, const char *port,
               int family, int type, int protocol, do_server_cb cb,
-              unsigned char *context, int naccept, BIO *bio_s_out);
-
+              unsigned char *context, int naccept, BIO *bio_s_out,
+              int tfo);
 int verify_callback(int ok, X509_STORE_CTX *ctx);
 
 int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
@@ -35,7 +36,8 @@ int ssl_print_groups(BIO *out, SSL *s, int noshared);
 int ssl_print_tmp_key(BIO *out, SSL *s);
 int init_client(int *sock, const char *host, const char *port,
                 const char *bindhost, const char *bindport,
-                int family, int type, int protocol);
+                int family, int type, int protocol, int tfo, int doconn,
+                BIO_ADDR **ba_ret);
 int should_retry(int i);
 void do_ssl_shutdown(SSL *ssl);
 

+ 1 - 1
libs/openssl/apps/info.c

@@ -86,7 +86,7 @@ opthelp:
             break;
         }
     }
-    if (opt_num_rest() != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
     if (dirty > 1) {
         BIO_printf(bio_err, "%s: Only one item allowed\n", prog);

+ 1 - 1
libs/openssl/apps/lib/app_libctx.c

@@ -36,7 +36,7 @@ OSSL_LIB_CTX *app_create_libctx(void)
      */
     if (app_libctx == NULL) {
         if (!app_provider_load(NULL, "null")) {
-            opt_printf_stderr( "Failed to create null provider\n");
+            opt_printf_stderr("Failed to create null provider\n");
             return NULL;
         }
         app_libctx = OSSL_LIB_CTX_new();

+ 4 - 6
libs/openssl/apps/lib/app_rand.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -18,12 +18,10 @@ static STACK_OF(OPENSSL_STRING) *randfiles;
 
 void app_RAND_load_conf(CONF *c, const char *section)
 {
-    const char *randfile = NCONF_get_string(c, section, "RANDFILE");
+    const char *randfile = app_conf_try_string(c, section, "RANDFILE");
 
-    if (randfile == NULL) {
-        ERR_clear_error();
+    if (randfile == NULL)
         return;
-    }
     if (RAND_load_file(randfile, -1) < 0) {
         BIO_printf(bio_err, "Can't load %s into RNG\n", randfile);
         ERR_print_errors(bio_err);
@@ -43,7 +41,7 @@ static int loadfiles(char *name)
     char *p;
     int last, ret = 1;
 
-    for ( ; ; ) {
+    for (;;) {
         last = 0;
         for (p = name; *p != '\0' && *p != LIST_SEPARATOR_CHAR; p++)
             continue;

文件差异内容过多而无法显示
+ 277 - 213
libs/openssl/apps/lib/apps.c


+ 25 - 0
libs/openssl/apps/lib/apps_opt_printf.c

@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "opt.h"
+#include <openssl/ui.h>
+#include "apps_ui.h"
+
+/* This function is defined here due to visibility of bio_err */
+int opt_printf_stderr(const char *fmt, ...)
+{
+    va_list ap;
+    int ret;
+
+    va_start(ap, fmt);
+    ret = BIO_vprintf(bio_err, fmt, ap);
+    va_end(ap);
+    return ret;
+}
+

+ 2 - 2
libs/openssl/apps/lib/build.info

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

+ 101 - 50
libs/openssl/apps/lib/cmp_mock_srv.c

@@ -18,9 +18,13 @@
 /* the context for the CMP mock server */
 typedef struct
 {
+    X509 *refCert;             /* cert to expect for oldCertID in kur/rr msg */
     X509 *certOut;             /* certificate to be returned in cp/ip/kup msg */
     STACK_OF(X509) *chainOut;  /* chain of certOut to add to extraCerts field */
-    STACK_OF(X509) *caPubsOut; /* certs to return in caPubs field of ip msg */
+    STACK_OF(X509) *caPubsOut; /* used in caPubs of ip and in caCerts of genp */
+    X509 *newWithNew;          /* to return in newWithNew of rootKeyUpdate */
+    X509 *newWithOld;          /* to return in newWithOld of rootKeyUpdate */
+    X509 *oldWithNew;          /* to return in oldWithNew of rootKeyUpdate */
     OSSL_CMP_PKISI *statusOut; /* status for ip/cp/kup/rp msg unless polling */
     int sendError;             /* send error response on given request type */
     OSSL_CMP_MSG *certReq;     /* ir/cr/p10cr/kur remembered while polling */
@@ -29,16 +33,16 @@ typedef struct
     int checkAfterTime;        /* time the client should wait between polling */
 } mock_srv_ctx;
 
-
 static void mock_srv_ctx_free(mock_srv_ctx *ctx)
 {
     if (ctx == NULL)
         return;
 
     OSSL_CMP_PKISI_free(ctx->statusOut);
+    X509_free(ctx->refCert);
     X509_free(ctx->certOut);
-    sk_X509_pop_free(ctx->chainOut, X509_free);
-    sk_X509_pop_free(ctx->caPubsOut, X509_free);
+    OSSL_STACK_OF_X509_free(ctx->chainOut);
+    OSSL_STACK_OF_X509_free(ctx->caPubsOut);
     OSSL_CMP_MSG_free(ctx->certReq);
     OPENSSL_free(ctx);
 }
@@ -62,21 +66,26 @@ static mock_srv_ctx *mock_srv_ctx_new(void)
     return NULL;
 }
 
-int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert)
-{
-    mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
-
-    if (ctx == NULL) {
-        ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
-        return 0;
+#define DEFINE_OSSL_SET1_CERT(FIELD) \
+    int ossl_cmp_mock_srv_set1_##FIELD(OSSL_CMP_SRV_CTX *srv_ctx, \
+                                       X509 *cert) \
+    { \
+        mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx); \
+ \
+        if (ctx == NULL) { \
+            ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT); \
+            return 0; \
+        } \
+        if (cert == NULL || X509_up_ref(cert)) { \
+            X509_free(ctx->FIELD); \
+            ctx->FIELD = cert; \
+            return 1; \
+        } \
+        return 0; \
     }
-    if (cert == NULL || X509_up_ref(cert)) {
-        X509_free(ctx->certOut);
-        ctx->certOut = cert;
-        return 1;
-    }
-    return 0;
-}
+
+DEFINE_OSSL_SET1_CERT(refCert)
+DEFINE_OSSL_SET1_CERT(certOut)
 
 int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
                                     STACK_OF(X509) *chain)
@@ -90,7 +99,7 @@ int ossl_cmp_mock_srv_set1_chainOut(OSSL_CMP_SRV_CTX *srv_ctx,
     }
     if (chain != NULL && (chain_copy = X509_chain_up_ref(chain)) == NULL)
         return 0;
-    sk_X509_pop_free(ctx->chainOut, X509_free);
+    OSSL_STACK_OF_X509_free(ctx->chainOut);
     ctx->chainOut = chain_copy;
     return 1;
 }
@@ -107,11 +116,15 @@ int ossl_cmp_mock_srv_set1_caPubsOut(OSSL_CMP_SRV_CTX *srv_ctx,
     }
     if (caPubs != NULL && (caPubs_copy = X509_chain_up_ref(caPubs)) == NULL)
         return 0;
-    sk_X509_pop_free(ctx->caPubsOut, X509_free);
+    OSSL_STACK_OF_X509_free(ctx->caPubsOut);
     ctx->caPubsOut = caPubs_copy;
     return 1;
 }
 
+DEFINE_OSSL_SET1_CERT(newWithNew)
+DEFINE_OSSL_SET1_CERT(newWithOld)
+DEFINE_OSSL_SET1_CERT(oldWithNew)
+
 int ossl_cmp_mock_srv_set_statusInfo(OSSL_CMP_SRV_CTX *srv_ctx, int status,
                                      int fail_info, const char *text)
 {
@@ -170,6 +183,21 @@ int ossl_cmp_mock_srv_set_checkAfterTime(OSSL_CMP_SRV_CTX *srv_ctx, int sec)
     return 1;
 }
 
+/* check for matching reference cert components, as far as given */
+static int refcert_cmp(const X509 *refcert,
+                       const X509_NAME *issuer, const ASN1_INTEGER *serial)
+{
+    const X509_NAME *ref_issuer;
+    const ASN1_INTEGER *ref_serial;
+
+    if (refcert == NULL)
+        return 1;
+    ref_issuer = X509_get_issuer_name(refcert);
+    ref_serial = X509_get0_serialNumber(refcert);
+    return (ref_issuer == NULL || X509_NAME_cmp(issuer, ref_issuer) == 0)
+        && (ref_serial == NULL || ASN1_INTEGER_cmp(serial, ref_serial) == 0);
+}
+
 static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
                                             const OSSL_CMP_MSG *cert_req,
                                             ossl_unused int certReqId,
@@ -180,6 +208,7 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
                                             STACK_OF(X509) **caPubs)
 {
     mock_srv_ctx *ctx = OSSL_CMP_SRV_CTX_get0_custom_ctx(srv_ctx);
+    int bodytype;
     OSSL_CMP_PKISI *si = NULL;
 
     if (ctx == NULL || cert_req == NULL
@@ -187,8 +216,8 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
         return NULL;
     }
-    if (ctx->sendError == 1
-            || ctx->sendError == OSSL_CMP_MSG_get_bodytype(cert_req)) {
+    bodytype = OSSL_CMP_MSG_get_bodytype(cert_req);
+    if (ctx->sendError == 1 || ctx->sendError == bodytype) {
         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
         return NULL;
     }
@@ -212,24 +241,18 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
         /* give final response after polling */
         ctx->curr_pollCount = 0;
 
-    if (OSSL_CMP_MSG_get_bodytype(cert_req) == OSSL_CMP_KUR
-            && crm != NULL && ctx->certOut != NULL) {
+    /* accept cert update request only for the reference cert, if given */
+    if (bodytype == OSSL_CMP_KUR
+            && crm != NULL /* thus not p10cr */ && ctx->refCert != NULL) {
         const OSSL_CRMF_CERTID *cid = OSSL_CRMF_MSG_get0_regCtrl_oldCertID(crm);
-        const X509_NAME *issuer = X509_get_issuer_name(ctx->certOut);
-        const ASN1_INTEGER *serial = X509_get0_serialNumber(ctx->certOut);
 
         if (cid == NULL) {
             ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_CERTID);
             return NULL;
         }
-        if (issuer != NULL
-            && X509_NAME_cmp(issuer, OSSL_CRMF_CERTID_get0_issuer(cid)) != 0) {
-            ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID);
-            return NULL;
-        }
-        if (serial != NULL
-            && ASN1_INTEGER_cmp(serial,
-                                OSSL_CRMF_CERTID_get0_serialNumber(cid)) != 0) {
+        if (!refcert_cmp(ctx->refCert,
+                         OSSL_CRMF_CERTID_get0_issuer(cid),
+                         OSSL_CRMF_CERTID_get0_serialNumber(cid))) {
             ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_CERTID);
             return NULL;
         }
@@ -237,11 +260,12 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
 
     if (ctx->certOut != NULL
             && (*certOut = X509_dup(ctx->certOut)) == NULL)
+        /* Should return a cert produced from request template, see FR #16054 */
         goto err;
     if (ctx->chainOut != NULL
             && (*chainOut = X509_chain_up_ref(ctx->chainOut)) == NULL)
         goto err;
-    if (ctx->caPubsOut != NULL
+    if (ctx->caPubsOut != NULL /* OSSL_CMP_PKIBODY_IP not visible here */
             && (*caPubs = X509_chain_up_ref(ctx->caPubsOut)) == NULL)
         goto err;
     if (ctx->statusOut != NULL
@@ -252,9 +276,9 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
  err:
     X509_free(*certOut);
     *certOut = NULL;
-    sk_X509_pop_free(*chainOut, X509_free);
+    OSSL_STACK_OF_X509_free(*chainOut);
     *chainOut = NULL;
-    sk_X509_pop_free(*caPubs, X509_free);
+    OSSL_STACK_OF_X509_free(*caPubs);
     *caPubs = NULL;
     return NULL;
 }
@@ -270,20 +294,16 @@ static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
         ERR_raise(ERR_LIB_CMP, CMP_R_NULL_ARGUMENT);
         return NULL;
     }
-    if (ctx->certOut == NULL || ctx->sendError == 1
+    if (ctx->sendError == 1
             || ctx->sendError == OSSL_CMP_MSG_get_bodytype(rr)) {
         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
         return NULL;
     }
 
-    /* Allow any RR derived from CSR, which may include subject and serial */
-    if (issuer == NULL || serial == NULL)
-        return OSSL_CMP_PKISI_dup(ctx->statusOut);
-
-    /* accept revocation only for the certificate we sent in ir/cr/kur */
-    if (X509_NAME_cmp(issuer, X509_get_issuer_name(ctx->certOut)) != 0
-            || ASN1_INTEGER_cmp(serial,
-                                X509_get0_serialNumber(ctx->certOut)) != 0) {
+    /* allow any RR derived from CSR which does not include issuer and serial */
+    if ((issuer != NULL || serial != NULL)
+        /* accept revocation only for the reference cert, if given */
+            && !refcert_cmp(ctx->refCert, issuer, serial)) {
         ERR_raise_data(ERR_LIB_CMP, CMP_R_REQUEST_NOT_ACCEPTED,
                        "wrong certificate to revoke");
         return NULL;
@@ -291,6 +311,26 @@ static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
     return OSSL_CMP_PKISI_dup(ctx->statusOut);
 }
 
+static OSSL_CMP_ITAV *process_genm_itav(mock_srv_ctx *ctx, int req_nid,
+                                        const OSSL_CMP_ITAV *req)
+{
+    OSSL_CMP_ITAV *rsp;
+
+    switch (req_nid) {
+    case NID_id_it_caCerts:
+        rsp = OSSL_CMP_ITAV_new_caCerts(ctx->caPubsOut);
+        break;
+    case NID_id_it_rootCaCert:
+        rsp = OSSL_CMP_ITAV_new_rootCaKeyUpdate(ctx->newWithNew,
+                                                ctx->newWithOld,
+                                                ctx->oldWithNew);
+        break;
+    default:
+        rsp = OSSL_CMP_ITAV_dup(req);
+    }
+    return rsp;
+}
+
 static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
                         const OSSL_CMP_MSG *genm,
                         const STACK_OF(OSSL_CMP_ITAV) *in,
@@ -308,6 +348,18 @@ static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
         ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE);
         return 0;
     }
+    if (sk_OSSL_CMP_ITAV_num(in) == 1) {
+        OSSL_CMP_ITAV *req = sk_OSSL_CMP_ITAV_value(in, 0), *rsp;
+        ASN1_OBJECT *obj = OSSL_CMP_ITAV_get0_type(req);
+
+        if ((*out = sk_OSSL_CMP_ITAV_new_reserve(NULL, 1)) == NULL)
+            return 0;
+        rsp = process_genm_itav(ctx, OBJ_obj2nid(obj), req);
+        if (rsp != NULL && sk_OSSL_CMP_ITAV_push(*out, rsp))
+            return 1;
+        sk_OSSL_CMP_ITAV_free(*out);
+        return 0;
+    }
 
     *out = sk_OSSL_CMP_ITAV_deep_copy(in, OSSL_CMP_ITAV_dup,
                                       OSSL_CMP_ITAV_free);
@@ -351,10 +403,9 @@ static void process_error(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *error,
         for (i = 0; i < sk_ASN1_UTF8STRING_num(errorDetails); i++) {
             if (i > 0)
                 BIO_printf(bio_err, ", ");
-            BIO_printf(bio_err, "\"");
-            ASN1_STRING_print(bio_err,
-                              sk_ASN1_UTF8STRING_value(errorDetails, i));
-            BIO_printf(bio_err, "\"");
+            ASN1_STRING_print_ex(bio_err,
+                                 sk_ASN1_UTF8STRING_value(errorDetails, i),
+                                 ASN1_STRFLGS_ESC_QUOTE);
         }
         BIO_printf(bio_err, "\n");
     }

+ 1 - 3
libs/openssl/apps/lib/engine_loader.c

@@ -71,10 +71,8 @@ static OSSL_STORE_LOADER_CTX *engine_open(const OSSL_STORE_LOADER *loader,
     char *keyid = NULL;
     OSSL_STORE_LOADER_CTX *ctx = NULL;
 
-    if (OPENSSL_strncasecmp(p, ENGINE_SCHEME_COLON, sizeof(ENGINE_SCHEME_COLON) - 1)
-        != 0)
+    if (!CHECK_AND_SKIP_CASE_PREFIX(p, ENGINE_SCHEME_COLON))
         return NULL;
-    p += sizeof(ENGINE_SCHEME_COLON) - 1;
 
     /* Look for engine ID */
     q = strchr(p, ':');

+ 170 - 153
libs/openssl/apps/lib/http_server.c

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

+ 108 - 0
libs/openssl/apps/lib/log.c

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

+ 1 - 1
libs/openssl/apps/lib/names.c

@@ -11,7 +11,7 @@
 #include <openssl/bio.h>
 #include <openssl/safestack.h>
 #include "names.h"
-#include "openssl/crypto.h"
+#include "internal/e_os.h"
 
 int name_cmp(const char * const *a, const char * const *b)
 {

+ 146 - 69
libs/openssl/apps/lib/opt.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -41,6 +41,7 @@ static int opt_index;
 static char *arg;
 static char *flag;
 static char *dunno;
+static const char *unknown_name;
 static const OPTIONS *unknown;
 static const OPTIONS *opts;
 static char prog[40];
@@ -166,7 +167,6 @@ char *opt_init(int ac, char **av, const OPTIONS *o)
     opt_begin();
     opts = o;
     unknown = NULL;
-
     /* Make sure prog name is set for usage output */
     (void)opt_progname(argv[0]);
 
@@ -194,7 +194,7 @@ char *opt_init(int ac, char **av, const OPTIONS *o)
         case   0: case '-': case '.':
         case '/': case '<': case '>': case 'E': case 'F':
         case 'M': case 'U': case 'f': case 'l': case 'n': case 'p': case 's':
-        case 'u': case 'c': case ':': case 'N':
+        case 'u': case 'c': case ':': case 'N': case 'A':
             break;
         default:
             OPENSSL_assert(0);
@@ -215,6 +215,7 @@ char *opt_init(int ac, char **av, const OPTIONS *o)
         }
 #endif
         if (o->name[0] == '\0') {
+            OPENSSL_assert(unknown_name != NULL);
             OPENSSL_assert(unknown == NULL);
             unknown = o;
             OPENSSL_assert(unknown->valtype == 0 || unknown->valtype == '-');
@@ -224,7 +225,9 @@ char *opt_init(int ac, char **av, const OPTIONS *o)
 }
 
 static OPT_PAIR formats[] = {
-    {"PEM/DER", OPT_FMT_PEMDER},
+    {"pem", OPT_FMT_PEM},
+    {"der", OPT_FMT_DER},
+    {"b64", OPT_FMT_B64},
     {"pkcs12", OPT_FMT_PKCS12},
     {"smime", OPT_FMT_SMIME},
     {"engine", OPT_FMT_ENGINE},
@@ -236,21 +239,22 @@ static OPT_PAIR formats[] = {
     {NULL}
 };
 
+void opt_set_unknown_name(const char *name)
+{
+    unknown_name = name;
+}
+
 /* Print an error message about a failed format parse. */
 static int opt_format_error(const char *s, unsigned long flags)
 {
     OPT_PAIR *ap;
 
-    if (flags == OPT_FMT_PEMDER) {
-        opt_printf_stderr("%s: Bad format \"%s\"; must be pem or der\n",
-                          prog, s);
-    } else {
-        opt_printf_stderr("%s: Bad format \"%s\"; must be one of:\n",
-                          prog, s);
-        for (ap = formats; ap->name; ap++)
-            if (flags & ap->retval)
-                opt_printf_stderr("   %s\n", ap->name);
-    }
+    opt_printf_stderr("%s: Bad format \"%s\"; must be one of: ", prog, s);
+    for (ap = formats; ap->name; ap++)
+        if (flags & ap->retval)
+            opt_printf_stderr(" %s", ap->name);
+    opt_printf_stderr("\n");
+
     return 0;
 }
 
@@ -261,9 +265,21 @@ int opt_format(const char *s, unsigned long flags, int *result)
     default:
         opt_printf_stderr("%s: Bad format \"%s\"\n", prog, s);
         return 0;
+    case 'B':
+    case 'b':
+        if (s[1] == '\0'
+            || strcmp(s, "B64") == 0 || strcmp(s, "b64") == 0
+            || strcmp(s, "BASE64") == 0 || strcmp(s, "base64") == 0 ) {
+            if ((flags & OPT_FMT_B64) == 0)
+                return opt_format_error(s, flags);
+            *result = FORMAT_BASE64;
+        } else {
+            return 0;
+        }
+        break;
     case 'D':
     case 'd':
-        if ((flags & OPT_FMT_PEMDER) == 0)
+        if ((flags & OPT_FMT_DER) == 0)
             return opt_format_error(s, flags);
         *result = FORMAT_ASN1;
         break;
@@ -313,7 +329,7 @@ int opt_format(const char *s, unsigned long flags, int *result)
     case 'P':
     case 'p':
         if (s[1] == '\0' || strcmp(s, "PEM") == 0 || strcmp(s, "pem") == 0) {
-            if ((flags & OPT_FMT_PEMDER) == 0)
+            if ((flags & OPT_FMT_PEM) == 0)
                 return opt_format_error(s, flags);
             *result = FORMAT_PEM;
         } else if (strcmp(s, "PVK") == 0 || strcmp(s, "pvk") == 0) {
@@ -399,8 +415,10 @@ int opt_cipher_any(const char *name, EVP_CIPHER **cipherp)
 {
     int ret;
 
+    if (name == NULL)
+         return 1;
     if ((ret = opt_cipher_silent(name, cipherp)) == 0)
-        opt_printf_stderr("%s: Unknown cipher: %s\n", prog, name);
+        opt_printf_stderr("%s: Unknown option or cipher: %s\n", prog, name);
     return ret;
 }
 
@@ -410,6 +428,8 @@ int opt_cipher(const char *name, EVP_CIPHER **cipherp)
      unsigned long int flags;
      EVP_CIPHER *c = NULL;
 
+    if (name == NULL)
+         return 1;
      if (opt_cipher_any(name, &c)) {
         mode = EVP_CIPHER_get_mode(c);
         flags = EVP_CIPHER_get_flags(c);
@@ -454,12 +474,22 @@ int opt_md(const char *name, EVP_MD **mdp)
 {
     int ret;
 
+    if (name == NULL)
+        return 1;
     if ((ret = opt_md_silent(name, mdp)) == 0)
-        opt_printf_stderr("%s: Unknown option or message digest: %s\n", prog,
-                          name != NULL ? name : "\"\"");
+        opt_printf_stderr("%s: Unknown option or message digest: %s\n",
+                          prog, name);
     return ret;
 }
 
+int opt_check_md(const char *name)
+{
+    if (opt_md(name, NULL))
+        return 1;
+    ERR_clear_error();
+    return 0;
+}
+
 /* Look through a list of name/value pairs. */
 int opt_pair(const char *name, const OPT_PAIR* pairs, int *result)
 {
@@ -956,11 +986,14 @@ int opt_next(void)
         case 'E':
         case 'F':
         case 'f':
+        case 'A':
+        case 'a':
             if (opt_format(arg,
                            o->valtype == 'c' ? OPT_FMT_PDS :
                            o->valtype == 'E' ? OPT_FMT_PDE :
-                           o->valtype == 'F' ? OPT_FMT_PEMDER
-                           : OPT_FMT_ANY, &ival))
+                           o->valtype == 'F' ? OPT_FMT_PEMDER :
+                           o->valtype == 'A' ? OPT_FMT_ASN1 :
+                           OPT_FMT_ANY, &ival))
                 break;
             opt_printf_stderr("%s: Invalid format \"%s\" for option -%s\n",
                               prog, arg, o->name);
@@ -971,6 +1004,11 @@ int opt_next(void)
         return o->retval;
     }
     if (unknown != NULL) {
+        if (dunno != NULL) {
+            opt_printf_stderr("%s: Multiple %s or unknown options: -%s and -%s\n",
+                              prog, unknown_name, dunno, p);
+            return -1;
+        }
         dunno = p;
         return unknown->retval;
     }
@@ -996,6 +1034,12 @@ char *opt_unknown(void)
     return dunno;
 }
 
+/* Reset the unknown option; needed by ocsp to allow multiple digest options. */
+void reset_unknown(void)
+{
+    dunno = NULL;
+}
+
 /* Return the rest of the arguments after parsing flags. */
 char **opt_rest(void)
 {
@@ -1013,6 +1057,31 @@ int opt_num_rest(void)
     return i;
 }
 
+int opt_check_rest_arg(const char *expected)
+{
+    char *opt = *opt_rest();
+
+    if (opt == NULL || *opt == '\0') {
+        if (expected == NULL)
+            return 1;
+        opt_printf_stderr("%s: Missing argument: %s\n", prog, expected);
+        return 0;
+    }
+    if (expected != NULL) {
+        opt = argv[opt_index + 1];
+        if (opt == NULL || *opt == '\0')
+            return 1;
+        opt_printf_stderr("%s: Extra argument after %s: \"%s\"\n", prog, expected, opt);
+        return 0;
+    }
+    if (opt_unknown() == NULL)
+        opt_printf_stderr("%s: Extra option: \"%s\"\n", prog, opt);
+    else
+        opt_printf_stderr("%s: Extra (unknown) options: \"%s\" \"%s\"\n",
+                          prog, opt_unknown(), opt);
+    return 0;
+}
+
 /* Return a string describing the parameter type. */
 static const char *valtype2param(const OPTIONS *o)
 {
@@ -1058,55 +1127,60 @@ static void opt_print(const OPTIONS *o, int doingparams, int width)
 {
     const char* help;
     char start[80 + 1];
-    char *p;
-
-        help = o->helpstr ? o->helpstr : "(No additional info)";
-        if (o->name == OPT_HELP_STR) {
-            opt_printf_stderr(help, prog);
-            return;
-        }
-        if (o->name == OPT_SECTION_STR) {
-            opt_printf_stderr("\n");
-            opt_printf_stderr(help, prog);
-            return;
-        }
-        if (o->name == OPT_PARAM_STR) {
-            opt_printf_stderr("\nParameters:\n");
-            return;
-        }
-
-        /* Pad out prefix */
-        memset(start, ' ', sizeof(start) - 1);
-        start[sizeof(start) - 1] = '\0';
+    int linelen, printlen;
+
+    /* Avoid OOB if width is beyond the buffer size of start */
+    if (width >= (int)sizeof(start))
+        width = (int)sizeof(start) - 1;
+
+    help = o->helpstr ? o->helpstr : "(No additional info)";
+    if (o->name == OPT_HELP_STR) {
+        opt_printf_stderr(help, prog);
+        return;
+    } else if (o->name == OPT_SECTION_STR) {
+        opt_printf_stderr("\n");
+        opt_printf_stderr(help, prog);
+        return;
+    } else if (o->name == OPT_PARAM_STR) {
+        opt_printf_stderr("\nParameters:\n");
+        return;
+    }
 
-        if (o->name == OPT_MORE_STR) {
-            /* Continuation of previous line; pad and print. */
-            start[width] = '\0';
-            opt_printf_stderr("%s  %s\n", start, help);
-            return;
-        }
+    /* Pad out prefix */
+    memset(start, ' ', sizeof(start) - 1);
+    start[sizeof(start) - 1] = '\0';
 
-        /* Build up the "-flag [param]" part. */
-        p = start;
-        *p++ = ' ';
-        if (!doingparams)
-            *p++ = '-';
-        if (o->name[0])
-            p += strlen(strcpy(p, o->name));
-        else
-            *p++ = '*';
-        if (o->valtype != '-') {
-            *p++ = ' ';
-            p += strlen(strcpy(p, valtype2param(o)));
-        }
-        *p = ' ';
-        if ((int)(p - start) >= MAX_OPT_HELP_WIDTH) {
-            *p = '\0';
-            opt_printf_stderr("%s\n", start);
-            memset(start, ' ', sizeof(start));
-        }
+    if (o->name == OPT_MORE_STR) {
+        /* Continuation of previous line; pad and print. */
         start[width] = '\0';
         opt_printf_stderr("%s  %s\n", start, help);
+        return;
+    }
+
+    /* Build up the "-flag [param]" part. */
+    linelen = 0;
+
+    printlen = opt_printf_stderr(" %s", !doingparams ? "-" : "");
+    linelen += (printlen > 0) ? printlen : MAX_OPT_HELP_WIDTH;
+
+    printlen = opt_printf_stderr("%s" , o->name[0] ? o->name : "*");
+    linelen += (printlen > 0) ? printlen : MAX_OPT_HELP_WIDTH;
+
+    if (o->valtype != '-') {
+        printlen = opt_printf_stderr(" %s" , valtype2param(o));
+        linelen += (printlen > 0) ? printlen : MAX_OPT_HELP_WIDTH;
+    }
+
+    if (linelen >= MAX_OPT_HELP_WIDTH || linelen > width) {
+        opt_printf_stderr("%s", "\n");
+        memset(start, ' ', sizeof(start));
+        linelen = 0;
+    }
+
+    width -= linelen;
+
+    start[width] = '\0';
+    opt_printf_stderr("%s  %s\n", start, help);
 }
 
 void opt_help(const OPTIONS *list)
@@ -1114,7 +1188,6 @@ void opt_help(const OPTIONS *list)
     const OPTIONS *o;
     int i, sawparams = 0, width = 5;
     int standard_prolog;
-    char start[80 + 1];
 
     /* Starts with its own help message? */
     standard_prolog = list[0].name != OPT_HELP_STR;
@@ -1123,14 +1196,18 @@ void opt_help(const OPTIONS *list)
     for (o = list; o->name; o++) {
         if (o->name == OPT_MORE_STR)
             continue;
+
         i = 2 + (int)strlen(o->name);
         if (o->valtype != '-')
             i += 1 + strlen(valtype2param(o));
-        if (i < MAX_OPT_HELP_WIDTH && i > width)
+
+        if (i > width)
             width = i;
-        OPENSSL_assert(i < (int)sizeof(start));
     }
 
+    if (width > MAX_OPT_HELP_WIDTH)
+        width = MAX_OPT_HELP_WIDTH;
+
     if (standard_prolog) {
         opt_printf_stderr("Usage: %s [options]\n", prog);
         if (list[0].name != OPT_SECTION_STR)

+ 91 - 17
libs/openssl/apps/lib/s_cb.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -258,7 +258,8 @@ static const char *get_sigtype(int nid)
         return "gost2012_512";
 
     default:
-        return NULL;
+        /* Try to output provider-registered sig alg name */
+        return OBJ_nid2sn(nid);
     }
 }
 
@@ -433,12 +434,15 @@ long bio_dump_callback(BIO *bio, int cmd, const char *argp, size_t len,
                        int argi, long argl, int ret, size_t *processed)
 {
     BIO *out;
+    BIO_MMSG_CB_ARGS *mmsgargs;
+    size_t i;
 
     out = (BIO *)BIO_get_callback_arg(bio);
     if (out == NULL)
         return ret;
 
-    if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
+    switch (cmd) {
+    case (BIO_CB_READ | BIO_CB_RETURN):
         if (ret > 0 && processed != NULL) {
             BIO_printf(out, "read from %p [%p] (%zu bytes => %zu (0x%zX))\n",
                        (void *)bio, (void *)argp, len, *processed, *processed);
@@ -447,7 +451,9 @@ long bio_dump_callback(BIO *bio, int cmd, const char *argp, size_t len,
             BIO_printf(out, "read from %p [%p] (%zu bytes => %d)\n",
                        (void *)bio, (void *)argp, len, ret);
         }
-    } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
+        break;
+
+    case (BIO_CB_WRITE | BIO_CB_RETURN):
         if (ret > 0 && processed != NULL) {
             BIO_printf(out, "write to %p [%p] (%zu bytes => %zu (0x%zX))\n",
                        (void *)bio, (void *)argp, len, *processed, *processed);
@@ -456,6 +462,51 @@ long bio_dump_callback(BIO *bio, int cmd, const char *argp, size_t len,
             BIO_printf(out, "write to %p [%p] (%zu bytes => %d)\n",
                        (void *)bio, (void *)argp, len, ret);
         }
+        break;
+
+    case (BIO_CB_RECVMMSG | BIO_CB_RETURN):
+        mmsgargs = (BIO_MMSG_CB_ARGS *)argp;
+        if (ret > 0) {
+            for (i = 0; i < *(mmsgargs->msgs_processed); i++) {
+                BIO_MSG *msg = (BIO_MSG *)((char *)mmsgargs->msg
+                                           + (i * mmsgargs->stride));
+
+                BIO_printf(out, "read from %p [%p] (%zu bytes => %zu (0x%zX))\n",
+                           (void *)bio, (void *)msg->data, msg->data_len,
+                           msg->data_len, msg->data_len);
+                BIO_dump(out, msg->data, msg->data_len);
+            }
+        } else if (mmsgargs->num_msg > 0) {
+            BIO_MSG *msg = mmsgargs->msg;
+
+            BIO_printf(out, "read from %p [%p] (%zu bytes => %d)\n",
+                       (void *)bio, (void *)msg->data, msg->data_len, ret);
+        }
+        break;
+
+    case (BIO_CB_SENDMMSG | BIO_CB_RETURN):
+        mmsgargs = (BIO_MMSG_CB_ARGS *)argp;
+        if (ret > 0) {
+            for (i = 0; i < *(mmsgargs->msgs_processed); i++) {
+                BIO_MSG *msg = (BIO_MSG *)((char *)mmsgargs->msg
+                                           + (i * mmsgargs->stride));
+
+                BIO_printf(out, "write to %p [%p] (%zu bytes => %zu (0x%zX))\n",
+                           (void *)bio, (void *)msg->data, msg->data_len,
+                           msg->data_len, msg->data_len);
+                BIO_dump(out, msg->data, msg->data_len);
+            }
+        } else if (mmsgargs->num_msg > 0) {
+            BIO_MSG *msg = mmsgargs->msg;
+
+            BIO_printf(out, "write to %p [%p] (%zu bytes => %d)\n",
+                       (void *)bio, (void *)msg->data, msg->data_len, ret);
+        }
+        break;
+
+    default:
+        /* do nothing */
+        break;
     }
     return ret;
 }
@@ -559,6 +610,7 @@ static STRINT_PAIR handshakes[] = {
     {", CertificateStatus", SSL3_MT_CERTIFICATE_STATUS},
     {", SupplementalData", SSL3_MT_SUPPLEMENTAL_DATA},
     {", KeyUpdate", SSL3_MT_KEY_UPDATE},
+    {", CompressedCertificate", SSL3_MT_COMPRESSED_CERTIFICATE},
 #ifndef OPENSSL_NO_NEXTPROTONEG
     {", NextProto", SSL3_MT_NEXT_PROTO},
 #endif
@@ -671,6 +723,8 @@ static STRINT_PAIR tlsext_types[] = {
     {"session ticket", TLSEXT_TYPE_session_ticket},
     {"renegotiation info", TLSEXT_TYPE_renegotiate},
     {"signed certificate timestamps", TLSEXT_TYPE_signed_certificate_timestamp},
+    {"client cert type", TLSEXT_TYPE_client_cert_type},
+    {"server cert type", TLSEXT_TYPE_server_cert_type},
     {"TLS padding", TLSEXT_TYPE_padding},
 #ifdef TLSEXT_TYPE_next_proto_neg
     {"next protocol", TLSEXT_TYPE_next_proto_neg},
@@ -685,6 +739,7 @@ static STRINT_PAIR tlsext_types[] = {
 #ifdef TLSEXT_TYPE_extended_master_secret
     {"extended master secret", TLSEXT_TYPE_extended_master_secret},
 #endif
+    {"compress certificate", TLSEXT_TYPE_compress_certificate},
     {"key share", TLSEXT_TYPE_key_share},
     {"supported versions", TLSEXT_TYPE_supported_versions},
     {"psk", TLSEXT_TYPE_psk},
@@ -998,7 +1053,7 @@ void ssl_excert_free(SSL_EXCERT *exc)
     while (exc) {
         X509_free(exc->cert);
         EVP_PKEY_free(exc->key);
-        sk_X509_pop_free(exc->chain, X509_free);
+        OSSL_STACK_OF_X509_free(exc->chain);
         curr = exc;
         exc = exc->next;
         OPENSSL_free(curr);
@@ -1168,7 +1223,7 @@ static char *hexencode(const unsigned char *data, size_t len)
 void print_verify_detail(SSL *s, BIO *bio)
 {
     int mdpth;
-    EVP_PKEY *mspki;
+    EVP_PKEY *mspki = NULL;
     long verify_err = SSL_get_verify_result(s);
 
     if (verify_err == X509_V_OK) {
@@ -1203,12 +1258,15 @@ void print_verify_detail(SSL *s, BIO *bio)
             hexdata = hexencode(data + dlen - TLSA_TAIL_SIZE, TLSA_TAIL_SIZE);
         else
             hexdata = hexencode(data, dlen);
-        BIO_printf(bio, "DANE TLSA %d %d %d %s%s %s at depth %d\n",
+        BIO_printf(bio, "DANE TLSA %d %d %d %s%s ",
                    usage, selector, mtype,
-                   (dlen > TLSA_TAIL_SIZE) ? "..." : "", hexdata,
-                   (mspki != NULL) ? "signed the certificate" :
-                   mdpth ? "matched TA certificate" : "matched EE certificate",
-                   mdpth);
+                   (dlen > TLSA_TAIL_SIZE) ? "..." : "", hexdata);
+        if (SSL_get0_peer_rpk(s) == NULL)
+            BIO_printf(bio, "%s certificate at depth %d\n",
+                       (mspki != NULL) ? "signed the peer" :
+                       mdpth ? "matched the TA" : "matched the EE", mdpth);
+        else
+            BIO_printf(bio, "matched the peer raw public key\n");
         OPENSSL_free(hexdata);
     }
 }
@@ -1216,17 +1274,16 @@ void print_verify_detail(SSL *s, BIO *bio)
 void print_ssl_summary(SSL *s)
 {
     const SSL_CIPHER *c;
-    X509 *peer;
+    X509 *peer = SSL_get0_peer_certificate(s);
+    EVP_PKEY *peer_rpk = SSL_get0_peer_rpk(s);
+    int nid;
 
     BIO_printf(bio_err, "Protocol version: %s\n", SSL_get_version(s));
     print_raw_cipherlist(s);
     c = SSL_get_current_cipher(s);
     BIO_printf(bio_err, "Ciphersuite: %s\n", SSL_CIPHER_get_name(c));
     do_print_sigalgs(bio_err, s, 0);
-    peer = SSL_get0_peer_certificate(s);
     if (peer != NULL) {
-        int nid;
-
         BIO_puts(bio_err, "Peer certificate: ");
         X509_NAME_print_ex(bio_err, X509_get_subject_name(peer),
                            0, get_nameopt());
@@ -1236,8 +1293,13 @@ void print_ssl_summary(SSL *s)
         if (SSL_get_peer_signature_type_nid(s, &nid))
             BIO_printf(bio_err, "Signature type: %s\n", get_sigtype(nid));
         print_verify_detail(s, bio_err);
+    } else if (peer_rpk != NULL) {
+        BIO_printf(bio_err, "Peer used raw public key\n");
+        if (SSL_get_peer_signature_type_nid(s, &nid))
+            BIO_printf(bio_err, "Signature type: %s\n", get_sigtype(nid));
+        print_verify_detail(s, bio_err);
     } else {
-        BIO_puts(bio_err, "No peer certificate\n");
+        BIO_puts(bio_err, "No peer certificate or raw public key\n");
     }
 #ifndef OPENSSL_NO_EC
     ssl_print_point_formats(bio_err, s);
@@ -1564,7 +1626,7 @@ void print_ca_names(BIO *bio, SSL *s)
         return;
     }
 
-    BIO_printf(bio, "---\nAcceptable %s certificate CA names\n",cs);
+    BIO_printf(bio, "---\nAcceptable %s certificate CA names\n", cs);
     for (i = 0; i < sk_X509_NAME_num(sk); i++) {
         X509_NAME_print_ex(bio, sk_X509_NAME_value(sk, i), 0, get_nameopt());
         BIO_write(bio, "\n", 1);
@@ -1580,3 +1642,15 @@ void ssl_print_secure_renegotiation_notes(BIO *bio, SSL *s)
         BIO_printf(bio, "This TLS version forbids renegotiation.\n");
     }
 }
+
+int progress_cb(EVP_PKEY_CTX *ctx)
+{
+    BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
+    int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
+    static const char symbols[] = ".+*\n";
+    char c = (p >= 0 && (size_t)p <= sizeof(symbols) - 1) ? symbols[p] : '?';
+
+    BIO_write(b, &c, 1);
+    (void)BIO_flush(b);
+    return 1;
+}

+ 57 - 18
libs/openssl/apps/lib/s_socket.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -64,6 +64,9 @@ BIO_ADDR *ourpeer = NULL;
  *  AF_UNSPEC
  * @type: socket type, must be SOCK_STREAM or SOCK_DGRAM
  * @protocol: socket protocol, e.g. IPPROTO_TCP or IPPROTO_UDP (or 0 for any)
+ * @tfo: flag to enable TCP Fast Open
+ * @doconn: whether we should call BIO_connect() on the socket
+ * @ba_ret: BIO_ADDR for the remote peer, to be freed by caller
  *
  * This will create a socket and use it to connect to a host:port, or if
  * family == AF_UNIX, to the path found in host.
@@ -76,7 +79,8 @@ BIO_ADDR *ourpeer = NULL;
  */
 int init_client(int *sock, const char *host, const char *port,
                 const char *bindhost, const char *bindport,
-                int family, int type, int protocol)
+                int family, int type, int protocol, int tfo, int doconn,
+                BIO_ADDR **ba_ret)
 {
     BIO_ADDRINFO *res = NULL;
     BIO_ADDRINFO *bindaddr = NULL;
@@ -84,6 +88,10 @@ int init_client(int *sock, const char *host, const char *port,
     const BIO_ADDRINFO *bi = NULL;
     int found = 0;
     int ret;
+    int options = 0;
+
+    if (tfo && ba_ret != NULL)
+        *ba_ret = NULL;
 
     if (BIO_sock_init() != 1)
         return 0;
@@ -160,14 +168,22 @@ int init_client(int *sock, const char *host, const char *port,
             BIO_free(tmpbio);
         }
 #endif
+        if (BIO_ADDRINFO_protocol(ai) == IPPROTO_TCP) {
+            options |= BIO_SOCK_NODELAY;
+            if (tfo)
+                options |= BIO_SOCK_TFO;
+        }
 
-        if (!BIO_connect(*sock, BIO_ADDRINFO_address(ai),
-                         BIO_ADDRINFO_protocol(ai) == IPPROTO_TCP ? BIO_SOCK_NODELAY : 0)) {
+        if (doconn && !BIO_connect(*sock, BIO_ADDRINFO_address(ai), options)) {
             BIO_closesocket(*sock);
             *sock = INVALID_SOCKET;
             continue;
         }
 
+        /* Save the address */
+        if (tfo || !doconn)
+            *ba_ret = BIO_ADDR_dup(BIO_ADDRINFO_address(ai));
+
         /* Success, don't try any more addresses */
         break;
     }
@@ -188,6 +204,13 @@ int init_client(int *sock, const char *host, const char *port,
         }
         ERR_print_errors(bio_err);
     } else {
+        char *hostname = NULL;
+
+        hostname = BIO_ADDR_hostname_string(BIO_ADDRINFO_address(ai), 1);
+        if (hostname != NULL) {
+            BIO_printf(bio_out, "Connecting to %s\n", hostname);
+            OPENSSL_free(hostname);
+        }
         /* Remove any stale errors from previous connection attempts */
         ERR_clear_error();
         ret = 1;
@@ -200,6 +223,25 @@ out:
     return ret;
 }
 
+void get_sock_info_address(int asock, char **hostname, char **service)
+{
+    union BIO_sock_info_u info;
+
+    if (hostname != NULL)
+        *hostname = NULL;
+    if (service != NULL)
+        *service = NULL;
+
+    if ((info.addr = BIO_ADDR_new()) != NULL
+            && BIO_sock_info(asock, BIO_SOCK_INFO_ADDRESS, &info)) {
+        if (hostname != NULL)
+            *hostname = BIO_ADDR_hostname_string(info.addr, 1);
+        if (service != NULL)
+            *service = BIO_ADDR_service_string(info.addr, 1);
+    }
+    BIO_ADDR_free(info.addr);
+}
+
 int report_server_accept(BIO *out, int asock, int with_address, int with_pid)
 {
     int success = 1;
@@ -207,30 +249,24 @@ int report_server_accept(BIO *out, int asock, int with_address, int with_pid)
     if (BIO_printf(out, "ACCEPT") <= 0)
         return 0;
     if (with_address) {
-        union BIO_sock_info_u info;
-        char *hostname = NULL;
-        char *service = NULL;
+        char *hostname, *service;
 
-        if ((info.addr = BIO_ADDR_new()) != NULL
-            && BIO_sock_info(asock, BIO_SOCK_INFO_ADDRESS, &info)
-            && (hostname = BIO_ADDR_hostname_string(info.addr, 1)) != NULL
-            && (service = BIO_ADDR_service_string(info.addr, 1)) != NULL) {
+        get_sock_info_address(asock, &hostname, &service);
+        success = hostname != NULL && service != NULL;
+        if (success)
             success = BIO_printf(out,
                                  strchr(hostname, ':') == NULL
                                  ? /* IPv4 */ " %s:%s"
                                  : /* IPv6 */ " [%s]:%s",
                                  hostname, service) > 0;
-        } else {
+        else
             (void)BIO_printf(out, "unknown:error\n");
-            success = 0;
-        }
         OPENSSL_free(hostname);
         OPENSSL_free(service);
-        BIO_ADDR_free(info.addr);
     }
     if (with_pid)
-        success = success && BIO_printf(out, " PID=%d", getpid()) > 0;
-    success = success && BIO_printf(out, "\n") > 0;
+        success *= BIO_printf(out, " PID=%d", getpid()) > 0;
+    success *= BIO_printf(out, "\n") > 0;
     (void)BIO_flush(out);
 
     return success;
@@ -258,7 +294,8 @@ int report_server_accept(BIO *out, int asock, int with_address, int with_pid)
  */
 int do_server(int *accept_sock, const char *host, const char *port,
               int family, int type, int protocol, do_server_cb cb,
-              unsigned char *context, int naccept, BIO *bio_s_out)
+              unsigned char *context, int naccept, BIO *bio_s_out,
+              int tfo)
 {
     int asock = 0;
     int sock;
@@ -292,6 +329,8 @@ int do_server(int *accept_sock, const char *host, const char *port,
     sock_protocol = BIO_ADDRINFO_protocol(res);
     sock_address = BIO_ADDRINFO_address(res);
     next = BIO_ADDRINFO_next(res);
+    if (tfo && sock_type == SOCK_STREAM)
+        sock_options |= BIO_SOCK_TFO;
 #ifdef AF_INET6
     if (sock_family == AF_INET6)
         sock_options |= BIO_SOCK_V6_ONLY;

+ 2 - 2
libs/openssl/apps/lib/tlssrp_depr.c

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

+ 7 - 7
libs/openssl/apps/lib/vms_term_sock.c

@@ -120,7 +120,7 @@ typedef struct _SocketPairTimeoutBlock {
 } SPTB;
 
 # ifdef TERM_SOCK_TEST
-
+
 /*----------------------------------------------------------------------------*/
 /*                                                                            */
 /*----------------------------------------------------------------------------*/
@@ -160,7 +160,7 @@ int main (int argc, char *argv[], char *envp[])
 
 }
 # endif
-
+
 /*----------------------------------------------------------------------------*/
 /*                                                                            */
 /*----------------------------------------------------------------------------*/
@@ -275,7 +275,7 @@ int TerminalSocket (int FunctionCode, int *ReturnSocket)
     return TERM_SOCK_SUCCESS;
 
 }
-
+
 /*----------------------------------------------------------------------------*/
 /*                                                                            */
 /*----------------------------------------------------------------------------*/
@@ -441,7 +441,7 @@ static int CreateSocketPair (int SocketFamily,
     sin.sin_port = LocalHostPort ;
 
     status = connect (SockDesc2, (struct sockaddr *) &sin, sizeof(sin));
-    if (status < 0 ) {
+    if (status < 0) {
         LogMessage ("CreateSocketPair: connect () - %d", errno);
         sys$cantim (&sptb, 0);
         sys$cancel (TcpAcceptChan);
@@ -485,7 +485,7 @@ static int CreateSocketPair (int SocketFamily,
     return (0) ;
 
 }
-
+
 /*----------------------------------------------------------------------------*/
 /*                                                                            */
 /*----------------------------------------------------------------------------*/
@@ -499,7 +499,7 @@ static void SocketPairTimeoutAst (int astparm)
     return;
 
 }
-
+
 /*----------------------------------------------------------------------------*/
 /*                                                                            */
 /*----------------------------------------------------------------------------*/
@@ -538,7 +538,7 @@ static int TerminalDeviceAst (int astparm)
     return status;
 
 }
-
+
 /*----------------------------------------------------------------------------*/
 /*                                                                            */
 /*----------------------------------------------------------------------------*/

+ 102 - 36
libs/openssl/apps/list.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -102,7 +102,7 @@ static void collect_ciphers(EVP_CIPHER *cipher, void *stack)
         EVP_CIPHER_up_ref(cipher);
 }
 
-static void list_ciphers(void)
+static void list_ciphers(const char *prefix)
 {
     STACK_OF(EVP_CIPHER) *ciphers = sk_EVP_CIPHER_new(cipher_cmp);
     int i;
@@ -113,12 +113,12 @@ static void list_ciphers(void)
     }
 #ifndef OPENSSL_NO_DEPRECATED_3_0
     if (include_legacy()) {
-        BIO_printf(bio_out, "Legacy:\n");
+        BIO_printf(bio_out, "%sLegacy:\n", prefix);
         EVP_CIPHER_do_all_sorted(legacy_cipher_fn, bio_out);
     }
 #endif
 
-    BIO_printf(bio_out, "Provided:\n");
+    BIO_printf(bio_out, "%sProvided:\n", prefix);
     EVP_CIPHER_do_all_provided(app_get0_libctx(), collect_ciphers, ciphers);
     sk_EVP_CIPHER_sort(ciphers);
     for (i = 0; i < sk_EVP_CIPHER_num(ciphers); i++) {
@@ -186,7 +186,7 @@ static void collect_digests(EVP_MD *digest, void *stack)
         EVP_MD_up_ref(digest);
 }
 
-static void list_digests(void)
+static void list_digests(const char *prefix)
 {
     STACK_OF(EVP_MD) *digests = sk_EVP_MD_new(md_cmp);
     int i;
@@ -197,12 +197,12 @@ static void list_digests(void)
     }
 #ifndef OPENSSL_NO_DEPRECATED_3_0
     if (include_legacy()) {
-        BIO_printf(bio_out, "Legacy:\n");
+        BIO_printf(bio_out, "%sLegacy:\n", prefix);
         EVP_MD_do_all_sorted(legacy_md_fn, bio_out);
     }
 #endif
 
-    BIO_printf(bio_out, "Provided:\n");
+    BIO_printf(bio_out, "%sProvided:\n", prefix);
     EVP_MD_do_all_provided(app_get0_libctx(), collect_digests, digests);
     sk_EVP_MD_sort(digests);
     for (i = 0; i < sk_EVP_MD_num(digests); i++) {
@@ -1209,9 +1209,11 @@ static int provider_cmp(const OSSL_PROVIDER * const *a,
 static int collect_providers(OSSL_PROVIDER *provider, void *stack)
 {
     STACK_OF(OSSL_PROVIDER) *provider_stack = stack;
-
-    sk_OSSL_PROVIDER_push(provider_stack, provider);
-    return 1;
+    /*
+     * If OK - result is the index of inserted data
+     * Error - result is -1 or 0
+     */
+    return sk_OSSL_PROVIDER_push(provider_stack, provider) > 0 ? 1 : 0;
 }
 
 static void list_provider_info(void)
@@ -1226,8 +1228,13 @@ static void list_provider_info(void)
         BIO_printf(bio_err, "ERROR: Memory allocation\n");
         return;
     }
+
+    if (OSSL_PROVIDER_do_all(NULL, &collect_providers, providers) != 1) {
+        BIO_printf(bio_err, "ERROR: Memory allocation\n");
+        return;
+    }
+
     BIO_printf(bio_out, "Providers:\n");
-    OSSL_PROVIDER_do_all(NULL, &collect_providers, providers);
     sk_OSSL_PROVIDER_sort(providers);
     for (i = 0; i < sk_OSSL_PROVIDER_num(providers); i++) {
         const OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(providers, i);
@@ -1286,6 +1293,9 @@ static void list_engines(void)
 static void list_disabled(void)
 {
     BIO_puts(bio_out, "Disabled algorithms:\n");
+#ifdef OPENSSL_NO_ARGON2
+    BIO_puts(bio_out, "ARGON2\n");
+#endif
 #ifdef OPENSSL_NO_ARIA
     BIO_puts(bio_out, "ARIA\n");
 #endif
@@ -1334,6 +1344,9 @@ static void list_disabled(void)
 #ifdef OPENSSL_NO_EC
     BIO_puts(bio_out, "EC\n");
 #endif
+#ifdef OPENSSL_NO_ECX
+    BIO_puts(bio_out, "ECX\n");
+#endif
 #ifdef OPENSSL_NO_EC2M
     BIO_puts(bio_out, "EC2M\n");
 #endif
@@ -1421,15 +1434,22 @@ static void list_disabled(void)
 #ifdef OPENSSL_NO_WHIRLPOOL
     BIO_puts(bio_out, "WHIRLPOOL\n");
 #endif
-#ifndef ZLIB
+#ifdef OPENSSL_NO_ZLIB
     BIO_puts(bio_out, "ZLIB\n");
 #endif
+#ifdef OPENSSL_NO_BROTLI
+    BIO_puts(bio_out, "BROTLI\n");
+#endif
+#ifdef OPENSSL_NO_ZSTD
+    BIO_puts(bio_out, "ZSTD\n");
+#endif
 }
 
 /* Unified enum for help and list commands. */
 typedef enum HELPLIST_CHOICE {
     OPT_COMMON,
     OPT_ONE, OPT_VERBOSE,
+    OPT_ALL_ARGORITHMS,
     OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS,
     OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS,
     OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED,
@@ -1455,6 +1475,7 @@ const OPTIONS list_options[] = {
     {"select", OPT_SELECT_NAME, 's', "Select a single algorithm"},
     {"commands", OPT_COMMANDS, '-', "List of standard commands"},
     {"standard-commands", OPT_COMMANDS, '-', "List of standard commands"},
+    {"all-algorithms", OPT_ALL_ARGORITHMS, '-', "List of all algorithms"},
 #ifndef OPENSSL_NO_DEPRECATED_3_0
     {"digest-commands", OPT_DIGEST_COMMANDS, '-',
      "List of message digest commands (deprecated)"},
@@ -1513,8 +1534,10 @@ int list_main(int argc, char **argv)
     char *prog;
     HELPLIST_CHOICE o;
     int one = 0, done = 0;
+    int print_newline = 0;
     struct {
         unsigned int commands:1;
+        unsigned int all_algorithms:1;
         unsigned int random_instances:1;
         unsigned int random_generators:1;
         unsigned int digest_commands:1;
@@ -1558,6 +1581,9 @@ opthelp:
         case OPT_ONE:
             one = 1;
             break;
+        case OPT_ALL_ARGORITHMS:
+            todo.all_algorithms = 1;
+            break;
         case OPT_COMMANDS:
             todo.commands = 1;
             break;
@@ -1647,57 +1673,97 @@ opthelp:
     }
 
     /* No extra arguments. */
-    if (opt_num_rest() != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
+#define MAYBE_ADD_NL(cmd) \
+    do { \
+        if (print_newline++) { \
+            BIO_printf(bio_out, "\n"); \
+        } \
+        cmd; \
+    } while(0)
+
     if (todo.commands)
-        list_type(FT_general, one);
+        MAYBE_ADD_NL(list_type(FT_general, one));
+    if (todo.all_algorithms) {
+        MAYBE_ADD_NL({});
+
+        BIO_printf(bio_out, "Digests:\n");
+        list_digests(" ");
+        BIO_printf(bio_out, "\nSymmetric Ciphers:\n");
+        list_ciphers(" ");
+        BIO_printf(bio_out, "\n");
+        list_kdfs();
+        BIO_printf(bio_out, "\n");
+        list_macs();
+
+        BIO_printf(bio_out, "\nProvided Asymmetric Encryption:\n");
+        list_asymciphers();
+        BIO_printf(bio_out, "\nProvided Key Exchange:\n");
+        list_keyexchanges();
+        BIO_printf(bio_out, "\nProvided Signatures:\n");
+        list_signatures();
+        BIO_printf(bio_out, "\nProvided Key encapsulation:\n");
+        list_kems();
+        BIO_printf(bio_out, "\nProvided Key managers:\n");
+        list_keymanagers();
+
+        BIO_printf(bio_out, "\n");
+        list_encoders();
+        BIO_printf(bio_out, "\n");
+        list_decoders();
+        BIO_printf(bio_out, "\n");
+        list_store_loaders();
+    }
     if (todo.random_instances)
-        list_random_instances();
+        MAYBE_ADD_NL(list_random_instances());
     if (todo.random_generators)
-        list_random_generators();
+        MAYBE_ADD_NL(list_random_generators());
     if (todo.digest_commands)
-        list_type(FT_md, one);
+        MAYBE_ADD_NL(list_type(FT_md, one));
     if (todo.digest_algorithms)
-        list_digests();
+        MAYBE_ADD_NL(list_digests(""));
     if (todo.kdf_algorithms)
-        list_kdfs();
+        MAYBE_ADD_NL(list_kdfs());
     if (todo.mac_algorithms)
-        list_macs();
+        MAYBE_ADD_NL(list_macs());
     if (todo.cipher_commands)
-        list_type(FT_cipher, one);
+        MAYBE_ADD_NL(list_type(FT_cipher, one));
     if (todo.cipher_algorithms)
-        list_ciphers();
+        MAYBE_ADD_NL(list_ciphers(""));
     if (todo.encoder_algorithms)
-        list_encoders();
+        MAYBE_ADD_NL(list_encoders());
     if (todo.decoder_algorithms)
-        list_decoders();
+        MAYBE_ADD_NL(list_decoders());
     if (todo.keymanager_algorithms)
-        list_keymanagers();
+        MAYBE_ADD_NL(list_keymanagers());
     if (todo.signature_algorithms)
-        list_signatures();
+        MAYBE_ADD_NL(list_signatures());
     if (todo.asym_cipher_algorithms)
-        list_asymciphers();
+        MAYBE_ADD_NL(list_asymciphers());
     if (todo.keyexchange_algorithms)
-        list_keyexchanges();
+        MAYBE_ADD_NL(list_keyexchanges());
     if (todo.kem_algorithms)
-        list_kems();
+        MAYBE_ADD_NL(list_kems());
     if (todo.pk_algorithms)
-        list_pkey();
+        MAYBE_ADD_NL(list_pkey());
     if (todo.pk_method)
-        list_pkey_meth();
+        MAYBE_ADD_NL(list_pkey_meth());
     if (todo.store_loaders)
-        list_store_loaders();
+        MAYBE_ADD_NL(list_store_loaders());
     if (todo.provider_info)
-        list_provider_info();
+        MAYBE_ADD_NL(list_provider_info());
 #ifndef OPENSSL_NO_DEPRECATED_3_0
     if (todo.engines)
-        list_engines();
+        MAYBE_ADD_NL(list_engines());
 #endif
     if (todo.disabled)
-        list_disabled();
+        MAYBE_ADD_NL(list_disabled());
     if (todo.objects)
-        list_objects();
+        MAYBE_ADD_NL(list_objects());
+
+#undef MAYBE_ADD_NL
 
     if (!done)
         goto opthelp;

+ 4 - 5
libs/openssl/apps/mac.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -137,10 +137,9 @@ opthelp:
     }
 
     /* One argument, the MAC name. */
-    argc = opt_num_rest();
-    argv = opt_rest();
-    if (argc != 1)
+    if (!opt_check_rest_arg("MAC name"))
         goto opthelp;
+    argv = opt_rest();
 
     mac = EVP_MAC_fetch(app_get0_libctx(), argv[0], app_get0_propq());
     if (mac == NULL) {
@@ -218,7 +217,7 @@ opthelp:
         for (i = 0; i < (int)len; ++i)
             BIO_printf(out, "%02X", buf[i]);
         if (outfile == NULL)
-            BIO_printf(out,"\n");
+            BIO_printf(out, "\n");
     }
 
     ret = 0;

+ 1 - 2
libs/openssl/apps/nseq.c

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

+ 32 - 26
libs/openssl/apps/ocsp.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -76,7 +76,7 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req
 
 static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
 static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio,
-                        const char *port, int timeout);
+                        int timeout);
 static int send_ocsp_response(BIO *cbio, const OCSP_RESPONSE *resp);
 static char *prog;
 
@@ -136,7 +136,7 @@ const OPTIONS ocsp_options[] = {
      "Don't include any certificates in signed request"},
     {"badsig", OPT_BADSIG, '-',
         "Corrupt last byte of loaded OCSP response signature (for test)"},
-    {"CA", OPT_CA, '<', "CA certificate"},
+    {"CA", OPT_CA, '<', "CA certificates"},
     {"nmin", OPT_NMIN, 'p', "Number of minutes before next update"},
     {"nrequest", OPT_REQUEST, 'p',
      "Number of requests to accept (default unlimited)"},
@@ -196,8 +196,10 @@ const OPTIONS ocsp_options[] = {
     {"VAfile", OPT_VAFILE, '<', "Validator certificates file"},
     {"verify_other", OPT_VERIFY_OTHER, '<',
      "Additional certificates to search for signer"},
-    {"cert", OPT_CERT, '<', "Certificate to check"},
-    {"serial", OPT_SERIAL, 's', "Serial number to check"},
+    {"cert", OPT_CERT, '<',
+     "Certificate to check; may be given multiple times"},
+    {"serial", OPT_SERIAL, 's',
+     "Serial number to check; may be given multiple times"},
     {"validity_period", OPT_VALIDITY_PERIOD, 'u',
      "Maximum validity discrepancy in seconds"},
     {"signkey", OPT_SIGNKEY, 's', "Private key to sign OCSP request with"},
@@ -228,7 +230,7 @@ int ocsp_main(int argc, char **argv)
     STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
     STACK_OF(X509) *issuers = NULL;
     X509 *issuer = NULL, *cert = NULL;
-    STACK_OF(X509) *rca_cert = NULL;
+    STACK_OF(X509) *rca_certs = NULL;
     EVP_MD *resp_certid_md = NULL;
     X509 *signer = NULL, *rsigner = NULL;
     X509_STORE *store = NULL;
@@ -261,6 +263,7 @@ int ocsp_main(int argc, char **argv)
             || (vpm = X509_VERIFY_PARAM_new()) == NULL)
         goto end;
 
+    opt_set_unknown_name("digest");
     prog = opt_init(argc, argv, ocsp_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -436,6 +439,7 @@ int ocsp_main(int argc, char **argv)
                 goto end;
             break;
         case OPT_CERT:
+            reset_unknown();
             X509_free(cert);
             cert = load_cert(opt_arg(), FORMAT_UNDEF, "certificate");
             if (cert == NULL)
@@ -449,6 +453,7 @@ int ocsp_main(int argc, char **argv)
             trailing_md = 0;
             break;
         case OPT_SERIAL:
+            reset_unknown();
             if (cert_id_md == NULL)
                 cert_id_md = (EVP_MD *)EVP_sha1();
             if (!add_ocsp_serial(&req, opt_arg(), cert_id_md, issuer, ids))
@@ -524,7 +529,7 @@ int ocsp_main(int argc, char **argv)
             break;
         case OPT_MULTI:
 #ifdef HTTP_DAEMON
-            multi = atoi(opt_arg());
+            n_responders = atoi(opt_arg());
 #endif
             break;
         case OPT_PROV_CASES:
@@ -535,8 +540,7 @@ int ocsp_main(int argc, char **argv)
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     if (trailing_md) {
@@ -576,7 +580,7 @@ int ocsp_main(int argc, char **argv)
 
     if (req == NULL && port != NULL) {
 #ifndef OPENSSL_NO_SOCK
-        acbio = http_server_init_bio(prog, port);
+        acbio = http_server_init(prog, port, -1);
         if (acbio == NULL)
             goto end;
 #else
@@ -593,7 +597,7 @@ int ocsp_main(int argc, char **argv)
             BIO_printf(bio_err, "Error loading responder certificate\n");
             goto end;
         }
-        if (!load_certs(rca_filename, 0, &rca_cert, NULL, "CA certificates"))
+        if (!load_certs(rca_filename, 0, &rca_certs, NULL, "CA certificates"))
             goto end;
         if (rcertfile != NULL) {
             if (!load_certs(rcertfile, 0, &rother, NULL,
@@ -611,7 +615,7 @@ int ocsp_main(int argc, char **argv)
     }
 
     if (ridx_filename != NULL
-        && (rkey == NULL || rsigner == NULL || rca_cert == NULL)) {
+        && (rkey == NULL || rsigner == NULL || rca_certs == NULL)) {
         BIO_printf(bio_err,
                    "Responder mode requires certificate, key, and CA.\n");
         goto end;
@@ -629,14 +633,15 @@ int ocsp_main(int argc, char **argv)
     }
 
 #ifdef HTTP_DAEMON
-    if (multi && acbio != NULL)
+    if (n_responders != 0 && acbio != NULL)
         spawn_loop(prog);
     if (acbio != NULL && req_timeout > 0)
         signal(SIGALRM, socket_timeout);
 #endif
 
     if (acbio != NULL)
-        log_message(prog, LOG_INFO, "waiting for OCSP client connections...");
+        trace_log_message(-1, prog,
+                          LOG_INFO, "waiting for OCSP client connections...");
 
 redo_accept:
 
@@ -650,14 +655,15 @@ redo_accept:
                 rdb = newrdb;
             } else {
                 free_index(newrdb);
-                log_message(prog, LOG_ERR, "error reloading updated index: %s",
-                            ridx_filename);
+                trace_log_message(-1, prog,
+                                  LOG_ERR, "error reloading updated index: %s",
+                                  ridx_filename);
             }
         }
 #endif
 
         req = NULL;
-        res = do_responder(&req, &cbio, acbio, port, req_timeout);
+        res = do_responder(&req, &cbio, acbio, req_timeout);
         if (res == 0)
             goto redo_accept;
 
@@ -721,7 +727,7 @@ redo_accept:
     }
 
     if (rdb != NULL) {
-        make_ocsp_response(bio_err, &resp, req, rdb, rca_cert, rsigner, rkey,
+        make_ocsp_response(bio_err, &resp, req, rdb, rca_certs, rsigner, rkey,
                            rsign_md, rsign_sigopts, rother, rflags, nmin, ndays,
                            badsig, resp_certid_md);
         if (resp == NULL)
@@ -858,9 +864,9 @@ redo_accept:
     EVP_MD_free(rsign_md);
     EVP_MD_free(resp_certid_md);
     X509_free(cert);
-    sk_X509_pop_free(issuers, X509_free);
+    OSSL_STACK_OF_X509_free(issuers);
     X509_free(rsigner);
-    sk_X509_pop_free(rca_cert, X509_free);
+    OSSL_STACK_OF_X509_free(rca_certs);
     free_index(rdb);
     BIO_free_all(cbio);
     BIO_free_all(acbio);
@@ -870,8 +876,8 @@ redo_accept:
     OCSP_BASICRESP_free(bs);
     sk_OPENSSL_STRING_free(reqnames);
     sk_OCSP_CERTID_free(ids);
-    sk_X509_pop_free(sign_other, X509_free);
-    sk_X509_pop_free(verify_other, X509_free);
+    OSSL_STACK_OF_X509_free(sign_other);
+    OSSL_STACK_OF_X509_free(verify_other);
     sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
     OPENSSL_free(thost);
     OPENSSL_free(tport);
@@ -1139,7 +1145,7 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req
     OCSP_copy_nonce(bs, req);
 
     mctx = EVP_MD_CTX_new();
-    if ( mctx == NULL || !EVP_DigestSignInit(mctx, &pkctx, rmd, NULL, rkey)) {
+    if (mctx == NULL || !EVP_DigestSignInit(mctx, &pkctx, rmd, NULL, rkey)) {
         *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, NULL);
         goto end;
     }
@@ -1197,13 +1203,13 @@ static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser)
 }
 
 static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio,
-                        const char *port, int timeout)
+                        int timeout)
 {
 #ifndef OPENSSL_NO_SOCK
     return http_server_get_asn1_req(ASN1_ITEM_rptr(OCSP_REQUEST),
                                     (ASN1_VALUE **)preq, NULL, pcbio, acbio,
                                     NULL /* found_keep_alive */,
-                                    prog, port, 1 /* accept_get */, timeout);
+                                    prog, 1 /* accept_get */, timeout);
 #else
     BIO_printf(bio_err,
                "Error getting OCSP request - sockets not supported\n");
@@ -1215,7 +1221,7 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio,
 static int send_ocsp_response(BIO *cbio, const OCSP_RESPONSE *resp)
 {
 #ifndef OPENSSL_NO_SOCK
-    return http_server_send_asn1_resp(cbio,
+    return http_server_send_asn1_resp(prog, cbio,
                                       0 /* no keep-alive */,
                                       "application/ocsp-response",
                                       ASN1_ITEM_rptr(OCSP_RESPONSE),

+ 2 - 2
libs/openssl/apps/openssl-vms.cnf

@@ -330,8 +330,8 @@ tsa_name		= yes	# Must the TSA name be included in the reply?
 				# (optional, default: no)
 ess_cert_id_chain	= no	# Must the ESS cert id chain be included?
 				# (optional, default: no)
-ess_cert_id_alg		= sha1	# algorithm to compute certificate
-				# identifier (optional, default: sha1)
+ess_cert_id_alg		= sha256	# algorithm to compute certificate
+				# identifier (optional, default: sha256)
 
 [insta] # CMP using Insta Demo CA
 # Message transfer

+ 23 - 15
libs/openssl/apps/openssl.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -8,8 +8,8 @@
  */
 
 #include <stdio.h>
-#include <string.h>
 #include <stdlib.h>
+#include "internal/common.h"
 #include <openssl/bio.h>
 #include <openssl/crypto.h>
 #include <openssl/trace.h>
@@ -157,8 +157,6 @@ static void tracedata_free(tracedata *data)
     OPENSSL_free(data);
 }
 
-static STACK_OF(tracedata) *trace_data_stack;
-
 static void cleanup_trace(void)
 {
     sk_tracedata_pop_free(trace_data_stack, tracedata_free);
@@ -232,6 +230,7 @@ static void setup_trace(const char *str)
 #endif /* OPENSSL_NO_TRACE */
 
 static char *help_argv[] = { "help", NULL };
+static char *version_argv[] = { "version", NULL };
 
 int main(int argc, char *argv[])
 {
@@ -241,6 +240,7 @@ int main(int argc, char *argv[])
     const char *fname;
     ARGS arg;
     int global_help = 0;
+    int global_version = 0;
     int ret = 0;
 
     arg.argv = NULL;
@@ -285,17 +285,26 @@ int main(int argc, char *argv[])
         global_help = argc > 1
             && (strcmp(argv[1], "-help") == 0 || strcmp(argv[1], "--help") == 0
                 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--h") == 0);
+        global_version = argc > 1
+            && (strcmp(argv[1], "-version") == 0 || strcmp(argv[1], "--version") == 0
+                || strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--v") == 0);
+
         argc--;
         argv++;
-        opt_appname(argc == 1 || global_help ? "help" : argv[0]);
+        opt_appname(argc == 1 || global_help ? "help" : global_version ? "version" : argv[0]);
     } else {
         argv[0] = pname;
     }
 
-    /* If there's a command, run with that, otherwise "help". */
-    ret = argc == 0 || global_help
-        ? do_cmd(prog, 1, help_argv)
-        : do_cmd(prog, argc, argv);
+    /*
+     * If there's no command, assume "help". If there's an override for help
+     * or version run those, otherwise run the command given.
+     */
+    ret =  (argc == 0) || global_help
+            ? do_cmd(prog, 1, help_argv)
+            : global_version
+                ? do_cmd(prog, 1, version_argv)
+                : do_cmd(prog, argc, argv);
 
  end:
     OPENSSL_free(default_config_file);
@@ -326,7 +335,6 @@ const OPTIONS help_options[] = {
     {NULL}
 };
 
-
 int help_main(int argc, char **argv)
 {
     FUNCTION *fp;
@@ -357,7 +365,7 @@ int help_main(int argc, char **argv)
         new_argv[2] = NULL;
         return do_cmd(prog_init(), 2, new_argv);
     }
-    if (opt_num_rest() != 0) {
+    if (!opt_check_rest_arg(NULL)) {
         BIO_printf(bio_err, "Usage: %s\n", prog);
         return 1;
     }
@@ -417,12 +425,12 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
             warn_deprecated(fp);
         return fp->func(argc, argv);
     }
-    if ((strncmp(argv[0], "no-", 3)) == 0) {
+    f.name = argv[0];
+    if (CHECK_AND_SKIP_PREFIX(f.name, "no-")) {
         /*
          * User is asking if foo is unsupported, by trying to "run" the
          * no-foo command.  Strange.
          */
-        f.name = argv[0] + 3;
         if (lh_FUNCTION_retrieve(prog, &f) == NULL) {
             BIO_printf(bio_out, "%s\n", argv[0]);
             return 0;
@@ -436,12 +444,12 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
     return 1;
 }
 
-static int function_cmp(const FUNCTION * a, const FUNCTION * b)
+static int function_cmp(const FUNCTION *a, const FUNCTION *b)
 {
     return strncmp(a->name, b->name, 8);
 }
 
-static unsigned long function_hash(const FUNCTION * a)
+static unsigned long function_hash(const FUNCTION *a)
 {
     return OPENSSL_LH_strhash(a->name);
 }

+ 2 - 2
libs/openssl/apps/openssl.cnf

@@ -330,8 +330,8 @@ tsa_name		= yes	# Must the TSA name be included in the reply?
 				# (optional, default: no)
 ess_cert_id_chain	= no	# Must the ESS cert id chain be included?
 				# (optional, default: no)
-ess_cert_id_alg		= sha1	# algorithm to compute certificate
-				# identifier (optional, default: sha1)
+ess_cert_id_alg		= sha256	# algorithm to compute certificate
+				# identifier (optional, default: sha256)
 
 [insta] # CMP using Insta Demo CA
 # Message transfer

+ 1 - 1
libs/openssl/apps/passwd.c

@@ -601,7 +601,7 @@ static char *shacrypt(const char *passwd, const char *magic, const char *salt)
     OPENSSL_strlcat(out_buf, ascii_salt, sizeof(out_buf));
 
     /* assert "$5$rounds=999999999$......salt......" */
-    if (strlen(out_buf) > 3 + 17 * rounds_custom + salt_len )
+    if (strlen(out_buf) > 3 + 17 * rounds_custom + salt_len)
         goto err;
 
     md = EVP_MD_CTX_new();

+ 94 - 29
libs/openssl/apps/pkcs12.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -14,12 +14,15 @@
 #include <string.h>
 #include "apps.h"
 #include "progs.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
 #include <openssl/crypto.h>
 #include <openssl/err.h>
 #include <openssl/pem.h>
 #include <openssl/pkcs12.h>
 #include <openssl/provider.h>
 #include <openssl/kdf.h>
+#include <openssl/rand.h>
 
 #define NOKEYS          0x1
 #define NOCERTS         0x2
@@ -53,6 +56,7 @@ void hex_prin(BIO *out, unsigned char *buf, int len);
 static int alg_print(const X509_ALGOR *alg);
 int cert_load(BIO *in, STACK_OF(X509) *sk);
 static int set_pbe(int *ppbe, const char *str);
+static int jdk_trust(PKCS12_SAFEBAG *bag, void *cbarg);
 
 typedef enum OPTION_choice {
     OPT_COMMON,
@@ -61,13 +65,13 @@ typedef enum OPTION_choice {
 #ifndef OPENSSL_NO_DES
     OPT_DESCERT,
 #endif
-    OPT_EXPORT, OPT_ITER, OPT_NOITER, OPT_MACITER, OPT_NOMACITER,
+    OPT_EXPORT, OPT_ITER, OPT_NOITER, OPT_MACITER, OPT_NOMACITER, OPT_MACSALTLEN,
     OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_NOENC, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE,
     OPT_INKEY, OPT_CERTFILE, OPT_UNTRUSTED, OPT_PASSCERTS,
     OPT_NAME, OPT_CSP, OPT_CANAME,
     OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH,
     OPT_CAFILE, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_ENGINE,
-    OPT_R_ENUM, OPT_PROV_ENUM,
+    OPT_R_ENUM, OPT_PROV_ENUM, OPT_JDKTRUST,
 #ifndef OPENSSL_NO_DES
     OPT_LEGACY_ALG
 #endif
@@ -148,23 +152,27 @@ const OPTIONS pkcs12_options[] = {
     {"noiter", OPT_NOITER, '-', "Don't use encryption iteration"},
     {"nomaciter", OPT_NOMACITER, '-', "Don't use MAC iteration)"},
     {"maciter", OPT_MACITER, '-', "Unused, kept for backwards compatibility"},
+    {"macsaltlen", OPT_MACSALTLEN, 'p', "Specify the salt len for MAC"},
     {"nomac", OPT_NOMAC, '-', "Don't generate MAC"},
+    {"jdktrust", OPT_JDKTRUST, 's', "Mark certificate in PKCS#12 store as trusted for JDK compatibility"},
     {NULL}
 };
 
 int pkcs12_main(int argc, char **argv)
 {
     char *infile = NULL, *outfile = NULL, *keyname = NULL, *certfile = NULL;
-    char *untrusted = NULL, *ciphername = NULL, *enc_flag = NULL;
+    char *untrusted = NULL, *ciphername = NULL, *enc_name = NULL;
     char *passcertsarg = NULL, *passcerts = NULL;
     char *name = NULL, *csp_name = NULL;
     char pass[PASSWD_BUF_SIZE] = "", macpass[PASSWD_BUF_SIZE] = "";
     int export_pkcs12 = 0, options = 0, chain = 0, twopass = 0, keytype = 0;
+    char *jdktrust = NULL;
 #ifndef OPENSSL_NO_DES
     int use_legacy = 0;
 #endif
     /* use library defaults for the iter, maciter, cert, and key PBE */
     int iter = 0, maciter = 0;
+    int macsaltlen = PKCS12_SALT_LEN;
     int cert_pbe = NID_undef;
     int key_pbe = NID_undef;
     int ret = 1, macver = 1, add_lmk = 0, private = 0;
@@ -182,6 +190,7 @@ int pkcs12_main(int argc, char **argv)
     EVP_CIPHER *enc = (EVP_CIPHER *)default_enc;
     OPTION_CHOICE o;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, pkcs12_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -215,6 +224,11 @@ int pkcs12_main(int argc, char **argv)
         case OPT_NOOUT:
             options |= (NOKEYS | NOCERTS);
             break;
+        case OPT_JDKTRUST:
+            jdktrust = opt_arg();
+            /* Adding jdk trust implies nokeys */
+            options |= NOKEYS;
+            break;
         case OPT_INFO:
             options |= INFO;
             break;
@@ -238,16 +252,15 @@ int pkcs12_main(int argc, char **argv)
         case OPT_NODES:
         case OPT_NOENC:
             /*
-             * |enc_flag| stores the name of the option used so it
+             * |enc_name| stores the name of the option used so it
              * can be printed if an error message is output.
              */
-            enc_flag = opt_flag() + 1;
+            enc_name = opt_flag() + 1;
             enc = NULL;
             ciphername = NULL;
             break;
         case OPT_CIPHER:
-            ciphername = opt_unknown();
-            enc_flag = opt_unknown();
+            enc_name = ciphername = opt_unknown();
             break;
         case OPT_ITER:
             maciter = iter = opt_int_arg();
@@ -261,6 +274,9 @@ int pkcs12_main(int argc, char **argv)
         case OPT_NOMACITER:
             maciter = 1;
             break;
+        case OPT_MACSALTLEN:
+            macsaltlen = opt_int_arg();
+            break;
         case OPT_NOMAC:
             cert_pbe = -1;
             maciter = -1;
@@ -356,17 +372,14 @@ int pkcs12_main(int argc, char **argv)
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     if (!app_RAND_load())
         goto end;
 
-    if (ciphername != NULL) {
-        if (!opt_cipher_any(ciphername, &enc))
-            goto opthelp;
-    }
+    if (!opt_cipher_any(ciphername, &enc))
+        goto opthelp;
     if (export_pkcs12) {
         if ((options & INFO) != 0)
             WARN_EXPORT("info");
@@ -378,7 +391,7 @@ int pkcs12_main(int argc, char **argv)
             WARN_EXPORT("cacerts");
         if (enc != default_enc)
             BIO_printf(bio_err,
-                       "Warning: output encryption option -%s ignored with -export\n", enc_flag);
+                       "Warning: output encryption option -%s ignored with -export\n", enc_name);
     } else {
         if (keyname != NULL)
             WARN_NO_EXPORT("inkey");
@@ -426,6 +439,8 @@ int pkcs12_main(int argc, char **argv)
             WARN_NO_EXPORT("nomaciter");
         if (cert_pbe == -1 && maciter == -1)
             WARN_NO_EXPORT("nomac");
+        if (macsaltlen != PKCS12_SALT_LEN)
+            WARN_NO_EXPORT("macsaltlen");
     }
 #ifndef OPENSSL_NO_DES
     if (use_legacy) {
@@ -520,6 +535,8 @@ int pkcs12_main(int argc, char **argv)
         EVP_MD *macmd = NULL;
         unsigned char *catmp = NULL;
         int i;
+        CONF *conf = NULL;
+        ASN1_OBJECT *obj = NULL;
 
         if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) {
             BIO_printf(bio_err, "Nothing to export due to -noout or -nocerts and -nokeys\n");
@@ -555,7 +572,7 @@ int pkcs12_main(int argc, char **argv)
                 /* Look for matching private key */
                 for (i = 0; i < sk_X509_num(certs); i++) {
                     x = sk_X509_value(certs, i);
-                    if (X509_check_private_key(x, key)) {
+                    if (cert_matches_key(x, key)) {
                         ee_cert = x;
                         /* Zero keyid and alias */
                         X509_keyid_set1(ee_cert, NULL, 0);
@@ -613,7 +630,7 @@ int pkcs12_main(int argc, char **argv)
                 /* Add the remaining certs (except for duplicates) */
                 add_certs = X509_add_certs(certs, chain2, X509_ADD_FLAG_UP_REF
                                            | X509_ADD_FLAG_NO_DUP);
-                sk_X509_pop_free(chain2, X509_free);
+                OSSL_STACK_OF_X509_free(chain2);
                 if (!add_certs)
                     goto export_end;
             } else {
@@ -664,9 +681,20 @@ int pkcs12_main(int argc, char **argv)
         if (!twopass)
             OPENSSL_strlcpy(macpass, pass, sizeof(macpass));
 
-        p12 = PKCS12_create_ex(cpass, name, key, ee_cert, certs,
-                               key_pbe, cert_pbe, iter, -1, keytype,
-                               app_get0_libctx(), app_get0_propq());
+        /* Load the config file */
+        if ((conf = app_load_config(default_config_file)) == NULL)
+            goto export_end;
+        if (!app_load_modules(conf))
+            goto export_end;
+
+        if (jdktrust != NULL) {
+            obj = OBJ_txt2obj(jdktrust, 0);
+        }
+
+        p12 = PKCS12_create_ex2(cpass, name, key, ee_cert, certs,
+                                key_pbe, cert_pbe, iter, -1, keytype,
+                                app_get0_libctx(), app_get0_propq(),
+                                jdk_trust, (void*)obj);
 
         if (p12 == NULL) {
             BIO_printf(bio_err, "Error creating PKCS12 structure for %s\n",
@@ -679,13 +707,13 @@ int pkcs12_main(int argc, char **argv)
                 goto opthelp;
         }
 
-        if (maciter != -1)
-            if (!PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd)) {
+        if (maciter != -1) {
+            if (!PKCS12_set_mac(p12, mpass, -1, NULL, macsaltlen, maciter, macmd)) {
                 BIO_printf(bio_err, "Error creating PKCS12 MAC; no PKCS12KDF support?\n");
                 BIO_printf(bio_err, "Use -nomac if MAC not required and PKCS12KDF support not available.\n");
                 goto export_end;
             }
-
+        }
         assert(private);
 
         out = bio_open_owner(outfile, FORMAT_PKCS12, private);
@@ -700,10 +728,11 @@ int pkcs12_main(int argc, char **argv)
 
         EVP_PKEY_free(key);
         EVP_MD_free(macmd);
-        sk_X509_pop_free(certs, X509_free);
-        sk_X509_pop_free(untrusted_certs, X509_free);
+        OSSL_STACK_OF_X509_free(certs);
+        OSSL_STACK_OF_X509_free(untrusted_certs);
         X509_free(ee_cert);
-
+        NCONF_free(conf);
+        ASN1_OBJECT_free(obj);
         ERR_print_errors(bio_err);
         goto end;
 
@@ -833,12 +862,36 @@ int pkcs12_main(int argc, char **argv)
     return ret;
 }
 
+static int jdk_trust(PKCS12_SAFEBAG *bag, void *cbarg)
+{
+    STACK_OF(X509_ATTRIBUTE) *attrs = NULL;
+    X509_ATTRIBUTE *attr = NULL;
+
+    /* Nothing to do */
+    if (cbarg == NULL)
+        return 1;
+
+    /* Get the current attrs */
+    attrs = (STACK_OF(X509_ATTRIBUTE)*)PKCS12_SAFEBAG_get0_attrs(bag);
+
+    /* Create a new attr for the JDK Trusted Usage and add it */
+    attr = X509_ATTRIBUTE_create(NID_oracle_jdk_trustedkeyusage, V_ASN1_OBJECT, (ASN1_OBJECT*)cbarg);
+
+    /* Add the new attr, if attrs is NULL, it'll be initialised */
+    X509at_add1_attr(&attrs, attr);
+
+    /* Set the bag attrs */
+    PKCS12_SAFEBAG_set0_attrs(bag, attrs);
+
+    X509_ATTRIBUTE_free(attr);
+    return 1;
+}
+
 int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass,
                         int passlen, int options, char *pempass,
                         const EVP_CIPHER *enc)
 {
     STACK_OF(PKCS7) *asafes = NULL;
-    STACK_OF(PKCS12_SAFEBAG) *bags;
     int i, bagnid;
     int ret = 0;
     PKCS7 *p7;
@@ -846,6 +899,8 @@ int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass,
     if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
         return 0;
     for (i = 0; i < sk_PKCS7_num(asafes); i++) {
+        STACK_OF(PKCS12_SAFEBAG) *bags;
+
         p7 = sk_PKCS7_value(asafes, i);
         bagnid = OBJ_obj2nid(p7->type);
         if (bagnid == NID_pkcs7_data) {
@@ -861,7 +916,7 @@ int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass,
         } else {
             continue;
         }
-        if (!bags)
+        if (bags == NULL)
             goto err;
         if (!dump_certs_pkeys_bags(out, bags, pass, passlen,
                                    options, pempass, enc)) {
@@ -869,7 +924,6 @@ int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass,
             goto err;
         }
         sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
-        bags = NULL;
     }
     ret = 1;
 
@@ -1132,6 +1186,8 @@ int cert_load(BIO *in, STACK_OF(X509) *sk)
 void print_attribute(BIO *out, const ASN1_TYPE *av)
 {
     char *value;
+    const char *ln;
+    char objbuf[80];
 
     switch (av->type) {
     case V_ASN1_BMPSTRING:
@@ -1158,6 +1214,15 @@ void print_attribute(BIO *out, const ASN1_TYPE *av)
         BIO_printf(out, "\n");
         break;
 
+    case V_ASN1_OBJECT:
+        ln = OBJ_nid2ln(OBJ_obj2nid(av->value.object));
+        if (!ln)
+            ln = "";
+        OBJ_obj2txt(objbuf, sizeof(objbuf), av->value.object, 1);
+        BIO_printf(out, "%s (%s)", ln, objbuf);
+        BIO_printf(out, "\n");
+        break;
+
     default:
         BIO_printf(out, "<Unsupported tag %d>\n", av->type);
         break;

+ 11 - 7
libs/openssl/apps/pkcs7.c

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

+ 16 - 7
libs/openssl/apps/pkcs8.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -17,6 +17,9 @@
 #include <openssl/evp.h>
 #include <openssl/pkcs12.h>
 
+#define STR(a) XSTR(a)
+#define XSTR(a) #a
+
 typedef enum OPTION_choice {
     OPT_COMMON,
     OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT,
@@ -26,6 +29,7 @@ typedef enum OPTION_choice {
 #endif
     OPT_V2, OPT_V1, OPT_V2PRF, OPT_ITER, OPT_PASSIN, OPT_PASSOUT,
     OPT_TRADITIONAL,
+    OPT_SALTLEN,
     OPT_R_ENUM, OPT_PROV_ENUM
 } OPTION_CHOICE;
 
@@ -53,7 +57,8 @@ const OPTIONS pkcs8_options[] = {
     {"traditional", OPT_TRADITIONAL, '-', "use traditional format private key"},
     {"iter", OPT_ITER, 'p', "Specify the iteration count"},
     {"noiter", OPT_NOITER, '-', "Use 1 as iteration count"},
-
+    {"saltlen", OPT_SALTLEN, 'p', "Specify the salt length (in bytes)"},
+    {OPT_MORE_STR, 0, 0, "Default: 8 (For PBE1) or 16 (for PBE2)"},
 #ifndef OPENSSL_NO_SCRYPT
     OPT_SECTION("Scrypt"),
     {"scrypt", OPT_SCRYPT, '-', "Use scrypt algorithm"},
@@ -88,6 +93,7 @@ int pkcs8_main(int argc, char **argv)
 #ifndef OPENSSL_NO_SCRYPT
     long scrypt_N = 0, scrypt_r = 0, scrypt_p = 0;
 #endif
+    int saltlen = 0; /* A value of zero chooses the default */
 
     prog = opt_init(argc, argv, pkcs8_options);
     while ((o = opt_next()) != OPT_EOF) {
@@ -189,12 +195,15 @@ int pkcs8_main(int argc, char **argv)
                 goto opthelp;
             break;
 #endif
+        case OPT_SALTLEN:
+            if (!opt_int(opt_arg(), &saltlen))
+                goto opthelp;
+            break;
         }
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     private = 1;
@@ -246,14 +255,14 @@ int pkcs8_main(int argc, char **argv)
             if (cipher) {
 #ifndef OPENSSL_NO_SCRYPT
                 if (scrypt_N && scrypt_r && scrypt_p)
-                    pbe = PKCS5_pbe2_set_scrypt(cipher, NULL, 0, NULL,
+                    pbe = PKCS5_pbe2_set_scrypt(cipher, NULL, saltlen, NULL,
                                                 scrypt_N, scrypt_r, scrypt_p);
                 else
 #endif
-                    pbe = PKCS5_pbe2_set_iv(cipher, iter, NULL, 0, NULL,
+                    pbe = PKCS5_pbe2_set_iv(cipher, iter, NULL, saltlen, NULL,
                                             pbe_nid);
             } else {
-                pbe = PKCS5_pbe_set(pbe_nid, iter, NULL, 0);
+                pbe = PKCS5_pbe_set(pbe_nid, iter, NULL, saltlen);
             }
             if (pbe == NULL) {
                 BIO_printf(bio_err, "Error setting PBE algorithm\n");

+ 4 - 6
libs/openssl/apps/pkey.c

@@ -83,6 +83,7 @@ int pkey_main(int argc, char **argv)
     char *point_format = NULL;
 #endif
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, pkey_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -171,8 +172,7 @@ int pkey_main(int argc, char **argv)
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     if (text && text_pub)
@@ -190,10 +190,8 @@ int pkey_main(int argc, char **argv)
 
     private = (!noout && !pubout) || (text && !text_pub);
 
-    if (ciphername != NULL) {
-        if (!opt_cipher(ciphername, &cipher))
-            goto opthelp;
-    }
+    if (!opt_cipher(ciphername, &cipher))
+        goto opthelp;
     if (cipher == NULL) {
         if (passoutarg != NULL)
             BIO_printf(bio_err,

+ 2 - 3
libs/openssl/apps/pkeyparam.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -91,8 +91,7 @@ int pkeyparam_main(int argc, char **argv)
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     in = bio_open_default(infile, 'r', FORMAT_PEM);

+ 5 - 6
libs/openssl/apps/pkeyutl.c

@@ -69,8 +69,8 @@ const OPTIONS pkeyutl_options[] = {
     OPT_SECTION("Input"),
     {"in", OPT_IN, '<', "Input file - default stdin"},
     {"rawin", OPT_RAWIN, '-', "Indicate the input data is in raw form"},
-    {"pubin", OPT_PUBIN, '-', "Input is a public key"},
-    {"inkey", OPT_INKEY, 's', "Input private key file"},
+    {"inkey", OPT_INKEY, 's', "Input key, by default private key"},
+    {"pubin", OPT_PUBIN, '-', "Input key is a public key"},
     {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
     {"peerkey", OPT_PEERKEY, 's', "Peer key file used in key derivation"},
     {"peerform", OPT_PEERFORM, 'E', "Peer key format (DER/PEM/P12/ENGINE)"},
@@ -253,8 +253,7 @@ int pkeyutl_main(int argc, char **argv)
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     if (!app_RAND_load())
@@ -729,7 +728,7 @@ static int do_raw_keyop(int pkey_op, EVP_MD_CTX *mctx,
             goto end;
         }
         mbuf = app_malloc(filesize, "oneshot sign/verify buffer");
-        switch(pkey_op) {
+        switch (pkey_op) {
         case EVP_PKEY_OP_VERIFY:
             buf_len = BIO_read(in, mbuf, filesize);
             if (buf_len != filesize) {
@@ -754,7 +753,7 @@ static int do_raw_keyop(int pkey_op, EVP_MD_CTX *mctx,
         goto end;
     }
 
-    switch(pkey_op) {
+    switch (pkey_op) {
     case EVP_PKEY_OP_VERIFY:
         for (;;) {
             buf_len = BIO_read(in, tbuf, TBUF_MAXSIZE);

+ 25 - 10
libs/openssl/apps/prime.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2004-2022 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -19,6 +19,23 @@ typedef enum OPTION_choice {
     OPT_PROV_ENUM
 } OPTION_CHOICE;
 
+static int check_num(const char *s, const int is_hex)
+{
+    int i;
+    /*
+     * It would make sense to use ossl_isxdigit and ossl_isdigit here,
+     * but ossl_ctype_check is a local symbol in libcrypto.so.
+     */
+    if (is_hex) {
+        for (i = 0; ('0' <= s[i] && s[i] <= '9')
+                    || ('A' <= s[i] && s[i] <= 'F')
+                    || ('a' <= s[i] && s[i] <= 'f'); i++);
+    } else {
+        for (i = 0;  '0' <= s[i] && s[i] <= '9'; i++);
+    }
+    return s[i] == 0;
+}
+
 const OPTIONS prime_options[] = {
     {OPT_HELP_STR, 1, '-', "Usage: %s [options] [number...]\n"},
 
@@ -83,12 +100,12 @@ opthelp:
     }
 
     /* Optional arguments are numbers to check. */
+    if (generate && !opt_check_rest_arg(NULL))
+        goto opthelp;
     argc = opt_num_rest();
     argv = opt_rest();
-    if (generate) {
-        if (argc != 0)
-            goto opthelp;
-    } else if (argc == 0) {
+    if (!generate && argc == 0) {
+        BIO_printf(bio_err, "Missing number (s) to check\n");
         goto opthelp;
     }
 
@@ -117,12 +134,10 @@ opthelp:
         OPENSSL_free(s);
     } else {
         for ( ; *argv; argv++) {
-            int r;
+            int r = check_num(argv[0], hex);
 
-            if (hex)
-                r = BN_hex2bn(&bn, argv[0]);
-            else
-                r = BN_dec2bn(&bn, argv[0]);
+            if (r)
+                r = hex ? BN_hex2bn(&bn, argv[0]) : BN_dec2bn(&bn, argv[0]);
 
             if (!r) {
                 BIO_printf(bio_err, "Failed to process value (%s)\n", argv[0]);

+ 4 - 6
libs/openssl/apps/progs.pl

@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
-# Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the Apache License 2.0 (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -104,7 +104,7 @@ EOF
 # The format of this table is:
 #   [0] = alternative command to use instead
 #   [1] = deprecented in this version
-#   [2] = preprocessor conditional for exclusing irrespective of deprecation
+#   [2] = preprocessor conditional for excluding irrespective of deprecation
 #        rsa      => [ "pkey",      "3_0", "rsa" ],
 #        genrsa   => [ "genpkey",   "3_0", "rsa" ],
         rsautl   => [ "pkeyutl",   "3_0", "rsa" ],
@@ -188,7 +188,7 @@ EOF
         "camellia-128-cbc", "camellia-128-ecb",
         "camellia-192-cbc", "camellia-192-ecb",
         "camellia-256-cbc", "camellia-256-ecb",
-        "base64", "zlib",
+        "base64", "zlib", "brotli", "zstd",
         "des", "des3", "desx", "idea", "seed", "rc4", "rc4-40",
         "rc2", "bf", "cast", "rc5",
         "des-ecb", "des-ede", "des-ede3",
@@ -205,9 +205,7 @@ EOF
     ) {
         my $str = "    {FT_cipher, \"$cmd\", enc_main, enc_options, NULL},\n";
         (my $algo = $cmd) =~ s/-.*//g;
-        if ($cmd eq "zlib") {
-            print "#ifdef ZLIB\n${str}#endif\n";
-        } elsif (grep { $algo eq $_ } @disablables) {
+        if (grep { $algo eq $_ } @disablables) {
             print "#ifndef OPENSSL_NO_" . uc($algo) . "\n${str}#endif\n";
         } elsif (my $disabler = $cipher_disabler{$algo}) {
             print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n";

+ 10 - 9
libs/openssl/apps/rand.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -52,7 +52,9 @@ int rand_main(int argc, char **argv)
     BIO *out = NULL;
     char *outfile = NULL, *prog;
     OPTION_CHOICE o;
-    int format = FORMAT_BINARY, i, num = -1, r, ret = 1;
+    int format = FORMAT_BINARY, r, i, ret = 1, buflen = 131072;
+    long num = -1;
+    uint8_t *buf = NULL;
 
     prog = opt_init(argc, argv, rand_options);
     while ((o = opt_next()) != OPT_EOF) {
@@ -93,9 +95,9 @@ int rand_main(int argc, char **argv)
     argc = opt_num_rest();
     argv = opt_rest();
     if (argc == 1) {
-        if (!opt_int(argv[0], &num) || num <= 0)
+        if (!opt_long(argv[0], &num) || num <= 0)
             goto opthelp;
-    } else if (argc != 0) {
+    } else if (!opt_check_rest_arg(NULL)) {
         goto opthelp;
     }
 
@@ -113,13 +115,11 @@ int rand_main(int argc, char **argv)
         out = BIO_push(b64, out);
     }
 
+    buf = app_malloc(buflen, "buffer for output file");
     while (num > 0) {
-        unsigned char buf[4096];
-        int chunk;
+        long chunk;
 
-        chunk = num;
-        if (chunk > (int)sizeof(buf))
-            chunk = sizeof(buf);
+        chunk = (num > buflen) ? buflen : num;
         r = RAND_bytes(buf, chunk);
         if (r <= 0)
             goto end;
@@ -143,6 +143,7 @@ int rand_main(int argc, char **argv)
  end:
     if (ret != 0)
         ERR_print_errors(bio_err);
+    OPENSSL_free(buf);
     release_engine(e);
     BIO_free_all(out);
     return ret;

+ 18 - 15
libs/openssl/apps/rehash.c

@@ -212,11 +212,11 @@ static int handle_symlink(const char *filename, const char *fullpath)
     }
     if (filename[i++] != '.')
         return -1;
-    for (type = OSSL_NELEM(suffixes) - 1; type > 0; type--) {
-        const char *suffix = suffixes[type];
-        if (OPENSSL_strncasecmp(suffix, &filename[i], strlen(suffix)) == 0)
+    for (type = OSSL_NELEM(suffixes) - 1; type > 0; type--)
+        if (OPENSSL_strncasecmp(&filename[i],
+                                suffixes[type], strlen(suffixes[type])) == 0)
             break;
-    }
+
     i += strlen(suffixes[type]);
 
     id = strtoul(&filename[i], &endptr, 10);
@@ -355,9 +355,9 @@ static int do_dir(const char *dirname, enum Hash h)
     OPENSSL_DIR_CTX *d = NULL;
     struct stat st;
     unsigned char idmask[MAX_COLLISIONS / 8];
-    int n, numfiles, nextid, buflen, errs = 0;
+    int n, numfiles, nextid, dirlen, buflen, errs = 0;
     size_t i;
-    const char *pathsep;
+    const char *pathsep = "";
     const char *filename;
     char *buf, *copy = NULL;
     STACK_OF(OPENSSL_STRING) *files = NULL;
@@ -366,9 +366,12 @@ static int do_dir(const char *dirname, enum Hash h)
         BIO_printf(bio_err, "Skipping %s, can't write\n", dirname);
         return 1;
     }
-    buflen = strlen(dirname);
-    pathsep = (buflen && !ends_with_dirsep(dirname)) ? "/": "";
-    buflen += NAME_MAX + 1 + 1;
+    dirlen = strlen(dirname);
+    if (dirlen != 0 && !ends_with_dirsep(dirname)) {
+        pathsep = "/";
+        dirlen++;
+    }
+    buflen = dirlen + NAME_MAX + 1;
     buf = app_malloc(buflen, "filename buffer");
 
     if (verbose)
@@ -427,12 +430,12 @@ static int do_dir(const char *dirname, enum Hash h)
                     while (bit_isset(idmask, nextid))
                         nextid++;
 
-                    BIO_snprintf(buf, buflen, "%s%s%n%08x.%s%d",
-                                 dirname, pathsep, &n, bp->hash,
+                    BIO_snprintf(buf, buflen, "%s%s%08x.%s%d",
+                                 dirname, pathsep, bp->hash,
                                  suffixes[bp->type], nextid);
                     if (verbose)
                         BIO_printf(bio_out, "link %s -> %s\n",
-                                   ep->filename, &buf[n]);
+                                   ep->filename, &buf[dirlen]);
                     if (unlink(buf) < 0 && errno != ENOENT) {
                         BIO_printf(bio_err,
                                    "%s: Can't unlink %s, %s\n",
@@ -449,12 +452,12 @@ static int do_dir(const char *dirname, enum Hash h)
                     bit_set(idmask, nextid);
                 } else if (remove_links) {
                     /* Link to be deleted */
-                    BIO_snprintf(buf, buflen, "%s%s%n%08x.%s%d",
-                                 dirname, pathsep, &n, bp->hash,
+                    BIO_snprintf(buf, buflen, "%s%s%08x.%s%d",
+                                 dirname, pathsep, bp->hash,
                                  suffixes[bp->type], ep->old_id);
                     if (verbose)
                         BIO_printf(bio_out, "unlink %s\n",
-                                   &buf[n]);
+                                   &buf[dirlen]);
                     if (unlink(buf) < 0 && errno != ENOENT) {
                         BIO_printf(bio_err,
                                    "%s: Can't unlink %s, %s\n",

+ 131 - 190
libs/openssl/apps/req.c

@@ -62,7 +62,6 @@ static int add_attribute_object(X509_REQ *req, char *text, const char *def,
 static int add_DN_object(X509_NAME *n, char *text, const char *def,
                          char *value, int nid, int n_min, int n_max,
                          unsigned long chtype, int mval);
-static int genpkey_cb(EVP_PKEY_CTX *ctx);
 static int build_data(char *text, const char *def, char *value,
                       int n_min, int n_max, char *buf, const int buf_size,
                       const char *desc1, const char *desc2);
@@ -86,12 +85,12 @@ typedef enum OPTION_choice {
     OPT_KEYOUT, OPT_PASSIN, OPT_PASSOUT, OPT_NEWKEY,
     OPT_PKEYOPT, OPT_SIGOPT, OPT_VFYOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS,
     OPT_VERIFY, OPT_NOENC, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8,
-    OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT, OPT_X509,
-    OPT_CA, OPT_CAKEY,
+    OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT,
+    OPT_X509, OPT_X509V1, OPT_CA, OPT_CAKEY,
     OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL,
-    OPT_COPY_EXTENSIONS, OPT_ADDEXT, OPT_EXTENSIONS,
-    OPT_REQEXTS, OPT_PRECERT, OPT_MD,
-    OPT_SECTION,
+    OPT_COPY_EXTENSIONS, OPT_EXTENSIONS, OPT_REQEXTS, OPT_ADDEXT,
+    OPT_PRECERT, OPT_MD,
+    OPT_SECTION, OPT_QUIET,
     OPT_R_ENUM, OPT_PROV_ENUM
 } OPTION_CHOICE;
 
@@ -104,7 +103,8 @@ const OPTIONS req_options[] = {
      "Specify engine to be used for key generation operations"},
 #endif
     {"in", OPT_IN, '<', "X.509 request input file (default stdin)"},
-    {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"},
+    {"inform", OPT_INFORM, 'F',
+     "CSR input format to use (PEM or DER; by default try PEM first)"},
     {"verify", OPT_VERIFY, '-', "Verify self-signature on the request"},
 
     OPT_SECTION("Certificate"),
@@ -117,6 +117,7 @@ const OPTIONS req_options[] = {
     {"text", OPT_TEXT, '-', "Text form of request"},
     {"x509", OPT_X509, '-',
      "Output an X.509 certificate structure instead of a cert request"},
+    {"x509v1", OPT_X509V1, '-', "Request cert generation with X.509 version 1"},
     {"CA", OPT_CA, '<', "Issuer cert to use for signing a cert, implies -x509"},
     {"CAkey", OPT_CAKEY, 's',
      "Issuer private key to use with -CA; default is -CA arg"},
@@ -130,14 +131,12 @@ const OPTIONS req_options[] = {
     {"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"},
     {"copy_extensions", OPT_COPY_EXTENSIONS, 's',
      "copy extensions from request when using -x509"},
+    {"extensions", OPT_EXTENSIONS, 's',
+     "Cert or request extension section (override value in config file)"},
+    {"reqexts", OPT_REQEXTS, 's', "An alias for -extensions"},
     {"addext", OPT_ADDEXT, 's',
      "Additional cert extension key=value pair (may be given more than once)"},
-    {"extensions", OPT_EXTENSIONS, 's',
-     "Cert extension section (override value in config file)"},
-    {"reqexts", OPT_REQEXTS, 's',
-     "Request extension section (override value in config file)"},
-    {"precert", OPT_PRECERT, '-',
-     "Add a poison extension to the generated cert (implies -new)"},
+    {"precert", OPT_PRECERT, '-', "Add a poison extension to generated cert (implies -new)"},
 
     OPT_SECTION("Keys and Signing"),
     {"key", OPT_KEY, 's', "Key for signing, and to include unless -in given"},
@@ -159,6 +158,7 @@ const OPTIONS req_options[] = {
     {"batch", OPT_BATCH, '-',
      "Do not ask anything during request generation"},
     {"verbose", OPT_VERBOSE, '-', "Verbose output"},
+    {"quiet", OPT_QUIET, '-', "Terse output"},
     {"noenc", OPT_NOENC, '-', "Don't encrypt private keys"},
     {"nodes", OPT_NODES, '-', "Don't encrypt private keys; deprecated"},
     {"noout", OPT_NOOUT, '-', "Do not output REQ"},
@@ -189,8 +189,8 @@ static void exts_cleanup(OPENSSL_STRING *x)
 }
 
 /*
- * Is the |kv| key already duplicated? This is remarkably tricky to get right.
- * Return 0 if unique, -1 on runtime error; 1 if found or a syntax error.
+ * Is the |kv| key already duplicated?
+ * Return 0 if unique, -1 on runtime error, -2 on syntax error; 1 if found.
  */
 static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv)
 {
@@ -199,11 +199,12 @@ static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv)
 
     /* Check syntax. */
     /* Skip leading whitespace, make a copy. */
-    while (*kv && isspace(_UC(*kv)))
-        if (*++kv == '\0')
-            return 1;
-    if ((p = strchr(kv, '=')) == NULL)
-        return 1;
+    while (isspace(_UC(*kv)))
+        kv++;
+    if ((p = strchr(kv, '=')) == NULL) {
+        BIO_printf(bio_err, "Parse error on -addext: missing '='\n");
+        return -2;
+    }
     off = p - kv;
     if ((kv = OPENSSL_strdup(kv)) == NULL)
         return -1;
@@ -213,14 +214,16 @@ static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv)
         if (!isspace(_UC(p[-1])))
             break;
     if (p == kv) {
+        BIO_printf(bio_err, "Parse error on -addext: missing key\n");
         OPENSSL_free(kv);
-        return 1;
+        return -2;
     }
     *p = '\0';
 
     /* Finally have a clean "key"; see if it's there [by attempt to add it]. */
     p = (char *)lh_OPENSSL_STRING_insert(addexts, (OPENSSL_STRING *)kv);
     if (p != NULL) {
+        BIO_printf(bio_err, "Duplicate extension name: %s\n", kv);
         OPENSSL_free(p);
         return 1;
     } else if (lh_OPENSSL_STRING_error(addexts)) {
@@ -243,25 +246,24 @@ int req_main(int argc, char **argv)
     X509 *new_x509 = NULL, *CAcert = NULL;
     X509_REQ *req = NULL;
     EVP_CIPHER *cipher = NULL;
-    EVP_MD *md = NULL;
     int ext_copy = EXT_COPY_UNSET;
     BIO *addext_bio = NULL;
-    char *extensions = NULL;
+    char *extsect = NULL;
     const char *infile = NULL, *CAfile = NULL, *CAkeyfile = NULL;
     char *outfile = NULL, *keyfile = NULL, *digest = NULL;
     char *keyalgstr = NULL, *p, *prog, *passargin = NULL, *passargout = NULL;
     char *passin = NULL, *passout = NULL;
     char *nofree_passin = NULL, *nofree_passout = NULL;
-    char *req_exts = NULL, *subj = NULL;
+    char *subj = NULL;
     X509_NAME *fsubj = NULL;
     char *template = default_config_file, *keyout = NULL;
     const char *keyalg = NULL;
     OPTION_CHOICE o;
     int days = UNSET_DAYS;
-    int ret = 1, gen_x509 = 0, i = 0, newreq = 0, verbose = 0;
+    int ret = 1, gen_x509 = 0, i = 0, newreq = 0, verbose = 0, progress = 1;
     int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, keyform = FORMAT_UNDEF;
     int modulus = 0, multirdn = 1, verify = 0, noout = 0, text = 0;
-    int noenc = 0, newhdr = 0, subject = 0, pubkey = 0, precert = 0;
+    int noenc = 0, newhdr = 0, subject = 0, pubkey = 0, precert = 0, x509v1 = 0;
     long newkey_len = -1;
     unsigned long chtype = MBSTRING_ASC, reqflag = 0;
 
@@ -269,6 +271,7 @@ int req_main(int argc, char **argv)
     cipher = (EVP_CIPHER *)EVP_des_ede3_cbc();
 #endif
 
+    opt_set_unknown_name("digest");
     prog = opt_init(argc, argv, req_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -387,6 +390,11 @@ int req_main(int argc, char **argv)
             break;
         case OPT_VERBOSE:
             verbose = 1;
+            progress = 1;
+            break;
+        case OPT_QUIET:
+            verbose = 0;
+            progress = 0;
             break;
         case OPT_UTF8:
             chtype = MBSTRING_UTF8;
@@ -402,6 +410,9 @@ int req_main(int argc, char **argv)
         case OPT_TEXT:
             text = 1;
             break;
+        case OPT_X509V1:
+            x509v1 = 1;
+            /* fall thru */
         case OPT_X509:
             gen_x509 = 1;
             break;
@@ -445,6 +456,10 @@ int req_main(int argc, char **argv)
                 goto end;
             }
             break;
+        case OPT_EXTENSIONS:
+        case OPT_REQEXTS:
+            extsect = opt_arg();
+            break;
         case OPT_ADDEXT:
             p = opt_arg();
             if (addexts == NULL) {
@@ -454,19 +469,13 @@ int req_main(int argc, char **argv)
                     goto end;
             }
             i = duplicated(addexts, p);
-            if (i == 1) {
-                BIO_printf(bio_err, "Duplicate extension: %s\n", p);
+            if (i == 1)
                 goto opthelp;
-            }
+            if (i == -1)
+                BIO_printf(bio_err, "Internal error handling -addext %s\n", p);
             if (i < 0 || BIO_printf(addext_bio, "%s\n", p) < 0)
                 goto end;
             break;
-        case OPT_EXTENSIONS:
-            extensions = opt_arg();
-            break;
-        case OPT_REQEXTS:
-            req_exts = opt_arg();
-            break;
         case OPT_PRECERT:
             newreq = precert = 1;
             break;
@@ -477,8 +486,7 @@ int req_main(int argc, char **argv)
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     if (!app_RAND_load())
@@ -490,8 +498,13 @@ int req_main(int argc, char **argv)
         if (ext_copy == EXT_COPY_NONE)
             BIO_printf(bio_err, "Ignoring -copy_extensions 'none' when -x509 is not given\n");
     }
-    if (gen_x509 && infile == NULL)
-        newreq = 1;
+    if (infile == NULL) {
+        if (gen_x509)
+            newreq = 1;
+        else if (!newreq)
+            BIO_printf(bio_err,
+                       "Warning: Will read cert request from stdin since no -in option is given\n");
+    }
 
     if (!app_passwd(passargin, passargout, &passin, &passout)) {
         BIO_printf(bio_err, "Error getting passwords\n");
@@ -511,9 +524,7 @@ int req_main(int argc, char **argv)
         goto end;
 
     if (req_conf != NULL) {
-        p = NCONF_get_string(req_conf, NULL, "oid_file");
-        if (p == NULL)
-            ERR_clear_error();
+        p = app_conf_try_string(req_conf, NULL, "oid_file");
         if (p != NULL) {
             BIO *oid_bio = BIO_new_file(p, "r");
 
@@ -532,35 +543,28 @@ int req_main(int argc, char **argv)
 
     /* Check that any specified digest is fetchable */
     if (digest != NULL) {
-        if (!opt_md(digest, &md)) {
-            ERR_clear_error();
+        if (!opt_check_md(digest))
             goto opthelp;
-        }
-        EVP_MD_free(md);
     } else {
         /* No digest specified, default to configuration */
-        p = NCONF_get_string(req_conf, section, "default_md");
-        if (p == NULL)
-            ERR_clear_error();
-        else
+        p = app_conf_try_string(req_conf, section, "default_md");
+        if (p != NULL)
             digest = p;
     }
 
-    if (extensions == NULL) {
-        extensions = NCONF_get_string(req_conf, section, V3_EXTENSIONS);
-        if (extensions == NULL)
-            ERR_clear_error();
-    }
-    if (extensions != NULL) {
-        /* Check syntax of file */
+    if (extsect == NULL)
+        extsect = app_conf_try_string(req_conf, section,
+                                   gen_x509 ? V3_EXTENSIONS : REQ_EXTENSIONS);
+    if (extsect != NULL) {
+        /* Check syntax of extension section in config file */
         X509V3_CTX ctx;
 
         X509V3_set_ctx_test(&ctx);
         X509V3_set_nconf(&ctx, req_conf);
-        if (!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) {
+        if (!X509V3_EXT_add_nconf(req_conf, &ctx, extsect, NULL)) {
             BIO_printf(bio_err,
-                       "Error checking x509 extension section %s\n",
-                       extensions);
+                       "Error checking %s extension section %s\n",
+                       gen_x509 ? "x509" : "request", extsect);
             goto end;
         }
     }
@@ -576,69 +580,42 @@ int req_main(int argc, char **argv)
         }
     }
 
-    if (passin == NULL) {
+    if (passin == NULL)
         passin = nofree_passin =
-            NCONF_get_string(req_conf, section, "input_password");
-        if (passin == NULL)
-            ERR_clear_error();
-    }
+            app_conf_try_string(req_conf, section, "input_password");
 
-    if (passout == NULL) {
+    if (passout == NULL)
         passout = nofree_passout =
-            NCONF_get_string(req_conf, section, "output_password");
-        if (passout == NULL)
-            ERR_clear_error();
-    }
-
-    p = NCONF_get_string(req_conf, section, STRING_MASK);
-    if (p == NULL)
-        ERR_clear_error();
+            app_conf_try_string(req_conf, section, "output_password");
 
+    p = app_conf_try_string(req_conf, section, STRING_MASK);
     if (p != NULL && !ASN1_STRING_set_default_mask_asc(p)) {
         BIO_printf(bio_err, "Invalid global string mask setting %s\n", p);
         goto end;
     }
 
     if (chtype != MBSTRING_UTF8) {
-        p = NCONF_get_string(req_conf, section, UTF8_IN);
-        if (p == NULL)
-            ERR_clear_error();
-        else if (strcmp(p, "yes") == 0)
+        p = app_conf_try_string(req_conf, section, UTF8_IN);
+        if (p != NULL && strcmp(p, "yes") == 0)
             chtype = MBSTRING_UTF8;
     }
 
-    if (req_exts == NULL) {
-        req_exts = NCONF_get_string(req_conf, section, REQ_EXTENSIONS);
-        if (req_exts == NULL)
-            ERR_clear_error();
-    }
-    if (req_exts != NULL) {
-        /* Check syntax of file */
-        X509V3_CTX ctx;
-
-        X509V3_set_ctx_test(&ctx);
-        X509V3_set_nconf(&ctx, req_conf);
-        if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) {
-            BIO_printf(bio_err,
-                       "Error checking request extension section %s\n",
-                       req_exts);
-            goto end;
-        }
-    }
-
     if (keyfile != NULL) {
         pkey = load_key(keyfile, keyform, 0, passin, e, "private key");
         if (pkey == NULL)
             goto end;
         app_RAND_load_conf(req_conf, section);
     }
+    if (keyalg != NULL && pkey != NULL) {
+        BIO_printf(bio_err,
+                   "Warning: Not generating key via given -newkey option since -key is given\n");
+        /* Better throw an error in this case */
+    }
     if (newreq && pkey == NULL) {
         app_RAND_load_conf(req_conf, section);
 
-        if (!NCONF_get_number(req_conf, section, BITS, &newkey_len)) {
-            ERR_clear_error();
+        if (!app_conf_try_number(req_conf, section, BITS, &newkey_len))
             newkey_len = DEFAULT_KEY_LENGTH;
-        }
 
         genctx = set_keygen_ctx(keyalg, &keyalgstr, &newkey_len, gen_eng);
         if (genctx == NULL)
@@ -681,8 +658,9 @@ int req_main(int argc, char **argv)
             }
         }
 
-        EVP_PKEY_CTX_set_cb(genctx, genpkey_cb);
         EVP_PKEY_CTX_set_app_data(genctx, bio_err);
+        if (progress)
+            EVP_PKEY_CTX_set_cb(genctx, progress_cb);
 
         pkey = app_keygen(genctx, keyalgstr, newkey_len, verbose);
         if (pkey == NULL)
@@ -691,11 +669,8 @@ int req_main(int argc, char **argv)
         EVP_PKEY_CTX_free(genctx);
         genctx = NULL;
     }
-    if (keyout == NULL && keyfile == NULL) {
-        keyout = NCONF_get_string(req_conf, section, KEYFILE);
-        if (keyout == NULL)
-            ERR_clear_error();
-    }
+    if (keyout == NULL && keyfile == NULL)
+        keyout = app_conf_try_string(req_conf, section, KEYFILE);
 
     if (pkey != NULL && (keyfile == NULL || keyout != NULL)) {
         if (verbose) {
@@ -709,14 +684,10 @@ int req_main(int argc, char **argv)
         if (out == NULL)
             goto end;
 
-        p = NCONF_get_string(req_conf, section, "encrypt_rsa_key");
-        if (p == NULL) {
-            ERR_clear_error();
-            p = NCONF_get_string(req_conf, section, "encrypt_key");
-            if (p == NULL)
-                ERR_clear_error();
-        }
-        if ((p != NULL) && (strcmp(p, "no") == 0))
+        p = app_conf_try_string(req_conf, section, "encrypt_rsa_key");
+        if (p == NULL)
+            p = app_conf_try_string(req_conf, section, "encrypt_key");
+        if (p != NULL && strcmp(p, "no") == 0)
             cipher = NULL;
         if (noenc)
             cipher = NULL;
@@ -747,10 +718,17 @@ int req_main(int argc, char **argv)
         goto end;
 
     if (!newreq) {
-        req = load_csr(infile /* if NULL, reads from stdin */,
-                       informat, "X509 request");
+        if (keyfile != NULL)
+            BIO_printf(bio_err,
+                       "Warning: Not placing -key in cert or request since request is used\n");
+        req = load_csr_autofmt(infile /* if NULL, reads from stdin */,
+                               informat, vfyopts, "X509 request");
         if (req == NULL)
             goto end;
+    } else if (infile != NULL) {
+        BIO_printf(bio_err,
+                   "Warning: Ignoring -in option since -new or -newkey or -precert is given\n");
+        /* Better throw an error in this case, as done in the x509 app */
     }
 
     if (CAkeyfile == NULL)
@@ -791,7 +769,7 @@ int req_main(int argc, char **argv)
                 goto end;
             }
 
-            if (!make_REQ(req, pkey, fsubj, multirdn, !gen_x509, chtype)){
+            if (!make_REQ(req, pkey, fsubj, multirdn, !gen_x509, chtype)) {
                 BIO_printf(bio_err, "Error making certificate request\n");
                 goto end;
             }
@@ -806,6 +784,10 @@ int req_main(int argc, char **argv)
             X509_NAME *n_subj = fsubj != NULL ? fsubj :
                 X509_REQ_get_subject_name(req);
 
+            if (CAcert != NULL && keyfile != NULL)
+                BIO_printf(bio_err,
+                           "Warning: Not using -key or -newkey for signing since -CA option is given\n");
+
             if ((new_x509 = X509_new_ex(app_get0_libctx(),
                                         app_get0_propq())) == NULL)
                 goto end;
@@ -844,26 +826,23 @@ int req_main(int argc, char **argv)
             if (CAcert == NULL) {
                 if (!X509V3_set_issuer_pkey(&ext_ctx, issuer_key))
                     goto end;
-                ERR_set_mark();
-                if (!X509_check_private_key(new_x509, issuer_key))
+                if (!cert_matches_key(new_x509, issuer_key))
                     BIO_printf(bio_err,
                                "Warning: Signature key and public key of cert do not match\n");
-                ERR_pop_to_mark();
             }
             X509V3_set_nconf(&ext_ctx, req_conf);
 
             /* Add extensions */
-            if (extensions != NULL
-                    && !X509V3_EXT_add_nconf(req_conf, &ext_ctx, extensions,
-                                             new_x509)) {
+            if (extsect != NULL
+                && !X509V3_EXT_add_nconf(req_conf, &ext_ctx, extsect, new_x509)) {
                 BIO_printf(bio_err, "Error adding x509 extensions from section %s\n",
-                           extensions);
+                           extsect);
                 goto end;
             }
             if (addext_conf != NULL
                 && !X509V3_EXT_add_nconf(addext_conf, &ext_ctx, "default",
                                          new_x509)) {
-                BIO_printf(bio_err, "Error adding extensions defined via -addext\n");
+                BIO_printf(bio_err, "Error adding x509 extensions defined via -addext\n");
                 goto end;
             }
 
@@ -876,28 +855,32 @@ int req_main(int argc, char **argv)
                 }
             }
 
-            i = do_X509_sign(new_x509, issuer_key, digest, sigopts, &ext_ctx);
+            i = do_X509_sign(new_x509, x509v1, issuer_key, digest, sigopts,
+                             &ext_ctx);
             if (!i)
                 goto end;
         } else {
             X509V3_CTX ext_ctx;
 
+            if (precert) {
+                BIO_printf(bio_err,
+                           "Warning: Ignoring -precert flag since no cert is produced\n");
+            }
             /* Set up V3 context struct */
-            X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0);
+            X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, X509V3_CTX_REPLACE);
             X509V3_set_nconf(&ext_ctx, req_conf);
 
             /* Add extensions */
-            if (req_exts != NULL
-                && !X509V3_EXT_REQ_add_nconf(req_conf, &ext_ctx,
-                                             req_exts, req)) {
+            if (extsect != NULL
+                && !X509V3_EXT_REQ_add_nconf(req_conf, &ext_ctx, extsect, req)) {
                 BIO_printf(bio_err, "Error adding request extensions from section %s\n",
-                           req_exts);
+                           extsect);
                 goto end;
             }
             if (addext_conf != NULL
                 && !X509V3_EXT_REQ_add_nconf(addext_conf, &ext_ctx, "default",
                                              req)) {
-                BIO_printf(bio_err, "Error adding extensions defined via -addext\n");
+                BIO_printf(bio_err, "Error adding request extensions defined via -addext\n");
                 goto end;
             }
             i = do_X509_REQ_sign(req, pkey, digest, sigopts);
@@ -938,7 +921,7 @@ int req_main(int argc, char **argv)
         if (i == 0)
             BIO_printf(bio_err, "Certificate request self-signature verify failure\n");
         else /* i > 0 */
-            BIO_printf(bio_err, "Certificate request self-signature verify OK\n");
+            BIO_printf(bio_out, "Certificate request self-signature verify OK\n");
     }
 
     if (noout && !text && !modulus && !subject && !pubkey) {
@@ -1073,16 +1056,12 @@ static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, X509_NAME *fsubj,
     STACK_OF(CONF_VALUE) *dn_sk = NULL, *attr_sk = NULL;
     char *tmp, *dn_sect, *attr_sect;
 
-    tmp = NCONF_get_string(req_conf, section, PROMPT);
-    if (tmp == NULL)
-        ERR_clear_error();
-    if ((tmp != NULL) && strcmp(tmp, "no") == 0)
+    tmp = app_conf_try_string(req_conf, section, PROMPT);
+    if (tmp != NULL && strcmp(tmp, "no") == 0)
         no_prompt = 1;
 
-    dn_sect = NCONF_get_string(req_conf, section, DISTINGUISHED_NAME);
-    if (dn_sect == NULL) {
-        ERR_clear_error();
-    } else {
+    dn_sect = app_conf_try_string(req_conf, section, DISTINGUISHED_NAME);
+    if (dn_sect != NULL) {
         dn_sk = NCONF_get_section(req_conf, dn_sect);
         if (dn_sk == NULL) {
             BIO_printf(bio_err, "Unable to get '%s' section\n", dn_sect);
@@ -1090,10 +1069,8 @@ static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, X509_NAME *fsubj,
         }
     }
 
-    attr_sect = NCONF_get_string(req_conf, section, ATTRIBUTES);
-    if (attr_sect == NULL) {
-        ERR_clear_error();
-    } else {
+    attr_sect = app_conf_try_string(req_conf, section, ATTRIBUTES);
+    if (attr_sect != NULL) {
         attr_sk = NCONF_get_section(req_conf, attr_sect);
         if (attr_sk == NULL) {
             BIO_printf(bio_err, "Unable to get '%s' section\n", attr_sect);
@@ -1189,31 +1166,23 @@ static int prompt_info(X509_REQ *req,
                 goto start;
             if (!join(buf, sizeof(buf), v->name, "_default", "Name"))
                 return 0;
-            if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
-                ERR_clear_error();
+            if ((def = app_conf_try_string(req_conf, dn_sect, buf)) == NULL)
                 def = "";
-            }
 
             if (!join(buf, sizeof(buf), v->name, "_value", "Name"))
                 return 0;
-            if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
-                ERR_clear_error();
+            if ((value = app_conf_try_string(req_conf, dn_sect, buf)) == NULL)
                 value = NULL;
-            }
 
             if (!join(buf, sizeof(buf), v->name, "_min", "Name"))
                 return 0;
-            if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) {
-                ERR_clear_error();
+            if (!app_conf_try_number(req_conf, dn_sect, buf, &n_min))
                 n_min = -1;
-            }
 
             if (!join(buf, sizeof(buf), v->name, "_max", "Name"))
                 return 0;
-            if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) {
-                ERR_clear_error();
+            if (!app_conf_try_number(req_conf, dn_sect, buf, &n_max))
                 n_max = -1;
-            }
 
             if (!add_DN_object(subj, v->value, def, value, nid,
                                n_min, n_max, chtype, mval))
@@ -1247,33 +1216,23 @@ static int prompt_info(X509_REQ *req,
 
                 if (!join(buf, sizeof(buf), type, "_default", "Name"))
                     return 0;
-                if ((def = NCONF_get_string(req_conf, attr_sect, buf))
-                    == NULL) {
-                    ERR_clear_error();
+                def = app_conf_try_string(req_conf, attr_sect, buf);
+                if (def == NULL)
                     def = "";
-                }
 
                 if (!join(buf, sizeof(buf), type, "_value", "Name"))
                     return 0;
-                if ((value = NCONF_get_string(req_conf, attr_sect, buf))
-                    == NULL) {
-                    ERR_clear_error();
-                    value = NULL;
-                }
+                value = app_conf_try_string(req_conf, attr_sect, buf);
 
                 if (!join(buf, sizeof(buf), type, "_min", "Name"))
                     return 0;
-                if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) {
-                    ERR_clear_error();
+                if (!app_conf_try_number(req_conf, attr_sect, buf, &n_min))
                     n_min = -1;
-                }
 
                 if (!join(buf, sizeof(buf), type, "_max", "Name"))
                     return 0;
-                if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) {
-                    ERR_clear_error();
+                if (!app_conf_try_number(req_conf, attr_sect, buf, &n_max))
                     n_max = -1;
-                }
 
                 if (!add_attribute_object(req,
                                           v->value, def, value, nid, n_min,
@@ -1666,21 +1625,3 @@ static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr,
     return gctx;
 }
 
-static int genpkey_cb(EVP_PKEY_CTX *ctx)
-{
-    char c = '*';
-    BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
-    int p;
-    p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
-    if (p == 0)
-        c = '.';
-    if (p == 1)
-        c = '+';
-    if (p == 2)
-        c = '*';
-    if (p == 3)
-        c = '\n';
-    BIO_write(b, &c, 1);
-    (void)BIO_flush(b);
-    return 1;
-}

+ 6 - 8
libs/openssl/apps/rsa.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -139,6 +139,7 @@ int rsa_main(int argc, char **argv)
     int selection = 0;
     OSSL_ENCODER_CTX *ectx = NULL;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, rsa_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -217,15 +218,12 @@ int rsa_main(int argc, char **argv)
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
-    if (ciphername != NULL) {
-        if (!opt_cipher(ciphername, &enc))
-            goto opthelp;
-    }
-    private = (text && !pubin) || (!pubout && !noout) ? 1 : 0;
+    if (!opt_cipher(ciphername, &enc))
+        goto opthelp;
+    private = (text && !pubin) || (!pubout && !noout);
 
     if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
         BIO_printf(bio_err, "Error getting passwords\n");

+ 4 - 5
libs/openssl/apps/rsautl.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -47,9 +47,9 @@ const OPTIONS rsautl_options[] = {
 
     OPT_SECTION("Input"),
     {"in", OPT_IN, '<', "Input file"},
-    {"inkey", OPT_INKEY, 's', "Input key"},
+    {"inkey", OPT_INKEY, 's', "Input key, by default an RSA private key"},
     {"keyform", OPT_KEYFORM, 'E', "Private key format (ENGINE, other values ignored)"},
-    {"pubin", OPT_PUBIN, '-', "Input is an RSA public"},
+    {"pubin", OPT_PUBIN, '-', "Input key is an RSA public pkey"},
     {"certin", OPT_CERTIN, '-', "Input is a cert carrying an RSA public key"},
     {"rev", OPT_REV, '-', "Reverse the order of the input buffer"},
     {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
@@ -169,8 +169,7 @@ int rsautl_main(int argc, char **argv)
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     if (!app_RAND_load())

+ 566 - 58
libs/openssl/apps/s_client.c

@@ -58,6 +58,46 @@ typedef unsigned int u_int;
 #define BUFSIZZ 1024*8
 #define S_CLIENT_IRC_READ_TIMEOUT 8
 
+#define USER_DATA_MODE_NONE     0
+#define USER_DATA_MODE_BASIC    1
+#define USER_DATA_MODE_ADVANCED 2
+
+#define USER_DATA_PROCESS_BAD_ARGUMENT 0
+#define USER_DATA_PROCESS_SHUT         1
+#define USER_DATA_PROCESS_RESTART      2
+#define USER_DATA_PROCESS_NO_DATA      3
+#define USER_DATA_PROCESS_CONTINUE     4
+
+struct user_data_st {
+    /* SSL connection we are processing commands for */
+    SSL *con;
+
+    /* Buffer where we are storing data supplied by the user */
+    char *buf;
+
+    /* Allocated size of the buffer */
+    size_t bufmax;
+
+    /* Amount of the buffer actually used */
+    size_t buflen;
+
+    /* Current location in the buffer where we will read from next*/
+    size_t bufoff;
+
+    /* The mode we are using for processing commands */
+    int mode;
+
+    /* Whether FIN has ben sent on the stream */
+    int isfin;
+};
+
+static void user_data_init(struct user_data_st *user_data, SSL *con, char *buf,
+                           size_t bufmax, int mode);
+static int user_data_add(struct user_data_st *user_data, size_t i);
+static int user_data_process(struct user_data_st *user_data, size_t *len,
+                             size_t *off);
+static int user_data_has_data(struct user_data_st *user_data);
+
 static char *prog;
 static int c_debug = 0;
 static int c_showcerts = 0;
@@ -75,6 +115,9 @@ static int ocsp_resp_cb(SSL *s, void *arg);
 static int ldap_ExtendedResponse_parse(const char *buf, long rem);
 static int is_dNS_name(const char *host);
 
+static const unsigned char cert_type_rpk[] = { TLSEXT_cert_type_rpk, TLSEXT_cert_type_x509 };
+static int enable_server_rpk = 0;
+
 static int saved_errno;
 
 static void save_errno(void)
@@ -435,7 +478,7 @@ typedef enum OPTION_choice {
     OPT_XMPPHOST, OPT_VERIFY, OPT_NAMEOPT,
     OPT_CERT, OPT_CRL, OPT_CRL_DOWNLOAD, OPT_SESS_OUT, OPT_SESS_IN,
     OPT_CERTFORM, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET,
-    OPT_BRIEF, OPT_PREXIT, OPT_CRLF, OPT_QUIET, OPT_NBIO,
+    OPT_BRIEF, OPT_PREXIT, OPT_NO_INTERACTIVE, OPT_CRLF, OPT_QUIET, OPT_NBIO,
     OPT_SSL_CLIENT_ENGINE, OPT_IGN_EOF, OPT_NO_IGN_EOF,
     OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_WDEBUG,
     OPT_MSG, OPT_MSGFILE, OPT_ENGINE, OPT_TRACE, OPT_SECURITY_DEBUG,
@@ -447,8 +490,8 @@ typedef enum OPTION_choice {
 #endif
     OPT_SSL3, OPT_SSL_CONFIG,
     OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
-    OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS,
-    OPT_CERT_CHAIN, OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN,
+    OPT_DTLS1_2, OPT_QUIC, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM,
+    OPT_PASS, OPT_CERT_CHAIN, OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN,
     OPT_NEXTPROTONEG, OPT_ALPN,
     OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH,
     OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE, OPT_VERIFYCAFILE,
@@ -457,17 +500,21 @@ typedef enum OPTION_choice {
     OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_PROTOHOST,
     OPT_MAXFRAGLEN, OPT_MAX_SEND_FRAG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES,
     OPT_READ_BUF, OPT_KEYLOG_FILE, OPT_EARLY_DATA, OPT_REQCAFILE,
+    OPT_TFO,
     OPT_V_ENUM,
     OPT_X_ENUM,
     OPT_S_ENUM, OPT_IGNORE_UNEXPECTED_EOF,
-    OPT_FALLBACKSCSV, OPT_NOCMDS, OPT_PROXY, OPT_PROXY_USER, OPT_PROXY_PASS,
-    OPT_DANE_TLSA_DOMAIN,
+    OPT_FALLBACKSCSV, OPT_NOCMDS, OPT_ADV, OPT_PROXY, OPT_PROXY_USER,
+    OPT_PROXY_PASS, OPT_DANE_TLSA_DOMAIN,
 #ifndef OPENSSL_NO_CT
     OPT_CT, OPT_NOCT, OPT_CTLOG_FILE,
 #endif
     OPT_DANE_TLSA_RRDATA, OPT_DANE_EE_NO_NAME,
     OPT_ENABLE_PHA,
+    OPT_ENABLE_SERVER_RPK,
+    OPT_ENABLE_CLIENT_RPK,
     OPT_SCTP_LABEL_BUG,
+    OPT_KTLS,
     OPT_R_ENUM, OPT_PROV_ENUM
 } OPTION_CHOICE;
 
@@ -539,6 +586,9 @@ const OPTIONS s_client_options[] = {
      "Do not load certificates from the default certificates store"},
     {"requestCAfile", OPT_REQCAFILE, '<',
       "PEM format file of CA names to send to the server"},
+#if defined(TCP_FASTOPEN) && !defined(OPENSSL_NO_TFO)
+    {"tfo", OPT_TFO, '-', "Connect using TCP Fast Open"},
+#endif
     {"dane_tlsa_domain", OPT_DANE_TLSA_DOMAIN, 's', "DANE TLSA base domain"},
     {"dane_tlsa_rrdata", OPT_DANE_TLSA_RRDATA, 's',
      "DANE TLSA rrdata presentation form"},
@@ -569,6 +619,8 @@ const OPTIONS s_client_options[] = {
      "Restrict output to brief summary of connection parameters"},
     {"prexit", OPT_PREXIT, '-',
      "Print session information when the program exits"},
+    {"no-interactive", OPT_NO_INTERACTIVE, '-',
+     "Don't run the client in the interactive mode"},
 
     OPT_SECTION("Debug"),
     {"showcerts", OPT_SHOWCERTS, '-',
@@ -595,6 +647,7 @@ const OPTIONS s_client_options[] = {
 #endif
     {"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"},
     {"nocommands", OPT_NOCMDS, '-', "Do not use interactive command letters"},
+    {"adv", OPT_ADV, '-', "Advanced command mode"},
     {"servername", OPT_SERVERNAME, 's',
      "Set TLS extension servername (SNI) in ClientHello (default)"},
     {"noservername", OPT_NOSERVERNAME, '-',
@@ -631,6 +684,7 @@ const OPTIONS s_client_options[] = {
 #endif
 #ifndef OPENSSL_NO_DTLS
     {"dtls", OPT_DTLS, '-', "Use any version of DTLS"},
+    {"quic", OPT_QUIC, '-', "Use QUIC"},
     {"timeout", OPT_TIMEOUT, '-',
      "Enable send/receive timeout on DTLS connections"},
     {"mtu", OPT_MTU, 'p', "Set the link layer MTU"},
@@ -651,6 +705,8 @@ const OPTIONS s_client_options[] = {
 #endif
     {"early_data", OPT_EARLY_DATA, '<', "File to send as early data"},
     {"enable_pha", OPT_ENABLE_PHA, '-', "Enable post-handshake-authentication"},
+    {"enable_server_rpk", OPT_ENABLE_SERVER_RPK, '-', "Enable raw public keys (RFC7250) from the server"},
+    {"enable_client_rpk", OPT_ENABLE_CLIENT_RPK, '-', "Enable raw public keys (RFC7250) from the client"},
 #ifndef OPENSSL_NO_SRTP
     {"use_srtp", OPT_USE_SRTP, 's',
      "Offer SRTP key management with a colon-separated profile list"},
@@ -665,6 +721,9 @@ const OPTIONS s_client_options[] = {
     {"srp_strength", OPT_SRP_STRENGTH, 'p',
      "(deprecated) Minimal length in bits for N"},
 #endif
+#ifndef OPENSSL_NO_KTLS
+    {"ktls", OPT_KTLS, '-', "Enable Kernel TLS for sending and receiving"},
+#endif
 
     OPT_R_OPTIONS,
     OPT_S_OPTIONS,
@@ -737,7 +796,8 @@ static const OPT_PAIR services[] = {
 
 #define IS_PROT_FLAG(o) \
  (o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \
-  || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2)
+  || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2 \
+  || o == OPT_QUIC)
 
 /* Free |*dest| and optionally set it to a copy of |source|. */
 static void freeandcopy(char **dest, const char *source)
@@ -815,16 +875,19 @@ int s_client_main(int argc, char **argv)
     struct timeval timeout, *timeoutp;
     fd_set readfds, writefds;
     int noCApath = 0, noCAfile = 0, noCAstore = 0;
-    int build_chain = 0, cbuf_len, cbuf_off, cert_format = FORMAT_UNDEF;
+    int build_chain = 0, cert_format = FORMAT_UNDEF;
+    size_t cbuf_len, cbuf_off;
     int key_format = FORMAT_UNDEF, crlf = 0, full_log = 1, mbuf_len = 0;
     int prexit = 0;
+    int nointeractive = 0;
     int sdebug = 0;
     int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0;
     int ret = 1, in_init = 1, i, nbio_test = 0, sock = -1, k, width, state = 0;
-    int sbuf_len, sbuf_off, cmdletters = 1;
+    int sbuf_len, sbuf_off, cmdmode = USER_DATA_MODE_BASIC;
     int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0;
     int starttls_proto = PROTO_OFF, crl_format = FORMAT_UNDEF, crl_download = 0;
     int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending;
+    int first_loop;
 #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS)
     int at_eof = 0;
 #endif
@@ -880,15 +943,21 @@ int s_client_main(int argc, char **argv)
 #endif
     BIO *bio_c_msg = NULL;
     const char *keylog_file = NULL, *early_data_file = NULL;
-#ifndef OPENSSL_NO_DTLS
-    int isdtls = 0;
-#endif
+    int isdtls = 0, isquic = 0;
     char *psksessf = NULL;
     int enable_pha = 0;
+    int enable_client_rpk = 0;
 #ifndef OPENSSL_NO_SCTP
     int sctp_label_bug = 0;
 #endif
     int ignore_unexpected_eof = 0;
+#ifndef OPENSSL_NO_KTLS
+    int enable_ktls = 0;
+#endif
+    int tfo = 0;
+    int is_infinite;
+    BIO_ADDR *peer_addr = NULL;
+    struct user_data_st user_data;
 
     FD_ZERO(&readfds);
     FD_ZERO(&writefds);
@@ -1073,6 +1142,9 @@ int s_client_main(int argc, char **argv)
         case OPT_PREXIT:
             prexit = 1;
             break;
+        case OPT_NO_INTERACTIVE:
+            nointeractive = 1;
+            break;
         case OPT_CRLF:
             crlf = 1;
             break;
@@ -1083,7 +1155,10 @@ int s_client_main(int argc, char **argv)
             c_nbio = 1;
             break;
         case OPT_NOCMDS:
-            cmdletters = 0;
+            cmdmode = USER_DATA_MODE_NONE;
+            break;
+        case OPT_ADV:
+            cmdmode = USER_DATA_MODE_ADVANCED;
             break;
         case OPT_ENGINE:
             e = setup_engine(opt_arg(), 1);
@@ -1210,6 +1285,7 @@ int s_client_main(int argc, char **argv)
 #ifndef OPENSSL_NO_DTLS
             isdtls = 0;
 #endif
+            isquic = 0;
             break;
         case OPT_TLS1_3:
             min_version = TLS1_3_VERSION;
@@ -1218,6 +1294,7 @@ int s_client_main(int argc, char **argv)
 #ifndef OPENSSL_NO_DTLS
             isdtls = 0;
 #endif
+            isquic = 0;
             break;
         case OPT_TLS1_2:
             min_version = TLS1_2_VERSION;
@@ -1226,6 +1303,7 @@ int s_client_main(int argc, char **argv)
 #ifndef OPENSSL_NO_DTLS
             isdtls = 0;
 #endif
+            isquic = 0;
             break;
         case OPT_TLS1_1:
             min_version = TLS1_1_VERSION;
@@ -1234,6 +1312,7 @@ int s_client_main(int argc, char **argv)
 #ifndef OPENSSL_NO_DTLS
             isdtls = 0;
 #endif
+            isquic = 0;
             break;
         case OPT_TLS1:
             min_version = TLS1_VERSION;
@@ -1242,12 +1321,14 @@ int s_client_main(int argc, char **argv)
 #ifndef OPENSSL_NO_DTLS
             isdtls = 0;
 #endif
+            isquic = 0;
             break;
         case OPT_DTLS:
 #ifndef OPENSSL_NO_DTLS
             meth = DTLS_client_method();
             socket_type = SOCK_DGRAM;
             isdtls = 1;
+            isquic = 0;
 #endif
             break;
         case OPT_DTLS1:
@@ -1257,6 +1338,7 @@ int s_client_main(int argc, char **argv)
             max_version = DTLS1_VERSION;
             socket_type = SOCK_DGRAM;
             isdtls = 1;
+            isquic = 0;
 #endif
             break;
         case OPT_DTLS1_2:
@@ -1266,6 +1348,19 @@ int s_client_main(int argc, char **argv)
             max_version = DTLS1_2_VERSION;
             socket_type = SOCK_DGRAM;
             isdtls = 1;
+            isquic = 0;
+#endif
+            break;
+        case OPT_QUIC:
+#ifndef OPENSSL_NO_QUIC
+            meth = OSSL_QUIC_client_method();
+            min_version = 0;
+            max_version = 0;
+            socket_type = SOCK_DGRAM;
+# ifndef OPENSSL_NO_DTLS
+            isdtls = 0;
+# endif
+            isquic = 1;
 #endif
             break;
         case OPT_SCTP:
@@ -1399,6 +1494,9 @@ int s_client_main(int argc, char **argv)
             if (!opt_pair(opt_arg(), services, &starttls_proto))
                 goto end;
             break;
+        case OPT_TFO:
+            tfo = 1;
+            break;
         case OPT_SERVERNAME:
             servername = opt_arg();
             break;
@@ -1462,12 +1560,22 @@ int s_client_main(int argc, char **argv)
         case OPT_ENABLE_PHA:
             enable_pha = 1;
             break;
+        case OPT_KTLS:
+#ifndef OPENSSL_NO_KTLS
+            enable_ktls = 1;
+#endif
+            break;
+        case OPT_ENABLE_SERVER_RPK:
+            enable_server_rpk = 1;
+            break;
+        case OPT_ENABLE_CLIENT_RPK:
+            enable_client_rpk = 1;
+            break;
         }
     }
 
     /* Optional argument is connect string if -connect not used. */
-    argc = opt_num_rest();
-    if (argc == 1) {
+    if (opt_num_rest() == 1) {
         /* Don't allow -connect and a separate argument. */
         if (connectstr != NULL) {
             BIO_printf(bio_err,
@@ -1477,12 +1585,15 @@ int s_client_main(int argc, char **argv)
         }
         connect_type = use_inet;
         freeandcopy(&connectstr, *opt_rest());
-    } else if (argc != 0) {
+    } else if (!opt_check_rest_arg(NULL)) {
         goto opthelp;
     }
     if (!app_RAND_load())
         goto end;
 
+    if (c_ign_eof)
+        cmdmode = USER_DATA_MODE_NONE;
+
     if (count4or6 >= 2) {
         BIO_printf(bio_err, "%s: Can't use both -4 and -6\n", prog);
         goto opthelp;
@@ -1527,6 +1638,7 @@ int s_client_main(int argc, char **argv)
     }
 
     if (proxystr != NULL) {
+#ifndef OPENSSL_NO_HTTP
         int res;
         char *tmp_host = host, *tmp_port = port;
 
@@ -1561,8 +1673,14 @@ int s_client_main(int argc, char **argv)
                        "%s: -proxy argument malformed or ambiguous\n", prog);
             goto end;
         }
+#else
+        BIO_printf(bio_err,
+                   "%s: -proxy not supported in no-http build\n", prog);
+	goto end;
+#endif
     }
 
+
     if (bindstr != NULL) {
         int res;
         res = BIO_parse_hostserv(bindstr, &bindhost, &bindport,
@@ -1724,6 +1842,10 @@ int s_client_main(int argc, char **argv)
 
     if (ignore_unexpected_eof)
         SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
+#ifndef OPENSSL_NO_KTLS
+    if (enable_ktls)
+        SSL_CTX_set_options(ctx, SSL_OP_ENABLE_KTLS);
+#endif
 
     if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) {
         BIO_printf(bio_err, "Error setting verify params\n");
@@ -1933,7 +2055,7 @@ int s_client_main(int argc, char **argv)
 
     /*
      * In TLSv1.3 NewSessionTicket messages arrive after the handshake and can
-     * come at any time. Therefore we use a callback to write out the session
+     * come at any time. Therefore, we use a callback to write out the session
      * when we know about it. This approach works for < TLSv1.3 as well.
      */
     SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT
@@ -1950,6 +2072,18 @@ int s_client_main(int argc, char **argv)
     if (enable_pha)
         SSL_set_post_handshake_auth(con, 1);
 
+    if (enable_client_rpk)
+        if (!SSL_set1_client_cert_type(con, cert_type_rpk, sizeof(cert_type_rpk))) {
+            BIO_printf(bio_err, "Error setting client certificate types\n");
+            goto end;
+        }
+    if (enable_server_rpk) {
+        if (!SSL_set1_server_cert_type(con, cert_type_rpk, sizeof(cert_type_rpk))) {
+            BIO_printf(bio_err, "Error setting server certificate types\n");
+            goto end;
+        }
+    }
+
     if (sess_in != NULL) {
         SSL_SESSION *sess;
         BIO *stmp = BIO_new_file(sess_in, "r");
@@ -1979,7 +2113,7 @@ int s_client_main(int argc, char **argv)
 
     if (!noservername && (servername != NULL || dane_tlsa_domain == NULL)) {
         if (servername == NULL) {
-            if(host == NULL || is_dNS_name(host))
+            if (host == NULL || is_dNS_name(host))
                 servername = (host == NULL) ? "localhost" : host;
         }
         if (servername != NULL && !SSL_set_tlsext_host_name(con, servername)) {
@@ -2013,22 +2147,48 @@ int s_client_main(int argc, char **argv)
                    "-dane_tlsa_domain option.\n", prog);
         goto end;
     }
+#ifndef OPENSSL_NO_DTLS
+    if (isdtls && tfo) {
+        BIO_printf(bio_err, "%s: DTLS does not support the -tfo option\n", prog);
+        goto end;
+    }
+#endif
+#ifndef OPENSSL_NO_QUIC
+    if (isquic && tfo) {
+        BIO_printf(bio_err, "%s: QUIC does not support the -tfo option\n", prog);
+        goto end;
+    }
+    if (isquic && alpn_in == NULL) {
+        BIO_printf(bio_err, "%s: QUIC requires ALPN to be specified (e.g. \"h3\" for HTTP/3) via the -alpn option\n", prog);
+        goto end;
+    }
+#endif
 
+    if (tfo)
+        BIO_printf(bio_c_out, "Connecting via TFO\n");
  re_start:
     if (init_client(&sock, host, port, bindhost, bindport, socket_family,
-                    socket_type, protocol) == 0) {
+                    socket_type, protocol, tfo, !isquic, &peer_addr) == 0) {
         BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error());
         BIO_closesocket(sock);
         goto end;
     }
     BIO_printf(bio_c_out, "CONNECTED(%08X)\n", sock);
 
-    if (c_nbio) {
+    /*
+     * QUIC always uses a non-blocking socket - and we have to switch on
+     * non-blocking mode at the SSL level
+     */
+    if (c_nbio || isquic) {
         if (!BIO_socket_nbio(sock, 1)) {
             ERR_print_errors(bio_err);
             goto end;
         }
-        BIO_printf(bio_c_out, "Turned on non blocking io\n");
+        if (c_nbio) {
+            if (isquic && !SSL_set_blocking_mode(con, 0))
+                goto end;
+            BIO_printf(bio_c_out, "Turned on non blocking io\n");
+        }
     }
 #ifndef OPENSSL_NO_DTLS
     if (isdtls) {
@@ -2089,6 +2249,15 @@ int s_client_main(int argc, char **argv)
         }
     } else
 #endif /* OPENSSL_NO_DTLS */
+#ifndef OPENSSL_NO_QUIC
+    if (isquic) {
+        sbio = BIO_new_dgram(sock, BIO_NOCLOSE);
+        if (!SSL_set1_initial_peer_addr(con, peer_addr)) {
+            BIO_printf(bio_err, "Failed to set the initial peer address\n");
+            goto shut;
+        }
+    } else
+#endif
         sbio = BIO_new_socket(sock, BIO_NOCLOSE);
 
     if (sbio == NULL) {
@@ -2098,6 +2267,12 @@ int s_client_main(int argc, char **argv)
         goto end;
     }
 
+    /* Now that we're using a BIO... */
+    if (tfo) {
+        (void)BIO_set_conn_address(sbio, peer_addr);
+        (void)BIO_set_tfo(sbio, 1);
+    }
+
     if (nbio_test) {
         BIO *test;
 
@@ -2150,18 +2325,21 @@ int s_client_main(int argc, char **argv)
     tty_on = 0;
     read_ssl = 1;
     write_ssl = 1;
+    first_loop = 1;
 
     cbuf_len = 0;
     cbuf_off = 0;
     sbuf_len = 0;
     sbuf_off = 0;
 
+#ifndef OPENSSL_NO_HTTP
     if (proxystr != NULL) {
         /* Here we must use the connect string target host & port */
         if (!OSSL_HTTP_proxy_connect(sbio, thost, tport, proxyuser, proxypass,
                                      0 /* no timeout */, bio_err, prog))
             goto shut;
     }
+#endif
 
     switch ((PROTOCOL_CHOICE) starttls_proto) {
     case PROTO_OFF:
@@ -2577,7 +2755,7 @@ int s_client_main(int argc, char **argv)
                  */
                 if (mbuf_len > 1 && mbuf[0] == '"') {
                     make_uppercase(mbuf);
-                    if (strncmp(mbuf, "\"STARTTLS\"", 10) == 0)
+                    if (HAS_PREFIX(mbuf, "\"STARTTLS\""))
                         foundit = 1;
                 }
             } while (mbuf_len > 1 && mbuf[0] == '"');
@@ -2605,7 +2783,7 @@ int s_client_main(int argc, char **argv)
              */
             strncpy(sbuf, mbuf, 2);
             make_uppercase(sbuf);
-            if (strncmp(sbuf, "OK", 2) != 0) {
+            if (!HAS_PREFIX(sbuf, "OK")) {
                 BIO_printf(bio_err, "STARTTLS not supported: %s", mbuf);
                 goto shut;
             }
@@ -2720,11 +2898,14 @@ int s_client_main(int argc, char **argv)
         BIO_free(edfile);
     }
 
+    user_data_init(&user_data, con, cbuf, BUFSIZZ, cmdmode);
     for (;;) {
         FD_ZERO(&readfds);
         FD_ZERO(&writefds);
 
-        if (SSL_is_dtls(con) && DTLSv1_get_timeout(con, &timeout))
+        if ((isdtls || isquic)
+            && SSL_get_event_timeout(con, &timeout, &is_infinite)
+            && !is_infinite)
             timeoutp = &timeout;
         else
             timeoutp = NULL;
@@ -2765,6 +2946,38 @@ int s_client_main(int argc, char **argv)
             }
         }
 
+        if (!write_ssl) {
+            do {
+                switch (user_data_process(&user_data, &cbuf_len, &cbuf_off)) {
+                default:
+                    BIO_printf(bio_err, "ERROR\n");
+                    /* fall through */
+                case USER_DATA_PROCESS_SHUT:
+                    ret = 0;
+                    goto shut;
+
+                case USER_DATA_PROCESS_RESTART:
+                    goto re_start;
+
+                case USER_DATA_PROCESS_NO_DATA:
+                    break;
+
+                case USER_DATA_PROCESS_CONTINUE:
+                    write_ssl = 1;
+                    break;
+                }
+            } while (!write_ssl
+                     && cbuf_len == 0
+                     && user_data_has_data(&user_data));
+            if (cbuf_len > 0) {
+                read_tty = 0;
+                timeout.tv_sec = 0;
+                timeout.tv_usec = 0;
+            } else {
+                read_tty = 1;
+            }
+        }
+
         ssl_pending = read_ssl && SSL_has_pending(con);
 
         if (!ssl_pending) {
@@ -2782,15 +2995,26 @@ int s_client_main(int argc, char **argv)
                     openssl_fdset(fileno_stdout(), &writefds);
 #endif
             }
-            if (read_ssl)
+
+            /*
+             * Note that for QUIC we never actually check FD_ISSET() for the
+             * underlying network fds. We just rely on select waking up when
+             * they become readable/writeable and then SSL_handle_events() doing
+             * the right thing.
+             */
+            if ((!isquic && read_ssl)
+                    || (isquic && SSL_net_read_desired(con)))
                 openssl_fdset(SSL_get_fd(con), &readfds);
-            if (write_ssl)
+            if ((!isquic && write_ssl)
+                    || (isquic && (first_loop || SSL_net_write_desired(con))))
                 openssl_fdset(SSL_get_fd(con), &writefds);
 #else
             if (!tty_on || !write_tty) {
-                if (read_ssl)
+                if ((!isquic && read_ssl)
+                        || (isquic && SSL_net_read_desired(con)))
                     openssl_fdset(SSL_get_fd(con), &readfds);
-                if (write_ssl)
+                if ((!isquic && write_ssl)
+                        || (isquic && (first_loop || SSL_net_write_desired(con))))
                     openssl_fdset(SSL_get_fd(con), &writefds);
             }
 #endif
@@ -2805,7 +3029,7 @@ int s_client_main(int argc, char **argv)
 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
             /*
              * Under Windows/DOS we make the assumption that we can always
-             * write to the tty: therefore if we need to write to the tty we
+             * write to the tty: therefore, if we need to write to the tty we
              * just fall through. Otherwise we timeout the select every
              * second and see if there are any keypresses. Note: this is a
              * hack, in a proper Windows application we wouldn't do this.
@@ -2834,10 +3058,17 @@ int s_client_main(int argc, char **argv)
             }
         }
 
-        if (SSL_is_dtls(con) && DTLSv1_handle_timeout(con) > 0)
-            BIO_printf(bio_err, "TIMEOUT occurred\n");
+        if (timeoutp != NULL) {
+            SSL_handle_events(con);
+            if (isdtls
+                    && !FD_ISSET(SSL_get_fd(con), &readfds)
+                    && !FD_ISSET(SSL_get_fd(con), &writefds))
+                BIO_printf(bio_err, "TIMEOUT occurred\n");
+        }
 
-        if (!ssl_pending && FD_ISSET(SSL_get_fd(con), &writefds)) {
+        if (!ssl_pending
+                && ((!isquic && FD_ISSET(SSL_get_fd(con), &writefds))
+                    || (isquic && (cbuf_len > 0 || first_loop)))) {
             k = SSL_write(con, &(cbuf[cbuf_off]), (unsigned int)cbuf_len);
             switch (SSL_get_error(con, k)) {
             case SSL_ERROR_NONE:
@@ -2846,7 +3077,7 @@ int s_client_main(int argc, char **argv)
                 if (k <= 0)
                     goto end;
                 /* we have done a  write(con,NULL,0); */
-                if (cbuf_len <= 0) {
+                if (cbuf_len == 0) {
                     read_tty = 1;
                     write_ssl = 0;
                 } else {        /* if (cbuf_len > 0) */
@@ -2888,9 +3119,12 @@ int s_client_main(int argc, char **argv)
 
             case SSL_ERROR_SYSCALL:
                 if ((k != 0) || (cbuf_len != 0)) {
-                    BIO_printf(bio_err, "write:errno=%d\n",
-                               get_last_socket_error());
-                    goto shut;
+                    int sockerr = get_last_socket_error();
+
+                    if (!tfo || sockerr != EISCONN) {
+                        BIO_printf(bio_err, "write:errno=%d\n", sockerr);
+                        goto shut;
+                    }
                 } else {
                     read_tty = 1;
                     write_ssl = 0;
@@ -2927,7 +3161,8 @@ int s_client_main(int argc, char **argv)
                 read_ssl = 1;
                 write_tty = 0;
             }
-        } else if (ssl_pending || FD_ISSET(SSL_get_fd(con), &readfds)) {
+        } else if (ssl_pending
+                   || (!isquic && FD_ISSET(SSL_get_fd(con), &readfds))) {
 #ifdef RENEG
             {
                 static int iiii;
@@ -2990,6 +3225,13 @@ int s_client_main(int argc, char **argv)
                 goto shut;
             }
         }
+
+        /* don't wait for client input in the non-interactive mode */
+        else if (nointeractive) {
+            ret = 0;
+            goto shut;
+        }
+
 /* OPENSSL_SYS_MSDOS includes OPENSSL_SYS_WINDOWS */
 #if defined(OPENSSL_SYS_MSDOS)
         else if (has_stdin_waiting())
@@ -3022,34 +3264,19 @@ int s_client_main(int argc, char **argv)
                 at_eof = 1;
 #endif
 
-            if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q' && cmdletters))) {
+            if (!c_ign_eof && i <= 0) {
                 BIO_printf(bio_err, "DONE\n");
                 ret = 0;
                 goto shut;
             }
 
-            if ((!c_ign_eof) && (cbuf[0] == 'R' && cmdletters)) {
-                BIO_printf(bio_err, "RENEGOTIATING\n");
-                SSL_renegotiate(con);
-                cbuf_len = 0;
-            } else if (!c_ign_eof && (cbuf[0] == 'K' || cbuf[0] == 'k' )
-                    && cmdletters) {
-                BIO_printf(bio_err, "KEYUPDATE\n");
-                SSL_key_update(con,
-                               cbuf[0] == 'K' ? SSL_KEY_UPDATE_REQUESTED
-                                              : SSL_KEY_UPDATE_NOT_REQUESTED);
-                cbuf_len = 0;
-            } else {
-                cbuf_len = i;
-                cbuf_off = 0;
-#ifdef CHARSET_EBCDIC
-                ebcdic2ascii(cbuf, cbuf, i);
-#endif
+            if (i > 0 && !user_data_add(&user_data, i)) {
+                ret = 0;
+                goto shut;
             }
-
-            write_ssl = 1;
             read_tty = 0;
         }
+        first_loop = 0;
     }
 
  shut:
@@ -3097,12 +3324,13 @@ int s_client_main(int argc, char **argv)
     X509_free(cert);
     sk_X509_CRL_pop_free(crls, X509_CRL_free);
     EVP_PKEY_free(key);
-    sk_X509_pop_free(chain, X509_free);
+    OSSL_STACK_OF_X509_free(chain);
     OPENSSL_free(pass);
 #ifndef OPENSSL_NO_SRP
     OPENSSL_free(srp_arg.srppassin);
 #endif
     OPENSSL_free(sname_alloc);
+    BIO_ADDR_free(peer_addr);
     OPENSSL_free(connectstr);
     OPENSSL_free(bindstr);
     OPENSSL_free(bindhost);
@@ -3189,6 +3417,23 @@ static void print_stuff(BIO *bio, SSL *s, int full)
         } else {
             BIO_printf(bio, "no peer certificate available\n");
         }
+
+        /* Only display RPK information if configured */
+        if (SSL_get_negotiated_client_cert_type(s) == TLSEXT_cert_type_rpk)
+            BIO_printf(bio, "Client-to-server raw public key negotiated\n");
+        if (SSL_get_negotiated_server_cert_type(s) == TLSEXT_cert_type_rpk)
+            BIO_printf(bio, "Server-to-client raw public key negotiated\n");
+        if (enable_server_rpk) {
+            EVP_PKEY *peer_rpk = SSL_get0_peer_rpk(s);
+
+            if (peer_rpk != NULL) {
+                BIO_printf(bio, "Server raw public key\n");
+                EVP_PKEY_print_public(bio, peer_rpk, 2, NULL);
+            } else {
+                BIO_printf(bio, "no peer rpk available\n");
+            }
+        }
+
         print_ca_names(bio, s);
 
         ssl_print_sigalgs(bio, s);
@@ -3329,7 +3574,7 @@ static void print_stuff(BIO *bio, SSL *s, int full)
         /*
          * We also print the verify results when we dump session information,
          * but in TLSv1.3 we may not get that right away (or at all) depending
-         * on when we get a NewSessionTicket. Therefore we print it now as well.
+         * on when we get a NewSessionTicket. Therefore, we print it now as well.
          */
         verify_result = SSL_get_verify_result(s);
         BIO_printf(bio, "Verify return code: %ld (%s)\n", verify_result,
@@ -3538,4 +3783,267 @@ static int is_dNS_name(const char *host)
 
     return isdnsname;
 }
+
+static void user_data_init(struct user_data_st *user_data, SSL *con, char *buf,
+                           size_t bufmax, int mode)
+{
+    user_data->con = con;
+    user_data->buf = buf;
+    user_data->bufmax = bufmax;
+    user_data->buflen = 0;
+    user_data->bufoff = 0;
+    user_data->mode = mode;
+    user_data->isfin = 0;
+}
+
+static int user_data_add(struct user_data_st *user_data, size_t i)
+{
+    if (user_data->buflen != 0 || i > user_data->bufmax)
+        return 0;
+
+    user_data->buflen = i;
+    user_data->bufoff = 0;
+
+    return 1;
+}
+
+#define USER_COMMAND_HELP        0
+#define USER_COMMAND_QUIT        1
+#define USER_COMMAND_RECONNECT   2
+#define USER_COMMAND_RENEGOTIATE 3
+#define USER_COMMAND_KEY_UPDATE  4
+#define USER_COMMAND_FIN         5
+
+static int user_data_execute(struct user_data_st *user_data, int cmd, char *arg)
+{
+    switch (cmd) {
+    case USER_COMMAND_HELP:
+        /* This only ever occurs in advanced mode, so just emit advanced help */
+        BIO_printf(bio_err, "Enter text to send to the peer followed by <enter>\n");
+        BIO_printf(bio_err, "To issue a command insert {cmd} or {cmd:arg} anywhere in the text\n");
+        BIO_printf(bio_err, "Entering {{ will send { to the peer\n");
+        BIO_printf(bio_err, "The following commands are available\n");
+        BIO_printf(bio_err, "  {help}: Get this help text\n");
+        BIO_printf(bio_err, "  {quit}: Close the connection to the peer\n");
+        BIO_printf(bio_err, "  {reconnect}: Reconnect to the peer\n");
+        if (SSL_is_quic(user_data->con)) {
+            BIO_printf(bio_err, "  {fin}: Send FIN on the stream. No further writing is possible\n");
+        } else if(SSL_version(user_data->con) == TLS1_3_VERSION) {
+            BIO_printf(bio_err, "  {keyup:req|noreq}: Send a Key Update message\n");
+            BIO_printf(bio_err, "                     Arguments:\n");
+            BIO_printf(bio_err, "                     req   = peer update requested (default)\n");
+            BIO_printf(bio_err, "                     noreq = peer update not requested\n");
+        } else {
+            BIO_printf(bio_err, "  {reneg}: Attempt to renegotiate\n");
+        }
+        BIO_printf(bio_err, "\n");
+        return USER_DATA_PROCESS_NO_DATA;
+
+    case USER_COMMAND_QUIT:
+        BIO_printf(bio_err, "DONE\n");
+        return USER_DATA_PROCESS_SHUT;
+
+    case USER_COMMAND_RECONNECT:
+        BIO_printf(bio_err, "RECONNECTING\n");
+        do_ssl_shutdown(user_data->con);
+        SSL_set_connect_state(user_data->con);
+        BIO_closesocket(SSL_get_fd(user_data->con));
+        return USER_DATA_PROCESS_RESTART;
+
+    case USER_COMMAND_RENEGOTIATE:
+        BIO_printf(bio_err, "RENEGOTIATING\n");
+        if (!SSL_renegotiate(user_data->con))
+            break;
+        return USER_DATA_PROCESS_CONTINUE;
+
+    case USER_COMMAND_KEY_UPDATE: {
+            int updatetype;
+
+            if (OPENSSL_strcasecmp(arg, "req") == 0)
+                updatetype = SSL_KEY_UPDATE_REQUESTED;
+            else if (OPENSSL_strcasecmp(arg, "noreq") == 0)
+                updatetype = SSL_KEY_UPDATE_NOT_REQUESTED;
+            else
+                return USER_DATA_PROCESS_BAD_ARGUMENT;
+            BIO_printf(bio_err, "KEYUPDATE\n");
+            if (!SSL_key_update(user_data->con, updatetype))
+                break;
+            return USER_DATA_PROCESS_CONTINUE;
+        }
+
+    case USER_COMMAND_FIN:
+        if (!SSL_stream_conclude(user_data->con, 0))
+            break;
+        user_data->isfin = 1;
+        return USER_DATA_PROCESS_NO_DATA;
+
+    default:
+        break;
+    }
+
+    BIO_printf(bio_err, "ERROR\n");
+    ERR_print_errors(bio_err);
+
+    return USER_DATA_PROCESS_SHUT;
+}
+
+static int user_data_process(struct user_data_st *user_data, size_t *len,
+                             size_t *off)
+{
+    char *buf_start = user_data->buf + user_data->bufoff;
+    size_t outlen = user_data->buflen;
+
+    if (user_data->buflen == 0) {
+        *len = 0;
+        *off = 0;
+        return USER_DATA_PROCESS_NO_DATA;
+    }
+
+    if (user_data->mode == USER_DATA_MODE_BASIC) {
+        switch (buf_start[0]) {
+        case 'Q':
+            user_data->buflen = user_data->bufoff = *len = *off = 0;
+            return user_data_execute(user_data, USER_COMMAND_QUIT, NULL);
+
+        case 'C':
+            user_data->buflen = user_data->bufoff = *len = *off = 0;
+            return user_data_execute(user_data, USER_COMMAND_RECONNECT, NULL);
+
+        case 'R':
+            user_data->buflen = user_data->bufoff = *len = *off = 0;
+            return user_data_execute(user_data, USER_COMMAND_RENEGOTIATE, NULL);
+
+        case 'K':
+        case 'k':
+            user_data->buflen = user_data->bufoff = *len = *off = 0;
+            return user_data_execute(user_data, USER_COMMAND_KEY_UPDATE,
+                                     buf_start[0] == 'K' ? "req" : "noreq");
+        default:
+            break;
+        }
+    } else if (user_data->mode == USER_DATA_MODE_ADVANCED) {
+        char *cmd_start = buf_start;
+
+        cmd_start[outlen] = '\0';
+        for (;;) {
+            cmd_start = strchr(cmd_start, '{');
+            if (cmd_start == buf_start && *(cmd_start + 1) == '{') {
+                /* The "{" is escaped, so skip it */
+                cmd_start += 2;
+                buf_start++;
+                user_data->bufoff++;
+                user_data->buflen--;
+                outlen--;
+                continue;
+            }
+            break;
+        }
+
+        if (cmd_start == buf_start) {
+            /* Command detected */
+            char *cmd_end = strchr(cmd_start, '}');
+            char *arg_start;
+            int cmd = -1, ret = USER_DATA_PROCESS_NO_DATA;
+            size_t oldoff;
+
+            if (cmd_end == NULL) {
+                /* Malformed command */
+                cmd_start[outlen - 1] = '\0';
+                BIO_printf(bio_err,
+                           "ERROR PROCESSING COMMAND. REST OF LINE IGNORED: %s\n",
+                           cmd_start);
+                user_data->buflen = user_data->bufoff = *len = *off = 0;
+                return USER_DATA_PROCESS_NO_DATA;
+            }
+            *cmd_end = '\0';
+            arg_start = strchr(cmd_start, ':');
+            if (arg_start != NULL) {
+                *arg_start = '\0';
+                arg_start++;
+            }
+            /* Skip over the { */
+            cmd_start++;
+            /*
+             * Now we have cmd_start pointing to a NUL terminated string for
+             * the command, and arg_start either being NULL or pointing to a
+             * NUL terminated string for the argument.
+             */
+            if (OPENSSL_strcasecmp(cmd_start, "help") == 0) {
+                cmd = USER_COMMAND_HELP;
+            } else if (OPENSSL_strcasecmp(cmd_start, "quit") == 0) {
+                cmd = USER_COMMAND_QUIT;
+            } else if (OPENSSL_strcasecmp(cmd_start, "reconnect") == 0) {
+                cmd = USER_COMMAND_RECONNECT;
+            } else if(SSL_is_quic(user_data->con)) {
+                if (OPENSSL_strcasecmp(cmd_start, "fin") == 0)
+                    cmd = USER_COMMAND_FIN;
+            } if (SSL_version(user_data->con) == TLS1_3_VERSION) {
+                if (OPENSSL_strcasecmp(cmd_start, "keyup") == 0) {
+                    cmd = USER_COMMAND_KEY_UPDATE;
+                    if (arg_start == NULL)
+                        arg_start = "req";
+                }
+            } else {
+                /* (D)TLSv1.2 or below */
+                if (OPENSSL_strcasecmp(cmd_start, "reneg") == 0)
+                    cmd = USER_COMMAND_RENEGOTIATE;
+            }
+            if (cmd == -1) {
+                BIO_printf(bio_err, "UNRECOGNISED COMMAND (IGNORED): %s\n",
+                           cmd_start);
+            } else {
+                ret = user_data_execute(user_data, cmd, arg_start);
+                if (ret == USER_DATA_PROCESS_BAD_ARGUMENT) {
+                    BIO_printf(bio_err, "BAD ARGUMENT (COMMAND IGNORED): %s\n",
+                               arg_start);
+                    ret = USER_DATA_PROCESS_NO_DATA;
+                }
+            }
+            oldoff = user_data->bufoff;
+            user_data->bufoff = (cmd_end - user_data->buf) + 1;
+            user_data->buflen -= user_data->bufoff - oldoff;
+            if (user_data->buf + 1 == cmd_start
+                    && user_data->buflen == 1
+                    && user_data->buf[user_data->bufoff] == '\n') {
+                /*
+                 * This command was the only thing on the whole line. We
+                 * suppress the final `\n`
+                 */
+                user_data->bufoff = 0;
+                user_data->buflen = 0;
+            }
+            *len = *off = 0;
+            return ret;
+        } else if (cmd_start != NULL) {
+            /*
+             * There is a command on this line, but its not at the start. Output
+             * the start of the line, and we'll process the command next time
+             * we call this function
+             */
+            outlen = cmd_start - buf_start;
+        }
+    }
+
+    if (user_data->isfin) {
+        user_data->buflen = user_data->bufoff = *len = *off = 0;
+        return USER_DATA_PROCESS_NO_DATA;
+    }
+
+#ifdef CHARSET_EBCDIC
+    ebcdic2ascii(buf_start, buf_start, outlen);
+#endif
+    *len = outlen;
+    *off = user_data->bufoff;
+    user_data->buflen -= outlen;
+    if (user_data->buflen == 0)
+        user_data->bufoff = 0;
+    else
+        user_data->bufoff += outlen;
+    return USER_DATA_PROCESS_CONTINUE;
+}
+
+static int user_data_has_data(struct user_data_st *user_data)
+{
+    return user_data->buflen > 0;
+}
 #endif                          /* OPENSSL_NO_SOCK */

+ 125 - 33
libs/openssl/apps/s_server.c

@@ -96,9 +96,13 @@ static int keymatexportlen = 20;
 static int async = 0;
 
 static int use_sendfile = 0;
+static int use_zc_sendfile = 0;
 
 static const char *session_id_prefix = NULL;
 
+static const unsigned char cert_type_rpk[] = { TLSEXT_cert_type_rpk, TLSEXT_cert_type_x509 };
+static int enable_client_rpk = 0;
+
 #ifndef OPENSSL_NO_DTLS
 static int enable_timeouts = 0;
 static long socket_mtu;
@@ -262,7 +266,7 @@ typedef struct {
     char buff[1];
 } EBCDIC_OUTBUFF;
 
-static const BIO_METHOD *BIO_f_ebcdic_filter()
+static const BIO_METHOD *BIO_f_ebcdic_filter(void)
 {
     if (methods_ebcdic == NULL) {
         methods_ebcdic = BIO_meth_new(BIO_TYPE_EBCDIC_FILTER,
@@ -716,7 +720,11 @@ typedef enum OPTION_choice {
     OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
     OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA,
     OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY, OPT_SCTP_LABEL_BUG,
-    OPT_HTTP_SERVER_BINMODE, OPT_NOCANAMES, OPT_IGNORE_UNEXPECTED_EOF,
+    OPT_HTTP_SERVER_BINMODE, OPT_NOCANAMES, OPT_IGNORE_UNEXPECTED_EOF, OPT_KTLS,
+    OPT_USE_ZC_SENDFILE,
+    OPT_TFO, OPT_CERT_COMP,
+    OPT_ENABLE_SERVER_RPK,
+    OPT_ENABLE_CLIENT_RPK,
     OPT_R_ENUM,
     OPT_S_ENUM,
     OPT_V_ENUM,
@@ -747,6 +755,9 @@ const OPTIONS s_server_options[] = {
 #endif
     {"4", OPT_4, '-', "Use IPv4 only"},
     {"6", OPT_6, '-', "Use IPv6 only"},
+#if defined(TCP_FASTOPEN) && !defined(OPENSSL_NO_TFO)
+    {"tfo", OPT_TFO, '-', "Listen for TCP Fast Open connections"},
+#endif
 
     OPT_SECTION("Identity"),
     {"context", OPT_CONTEXT, 's', "Set session ID context"},
@@ -840,6 +851,9 @@ const OPTIONS s_server_options[] = {
      "No verify output except verify errors"},
     {"ign_eof", OPT_IGN_EOF, '-', "Ignore input EOF (default when -quiet)"},
     {"no_ign_eof", OPT_NO_IGN_EOF, '-', "Do not ignore input EOF"},
+#ifndef OPENSSL_NO_COMP_ALG
+    {"cert_comp", OPT_CERT_COMP, '-', "Pre-compress server certificates"},
+#endif
 
 #ifndef OPENSSL_NO_OCSP
     OPT_SECTION("OCSP"),
@@ -958,9 +972,12 @@ const OPTIONS s_server_options[] = {
     {"alpn", OPT_ALPN, 's',
      "Set the advertised protocols for the ALPN extension (comma-separated list)"},
 #ifndef OPENSSL_NO_KTLS
+    {"ktls", OPT_KTLS, '-', "Enable Kernel TLS for sending and receiving"},
     {"sendfile", OPT_SENDFILE, '-', "Use sendfile to response file with -WWW"},
+    {"zerocopy_sendfile", OPT_USE_ZC_SENDFILE, '-', "Use zerocopy mode of KTLS sendfile"},
 #endif
-
+    {"enable_server_rpk", OPT_ENABLE_SERVER_RPK, '-', "Enable raw public keys (RFC7250) from the server"},
+    {"enable_client_rpk", OPT_ENABLE_CLIENT_RPK, '-', "Enable raw public keys (RFC7250) from the client"},
     OPT_R_OPTIONS,
     OPT_S_OPTIONS,
     OPT_V_OPTIONS,
@@ -1053,6 +1070,12 @@ int s_server_main(int argc, char *argv[])
     int sctp_label_bug = 0;
 #endif
     int ignore_unexpected_eof = 0;
+#ifndef OPENSSL_NO_KTLS
+    int enable_ktls = 0;
+#endif
+    int tfo = 0;
+    int cert_comp = 0;
+    int enable_server_rpk = 0;
 
     /* Init of few remaining global variables */
     local_argc = argc;
@@ -1068,6 +1091,7 @@ int s_server_main(int argc, char *argv[])
     s_brief = 0;
     async = 0;
     use_sendfile = 0;
+    use_zc_sendfile = 0;
 
     port = OPENSSL_strdup(PORT);
     cctx = SSL_CONF_CTX_new();
@@ -1634,20 +1658,41 @@ int s_server_main(int argc, char *argv[])
         case OPT_NOCANAMES:
             no_ca_names = 1;
             break;
+        case OPT_KTLS:
+#ifndef OPENSSL_NO_KTLS
+            enable_ktls = 1;
+#endif
+            break;
         case OPT_SENDFILE:
 #ifndef OPENSSL_NO_KTLS
             use_sendfile = 1;
+#endif
+            break;
+        case OPT_USE_ZC_SENDFILE:
+#ifndef OPENSSL_NO_KTLS
+            use_zc_sendfile = 1;
 #endif
             break;
         case OPT_IGNORE_UNEXPECTED_EOF:
             ignore_unexpected_eof = 1;
             break;
+        case OPT_TFO:
+            tfo = 1;
+            break;
+        case OPT_CERT_COMP:
+            cert_comp = 1;
+            break;
+        case OPT_ENABLE_SERVER_RPK:
+            enable_server_rpk = 1;
+            break;
+        case OPT_ENABLE_CLIENT_RPK:
+            enable_client_rpk = 1;
+            break;
         }
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     if (!app_RAND_load())
@@ -1671,6 +1716,11 @@ int s_server_main(int argc, char *argv[])
     }
 #endif
 
+    if (tfo && socket_type != SOCK_STREAM) {
+        BIO_printf(bio_err, "Can only use -tfo with TLS\n");
+        goto end;
+    }
+
     if (stateless && socket_type != SOCK_STREAM) {
         BIO_printf(bio_err, "Can only use --stateless with TLS\n");
         goto end;
@@ -1701,6 +1751,16 @@ int s_server_main(int argc, char *argv[])
 #endif
 
 #ifndef OPENSSL_NO_KTLS
+    if (use_zc_sendfile && !use_sendfile) {
+        BIO_printf(bio_out, "Warning: -zerocopy_sendfile depends on -sendfile, enabling -sendfile now.\n");
+        use_sendfile = 1;
+    }
+
+    if (use_sendfile && enable_ktls == 0) {
+        BIO_printf(bio_out, "Warning: -sendfile depends on -ktls, enabling -ktls now.\n");
+        enable_ktls = 1;
+    }
+
     if (use_sendfile && www <= 1) {
         BIO_printf(bio_err, "Can't use -sendfile without -WWW or -HTTP\n");
         goto end;
@@ -1898,6 +1958,12 @@ int s_server_main(int argc, char *argv[])
 
     if (ignore_unexpected_eof)
         SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
+#ifndef OPENSSL_NO_KTLS
+    if (enable_ktls)
+        SSL_CTX_set_options(ctx, SSL_OP_ENABLE_KTLS);
+    if (use_zc_sendfile)
+        SSL_CTX_set_options(ctx, SSL_OP_ENABLE_KTLS_TX_ZEROCOPY_SENDFILE);
+#endif
 
     if (max_send_fragment > 0
         && !SSL_CTX_set_max_send_fragment(ctx, max_send_fragment)) {
@@ -2214,6 +2280,24 @@ int s_server_main(int argc, char *argv[])
     if (recv_max_early_data >= 0)
         SSL_CTX_set_recv_max_early_data(ctx, recv_max_early_data);
 
+    if (cert_comp) {
+        BIO_printf(bio_s_out, "Compressing certificates\n");
+        if (!SSL_CTX_compress_certs(ctx, 0))
+            BIO_printf(bio_s_out, "Error compressing certs on ctx\n");
+        if (ctx2 != NULL && !SSL_CTX_compress_certs(ctx2, 0))
+            BIO_printf(bio_s_out, "Error compressing certs on ctx2\n");
+    }
+    if (enable_server_rpk)
+        if (!SSL_CTX_set1_server_cert_type(ctx, cert_type_rpk, sizeof(cert_type_rpk))) {
+            BIO_printf(bio_s_out, "Error setting server certificate types\n");
+            goto end;
+        }
+    if (enable_client_rpk)
+        if (!SSL_CTX_set1_client_cert_type(ctx, cert_type_rpk, sizeof(cert_type_rpk))) {
+            BIO_printf(bio_s_out, "Error setting server certificate types\n");
+            goto end;
+        }
+
     if (rev)
         server_cb = rev_body;
     else if (www)
@@ -2225,8 +2309,10 @@ int s_server_main(int argc, char *argv[])
         && unlink_unix_path)
         unlink(host);
 #endif
+    if (tfo)
+        BIO_printf(bio_s_out, "Listening for TFO\n");
     do_server(&accept_socket, host, port, socket_family, socket_type, protocol,
-              server_cb, context, naccept, bio_s_out);
+              server_cb, context, naccept, bio_s_out, tfo);
     print_stats(bio_s_out, ctx);
     ret = 0;
  end:
@@ -2238,8 +2324,8 @@ int s_server_main(int argc, char *argv[])
     X509_free(s_dcert);
     EVP_PKEY_free(s_key);
     EVP_PKEY_free(s_dkey);
-    sk_X509_pop_free(s_chain, X509_free);
-    sk_X509_pop_free(s_dchain, X509_free);
+    OSSL_STACK_OF_X509_free(s_chain);
+    OSSL_STACK_OF_X509_free(s_dchain);
     OPENSSL_free(pass);
     OPENSSL_free(dpass);
     OPENSSL_free(host);
@@ -2327,7 +2413,7 @@ static int sv_body(int s, int stype, int prot, unsigned char *context)
     char *buf = NULL;
     fd_set readfds;
     int ret = 1, width;
-    int k, i;
+    int k;
     unsigned long l;
     SSL *con = NULL;
     BIO *sbio;
@@ -2443,7 +2529,6 @@ static int sv_body(int s, int stype, int prot, unsigned char *context)
             BIO_free(sbio);
             goto err;
         }
-
         sbio = BIO_push(test, sbio);
     }
 
@@ -2515,6 +2600,7 @@ static int sv_body(int s, int stype, int prot, unsigned char *context)
     else
         width = s + 1;
     for (;;) {
+        int i;
         int read_from_terminal;
         int read_from_sslcon;
 
@@ -2614,7 +2700,6 @@ static int sv_body(int s, int stype, int prot, unsigned char *context)
                     SSL_renegotiate(con);
                     i = SSL_do_handshake(con);
                     printf("SSL_do_handshake -> %d\n", i);
-                    i = 0;      /* 13; */
                     continue;
                 }
                 if ((buf[0] == 'R') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
@@ -2624,7 +2709,6 @@ static int sv_body(int s, int stype, int prot, unsigned char *context)
                     SSL_renegotiate(con);
                     i = SSL_do_handshake(con);
                     printf("SSL_do_handshake -> %d\n", i);
-                    i = 0;      /* 13; */
                     continue;
                 }
                 if ((buf[0] == 'K' || buf[0] == 'k')
@@ -2634,7 +2718,6 @@ static int sv_body(int s, int stype, int prot, unsigned char *context)
                                         : SSL_KEY_UPDATE_NOT_REQUESTED);
                     i = SSL_do_handshake(con);
                     printf("SSL_do_handshake -> %d\n", i);
-                    i = 0;
                     continue;
                 }
                 if (buf[0] == 'c' && ((buf[1] == '\n') || (buf[1] == '\r'))) {
@@ -2646,7 +2729,6 @@ static int sv_body(int s, int stype, int prot, unsigned char *context)
                     } else {
                         i = SSL_do_handshake(con);
                         printf("SSL_do_handshake -> %d\n", i);
-                        i = 0;
                     }
                     continue;
                 }
@@ -2963,6 +3045,19 @@ static void print_connection_info(SSL *con)
         dump_cert_text(bio_s_out, peer);
         peer = NULL;
     }
+    /* Only display RPK information if configured */
+    if (SSL_get_negotiated_server_cert_type(con) == TLSEXT_cert_type_rpk)
+        BIO_printf(bio_s_out, "Server-to-client raw public key negotiated\n");
+    if (SSL_get_negotiated_client_cert_type(con) == TLSEXT_cert_type_rpk)
+        BIO_printf(bio_s_out, "Client-to-server raw public key negotiated\n");
+    if (enable_client_rpk) {
+        EVP_PKEY *client_rpk = SSL_get0_peer_rpk(con);
+
+        if (client_rpk != NULL) {
+            BIO_printf(bio_s_out, "Client raw public key\n");
+            EVP_PKEY_print_public(bio_s_out, client_rpk, 2, NULL);
+        }
+    }
 
     if (SSL_get_shared_ciphers(con, buf, sizeof(buf)) != NULL)
         BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf);
@@ -3032,7 +3127,7 @@ static void print_connection_info(SSL *con)
 
 static int www_body(int s, int stype, int prot, unsigned char *context)
 {
-    char *buf = NULL;
+    char *buf = NULL, *p;
     int ret = 1;
     int i, j, k, dot;
     SSL *con;
@@ -3056,7 +3151,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
 
     /* as we use BIO_gets(), and it always null terminates data, we need
      * to allocate 1 byte longer buffer to fit the full 2^14 byte record */
-    buf = app_malloc(bufsize + 1, "server www buffer");
+    p = buf = app_malloc(bufsize + 1, "server www buffer");
     io = BIO_new(BIO_f_buffer());
     ssl_bio = BIO_new(BIO_f_ssl());
     if ((io == NULL) || (ssl_bio == NULL))
@@ -3154,7 +3249,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
                     continue;
                 }
 #endif
-                ossl_sleep(1000);
+                OSSL_sleep(1000);
                 continue;
             }
         } else if (i == 0) {    /* end of input */
@@ -3163,15 +3258,14 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
         }
 
         /* else we have data */
-        if (((www == 1) && (strncmp("GET ", buf, 4) == 0)) ||
-            ((www == 2) && (strncmp("GET /stats ", buf, 11) == 0))) {
-            char *p;
+        if ((www == 1 && HAS_PREFIX(buf, "GET "))
+             || (www == 2 && HAS_PREFIX(buf, "GET /stats "))) {
             X509 *peer = NULL;
             STACK_OF(SSL_CIPHER) *sk;
             static const char *space = "                          ";
 
-            if (www == 1 && strncmp("GET /reneg", buf, 10) == 0) {
-                if (strncmp("GET /renegcert", buf, 14) == 0)
+            if (www == 1 && HAS_PREFIX(buf, "GET /reneg")) {
+                if (HAS_PREFIX(buf, "GET /renegcert"))
                     SSL_set_verify(con,
                                    SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE,
                                    NULL);
@@ -3212,6 +3306,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
             BIO_puts(io, "\n");
             for (i = 0; i < local_argc; i++) {
                 const char *myp;
+
                 for (myp = local_argv[i]; *myp; myp++)
                     switch (*myp) {
                     case '<':
@@ -3291,16 +3386,12 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
             }
             BIO_puts(io, "</pre></BODY></HTML>\r\n\r\n");
             break;
-        } else if ((www == 2 || www == 3)
-                   && (strncmp("GET /", buf, 5) == 0)) {
+        } else if ((www == 2 || www == 3) && CHECK_AND_SKIP_PREFIX(p, "GET /")) {
             BIO *file;
-            char *p, *e;
+            char *e;
             static const char *text =
                 "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
 
-            /* skip the '/' */
-            p = &(buf[5]);
-
             dot = 1;
             for (e = p; *e != '\0'; e++) {
                 if (e[0] == ' ')
@@ -3473,7 +3564,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
             break;
     }
  end:
-    /* make sure we re-use sessions */
+    /* make sure we reuse sessions */
     do_ssl_shutdown(con);
 
  err:
@@ -3599,7 +3690,7 @@ static int rev_body(int s, int stype, int prot, unsigned char *context)
                     continue;
                 }
 #endif
-                ossl_sleep(1000);
+                OSSL_sleep(1000);
                 continue;
             }
         } else if (i == 0) {    /* end of input */
@@ -3612,7 +3703,7 @@ static int rev_body(int s, int stype, int prot, unsigned char *context)
                 p--;
                 i--;
             }
-            if (!s_ign_eof && (i == 5) && (strncmp(buf, "CLOSE", 5) == 0)) {
+            if (!s_ign_eof && i == 5 && HAS_PREFIX(buf, "CLOSE")) {
                 ret = 1;
                 BIO_printf(bio_err, "CONNECTION CLOSED\n");
                 goto end;
@@ -3630,7 +3721,7 @@ static int rev_body(int s, int stype, int prot, unsigned char *context)
         }
     }
  end:
-    /* make sure we re-use sessions */
+    /* make sure we reuse sessions */
     do_ssl_shutdown(con);
 
  err:
@@ -3734,7 +3825,8 @@ static SSL_SESSION *get_session(SSL *ssl, const unsigned char *id, int idlen,
         if (idlen == (int)sess->idlen && !memcmp(sess->id, id, idlen)) {
             const unsigned char *p = sess->der;
             BIO_printf(bio_err, "Lookup session: cache hit\n");
-            return d2i_SSL_SESSION(NULL, &p, sess->derlen);
+            return d2i_SSL_SESSION_ex(NULL, &p, sess->derlen, app_get0_libctx(),
+                                      app_get0_propq());
         }
     }
     BIO_printf(bio_err, "Lookup session: cache miss\n");

+ 1 - 2
libs/openssl/apps/s_time.c

@@ -234,8 +234,7 @@ int s_time_main(int argc, char **argv)
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     if (cipher == NULL)

+ 1 - 2
libs/openssl/apps/sess_id.c

@@ -98,8 +98,7 @@ int sess_id_main(int argc, char **argv)
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     x = load_sess_id(infile, informat);

+ 45 - 14
libs/openssl/apps/smime.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -28,9 +28,9 @@ static int smime_cb(int ok, X509_STORE_CTX *ctx);
 #define SMIME_ENCRYPT   (1 | SMIME_OP)
 #define SMIME_DECRYPT   (2 | SMIME_IP)
 #define SMIME_SIGN      (3 | SMIME_OP | SMIME_SIGNERS)
+#define SMIME_RESIGN    (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
 #define SMIME_VERIFY    (4 | SMIME_IP)
 #define SMIME_PK7OUT    (5 | SMIME_IP | SMIME_OP)
-#define SMIME_RESIGN    (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
 
 typedef enum OPTION_choice {
     OPT_COMMON,
@@ -75,12 +75,12 @@ const OPTIONS smime_options[] = {
     {"sign", OPT_SIGN, '-', "Sign message"},
     {"resign", OPT_RESIGN, '-', "Resign a signed message"},
     {"verify", OPT_VERIFY, '-', "Verify signed message"},
+    {"pk7out", OPT_PK7OUT, '-', "Output PKCS#7 structure"},
 
     OPT_SECTION("Signing/Encryption"),
     {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
     {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"},
     {"", OPT_CIPHER, '-', "Any supported cipher"},
-    {"pk7out", OPT_PK7OUT, '-', "Output PKCS#7 structure"},
     {"nointern", OPT_NOINTERN, '-',
      "Don't search certificates in message for signer"},
     {"nodetach", OPT_NODETACH, '-', "Use opaque signing"},
@@ -129,6 +129,32 @@ const OPTIONS smime_options[] = {
     {NULL}
 };
 
+static const char *operation_name(int operation)
+{
+    switch (operation) {
+    case SMIME_ENCRYPT:
+        return "encrypt";
+    case SMIME_DECRYPT:
+        return "decrypt";
+    case SMIME_SIGN:
+        return "sign";
+    case SMIME_RESIGN:
+        return "resign";
+    case SMIME_VERIFY:
+        return "verify";
+    case SMIME_PK7OUT:
+        return "pk7out";
+    default:
+        return "(invalid operation)";
+    }
+}
+
+#define SET_OPERATION(op) \
+    ((operation != 0 && (operation != (op))) \
+     ? 0 * BIO_printf(bio_err, "%s: Cannot use -%s together with -%s\n", \
+                      prog, operation_name(op), operation_name(operation)) \
+     : (operation = (op)))
+
 int smime_main(int argc, char **argv)
 {
     CONF *conf = NULL;
@@ -160,6 +186,7 @@ int smime_main(int argc, char **argv)
     if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
         return 1;
 
+    opt_set_unknown_name("cipher");
     prog = opt_init(argc, argv, smime_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -187,22 +214,28 @@ int smime_main(int argc, char **argv)
             outfile = opt_arg();
             break;
         case OPT_ENCRYPT:
-            operation = SMIME_ENCRYPT;
+            if (!SET_OPERATION(SMIME_ENCRYPT))
+                goto end;
             break;
         case OPT_DECRYPT:
-            operation = SMIME_DECRYPT;
+            if (!SET_OPERATION(SMIME_DECRYPT))
+                goto end;
             break;
         case OPT_SIGN:
-            operation = SMIME_SIGN;
+            if (!SET_OPERATION(SMIME_SIGN))
+                goto end;
             break;
         case OPT_RESIGN:
-            operation = SMIME_RESIGN;
+            if (!SET_OPERATION(SMIME_RESIGN))
+                goto end;
             break;
         case OPT_VERIFY:
-            operation = SMIME_VERIFY;
+            if (!SET_OPERATION(SMIME_VERIFY))
+                goto end;
             break;
         case OPT_PK7OUT:
-            operation = SMIME_PK7OUT;
+            if (!SET_OPERATION(SMIME_PK7OUT))
+                goto end;
             break;
         case OPT_TEXT:
             flags |= PKCS7_TEXT;
@@ -366,10 +399,8 @@ int smime_main(int argc, char **argv)
         if (!opt_md(digestname, &sign_md))
             goto opthelp;
     }
-    if (ciphername != NULL) {
-        if (!opt_cipher_any(ciphername, &cipher))
+    if (!opt_cipher_any(ciphername, &cipher))
             goto opthelp;
-    }
     if (!(operation & SMIME_SIGNERS) && (skkeys != NULL || sksigners != NULL)) {
         BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
         goto opthelp;
@@ -653,8 +684,8 @@ int smime_main(int argc, char **argv)
  end:
     if (ret)
         ERR_print_errors(bio_err);
-    sk_X509_pop_free(encerts, X509_free);
-    sk_X509_pop_free(other, X509_free);
+    OSSL_STACK_OF_X509_free(encerts);
+    OSSL_STACK_OF_X509_free(other);
     X509_VERIFY_PARAM_free(vpm);
     sk_OPENSSL_STRING_free(sksigners);
     sk_OPENSSL_STRING_free(skkeys);

文件差异内容过多而无法显示
+ 547 - 91
libs/openssl/apps/speed.c


+ 6 - 6
libs/openssl/apps/spkac.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -133,8 +133,7 @@ int spkac_main(int argc, char **argv)
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     if (!app_passwd(passinarg, NULL, &passin, NULL)) {
@@ -153,9 +152,10 @@ int spkac_main(int argc, char **argv)
         spki = NETSCAPE_SPKI_new();
         if (spki == NULL)
             goto end;
-        if (challenge != NULL)
-            ASN1_STRING_set(spki->spkac->challenge,
-                            challenge, (int)strlen(challenge));
+        if (challenge != NULL
+            && !ASN1_STRING_set(spki->spkac->challenge,
+                                challenge, (int)strlen(challenge)))
+            goto end;
         if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) {
             BIO_printf(bio_err, "Error setting public key\n");
             goto end;

+ 7 - 8
libs/openssl/apps/storeutl.c

@@ -74,7 +74,7 @@ int storeutl_main(int argc, char *argv[])
     BIO *out = NULL;
     ENGINE *e = NULL;
     OPTION_CHOICE o;
-    char *prog = opt_init(argc, argv, storeutl_options);
+    char *prog;
     PW_CB_DATA pw_cb_data;
     int expected = 0;
     int criterion = 0;
@@ -87,6 +87,8 @@ int storeutl_main(int argc, char *argv[])
     EVP_MD *digest = NULL;
     OSSL_LIB_CTX *libctx = app_get0_libctx();
 
+    opt_set_unknown_name("digest");
+    prog = opt_init(argc, argv, storeutl_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
         case OPT_EOF:
@@ -256,15 +258,12 @@ int storeutl_main(int argc, char *argv[])
     }
 
     /* One argument, the URI */
-    argc = opt_num_rest();
-    argv = opt_rest();
-    if (argc != 1)
+    if (!opt_check_rest_arg("URI"))
         goto opthelp;
+    argv = opt_rest();
 
-    if (digestname != NULL) {
-        if (!opt_md(digestname, &digest))
-            goto opthelp;
-    }
+    if (!opt_md(digestname, &digest))
+        goto opthelp;
 
     if (criterion != 0) {
         switch (criterion) {

+ 14 - 11
libs/openssl/apps/ts.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -181,6 +181,7 @@ int ts_main(int argc, char **argv)
     if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
         goto end;
 
+    opt_set_unknown_name("digest");
     prog = opt_init(argc, argv, ts_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -204,8 +205,10 @@ int ts_main(int argc, char **argv)
         case OPT_QUERY:
         case OPT_REPLY:
         case OPT_VERIFY:
-            if (mode != OPT_ERR)
+            if (mode != OPT_ERR) {
+                BIO_printf(bio_err, "%s: Must give only one of -query, -reply, or -verify\n", prog);
                 goto opthelp;
+            }
             mode = o;
             break;
         case OPT_DATA:
@@ -288,17 +291,18 @@ int ts_main(int argc, char **argv)
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0 || mode == OPT_ERR)
+    if (!opt_check_rest_arg(NULL))
+        goto opthelp;
+    if (mode == OPT_ERR) {
+        BIO_printf(bio_err, "%s: Must give one of -query, -reply, or -verify\n", prog);
         goto opthelp;
+    }
 
     if (!app_RAND_load())
         goto end;
 
-    if (digestname != NULL) {
-        if (!opt_md(digestname, &md))
-            goto opthelp;
-    }
+    if (!opt_md(digestname, &md))
+        goto opthelp;
     if (mode == OPT_REPLY && passin &&
         !app_passwd(passin, NULL, &password, NULL)) {
         BIO_printf(bio_err, "Error getting password.\n");
@@ -371,7 +375,7 @@ static CONF *load_config_file(const char *configfile)
         const char *p;
 
         BIO_printf(bio_err, "Using configuration from %s\n", configfile);
-        p = NCONF_get_string(conf, NULL, ENV_OID_FILE);
+        p = app_conf_try_string(conf, NULL, ENV_OID_FILE);
         if (p != NULL) {
             BIO *oid_bio = BIO_new_file(p, "r");
             if (!oid_bio)
@@ -380,8 +384,7 @@ static CONF *load_config_file(const char *configfile)
                 OBJ_create_objects(oid_bio);
                 BIO_free_all(oid_bio);
             }
-        } else
-            ERR_clear_error();
+        }
         if (!add_oid_section(conf))
             ERR_print_errors(bio_err);
     }

+ 1 - 1
libs/openssl/apps/tsget.in

@@ -1,5 +1,5 @@
 #!{- $config{HASHBANGPERL} -}
-# Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
 # Copyright (c) 2002 The OpenTSA Project. All rights reserved.
 #
 # Licensed under the Apache License 2.0 (the "License").  You may not use

+ 3 - 3
libs/openssl/apps/verify.c

@@ -234,8 +234,8 @@ int verify_main(int argc, char **argv)
  end:
     X509_VERIFY_PARAM_free(vpm);
     X509_STORE_free(store);
-    sk_X509_pop_free(untrusted, X509_free);
-    sk_X509_pop_free(trusted, X509_free);
+    OSSL_STACK_OF_X509_free(untrusted);
+    OSSL_STACK_OF_X509_free(trusted);
     sk_X509_CRL_pop_free(crls, X509_CRL_free);
     sk_OPENSSL_STRING_free(vfyopts);
     release_engine(e);
@@ -308,7 +308,7 @@ static int check(X509_STORE *ctx, const char *file,
                     BIO_printf(bio_out, " (untrusted)");
                 BIO_printf(bio_out, "\n");
             }
-            sk_X509_pop_free(chain, X509_free);
+            OSSL_STACK_OF_X509_free(chain);
         }
     } else {
         BIO_printf(bio_err,

+ 1 - 2
libs/openssl/apps/version.c

@@ -99,8 +99,7 @@ opthelp:
     }
 
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     if (!dirty)

+ 68 - 63
libs/openssl/apps/x509.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -70,7 +70,7 @@ const OPTIONS x509_options[] = {
     {"copy_extensions", OPT_COPY_EXTENSIONS, 's',
      "copy extensions when converting from CSR to x509 or vice versa"},
     {"inform", OPT_INFORM, 'f',
-     "CSR input file format (DER or PEM) - default PEM"},
+     "CSR input format to use (PEM or DER; by default try PEM first)"},
     {"vfyopt", OPT_VFYOPT, 's', "CSR verification parameter in n:v form"},
     {"key", OPT_KEY, 's',
      "Key for signing, and to include unless using -force_pubkey"},
@@ -87,7 +87,8 @@ const OPTIONS x509_options[] = {
 
     OPT_SECTION("Certificate printing"),
     {"text", OPT_TEXT, '-', "Print the certificate in text form"},
-    {"dateopt", OPT_DATEOPT, 's', "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."},
+    {"dateopt", OPT_DATEOPT, 's',
+     "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."},
     {"certopt", OPT_CERTOPT, 's', "Various certificate text printing options"},
     {"fingerprint", OPT_FINGERPRINT, '-', "Print the certificate fingerprint"},
     {"alias", OPT_ALIAS, '-', "Print certificate alias"},
@@ -139,7 +140,7 @@ const OPTIONS x509_options[] = {
      "Preserve existing validity dates"},
     {"subj", OPT_SUBJ, 's', "Set or override certificate subject (and issuer)"},
     {"force_pubkey", OPT_FORCE_PUBKEY, '<',
-     "Place the given key in new certificate"},
+     "Key to be placed in new certificate or certificate request"},
     {"clrext", OPT_CLREXT, '-',
      "Do not take over any extensions from the source certificate or request"},
     {"extfile", OPT_EXTFILE, '<', "Config file with X509V3 extensions to add"},
@@ -299,9 +300,10 @@ int x509_main(int argc, char **argv)
 
     ctx = X509_STORE_new();
     if (ctx == NULL)
-        goto end;
+        goto err;
     X509_STORE_set_verify_cb(ctx, callb);
 
+    opt_set_unknown_name("digest");
     prog = opt_init(argc, argv, x509_options);
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
@@ -309,7 +311,7 @@ int x509_main(int argc, char **argv)
         case OPT_ERR:
  opthelp:
             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
-            goto end;
+            goto err;
         case OPT_HELP:
             opt_help(x509_options);
             ret = 0;
@@ -348,14 +350,14 @@ int x509_main(int argc, char **argv)
             if (!set_dateopt(&dateopt, opt_arg())) {
                 BIO_printf(bio_err,
                            "Invalid date format: %s\n", opt_arg());
-                goto end;
+                goto err;
             }
             break;
         case OPT_COPY_EXTENSIONS:
             if (!set_ext_copy(&ext_copy, opt_arg())) {
                 BIO_printf(bio_err,
                            "Invalid extension copy option: %s\n", opt_arg());
-                goto end;
+                goto err;
             }
             break;
 
@@ -376,7 +378,7 @@ int x509_main(int argc, char **argv)
             if (days < -1) {
                 BIO_printf(bio_err, "%s: -days parameter arg must be >= -1\n",
                            prog);
-                goto end;
+                goto err;
             }
             break;
         case OPT_PASSIN:
@@ -592,25 +594,26 @@ int x509_main(int argc, char **argv)
             break;
         }
     }
-
     /* No extra arguments. */
-    argc = opt_num_rest();
-    if (argc != 0)
+    if (!opt_check_rest_arg(NULL))
         goto opthelp;
 
     if (!app_RAND_load())
         goto end;
 
+    if (!opt_check_md(digest))
+        goto opthelp;
+
     if (preserve_dates && days != UNSET_DAYS) {
         BIO_printf(bio_err, "Cannot use -preserve_dates with -days option\n");
-        goto end;
+        goto err;
     }
     if (days == UNSET_DAYS)
         days = DEFAULT_DAYS;
 
     if (!app_passwd(passinarg, NULL, &passin, NULL)) {
         BIO_printf(bio_err, "Error getting password\n");
-        goto end;
+        goto err;
     }
 
     if (!X509_STORE_set_default_paths_ex(ctx, app_get0_libctx(),
@@ -619,12 +622,11 @@ int x509_main(int argc, char **argv)
 
     if (newcert && infile != NULL) {
         BIO_printf(bio_err, "The -in option cannot be used with -new\n");
-        goto end;
+        goto err;
     }
     if (newcert && reqfile) {
-        BIO_printf(bio_err,
-                   "The -req option cannot be used with -new\n");
-        goto end;
+        BIO_printf(bio_err, "The -req option cannot be used with -new\n");
+        goto err;
     }
     if (privkeyfile != NULL) {
         privkey = load_key(privkeyfile, keyformat, 0, passin, e, "private key");
@@ -641,12 +643,12 @@ int x509_main(int argc, char **argv)
         if (subj == NULL) {
             BIO_printf(bio_err,
                        "The -new option requires a subject to be set using -subj\n");
-            goto end;
+            goto err;
         }
         if (privkeyfile == NULL && pubkeyfile == NULL) {
             BIO_printf(bio_err,
                        "The -new option requires using the -key or -force_pubkey option\n");
-            goto end;
+            goto err;
         }
     }
     if (subj != NULL
@@ -658,7 +660,7 @@ int x509_main(int argc, char **argv)
     if (CAfile != NULL) {
         if (privkeyfile != NULL) {
             BIO_printf(bio_err, "Cannot use both -key/-signkey and -CA option\n");
-            goto end;
+            goto err;
         }
     } else {
 #define WARN_NO_CA(opt) BIO_printf(bio_err, \
@@ -685,36 +687,38 @@ int x509_main(int argc, char **argv)
         if ((extconf = app_load_config(extfile)) == NULL)
             goto end;
         if (extsect == NULL) {
-            extsect = NCONF_get_string(extconf, "default", "extensions");
-            if (extsect == NULL) {
-                ERR_clear_error();
+            extsect = app_conf_try_string(extconf, "default", "extensions");
+            if (extsect == NULL)
                 extsect = "default";
-            }
         }
         X509V3_set_ctx_test(&ctx2);
         X509V3_set_nconf(&ctx2, extconf);
         if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) {
             BIO_printf(bio_err,
                        "Error checking extension section %s\n", extsect);
-            goto end;
+            goto err;
         }
     }
 
     if (reqfile) {
-        req = load_csr(infile, informat, "certificate request input");
+        if (infile == NULL)
+            BIO_printf(bio_err,
+                       "Warning: Reading cert request from stdin since no -in option is given\n");
+        req = load_csr_autofmt(infile, informat, vfyopts,
+                               "certificate request input");
         if (req == NULL)
             goto end;
 
         if ((pkey = X509_REQ_get0_pubkey(req)) == NULL) {
             BIO_printf(bio_err, "Error unpacking public key from CSR\n");
-            goto end;
+            goto err;
         }
         i = do_X509_REQ_verify(req, pkey, vfyopts);
         if (i <= 0) {
             BIO_printf(bio_err, i < 0
                        ? "Error while verifying certificate request self-signature\n"
                        : "Certificate request self-signature did not match the contents\n");
-            goto end;
+            goto err;
         }
         BIO_printf(bio_err, "Certificate request self-signature ok\n");
 
@@ -731,7 +735,7 @@ int x509_main(int argc, char **argv)
         if (privkeyfile == NULL && CAkeyfile == NULL) {
             BIO_printf(bio_err,
                        "We need a private key to sign with, use -key or -CAkey or -CA with private key\n");
-            goto end;
+            goto err;
         }
         if ((x = X509_new_ex(app_get0_libctx(), app_get0_propq())) == NULL)
             goto end;
@@ -743,13 +747,16 @@ int x509_main(int argc, char **argv)
         if (req != NULL && ext_copy != EXT_COPY_UNSET) {
             if (clrext && ext_copy != EXT_COPY_NONE) {
                 BIO_printf(bio_err, "Must not use -clrext together with -copy_extensions\n");
-                goto end;
+                goto err;
             } else if (!copy_extensions(x, req, ext_copy)) {
                 BIO_printf(bio_err, "Error copying extensions from request\n");
-                goto end;
+                goto err;
             }
         }
     } else {
+        if (infile == NULL)
+            BIO_printf(bio_err,
+                       "Warning: Reading certificate from stdin since no -in or -new option is given\n");
         x = load_cert_pass(infile, informat, 1, passin, "certificate");
         if (x == NULL)
             goto end;
@@ -774,9 +781,6 @@ int x509_main(int argc, char **argv)
     if (out == NULL)
         goto end;
 
-    if (!noout || text || next_serial)
-        OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3");
-
     if (alias)
         X509_alias_set1(x, (unsigned char *)alias, -1);
 
@@ -814,6 +818,10 @@ int x509_main(int argc, char **argv)
             goto end;
         if (!x509toreq && !reqfile && !newcert && !self_signed(ctx, x))
             goto end;
+    } else {
+        if (privkey != NULL && !cert_matches_key(x, privkey))
+            BIO_printf(bio_err,
+                       "Warning: Signature key and public key of cert do not match\n");
     }
 
     if (sno != NULL && !X509_set_serialNumber(x, sno))
@@ -837,7 +845,7 @@ int x509_main(int argc, char **argv)
         if (!X509V3_EXT_add_nconf(extconf, &ext_ctx, extsect, x)) {
             BIO_printf(bio_err,
                        "Error adding extensions from section %s\n", extsect);
-            goto end;
+            goto err;
         }
     }
 
@@ -846,17 +854,17 @@ int x509_main(int argc, char **argv)
     pkey = X509_get0_pubkey(x);
     if ((print_pubkey != 0 || modulus != 0) && pkey == NULL) {
         BIO_printf(bio_err, "Error getting public key\n");
-        goto end;
+        goto err;
     }
 
     if (x509toreq) { /* also works in conjunction with -req */
         if (privkey == NULL) {
             BIO_printf(bio_err, "Must specify request signing key using -key\n");
-            goto end;
+            goto err;
         }
         if (clrext && ext_copy != EXT_COPY_NONE) {
             BIO_printf(bio_err, "Must not use -clrext together with -copy_extensions\n");
-            goto end;
+            goto err;
         }
         if ((rq = x509_to_req(x, ext_copy, ext_names)) == NULL)
             goto end;
@@ -865,7 +873,7 @@ int x509_main(int argc, char **argv)
             if (!X509V3_EXT_REQ_add_nconf(extconf, &ext_ctx, extsect, rq)) {
                 BIO_printf(bio_err,
                            "Error adding request extensions from section %s\n", extsect);
-                goto end;
+                goto err;
             }
         }
         if (!do_X509_REQ_sign(rq, privkey, digest, sigopts))
@@ -880,13 +888,10 @@ int x509_main(int argc, char **argv)
             if (!i) {
                 BIO_printf(bio_err,
                            "Unable to write certificate request\n");
-                goto end;
+                goto err;
             }
         }
         noout = 1;
-    } else if (privkey != NULL) {
-        if (!do_X509_sign(x, privkey, digest, sigopts, &ext_ctx))
-            goto end;
     } else if (CAfile != NULL) {
         if ((CAkey = load_key(CAkeyfile, CAkeyformat,
                               0, passin, e, "CA private key")) == NULL)
@@ -894,10 +899,13 @@ int x509_main(int argc, char **argv)
         if (!X509_check_private_key(xca, CAkey)) {
             BIO_printf(bio_err,
                        "CA certificate and CA private key do not match\n");
-            goto end;
+            goto err;
         }
 
-        if (!do_X509_sign(x, CAkey, digest, sigopts, &ext_ctx))
+        if (!do_X509_sign(x, 0, CAkey, digest, sigopts, &ext_ctx))
+            goto end;
+    } else if (privkey != NULL) {
+        if (!do_X509_sign(x, 0, privkey, digest, sigopts, &ext_ctx))
             goto end;
     }
     if (badsig) {
@@ -1007,13 +1015,13 @@ int x509_main(int argc, char **argv)
             if ((fdig = EVP_MD_fetch(app_get0_libctx(), fdigname,
                                      app_get0_propq())) == NULL) {
                 BIO_printf(bio_err, "Unknown digest\n");
-                goto end;
+                goto err;
             }
             digres = X509_digest(x, fdig, md, &n);
             EVP_MD_free(fdig);
             if (!digres) {
                 BIO_printf(bio_err, "Out of memory\n");
-                goto end;
+                goto err;
             }
 
             BIO_printf(out, "%s Fingerprint=", fdigname);
@@ -1037,7 +1045,8 @@ int x509_main(int argc, char **argv)
         goto end;
     }
 
-    print_cert_checks(out, x, checkhost, checkemail, checkip);
+    if (!check_cert_attributes(out, x, checkhost, checkemail, checkip, 1))
+        goto err;
 
     if (noout || nocert) {
         ret = 0;
@@ -1053,17 +1062,20 @@ int x509_main(int argc, char **argv)
             i = PEM_write_bio_X509(out, x);
     } else {
         BIO_printf(bio_err, "Bad output format specified for outfile\n");
-        goto end;
+        goto err;
     }
     if (!i) {
         BIO_printf(bio_err, "Unable to write certificate\n");
-        goto end;
+        goto err;
     }
+
     ret = 0;
+    goto end;
+
+ err:
+    ERR_print_errors(bio_err);
 
  end:
-    if (ret != 0)
-        ERR_print_errors(bio_err);
     NCONF_free(extconf);
     BIO_free_all(out);
     X509_STORE_free(ctx);
@@ -1137,16 +1149,7 @@ static int callb(int ok, X509_STORE_CTX *ctx)
     if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
         return 1;
 
-    /*
-     * BAD we should have gotten an error.  Normally if everything worked
-     * X509_STORE_CTX_get_error(ctx) will still be set to
-     * DEPTH_ZERO_SELF_....
-     */
-    if (ok) {
-        BIO_printf(bio_err,
-                   "Error with certificate to be certified - should be self-signed\n");
-        return 0;
-    } else {
+    if (!ok) {
         err_cert = X509_STORE_CTX_get_current_cert(ctx);
         print_name(bio_err, "subject=", X509_get_subject_name(err_cert));
         BIO_printf(bio_err,
@@ -1155,6 +1158,8 @@ static int callb(int ok, X509_STORE_CTX *ctx)
                    X509_verify_cert_error_string(err));
         return 1;
     }
+
+    return 1;
 }
 
 static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)

+ 10 - 1
libs/openssl/build.info

@@ -22,6 +22,7 @@ DEPEND[]=include/openssl/asn1.h \
          include/openssl/cmp.h \
          include/openssl/cms.h \
          include/openssl/conf.h \
+         include/openssl/core_names.h \
          include/openssl/crmf.h \
          include/openssl/crypto.h \
          include/openssl/ct.h \
@@ -40,7 +41,8 @@ DEPEND[]=include/openssl/asn1.h \
          include/openssl/x509.h \
          include/openssl/x509v3.h \
          include/openssl/x509_vfy.h \
-         include/crypto/bn_conf.h include/crypto/dso_conf.h
+         include/crypto/bn_conf.h include/crypto/dso_conf.h \
+         include/internal/param_names.h crypto/params_idx.c
 
 GENERATE[include/openssl/asn1.h]=include/openssl/asn1.h.in
 GENERATE[include/openssl/asn1t.h]=include/openssl/asn1t.h.in
@@ -73,6 +75,13 @@ GENERATE[include/openssl/x509_vfy.h]=include/openssl/x509_vfy.h.in
 GENERATE[include/crypto/bn_conf.h]=include/crypto/bn_conf.h.in
 GENERATE[include/crypto/dso_conf.h]=include/crypto/dso_conf.h.in
 
+DEPEND[crypto/params_idx.c \
+       include/internal/param_names.h \
+       include/openssl/core_names.h]=util/perl|OpenSSL/paramnames.pm
+GENERATE[crypto/params_idx.c]=crypto/params_idx.c.in
+GENERATE[include/internal/param_names.h]=include/internal/param_names.h.in
+GENERATE[include/openssl/core_names.h]=include/openssl/core_names.h.in
+
 IF[{- defined $target{shared_defflag} -}]
   SHARED_SOURCE[libcrypto]=libcrypto.ld
   SHARED_SOURCE[libssl]=libssl.ld

部分文件因为文件数量过多而无法显示