SSL/TLS

Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.


功能概述

本章节介绍SSL/TLS协议的基本概念、功能特点和应用场景,帮助用户理解SSL在嵌入式/物联网场景中的应用。

简介

SSL/TLS功能模块提供统一的加密通信接口,支持多种SSL/TLS协议和加密算法,提供安全的数据传输功能。该模块支持证书验证、会话恢复等高级特性。

SSL(Secure Sockets Layer)和TLS(Transport Layer Security)是用于在计算机网络中提供通信安全性的加密协议。它们位于应用层协议(如HTTP、SMTP、MQTT)和传输层协议(如TCP)之间,为数据传输提供加密、数据完整性和身份验证。

功能特点

  • 多协议支持:支持TLS和DTLS协议

  • 灵活的认证方式:支持证书认证和PSK认证

  • 证书管理:支持CA证书、客户端证书的加载和验证

  • 会话管理:支持会话恢复和复用

  • 非阻塞模式:支持异步IO操作

  • 错误处理:提供详细的错误码和错误信息

  • 安全特性:支持证书验证、主机名验证等

应用场景

  • HTTPS安全通信:为Web应用提供加密通信

  • MQTT over TLS:物联网设备的安全MQTT通信

  • 安全的WebSocket连接:实时通信的安全保障

  • DTLS安全UDP通信:基于UDP的安全通信

  • 其他需要加密通信的场景:如FTP over TLS、邮件加密传输等

SSL API

头文件

qosa_def.h

qosa_sys.h

qosa_queue_list.h

qcm_vtls_cfg.h

函数概览

函数

描述

qcm_ssl_init()

初始化SSL/TLS模块

qcm_ssl_new()

创建SSL连接对象

qcm_ssl_free()

用于回收qcm_ssl_new申请的资源

qcm_ssl_connect()

发送SSL链接接口,阻塞式接口

qcm_ssl_connect_nonblocking()

发送SSL链接接口,非阻塞式接口

qcm_ssl_close()

SSL资源释放关闭

qcm_ssl_read()

SSL连接成功后数据读取接口

qcm_ssl_write()

SSL连接成功后数据发送接口

qcm_ssl_add_sessionid()

设置SSL session会话保存

qcm_ssl_get_session()

获取SSL session会话ID

qcm_ssl_clean_all_sessionid()

清空全部SSL session会话

qcm_ssl_version()

获取SSL版本相关信息

qcm_ssl_data_pending()

获取SSL缓存数据信息状态

qcm_ssl_check_ciphersuit_is_valid()

检索对应的ciphersuit算法是否有效

qcm_ssl_set_hostinfo()

如果开启SNI或者session,则必须配置hostinfo连接信息,用以保存host主机名称以及对应的端口号

qcm_ssl_set_cacertex_path()

设置全局SSL使用的CA证书

qcm_ssl_get_cacertex_path()

获取全局对应配置的CA证书路径

函数详解

本章节详细说明SSL/TLS功能模块提供的API,包括初始化、连接管理、数据传输、会话管理以及辅助接口。

初始化和配置API

qcm_ssl_init

  • 功能描述
    VTLS相关功能初始化调用,用于初始化内部配置管理信息,只需要初始化一次即可,可重复调用。

  • 函数原型

int qcm_ssl_init(void)
  • 参数说明

  • 返回值说明
    1:函数执行成功
    0:函数执行失败

备注

  1. 在调用任何其他SSL函数之前,必须至少调用一次此函数。

  2. 该函数初始化SSL模块的全局资源,多次调用效果相同。

  3. 建议在程序启动时调用一次,在程序退出时不需要显式调用去初始化函数。

示例

int main(void)
{
    if (qcm_ssl_init() == 0) {
        printf("SSL初始化失败\n");
        return -1;
    }
    /* 使用SSL功能... */
    return 0;
}

qcm_ssl_new

  • 功能描述
    创建SSL连接对象,针对 qcm_ssl_config_t 可以根据需要自行配置对应所要启用的SSL能力。

  • 函数原型

qcm_ssl_connect_data_t *qcm_ssl_new(qcm_ssl_config_t *ssl_config_ptr)
  • 参数说明

参数名

输入/输出

类型

说明

ssl_config_ptr

输入

qcm_ssl_config_t*

用户自定义SSL配置

  • 返回值说明
    返回对应申请地址:函数执行成功
    OSA_NULL:函数执行失败

备注

  1. 调用此函数前必须确保已调用 qcm_ssl_init() 进行初始化。

  2. 返回的指针需要在使用完毕后通过 qcm_ssl_free() 释放。

  3. 配置结构体中的字段应根据实际使用场景进行设置,不使用的字段可以设置为 NULL0

  • 示例

