Ubuntu 下 nginx-1.24.0 源码分析 - ngx_ssl_version 函数

定义

event\ngx_event_openssl.h 中:

复制代码
#if (OPENSSL_VERSION_NUMBER >= 0x10100001L)

#define ngx_ssl_version()       OpenSSL_version(OPENSSL_VERSION)

#else

#define ngx_ssl_version()       SSLeay_version(SSLEAY_VERSION)

#endif
复制代码
#if (OPENSSL_VERSION_NUMBER >= 0x10100001L)

预处理指令,用于条件编译 ,

检查 OPENSSL_VERSION_NUMBER 是否大于或等于 0x10100001L(OpenSSL 1.1.0 版本对应的十六进制常量)

根据 OpenSSL 的版本号,决定使用不同的版本获取函数。这是为了确保代码与不同版本的 OpenSSL 兼容

OpenSSL 的版本号是通过一个宏 OPENSSL_VERSION_NUMBER 来表示的,这个宏的值是一个十六进制常量,它编码了 OpenSSL 的版本信息。
OpenSSL_version() 是 OpenSSL 1.1.0 新增的 API,用于获取版本信息。

OPENSSL_VERSION 是参数,表示需要获取完整的版本字符串

OPENSSL_VERSION_NUMBER

定义在 event\ngx_event_openssl.h

复制代码
#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L)
#undef OPENSSL_VERSION_NUMBER
#if (LIBRESSL_VERSION_NUMBER >= 0x2080000fL)
#define OPENSSL_VERSION_NUMBER  0x1010000fL
#else
#define OPENSSL_VERSION_NUMBER  0x1000107fL
#endif
#endif

这段代码是 Nginx 源码中用于处理 LibreSSL 和 OpenSSL 版本兼容性问题的部分。

复制代码
#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L)

defined LIBRESSL_VERSION_NUMBER

检查是否定义了 LIBRESSL_VERSION_NUMBER 宏。

这个宏通常在使用 LibreSSL 的时候会被定义,表明当前环境使用的是 LibreSSL 而非 OpenSSL。

OPENSSL_VERSION_NUMBER == 0x20000000L

检查 OPENSSL_VERSION_NUMBER 是否等于 0x20000000L

这个常量可能是一个特殊的占位值或标识符,通常用于区分 LibreSSL 和 OpenSSL 的版本

第三方库 openssl/opensslv.h 中定义了 OPENSSL_VERSION_NUMBER

用以下代码去输出它的值:

复制代码
#include <stdio.h>
#include <openssl/opensslv.h>

int main() {
    printf("OPENSSL_VERSION_NUMBER: 0x%lx\n", OPENSSL_VERSION_NUMBER);
    return 0;
}

没有 LIBRESSL_VERSION_NUMBER 的定义

#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L)

条件不成立

OPENSSL_VERSION_NUMBER 的值还是 0x30000020

#if (OPENSSL_VERSION_NUMBER >= 0x10100001L)

这个条件就成立

于是 ngx_ssl_version 的定义是这个

复制代码
#define ngx_ssl_version()       OpenSSL_version(OPENSSL_VERSION)

可用以下代码查看 OPENSSL_VERSION 的值:

复制代码
#include <stdio.h>
#include <openssl/crypto.h>

int main() {
    printf("OPENSSL_VERSION: %d\n", OPENSSL_VERSION);
    return 0;
}

用以下代码去使用以下 OpenSSL_version(OPENSSL_VERSION) 看一下效果

在编译时,需要使用 -lcrypto-lssl 选项来链接 OpenSSL 的库

复制代码
#include <stdio.h>
#include <openssl/crypto.h>
#include <openssl/opensslv.h>

int main() {
    printf("OPENSSL_VERSION: %s\n", OpenSSL_version(OPENSSL_VERSION));
    return 0;
}
复制代码
#undef OPENSSL_VERSION_NUMBER

取消定义 OPENSSL_VERSION_NUMBER

如果满足前面的条件(即当前环境是 LibreSSL 并且 OPENSSL_VERSION_NUMBER 被设置为 0x20000000L),则取消它的定义。这是因为需要重新定义 OPENSSL_VERSION_NUMBER 为一个更合理的值,以适应 Nginx 的版本检查逻辑

复制代码
#if (LIBRESSL_VERSION_NUMBER >= 0x2080000fL)

LIBRESSL_VERSION_NUMBER >= 0x2080000fL

检查 LibreSSL 的版本号是否大于或等于 0x2080000fL

如果 LibreSSL 的版本号足够新,则执行接下来的代码块。这个版本号的编码格式通常与 LibreSSL 的内部版本表示有关,0x2080000fL 对应的是一个特定的 LibreSSL 版本。

复制代码
#define OPENSSL_VERSION_NUMBER  0x1010000fL

定义 OPENSSL_VERSION_NUMBER0x1010000fL

如果 LibreSSL 的版本号 >= 0x2080000fL,则将 OPENSSL_VERSION_NUMBER 设置为 0x1010000fL。这个值对应的是 OpenSSL 1.1.0 的版本号(或者类似的功能集合),目的是让 Nginx 在处理 LibertySSL 的时候,能够伪造成 OpenSSL 1.1.0 的版本,从而兼容某些依赖于 OpenSSL 版本号的逻辑。

复制代码
#else

预处理指令,表示如果第 3 行的条件不成立(即 LibreSSL 的版本号 < 0x2080000fL),则执行接下来的代码块

复制代码
#define OPENSSL_VERSION_NUMBER  0x1000107fL
相关推荐
吠品29 分钟前
免费SSL证书自动化申请:DNS代理验证
网络协议·自动化·ssl
zhuyasen5 小时前
Go Web 开发利器:如何让你的 Gin 服务拥有 Nginx 般的静态文件处理能力?
nginx·go·gin
achi0105 小时前
Ubuntu 24.04 LTS 下 Vue 3 开发环境搭建与生产部署完整指南
nginx·node·nvm·vue 3·ubuntu 24·开发环境搭建·国内镜像仓库
Eric.Lee20218 小时前
ubuntu 安装 Miniconda
linux·运维·python·ubuntu·miniconda
普普通通的南瓜9 小时前
IP证书在关键信息基础设施安全防护中的实践与挑战
网络·数据库·网络协议·tcp/ip·安全·ssl
W***832010 小时前
如何在 Ubuntu 22.04 上安装 MySQL
linux·mysql·ubuntu
2501_9219392611 小时前
11.25Nginx服务器和Wordpress服务器
运维·服务器·nginx
itmrl12 小时前
Nginx搭建与配置
nginx
小熊officer12 小时前
Nginx中正向代理,反向代理,负载均衡
java·nginx·负载均衡
tzhou6445212 小时前
Nginx 性能优化与防盗链配置
运维·nginx·性能优化