SSL Development Guide_Rev1.0

中文

Revision History

Version

Date

Author

Revision Content

Rev1.0

2026-03-17

MBB

Initial document creation

1 Introduction

This document introduces the LTE-EC71X SSL2 function interfaces. The function interfaces are declared in the file components/kernel/lierda_api/liot_ssl2/liot_ssl2.h.

1.1 SSL Principle Introduction

SSL/TLS supports three authentication methods: no authentication (no certificate verification, communication encrypted), one-way authentication (client verifies server certificate), and two-way authentication (client and server mutually verify certificates). The main differences lie in the certificate verification direction and the certificates that the client needs to prepare.

Authentication Method

auth_type Configuration

Certificates Required by Client

No Authentication

LIOT_SSL_VERIFY_NONE (0)

No certificate required

One-way Authentication

LIOT_SSL_VERIFY_SERVER (1)

CA root certificate (to verify server)

Two-way Authentication

LIOT_SSL_VERIFY_CLIENT_SERVER (2)

CA root certificate + Client certificate + Client private key

2 API Function Overview

Function

Description

Liot_SSLSetCfg()

Set SSL configuration information

Liot_SSLSocketOpen()

Open SSL connection

Liot_SSLSocketSend()

Send SSL data

Liot_SSLSocketGetStatus()

Get SSL connection status

Liot_SSLSocketClose()

Close SSL connection

3 Type Descriptions

3.1 liot_ssl_session_t

SSL session handle.

  1. Declaration

typedef int liot_ssl_session_t; 

3.2 liot_ssl_client_t

SSL client handle.

  1. Declaration

typedef void *liot_ssl_client_t;

3.3 liot_ssl_config

SSL configuration handle.

  1. Declaration

typedef void *liot_ssl_config;

3.4 liot_sslClient_recvCb_t

SSL client data reception callback function.

  1. Function Declaration

    typedef void (liot_sslClient_recvCb_t)(uint8_t clientId, void data, uint32_t dataLen, void *arg);
    
  2. Parameter Description

    Parameter

    Description

    clientId

    SSL client ID

    data

    Received data

    dataLen

    Data length

    arg

    User parameter

    4.5 liot_ssl_error_code_e

    SSL error codes.

    1. Enumeration Type Declaration

typedef enum {
    LIOT_SSL_SUCCESS               = 0,
    LIOT_SSL_ERROR_UNKOWN          = -1,
    LIOT_SSL_ERROR_WOUNDBLOCK      = -2,
    LIOT_SSL_ERROR_INVALID_PARAM   = -3,
    LIOT_SSL_ERROR_OUT_OF_MEM      = -4,
    LIOT_SSL_ERROR_NOT_SUPPORT     = -5,
    LIOT_SSL_ERROR_HS_FAILURE      = -6,
    LIOT_SSL_ERROR_DECRYPT_FAILURE = -7,
    LIOT_SSL_ERROR_ENCRYPT_FAILURE = -8,
    LIOT_SSL_ERROR_HS_INPROGRESS   = -9,
    LIOT_SSL_ERROR_BAD_REQUEST     = -10,
    LIOT_SSL_ERROR_WANT_READ       = -11,
    LIOT_SSL_ERROR_WANT_WRITE      = -12,
    LIOT_SSL_ERROR_SOCKET_RESET    = -13,
    LIOT_SSL_ERROR_TIMEOUT         = -14,
    LIOT_SSL_ERROR_SOCKET_CLOSED   = -15,
    LIOT_SSL_ERROR_SOCKET_ERROR    = -16,
    LIOT_SSL_ERROR_INVALID_CERT    = -17,
    LIOT_SSL_ERROR_VERIFY_FAILED   = -18,
    LIOT_SSL_ERROR_SEND_FAILURE    = -19,
    LIOT_SSL_ERROR_STATUS_ERROR    = -20,
} liot_ssl_error_code_e;
  1. Enumeration Description

Parameter

Description

LIOT_SSL_SUCCESS

Operation successful

LIOT_SSL_ERROR_UNKOWN

Unknown error

LIOT_SSL_ERROR_WOUNDBLOCK

Blocking error

LIOT_SSL_ERROR_INVALID_PARAM

Invalid parameter

LIOT_SSL_ERROR_OUT_OF_MEM

Insufficient memory

LIOT_SSL_ERROR_NOT_SUPPORT

Feature not supported

LIOT_SSL_ERROR_HS_FAILURE

Handshake failed

LIOT_SSL_ERROR_DECRYPT_FAILURE

Decryption failed

LIOT_SSL_ERROR_ENCRYPT_FAILURE

Encryption failed

LIOT_SSL_ERROR_HS_INPROGRESS

Handshake in progress

LIOT_SSL_ERROR_BAD_REQUEST

Bad request

LIOT_SSL_ERROR_WANT_READ

Need to read

LIOT_SSL_ERROR_WANT_WRITE

Need to write

LIOT_SSL_ERROR_SOCKET_RESET

Socket reset

LIOT_SSL_ERROR_TIMEOUT

Operation timeout

LIOT_SSL_ERROR_SOCKET_CLOSED

Socket closed

LIOT_SSL_ERROR_SOCKET_ERROR

Socket error

LIOT_SSL_ERROR_INVALID_CERT

Invalid certificate

LIOT_SSL_ERROR_VERIFY_FAILED

Verification failed

LIOT_SSL_ERROR_SEND_FAILURE