int main(void)
{
    qcm_ssl_config_t ssl_config = {0};
    qcm_ssl_connect_data_t *ssl_conn = NULL;
    
    // 配置SSL参数
    ssl_config.ssl_version = QCM_SSL_VERSION_3;  // TLS 1.2
    ssl_config.transport = QCM_SSL_TLS_PROTOCOL;
    ssl_config.auth_mode = QCM_SSL_VERIFY_SERVER;
    
    if (qcm_ssl_init() == 0) {
        return -1;
    }
    
    ssl_conn = qcm_ssl_new(&ssl_config);
    if (ssl_conn == NULL) {
        printf("创建SSL连接对象失败\n");
        return -1;
    }
    
    // 使用SSL连接...
    
    qcm_ssl_free(ssl_conn);
    return 0;
}

qcm_ssl_free

  • 函数原型

void qcm_ssl_free(qcm_ssl_connect_data_t *connssl)
  • 功能描述
    用于回收 qcm_ssl_new() 申请的资源。

  • 参数说明

参数名

输入/输出

类型

说明

connssl

输入

*qcm_ssl_connect_data_t **

SSL连接地址指针

  • 返回值说明

备注

  1. 调用之前需要先执行 qcm_ssl_close(),释放SSL会话。

  2. 释放后的指针不应再被使用。

  3. 对NULL指针调用此函数是安全的。

示例

void cleanup_ssl(qcm_ssl_connect_data_t *ssl_conn)
{
    if (ssl_conn != NULL) {
        qcm_ssl_close(ssl_conn);
        qcm_ssl_free(ssl_conn);
    }
}

连接管理API

qcm_ssl_connect

  • 函数原型

qcm_vtls_result_status_e qcm_ssl_connect(qcm_ssl_connect_data_t *connssl)
  • 功能描述
    发送SSL链接接口和阻塞式接口,退出即可检查对应SSL链接状态。

  • 参数说明

参数名

输入/输出

类型

说明

connssl

输入

*qcm_ssl_connect_data_t **

SSL内部链接配置指针

  • 返回值说明
    QCM_VTLS_RESULT_OK:函数执行成功
    其他错误码:函数执行失败

备注

  1. 此函数为阻塞式调用,在SSL握手完成或超时前不会返回。

  2. 调用前需要确保已正确配置SSL连接对象。

  3. 建议设置合理的超时时间,避免长时间阻塞。

  • 示例

int establish_ssl_connection(qcm_ssl_connect_data_t *ssl_conn)
{
    qcm_vtls_result_status_e result;
    
    result = qcm_ssl_connect(ssl_conn);
    if (result != QCM_VTLS_RESULT_OK) {
        printf("SSL连接失败,错误码: %d\n", result);
        return -1;
    }
    
    printf("SSL连接成功建立\n");
    return 0;
}

qcm_ssl_connect_nonblocking

  • 函数原型

qcm_vtls_result_status_e qcm_ssl_connect_nonblocking(qcm_ssl_connect_data_t *connssl, qosa_bool_t *done);
  • 功能描述
    发送SSL链接接口,非阻塞式接口。

  • 参数说明

参数名

输入/输出

类型

说明

connssl

输入/输出

*qcm_ssl_connect_data_t **

SSL连接对象指针

done

输出

qosa_bool_t *

用来告知上层握手是否完成;取值范围:0~1

  • 返回值说明
    QCM_VTLS_RESULT_OK:函数执行成功
    其他错误码:函数执行失败

备注

  1. 此函数为非阻塞式调用,需要多次调用直到握手完成。

  2. 当*done为 QOSA_TRUE 时,表示握手完成。

  3. 在非阻塞模式下,需要配合 qcm_ssl_data_pending() 等函数使用。

  • 示例

int nonblocking_ssl_connect(qcm_ssl_connect_data_t *ssl_conn)
{
    qcm_vtls_result_status_e result;
    qosa_bool_t done = QOSA_FALSE;
    int retry_count = 0;
    
    while (!done && retry_count < 100) {
        result = qcm_ssl_connect_nonblocking(ssl_conn, &done);
        if (result != QCM_VTLS_RESULT_OK && result != QCM_VTLS_SSL_READ_WRITE_EAGAIN) {
            printf("非阻塞SSL连接失败,错误码: %d\n", result);
            return -1;
        }
        
        if (!done) {
            // 等待一段时间后重试
            qosa_sleep(100);
            retry_count++;
        }
    }
    
    if (done) {
        printf("非阻塞SSL连接成功建立\n");
        return 0;
    } else {
        printf("非阻塞SSL连接超时\n");
        return -1;
    }
}

qcm_ssl_close

  • 函数原型

void qcm_ssl_close(qcm_ssl_connect_data_t *connssl)
  • 功能描述
    SSL资源释放关闭。

  • 参数说明

参数名

输入/输出

类型

说明

connssl

输入

*qcm_ssl_connect_data_t **

SSL连接对象指针

  • 返回值说明

备注

  1. 关闭SSL连接后,底层socket连接可能仍然保持打开状态。

  2. 建议在关闭SSL连接后也关闭底层socket连接。

  3. 对NULL指针调用此函数是安全的。

  • 示例

