安全套接字库 - FreeRTOS
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

安全套接字库

概述

您可以使用 FreeRTOS 安全套接字库来创建安全通信的嵌入式应用程序。该库旨在使来自各种网络编程背景的软件开发人员能够轻松掌握。

FreeRTOS 安全套接字库基于 Berkeley 套接字接口,并具有通过 TLS 协议进行安全通信的额外选项。有关 FreeRTOS 安全套接字库和 Berkeley 套接字接口之间的差异的信息,请参阅安全套接字 API 参考中的 SOCKETS_SetSockOpt

注意

目前,FreeRTOS 安全套接字仅支持客户端 API。

依赖项和要求

FreeRTOS 安全套接字库依赖于 TCP/IP 堆栈和 TLS 实现。FreeRTOS 的端口通过三种方式之一来满足这些依赖项:

  • TCP/IP 和 TLS 的自定义实现

  • TCP/I 的自定义实现,以及带 mbedTLS 的 FreeRTOS TLS 层

  • FreeRTOS+TCP 以及带 mbedTLS 的 FreeRTOS TLS 层

以下依赖项图显示了 FreeRTOS 安全套接字库附带的参考实施。此参考实施通过以太网和 Wi-Fi 支持 TLS 和 TCP/IP,并将 FreeRTOS+TCP 和 mbedTLS 作为依赖项。有关 FreeRTOS TLS 层的更多信息,请参阅传输层安全

功能

FreeRTOS 安全套接字库的功能包括:

  • 一个基于 Berkeley 套接字的标准接口

  • 用于发送和接收数据的线程安全的 API

  • 易于启用的 TLS

故障排除

错误代码

FreeRTOS 安全套接字库返回的错误代码为负值。有关每个错误代码的更多信息,请参阅安全套接字 API 参考中的安全套接字错误代码。

注意

如果 FreeRTOS 安全套接字 API 返回错误代码,则 MQTT 库,版本 1.0.0(依赖于 FreeRTOS 安全套接字库)返回错误代码 AWS_IOT_MQTT_SEND_ERROR

开发人员支持

FreeRTOS 安全套接字库包含两个用于处理 IP 地址的辅助标记宏:

SOCKETS_inet_addr_quick

此宏将表示为四个独立数字八位字节的 IP 地址转换为按网络字节顺序表示为 32 位数字的 IP 地址。

SOCKETS_inet_ntoa

此宏将按网络字节顺序表示为 32 位数字的 IP 地址转换为用十进制表示的字符串。

使用限制

FreeRTOS 安全套接字库仅支持 TCP 套接字。不支持 UDP 套接字。

FreeRTOS 安全套接字库仅支持客户端 API。不支持服务器 API,包括 BindAcceptListen

初始化

要使用 FreeRTOS 安全套接字库,您需要初始化该库及其依赖项。要初始化安全套接字库,请在应用程序中使用以下代码:

BaseType_t xResult = pdPASS; xResult = SOCKETS_Init();

必须单独初始化相关库。例如,如果 FreeRTOS+TCP 是一个依赖项,则您还需要在应用程序中调用 FreeRTOS_IPInit

API 参考

有关完整 API 参考,请参阅安全套接字 API 参考

示例用法

以下代码可将客户端连接到服务器。

#include "aws_secure_sockets.h" #define configSERVER_ADDR0 127 #define configSERVER_ADDR1 0 #define configSERVER_ADDR2 0 #define configSERVER_ADDR3 1 #define configCLIENT_PORT 443 /* Rx and Tx timeouts are used to ensure the sockets do not wait too long for * missing data. */ static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 2000 ); static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 2000 ); /* PEM-encoded server certificate */ /* The certificate used below is one of the Amazon Root CAs.\ Change this to the certificate of your choice. */ static const char cTlsECHO_SERVER_CERTIFICATE_PEM[] = "-----BEGIN CERTIFICATE-----\n" "MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5\n" "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n" "Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG\n" "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg\n" "Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl\n" "ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j\n" "QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr\n" "ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr\n" "BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM\n" "YyRIHN8wfdVoOw==\n" "-----END CERTIFICATE-----\n"; static const uint32_t ulTlsECHO_SERVER_CERTIFICATE_LENGTH = sizeof( cTlsECHO_SERVER_CERTIFICATE_PEM ); void vConnectToServerWithSecureSocket( void ) { Socket_t xSocket; SocketsSockaddr_t xEchoServerAddress; BaseType_t xTransmitted, lStringLength; xEchoServerAddress.usPort = SOCKETS_htons( configCLIENT_PORT ); xEchoServerAddress.ulAddress = SOCKETS_inet_addr_quick( configSERVER_ADDR0, configSERVER_ADDR1, configSERVER_ADDR2, configSERVER_ADDR3 ); /* Create a TCP socket. */ xSocket = SOCKETS_Socket( SOCKETS_AF_INET, SOCKETS_SOCK_STREAM, SOCKETS_IPPROTO_TCP ); configASSERT( xSocket != SOCKETS_INVALID_SOCKET ); /* Set a timeout so a missing reply does not cause the task to block indefinitely. */ SOCKETS_SetSockOpt( xSocket, 0, SOCKETS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); SOCKETS_SetSockOpt( xSocket, 0, SOCKETS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) ); /* Set the socket to use TLS. */ SOCKETS_SetSockOpt( xSocket, 0, SOCKETS_SO_REQUIRE_TLS, NULL, ( size_t ) 0 ); SOCKETS_SetSockOpt( xSocket, 0, SOCKETS_SO_TRUSTED_SERVER_CERTIFICATE, cTlsECHO_SERVER_CERTIFICATE_PEM, ulTlsECHO_SERVER_CERTIFICATE_LENGTH ); if( SOCKETS_Connect( xSocket, &xEchoServerAddress, sizeof( xEchoServerAddress ) ) == 0 ) { /* Send the string to the socket. */ xTransmitted = SOCKETS_Send( xSocket, /* The socket receiving. */ ( void * )"some message", /* The data being sent. */ 12, /* The length of the data being sent. */ 0 ); /* No flags. */ if( xTransmitted < 0 ) { /* Error while sending data */ return; } SOCKETS_Shutdown( xSocket, SOCKETS_SHUT_RDWR ); } else { //failed to connect to server } SOCKETS_Close( xSocket ); }

有关完整示例,请参阅安全套接字 Echo 客户端演示

移植

FreeRTOS 安全套接字依赖于 TCP/IP 堆栈和 TLS 实施。根据您的堆栈,要移植安全套接字库,您可能需要移植以下项目中的部分项目:

有关移植的更多信息,请参阅 FreeRTOS 移植指南中的移植安全套接字库