Send failed

LIOT_SSL_ERROR_STATUS_ERROR

Status error

3.6 liot_ssl_client_status_e

SSL client status.

  1. Enumeration Type Declaration

    typedef enum {
        LIOT_SSL_CLIENT_STATUS_INIT = 0,
        LIOT_SSL_CLIENT_STATUS_CONNECTING,
        LIOT_SSL_CLIENT_STATUS_CONNECTED,
        LIOT_SSL_CLIENT_STATUS_DISCONNECTING,
        LIOT_SSL_CLIENT_STATUS_DISCONNECTED,
        LIOT_SSL_CLIENT_STATUS_CLOSED,
    } liot_ssl_client_status_e;
    
  2. Enumeration Description

Parameter

Description

LIOT_SSL_CLIENT_STATUS_INIT

Initial state

LIOT_SSL_CLIENT_STATUS_CONNECTING

Connecting

LIOT_SSL_CLIENT_STATUS_CONNECTED

Connected

LIOT_SSL_CLIENT_STATUS_DISCONNECTING

Disconnecting

LIOT_SSL_CLIENT_STATUS_DISCONNECTED

Disconnected

LIOT_SSL_CLIENT_STATUS_CLOSED

Closed

3.7 liot_ssl_ca_chain_s

SSL CA certificate chain structure.

  1. Structure Declaration

    typedef struct {
        char *ca_cert_list[LIOT_SSL_CA_CERT_MAX_CNT];
        int ca_depth;
    } liot_ssl_ca_chain_s;
    
  2. Structure Description

Member

Description

ca_cert_list

CA certificate list

ca_depth

CA certificate depth

3.8 liot_ssl_user_cert_s

User certificate information structure.

  1. Structure Declaration

    typedef struct {
        char *cert_file;
        char *key_file;
        char *key_password;
    } liot_ssl_user_cert_s;
    
  2. Structure Description

Member

Description

cert_file

Certificate file

key_file

Private key file

key_password

Private key password

3.9 liot_ssl_psk_info_s

PSK information structure.

  1. Structure Declaration

    typedef struct {
        unsigned short psk_len;
        char *psk;
        unsigned short psk_identity_len;
        char *psk_identity;
    } liot_ssl_psk_info_s;
    
  2. Structure Description

Member

Description

psk_len

PSK length

psk

Pre-shared key

psk_identity_len

PSK identity length

psk_identity

PSK identity

3.10 Liot_sslContext_t

SSL context configuration structure.

  1. Structure Declaration

    typedef struct {
        uint8_t ssl_version;
        uint8_t auth_type;
        int32_t ciphersuite[2];
        uint8_t *alpn_list[LIOT_SSL_ALPN_NAME_LEN];
        uint8_t sni_support;
        uint8_t cert_buffer_type;
        uint32_t r_timeout;
        uint32_t s_timeout;
        uint8_t transport_protocol;
        uint8_t *ca_cert;
        uint32_t ca_cert_length;
        uint8_t ca_cert_index;
        uint8_t *user_cert;
        uint32_t user_cert_length;
        uint8_t *user_key;
        uint32_t user_key_length;
        uint8_t *user_key_pwd;
        uint8_t *psk;
        uint32_t psk_length;
        uint8_t *psk_identity;
        uint32_t psk_identity_length;
        uint32_t ignore_cert_flag;
        uint32_t ignore_certitem;
        uint8_t is_ignore_multicertchain_verify;
        uint8_t cache_enable;
    } Liot_sslContext_t;
    
  2. Structure Description

Member

Description

ssl_version

SSL version

auth_type

Authentication type (0=no authentication, 1=one-way, 2=two-way)

ciphersuite

Cipher suite

alpn_list

ALPN list

sni_support

SNI support

r_timeout

Receive timeout

s_timeout

Send timeout

transport_protocol

Transport protocol

ca_cert

CA certificate

user_cert

User certificate (required for two-way authentication)

user_key

User private key (required for two-way authentication)

psk

PSK key

psk_identity

PSK identity

cache_enable

Cache enable

3.11 Liot_sslClientInfo_t

SSL client information structure.

  1. Structure Declaration

    typedef struct {
        uint8_t sslClientId;
        uint8_t cid;
        uint8_t socket_type;
        uint8_t *host;
        uint16_t port;
        uint16_t local_port;
        uint8_t KeepaliveEn;
        uint8_t keepidle;
        uint8_t keepinterval;
        uint8_t keepcount;
        Liot_sslContext_t *ssl_context;
        liot_sslClient_recvCb_t sslClient_cb;
    } Liot_sslClientInfo_t;
    
  2. Structure Description

Member

Description

sslClientId

SSL client ID

host

Server hostname

port

Server port

local_port

Local port

KeepaliveEn

Heartbeat enable

keepidle

Heartbeat idle time

keepinterval

Heartbeat interval

keepcount

Heartbeat count

ssl_context

SSL configuration

sslClient_cb

Reception callback function

4 API Function Details

4.1 Liot_SSLSetCfg

This function is used to set SSL configuration information.

  1. Declaration

    int32_t Liot_SSLSetCfg(void *ssl_cfg);
    
  2. Parameters

  • sslClientID: [In] SSL configuration pointer, pointing to Liot_sslClientInfo_t structure.

  1. Return Value

  • 0: Configuration successful.

  • -1: Configuration failed.

4.2 Liot_SSLSocketOpen

