惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
V2EX
C
Check Point Blog
博客园_首页
B
Blog
D
Docker
U
Unit 42
量子位
I
InfoQ
有赞技术团队
有赞技术团队
Martin Fowler
Martin Fowler
GbyAI
GbyAI
L
LangChain Blog
云风的 BLOG
云风的 BLOG
博客园 - Franky
美团技术团队
T
The Blog of Author Tim Ferriss
阮一峰的网络日志
阮一峰的网络日志
月光博客
月光博客
Vercel News
Vercel News
Recent Announcements
Recent Announcements
雷峰网
雷峰网
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
Google DeepMind News
Google DeepMind News

I'm OWenT

国产大模型(GLM 5.1、Kimi K2.6)真实场景效果和 Coding Plan 额度测试 新版本libatapp的连接管理——从etcd服务发现到拓扑驱动的自动重连 新版本libatbus的设计变更——从树形路由到拓扑驱动 Protobuf又一坑 - C++标准和ABI兼容性 AI真好用-给Blog主题统一加mermaid,chart.js,excalidraw,draw.io的多种引入方式支持 给内网部署Squid-通用HTTP下载缓存 UE使用CodeChecker和clang-tidy生成静态分析报告 找出UE的循环依赖 C++小协程栈和临时变量及作用域的栈溢出问题分析 游戏服务的可观测性能力建设(C++生态) 指标上报的多线程优化和多拉取源点优化 协程(libcopp)的Channel功能和CPU命中率优化 通用RPC代码生成器 实现strong_rc_ptr(比shared_ptr更快的引用计数智能指针) 手夯一个STL allocator和对象内存分析组件 std::condition_variable 的信号丢失问题 踩坑一处(GCC)STL std::async 实现BUG导致的crash问题 GCC 14的一个warning to error BUG 给xresloader(Excel导表工具)增强UE读表支持(包含蓝图,Blueprint) Opentelemetry社区在gRPC的几个链接问题(静态库和动态库混用,musl工具链,符号裁剪) Excel转表工具(xresloader)的新验证器(验证外部Excel和文本数据,唯一性和自定义规则) protobuf v22和gRPC v1.55版本升级的依赖变化和upb适配 关于protobuf近期版本(v20/v3.20+)和 gRPC v1.54版本在某些编译环境下的一些链接和编译问题 xresloader-Excel导表工具链的近期变更汇总 打通游戏服务端框架的C++20协程改造的最后一环 Opentelemetry-cpp的Logs模块标准更新(涉及近期版本:1.8-1.9的BREAK CHANGES) 给cmake-toolset和工具链(curl等)加HTTP/2和HTTP/3支持 又开新坑之 coredns 插件: nftables和filter 关于opentelemetry-cpp社区对于C++ Head Only组件单例和符号可见性的讨论小记 填个转表工具 xresloader 去年的坑(数组尾部裁剪)
适配Boringssl和OpenSSL 3.0
owent · 2021-12-12 · via I'm OWenT

blog-website

前言

openssl 3.0发布好一阵子了,我的 atframe_utils 其实也挺早前就完成了对 openssl 3.0 和 boringssl 的适配。但是由于懒,一直没写这篇文章。在升级 [openssl] 3.0 和 boringssl 还是碰到了一些问题的,有些是由于接口变化,有些是由于功能支持还有些也和构建系统相关。还是有必要记录一下,至少能方便以后查找。

boringssl 是Goolge对早期 openssl 的fork和魔改。大部分接口是相同的,而且它原生支持了 cmake 构建系统,所以接入起来相对容易(特别是涉及交叉编译的时候)。但是这个 cmake 的支持还是有一些问题。

首先, boringssl 的代码兼容性感觉并没有 openssl 好,但是它非得开 /WX (MSVC) 和 -Werror (GCC/Clang)。于是有些编译环境,特别是高版本的编译器会有warning导致编译不过。其次它的子模块 boringssl_gtest 在Windows上编译成动态库是有问题的。最后更重要的问题, boringsslcmake 脚本并没有正确设置 install 目标。所以首先构建系统上需要解决这些问题。

boringssl 我适配的这个版本的编译不过包含 utf-8 char 不能隐式转换到 const char* , 有代码申明为 int x509v3_a2i_ipadd(unsigned char ipout[16], const char *ipasc) 但是实现是 int x509v3_a2i_ipadd(unsigned char* ipout, const char *ipasc) 等等。

然后在代码适配层面,boringssl 比较激进似乎删掉了很多不是那么古老的算法,其中就包含 DH 密钥交换。于是我在使用 boringssl 接入 atframe_utilscrypto_dh 是不得不移除DH算法,仅保留 ECDH 。

OpenSSL 3.0

openssl 3.0 优化了很多流程,它输出的库目录更加标准化了,这也带来了一些 cmake 适配上的问题。首先,有些平台下 openssl 3.0 会把安装的库放在 lib64 目录下。但是 cmake 官方的 FindOpenSSL.cmake 脚本中(3.0-3.21版本都是如此),写死了只查找 lib 目录。我现在的解决方法是在编译 openssl 3.0 的时候强行指定 "--libdir=${PROJECT_THIRD_PARTY_INSTALL_DIR}/lib" ,这样可以兼容一些其他直接使用 cmakeFindOpenSSL.cmake 的第三方组件。

第二个问题之前的版本应该就有,只是没测试到位。在 cmake 不使用 * Makefile 而使用 Ninja 作为构建系统Generator时,CMAKE_MAKE_PROGRAM 这个变量指向的是 ninja 。而像 openssl 这类在 Unix Like 系统下只能用 Makefile 的 packages 来说,就不能透传 CMAKE_MAKE_PROGRAM 作为构建工具,必须自己查找。自己查找的话还有另一个问题是在 MinGW 环境下,是有可能没有安装 make 仅安装了 mingw32-make 的。这些都是构建系统上需要适配的内容。

在接口和功能上, openssl 正在逐步淘汰古老的低级API,转而使用高级版本的接口 EVP_PKEY_* 等。在 openssl 3.0 中,则是移除了 DH 算法的低级API,于是我们这里又要进行适配。详情可以见 migration_guide 中的 Main Changes from OpenSSL 1.1.1 。简单地说,新版本的 openssl 提供了一组高级接口的 OSSL 库,对多种不同的算法进行了流程上的统一封装。我们就可以使用这一组新的高级接口来操作 DH 密钥交换算法。

在重新适配接入 openssl 的 DH 密钥交换算法过程中,我还发现了一个坑,那就是 EVP_PKEY_set_bn_param() 无效,返回正确但是实际上并没有起任何作用,并不像 ECDH 可以直接用高级接口,我没有深究所以不清楚是 BUG 还是设计如此。在这方面, openssl 的文档还是有一些滞后和粗略,我们目前解决这个问题的方案仍然是通过看 openssl 3.0 的 OSSL_* 的相关的代码流程来自己完成类似的功能。这套接口的流程和代码位置和之前版本的 openssl 差异也比较大,找起来还挺费劲的。主要是把 EVP_PKEY_set_bn_param() 换成了 OSSL_PARAM_BLD_push_BN()

写在最后

大体上适配 openssl 3.0 和 boringssl 就这些问题。其中 boringssl 需要打patch,而且和版本相关性比较大,我写进了构建系统中,并且增加了 iOS、Android、iPhoneSimulator的交叉编译检测。可能后面 boringssl 我更新不会那么频繁,有些warning也许后面也会被修复一些。

最后也欢迎有兴趣的小伙伴们互相交流。