# NetLeaf TLS/SSL 扩展库
## 概述
`netleaf_tls` 是 NetLeaf 的 TLS/SSL 加密扩展库,基于内置的 **mbedTLS 2.28.10 LTS** 源码实现。作为独立的基础扩展库,它可被其他协议模块(如 MQTT、HTTP 等)通过 NL扩展系统调用。
## 架构说明
```mermaid
flowchart TD
TLS["netleaf_tls.dll
TLS/SSL 基础扩展库
———————
• mbedtls 内置源码 (third-party/mbedtls/)
• 通用 TLS/SSL 功能
• 可作为标准库被其他模块调用"]
MQTT["netleaf_mqtt.dll
MQTT 协议扩展库
———————
• netleaf_mqtt.c (MQTT 核心功能)
• netleaf_mqtt_tls.c (MQTT TLS 功能)
• 依赖 netleaf_tls (可选)"]
TLS -->|可被调用| MQTT
```
**关键说明**:
- `netleaf_tls.dll` 是独立的 TLS/SSL 基础扩展库
- MQTT TLS 功能包含在 `netleaf_mqtt.dll` 中,不是独立的模块
- 其他协议模块(如未来的 HTTP、FTP 等)也可以调用 `netleaf_tls.dll` 的功能
- 通过 CMake 的 `BUILD_TLS` 选项控制是否编译 TLS 功能
## 依赖项
- mbedTLS 2.28.10 LTS(已内置于 `third-party/mbedtls/`)
- 无需单独安装 mbedTLS
## API 概览
### 模块信息
```c
// 获取 TLS 模块信息
nl_module_info_t* nl_tls_get_module_info(void);
// 初始化 TLS 模块
int nl_tls_init(void);
// 获取版本
const char* nl_tls_version(void);
// 检查可用性
int nl_tls_is_available(void);
```
### 上下文管理
```c
// 创建 TLS 上下文
nl_tls_ctx_t* nl_tls_create(void);
// 销毁 TLS 上下文
void nl_tls_destroy(nl_tls_ctx_t* ctx);
```
### 配置
```c
// 配置 TLS 上下文
int nl_tls_configure(nl_tls_ctx_t* ctx, const nl_tls_config_t* cfg);
// 设置验证选项
int nl_tls_set_verify(nl_tls_ctx_t* ctx, int verify_peer);
```
**配置结构:**
```c
typedef struct nl_tls_config {
const char* ca_file; // CA证书文件路径
const char* ca_path; // CA证书目录路径
const char* cert_file; // 客户端证书文件
const char* key_file; // 客户端私钥文件
const char* key_pass; // 私钥密码
int verify_peer; // 验证对端证书(0或1)
int client_auth; // 要求客户端认证(0或1)
nl_tls_protocol_t min_proto; // 最低协议版本
nl_tls_protocol_t max_proto; // 最高协议版本
} nl_tls_config_t;
```
### SSL 握手
```c
// 执行 TLS 握手
int nl_tls_handshake(nl_tls_ctx_t* ctx, int sock);
```
### 数据传输
```c
// 通过 TLS 发送数据
int nl_tls_send(nl_tls_ctx_t* ctx, const void* buf, size_t len);
// 通过 TLS 接收数据
int nl_tls_recv(nl_tls_ctx_t* ctx, void* buf, size_t len);
// 优雅关闭 TLS 连接
int nl_tls_close(nl_tls_ctx_t* ctx);
```
### 状态查询
```c
// 检查 TLS 连接是否活跃
int nl_tls_is_active(const nl_tls_ctx_t* ctx);
// 获取对端证书信息
const char* nl_tls_get_peer_cert(nl_tls_ctx_t* ctx);
// 获取错误信息
const char* nl_tls_strerror(int err);
```
### 结果码
```c
typedef enum {
NL_TLS_OK = 0,
NL_TLS_ERROR = -1,
NL_TLS_BAD_CA = -2,
NL_TLS_BAD_CERT = -3,
NL_TLS_BAD_KEY = -4,
NL_TLS_ALLOC_FAIL = -5,
NL_TLS_HANDSHAKE = -6,
NL_TLS_READ = -7,
NL_TLS_WRITE = -8,
NL_TLS_NOT_INIT = -9,
NL_TLS_INVALID_STATE = -10,
NL_TLS_UNKNOWN_ERROR = -99
} nl_tls_result_t;
```
## 使用示例
### 基本 TLS 连接
```c
#include "netleaf_tls.h"
#include
#include
int main() {
// 初始化 TLS 模块
nl_tls_init();
// 创建套接字
int sock = socket(AF_INET, SOCK_STREAM, 0);
// 连接到服务器
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = htons(443);
inet_pton(AF_INET, "93.184.216.34", &addr.sin_addr);
connect(sock, (struct sockaddr*)&addr, sizeof(addr));
// 创建 TLS 上下文
nl_tls_ctx_t* ctx = nl_tls_create();
// 配置证书验证
nl_tls_config_t cfg = {
.ca_file = "ca.crt",
.verify_peer = 1
};
nl_tls_configure(ctx, &cfg);
// 执行握手
int ret = nl_tls_handshake(ctx, sock);
if (ret != NL_TLS_OK) {
printf("Handshake failed: %s\n", nl_tls_strerror(ret));
return 1;
}
// 发送 HTTPS 请求
const char* request = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n";
nl_tls_send(ctx, request, strlen(request));
// 接收响应
char buffer[4096];
int bytes = nl_tls_recv(ctx, buffer, sizeof(buffer) - 1);
buffer[bytes] = '\0';
printf("%s\n", buffer);
// 清理
nl_tls_close(ctx);
nl_tls_destroy(ctx);
close(sock);
return 0;
}
```
### MQTT over TLS 示例
```c
#include "netleaf_mqtt.h"
#include "netleaf_mqtt_tls.h"
#include
void on_connect(int rc, void* userdata) {
printf("MQTT connected with result: %d\n", rc);
}
void on_message(const char* topic, const void* payload, size_t len, void* userdata) {
printf("Received [%s]: %.20s...\n", topic, payload);
}
int main() {
// 创建 MQTT 客户端
nl_mqtt_client_t* client = nl_mqtt_create();
// 连接选项
nl_mqtt_connect_opts_t opts = {
.client_id = "netleaf_client_001",
.keep_alive = 60,
.clean_session = 1
};
// 使用 TLS 连接(端口 8883)
nl_mqtt_connect(client, "broker.hivemq.com", 8883, &opts, on_connect);
nl_mqtt_subscribe(client, "netleaf/#", &(nl_mqtt_sub_opts_t){.qos = 1}, on_message, NULL);
// 事件循环
while (1) {
nl_mqtt_maintain(client, 1000);
}
nl_mqtt_destroy(client);
return 0;
}
```
## 构建配置
### CMake 选项
```bash
# 启用 TLS 构建
cmake -B build -DBUILD_TLS=ON
# 同时启用 MQTT + TLS
cmake -B build -DBUILD_TLS=ON -DBUILD_MQTT=ON
```
### 构建脚本
```bash
# Windows
build_tls.bat
# Linux/macOS
./build_tls.sh
```
## 支持的协议版本
- TLS 1.0 ⚠️(已废弃,**不推荐**)
- TLS 1.1 ⚠️(已废弃,**不推荐**)
- TLS 1.2 ✅(推荐的最低版本)
- TLS 1.3 ✅(推荐)
> ⚠️ **安全提示(不推荐 TLS 1.0 / 1.1)**
> TLS 1.0 与 TLS 1.1 已被 [RFC 8996](https://www.rfc-editor.org/rfc/rfc8996) 正式废弃且不再安全,**不建议使用**。
> 本模块(`netleaf_tls`)作为**独立的 TLS 扩展库**统一负责 NetLeaf 的 TLS 能力;保留 TLS 1.0/1.1 仅为兼容老旧对端,
> 实际使用请将 `min_proto` 设置为 `NL_TLS_PROTO_TLS1_2` 或更高。
## 开源项目来源
本模块基于以下开源项目:
| 项目 | 用途 | 许可证 | 仓库链接 |
|------|------|--------|----------|
| **mbedTLS** | TLS/SSL 加密库 | Apache 2.0 / GPL v2.0 | [Mbed-TLS/mbedTLS](https://github.com/Mbed-TLS/mbedTLS) |
## 注意事项
1. **证书文件路径**:确保证书文件路径正确,建议使用绝对路径
2. **随机数生成**:TLS 握手需要安全的随机数,已内置 entropy + CTR-DRBG
3. **线程安全**:单个 TLS 上下文不保证线程安全,多线程使用请各自创建独立上下文
4. **错误处理**:始终检查函数返回值,使用 `nl_tls_strerror()` 获取错误详情
## 相关文档
- [API 参考](API-Reference.md) - 完整 API 列表
- [功能特性](Features.md) - TLS 功能介绍
- [示例代码](Examples.md) - 使用示例