使用指南
这里主要介绍 mbedtls 程序的基本使用流程,并针对使用过程中经常涉及到的结构体和重要 API 进行简要说明。
mbedtls 的基本工作流程如下所示:
初始化 SSL/TLS 上下文
建立 SSL/TLS 握手
发送、接收数据
交互完成,关闭连接
menuconfig 配置说明
获取 mbedtls 软件包或者修改用户配置都需要使用 menuconfig。需要用户打开 ENV 工具,并将目录切换到您所用的 BSP 目录,使用 menuconfig 命令打开配置界面。
在 RT-Thread online packages → security packages 中选择 mbedtls 软件包,操作界面如下图所示:
详细的配置介绍如下所示:
Using all default CA 配置选项会将 certs/default 目录下的所有预置证书加入编译,将占用很大的内存
Using user CA 配置选项允许用户将自己需要的证书文件加入编译,需要用户将证书文件拷贝到 certs 根目录
选择合适的配置项后,使用 pkgs —update 命令下载软件包并更新用户配置。
功能配置说明
mbedtls 功能模块的开启与关闭定义在 mbedtls/config.h 和 ports/inc/tls_config.h 文件中
mbedtls/config.h 是 mbedtls 源码里提供的配置文件,ports/inc/tls_config.h 是 RT-Thread 基于 mbedtls 源码中的配置文件进行的裁剪和适配。
最终,用户使用的是 RT-Thread 提供的配置文件 ports/inc/tls_config.h 。
用户可以通过文件中的宏来使能或失能部分不需要使用的功能模块,从而将 mbedtls 配置到合适的尺寸。
证书配置说明
预置的 CA 证书文件存放在 certs/default 目录中
用户增加的 CA 证书文件存放在 certs 根目录中
certs/default 目录中已经包含了大多数 CA 根证书,如果您使用的根证书不在该文件夹内,需要用户将自己的 PEM 格式的 CA 证书拷贝 certs 根目录下。(仅支持 PEM 格式证书,不支持 DER 格式证书)。
该证书文件中已经包含了大多数 CA 根证书,,参考后边的 添加新证书 章节。
初始化 TLS 会话
MbedTLSSession 用于保存建立 TLS 会话连接时的配置信息,在 TLS 上下文中传递使用。用户在使用建立 TLS 会话前,必须定义一个存储会话内容的结构体,如下所示:
这里需要设置 SSL/TLS 服务器的 host 和 port,以及数据接收 buffer 等配置。
初始化 SSL/TLS 客户端
应用程序使用 mbedtls_client_init 函数初始化 TLS 客户端。
初始化阶段按照 API 参数定义传入相关参数即可,主要用来初始化网络接口、证书、SSL 会话配置等 SSL 交互必须的一些配置,以及设置相关的回调函数。
示例代码如下所示:
实际调用的 mbedtls 库函数如下所示:
初始化 SSL/TLS 客户端上下文
应用程序使用 mbedtls_client_context 函数配置客户端上下文信息,包括证书解析、设置主机名、设置默认 SSL 配置、设置认证模式(默认 MBEDTLS_SSL_VERIFY_OPTIONAL)等。
示例代码如下所示:
建立 SSL/TLS 连接
使用 mbedtls_client_connect 函数为 SSL/TLS 连接建立通道。这里包含整个的握手连接过程,以及证书校验结果。
示例代码如下所示:
读写数据
向 SSL/TLS 中写入数据
示例代码如下所示:
static const char *REQUEST = "GET HTTP/1.0\r\n" "Host: www.howsmyssl.com\r\n" "User-Agent: rtthread/3.1 rtt\r\n" "\r\n";
从 SSL/TLS 中读取数据
示例代码如下所示:
注意,如果读写接口返回了一个错误,必须关闭连接。
关闭 SSL/TLS 客户端连接
客户端主动关闭连接或者因为异常错误关闭连接,都需要使用 mbedtls_client_close 关闭连接并释放资源。
示例代码如下所示:
mbedtls_client_close(tls_session);
mbedtls 使用范式
参考示例程序 samples/tls_app_test.c。
添加新证书
CA 证书有两种常用格式 PEM 格式 和 DER 格式,目前 RT-Thread mbedtls 仅支持 PEM 格式 的证书文件。
PEM 格式证书
PEM 格式证书 通常是以 .pem 和 .cer 后缀名结尾的文件。
使用文本编辑器打开后,文件内容以 ——-BEGIN CERTIFICATE——- 开头,以 ——-END CERTIFICATE——- 结尾。- DER 格式证书
DER 格式证书 是二进制文件类型。
根证书样式
双击 .cer 后缀名结尾的 CA 文件(Windows系统)可以看到证书的签发机构和有效期,如下图所示:
PEM 格式 格式的证书文件内容内容样式如下所示:
获取根证书
直接向服务商索取
向服务商索取 base64 编码 X.509 编码的 PEM 格式 证书文件。
从服务商网站导出
TLS 握手是证书验证需要时间的验证,本地时间获取有误导致
检查 RTC 设备是否支持,检查 RT_USING_RTC 宏是否打开,校准设备时间。建议使用 NTP 同步本地时间。
证书 CN 错误
测试其他 TLS 网站时,若输入域名不符合证书的 Common Name(CN)出现 CN 验证失败问题
检查输入域名和证书中 CN 是否匹配或输入 IP 地址
0x7200 错误
部分原因是因为 mbedTls 收到了大于缓冲区大小的数据包
menuconfig 配置增加数据帧大小 ( Maxium fragment length in bytes )
浏览器打开服务商网站
点击浏览器地址栏的 安全 ,然后点击证书
查看证书详细信息
根证书导出向导
选择导出 Base64 编码证书
选择证书存储位置
完成证书文件导出
完成证书导出,假设证书文件名为 USER_ROOT_CA.cer 。
导入证书
使用文本编辑器打开上个步骤导出的根证书文件 USER_ROOT_CA.cer
拷贝 USER_ROOT_CA.cer 文件到 certs 根目录
使用 scons 命令重新编译
注:
scons 命令编译后,会自动将证书文件拷贝到 const char mbedtls_root_certificate[] 数组中。
常见问题
证书验证失败
[tls]verification info: ! The CRL is not correctly signed by the trusted CA
原因
mbedtls 包中支持多种主流 CA 机构根证书,部分 CA 机构未支持
解决方法
若测试其他 TLS 网站证书验证失败,手动获取测试网站根证书(Root Cerificate)添加到mbedtls/tls_cerificate.c文件中
证书时间错误
原因
TLS 握手是证书验证需要时间的验证,本地时间获取有误导致
解决方式
检查 RTC 设备是否支持,检查 RT_USING_RTC 宏是否打开,校准设备时间。建议使用 NTP 同步本地时间。
证书 CN 错误
verification info: ! The certificate Common Name (CN) does not match with the expected CN
原因
测试其他 TLS 网站时,若输入域名不符合证书的 Common Name(CN)出现 CN 验证失败问题
解决方法
检查输入域名和证书中 CN 是否匹配或输入 IP 地址
0x7200 错误
原因
部分原因是因为 mbedTls 收到了大于缓冲区大小的数据包
解决方法
menuconfig 配置增加数据帧大小 ( Maxium fragment length in bytes )
原作者:RT-Thread软件包手册