This function is used to open SSL connection.

  1. Declaration

    int32_t Liot_SSLSocketOpen(int32_t sslClientID);
    
  2. Parameters

  • sslClientID: [In] SSL client ID

  1. Return Value

Execution result code, see liot_ssl_error_code_e for reference.

4.3 Liot_SSLSocketSend

This function is used to send SSL data.

  1. Declaration

    int32_t Liot_SSLSocketSend(int32_t sslClientID, uint8_t *data, uint16_t len);
    
  2. Parameters

  • sslClientID: [In] SSL client ID

  • data: [In] SSL data pointer to be sent

  • len: [In] Data length

  1. Return Value

Execution result code, see liot_ssl_error_code_e for reference.

4.4 Liot_SSLSocketGetStatus

This function is used to get SSL connection status.

  1. Declaration

    int32_t Liot_SSLSocketGetStatus(int32_t sslClientID);
    
  2. Parameters

  • sslClientID: [In] SSL client ID

  1. Return Value

Returns SSL client status, see liot_ssl_error_code_e for reference.

4.5 Liot_SSLSocketClose

This function is used to close SSL connection.

  1. Declaration

int32_t Liot_SSLSocketClose(int32_t sslClientID);
  1. Parameters

  • sslClientID: [In] SSL client ID

  1. Return Value

Execution result code, see liot_ssl_error_code_e for reference.

5 Code Example

5.1 Sample Code

Sample code reference: examples\demo\src\demo_ssl2.c file.

  • SSL initialization with certificate configuration

  • SSL connection establishment

  • Data sending and receiving

  • Connection status monitoring

  • Resource cleanup

5.2 No Authentication Mode Configuration Example

#include "liot_ssl2.h"

#define DEMO_SSL_CLIENT_ID 0

Liot_sslClientInfo_t ssl_client_info;

void ssl_recv_callback(uint8_t clientId, void *data, uint32_t dataLen, void *arg)
{
    printf("Received %d bytes\n", dataLen);
}

