ext/openssl: 8.2.31+/8.3.31+ fail to build against OpenSSL 1.0.2 (ASN1_STRING_get0_data in xp_ssl.c)

未關閉 適合新手
#25,402 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

還沒有人認領這個 Issue。

評估

難度
2/5
預估耗時
1-3 小時
新手友好度
79/100
Issue 類型
缺陷
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
c, php

研究方向

閱讀 ext/openssl/xp_ssl.c 中 php_openssl_matches_san_list() 附近的程式碼,並與 ext/openssl/openssl.c 中的 OpenSSL 相容性回退方案進行比較。使用 PHP 8.3.36 和 OpenSSL 1.0.2 重現建置,接著確認建置成功且 IP SAN 比對仍可正常運作。當受影響的 PHP 8.2 和 8.3 分支能以 OpenSSL 1.0.2 編譯,且不會影響使用較新 OpenSSL 的建置時,即告完成。

由索引模型根據 Issue 內容生成。

描述

Description

PHP 8.2.31+ and 8.3.31+ no longer compile against OpenSSL 1.0.2, though both branches still accept it (ext/openssl/config0.m4: "requires OpenSSL >= 1.0.2").

To reproduce, build PHP 8.3.36 (or any 8.3.31+ or 8.2.31+) --with-openssl against OpenSSL 1.0.2, e.g. on CentOS 7 (OpenSSL 1.0.2k, gcc 4.8.5).

Resulted in this output:

ext/openssl/xp_ssl.c: In function 'php_openssl_matches_san_list':
ext/openssl/xp_ssl.c:506:6: warning: implicit declaration of function 'ASN1_STRING_get0_data' [-Wimplicit-function-declaration]
      ASN1_STRING_get0_data(san->d.iPAddress)[0],
      ^
ext/openssl/xp_ssl.c:506:45: error: subscripted value is neither array nor pointer nor vector
      ASN1_STRING_get0_data(san->d.iPAddress)[0],
                                             ^
ext/openssl/xp_ssl.c:507:45: error: subscripted value is neither array nor pointer nor vector
ext/openssl/xp_ssl.c:508:45: error: subscripted value is neither array nor pointer nor vector
ext/openssl/xp_ssl.c:509:45: error: subscripted value is neither array nor pointer nor vector
ext/openssl/xp_ssl.c:138:10: error: subscripted value is neither array nor pointer nor vector
    _bytes[0] << 8 | _bytes[1], \

But I expected the build to succeed, as it does with 8.3.30 / 8.2.30 against the same OpenSSL.

Cause: 19255f4b78 ("Backport compatibility changes for OpenSSL 4.0") changed the IP SAN code in php_openssl_matches_san_list() from san->d.iPAddress->data to ASN1_STRING_get0_data(san->d.iPAddress). ASN1_STRING_get0_data() was added in OpenSSL 1.1.0. ext/openssl/openssl.c already defines a fallback for it under #if PHP_OPENSSL_API_VERSION < 0x10100 (return M_ASN1_STRING_data(asn1);), but that is static to openssl.c, and xp_ssl.c has no equivalent. (ASN1_STRING_length(), used in the same change, does exist in 1.0.2.) PHP-8.2 and PHP-8.3 HEAD are both still affected. 8.4+ requires OpenSSL >= 1.1.1, so it is not.

Suggested fix: the same fallback in xp_ssl.c, under the same guard (it compiles away on 1.1.0+):

--- a/ext/openssl/xp_ssl.c
+++ b/ext/openssl/xp_ssl.c
@@ -36,6 +36,10 @@
 #include <openssl/bn.h>
 #include <openssl/dh.h>
 
+#if PHP_OPENSSL_API_VERSION < 0x10100
+# define ASN1_STRING_get0_data(asn1) ((const unsigned char *)M_ASN1_STRING_data(asn1))
+#endif
+
 #ifdef PHP_WIN32
 #include "win32/winutil.h"
 #include "win32/time.h"

With that applied, 8.3.36 builds on CentOS 7 against OpenSSL 1.0.2k. A verified TLS connection to a server whose certificate's only SAN is IP:127.0.0.1 succeeds, and the same connection with a peer_name the certificate doesn't cover is refused, so the IP SAN matching works. Alternatively, the fallback could move to php_openssl.h so both files share it.

PHP Version
PHP 8.3.36 (fails to build against OpenSSL 1.0.2; first affected: 8.3.31 and 8.2.31)
Operating System

CentOS 7 (OpenSSL 1.0.2k)

主要語言
C
星號
41.8k
分支
8.5k
平均合併
2 天 13 小時
30 天內合併 PR
145

環境準備

  • 沒有 Dockerfile 或 Docker Compose 檔案
  • 沒有 Pull Request 範本
  • 閱讀貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

php/php-src 的其他 Issue

查看 php/php-src 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。