void close_ssl_connection(qcm_ssl_connect_data_t *ssl_conn, int socket_fd)
{
    if (ssl_conn != NULL) {
        qcm_ssl_close(ssl_conn);
    }
    
    if (socket_fd >= 0) {
        close(socket_fd);
    }
}

数据传输API

qcm_ssl_read

  • 函数原型

qosa_size_t qcm_ssl_read(qcm_ssl_connect_data_t *connssl, char *buf, qosa_size_t buffersize, qcm_vtls_result_status_e *curlcode)
  • 功能描述
    SSL连接成功后数据读取接口。

  • 参数说明

参数名

输入/输出

类型

说明

connssl

输入

*qcm_ssl_connect_data_t **

对应ssl内部链接指针;范围为有效连接对象指针

buf

输出

char *

read读取数据内容指针;范围为有效缓冲区指针

buffersize

输入

qosa_size_t

对应buff空间大小,需大于0

curlcode

输出

*qcm_vtls_result_status_e **

错误码;范围为有效指针

  • 返回值说明
    返回对应实际读取到的数量大小。

备注

  1. 读取的数据可能少于请求的缓冲区大小。

  2. 当返回 0 且错误码为 QCM_VTLS_SSL_PEER_CLOSE_NOTIFY_ERR 时,表示对端已关闭连接。

  3. 在非阻塞模式下,可能需要多次调用才能读取完整数据。

  • 示例

int read_ssl_data(qcm_ssl_connect_data_t *ssl_conn, char *buffer, size_t buffer_size)
{
    qcm_vtls_result_status_e error_code;
    qosa_size_t bytes_read;
    
    bytes_read = qcm_ssl_read(ssl_conn, buffer, buffer_size, &error_code);
    
    if (error_code != QCM_VTLS_RESULT_OK) {
        if (error_code == QCM_VTLS_SSL_PEER_CLOSE_NOTIFY_ERR) {
            printf("对端已关闭SSL连接\n");
        } else {
            printf("读取SSL数据失败,错误码: %d\n", error_code);
        }
        return -1;
    }
    
    printf("成功读取%zu字节数据\n", bytes_read);
    return bytes_read;
}

qcm_ssl_write

  • 函数原型

qosa_size_t qcm_ssl_write(qcm_ssl_connect_data_t *connssl, char *buf, qosa_size_t buffersize, qcm_vtls_result_status_e *curlcode)
  • 功能描述
    向SSL连接写入数据。

  • 参数说明

参数名

输入/输出

类型

说明

connssl

输入

*qcm_ssl_connect_data_t **

SSL连接对象指针;范围为有效连接对象指针

buf

输入

char *

write写数据内容指针;范围为有效数据指针

buffersize

输入

qosa_size_t

对应buff内部的实际数据长度;需大于0

curlcode

输出

*qcm_vtls_result_status_e **

错误码;范围为有效指针

  • 返回值说明
    返回对应实际写入的数量大小。

备注

  1. 写入的数据可能少于请求的数据大小。

  2. 在非阻塞模式下,可能需要多次调用才能写入完整数据。

  3. 建议检查返回值,确保所有数据都已成功写入。

  • 示例

int write_ssl_data(qcm_ssl_connect_data_t *ssl_conn, const char *data, size_t data_len)
{
    qcm_vtls_result_status_e error_code;
    qosa_size_t total_written = 0;
    qosa_size_t bytes_written;
    
    while (total_written < data_len) {
        bytes_written = qcm_ssl_write(ssl_conn, (char *)data + total_written, 
                                      data_len - total_written, &error_code);
        
        if (error_code != QCM_VTLS_RESULT_OK && 
            error_code != QCM_VTLS_SSL_READ_WRITE_EAGAIN) {
            printf("写入SSL数据失败,错误码: %d\n", error_code);
            return -1;
        }
        
        if (bytes_written > 0) {
            total_written += bytes_written;
        }
        
        if (total_written < data_len) {
            // 等待可写事件
            qosa_sleep(10);
        }
    }
    
    printf("成功写入%zu字节数据\n", total_written);
    return total_written;
}

会话管理API

qcm_ssl_add_sessionid

  • 函数原型

qcm_vtls_result_status_e qcm_ssl_add_sessionid(qcm_ssl_connect_data_t *connssl, void *ssl_sessionid)
  • 功能描述
    设置SSL session会话保存。

  • 参数说明

参数名

输入/输出

类型

说明

connssl

输入

*qcm_ssl_connect_data_t **

SSL连接对象指针,范围为有效连接对象指针

ssl_sessionid

输入

void *

SSL会话结构体指针;范围为有效的结构体指针

  • 返回值说明
    QCM_VTLS_RESULT_OK:函数执行成功
    其他错误码:函数执行失败

备注

  1. 会话恢复可以显著提高后续SSL连接的速度。

  2. 保存的会话信息应在后续连接中尽快使用。

  3. 会话信息可能因服务器配置而过期。

  • 示例

