squid/squid-6.10-provider-keys-digest.patch
Luboš Uhliarik 00d5540e37 Resolves: RHEL-107994 - squid does not work with post-quantum crypto
- update the patch to match upstream changes
2025-09-24 10:17:43 +02:00

60 lines
2.5 KiB
Diff

diff --git a/src/ssl/gadgets.cc b/src/ssl/gadgets.cc
index 1f8ac9d..3f54e3d 100644
--- a/src/ssl/gadgets.cc
+++ b/src/ssl/gadgets.cc
@@ -13,6 +13,42 @@
#include "security/Io.h"
#include "ssl/gadgets.h"
+/// whether to supply a digest algorithm name when calling X509_sign() with the given key
+static bool
+signWithDigest(const Security::PrivateKeyPointer &key) {
+ Assure(key); // TODO: Add and use Security::PrivateKey (here and in caller).
+ const auto pkey = key.get();
+
+ // OpenSSL does not define a maximum name size, but does terminate longer
+ // names without returning an error to the caller. Many similar callers in
+ // OpenSSL sources use 80-byte buffers.
+ char defaultDigestName[80] = "";
+ const auto nameGetterResult = EVP_PKEY_get_default_digest_name(pkey, defaultDigestName, sizeof(defaultDigestName));
+ debugs(83, 3, "nameGetterResult=" << nameGetterResult << " defaultDigestName=" << defaultDigestName);
+ if (nameGetterResult <= 0) {
+ debugs(83, 3, "ERROR: EVP_PKEY_get_default_digest_name() failure: " << Ssl::ReportAndForgetErrors);
+ // Backward compatibility: On error, assume digest should be used.
+ // TODO: Return false for -2 nameGetterResult as it "indicates the
+ // operation is not supported by the public key algorithm"?
+ return true;
+ }
+
+ // The name "UNDEF" signifies that a digest must (for return value 2) or may
+ // (for return value 1) be left unspecified.
+ if (nameGetterResult == 2 && strcmp(defaultDigestName, "UNDEF") == 0)
+ return false;
+
+ // Defined mandatory algorithms and "may be left unspecified" cases mentioned above.
+ return true;
+}
+
+/// OpenSSL X509_sign() wrapper
+static auto
+Sign(Security::Certificate &cert, const Security::PrivateKeyPointer &key, const EVP_MD &availableDigest) {
+ const auto digestOrNil = signWithDigest(key) ? &availableDigest : nullptr;
+ return X509_sign(&cert, key.get(), digestOrNil);
+}
+
void
Ssl::ForgetErrors()
{
@@ -618,9 +654,9 @@ static bool generateFakeSslCertificate(Security::CertPointer & certToStore, Secu
assert(hash);
/*Now sign the request */
if (properties.signAlgorithm != Ssl::algSignSelf && properties.signWithPkey.get())
- ret = X509_sign(cert.get(), properties.signWithPkey.get(), hash);
+ ret = Sign(*cert, properties.signWithPkey, *hash);
else //else sign with self key (self signed request)
- ret = X509_sign(cert.get(), pkey.get(), hash);
+ ret = Sign(*cert, pkey, *hash);
if (!ret)
return false;