1# TLS Feature Introduction 2 3## Protocol Description 4 5openHiTLS offers functions such as creating, configuring, and managing security protocol links based on transport-layer security protocol standards, with the main functional interfaces available in the protocol module. openHiTLS supports various protocol versions and features, including basic protocol handshake, key update, application-layer protocol negotiation, and server name indication. 6 7Currently, openHiTLS supports the following protocol versions: 8 9- TLS1.2: used for secure renegotiation, application-layer protocol negotiation, server name indication, and session resumption 10- TLS1.3: used for key update, application-layer protocol negotiation, server name indication, and session resumption 11- DTLS1.2: used for secure renegotiation, application-layer protocol negotiation, server name indication, and session resumption 12- TLCP: used for secure renegotiation and session resumption 13 14### TLS/DTLS1.2 Specifications 15 16| Configuration Item| Specifications| 17| :---- | :---- | 18| TLS version| TLS12 (0x0303u)<br>DTLS12 (0xfefdu)| 19| Algorithm suite| TLS_RSA_WITH_AES_128_CBC_SHA (0x002F)<br>TLS_DHE_DSS_WITH_AES_128_CBC_SHA (0x0032)<br>TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)<br>TLS_DH_anon_WITH_AES_128_CBC_SHA (0x0034)<br>TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)<br>TLS_DHE_DSS_WITH_AES_256_CBC_SHA (0x0038)<br>TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039)<br>TLS_DH_anon_WITH_AES_256_CBC_SHA (0x003A)<br>TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003C)<br>TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003D)<br>TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 (0x0040)<br>TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x0067)<br>TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 (0x006A)<br>TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x006B)<br>TLS_DH_anon_WITH_AES_128_CBC_SHA256 (0x006C)<br>TLS_DH_anon_WITH_AES_256_CBC_SHA256 (0x006D)<br>TLS_PSK_WITH_AES_128_CBC_SHA (0x008C)<br>TLS_PSK_WITH_AES_256_CBC_SHA (0x008D)<br>TLS_DHE_PSK_WITH_AES_128_CBC_SHA (0x0090)<br>TLS_DHE_PSK_WITH_AES_256_CBC_SHA (0x0091)<br>TLS_RSA_PSK_WITH_AES_128_CBC_SHA (0x0094)<br>TLS_RSA_PSK_WITH_AES_256_CBC_SHA (0x0095)<br>TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009C)<br>TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009D)<br>TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009E)<br>TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x009F)<br>TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 (0x00A2)<br>TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 (0x00A3)<br>TLS_DH_anon_WITH_AES_128_GCM_SHA256 (0x00A6)<br>TLS_DH_anon_WITH_AES_256_GCM_SHA384 (0x00A7)<br>TLS_PSK_WITH_AES_128_GCM_SHA256 (0x00A8)<br>TLS_PSK_WITH_AES_256_GCM_SHA384 (0x00A9)<br>TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 (0x00AA)<br>TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 (0x00AB)<br>TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 (0x00AC)<br>TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 (0x00AD)<br>TLS_PSK_WITH_AES_128_CBC_SHA256 (0x00AE)<br>TLS_PSK_WITH_AES_256_CBC_SHA384 (0x00AF)<br>TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 (0x00B2)<br>TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 (0x00B3)<br>TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 (0x00B6)<br>TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 (0x00B7)<br>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xC009)<br>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xC00A)<br>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xC013)<br>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xC014)<br>TLS_ECDH_anon_WITH_AES_128_CBC_SHA (0xC018)<br>TLS_ECDH_anon_WITH_AES_256_CBC_SHA (0xC019)<br>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xC023)<br>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xC024)<br>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xC027)<br>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xC028)<br>TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xC02B)<br>TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xC02C)<br>TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xC02F)<br>TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xC030)<br>TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA (0xC035)<br>TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA (0xC036)<br>TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 (0xC037)<br>TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 (0xC038)<br>TLS_RSA_WITH_AES_128_CCM (0xC09C)<br>TLS_RSA_WITH_AES_256_CCM (0xC09D)<br>TLS_DHE_RSA_WITH_AES_128_CCM (0xC09E)<br>TLS_DHE_RSA_WITH_AES_256_CCM (0xC09F)<br>TLS_RSA_WITH_AES_128_CCM_8 (0xC0A0)<br>TLS_RSA_WITH_AES_256_CCM_8 (0xC0A1)<br>TLS_PSK_WITH_AES_256_CCM (0xC0A5)<br>TLS_DHE_PSK_WITH_AES_128_CCM (0xC0A6)<br>TLS_DHE_PSK_WITH_AES_256_CCM (0xC0A7)<br>TLS_ECDHE_ECDSA_WITH_AES_128_CCM (0xC0AC)<br>TLS_ECDHE_ECDSA_WITH_AES_256_CCM (0xC0AD)<br>TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xCCA8)<br>TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xCCA9)<br>TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xCCAA)<br>TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 (0xCCAB)<br>TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 (0xCCAC)<br>TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 (0xCCAD)<br>TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 (0xCCAE)<br>TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 (0xD001)<br>TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384 (0xD002)<br>TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256 (0xD005)| 20| EC dotted format| uncompressed (0)| 21| Elliptic curve| secp256r1 (23)<br>secp384r1 (24)<br>secp521r1 (25)<br>brainpoolP256r1 (26)<br>brainpoolP384r1 (27)<br>brainpoolP512r1 (28)<br>x25519 (29)| 22| Signature hash algorithm| dsa_sha256 (0x0402)<br>dsa_sha384 (0x0502)<br>dsa_sha512 (0x0602)<br>rsa_pkcs1_sha256 (0x0401)<br>rsa_pkcs1_sha384 (0x0501)<br>rsa_pkcs1_sha512 (0x0601)<br>ecdsa_secp256r1_sha256 (0x0403)<br>ecdsa_secp384r1_sha384 (0x0503)<br>ecdsa_secp521r1_sha512 (0x0603)<br>rsa_pss_rsae_sha256 (0x0804)<br>rsa_pss_rsae_sha384 (0x0805)<br>rsa_pss_rsae_sha512 (0x0806)<br>rsa_pss_pss_sha256 (0x0809)<br>rsa_pss_pss_sha384 (0x080a)<br>rsa_pss_pss_sha512 (0x080b)<br>ed25519 (0x0807)| 23| Dual-ended verification| **HITLS_CFG_SetClientVerifySupport** (disabled by default)| 24| Blank client certificate| **HITLS_CFG_SetNoClientCertSupport** (disabled by default)| 25| Do not verify peer certificate| **HITLS_CFG_SetVerifyNoneSupport** (disabled by default)| 26| Renegotiation| **HITLS_CFG_SetRenegotiationSupport** (disabled by default)| 27| Verify client certificate only once| **HITLS_CFG_SetClientOnceVerifySupport** (disabled by default)| 28| Send handshake packets in a single flight| **HITLS_CFG_SetFlightTransmitSwitch** (disabled by default)| 29| Quiet shutdown mode| **HITLS_CFG_SetQuietShutdown** (disabled by default)| 30| Extend primary key| **HITLS_CFG_SetExtenedMasterSecretSupport** (enabled by default)| 31| Support **sessionTicket**| **HITLS_CFG_SetSessionTicketSupport** (enabled by default)| 32| Verify **keyUsage**| **HITLS_CFG_SetCheckKeyUsage** (enabled by default)| 33| Auto-generate DH parameter| **HITLS_CFG_SetDhAutoSupport** (enabled by default)| 34 35### TLS1.3 Specifications 36 37| Configuration Item| Specifications| 38| :---- | :---- | 39| TLS version| TLS13 (0x0304u)| 40| Algorithm suite| TLS_AES_128_GCM_SHA256 (0x1301)<br>TLS_AES_256_GCM_SHA384 (0x1302)<br>TLS_CHACHA20_POLY1305_SHA256 (0x1303)<br>TLS_AES_128_CCM_SHA256 (0x1304)<br>TLS_AES_128_CCM_8_SHA256 (0x1305)| 41| EC dotted format| uncompressed (0)| 42| Elliptic curve| secp256r1 (23)<br>secp384r1 (24)<br>secp521r1 (25)<br>x25519 (29)<br>ffdhe2048 (256)<br>ffdhe3072 (257)<br>ffdhe4096 (258)<br>ffdhe6144 (259)<br>ffdhe8192 (260)| 43| Signature hash algorithm| rsa_pkcs1_sha256 (0x0401)<br>rsa_pkcs1_sha384 (0x0501)<br>rsa_pkcs1_sha512 (0x0601)<br>ecdsa_secp256r1_sha256 (0x0403)<br>ecdsa_secp384r1_sha384 (0x0503)<br>ecdsa_secp521r1_sha512 (0x0603)<br>rsa_pss_rsae_sha256 (0x0804)<br>rsa_pss_rsae_sha384 (0x0805)<br>rsa_pss_rsae_sha512 (0x0806)<br>rsa_pss_pss_sha256 (0x0809)<br>rsa_pss_pss_sha384 (0x080a)<br>rsa_pss_pss_sha512 (0x080b)<br>ed25519 (0x0807)| 44| Dual-ended verification| **HITLS_CFG_SetClientVerifySupport** (disabled by default)| 45| Blank client certificate| **HITLS_CFG_SetNoClientCertSupport** (disabled by default)| 46| Do not verify peer certificate| **HITLS_CFG_SetVerifyNoneSupport** (disabled by default)| 47| Verify client certificate only once| **HITLS_CFG_SetClientOnceVerifySupport** (disabled by default)| 48| Authentication after handshake| **HITLS_CFG_SetPostHandshakeAuthSupport** (disabled by default)| 49| Send handshake packets in a single flight| **HITLS_CFG_SetFlightTransmitSwitch** (disabled by default)| 50| Quiet shutdown mode| **HITLS_CFG_SetQuietShutdown** (disabled by default)| 51| Extend primary key| **HITLS_CFG_SetExtenedMasterSecretSupport** (enabled by default)| 52| Support **sessionTicket**| **HITLS_CFG_SetSessionTicketSupport** (enabled by default)| 53| Verify **keyUsage**| **HITLS_CFG_SetCheckKeyUsage** (enabled by default)| 54| Auto-generate DH parameter| **HITLS_CFG_SetDhAutoSupport** (enabled by default)| 55 56### TLCP Specifications 57 58| Configuration Item| Specifications| 59| :---- | :---- | 60| TLCP version| TLCP11 (0x0101u)| 61| Algorithm suite| ECDHE_SM4_CBC_SM3 (0xE011)<br>ECC_SM4_CBC_SM3 (0xE013)| 62| EC dotted format| HITLS_POINT_FORMAT_UNCOMPRESSED (0)| 63| Elliptic curve| curveSM2 (41)| 64| Signature hash algorithm| sm2sig_sm3 (0x0708)| 65| Dual-ended verification| **HITLS_CFG_SetClientVerifySupport** (disabled by default)| 66| Blank client certificate| **HITLS_CFG_SetNoClientCertSupport** (disabled by default)| 67| Do not verify peer certificate| **HITLS_CFG_SetVerifyNoneSupport** (disabled by default)| 68| Verify client certificate only once| **HITLS_CFG_SetClientOnceVerifySupport** (disabled by default)| 69| Send handshake packets in a single flight| **HITLS_CFG_SetFlightTransmitSwitch** (disabled by default)| 70| Quiet shutdown mode| **HITLS_CFG_SetQuietShutdown** (disabled by default)| 71| Verify **keyUsage**| **HITLS_CFG_SetCheckKeyUsage** (enabled by default)| 72 73### Extended Capabilities 74 75| Name| DTLS1.2 | TLS1.2 | TLS1.3 | TLCP | 76| :---- | :---- | :---- | :---- | :---- | 77| server_name | Yes| Yes| Yes| No| 78| supported_groups | Yes| Yes| Yes| Yes| 79| ec_point_formats | Yes| Yes| No| Yes| 80| signature_algorithms | Yes| Yes| Yes| No| 81| application_layer_protocol_negotiation | Yes| Yes| Yes| No| 82| extended_master_secret | Yes| Yes| No| No| 83| session_ticket | Yes| Yes| No| No| 84| encrypt_then_mac | Yes| Yes| No| Yes| 85| renegotiation_info | Yes| Yes| No| Yes| 86| early_data | No| No| No| No| 87| supported_versions | No| No| Yes| No| 88| cookie | Yes| No| Yes| No| 89| pre_shared_key | No| No| Yes| No| 90| psk_key_exchange_modes | No| No| Yes| No| 91| certificate_authorities | No| No| No| No| 92| oid_filters | No| No| No| No| 93| post_handshake_auth | No| No| Yes| No| 94| signature_algorithms_cert | No| No| No| No| 95| key_share | No| No| Yes| No| 96 97### Framework 98 99 100 101### Context Overview 102 103In openHiTLS, secure transmission context is split into two layers: `HITLS_Config` and `HITLS_Ctx`. `HITLS_Config` is the configuration context, with one context for each service type (like client or server) in a process. `HITLS_Ctx` is the link context, with one context for each connection. The configuration context and link context have a many-to-one relationship, and each link context in openHiTLS has a copy of the configuration context. 104 105### Non-blocking I/O Capability 106 107The protocol module cannot create file descriptions (FDs). Users must create and configure FDs in openHiTLS. Once openHiTLS reads and writes the FDs, users should close them. openHiTLS supports **non-blocking I/O** in both handshake and read/write phases. If calling `HITLS_Read` or `HITLS_Write` returns `HITLS_REC_NORMAL_RECV_BUF_EMPTY` or `HITLS_REC_NORMAL_IO_BUSY`, openHiTLS needs to repeat the read/write operation. In practice, the epoll/select driver is typically used to implement non-blocking I/O capabilities. The following is a piece of exemplary code of non-blocking I/O: 108 109```c 110// Shake hands with the client. 111do { 112 ret = HITLS_Connect(ctx); 113} while (ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY || ret == HITLS_REC_NORMAL_IO_BUSY); 114// Shake hands with the server. 115do { 116 ret = HITLS_Accept(ctx); 117} while (ret == HITLS_REC_NORMAL_RECV_BUF_EMPTY || ret == HITLS_REC_NORMAL_IO_BUSY); 118``` 119 120> **NOTE:** The `do while` statement serves as a reference only. In practice, the service logic may be implemented in a different manner. 121 122### Constraints 123 1241. The openHiTLS client and server are both authenticated using certificates. 1252. Users can quickly get started with openHiTLS using the default configurations provided. Typically, only a few additional configurations based on the defaults are required for openHiTLS to function properly. openHiTLS provides a rich set of configuration interfaces, and an API manual is provided to help product developers configure openHiTLS options as needed. 126 127### Dependencies 128 129The openHiTLS algorithm and certificate are decoupled from the protocol layer. Currently, it provides a self-implemented callback registration capability. The registration-related functions are as follows: 130 131```c 132/** 133 * @brief Register the default certificate callback function 134 */ 135int32_t HITLS_CertMethodInit(void); 136 137/** 138 * @brief Register the default algorithm callback function 139 */ 140void HITLS_CryptMethodInit(void); 141 142/** 143 * @brief Registering memory management callback functions 144 */ 145int32_t BSL_SAL_CallBack_Ctrl(BSL_SAL_CB_FUNC_TYPE funcType, void *funcCb); 146 147/** 148 * @brief Initialize global random number 149 */ 150int32_t CRYPT_EAL_RandInit(CRYPT_RAND_AlgId id, CRYPT_RandSeedMethod *seedMeth, void *seedCtx, 151 const uint8_t *pers, uint32_t persLen); 152``` 153 154## Time Sequence Interaction of Secure Communication Applications 155 156 157 158# Example TLS Client 159 160## Client Type 161 162### Certificate Authentication-based Client 163 164To use the certificate authentication-based client, you need both a trust certificate pool and device certificates. The trust certificate pool specifies which certificate authorities the client trusts. 165 166#### Loading Trust Certificates 167 168- The trust certificate pool specifies which certificate authorities the client trusts. It must be configured prior to connection establishment and will then be loaded into the certificate management engine. There are two types of trust certificate pools: 169 1701. Pool used to verify the peer certificate chain 171 When using algorithm suites that require server identity verification, the server sends certificates and the certificate chain to the TLS client through handshake messages. If the certificates and certificate chain are not issued by any authority trusted by the client, the client will send a critical alarm and terminate the handshake process. If no trust certificate pool is configured, certificate chain verification will fail, resulting in a TLS handshake failure. 172 173 For the configuration context, users can use the following interface to configure a trust certificate pool for verifying peer certificates: 174 175 ```c 176 /** 177 * @brief Set `VerifyStore` for TLS to verify certificates. 178 */ 179 int32_t HITLS_CFG_SetVerifyStore(HITLS_Config *config, HITLS_CERT_Store *store, bool isClone); 180 ``` 181 182 For the link context, users can call `HITLS_SetVerifyStore` to set `VerifyStore`. 183 184 > **NOTE:** Calling `HITLS_CFG_NewXXXConfig` will generate a default certificate pool, `CertStore`. If `VerifyStore` is not set, `CertStore` will be used to verify the certificate chain by default. 185 1862. Pool used to generate the local certificate chain 187 As part of the handshake process, the server sends its local certificate to the peer for verification. If the certificate chain for the local certificate is not configured, the server will search the trust certificate pool for the chain and send it to the peer. If the server has sent a certificate chain, it can request the TLS client's certificate to verify the client's identity, which is known as ***two-way authentication***. The TLS client will then send its local certificate and certificate chain to the server through handshake messages. If the local certificate is not found in the configured trust certificate pool or the pool is not configured, the client will send an empty certificate message. Whether the handshake can proceed depends on the server's behavior. 188 189 Users can use the following interface to configure a trust certificate pool for generating the local certificate chain: 190 191 ```c 192 /** 193 * @brief Set the chain store used for TLS configuration to construct a certificate chain. 194 */ 195 int32_t HITLS_CFG_SetChainStore(HITLS_Config *config, HITLS_CERT_Store *store, bool isClone); 196 ``` 197 198- Using device certificates and the corresponding certificate chains: The server or client (in two-way authentication) needs to send device certificates and certificate chains to the peer. In addition to the trust certificate pools, the certificate chains can be added based on the device certificates. When certificate chains are sent to the peer, those that match the device certificates are preferred. You can use the following interfaces to add the desired certificate chains: 199 200 ```c 201 /** 202 * @brief Add certificates to the certificate chain being used by **config**. 203 */ 204 int32_t HITLS_CFG_AddChainCert(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone); 205 ``` 206 207- Adding certificates to the trust certificate pool: After configuring a trust certificate pool, you can add trust certificates to it through the following interface: 208 209 ```c 210 /** 211 * @brief Add certificates to the specified trust certificate pool. 212 */ 213 int32_t HITLS_CFG_AddCertToStore(HITLS_Config *config, char *certPath, HITLS_CERT_StoreType storeType); 214 ``` 215 216 > **NOTE:** This interface can be used to add certificates to the default certificate pool, verification certificate pool, and certificate chain pool. The certificates are transferred using relative paths. 217 218#### Configuring Client Certificates 219 220A client certificate is a credential for client identity authentication. In two-way authentication, the TLS client will send its local certificate and certificate chain to the server through handshake messages. If no certificate is found in the client or no certificate is configured by users, the TLS client sends an empty certificate message. Whether the handshake can proceed depends on the server's behavior. 221 222For the configuration context, users can use the following interfaces to configure client certificates: 223 224```c 225/** 226 * @brief Add device certificates. Only one certificate of each type can be added. 227 */ 228int32_t HITLS_CFG_SetCertificate(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone); 229/** 230 * @brief Load the device certificates from a file. 231 */ 232int32_t HITLS_CFG_LoadCertFile(HITLS_Config *config, const uint8_t *file, HITLS_ParseFormat format); 233/** 234 * @brief Read the device certificates from the buffer. 235 */ 236int32_t HITLS_CFG_LoadCertBuffer(HITLS_Config *config, const uint8_t *buf, uint32_t bufLen, HITLS_ParseFormat format); 237/** 238 * @brief Add SM device certificates. Only one certificate of each type can be added. 239 */ 240int32_t HITLS_CFG_SetTlcpCertificate(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone, bool isTlcpEncCert); 241``` 242 243In addition to certificates, you need to configure private keys. Configuring certificates alone will also lead to handshake failure. You can use the following interfaces to configure private keys for certificates in the configuration context: 244 245```c 246/** 247 * @brief Add private keys for device certificates. Only one private key can be added for each type of certificate. 248 */ 249int32_t HITLS_CFG_SetPrivateKey(HITLS_Config *config, HITLS_CERT_Key *privateKey, bool isClone); 250/** 251 * @brief Load the private keys of device certificates from a file. 252 */ 253int32_t HITLS_CFG_LoadKeyFile(HITLS_Config *config, const uint8_t *file, HITLS_ParseFormat format); 254/** 255 * @brief Read the private keys of device certificates from the buffer. 256 */ 257int32_t HITLS_CFG_LoadKeyBuffer(HITLS_Config *config, const uint8_t *buf, uint32_t bufLen, HITLS_ParseFormat format); 258/** 259 * @brief Add SM device certificates. Only one certificate of each type can be added. 260 */ 261int32_t HITLS_CFG_SetTlcpCertificate(HITLS_Config *config, HITLS_CERT_X509 *cert, bool isClone, bool isTlcpEncCert); 262``` 263 264You can use the following interface to delete all certificates and private keys: 265 266```c 267/** 268 * @brief Release all loaded certificates and private keys. 269 */ 270int32_t HITLS_CFG_RemoveCertAndKey(HITLS_Config *config); 271``` 272 273In the link contexts that have been generated, you can use the following interface to delete the certificates and private keys: 274 275```c 276/** 277 * @brief Release all loaded certificates and private keys. 278 */ 279int32_t HITLS_RemoveCertAndKey(HITLS_Ctx *ctx); 280``` 281 282> **NOTE:** Each type of certificate and the corresponding private keys can be configured only once. If you try to configure them again, the previous configuration will be overwritten. Certificates of different types are not affected. For example, if two RSA certificates are configured in sequence, only the last one takes effect. If you configure an RSA certificate and an ECDSA certificate in sequence, both certificates take effect. 283 284### PSK Authentication-based Client 285 286The procedure for establishing connections based on PSK negotiation is as follows: 287 288 289 2901. If PSK negotiation is used, the client sends a **ClientHello** message containing the PSK algorithm suite to the server, and the server determines whether to use the PSK algorithm suite. 2912. After a specific PSK algorithm suite is selected, the server includes **`identity_hint`** in the **ServerKeyExchange** message to indicate which PSK the client should use. 2923. After receiving the **ServerKeyExchange** message containing **`identity_hint`**, the client requests the PSK and identity information from the TLS user through callback. 2934. Then, the client includes **`identity`** in the **ClientKeyExchange** message to indicate which PSK the server should use. 2945. After receiving the **ClientKeyExchange** message containing **`identity`**, the server requests the PSK from the upper-layer (the TLS user) through callback. 2956. Then, the two ends generate a pre-master key based on the obtained PSK individually and clear the PSK. The PSK negotiation process is complete. 296 297Therefore, the client using PSK authentication needs to set a pre-shared key to obtain the following callback information: 298 299```c 300/** 301 * @brief Obtain the PSK prototype on the client. 302 */ 303typedef uint32_t (*HITLS_PskClientCb)(HITLS_Ctx *ctx, const uint8_t *hint, uint8_t *identity, uint32_t maxIdentityLen, uint8_t *psk, uint32_t maxPskLen); 304/** 305 * @brief Set the PSK callback on the client, which is used to obtain an identity and PSK during PSK negotiation. 306 */ 307int32_t HITLS_CFG_SetPskClientCallback(HITLS_Config *config, HITLS_PskClientCb callback); 308``` 309 310## Sample Code 311 312### Certificate Authentication-based Client 313 314See [client.c](../../../testcode/demo/client.c) 315 316### PSK Authentication-based Client 317 318Most code of PSK Authentication-based client is the same as that Certificate Authentication-based client, except for the configuration of `HITLS_Config`. 319 320```c 321... 322uint32_t ExampleClientCb(HITLS_Ctx *ctx, const uint8_t *hint, uint8_t *identity, uint32_t maxIdentityLen, uint8_t *psk, 323 uint32_t maxPskLen) 324{ 325 (void)ctx; 326 (void)hint; 327 int32_t ret; 328 const char pskTrans[] = "psk data"; 329 uint32_t pskTransUsedLen = sizeof(pskTransUsedLen); 330 if (memcpy_s(identity, maxIdentityLen, "hello", strlen("hello") + 1) != EOK) { 331 return 0; 332 } 333 if (memcpy_s(psk, maxPskLen, pskTrans, pskTransUsedLen) != EOK) { 334 return 0; 335 } 336 return pskTransUsedLen; 337} 338 339 340int main(int32_t argc, char *argv[]) 341{ 342 ... 343 config = HITLS_CFG_NewTLS12Config(); 344 if (config == NULL) { 345 printf("HITLS_CFG_NewTLS12Config failed.\n"); 346 return -1; 347 } 348 uint16_t cipherSuite = HITLS_PSK_WITH_AES_128_GCM_SHA256; 349 // config cipher suite 350 if (HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1) != HITLS_SUCCESS) { 351 printf("HITLS_CFG_SetCipherSuites err\n"); 352 return -1; 353 } 354 // config PSK callbacks 355 if (HITLS_CFG_SetPskClientCallback(config, (HITLS_PskClientCb)ExampleClientCb) != HITLS_SUCCESS) { 356 printf("HITLS_CFG_SetPskClientCallback err\n"); 357 return -1; 358 } 359 360 ctx = HITLS_New(config); 361 if (ctx == NULL) { 362 printf("HITLS_New failed.\n"); 363 goto EXIT; 364 } 365 366 ... 367} 368``` 369 370### TLCP Client 371 372The steps except for the following are the same as those described in "Certificate Authentication-based Client." 373 374```c 375config = HITLS_CFG_NewTLCPConfig(); 376if (config == NULL) { 377 printf("HITLS_CFG_NewTLCPConfig failed.\n"); 378 return -1; 379} 380uint16_t cipherSuite = HITLS_ECC_SM4_CBC_SM3; 381// Configure the algorithm suite. 382if (HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1) != HITLS_SUCCESS) { 383 printf("HITLS_CFG_SetCipherSuites err\n"); 384 return -1; 385} 386 387/* Load certificates. This capability needs to be implemented by users. */ 388HITLS_CFG_AddCertToStore(config, "rootCA.pem", TLS_CERT_STORE_TYPE_DEFAULT); 389HITLS_CFG_AddCertToStore(config, "intCA.pem", TLS_CERT_STORE_TYPE_DEFAULT); 390// In two-way authentication scenarios, load the signature certificate and private key from a file. This capability needs to be implemented by users. 391HITLS_CERT_X509 *signCert = LoadCertFromFile("ClientSignCert.pem"); 392HITLS_CERT_X509 *signKey = LoadKeyFromFile("ClientSignKey.pem"); 393// Load the encryption certificate and private key from a file. 394HITLS_CERT_X509 *encCert = LoadCertFromFile("ClientEncCert.pem"); 395HITLS_CERT_X509 *encKey = LoadKeyFromFile("ClientEncKey.pem"); 396//Add the SM signature certificate and private key. 397HITLS_CFG_SetTlcpCertificate(config, signCert, false, false); 398HITLS_CFG_SetTlcpPrivateKey(config, signKey, false, false); 399//Add the SM encryption certificate and private key. 400HITLS_CFG_SetTlcpCertificate(config, signCert, false, true); 401HITLS_CFG_SetTlcpPrivateKey(config, signKey, false, true); 402... 403``` 404 405# Example TLS Server 406 407## Server Type 408 409### Certificate Authentication-based Server 410 411To use the certificate authentication-based TLS server, you need both a trust certificate pool and device certificates. The trust certificate pool specifies which certificate authorities the client trusts. A device certificate is a credential for server identity authentication. The server can determine whether to verify the client identity based on two-way authentication configuration items. 412 413#### Configuring the Two-Way Authentication Server 414 415If the server has sent a certificate chain, it can request the TLS client's certificate to verify the client's identity, which is known as two-way authentication. 416openHiTLS provides the following configuration items: 417 4181. Two-way authentication 419 This function is disabled by default. That is, the server does not verify the client identity by default. You can control the function through the `HITLS_CFG_SetClientVerifySupport` interface. 420 421```c 422/** 423 * @brief Set whether to verify the client certificate. 424 This setting has no impact on the client. 425 The server sends a certificate request. 426 */ 427int32_t HITLS_CFG_SetClientVerifySupport(HITLS_Config *config, bool support); 428``` 429 4302. Acceptance of no client certificates 431 This setting takes effect only when two-way authentication is enabled. It is disabled by default, meaning that the TLS server must verify the client certificate. If the certificate chain sent by the client is empty or fails verification, the TLS server sends a critical alarm and terminates the handshake. 432 You can control the function through the `HITLS_CFG_SetNoClientCertSupport` interface. 433 434```c 435/** 436 * @brief Set whether to accept the scenario without any client certificates. This setting takes effect only when client certificate verification is enabled. 437 This setting has no impact on the client. 438 The server checks whether the certificate verification is successful when receiving an empty certificate from the client. The verification fails by default. 439 */ 440int32_t HITLS_CFG_SetNoClientCertSupport(HITLS_Config *config, bool support); 441``` 442 443#### Loading Trust Certificate Pools 444 445Refer to "Loading Trust Certificates." 446 447#### Configuring Server Certificates 448 449If the algorithm suite requires server identity verification, users need to configure the server certificates, certificate chain, and private keys. Refer to "Configuring Client Certificates." 450 451### PSK Authentication-based Server 452 453The callback for the PSK authentication-based server to obtain the pre-shared key is slightly different from that used by the client, as shown below: 454 455```c 456/** 457 * @brief Server PSK negotiation callback 458*/ 459typedef int32_t (*HITLS_PskFindSessionCb)(HITLS_Ctx *ctx, const uint8_t *identity, uint32_t identityLen, 460 HITLS_Session **session); 461/** 462 * @brief Set the callback for the PSK authentication-based server, which is used to obtain a PSK during PSK negotiation. 463 */ 464int32_t HITLS_CFG_SetPskServerCallback(HITLS_Config *config, HITLS_PskServerCb callback); 465``` 466 467For details about the remaining procedure, see "PSK Authentication-based Client." 468 469## Sample Code 470 471### Certificate Authentication-based Server 472 473See [server.c](../../../testcode/demo/server.c) 474 475### ### PSK Authentication-based Server 476 477Most code of PSK Authentication-based server is the same as that Certificate Authentication-based server, except for the configuration of `HITLS_Config`. 478 479```c 480... 481 482uint32_t ExampleServerCb(HITLS_Ctx *ctx, const uint8_t *identity, uint8_t *psk, uint32_t maxPskLen) 483{ 484 (void)ctx; 485 if (identity == NULL || strcmp((const char *)identity, "hello") != 0) { 486 return 0; 487 } 488 const char pskTrans[] = "psk data"; 489 uint32_t pskTransUsedLen = sizeof(pskTransUsedLen); 490 if (memcpy_s(psk, maxPskLen, pskTrans, pskTransUsedLen) != EOK) { 491 return 0; 492 } 493 return pskTransUsedLen; 494} 495 496int main(int32_t argc, char *argv[]) 497{ 498 ... 499 config = HITLS_CFG_NewTLS12Config(); 500 if (config == NULL) { 501 printf("HITLS_CFG_NewTLS12Config failed.\n"); 502 return -1; 503 } 504 uint16_t cipherSuite = HITLS_PSK_WITH_AES_128_GCM_SHA256; 505 // config cipher suite 506 if (HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1) != HITLS_SUCCESS) { 507 printf("HITLS_CFG_SetCipherSuites err\n"); 508 return -1; 509 } 510 // config PSK callback 511 if (HITLS_CFG_SetPskServerCallback(tlsConfig, (HITLS_PskServerCb)ExampleServerCb) != HITLS_SUCCESS) { 512 printf("HITLS_CFG_SetPskClientCallback err\n"); 513 return -1; 514 } 515 516 ctx = HITLS_New(config); 517 if (ctx == NULL) { 518 printf("HITLS_New failed.\n"); 519 goto EXIT; 520 } 521 522 ... 523} 524``` 525 526### TLCP Server 527 528The steps except for the following are the same as those described in "Certificate Authentication-based Server." 529 530```c 531... 532config = HITLS_CFG_NewTLCPConfig(); 533if (cfg == NULL) { 534 printf("HITLS_CFG_NewTLCPConfig failed.\n"); 535 return -1; 536} 537 538uint16_t cipherSuite = HITLS_ECC_SM4_CBC_SM3; 539// Configure the algorithm suite. 540if (HITLS_CFG_SetCipherSuites(config, &cipherSuite, 1) != HITLS_SUCCESS) { 541 printf("HITLS_CFG_SetCipherSuites err\n"); 542 return -1; 543} 544 545if (HITLS_CFG_SetClientVerifySupport(config, true) != HITLS_SUCCESS) { 546 printf("HITLS_CFG_SetClientVerifySupport err\n"); 547 return -1; 548} 549 550/* Load certificates. This capability needs to be implemented by users. */ 551HITLS_CFG_AddCertToStore(config, "rootCA.pem", TLS_CERT_STORE_TYPE_DEFAULT); 552HITLS_CFG_AddCertToStore(config, "intCA.pem", TLS_CERT_STORE_TYPE_DEFAULT); 553// Load the signature certificate and private key from a file. This capability needs to be implemented by users. 554HITLS_CERT_X509 *signCert = LoadCertFromFile("ServerSignCert.pem"); 555HITLS_CERT_X509 *signKey = LoadKeyFromFile("ServerSignKey.pem"); 556// Load the encryption certificate and private key from a file. 557HITLS_CERT_X509 *encCert = LoadCertFromFile("ServerEncCert.pem"); 558HITLS_CERT_X509 *encKey = LoadKeyFromFile("ServerEncKey.pem"); 559//Add the SM signature certificate and private key. 560HITLS_CFG_SetTlcpCertificate(config, signCert, false, false); 561HITLS_CFG_SetTlcpPrivateKey(config, signKey, false, false); 562//Add the SM encryption certificate and private key. 563HITLS_CFG_SetTlcpCertificate(config, signCert, false, true); 564HITLS_CFG_SetTlcpPrivateKey(config, signKey, false, true); 565... 566``` 567 568# Example of TLS Session Key Update 569 570## Update Type 571 572### TLS1.2/TLCP or DTLS1.2/TLCP Renegotiation Example 573 574TLS1.2/TLCP or DTLS1.2/TLCP supports security renegotiation. The renegotiation function enables the client or server to initiate a new negotiation over the same security connection to generate a new key. This function applies to connections that require high confidentiality and transmit a large amount of data. 575The security renegotiation procedure is as follows: 576 577 578 579> **NOTE:** Users can enter the renegotiation state through the `HITLS_Renegotiate` interface and trigger renegotiation handshakes through the `HITLS_Accept`, `HITLS_Connect`, `HITLS_Write`, or `HITLS_Read` interface. The `HITLS_Accept` and `HITLS_Connect` interfaces are recommended. 580 581**Client example** 582 583```c 584/* Exchange data at the application layer. */ 585const uint8_t sndBuf[] = "Hi, this is client\n"; 586uint32_t writeLen = 0; 587ret = HITLS_Write(ctx, sndBuf, sizeof(sndBuf), &writeLen); 588if (ret != HITLS_SUCCESS) { 589 printf("HITLS_Write error:error code:%d\n", ret); 590 goto EXIT; 591} 592uint8_t readBuf[HTTP_BUF_MAXLEN + 1] = {0}; 593uint32_t readLen = 0; 594ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); 595if (ret != HITLS_SUCCESS) { 596 printf("HITLS_Read failed, ret = 0x%x.\n", ret); 597 goto EXIT; 598} 599/* The client enters the renegotiation state. */ 600ret = HITLS_Renegotiate(ctx); 601if (ret != HITLS_SUCCESS) { 602 printf("HITLS_Renegotiate error:error code:%d\n", ret); 603 goto EXIT; 604} 605/* The client initiates a handshake, and the server processes the handshake through the `HITLS_Read` interface. */ 606ret = HITLS_Connect(ctx); 607if (ret != HITLS_SUCCESS) { 608 printf("HITLS_Connect failed, ret = 0x%x.\n", ret); 609 goto EXIT; 610} 611/* The renegotiation is complete, and the data exchange at the application layer proceeds. */ 612``` 613 614**Server example** 615 616```c 617/* Exchange data at the application layer. */ 618uint8_t readBuf[HTTP_BUF_MAXLEN + 1] = {0}; 619uint32_t readLen = 0; 620ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); 621if (ret != HITLS_SUCCESS) { 622 printf("HITLS_Read failed, ret = 0x%x.\n", ret); 623 goto EXIT; 624} 625const uint8_t sndBuf[] = "Hi, this is server\n"; 626uint32_t writeLen = 0; 627ret = HITLS_Write(ctx, sndBuf, sizeof(sndBuf), &writeLen); 628if (ret != HITLS_SUCCESS) { 629 printf("HITLS_Write error:error code:%d\n", ret); 630 goto EXIT; 631} 632/* The server enters the renegotiation state. */ 633ret = HITLS_Renegotiate(ctx); 634if (ret != HITLS_SUCCESS) { 635 printf("HITLS_Renegotiate error:error code:%d\n", ret); 636 goto EXIT; 637} 638/* The server initiates a handshake, and the client processes the handshake through the `HITLS_Read` interface. */ 639ret = HITLS_Accept(ctx); 640if (ret != HITLS_SUCCESS) { 641 printf("HITLS_Accept failed, ret = 0x%x.\n", ret); 642 goto EXIT; 643} 644/* The renegotiation is complete, and the data exchange at the application layer proceeds. */ 645``` 646 647### Example of TLS1.3 Key Update 648 649TLS1.3 supports key update after connection establishment. The involved functions are as follows: 650 651```c 652/** 653 * @brief Set the `KeyUpdate` type and send a `KeyUpdate` message to the peer. 654 */ 655int32_t HITLS_KeyUpdate(HITLS_Ctx *ctx, uint32_t updateType); 656``` 657 658The following `KeyUpdate` types are supported: 659 660```c 661The HITLS_UPDATE_NOT_REQUESTED = 0, // The peer does not have to reply to the `KeyUpdate` message. 662HITLS_UPDATE_REQUESTED = 1, // The peer must reply to the `KeyUpdate` message. 663``` 664 665**Client example** 666 667```c 668/* Exchange data at the application layer. */ 669uint8_t readBuf[HTTP_BUF_MAXLEN + 1] = {0}; 670uint32_t readLen = 0; 671ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); 672if (ret != HITLS_SUCCESS) { 673 printf("HITLS_Read failed, ret = 0x%x.\n", ret); 674 goto EXIT; 675} 676const uint8_t sndBuf[] = "Hi, this is server\n"; 677uint32_t writeLen = 0; 678ret = HITLS_Write(ctx, sndBuf, sizeof(sndBuf), &writeLen); 679if (ret != HITLS_SUCCESS) { 680 printf("HITLS_Write error:error code:%d\n", ret); 681 goto EXIT; 682} 683/* The client initiates a `KeyUpdate` message that does not require replies from the peer. The peer processes the message through the `HITLS_Read` interface. */ 684ret = HITLS_KeyUpdate(ctx, HITLS_UPDATE_NOT_REQUESTED); 685if (ret != HITLS_SUCCESS) { 686 printf("HITLS_KeyUpdate error:error code:%d\n", ret); 687 goto EXIT; 688} 689/* The key update process is complete. */ 690``` 691 692**Server example** 693 694```c 695/* Exchange data at the application layer. */ 696uint8_t readBuf[HTTP_BUF_MAXLEN + 1] = {0}; 697uint32_t readLen = 0; 698ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); 699if (ret != HITLS_SUCCESS) { 700 printf("HITLS_Read failed, ret = 0x%x.\n", ret); 701 goto EXIT; 702} 703const uint8_t sndBuf[] = "Hi, this is server\n"; 704uint32_t writeLen = 0; 705ret = HITLS_Write(ctx, sndBuf, sizeof(sndBuf), &writeLen); 706if (ret != HITLS_SUCCESS) { 707 printf("HITLS_Write error:error code:%d\n", ret); 708 goto EXIT; 709} 710/* The server initiates a `KeyUpdate` message that requires replies from the peer. The peer processes the message through the `HITLS_Read` interface and returns replies to the `KeyUpdate` message. */ 711ret = HITLS_KeyUpdate(ctx, HITLS_UPDATE_REQUESTED); 712if (ret != HITLS_SUCCESS) { 713 printf("HITLS_KeyUpdate error:error code:%d\n", ret); 714 goto EXIT; 715} 716/* The `HITLS_Read` interface receives the peer's replies to the `KeyUpdate` message. */ 717ret = HITLS_Read(ctx, readBuf, HTTP_BUF_MAXLEN, &readLen); 718if (ret != HITLS_SUCCESS) { 719 printf("HITLS_Read failed, ret = 0x%x.\n", ret); 720 goto EXIT; 721} 722/* The key update process is complete. */ 723``` 724 725