int save_ssl_session(qcm_ssl_connect_data_t *ssl_conn, void *session_data)
{
    qcm_vtls_result_status_e result;
    
    result = qcm_ssl_add_sessionid(ssl_conn, session_data);
    if (result != QCM_VTLS_RESULT_OK) {
        printf("保存SSL会话失败,错误码: %d\n", result);
        return -1;
    }
    
    printf("SSL会话保存成功\n");
    return 0;
}

qcm_ssl_get_sessionid

  • 函数原型

qcm_vtls_result_status_e qcm_ssl_get_sessionid(qcm_ssl_connect_data_t *connssl, void **ssl_sessionid);
  • 功能描述
    获取SSL session会话ID。

  • 参数说明

参数名

输入/输出

类型

说明

connssl

输入

*qcm_ssl_connect_data_t **

SSL连接对象指针;范围为有效连接对象指针

ssl_sessionid

输出

void **

获取对应的ssl session地址;范围为有效双重指针

  • 返回值说明
    QCM_VTLS_RESULT_OK:函数执行成功
    其他错误码:函数执行失败

备注

  1. 获取的会话信息可用于后续连接的快速恢复。

  2. 使用完毕后需要适当管理会话内存。

  3. 会话信息可能因超时或服务器策略而失效。

  • 示例

int get_ssl_session(qcm_ssl_connect_data_t *ssl_conn, void **session_ptr)
{
    qcm_vtls_result_status_e result;
    
    result = qcm_ssl_get_sessionid(ssl_conn, session_ptr);
    if (result != QCM_VTLS_RESULT_OK) {
        printf("获取SSL会话失败,错误码: %d\n", result);
        return -1;
    }
    
    if (*session_ptr == NULL) {
        printf("未找到有效的SSL会话\n");
        return -1;
    }
    
    printf("SSL会话获取成功\n");
    return 0;
}

qcm_ssl_clean_all_sessionid

  • 函数原型

void qcm_ssl_clean_all_sessionid(void)
  • 功能描述
    清空全部SSL session会话。

  • 参数说明

  • 返回值说明

备注

  1. 此函数清除所有保存的SSL会话信息。

  2. 调用后,所有会话恢复功能将不可用,直到建立新的会话。

  3. 建议在内存紧张或安全要求高的情况下调用此函数。

  • 示例

void cleanup_all_sessions(void)
{
    qcm_ssl_clean_all_sessionid();
    printf("所有SSL会话已清除\n");
}

辅助API

qcm_ssl_version

  • 函数原型

qosa_size_t qcm_ssl_version(char *buffer, qosa_size_t size)
  • 功能描述
    获取SSL版本相关信息。

  • 参数说明

参数名

输入/输出

类型

说明

buffer

输出

char *

存储版本信息相关地址空间;范围为有效缓冲区指针

size

输入

qosa_size_t

缓冲区大小;需大于0

  • 返回值说明
    返回实际赋值buffer长度大小

备注

  1. 确保缓冲区足够大以容纳版本信息。

  2. 版本信息通常包括SSL库名称和版本号。

  3. 可用于调试和日志记录。

  • 示例

void print_ssl_version(void)
{
    char version_buffer[256];
    qosa_size_t length;
    
    length = qcm_ssl_version(version_buffer, sizeof(version_buffer));
    if (length > 0 && length < sizeof(version_buffer)) {
        version_buffer[length] = '\0';
        printf("SSL版本信息: %s\n", version_buffer);
    } else {
        printf("获取SSL版本信息失败\n");
    }
}

qcm_ssl_data_pending

  • 函数原型

qosa_bool_t qcm_ssl_data_pending(qcm_ssl_connect_data_t *connssl)
  • 功能描述
    获取SSL缓存数据信息状态。

  • 参数说明

参数名

输入/输出

类型

说明

connssl

输入

*qcm_ssl_connect_data_t **

SSL连接对象指针;范围为有效连接对象指针

  • 返回值说明
    0:没有数据
    1:有数据

备注

  1. 在非阻塞读取前调用此函数可以避免不必要的阻塞。

  2. 返回值只表示SSL层有缓存数据,不代表socket层有数据。

  3. 对于性能敏感的应用程序,合理使用此函数可以提高效率。

  • 示例

int check_pending_data(qcm_ssl_connect_data_t *ssl_conn)
{
    if (qcm_ssl_data_pending(ssl_conn)) {
        printf("SSL缓存中有待处理数据\n");
        return 1;
    } else {
        printf("SSL缓存中无待处理数据\n");
        return 0;
    }
}

qcm_ssl_check_ciphersuit_is_valid

  • 函数原型

qosa_bool_t qcm_ssl_check_ciphersuit_is_valid(int cs_id)
  • 功能描述
    检索对应的ciphersuit算法是否有效。

  • 参数说明

参数名

