协议通信
概述
协议通信 (protocomm) 组件用于管理安全会话并为多种传输提供框架。应用程序还可以直接使用 protocomm 层来增加特定扩展,用于配网或非配网使用场景。
以下功能可用于配网:
- 应用程序层面的通信安全
* `protocomm_security0` (无安全功能) * `protocomm_security1` (Curve25519 密钥交换 + AES-CTR 加密/解密) * `protocomm_security2` (基于 SRP6a 的密钥交换 + AES-GCM 加密/解密)
所有权验证 (Proof-of-possession)(仅
protocomm_security1
支持该功能)盐值和验证器 (Salt and Verifier)(仅
protocomm_security2
支持该功能)
在 protocomm 内部,protobuf(协议缓冲区)用于建立安全会话。用户可以自行选择(即使在不使用 Protobuf 的情况下)实现安全性,也可以在没有任何安全层的情况下使用协议。
Protocomm 为以下各种传输提供框架:
低功耗蓝牙
Wi-Fi (SoftAP + HTTPD)
控制台:使用该传输方案时,设备端会自动调用处理程序。相关代码片段,请参见下文传输示例。
请注意,对于 protocomm_security1
和 protocomm_security2
,客户端仍需要执行双向握手来建立会话。关于安全握手逻辑的详情,请参阅 统一配网。
启用 protocomm 安全版本
关于启用/禁用相应的安全版本,请参阅 protocomm 组件的项目配置菜单。相应配置选项如下:
支持
protocomm_security0
,该版本无安全功能:CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0,该选项默认启用。支持
protocomm_security1
,使用 Curve25519 密钥交换和 AES-CTR 加密/解密:CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1,该选项默认启用。支持
protocomm_security2
,使用基于 SRP6a 的密钥交换和 AES-GCM 加密/解密:CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2。
备注
启用多个安全版本后可以动态控制安全版本,但也会增加固件大小。
使用 Security 2 的 SoftAP + HTTP 传输方案示例
示例用法请参阅 wifi_provisioning/src/scheme_softap.c。
/* 此为将通过 protocomm 注册的端点处理程序,会直接回显接收到的数据 */
esp_err_t echo_req_handler (uint32_t session_id,
const uint8_t *inbuf, ssize_t inlen,
uint8_t **outbuf, ssize_t *outlen,
void *priv_data)
{
/* Session ID 可以用于持久化 */
printf("Session ID : %d", session_id);
/* 回显接收到的数据 */
*outlen = inlen; /* 输出更新后的数据长度 */
*outbuf = malloc(inlen); /* 将在外部释放 */
memcpy(*outbuf, inbuf, inlen);
/* 端点创建时传递的私有数据 */
uint32_t *priv = (uint32_t *) priv_data;
if (priv) {
printf("Private data : %d", *priv);
}
return ESP_OK;
}
static const char sec2_salt[] = {0xf7, 0x5f, 0xe2, 0xbe, 0xba, 0x7c, 0x81, 0xcd};
static const char sec2_verifier[] = {0xbf, 0x86, 0xce, 0x63, 0x8a, 0xbb, 0x7e, 0x2f, 0x38, 0xa8, 0x19, 0x1b, 0x35,
0xc9, 0xe3, 0xbe, 0xc3, 0x2b, 0x45, 0xee, 0x10, 0x74, 0x22, 0x1a, 0x95, 0xbe, 0x62, 0xf7, 0x0c, 0x65, 0x83, 0x50,
0x08, 0xef, 0xaf, 0xa5, 0x94, 0x4b, 0xcb, 0xe1, 0xce, 0x59, 0x2a, 0xe8, 0x7b, 0x27, 0xc8, 0x72, 0x26, 0x71, 0xde,
0xb2, 0xf2, 0x80, 0x02, 0xdd, 0x11, 0xf0, 0x38, 0x0e, 0x95, 0x25, 0x00, 0xcf, 0xb3, 0x3f, 0xf0, 0x73, 0x2a, 0x25,
0x03, 0xe8, 0x51, 0x72, 0xef, 0x6d, 0x3e, 0x14, 0xb9, 0x2e, 0x9f, 0x2a, 0x90, 0x9e, 0x26, 0xb6, 0x3e, 0xc7, 0xe4,
0x9f, 0xe3, 0x20, 0xce, 0x28, 0x7c, 0xbf, 0x89, 0x50, 0xc9, 0xb6, 0xec, 0xdd, 0x81, 0x18, 0xf1, 0x1a, 0xd9, 0x7a,
0x21, 0x99, 0xf1, 0xee, 0x71, 0x2f, 0xcc, 0x93, 0x16, 0x34, 0x0c, 0x79, 0x46, 0x23, 0xe4, 0x32, 0xec, 0x2d, 0x9e,
0x18, 0xa6, 0xb9, 0xbb, 0x0a, 0xcf, 0xc4, 0xa8, 0x32, 0xc0, 0x1c, 0x32, 0xa3, 0x97, 0x66, 0xf8, 0x30, 0xb2, 0xda,
0xf9, 0x8d, 0xc3, 0x72, 0x72, 0x5f, 0xe5, 0xee, 0xc3, 0x5c, 0x24, 0xc8, 0xdd, 0x54, 0x49, 0xfc, 0x12, 0x91, 0x81,
0x9c, 0xc3, 0xac, 0x64, 0x5e, 0xd6, 0x41, 0x88, 0x2f, 0x23, 0x66, 0xc8, 0xac, 0xb0, 0x35, 0x0b, 0xf6, 0x9c, 0x88,
0x6f, 0xac, 0xe1, 0xf4, 0xca, 0xc9, 0x07, 0x04, 0x11, 0xda, 0x90, 0x42, 0xa9, 0xf1, 0x97, 0x3d, 0x94, 0x65, 0xe4,
0xfb, 0x52, 0x22, 0x3b, 0x7a, 0x7b, 0x9e, 0xe9, 0xee, 0x1c, 0x44, 0xd0, 0x73, 0x72, 0x2a, 0xca, 0x85, 0x19, 0x4a,
0x60, 0xce, 0x0a, 0xc8, 0x7d, 0x57, 0xa4, 0xf8, 0x77, 0x22, 0xc1, 0xa5, 0xfa, 0xfb, 0x7b, 0x91, 0x3b, 0xfe, 0x87,
0x5f, 0xfe, 0x05, 0xd2, 0xd6, 0xd3, 0x74, 0xe5, 0x2e, 0x68, 0x79, 0x34, 0x70, 0x40, 0x12, 0xa8, 0xe1, 0xb4, 0x6c,
0xaa, 0x46, 0x73, 0xcd, 0x8d, 0x17, 0x72, 0x67, 0x32, 0x42, 0xdc, 0x10, 0xd3, 0x71, 0x7e, 0x8b, 0x00, 0x46, 0x9b,
0x0a, 0xe9, 0xb4, 0x0f, 0xeb, 0x70, 0x52, 0xdd, 0x0a, 0x1c, 0x7e, 0x2e, 0xb0, 0x61, 0xa6, 0xe1, 0xa3, 0x34, 0x4b,
0x2a, 0x3c, 0xc4, 0x5d, 0x42, 0x05, 0x58, 0x25, 0xd3, 0xca, 0x96, 0x5c, 0xb9, 0x52, 0xf9, 0xe9, 0x80, 0x75, 0x3d,
0xc8, 0x9f, 0xc7, 0xb2, 0xaa, 0x95, 0x2e, 0x76, 0xb3, 0xe1, 0x48, 0xc1, 0x0a, 0xa1, 0x0a, 0xe8, 0xaf, 0x41, 0x28,
0xd2, 0x16, 0xe1, 0xa6, 0xd0, 0x73, 0x51, 0x73, 0x79, 0x98, 0xd9, 0xb9, 0x00, 0x50, 0xa2, 0x4d, 0x99, 0x18, 0x90,
0x70, 0x27, 0xe7, 0x8d, 0x56, 0x45, 0x34, 0x1f, 0xb9, 0x30, 0xda, 0xec, 0x4a, 0x08, 0x27, 0x9f, 0xfa, 0x59, 0x2e,
0x36, 0x77, 0x00, 0xe2, 0xb6, 0xeb, 0xd1, 0x56, 0x50, 0x8e};
/* 通过 HTTP 启动 protocomm 实例的示例函数 */
protocomm_t *start_pc()
{
protocomm_t *pc = protocomm_new();
/* 配置 protocomm_httpd_start() */
protocomm_httpd_config_t pc_config = {
.data = {
.config = PROTOCOMM_HTTPD_DEFAULT_CONFIG()
}
};
/* 启动基于 HTTP 的 protocomm 服务器 */
protocomm_httpd_start(pc, &pc_config);
/* 从盐值和验证器创建 security2 参数对象。该对象必须在 protocomm 端点作用域内有效,且无需为静态对象,即可以在删除端点时动态分配和释放。*/
const static protocomm_security2_params_t sec2_params = {
.salt = (const uint8_t *) salt,
.salt_len = sizeof(salt),
.verifier = (const uint8_t *) verifier,
.verifier_len = sizeof(verifier),
};
/* 在应用程序层面为通信设置安全方案。与请求处理程序类似,设置安全方案会创建一个端点,并注册 protocomm_security1 提供的处理程序。也可以使用 protocomm_security0 进行类似操作。单个 protocomm 实例中一次只能设置一种类型的安全方案。*/
protocomm_set_security(pc, "security_endpoint", &protocomm_security2, &sec2_params);
/* 传递给端点的私有数据必须在 protocomm 端点作用域内有效。该数据无需为静态数据,即可以在删除端点时动态分配和释放。*/
static uint32_t priv_data = 1234;
/* 为 protocomm 实例添加一个新端点,该端点由唯一名称标识,再注册一个处理函数,在执行函数时传递私有数据。只要端点由唯一名称标识,即可添加多个端点。*/
protocomm_add_endpoint(pc, "echo_req_endpoint",
echo_req_handler, (void *) &priv_data);
return pc;
}
/* 停止 protocomm 实例的示例函数 */
void stop_pc(protocomm_t *pc)
{
/* 移除由其唯一名称标识的端点 */
protocomm_remove_endpoint(pc, "echo_req_endpoint");
/* 移除由其名称标识的安全端点 */
protocomm_unset_security(pc, "security_endpoint");
/* 停止 HTTP 服务器 */
protocomm_httpd_stop(pc);
/* 删除(即释放)protocomm 实例 */
protocomm_delete(pc);
}
使用 Security 1 的 SoftAP + HTTP 传输方案示例
示例用法请参阅 wifi_provisioning/src/scheme_softap.c。
/* 此为将通过 protocomm 注册的端点处理程序,会直接回显接收到的数据 */
esp_err_t echo_req_handler (uint32_t session_id,
const uint8_t *inbuf, ssize_t inlen,
uint8_t **outbuf, ssize_t *outlen,
void *priv_data)
{
/* Session ID 可以用于持久化 */
printf("Session ID : %d", session_id);
/* 回显接收到的数据 */
*outlen = inlen; /* 输出更新后的数据长度 */
*outbuf = malloc(inlen); /* 将在外部释放 */
memcpy(*outbuf, inbuf, inlen);
/* 端点创建时传递的私有数据 */
uint32_t *priv = (uint32_t *) priv_data;
if (priv) {
printf("Private data : %d", *priv);
}
return ESP_OK;
}
/* 通过 HTTP 启动 protocomm 实例的示例函数 */
protocomm_t *start_pc(const char *pop_string)
{
protocomm_t *pc = protocomm_new();
/* 配置 protocomm_httpd_start() */
protocomm_httpd_config_t pc_config = {
.data = {
.config = PROTOCOMM_HTTPD_DEFAULT_CONFIG()
}
};
/* 启动基于 HTTP 的 protocomm 服务器 */
protocomm_httpd_start(pc, &pc_config);
/* 从 pop_string 创建 security1 参数对象。该对象必须在 protocomm 端点作用域内有效,且无需为静态对象,即可以在删除端点时动态分配和释放。*/
const static protocomm_security1_params_t sec1_params = {
.data = (const uint8_t *) strdup(pop_string),
.len = strlen(pop_string)
};
/* 在应用程序层面为通信设置安全方案。与请求处理程序类似,设置安全方案会创建一个端点,并注册 protocomm_security1 提供的处理程序。也可以使用 protocomm_security0 进行类似操作。单个 protocomm 实例中一次只能设置一种类型的安全方案*/
protocomm_set_security(pc, "security_endpoint", &protocomm_security1, &sec1_params);
/* 传递给端点的私有数据必须在 protocomm 端点作用域内有效。该数据无需为静态数据,即可以在删除端点时动态分配和释放。*/
static uint32_t priv_data = 1234;
/* 为 protocomm 实例添加一个新端点,该端点由唯一名称标识,再注册一个处理函数,在执行函数时传递私有数据。只要端点由唯一名称标识,即可添加多个端点。*/
protocomm_add_endpoint(pc, "echo_req_endpoint",
echo_req_handler, (void *) &priv_data);
return pc;
}
/* 停止 protocomm 实例的示例函数 */
void stop_pc(protocomm_t *pc)
{
/* 移除由其唯一名称标识的端点 */
protocomm_remove_endpoint(pc, "echo_req_endpoint");
/* 移除由其名称标识的安全端点 */
protocomm_unset_security(pc, "security_endpoint");
/* 停止 HTTP 服务器 */
protocomm_httpd_stop(pc);
/* 删除(即释放)protocomm 实例 */
protocomm_delete(pc);
}
使用 Security 0 的低功耗蓝牙传输方案示例
示例用法请参阅 wifi_provisioning/src/scheme_ble.c。
/* 通过低功耗蓝牙启动安全 protocomm 实例的示例函数 */
protocomm_t *start_pc()
{
protocomm_t *pc = protocomm_new();
/* 端点 UUID */
protocomm_ble_name_uuid_t nu_lookup_table[] = {
{"security_endpoint", 0xFF51},
{"echo_req_endpoint", 0xFF52}
};
/* 配置 protocomm_ble_start() */
protocomm_ble_config_t config = {
.service_uuid = {
/* 最低有效位 <---------------------------------------
* ---------------------------------------> 最高有效位 */
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
0x00, 0x10, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
},
.nu_lookup_count = sizeof(nu_lookup_table)/sizeof(nu_lookup_table[0]),
.nu_lookup = nu_lookup_table
};
/* 启动基于低功耗蓝牙的 protocomm 层 */
protocomm_ble_start(pc, &config);
/* protocomm_security0 方案不使用所有权证明,因此可以将其保持为 NULL */
protocomm_set_security(pc, "security_endpoint", &protocomm_security0, NULL);
protocomm_add_endpoint(pc, "echo_req_endpoint", echo_req_handler, NULL);
return pc;
}
/* 停止 protocomm 实例的示例函数 */
void stop_pc(protocomm_t *pc)
{
protocomm_remove_endpoint(pc, "echo_req_endpoint");
protocomm_unset_security(pc, "security_endpoint");
/* 停止低功耗蓝牙 protocomm 服务 */
protocomm_ble_stop(pc);
protocomm_delete(pc);
}
API 参考
Header File
This header file can be included with:
#include "protocomm.h"
- This header file is a part of the API provided by the
protocomm
component. To declare that your component depends onprotocomm
, add the following to your CMakeLists.txt:
REQUIRES protocomm
or
> PRIV_REQUIRES protocomm
Functions
protocomm_t *protocomm_new(void)
Create a new protocomm instance.
This API will return a new dynamically allocated protocomm instance with all elements of the protocomm_t structure initialized to NULL.
返回
protocomm_t* : On success
NULL : No memory for allocating new instance
void protocomm_delete(protocomm_t *pc)
Delete a protocomm instance.
This API will deallocate a protocomm instance that was created using protocomm_new()
.
参数
pc -- [in] Pointer to the protocomm instance to be deleted
esp_err_t protocomm_add_endpoint(protocomm_t *pc, const char *ep_name, protocomm_req_handler_t h, void *priv_data)
Add endpoint request handler for a protocomm instance.
This API will bind an endpoint handler function to the specified endpoint name, along with any private data that needs to be pass to the handler at the time of call.
备注
An endpoint must be bound to a valid protocomm instance, created using
protocomm_new()
.This function internally calls the registered
add_endpoint()
function of the selected transport which is a member of the protocomm_t instance structure.
参数
pc -- [in] Pointer to the protocomm instance
ep_name -- [in] Endpoint identifier(name) string
h -- [in] Endpoint handler function
priv_data -- [in] Pointer to private data to be passed as a parameter to the handler function on call. Pass NULL if not needed.
返回
ESP_OK : Success
ESP_FAIL : Error adding endpoint / Endpoint with this name already exists
ESP_ERR_NO_MEM : Error allocating endpoint resource
ESP_ERR_INVALID_ARG : Null instance/name/handler arguments
esp_err_t protocomm_remove_endpoint(protocomm_t *pc, const char *ep_name)
Remove endpoint request handler for a protocomm instance.
This API will remove a registered endpoint handler identified by an endpoint name.
备注
- This function internally calls the registered
remove_endpoint()
function which is a member of the protocomm_t instance structure.
参数
pc -- [in] Pointer to the protocomm instance
ep_name -- [in] Endpoint identifier(name) string
返回
ESP_OK : Success
ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist
ESP_ERR_INVALID_ARG : Null instance/name arguments
esp_err_t protocomm_open_session(protocomm_t *pc, uint32_t session_id)
Allocates internal resources for new transport session.
备注
- An endpoint must be bound to a valid protocomm instance, created using
protocomm_new()
.
参数
pc -- [in] Pointer to the protocomm instance
session_id -- [in] Unique ID for a communication session
返回
ESP_OK : Request handled successfully
ESP_ERR_NO_MEM : Error allocating internal resource
ESP_ERR_INVALID_ARG : Null instance/name arguments
esp_err_t protocomm_close_session(protocomm_t *pc, uint32_t session_id)
Frees internal resources used by a transport session.
备注
- An endpoint must be bound to a valid protocomm instance, created using
protocomm_new()
.
参数
pc -- [in] Pointer to the protocomm instance
session_id -- [in] Unique ID for a communication session
返回
ESP_OK : Request handled successfully
ESP_ERR_INVALID_ARG : Null instance/name arguments
esp_err_t protocomm_req_handle(protocomm_t *pc, const char *ep_name, uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, uint8_t **outbuf, ssize_t *outlen)
Calls the registered handler of an endpoint session for processing incoming data and generating the response.
备注
An endpoint must be bound to a valid protocomm instance, created using
protocomm_new()
.Resulting output buffer must be deallocated by the caller.
参数
pc -- [in] Pointer to the protocomm instance
ep_name -- [in] Endpoint identifier(name) string
session_id -- [in] Unique ID for a communication session
inbuf -- [in] Input buffer contains input request data which is to be processed by the registered handler
inlen -- [in] Length of the input buffer
outbuf -- [out] Pointer to internally allocated output buffer, where the resulting response data output from the registered handler is to be stored
outlen -- [out] Buffer length of the allocated output buffer
返回
ESP_OK : Request handled successfully
ESP_FAIL : Internal error in execution of registered handler
ESP_ERR_NO_MEM : Error allocating internal resource
ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist
ESP_ERR_INVALID_ARG : Null instance/name arguments
esp_err_t protocomm_set_security(protocomm_t *pc, const char *ep_name, const protocomm_security_t *sec, const void *sec_params)
Add endpoint security for a protocomm instance.
This API will bind a security session establisher to the specified endpoint name, along with any proof of possession that may be required for authenticating a session client.
备注
An endpoint must be bound to a valid protocomm instance, created using
protocomm_new()
.The choice of security can be any
protocomm_security_t
instance. Choicesprotocomm_security0
andprotocomm_security1
andprotocomm_security2
are readily available.
参数
pc -- [in] Pointer to the protocomm instance
ep_name -- [in] Endpoint identifier(name) string
sec -- [in] Pointer to endpoint security instance
sec_params -- [in] Pointer to security params (NULL if not needed) The pointer should contain the security params struct of appropriate security version. For protocomm security version 1 and 2 sec_params should contain pointer to struct of type protocomm_security1_params_t and protocmm_security2_params_t respectively. The contents of this pointer must be valid till the security session has been running and is not closed.
返回
ESP_OK : Success
ESP_FAIL : Error adding endpoint / Endpoint with this name already exists
ESP_ERR_INVALID_STATE : Security endpoint already set
ESP_ERR_NO_MEM : Error allocating endpoint resource
ESP_ERR_INVALID_ARG : Null instance/name/handler arguments
esp_err_t protocomm_unset_security(protocomm_t *pc, const char *ep_name)
Remove endpoint security for a protocomm instance.
This API will remove a registered security endpoint identified by an endpoint name.
参数
pc -- [in] Pointer to the protocomm instance
ep_name -- [in] Endpoint identifier(name) string
返回
ESP_OK : Success
ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist
ESP_ERR_INVALID_ARG : Null instance/name arguments
esp_err_t protocomm_set_version(protocomm_t *pc, const char *ep_name, const char *version)
Set endpoint for version verification.
This API can be used for setting an application specific protocol version which can be verified by clients through the endpoint.
备注
- An endpoint must be bound to a valid protocomm instance, created using
protocomm_new()
.
参数
pc -- [in] Pointer to the protocomm instance
ep_name -- [in] Endpoint identifier(name) string
version -- [in] Version identifier(name) string
返回
ESP_OK : Success
ESP_FAIL : Error adding endpoint / Endpoint with this name already exists
ESP_ERR_INVALID_STATE : Version endpoint already set
ESP_ERR_NO_MEM : Error allocating endpoint resource
ESP_ERR_INVALID_ARG : Null instance/name/handler arguments
esp_err_t protocomm_unset_version(protocomm_t *pc, const char *ep_name)
Remove version verification endpoint from a protocomm instance.
This API will remove a registered version endpoint identified by an endpoint name.
参数
pc -- [in] Pointer to the protocomm instance
ep_name -- [in] Endpoint identifier(name) string
返回
ESP_OK : Success
ESP_ERR_NOT_FOUND : Endpoint with specified name doesn't exist
ESP_ERR_INVALID_ARG : Null instance/name arguments
Type Definitions
typedef esp_err_t (*protocomm_req_handler_t)(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, uint8_t **outbuf, ssize_t *outlen, void *priv_data)
Function prototype for protocomm endpoint handler.
typedef struct protocomm protocomm_t
This structure corresponds to a unique instance of protocomm returned when the API protocomm_new()
is called. The remaining Protocomm APIs require this object as the first parameter.
备注
Structure of the protocomm object is kept private
Header File
This header file can be included with:
#include "protocomm_security.h"
- This header file is a part of the API provided by the
protocomm
component. To declare that your component depends onprotocomm
, add the following to your CMakeLists.txt:
REQUIRES protocomm
or
> PRIV_REQUIRES protocomm
Structures
struct protocomm_security1_params
Protocomm Security 1 parameters: Proof Of Possession.
Public Members
const uint8_t *data
Pointer to buffer containing the proof of possession data
uint16_t len
Length (in bytes) of the proof of possession data
struct protocomm_security2_params
Protocomm Security 2 parameters: Salt and Verifier.
Public Members
const char *salt
Pointer to the buffer containing the salt
uint16_t salt_len
Length (in bytes) of the salt
const char *verifier
Pointer to the buffer containing the verifier
uint16_t verifier_len
Length (in bytes) of the verifier
struct protocomm_security
Protocomm security object structure.
The member functions are used for implementing secure protocomm sessions.
备注
This structure should not have any dynamic members to allow re-entrancy
Public Members
int ver
Unique version number of security implementation
esp_err_t (*init)(protocomm_security_handle_t *handle)
Function for initializing/allocating security infrastructure
esp_err_t (*cleanup)(protocomm_security_handle_t handle)
Function for deallocating security infrastructure
esp_err_t (*new_transport_session)(protocomm_security_handle_t handle, uint32_t session_id)
Starts new secure transport session with specified ID
esp_err_t (*close_transport_session)(protocomm_security_handle_t handle, uint32_t session_id)
Closes a secure transport session with specified ID
esp_err_t (*security_req_handler)(protocomm_security_handle_t handle, const void *sec_params, uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, uint8_t **outbuf, ssize_t *outlen, void *priv_data)
Handler function for authenticating connection request and establishing secure session
esp_err_t (*encrypt)(protocomm_security_handle_t handle, uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, uint8_t **outbuf, ssize_t *outlen)
Function which implements the encryption algorithm
esp_err_t (*decrypt)(protocomm_security_handle_t handle, uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, uint8_t **outbuf, ssize_t *outlen)
Function which implements the decryption algorithm
Type Definitions
typedef struct protocomm_security1_params protocomm_security1_params_t
Protocomm Security 1 parameters: Proof Of Possession.
typedef protocomm_security1_params_t protocomm_security_pop_t
typedef struct protocomm_security2_params protocomm_security2_params_t
Protocomm Security 2 parameters: Salt and Verifier.
typedef void *protocomm_security_handle_t
typedef struct protocomm_security protocomm_security_t
Protocomm security object structure.
The member functions are used for implementing secure protocomm sessions.
备注
This structure should not have any dynamic members to allow re-entrancy
Enumerations
enum protocomm_security_session_event_t
Events generated by the protocomm security layer.
These events are generated while establishing secured session.
Values:
enumerator PROTOCOMM_SECURITY_SESSION_SETUP_OK
Secured session established successfully
enumerator PROTOCOMM_SECURITY_SESSION_INVALID_SECURITY_PARAMS
Received invalid (NULL) security parameters (username / client public-key)
enumerator PROTOCOMM_SECURITY_SESSION_CREDENTIALS_MISMATCH
Received incorrect credentials (username / PoP)
Header File
This header file can be included with:
#include "protocomm_security0.h"
- This header file is a part of the API provided by the
protocomm
component. To declare that your component depends onprotocomm
, add the following to your CMakeLists.txt:
REQUIRES protocomm
or
> PRIV_REQUIRES protocomm
Header File
This header file can be included with:
#include "protocomm_security1.h"
- This header file is a part of the API provided by the
protocomm
component. To declare that your component depends onprotocomm
, add the following to your CMakeLists.txt:
REQUIRES protocomm
or
> PRIV_REQUIRES protocomm
Header File
This header file can be included with:
#include "protocomm_security2.h"
- This header file is a part of the API provided by the
protocomm
component. To declare that your component depends onprotocomm
, add the following to your CMakeLists.txt:
REQUIRES protocomm
or
> PRIV_REQUIRES protocomm
Header File
This header file can be included with:
#include "esp_srp.h"
- This header file is a part of the API provided by the
protocomm
component. To declare that your component depends onprotocomm
, add the following to your CMakeLists.txt:
REQUIRES protocomm
or
> PRIV_REQUIRES protocomm
Functions
esp_srp_handle_t *esp_srp_init(esp_ng_type_t ng)
Initialize srp context for given NG type.
备注
the handle gets freed with esp_srp_free
参数
ng -- NG type given by esp_ng_type_t
返回
esp_srp_handle_t* srp handle
void esp_srp_free(esp_srp_handle_t *hd)
free esp_srp_context
参数
hd -- handle to be free
esp_err_t esp_srp_srv_pubkey(esp_srp_handle_t *hd, const char *username, int username_len, const char *pass, int pass_len, int salt_len, char **bytes_B, int *len_B, char **bytes_salt)
Returns B (pub key) and salt. [Step2.b].
备注
*bytes_B MUST NOT BE FREED BY THE CALLER
备注
*bytes_salt MUST NOT BE FREE BY THE CALLER
参数
hd -- esp_srp handle
username -- Username not expected NULL terminated
username_len -- Username length
pass -- Password not expected to be NULL terminated
pass_len -- Pasword length
salt_len -- Salt length
bytes_B -- Public Key returned
len_B -- Length of the public key
bytes_salt -- Salt bytes generated
返回
esp_err_t ESP_OK on success, appropriate error otherwise
esp_err_t esp_srp_gen_salt_verifier(const char *username, int username_len, const char *pass, int pass_len, char **bytes_salt, int salt_len, char **verifier, int *verifier_len)
Generate salt-verifier pair, given username, password and salt length.
备注
if API has returned ESP_OK, salt and verifier generated need to be freed by caller
备注
Usually, username and password are not saved on the device. Rather salt and verifier are generated outside the device and are embedded. this covenience API can be used to generate salt and verifier on the fly for development use case. OR for devices which intentionally want to generate different password each time and can send it to the client securely. e.g., a device has a display and it shows the pin
参数
username -- [in] username
username_len -- [in] length of the username
pass -- [in] password
pass_len -- [in] length of the password
bytes_salt -- [out] generated salt on successful generation, or NULL
salt_len -- [in] salt length
verifier -- [out] generated verifier on successful generation, or NULL
verifier_len -- [out] length of the generated verifier
返回
esp_err_t ESP_OK on success, appropriate error otherwise
esp_err_t esp_srp_set_salt_verifier(esp_srp_handle_t *hd, const char *salt, int salt_len, const char *verifier, int verifier_len)
Set the Salt and Verifier pre-generated for a given password. This should be used only if the actual password is not available. The public key can then be generated using esp_srp_srv_pubkey_from_salt_verifier() and not esp_srp_srv_pubkey()
参数
hd -- esp_srp_handle
salt -- pre-generated salt bytes
salt_len -- length of the salt bytes
verifier -- pre-generated verifier
verifier_len -- length of the verifier bytes
返回
esp_err_t ESP_OK on success, appropriate error otherwise
esp_err_t esp_srp_srv_pubkey_from_salt_verifier(esp_srp_handle_t *hd, char **bytes_B, int *len_B)
Returns B (pub key)[Step2.b] when the salt and verifier are set using esp_srp_set_salt_verifier()
备注
*bytes_B MUST NOT BE FREED BY THE CALLER
参数
hd -- esp_srp handle
bytes_B -- Key returned to the called
len_B -- Length of the key returned
返回
esp_err_t ESP_OK on success, appropriate error otherwise
esp_err_t esp_srp_get_session_key(esp_srp_handle_t *hd, char *bytes_A, int len_A, char **bytes_key, uint16_t *len_key)
Get session key in *bytes_key
given by len in *len_key
. [Step2.c].
This calculated session key is used for further communication given the proofs are exchanged/authenticated with esp_srp_exchange_proofs
备注
*bytes_key MUST NOT BE FREED BY THE CALLER
参数
hd -- esp_srp handle
bytes_A -- Private Key
len_A -- Private Key length
bytes_key -- Key returned to the caller
len_key -- length of the key in *bytes_key
返回
esp_err_t ESP_OK on success, appropriate error otherwise
esp_err_t esp_srp_exchange_proofs(esp_srp_handle_t *hd, char *username, uint16_t username_len, char *bytes_user_proof, char *bytes_host_proof)
Complete the authentication. If this step fails, the session_key exchanged should not be used.
This is the final authentication step in SRP algorithm [Step4.1, Step4.b, Step4.c]
参数
hd -- esp_srp handle
username -- Username not expected NULL terminated
username_len -- Username length
bytes_user_proof -- param in
bytes_host_proof -- parameter out (should be SHA512_DIGEST_LENGTH) bytes in size
返回
esp_err_t ESP_OK if user's proof is ok and subsequently bytes_host_proof is populated with our own proof.
Type Definitions
typedef struct esp_srp_handle esp_srp_handle_t
esp_srp handle as the result of esp_srp_init
The handle is returned by esp_srp_init
on successful init. It is then passed for subsequent API calls as an argument. esp_srp_free
can be used to clean up the handle. After esp_srp_free
the handle becomes invalid.
Enumerations
enum esp_ng_type_t
Large prime+generator to be used for the algorithm.
Values:
enumerator ESP_NG_3072
Header File
This header file can be included with:
#include "protocomm_httpd.h"
- This header file is a part of the API provided by the
protocomm
component. To declare that your component depends onprotocomm
, add the following to your CMakeLists.txt:
REQUIRES protocomm
or
> PRIV_REQUIRES protocomm
Functions
esp_err_t protocomm_httpd_start(protocomm_t *pc, const protocomm_httpd_config_t *config)
Start HTTPD protocomm transport.
This API internally creates a framework to allow endpoint registration and security configuration for the protocomm.
备注
This is a singleton. ie. Protocomm can have multiple instances, but only one instance can be bound to an HTTP transport layer.
参数
pc -- [in] Protocomm instance pointer obtained from protocomm_new()
config -- [in] Pointer to config structure for initializing HTTP server
返回
ESP_OK : Success
ESP_ERR_INVALID_ARG : Null arguments
ESP_ERR_NOT_SUPPORTED : Transport layer bound to another protocomm instance
ESP_ERR_INVALID_STATE : Transport layer already bound to this protocomm instance
ESP_ERR_NO_MEM : Memory allocation for server resource failed
ESP_ERR_HTTPD_* : HTTP server error on start
esp_err_t protocomm_httpd_stop(protocomm_t *pc)
Stop HTTPD protocomm transport.
This API cleans up the HTTPD transport protocomm and frees all the handlers registered with the protocomm.
参数
pc -- [in] Same protocomm instance that was passed to protocomm_httpd_start()
返回
ESP_OK : Success
ESP_ERR_INVALID_ARG : Null / incorrect protocomm instance pointer
Unions
union protocomm_httpd_config_data_t
#include <protocomm_httpd.h>
Protocomm HTTPD Configuration Data
Public Members
void *handle
HTTP Server Handle, if ext_handle_provided is set to true
protocomm_http_server_config_t config
HTTP Server Configuration, if a server is not already active
Structures
struct protocomm_http_server_config_t
Config parameters for protocomm HTTP server.
Public Members
uint16_t port
Port on which the HTTP server will listen
size_t stack_size
Stack size of server task, adjusted depending upon stack usage of endpoint handler
unsigned task_priority
Priority of server task
struct protocomm_httpd_config_t
Config parameters for protocomm HTTP server.
Public Members
bool ext_handle_provided
Flag to indicate of an external HTTP Server Handle has been provided. In such as case, protocomm will use the same HTTP Server and not start a new one internally.
protocomm_httpd_config_data_t data
Protocomm HTTPD Configuration Data
Macros
PROTOCOMM_HTTPD_DEFAULT_CONFIG()
Header File
This header file can be included with:
#include "protocomm_ble.h"
- This header file is a part of the API provided by the
protocomm
component. To declare that your component depends onprotocomm
, add the following to your CMakeLists.txt:
REQUIRES protocomm
or
> PRIV_REQUIRES protocomm
Functions
esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *config)
Start Bluetooth Low Energy based transport layer for provisioning.
Initialize and start required BLE service for provisioning. This includes the initialization for characteristics/service for BLE.
参数
pc -- [in] Protocomm instance pointer obtained from protocomm_new()
config -- [in] Pointer to config structure for initializing BLE
返回
ESP_OK : Success
ESP_FAIL : Simple BLE start error
ESP_ERR_NO_MEM : Error allocating memory for internal resources
ESP_ERR_INVALID_STATE : Error in ble config
ESP_ERR_INVALID_ARG : Null arguments
esp_err_t protocomm_ble_stop(protocomm_t *pc)
Stop Bluetooth Low Energy based transport layer for provisioning.
Stops service/task responsible for BLE based interactions for provisioning
备注
You might want to optionally reclaim memory from Bluetooth. Refer to the documentation of esp_bt_mem_release
in that case.
参数
pc -- [in] Same protocomm instance that was passed to protocomm_ble_start()
返回
ESP_OK : Success
ESP_FAIL : Simple BLE stop error
ESP_ERR_INVALID_ARG : Null / incorrect protocomm instance
Structures
struct name_uuid
This structure maps handler required by protocomm layer to UUIDs which are used to uniquely identify BLE characteristics from a smartphone or a similar client device.
Public Members
const char *name
Name of the handler, which is passed to protocomm layer
uint16_t uuid
UUID to be assigned to the BLE characteristic which is mapped to the handler
struct protocomm_ble_event_t
Structure for BLE events in Protocomm.
Public Members
uint16_t evt_type
This field indicates the type of BLE event that occurred.
uint16_t conn_handle
The handle of the relevant connection.
uint16_t conn_status
The status of the connection attempt; o 0: the connection was successfully established. o BLE host error code: the connection attempt failed for the specified reason.
uint16_t disconnect_reason
Return code indicating the reason for the disconnect.
struct protocomm_ble_config
Config parameters for protocomm BLE service.
Public Members
char device_name[MAX_BLE_DEVNAME_LEN + 1]
BLE device name being broadcast at the time of provisioning
uint8_t service_uuid[BLE_UUID128_VAL_LENGTH]
128 bit UUID of the provisioning service
uint8_t *manufacturer_data
BLE device manufacturer data pointer in advertisement
ssize_t manufacturer_data_len
BLE device manufacturer data length in advertisement
ssize_t nu_lookup_count
Number of entries in the Name-UUID lookup table
protocomm_ble_name_uuid_t *nu_lookup
Pointer to the Name-UUID lookup table
unsigned ble_bonding
BLE bonding
unsigned ble_sm_sc
BLE security flag
unsigned ble_link_encryption
BLE security flag
Macros
MAX_BLE_DEVNAME_LEN
BLE device name cannot be larger than this value 31 bytes (max scan response size) - 1 byte (length) - 1 byte (type) = 29 bytes
BLE_UUID128_VAL_LENGTH
MAX_BLE_MANUFACTURER_DATA_LEN
Theoretically, the limit for max manufacturer length remains same as BLE device name i.e. 31 bytes (max scan response size) - 1 byte (length) - 1 byte (type) = 29 bytes However, manufacturer data goes along with BLE device name in scan response. So, it is important to understand the actual length should be smaller than (29 - (BLE device name length) - 2).
Type Definitions
typedef struct name_uuid protocomm_ble_name_uuid_t
This structure maps handler required by protocomm layer to UUIDs which are used to uniquely identify BLE characteristics from a smartphone or a similar client device.
typedef struct protocomm_ble_config protocomm_ble_config_t
Config parameters for protocomm BLE service.
Enumerations
enum protocomm_transport_ble_event_t
Events generated by BLE transport.
These events are generated when the BLE transport is paired and disconnected.
Values:
enumerator PROTOCOMM_TRANSPORT_BLE_CONNECTED
enumerator PROTOCOMM_TRANSPORT_BLE_DISCONNECTED