void ssl_none_auth_init(void)
{
    memset(&ssl_client_info, 0, sizeof(ssl_client_info));

    ssl_client_info.sslClientId = DEMO_SSL_CLIENT_ID;
    ssl_client_info.socket_type = 1;
    ssl_client_info.host = (uint8_t *)"192.168.1.100";
    ssl_client_info.port = 8883;

5.1 示例代码

示例代码参考 examples\demo\src\demo_ssl2.c 文件。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lierda_app_main.h"
#include "liot_datacall.h"
#include "liot_os.h"
#include "liot_type.h"
#include "liot_fs_api.h"
#include "liot_nw.h"
#include "liot_sockets.h"
#include "liot_ssl2.h"

#define LIOT_SSL_LOG liot_trace
#if 1
#define LIOT_TEST_HOST_ADDR "cmp-tcp-monitor.xiot.senthink.com"
#define LIOT_TEST_HOST_PORT 41003

#define LIOT_TEST_SEND_DATA \
    "Hello Lierda\0"
#else
#define LIOT_TEST_HOST_ADDR "220.180.239.212"
#define LIOT_TEST_HOST_PORT 8586
#define LIOT_TEST_SEND_DATA "1234567890123456789012345678901234567890"
#endif

#define LIOT_ROOT_CRT_PATH   "UFS:root.crt"
#define LIOT_CLIENT_KEY_PATH "UFS:client.key"
#define LIOT_CLIENT_CRT_PATH "UFS:client.crt"

#define liot_root_crt \
    "-----BEGIN CERTIFICATE-----\n\
MIIEQjCCAyqgAwIBAgIIUqzcXCgwtxUwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE\n\
BhMCQ04xDzANBgNVBBETBjMxMTEyMTEZMBcGA1UEChMQTGllcmRhIEdyb3VwIElu\n\
YzEfMB0GA1UEAxMWTGllcmRhIFJTQSBDQSBUTFMgMjAyMzEgMB4GCSqGSIb3DQEJ\n\
AQwRZGV2b3BzQGxpZXJkYS5jb20wIBcNMjMwMzIzMDM1NzEwWhgPMjEyMzAzMjMw\n\
MzU3MTBaMHwxCzAJBgNVBAYTAkNOMQ8wDQYDVQQREwYzMTExMjExGTAXBgNVBAoT\n\
EExpZXJkYSBHcm91cCBJbmMxHzAdBgNVBAMTFkxpZXJkYSBSU0EgQ0EgVExTIDIw\n\
MjMxIDAeBgkqhkiG9w0BCQEMEWRldm9wc0BsaWVyZGEuY29tMIIBIjANBgkqhkiG\n\
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7Km6RoA8W+ABfVi4Su5CBXXXX03W4tRft2CU\n\
PL2WxSXmt+NLa6qVpXwdXhnOFka7W3Yky7sJsEa+4L3ZAdvLAaV+T/YWjWUs4kBS\n\
g4m1qvNbVBf+QRMnN7T4KDykAmVt9slk5hrl9wmaza2uC0mVybCus1hWFl4O6bEK\n\
NVfVj67RMYJ0/V8rGo1RaM9gY9ocfsvCWnfmoBCBWVJqgKHt3zw3eVdgiK1c3/ZD\n\
Uksl+YEnHc0xZpUp++K/xn5BdgWJPY/5Xe/YGOMGXIJqINoW9br2ZKXIGsWmByus\n\
LltumLIThO6fnP2cyJjhJM+UnTUGJ/38tk7zjp2NnFQFFEjhlQIDAQABo4HFMIHC\n\
MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEw\n\
DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU3amZSimWqD7Ws6eB19/JaiRbJMQw\n\
KwYIKwYBBQUHAQEEHzAdMBsGCCsGAQUFBzAChg94aW90LmxpZXJkYS5jb20wNAYD\n\
VR0RBC0wK4IWTGllcmRhIFJTQSBDQSBUTFMgMjAyM4ERZGV2b3BzQGxpZXJkYS5j\n\
b20wDQYJKoZIhvcNAQELBQADggEBADGONA83hjydoGGSfbAF9KLDYUXGqLuAk3w+\n\
hZSt22x/nrq24TTGp/nVdhPs1CWNKzm/E0J+PpR/igWE/wYoLPCBZp1Yw5Lr+Gsu\n\
1dREldvcrnwCD6lGBk+liL3e/JTa7XTpoN+gYbpr9LVzPPlSwbFv8HXUQpoKCCXl\n\
A3L2TgoXCWKmW/TlPveT4eeSBPKif03hA6LsIFC5ebKztIe8cLRQiC+nuVg+vgOn\n\
L2o7gudAW9oeLHHwaZaJ862g0QlzhP+xKbK5vF2hRVpuE3VOWXFmUiWOhPw9BBgb\n\
6qrLAy26wFxdlnE8Q5yJcNGdJHk2d7TnnCohghLOjdhfE5lUWGc=\n\
-----END CERTIFICATE-----\n\
-----BEGIN CERTIFICATE-----\n\
MIIElTCCA32gAwIBAgIIEv+6yZm7eTMwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE\n\
BhMCQ04xDzANBgNVBBETBjMxMTEyMTEZMBcGA1UEChMQTGllcmRhIEdyb3VwIElu\n\
YzEfMB0GA1UEAxMWTGllcmRhIFJTQSBDQSBUTFMgMjAyMzEgMB4GCSqGSIb3DQEJ\n\
AQwRZGV2b3BzQGxpZXJkYS5jb20wIBcNMjMwMzIzMDQ0MDU4WhgPMjEyMzAyMjMw\n\
NDQwNThaMIGCMQswCQYDVQQGEwJDTjEPMA0GA1UEERMGMzExMTIxMQ8wDQYDVQQK\n\
EwZMaWVyZGExETAPBgNVBAsTCFNlbnRoaW5rMRwwGgYDVQQDDBMqLnhpb3Quc2Vu\n\
dGhpbmsuY29tMSAwHgYJKoZIhvcNAQkBDBFkZXZvcHNAbGllcmRhLmNvbTCCASIw\n\
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOZp21VtvMnztvuhLiBUGD8rZXcP\n\
5Co3WXMM1All0MvRxrWPMxMUUlvhfXCbq8KEizjpirnjZEMroPdNj7yDS7Ua4wQ9\n\
NfCMKy/xpZFRRfCAFEZmMQnbA3RDGZbIMtc2sWv9DbzEKNmxFbSd52aEFT08qpjC\n\
tToQpFzDsmdNGGW/kT/3hjBMPsB/MusREh93V8QAc+91bsMPhadQbhpZ+KfDXkO2\n\
yqosbjttywmKh53nCTrjWz+ti8rXEGcLOhUEIinMeEGFFSql9X5AUGEE3hAVw4T4\n\
N9JD5xGSW5xoiVI81zwjOF1I0ytfcnuxyoODQ7pMfdMnGh10wGwHvMsDLNsCAwEA\n\
AaOCARAwggEMMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYI\n\
KwYBBQUHAwIwHQYDVR0OBBYEFIdFQk2DWZPhKuxN75FM9ru8TsvQMB8GA1UdIwQY\n\
MBaAFN2pmUoplqg+1rOngdffyWokWyTEMCsGCCsGAQUFBwEBBB8wHTAbBggrBgEF\n\
BQcwAoYPeGlvdC5saWVyZGEuY29tMG4GA1UdEQRnMGWCEyoueGlvdC5zZW50aGlu\n\
ay5jb22CESoueGlvdC5saWVyZGEuY29tghMqLnRlc3Quc2VudGhpbmsuY29tghMq\n\
LnN0YWcuc2VudGhpbmsuY29tgRFkZXZvcHNAbGllcmRhLmNvbTANBgkqhkiG9w0B\n\
AQsFAAOCAQEABF/qYc9/+9YhabnGLpUGSYtbht1fXHM9LOc1yqaoJbkP6tTxdrex\n\
kewzR5N4bLV+sl8QirsKZjxBmmnyjjBFJE9wnmeGiEr3pRO3MjCxjbQC/hLNjGNj\n\
fvPrxmAEyOcrp6drYGPum49p4/ecXRlM5vNKYXZSEsm2hxU2Mp1xcPVZSU4ttzoQ\n\
73BbdO1SYgPqYeQjw4sawqTW60aurDZNzW5yMnkh56320kjcy1DwI6xYW4q7HPnI\n\
8lmgl1ARntMlAQPCi77aLid91sxPFttfnH+NAe4UTjL6B7xCD2RqpiJRb3DyFaUl\n\
L3ZMQQC9ylYlcmYE6RUNKgVZ7WaJLPzl4g==\n\
-----END CERTIFICATE-----"

#define liot_client_crt \
"-----BEGIN CERTIFICATE-----\n\
MIIEizCCA3OgAwIBAgIIEaRUDbqjWgEwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE\n\
BhMCQ04xDzANBgNVBBETBjMxMTEyMTEZMBcGA1UEChMQTGllcmRhIEdyb3VwIElu\n\
YzEfMB0GA1UEAxMWTGllcmRhIFJTQSBDQSBUTFMgMjAyMzEgMB4GCSqGSIb3DQEJ\n\
AQwRZGV2b3BzQGxpZXJkYS5jb20wIBcNMjMwMzIzMDQ0MjU1WhgPMjEyMzAyMjMw\n\
NDQyNTVaMIGCMQswCQYDVQQGEwJDTjEPMA0GA1UEERMGMzExMTIxMQ8wDQYDVQQK\n\
EwZMaWVyZGExETAPBgNVBAsTCFNlbnRoaW5rMRwwGgYDVQQDDBMqLnhpb3Quc2Vu\n\
dGhpbmsuY29tMSAwHgYJKoZIhvcNAQkBDBFkZXZvcHNAbGllcmRhLmNvbTCCASIw\n\
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPIGB6UVDXHwiVEfeUTo+zKMzz4c\n\
MDPfKTpRciDLmmg27blh5+jVBC7xMNaM5ran6GjF7JuYO9EipYPCMv5WnfyPzAU3\n\
HFDbynaGhPLE/ZTs71PU8fPgK7M8WxesPCDJ5Q9NOkIGq+PtI2pHMRMaDUOjMEGE\n\
ftm7VGSMwfE+dQTeOBwDNoQ6ENTVg0a5yfy+SXgKXW3QI9flW//Wagw6WLjIVeYQ\n\
ffXc8IuJHmlYtaYrFeZaL1tRXoscnlFRUMdB60XIq5JOyxqFtPEYgv8LwYDgozpW\n\
2jJTpH+Tp/+Sxc2rQHO56XCx1Z51W3Ia7Q30Mu1WJHYsLphdWeeMlkXT+eECAwEA\n\
AaOCAQYwggECMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAjAd\n\
BgNVHQ4EFgQUBqMN+wB9BUK01w1HHL+ZonufeOowHwYDVR0jBBgwFoAU3amZSimW\n\
qD7Ws6eB19/JaiRbJMQwKwYIKwYBBQUHAQEEHzAdMBsGCCsGAQUFBzAChg94aW90\n\
LmxpZXJkYS5jb20wbgYDVR0RBGcwZYITKi54aW90LnNlbnRoaW5rLmNvbYIRKi54\n\
aW90LmxpZXJkYS5jb22CEyoudGVzdC5zZW50aGluay5jb22CEyouc3RhZy5zZW50\n\
aGluay5jb22BEWRldm9wc0BsaWVyZGEuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQDP\n\
tC24Uw1ud4wO2C3qWHZluLrNtsIVcD5tLcYMlX2oa3uuNaI9fsvFEPikf8LI7LYU\n\
NKQVBbeKpnIfBCtrmarj6jOQumSZXKC02f3w52Z1BFGvMj8GNj8ts7EHMqe8yohJ\n\
3lsoReAb0VDPerExFX/uhkmxd4OEQatpvjLR8nKrjlvq2sNQ+SrQALvM3/iVQ0Vo\n\
ld3qaIy/rpg+SRJeSmoh3tPl18H5CEqQYImWs5G9bKS7eFCj4Rr/a+4NeRwaV/0y\n\
hwt7V7AaWKdpwEpRoV3ecxIdyIod313T18ndIDLIWlcVTllLA3Y60f6G8J4Lp9Gs\n\
Utn0AVYamn42u8y+Itjh\n\
-----END CERTIFICATE-----"

#define liot_client_key \
"-----BEGIN RSA PRIVATE KEY-----\n\
MIIEpAIBAAKCAQEA8gYHpRUNcfCJUR95ROj7MozPPhwwM98pOlFyIMuaaDbtuWHn\n\
6NUELvEw1ozmtqfoaMXsm5g70SKlg8Iy/lad/I/MBTccUNvKdoaE8sT9lOzvU9Tx\n\
8+ArszxbF6w8IMnlD006Qgar4+0jakcxExoNQ6MwQYR+2btUZIzB8T51BN44HAM2\n\
hDoQ1NWDRrnJ/L5JeApdbdAj1+Vb/9ZqDDpYuMhV5hB99dzwi4keaVi1pisV5lov\n\
W1FeixyeUVFQx0HrRcirkk7LGoW08RiC/wvBgOCjOlbaMlOkf5On/5LFzatAc7np\n\
cLHVnnVbchrtDfQy7VYkdiwumF1Z54yWRdP54QIDAQABAoIBAQCHibTyUG3tJ0Xf\n\
dn7VhpxW3OCa6fJculc+X6pIj31za3+KWDgl/lWPbGdrYBE8rZ/MPTuaj5DAOGT0\n\
+ubP5PYpIOai7RAggFZMNl1yD7vrkR0el5zAdQREJkLlaQFrY2WyQg+kNlRBGubA\n\
eAoVpntTK6q0plzb1rsWbHWYgt/JzwpU078m2BnF0PG6sqZWRPjSqpMBHkkKPn52\n\
nThKlTL2/XfpahxWnN+j3Gq7eSI3t7XXopHBOxSPbPa0Hx+jLLPfxnRihzhIb9IZ\n\
r7CCBhGFrab+/VbOJc+FUstTGEd/2tO2+AbqZnonUTPgkPMMPrWGqCKlsIoUxwqV\n\
lS1B+/FZAoGBAPmZAp7cFMp3DWqd8NiR4EutrH2tfOoK3zAt1S7ErVmiS+UKBaZ+\n\
WcWnUzn27DZ3uslnB2aIQ8ZFaunM6NkdG7jkpNQpw2myFTK7Vd5VsqUHjPNJwPhT\n\
xjAdxvBTED3c12U3xlxmfgob9Mv3EwmseH+AZPGcojw7Vg8VbeZDsjw7AoGBAPg7\n\
SKjFA4ZpiWEiELWl/i5IrQsuLINM/hM7fAPNCzFrN2/ZVfqoe6kbkII5c8DIgU6i\n\
5LxTkgaEYC3ne8pGjnB0WN1xI/nbqtg3ZNrN4S9ArlEkzHiI9r0xsnyRUt99wAlB\n\
3jjOPBPXzFRgDy/VXoE1k4OUrCPnwV1JVwM2j+yTAoGAGu0UyUp4u7bILb5IIzTp\n\
e4CK4Sv8E8uEdFAddWQmR0so4NaJ8YIj8Ryx78jhhqa38c45kCgXF6aZeAtw+ysW\n\
uIWB+pleyWI6wzROeSPJl+AOpphIRwHSmZI8yeRMFkBixDqWHZW49yI48GABH8QJ\n\
Y8fYG/CH1/OWvx3Ss0qOSc0CgYB5UohVrEznwecaKUsfbOzJdE3XHA83cUbw4W7g\n\
cLPayHtE2GV0aCpgYY+Ehk3z2EuSwnynKvVA6CwV44CWQVvWzJauTGD3+owKtzA8\n\
3MkFjkhkcmbZNp/ZolOJHIHzp4NXQvE4tFuamytLxdNGXrOc1TGu6tgjiF7ymCjF\n\
8kHvrwKBgQCpbYvfsn9T2hE1jyK5Qh7P8XqSprQ7cZ05VYhDbMZ8iOn2LWXJLf1j\n\
DQEUjO44VzU4IRb2f0hiw7SYMjPbNh+rKkjUxCdLa5RvJ9CWT9xddjQZHjfv1Px2\n\
I2H+OQwOo8QOUXH6z8gUAw8MsNYiDlvtRw/6GFAkc4D5A25UzVBmcA==\n\
-----END RSA PRIVATE KEY-----"

#define DEMO_SSL_CLIENT_ID 1
#define DEMO_SEND_INTERVAL 60000 // 发送间隔,单位:毫秒
#define LIOT_SSL_LOG liot_trace

Liot_sslClientInfo_t ssl_client_info;

/
 * ssl recv callback
 * @param[in] clientId ssl client id
 * @param[in] data received data
 * @param[in] arg user argument
 * @return none
 */
void ssl_recv_callback(uint8_t clientId, void *data, uint32_t dataLen, void *arg)
{
    LIOT_SSL_LOG("Received data: %d.*%s", dataLen, (char *)data);
}

/
 * ssl client init
 * @return none
 */
void liot_ssl_init(void)
{
    memset(&ssl_client_info, 0, sizeof(ssl_client_info));

 
    ssl_client_info.sslClientId = DEMO_SSL_CLIENT_ID;
    ssl_client_info.socket_type = 1; // TCP
    ssl_client_info.host = (uint8_t *)LIOT_TEST_HOST_ADDR;
    ssl_client_info.port = LIOT_TEST_HOST_PORT;
    if(ssl_client_info.ssl_context == NULL)
    {
        ssl_client_info.ssl_context = liot_rtos_malloc(sizeof(Liot_sslContext_t));
        if (ssl_client_info.ssl_context == NULL)
        {
            LIOT_SSL_LOG("Failed to allocate memory for SSL context");
            return;
        }
    }
    memset(ssl_client_info.ssl_context, 0, sizeof(Liot_sslContext_t));

    ssl_client_info.ssl_context->auth_type = LIOT_SSL_VERIFY_CLIENT_SERVER;  // 
    ssl_client_info.ssl_context->ca_cert = (uint8_t *)liot_root_crt;
    ssl_client_info.ssl_context->ca_cert_length = strlen(liot_root_crt) + 1;
    ssl_client_info.ssl_context->user_cert = (uint8_t *)liot_client_crt;
    ssl_client_info.ssl_context->user_cert_length = strlen(liot_client_crt) + 1;
    ssl_client_info.ssl_context->user_key = (uint8_t *)liot_client_key;
    ssl_client_info.ssl_context->user_key_length = strlen(liot_client_key) + 1;
    ssl_client_info.ssl_context->ssl_version = LIOT_SSL_VERSION_3; // TLS 1.2
    ssl_client_info.ssl_context->r_timeout = 10; 
    ssl_client_info.ssl_context->sni_support = 1;
    ssl_client_info.ssl_context->ciphersuite[0] =0XFFFF ;


    ssl_client_info.KeepaliveEn = 1; // enable Keepalive
    ssl_client_info.keepidle = 30;   
    ssl_client_info.keepinterval = 10; 
    ssl_client_info.keepcount = 5;   

    ssl_client_info.sslClient_cb = ssl_recv_callback;

    int ret = Liot_SSLSetCfg(&ssl_client_info);
    if (ret != LIOT_SSL_SUCCESS)
    {
        LIOT_SSL_LOG("Liot_SSLSetCfg failed, ret: %d", ret);
        liot_rtos_free(ssl_client_info.ssl_context);
        return;
    }
}

/
 *  ssl test
 * @param[in] profile_idx profile index
 * @return none
 */
static int liot_ssl_test(int profile_idx)
{
    liot_data_call_info_t info;
    int ret = LIOT_SSL_SUCCESS;
    int i = 0;
    int ssl_status = 0; 
    // Get data call information for the specified profile
    liot_get_data_call_info(0, profile_idx, &info);

start:

    liot_ssl_init();
    
    ret = Liot_SSLSocketOpen(DEMO_SSL_CLIENT_ID);
    if (ret != LIOT_SSL_SUCCESS)
    {
        LIOT_SSL_LOG("Liot_SSLSocketOpen failed, ret: %d", ret);
        liot_rtos_free(ssl_client_info.ssl_context);
        return LIOT_SSL_ERROR_UNKOWN;
    }

    while (1)
    {
        ssl_status = Liot_SSLSocketGetStatus(DEMO_SSL_CLIENT_ID);
        LIOT_SSL_LOG("Current SSL status: %d", ssl_status);
        const char *send_data = LIOT_TEST_SEND_DATA;
        ret = Liot_SSLSocketSend(DEMO_SSL_CLIENT_ID, (uint8_t *)send_data, strlen(send_data));
        if (ret < 0)
        {
            LIOT_SSL_LOG("Liot_SSLSocketSend failed, ret: %d", ret);
            ret = LIOT_SSL_ERROR_SEND_FAILURE;
            break;
        }
        LIOT_SSL_LOG("Data sent: %s", send_data);
        i++;
        if (i >= 3)
        {
            break;
        }
        ssl_status = Liot_SSLSocketGetStatus(DEMO_SSL_CLIENT_ID);
        LIOT_SSL_LOG("Current SSL status: %d", ssl_status);
        liot_rtos_task_sleep_ms(DEMO_SEND_INTERVAL);
    }
    if(ssl_status == LIOT_SSL_CLIENT_STATUS_CLOSED)
    {
        LIOT_SSL_LOG("SSL is closed, start reconnecting!! : %d", ssl_status);
        goto start;
    }
    Liot_SSLSocketClose(DEMO_SSL_CLIENT_ID);
    liot_rtos_free(ssl_client_info.ssl_context);
    LIOT_SSL_LOG("SSL demo task finished");
    return ret;
}

/
 * @brief Main SSL application thread.
 * This thread handles the complete SSL demo workflow including:
 * 1. Establishing data connection
 * 2. Initializing certificates
 * 3. Performing SSL/TLS operations
 * 4. Cleaning up resources
 * 
 * @param arg Thread arguments (unused)
 */
void liot_ssl2_demo_thread(void *arg)
{
    int ret         = 0;
    int profile_idx = 1;
    liot_data_call_info_t info;
   // char ip4_addr_str[16] = {0};
    uint8_t nSim          = 0;

    LIOT_SSL_LOG("========== ssl demo start ==========");

    LIOT_SSL_LOG("===start data call begin====");
    liot_start_data_call(nSim, profile_idx, LIOT_DATA_TYPE_IP, "APNTEST", "", "", LIOT_DATA_AUTH_TYPE_NONE);
    LIOT_SSL_LOG("===start data call end====");

    ret = liot_get_data_call_info(nSim, profile_idx, &info);
    if (ret != 0)
    {
        liot_stop_data_call(nSim, profile_idx);
        liot_trace("liot_get_data_call_info ret: %d", ret);
        goto exit;
    }
    liot_trace("info->cid: %d", info.cid);
    liot_trace("info->ip_version: %d", info.ip_version);

    ret = liot_ssl_test(profile_idx);
    liot_trace("liot_ssl_test ret: %d", ret);
exit:
    liot_rtos_task_delete(NULL);
    return;
}

5.2 无认证模式配置示例

#include "liot_ssl2.h"

#define DEMO_SSL_CLIENT_ID 0

Liot_sslClientInfo_t ssl_client_info;

void ssl_recv_callback(uint8_t clientId, void *data, uint32_t dataLen, void *arg)
{
    printf("Received %d bytes\n", dataLen);
}

void ssl_none_auth_init(void)
{
    memset(&ssl_client_info, 0, sizeof(ssl_client_info));

    ssl_client_info.sslClientId = DEMO_SSL_CLIENT_ID;
    ssl_client_info.socket_type = 1;
    ssl_client_info.host = (uint8_t *)"192.168.1.100";
    ssl_client_info.port = 8883;

    ssl_client_info.ssl_context = liot_rtos_malloc(sizeof(Liot_sslContext_t));
    memset(ssl_client_info.ssl_context, 0, sizeof(Liot_sslContext_t));

    // ========== 无认证配置 ==========
    ssl_client_info.ssl_context->auth_type = LIOT_SSL_VERIFY_NONE;
    ssl_client_info.ssl_context->ssl_version = LIOT_SSL_VERSION_3;
    ssl_client_info.ssl_context->sni_support = 1;
    ssl_client_info.ssl_context->ciphersuite[0] = 0xFFFF;
    ssl_client_info.ssl_context->r_timeout = 10;

    ssl_client_info.sslClient_cb = ssl_recv_callback;

    Liot_SSLSetCfg(&ssl_client_info);
}


5.3 单向认证模式配置

#include "liot_ssl2.h"

#define DEMO_SSL_CLIENT_ID 0

// CA 根证书 (PEM 格式字符串)
#define liot_root_crt \
    "-----BEGIN CERTIFICATE-----\n" \
    "MIIEQjCCAyqgAwIBAgIIUqzcXCgwtxUwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE\n" \
    "BhMCQ04xDzANBgNVBBETBjMxMTEyMTEZMBcGA1UEChMQTGllcmRhIEdyb3VwIElu\n" \
    "...(证书内容)...\n" \
    "-----END CERTIFICATE-----"

Liot_sslClientInfo_t ssl_client_info;

void ssl_recv_callback(uint8_t clientId, void *data, uint32_t dataLen, void *arg)
{
    printf("Received %d bytes\n", dataLen);
}

void ssl_server_auth_init(void)
{
    memset(&ssl_client_info, 0, sizeof(ssl_client_info));

    ssl_client_info.sslClientId = DEMO_SSL_CLIENT_ID;
    ssl_client_info.socket_type = 1;
    ssl_client_info.host = (uint8_t *)"mqtt.example.com";  // 服务器域名 (用于 SNI)
    ssl_client_info.port = 8883;

    ssl_client_info.ssl_context = liot_rtos_malloc(sizeof(Liot_sslContext_t));
    memset(ssl_client_info.ssl_context, 0, sizeof(Liot_sslContext_t));

    // ========== 单向认证配置 ==========
    ssl_client_info.ssl_context->auth_type = LIOT_SSL_VERIFY_SERVER;
    ssl_client_info.ssl_context->ssl_version = LIOT_SSL_VERSION_3;
    ssl_client_info.ssl_context->sni_support = 1;
    ssl_client_info.ssl_context->ciphersuite[0] = 0xFFFF;
    ssl_client_info.ssl_context->r_timeout = 30;

    // CA 证书配置
    ssl_client_info.ssl_context->ca_cert = (uint8_t *)liot_root_crt;
    ssl_client_info.ssl_context->ca_cert_length = strlen(liot_root_crt) + 1;

    ssl_client_info.sslClient_cb = ssl_recv_callback;

    Liot_SSLSetCfg(&ssl_client_info);
}


5.4 双向认证模式配置

#include "liot_ssl2.h"

#define DEMO_SSL_CLIENT_ID 0

// CA 根证书
#define liot_root_crt \
    "-----BEGIN CERTIFICATE-----\n" \
    "MIIEQjCCAyqgAwIBAgIIUqzcXCgwtxUwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE\n" \
    "...(CA 证书内容)...\n" \
    "-----END CERTIFICATE-----"

// 客户端证书
#define liot_client_crt \
    "-----BEGIN CERTIFICATE-----\n" \
    "MIIEizCCA3OgAwIBAgIIEaRUDbqjWgEwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE\n" \
    "...(客户端证书内容)...\n" \
    "-----END CERTIFICATE-----"

// 客户端私钥
#define liot_client_key \
    "-----BEGIN RSA PRIVATE KEY-----\n" \
    "MIIEpAIBAAKCAQEA8gYHpRUNcfCJUR95ROj7MozPPhwwM98pOlFyIMuaaDbtuWHn\n" \
    "...(私钥内容)...\n" \
    "-----END RSA PRIVATE KEY-----"

Liot_sslClientInfo_t ssl_client_info;

void ssl_recv_callback(uint8_t clientId, void *data, uint32_t dataLen, void *arg)
{
    printf("Received %d bytes\n", dataLen);
}

void ssl_mutual_auth_init(void)
{
    memset(&ssl_client_info, 0, sizeof(ssl_client_info));

    ssl_client_info.sslClientId = DEMO_SSL_CLIENT_ID;
    ssl_client_info.socket_type = 1;
    ssl_client_info.host = (uint8_t *)"secure.example.com";
    ssl_client_info.port = 8883;

    ssl_client_info.ssl_context = liot_rtos_malloc(sizeof(Liot_sslContext_t));
    memset(ssl_client_info.ssl_context, 0, sizeof(Liot_sslContext_t));

    // ========== 双向认证配置 ==========
    ssl_client_info.ssl_context->auth_type = LIOT_SSL_VERIFY_CLIENT_SERVER;
    ssl_client_info.ssl_context->ssl_version = LIOT_SSL_VERSION_3;
    ssl_client_info.ssl_context->sni_support = 1;
    ssl_client_info.ssl_context->ciphersuite[0] = 0xFFFF;
    ssl_client_info.ssl_context->r_timeout = 30;

    // CA 证书配置
    ssl_client_info.ssl_context->ca_cert = (uint8_t *)liot_root_crt;
    ssl_client_info.ssl_context->ca_cert_length = strlen(liot_root_crt) + 1;

    // 客户端证书配置
    ssl_client_info.ssl_context->user_cert = (uint8_t *)liot_client_crt;
    ssl_client_info.ssl_context->user_cert_length = strlen(liot_client_crt) + 1;

    // 客户端私钥配置
    ssl_client_info.ssl_context->user_key = (uint8_t *)liot_client_key;
    ssl_client_info.ssl_context->user_key_length = strlen(liot_client_key) + 1;

    ssl_client_info.sslClient_cb = ssl_recv_callback;

    Liot_SSLSetCfg(&ssl_client_info);
}