输入/输出

类型

说明

cs_id

输入

int

加密套件ID;范围为有效加密套件ID

  • 返回值说明
    0:无效
    1:有效

备注

  1. 加密套件ID应与SSL库支持的套件匹配。

  2. 使用不支持的加密套件可能导致连接失败。

  3. 建议在配置加密套件前使用此函数进行验证。

  • 示例

int validate_ciphersuite(int cipher_id)
{
    if (qcm_ssl_check_ciphersuit_is_valid(cipher_id)) {
        printf("加密套件%d有效\n", cipher_id);
        return 1;
    } else {
        printf("加密套件%d无效\n", cipher_id);
        return 0;
    }
}

qcm_ssl_set_hostinfo

  • 函数原型

qcm_vtls_result_status_e qcm_ssl_set_hostinfo(qcm_ssl_connect_data_t *connssl, const char *hostname, qosa_uint16_t port);
  • 功能描述
    如果开启SNI,或者session则必须配置hostinfo连接信息,用以保存host主机名称以及对应的端口号。

  • 参数说明

参数名

输入/输出

类型

说明

connssl

输入/输出

*qcm_ssl_connect_data_t **

SSL连接对象指针;范围为有效连接对象指针

hostname

输入

const char *

配置SNI的主机名称;范围为有效域名字符串

port

输入

qosa_uint16_t

配置SNI的主机端口号;范围为有效主机端口号

  • 返回值说明
    QCM_VTLS_RESULT_OK:函数执行成功
    其他错误码:函数执行失败

备注

  1. SNI(Server Name Indication)用于虚拟主机场景。

  2. 主机名应与服务器证书中的主机名匹配。

  3. 端口号用于会话恢复时的标识。

  • 示例

int set_host_info(qcm_ssl_connect_data_t *ssl_conn, const char *hostname, uint16_t port)
{
    qcm_vtls_result_status_e result;
    
    result = qcm_ssl_set_hostinfo(ssl_conn, hostname, port);
    if (result != QCM_VTLS_RESULT_OK) {
        printf("设置主机信息失败,错误码: %d\n", result);
        return -1;
    }
    
    printf("主机信息设置成功: %s:%d\n", hostname, port);
    return 0;
}

qcm_ssl_set_cacertex_path

  • 函数原型

qcm_vtls_result_status_e qcm_ssl_set_cacertex_path(int index, char *path)
  • 功能描述
    设置全局SSL使用的CA证书,配置将失效用户在 qcm_ssl_config_t 结构体中 ca_cert_path 配置。

  • 参数说明

参数名

输入/输出

类型

说明

index

输入

int

证书索引;范围:0~5(SSL_MAX_CA_CERT_EX_CNT-1)

path

输入

char *

证书路径

  • 返回值说明
    QCM_VTLS_RESULT_OK:函数执行成功
    其他错误码:函数执行失败

备注

  1. 证书路径应为绝对路径。

  2. 证书文件格式应为PEM格式。

  3. 多个CA证书可以按索引顺序设置。

  • 示例

int set_ca_certificate(int index, const char *cert_path)
{
    qcm_vtls_result_status_e result;
    char *path_copy = strdup(cert_path);
    
    if (path_copy == NULL) {
        printf("内存分配失败\n");
        return -1;
    }
    
    result = qcm_ssl_set_cacertex_path(index, path_copy);
    if (result != QCM_VTLS_RESULT_OK) {
        printf("设置CA证书路径失败,错误码: %d\n", result);
        free(path_copy);
        return -1;
    }
    
    printf("CA证书路径设置成功: 索引%d -> %s\n", index, cert_path);
    // 注意:path_copy由SSL库管理,不要释放
    return 0;
}

qcm_ssl_get_cacertex_path

函数原型

qcm_vtls_result_status_e qcm_ssl_get_cacertex_path(int index, char **path)
  • 功能描述
    获取全局对应配置的CA证书路径。

  • 参数说明

参数名

输入/输出

类型

说明

index

输入

int

要获取CA证书路径序号;范围:0~5

path

输出

char **

对应的CA证书路径地址;范围:有效双重指针

  • 返回值说明
    QCM_VTLS_RESULT_OK:函数执行成功
    其他错误码:函数执行失败

备注

  1. 返回的路径字符串由SSL库管理,不应修改或释放。

  2. 索引应在有效范围内。

  3. 可用于验证配置或调试。

示例

int get_ca_certificate_path(int index)
{
    qcm_vtls_result_status_e result;
    char *path = NULL;
    
    result = qcm_ssl_get_cacertex_path(index, &path);
    if (result != QCM_VTLS_RESULT_OK) {
        printf("获取CA证书路径失败,错误码: %d\n", result);
        return -1;
    }
    
    if (path != NULL) {
        printf("CA证书路径[%d]: %s\n", index, path);
    } else {
        printf("CA证书路径[%d]: 未设置\n", index);
    }
    
    return 0;
}

