diff mbox series

[meta-oe,RFC,07/20] grpc: fix build with OpenSSL 4.0

Message ID 20260827185324.78997-8-jaipaul.cheernam@est.tech
State New
Headers show
Series Fix OpenSSL 4.0.1 build failures across meta-openembedded | expand

Commit Message

Jaipaul Cheernam Aug. 27, 2026, 6:53 p.m. UTC
OpenSSL 4.0 returns const pointers from X509 accessor functions,
makes ASN1_OCTET_STRING opaque, and deprecates HMAC one-shot API.

Four patches addressing credentials, TSI transport security, and
TSI utils.

Upstream-Status: Submitted [https://github.com/grpc/grpc/pull/41932]
Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
---
 ...ls-Fix-OpenSSL-3.0-4.0-compatibility.patch | 85 +++++++++++++++++++
 ...L-4.0-const-and-opaque-compatibility.patch | 59 +++++++++++++
 ...sport_security_utils-for-OpenSSL-4.0.patch | 61 +++++++++++++
 ...ing-const-qualifiers-for-OpenSSL-4.0.patch | 47 ++++++++++
 meta-oe/recipes-devtools/grpc/grpc_1.83.0.bb  |  4 +
 5 files changed, 256 insertions(+)
 create mode 100644 meta-oe/recipes-devtools/grpc/grpc/0001-credentials-Fix-OpenSSL-3.0-4.0-compatibility.patch
 create mode 100644 meta-oe/recipes-devtools/grpc/grpc/0002-tsi-fix-OpenSSL-4.0-const-and-opaque-compatibility.patch
 create mode 100644 meta-oe/recipes-devtools/grpc/grpc/0003-tsi-fix-ssl_transport_security_utils-for-OpenSSL-4.0.patch
 create mode 100644 meta-oe/recipes-devtools/grpc/grpc/0004-tsi-fix-remaining-const-qualifiers-for-OpenSSL-4.0.patch
diff mbox series

Patch

diff --git a/meta-oe/recipes-devtools/grpc/grpc/0001-credentials-Fix-OpenSSL-3.0-4.0-compatibility.patch b/meta-oe/recipes-devtools/grpc/grpc/0001-credentials-Fix-OpenSSL-3.0-4.0-compatibility.patch
new file mode 100644
index 0000000000..f062ecce08
--- /dev/null
+++ b/meta-oe/recipes-devtools/grpc/grpc/0001-credentials-Fix-OpenSSL-3.0-4.0-compatibility.patch
@@ -0,0 +1,85 @@ 
+From b07ee3b98c30251094692b84d1253e3ca881ff96 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= <bjorn.a.svensson@est.tech>
+Date: Tue, 24 Mar 2026 13:12:07 +0100
+Subject: [PATCH] credentials: Fix OpenSSL 3.0+/4.0 compatibility
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+- Guard openssl/hmac.h include behind OpenSSL < 3.0 version check
+- Replace one-shot HMAC() with EVP_Q_mac() for OpenSSL 3.0+
+- Handle X509_CRL_get_issuer() which returns const in OpenSSL 4.0,
+  with const_cast for i2d_X509_NAME()
+
+Signed-off-by: Björn Svensson <bjorn.a.svensson@est.tech>
+Upstream-Status: Submitted [https://github.com/grpc/grpc/pull/41932]
+Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
+---
+ .../credentials/call/external/aws_request_signer.cc | 13 +++++++++++++
+ .../transport/tls/grpc_tls_crl_provider.cc          |  4 ++--
+ 2 files changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/src/core/credentials/call/external/aws_request_signer.cc b/src/core/credentials/call/external/aws_request_signer.cc
+index f7fb7a25b1d0b..26c70ccc7c174 100644
+--- a/src/core/credentials/call/external/aws_request_signer.cc
++++ b/src/core/credentials/call/external/aws_request_signer.cc
+@@ -18,7 +18,9 @@
+ #include <grpc/support/port_platform.h>
+ #include <openssl/crypto.h>
+ #include <openssl/evp.h>
++#if OPENSSL_VERSION_NUMBER < 0x30000000L
+ #include <openssl/hmac.h>
++#endif
+ #include <openssl/sha.h>
+ 
+ #include <utility>
+@@ -41,6 +43,7 @@ namespace {
+ 
+ #if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ const char kSha256[] = "SHA256";
++const char kHmacName[] = "HMAC";
+ #endif
+ const char kAlgorithm[] = "AWS4-HMAC-SHA256";
+ const char kDateFormat[] = "%a, %d %b %E4Y %H:%M:%S %Z";
+@@ -67,12 +70,22 @@ std::string SHA256Hex(const std::string& str) {
+ }
+ 
+ std::string HMAC(const std::string& key, const std::string& msg) {
++#if OPENSSL_VERSION_NUMBER < 0x30000000L
+   unsigned int len;
+   unsigned char digest[EVP_MAX_MD_SIZE];
+   HMAC(EVP_sha256(), key.c_str(), key.length(),
+        reinterpret_cast<const unsigned char*>(msg.c_str()), msg.length(),
+        digest, &len);
+   return std::string(digest, digest + len);
++#else
++  size_t len = 0;
++  unsigned char digest[EVP_MAX_MD_SIZE];
++  EVP_Q_mac(nullptr, kHmacName, nullptr, kSha256, nullptr,
++            reinterpret_cast<const unsigned char*>(key.c_str()), key.length(),
++            reinterpret_cast<const unsigned char*>(msg.c_str()), msg.length(),
++            digest, sizeof(digest), &len);
++  return std::string(digest, digest + len);
++#endif
+ }
+ 
+ }  // namespace
+diff --git a/src/core/credentials/transport/tls/grpc_tls_crl_provider.cc b/src/core/credentials/transport/tls/grpc_tls_crl_provider.cc
+index 7bd4c5ab0b49f..99ed93d5d2944 100644
+--- a/src/core/credentials/transport/tls/grpc_tls_crl_provider.cc
++++ b/src/core/credentials/transport/tls/grpc_tls_crl_provider.cc
+@@ -56,12 +56,12 @@ absl::StatusOr<std::string> IssuerFromCrl(X509_CRL* crl) {
+   if (crl == nullptr) {
+     return absl::InvalidArgumentError("crl cannot be null");
+   }
+-  X509_NAME* issuer = X509_CRL_get_issuer(crl);
++  auto* issuer = X509_CRL_get_issuer(crl);
+   if (issuer == nullptr) {
+     return absl::InvalidArgumentError("crl cannot have null issuer");
+   }
+   unsigned char* buf = nullptr;
+-  int len = i2d_X509_NAME(issuer, &buf);
++  int len = i2d_X509_NAME(const_cast<X509_NAME*>(issuer), &buf);
+   if (len < 0 || buf == nullptr) {
+     return absl::InvalidArgumentError("crl cannot have null issuer");
+   }
diff --git a/meta-oe/recipes-devtools/grpc/grpc/0002-tsi-fix-OpenSSL-4.0-const-and-opaque-compatibility.patch b/meta-oe/recipes-devtools/grpc/grpc/0002-tsi-fix-OpenSSL-4.0-const-and-opaque-compatibility.patch
new file mode 100644
index 0000000000..afaaf509ad
--- /dev/null
+++ b/meta-oe/recipes-devtools/grpc/grpc/0002-tsi-fix-OpenSSL-4.0-const-and-opaque-compatibility.patch
@@ -0,0 +1,59 @@ 
+From 42693a829197a9120816fa91b9ce55535d798b28 Mon Sep 17 00:00:00 2001
+From: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
+Date: Wed, 26 Aug 2026 19:50:00 +0000
+Subject: [PATCH] tsi: fix OpenSSL 4.0 const and opaque type compatibility
+
+OpenSSL 4.0 returns const pointers from X509_get_subject_name(),
+X509_get_issuer_name(), X509_get0_serialNumber() and makes
+ASN1_OCTET_STRING opaque. Use auto* to deduce correct const type
+and use ASN1_STRING accessors for opaque struct access.
+
+Upstream-Status: Submitted [https://github.com/grpc/grpc/pull/41932]
+
+Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
+---
+ src/core/tsi/ssl_transport_security.cc | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc
+index 922bb836e14..ee2092acece 100644
+--- a/src/core/tsi/ssl_transport_security.cc
++++ b/src/core/tsi/ssl_transport_security.cc
+@@ -893,7 +893,7 @@ static tsi_result ssl_get_x509_common_name(X509* cert, unsigned char** utf8,
+   int common_name_index = -1;
+   X509_NAME_ENTRY* common_name_entry = nullptr;
+   ASN1_STRING* common_name_asn1 = nullptr;
+-  X509_NAME* subject_name = X509_get_subject_name(cert);
++  auto* subject_name = X509_get_subject_name(cert);
+   int utf8_returned_size = 0;
+   if (subject_name == nullptr) {
+     VLOG(2) << "Could not get subject name from certificate.";
+@@ -951,7 +951,7 @@ static tsi_result peer_property_from_x509_common_name(
+ static tsi_result peer_property_from_x509_subject(X509* cert,
+                                                   tsi_peer_property* property,
+                                                   bool is_verified_root_cert) {
+-  X509_NAME* subject_name = X509_get_subject_name(cert);
++  auto* subject_name = X509_get_subject_name(cert);
+   if (subject_name == nullptr) {
+     GRPC_TRACE_LOG(tsi, INFO) << "Could not get subject name from certificate.";
+     return TSI_NOT_FOUND;
+@@ -1047,16 +1047,16 @@ static tsi_result add_subject_alt_names_properties_to_peer(
+       char ntop_buf[INET6_ADDRSTRLEN];
+       int af;
+ 
+-      if (subject_alt_name->d.iPAddress->length == 4) {
++      if (ASN1_STRING_length(subject_alt_name->d.iPAddress) == 4) {
+         af = AF_INET;
+-      } else if (subject_alt_name->d.iPAddress->length == 16) {
++      } else if (ASN1_STRING_length(subject_alt_name->d.iPAddress) == 16) {
+         af = AF_INET6;
+       } else {
+         LOG(ERROR) << "SAN IP Address contained invalid IP";
+         result = TSI_INTERNAL_ERROR;
+         break;
+       }
+-      const char* name = inet_ntop(af, subject_alt_name->d.iPAddress->data,
++      const char* name = inet_ntop(af, ASN1_STRING_get0_data(subject_alt_name->d.iPAddress),
+                                    ntop_buf, INET6_ADDRSTRLEN);
+       if (name == nullptr) {
+         LOG(ERROR) << "Could not get IP string from asn1 octet.";
diff --git a/meta-oe/recipes-devtools/grpc/grpc/0003-tsi-fix-ssl_transport_security_utils-for-OpenSSL-4.0.patch b/meta-oe/recipes-devtools/grpc/grpc/0003-tsi-fix-ssl_transport_security_utils-for-OpenSSL-4.0.patch
new file mode 100644
index 0000000000..a7d6c0f789
--- /dev/null
+++ b/meta-oe/recipes-devtools/grpc/grpc/0003-tsi-fix-ssl_transport_security_utils-for-OpenSSL-4.0.patch
@@ -0,0 +1,61 @@ 
+From d2beead89706a34ade404bfa7bec2f95e9b6225a Mon Sep 17 00:00:00 2001
+From: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
+Date: Wed, 26 Aug 2026 19:51:01 +0000
+Subject: [PATCH] tsi: fix ssl_transport_security_utils for OpenSSL 4.0
+
+OpenSSL 4.0 returns const pointers from X509_get_issuer_name(),
+X509_CRL_get_issuer(), and makes ASN1_OCTET_STRING opaque. Use
+auto* for X509_NAME and const for ASN1_OCTET_STRING.
+
+Upstream-Status: Submitted [https://github.com/grpc/grpc/pull/41932]
+
+Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
+---
+ src/core/tsi/ssl_transport_security_utils.cc | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/tsi/ssl_transport_security_utils.cc b/src/core/tsi/ssl_transport_security_utils.cc
+index 7318bc3f780..2738ffad923 100644
+--- a/src/core/tsi/ssl_transport_security_utils.cc
++++ b/src/core/tsi/ssl_transport_security_utils.cc
+@@ -282,11 +282,11 @@ bool VerifyCrlCertIssuerNamesMatch(X509_CRL* crl, X509* cert) {
+   if (cert == nullptr || crl == nullptr) {
+     return false;
+   }
+-  X509_NAME* cert_issuer_name = X509_get_issuer_name(cert);
++  auto* cert_issuer_name = X509_get_issuer_name(cert);
+   if (cert_issuer_name == nullptr) {
+     return false;
+   }
+-  X509_NAME* crl_issuer_name = X509_CRL_get_issuer(crl);
++  auto* crl_issuer_name = X509_CRL_get_issuer(crl);
+   if (crl_issuer_name == nullptr) {
+     return false;
+   }
+@@ -317,7 +317,7 @@ absl::StatusOr<std::string> IssuerFromCert(X509* cert) {
+   if (cert == nullptr) {
+     return absl::InvalidArgumentError("cert cannot be null");
+   }
+-  X509_NAME* issuer = X509_get_issuer_name(cert);
++  auto* issuer = X509_get_issuer_name(cert);
+   unsigned char* buf = nullptr;
+   int len = i2d_X509_NAME(issuer, &buf);
+   if (len < 0 || buf == nullptr) {
+@@ -332,7 +332,7 @@ absl::StatusOr<std::string> AkidFromCertificate(X509* cert) {
+   if (cert == nullptr) {
+     return absl::InvalidArgumentError("cert cannot be null.");
+   }
+-  ASN1_OCTET_STRING* akid = nullptr;
++  const ASN1_OCTET_STRING* akid = nullptr;
+   int j = X509_get_ext_by_NID(cert, NID_authority_key_identifier, -1);
+   // Can't have multiple occurrences
+   if (j >= 0) {
+@@ -357,7 +357,7 @@ absl::StatusOr<std::string> AkidFromCrl(X509_CRL* crl) {
+   if (crl == nullptr) {
+     return absl::InvalidArgumentError("Could not get AKID from crl.");
+   }
+-  ASN1_OCTET_STRING* akid = nullptr;
++  const ASN1_OCTET_STRING* akid = nullptr;
+   int j = X509_CRL_get_ext_by_NID(crl, NID_authority_key_identifier, -1);
+   // Can't have multiple occurrences
+   if (j >= 0) {
diff --git a/meta-oe/recipes-devtools/grpc/grpc/0004-tsi-fix-remaining-const-qualifiers-for-OpenSSL-4.0.patch b/meta-oe/recipes-devtools/grpc/grpc/0004-tsi-fix-remaining-const-qualifiers-for-OpenSSL-4.0.patch
new file mode 100644
index 0000000000..468aa9d669
--- /dev/null
+++ b/meta-oe/recipes-devtools/grpc/grpc/0004-tsi-fix-remaining-const-qualifiers-for-OpenSSL-4.0.patch
@@ -0,0 +1,47 @@ 
+From 12710dde230ae1721e1c7119f51490c239513c41 Mon Sep 17 00:00:00 2001
+From: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
+Date: Thu, 27 Aug 2026 09:42:20 +0000
+Subject: [PATCH] tsi: fix remaining const qualifiers for OpenSSL 4.0
+
+OpenSSL 4.0 returns const pointers from X509_NAME_get_entry(),
+X509_NAME_ENTRY_get_data(), and X509_get_subject_name().
+Combine X509_get_subject_name + X509_NAME_dup into single call
+to avoid const-to-non-const assignment.
+
+Upstream-Status: Submitted [https://github.com/grpc/grpc/pull/41932]
+
+Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
+---
+ src/core/tsi/ssl_transport_security.cc | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc
+index ee2092acece..23340beda98 100644
+--- a/src/core/tsi/ssl_transport_security.cc
++++ b/src/core/tsi/ssl_transport_security.cc
+@@ -891,8 +891,8 @@ static int looks_like_ip_address(absl::string_view name) {
+ static tsi_result ssl_get_x509_common_name(X509* cert, unsigned char** utf8,
+                                            size_t* utf8_size) {
+   int common_name_index = -1;
+-  X509_NAME_ENTRY* common_name_entry = nullptr;
+-  ASN1_STRING* common_name_asn1 = nullptr;
++  const X509_NAME_ENTRY* common_name_entry = nullptr;
++  const ASN1_STRING* common_name_asn1 = nullptr;
+   auto* subject_name = X509_get_subject_name(cert);
+   int utf8_returned_size = 0;
+   if (subject_name == nullptr) {
+@@ -1342,13 +1342,12 @@ static tsi_result x509_store_load_certs(X509_STORE* cert_store,
+       break;  // We're at the end of stream.
+     }
+     if (root_names != nullptr) {
+-      root_name = X509_get_subject_name(root);
++      root_name = X509_NAME_dup(X509_get_subject_name(root));
+       if (root_name == nullptr) {
+         LOG(ERROR) << "Could not get name from root certificate.";
+         result = TSI_INVALID_ARGUMENT;
+         break;
+       }
+-      root_name = X509_NAME_dup(root_name);
+       if (root_name == nullptr) {
+         result = TSI_OUT_OF_RESOURCES;
+         break;
diff --git a/meta-oe/recipes-devtools/grpc/grpc_1.83.0.bb b/meta-oe/recipes-devtools/grpc/grpc_1.83.0.bb
index 3e03bf510e..34ec8863ac 100644
--- a/meta-oe/recipes-devtools/grpc/grpc_1.83.0.bb
+++ b/meta-oe/recipes-devtools/grpc/grpc_1.83.0.bb
@@ -27,6 +27,10 @@  SRCREV = "c876f4da50f7da2f331888b88b2a7243514139fe"
 BRANCH = "v1.83.x"
 SRC_URI = "gitsm://github.com/grpc/grpc.git;protocol=https;branch=${BRANCH};tag=v${PV} \
            file://0001-cmake-Link-with-libatomic-on-rv32-rv64.patch \
+           file://0001-credentials-Fix-OpenSSL-3.0-4.0-compatibility.patch \
+           file://0002-tsi-fix-OpenSSL-4.0-const-and-opaque-compatibility.patch \
+           file://0003-tsi-fix-ssl_transport_security_utils-for-OpenSSL-4.0.patch \
+           file://0004-tsi-fix-remaining-const-qualifiers-for-OpenSSL-4.0.patch \
            "
 
 inherit cmake pkgconfig