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
相关推荐
小小鱼儿小小林2 小时前
免费一键自动化申请、续期、部署、监控所有 SSL/TLS 证书,ALLinSSL开源免费的 SSL 证书自动化管理平台
开源·自动化·ssl
RW~2 小时前
Minio安装配置,桶权限设置,nginx代理 https minio
运维·nginx·https·minio
CodeWithMe4 小时前
Nginx入门进阶:从零到高手的实战指南
运维·nginx
Ahlson4 小时前
【fnNAS】docker的nginx配置html
nginx·docker·容器·fnnas
ZPC82105 小时前
ubuntu 6.8.0 安装xenomai3.3
linux·运维·ubuntu
电脑能手6 小时前
遇到该问题:kex_exchange_identification: read: Connection reset`的解决办法
linux·ubuntu·ssh
snoopyfly~6 小时前
Ubuntu 24.04 安装配置 Redis 7.0 开机自启
linux·redis·ubuntu
精英的英6 小时前
在Ubuntu 24.04主机上创建Ubuntu 14.04编译环境的完整指南
linux·运维·ubuntu
斯普信专业组6 小时前
K8s环境下基于Nginx WebDAV与TLS/SSL的文件上传下载部署指南
nginx·kubernetes·ssl
奇妙之二进制7 小时前
计算机科学导论(10)什么是BIOS
ubuntu·计算机基础