最佳实践

线程安全

  • 初始化/去初始化qcm_ssl_init()qcm_ssl_clean_all_sessionid() 不是线程安全的,需要外部同步。

  • 连接对象:每个线程应使用独立的SSL连接对象,避免共享。

  • 会话管理:会话缓存操作需要适当的同步机制。

性能提示

  • 会话恢复:启用会话缓存可以显著提高后续连接速度。

  • 连接复用:尽可能复用SSL连接对象。

  • 非阻塞IO:在高并发场景下使用非阻塞模式。

  • 缓冲区大小:根据应用场景调整读写缓冲区大小。

超时配置建议

  • 握手超时:根据网络状况设置合理的SSL握手超时时间(建议30~60秒)。

  • 读写超时:根据数据传输量设置读写超时。

  • 心跳机制:对于长连接,实现应用层心跳保活。

常见问题排查指南

问题

原因

解决方案

SSL连接失败

证书验证失败

检查CA证书、客户端证书配置

握手超时

网络延迟或服务器问题

增加超时时间或检查网络连接

内存不足

SSL对象未释放

确保正确调用 qcm_ssl_free()

数据读取失败

连接已关闭

检查对端状态或实现重连机制

性能低下

未启用会话缓存

启用会话缓存功能

结构体定义

qcm_ssl_config_t

SSL配置结构体定义如下:

typedef struct
{
    qcm_ssl_version_type_e      ssl_version;
    qcm_ssl_transport_type_e    transport;
    int                        *ciphersuites;
    qcm_ssl_authmode_e          auth_mode;
    qosa_bool_t                 sni_enable;
    char                       *ca_cert_path[SSL_MAX_CA_CERT_CNT];
    char                       *own_cert_path;
    char                       *own_key_path;
    char                       *own_key_pwd;
    char                       *ca_cert_buffer[SSL_MAX_CA_CERT_CNT];
    qcm_ssl_client_cert_type_e  client_cert_type;
    char                       *own_cert_buffer;
    char                       *own_key_buff;
    int                         ssl_negotiate_timeout;
    int                         ignore_invalid_certsign;
    qosa_uint32_t               ignore_certitem;
    int                         ignore_multi_certchain_verify;
    qcm_ssl_dtls_version_type_e dtls_version;
    int                         psk_enable;
    char                       *psk_identity;
    char                       *psk_key;
    char                        psk_key_len;
    qosa_bool_t                 renegotiation;
    qosa_ptr                    socket_fd;
    qosa_uint8_t                ssl_log_debug;
    qosa_bool_t                 session_cache_enable;
    qosa_uint16_t               dtls_mtu_size;
    qosa_bool_t                 close_time_mode;
    char                       *alpn_name;
    qosa_bool_t                 mfl_support;
    qosa_uint8_t                mfl_size;
    vtls_io_read                io_read;
    vtls_io_write               io_write;
    vtls_io_select              io_select;
} qcm_ssl_config_t;

参数

类型

说明

ssl_version

qcm_ssl_version_type_e

SSL算法版本类型;范围请参考 qcm_ssl_version_type_e 枚举定义

transport

qcm_ssl_transport_type_e

SSL传输类型(TLS/DTLS);范围请参考 qcm_ssl_transport_type_e 枚举定义

ciphersuites

int

配置指定的支持的算法类型;传入支持算法加密套件的整型数组指针,不推荐客户使用,如需要制定加密套件请联系FAE获取demo

auth_mode

qcm_ssl_authmode_e

鉴权类型;范围请参考qcm_ssl_authmode_e枚举定义

sni_enable

qosa_bool_t

SNI扩展是否启用
QOSA_TRUE打开SNI,QOSA_FALSE关闭SNI

ca_cert_path

qosa_bool_t

储存CA根证书存放的路径和名称

own_cert_path

char

存放客户端证书路径名称

own_key_path

char

存放客户端公钥路径名称

own_key_pwd

char

客户端公钥密码字符串

ca_cert_buffer

char

储存CA根证书内容

client_cert_type

qcm_ssl_client_cert_type_e

客户端证书类型是buff模式还是文件方式

own_cert_buffer

char

客户端证书内容地址指针

own_key_buff

char

客户端证书key内容地址指针

ssl_negotiate_timeout

int

SSL握手超时时间

ignore_invalid_certsign

int

忽略证书中对应项目的某一项错误值

ignore_certitem

qosa_uint32_t

是否忽略对证书的校验

ignore_multi_certchain_verify

int

忽略多级证书链校验

dtls_version

qcm_ssl_dtls_version_type_e

DTLS版本DTLS1.1 DTLS1.2

psk_enable

int

是否使能DTLS PSK功能

psk_identity

char

对应DTLS PSK identity只能是字符串

psk_key

char

DTLS PSK字符可以包含字符0x00

psk_key_len

char

psk key字符长度

renegotiation

qosa_bool_t

是否启用TLS会话重协商

