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
相关推荐
FREEDOM_X1 小时前
ubuntu20.04 远程桌面Xrdp方式
ubuntu·vmware
꧁坚持很酷꧂2 小时前
配置Ubuntu18.04中的Qt Creator为中文(图文详解)
开发语言·qt·ubuntu
Sapphire~2 小时前
Linux-06 ubuntu 系统截图软件使用简单记录
linux·运维·ubuntu
biter00883 小时前
ubuntu(28):ubuntu系统多版本conda和多版本cuda共存
linux·人工智能·ubuntu·conda
Hello.Reader4 小时前
在 Ubuntu 环境为 Elasticsearch 引入 `icu_tokenizer
ubuntu·elasticsearch·jenkins
Sonetto19994 小时前
Nginx 反向代理,啥是“反向代理“啊,为啥叫“反向“代理?而不叫“正向”代理?它能干哈?
运维·前端·nginx
foo1st17 小时前
JDK(Ubuntu 18.04.6 LTS)安装笔记
java·笔记·ubuntu
白总Server19 小时前
Nginx 中间件
大数据·linux·运维·服务器·nginx·bash·web
maotou5261 天前
Ubuntu22学习记录
linux·ubuntu
异常君1 天前
HTTP头中的Accept-Encoding与Content-Encoding深度剖析
后端·nginx·http