socket_fd

qosa_ptr

对应socket连接的连接句柄,可以是原始套接字FD,也可以是强转的指针地址。一般都是在如io_read/io_write/io_select中通过强转为用户自定义的句柄类型

ssl_log_debug

qosa_uint8_t

ssl调试log是否打开

session_cache_enable

qosa_bool_t

选择开启或关闭session cache功能

dtls_mtu_size

qosa_uint16_t

配置DTLS MTU大小

close_time_mode

qosa_bool_t

SSL关闭延时时间是否启用

alpn_name

char

存储SSL的ALPN信息

mfl_support

qosa_bool_t

是否支持MFL扩展

mfl_size

qosa_uint8_t

配置MFL扩展大小

io_read

vtls_io_read

配置SSL使用的read io接口函数

io_write

vtls_io_write

配置SSL使用的write IO接口函数

io_select

vtls_io_select

配置SSL使用的select IO函数接口

qcm_ssl_connect_data_t

SSL连接数据结构体定义如下:

typedef struct
{
    qcm_ssl_connection_state_e state;
    qcm_ssl_connect_state_e    connecting_state;
    void                      *backend;
    qcm_ssl_config_t           ssl_config;
    char                      *hostname;
    int                        port;
    qosa_time_t                cur_connect_time;
    qosa_timer_t               dtls_retransmission_timer;
} qcm_ssl_connect_data_t;

参数

类型

说明

state

qcm_ssl_connection_state_e

对应SSL最上层状态

connecting_state

qcm_ssl_connect_state_e

对应SSL内部链接状态变化

backend

void

对应SSL后端内部结构体存储信息

ssl_config

qcm_ssl_config_t

当前SSL链接所用的config配置信息

hostname

char

主机名

port

int

远程端口

cur_connect_time

qosa_time_t

SSL开始握手连接的当前时间

dtls_retransmission_timer

qosa_timer_t

DTLS的重传定时器

枚举定义

qcm_ssl_version_type_e

SSL版本类型枚举定义如下:

typedef enum
{
    QCM_SSL_VERSION_0 = 0,   /* SSL protocol ver. 3.0 */
    QCM_SSL_VERSION_1 = 1,   /* TLS protocol ver. 1.0 */
    QCM_SSL_VERSION_2 = 2,   /* TLS protocol ver. 1.1 */
    QCM_SSL_VERSION_3 = 3,   /* TLS protocol ver. 1.2 */
    QCM_SSL_VERSION_ALL = 4, /* NOTE: select ALL */
    QCM_SSL_VERSION_5 = 5,   /* TLS protocol ver. 1.3 */
} qcm_ssl_version_type_e;

成员

说明

QCM_SSL_VERSION_0

SSL协议版本3.0

QCM_SSL_VERSION_1

TLS协议版本1.0

QCM_SSL_VERSION_2

TLS协议版本1.1

QCM_SSL_VERSION_3

TLS协议版本1.2

QCM_SSL_VERSION_ALL

选择所有版本

QCM_SSL_VERSION_5

TLS协议版本1.3

qcm_ssl_transport_type_e

SSL传输类型枚举定义如下:

typedef enum
{
    QCM_SSL_TLS_PROTOCOL = 0,  /* SSL使用TLS连接协议,仅适用用TCP */
    QCM_SSL_DTLS_PROTOCOL = 1, /* SSL使用DTLS连接协议,仅适用于UDP通讯 */
} qcm_ssl_transport_type_e;

成员

说明

QCM_SSL_TLS_PROTOCOL

SSL使用TLS连接协议,仅适用用TCP

QCM_SSL_DTLS_PROTOCOL

SSL使用DTLS连接协议,仅适用于UDP通讯

qcm_ssl_authmode_e

SSL认证模式枚举定义如下:

typedef enum
{
    QCM_SSL_VERIFY_NULL = 0x0000,          /* SSL无认证,不校验服务器证书 */
    QCM_SSL_VERIFY_SERVER = 0x0001,        /* SSL校验服务器证书 */
    QCM_SSL_VERIFY_CLIENT_SERVER = 0x0002, /* SSL连接双向认证,检验服务器证书,服务器校验客户端证书 */
} qcm_ssl_authmode_e;

成员

说明

QCM_SSL_VERIFY_NULL

SSL无认证,不校验服务器证书

QCM_SSL_VERIFY_SERVER

SSL校验服务器证书

QCM_SSL_VERIFY_CLIENT_SERVER

SSL连接双向认证,检验服务器证书,服务器校验客户端证书

qcm_ssl_client_cert_type_e

客户端证书类型枚举定义如下:

typedef enum
{
    QCM_SSL_CLIENT_CERT_FILE = 0,   /* 客户端证书是以文件形式保存提供 */
    QCM_SSL_CLIENT_CERT_BUFFER = 1, /* 客户端证书是以buffer缓存形式提供保存 */
} qcm_ssl_client_cert_type_e;

成员

说明

QCM_SSL_CLIENT_CERT_FILE

客户端证书是以文件形式保存提供

QCM_SSL_CLIENT_CERT_BUFFER

客户端证书是以buffer缓存形式提供保存

qcm_ssl_dtls_version_type_e

DTLS版本类型枚举定义如下:

typedef enum
{
    QCM_SSL_VER_DTLS10 = 0,   /* DTLS protocol ver. 1.0. */
    QCM_SSL_VER_DTLS12 = 1,   /* DTLS protocal ver. 1.2. */
    QCM_SSL_VER_DTLS_ALL = 2, /* 支持DTLS1.0 DTLS1.2服务器自选 */
} qcm_ssl_dtls_version_type_e;

成员

说明

QCM_SSL_VER_DTLS10

DTLS协议版本1.0

QCM_SSL_VER_DTLS12

DTLS协议版本1.2

QCM_SSL_VER_DTLS_ALL

支持DTLS1.0 DTLS1.2服务器自选

qcm_ssl_connection_state_e

SSL连接状态枚举定义如下:

typedef enum
{
    QCM_SSL_CONNECTION_NONE,        /*!< SSL链接初始状态 */
    QCM_SSL_CONNECTION_NEGOTIATING, /*!< 正在协商中 */
    QCM_SSL_CONNECTION_COMPLETE     /*!< 协商完成 */
} qcm_ssl_connection_state_e;

成员

说明

QCM_SSL_CONNECTION_NONE

SSL链接初始状态

QCM_SSL_CONNECTION_NEGOTIATING

正在协商中

QCM_SSL_CONNECTION_COMPLETE

协商完成

qcm_ssl_connect_state_e

SSL连接内部状态枚举定义如下:

typedef enum
{
    QCM_SSL_CONNECT_1,         /*!< 初始阶段SSL初始化配置 */
    QCM_SSL_CONNECT_2,         /*!< SSL链接鉴权阶段 */
    QCM_SSL_CONNECT_2_READING, /*!< SSL异步Socket状态读取数据阶段 */
    QCM_SSL_CONNECT_2_WRITING, /*!< SSL异步Socket状态写入数据阶段 */
    QCM_SSL_CONNECT_3,         /*!< SSL链接已经完成,最后的信息保存 */
    QCM_SSL_CONNECT_DONE       /*!< SSL链接完成 */
} qcm_ssl_connect_state_e;

成员

说明

QCM_SSL_CONNECT_1

初始阶段SSL初始化配置

QCM_SSL_CONNECT_2

SSL链接鉴权阶段

QCM_SSL_CONNECT_2_READING

SSL异步Socket状态读取数据阶段

QCM_SSL_CONNECT_2_WRITING

SSL异步Socket状态写入数据阶段

QCM_SSL_CONNECT_3

SSL链接已经完成,最后的信息保存

QCM_SSL_CONNECT_DONE

SSL链接完成

qcm_vtls_result_status_e

VTLS结果状态枚举定义如下:

typedef enum
{
    QCM_VTLS_RESULT_OK = 0,
    QCM_VTLS_FAILED_INIT_ERR = 1 | QCM_ERRCODE_VTLS_BASE,
    QCM_VTLS_SSL_CONNECT_ERR,
    QCM_VTLS_SSL_INVALID_PARAM_ERR,
    QCM_VTLS_PEER_FAILED_VERIFICATION,
    QCM_VTLS_SSL_READ_WRITE_EAGAIN,
    QCM_VTLS_SSL_OPERATION_TIMEDOUT,
    QCM_VTLS_SSL_MEMORY_ERR,
    QCM_VTLS_SSL_PEER_CLOSE_NOTIFY_ERR,

    QCM_VTLS_RESULT_MAX
} qcm_vtls_result_status_e;

成员

说明

QCM_VTLS_RESULT_OK

操作成功

QCM_VTLS_FAILED_INIT_ERR

初始化错误

QCM_VTLS_SSL_CONNECT_ERR

SSL连接错误

QCM_VTLS_SSL_INVALID_PARAM_ERR

SSL连接无效参数

QCM_VTLS_PEER_FAILED_VERIFICATION

证书校验错误

QCM_VTLS_SSL_READ_WRITE_EAGAIN

非阻塞IO函数返回状态,需要等待事件通知到达后再次调用

QCM_VTLS_SSL_OPERATION_TIMEDOUT

SSL连接操作超时

QCM_VTLS_SSL_MEMORY_ERR

内部内存申请失败

QCM_VTLS_SSL_PEER_CLOSE_NOTIFY_ERR

通知准备关闭,正常结果码

QCM_VTLS_RESULT_MAX

枚举边界

应用逻辑流程图

../../../_images/image_PAeLbtKR1odVQ8xA0PScnLrBnBh.webp

Demo

阻塞式SSL连接示例

完整示例代码,请查看https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/network/network_protocol/ssl/ssl_blocking_demo.c