将 wolfSSL 用于 TLS 连接

Azure Sphere SDK 包括一部分 wolfSSL 库,用于传输层安全性 (TLS) ,高级应用程序可以使用这些库来创建安全的 TLS 连接。

wolfSSL API 参考提供了 wolfSSL API 的完整文档以及许多示例。 Azure Sphere 支持确保二进制兼容性 的 API 子集

使用 wolfSSL 库的应用程序的要求

使用 wolfSSL 库的应用程序必须包含必要的头文件和生成配置。

wolfSSL TLS API 不需要应用程序清单中的功能。 但是,如果应用程序连接到 Internet 终结点,则应用程序清单必须包含有关连接的信息。 有关启用连接的更多详细信息,请参阅 连接到 Web 服务

头文件

使用 wolfSSL API 的应用程序必须包含 ssl.h 头文件,并且可能需要一个或多个附加的头文件,具体取决于使用的 wolfSSL 功能:

#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/ssl.h>

请参阅 wolfSSL 文档,确定应用程序需要哪些头文件。

生成配置

若要生成支持 wolfSSL TLS API 的应用程序,请分别编辑CMakePresets.json和 CMakeLists.txt 文件以指定目标 API 集,并链接 wolfSSL 库。

  1. 将 CMakePresets.json 中的TARGET_API_SET设置为 6 或更大。

    "AZURE_SPHERE_TARGET_API_SET": "6"
    
  2. 将 添加到 wolfssl CMakeLists.txt 中的target_link_libraries列表,以将 wolfSSL 库链接到项目中:

    target_link_libraries(${PROJECT_NAME} applibs pthread gcc_s c wolfssl)
    

支持的功能

Azure Sphere SDK 使用 Microsoft 提供的客户端证书、证书或你选择的证书支持客户端 wolfSSL TLS。 Azure Sphere SDK 仅支持使用所选证书的服务器端 wolfSSL TLS。 值得注意的不受支持的方案包括:

  • Microsoft 提供的客户端证书仅支持 wolfSSL 客户端 TLS 连接。 服务器端 TLS 连接无法使用 Microsoft 提供的客户端证书。

  • 应用程序可以使用内置的 wolfSSL TLS 支持,也可以在其他 wolfSSL 库实现中使用 和 链接。 但是,不支持将内置支持与另一个 wolfSSL 库混合使用。

在 Azure Sphere 中使用 wolfSSL

高级 Azure Sphere 应用程序可以使用 wolfSSL 通过 TLS 连接创建和通信。 应用程序通常必须结合使用这些技术来创建这些连接并通过这些连接进行通信。

注意

为了增强安全性,应用程序应使用 wolfSSL_CTX_set_verify () 来验证主机。 有关详细信息,请参阅 wolfSSL 文档

为客户端 TLS 连接初始化 wolfSSL

若要使用 wolfSSL 创建 TLS 连接,应用程序首先必须初始化库和 SSL 上下文 (CTX) ,如以下代码片段所示:

    // Configure the wolfSSL library

    if (wolfSSL_Init() != WOLFSSL_SUCCESS) {
        Log_Debug("Error initializing wolfSSL library.\n");
        goto cleanupLabel;
    }

    // Configure wolfSSL CTX functionality

    WOLFSSL_METHOD *wolfSslMethod = wolfTLSv1_3_client_method();
    if (wolfSslMethod == NULL) {
        Log_Debug("Unable to allocate TLS v1.3 method.\n");
        goto cleanupLabel;
    }

    WOLFSSL_CTX *wolfSslCtx = wolfSSL_CTX_new(wolfSslMethod);
    if (wolfSslCtx == NULL) {
        Log_Debug("Unable get create SSL context.\n");
        goto cleanupLabel;
    }

加载证书

初始化 wolfSSL 后,它可以加载用于 TLS 连接的证书。 可以将证书包含在应用程序映像包中,如 将 CA 证书添加到映像包中所述。

以下示例演示应用如何使用 Storage_GetAbsolutePathInImagePackage 获取属于应用程序映像包的客户端证书的路径,然后调用 wolfSSL_CTX_load_verify_locations 将证书加载到 wolfSSL 中。 请注意,应用必须包含 storage.h 头文件才能使用 Storage_GetAbsolutePathInImagePackage

   #include <applibs/storage.h>
   ...

    // Get the full path to the certificate file used to authenticate the HTTPS server identity.
    // The .pem file is the certificate that is used to verify the
    // server identity.

    certificatePath = Storage_GetAbsolutePathInImagePackage("certs/YourDesiredCert.pem");
    if (certificatePath == NULL) {
        Log_Debug("The certificate path could not be resolved: errno=%d (%s)\n", errno,
                  strerror(errno));
        goto cleanupLabel;
    }

    // Load the client certificate into wolfSSL
    if (wolfSSL_CTX_load_verify_locations(ctx, certificatePath, NULL) != WOLFSSL_SUCCESS) {
        Log_Debug("Error loading certificate.\n");
        goto cleanupLabel;
    }

创建客户端连接

加载证书后,应用可以建立 TLS 连接。 此步骤涉及创建 SSL 对象,将其与套接字描述符相关联,然后创建连接,如以下示例所示:

    // Create the SSL object
    if ((ssl = wolfSSL_new(ctx)) == NULL) {
        Log_Debug("Error creating final SSL object.\n");
        goto cleanupLabel;
    }

    // Attach the socket file descriptor to wolfSSL
    if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
        Log_Debug("Error attaching socket fd to wolfSSL.\n");
        goto cleanupLabel;
    }

    // Call Connect for incoming connections
    if (wolfSSL_connect(ssl) != WOLFSSL_SUCCESS) {
        Log_Debug("Error establishing TLS connection to host.\n");
        goto cleanupLabel;
    }

从连接读取和写入数据

若要从连接中写入和读取数据,应用程序可以分别使用 wolfSSL_writewolfSSL_read,如以下示例所示。 在此示例中,写入服务器包含检索页面内容的标准 HTTP/1.1 请求。 HTTP/1.1:请求 (w3.org) 中的文档提供了此结构的良好概述。 但是,请注意,本文档已被取代,你可以在其替换 RFC 9110 中找到有关请求结构的更多详细信息:HTTP 语义 (rfc-editor.org)

    sprintf(buffer, "GET / HTTP/1.1\r\nHost: example.com\r\nAccept: */*\r\n\r\n");
    ret = wolfSSL_write(ssl, buffer, (int)strlen(buffer));
    if (ret != strlen(buffer)) {
        Log_Debug("Error writing GET command to server.\n");
        goto cleanupLabel;
    }

    // Read the data back
    ret = wolfSSL_read(ssl, buffer, BUFFER_SIZE);
    if (ret == -1) {
        Log_Debug("Error reading from host.\n");
        goto cleanupLabel;
    }

    Log_Debug("Received %d bytes from host.\n", ret);
    Log_Debug("%s\n", buffer);

为服务器端连接初始化 wolfSSL

若要使用 wolfSSL 创建 TLS 服务器,应用程序必须首先初始化库和 SSL 上下文 (CTX) ,如以下代码片段所示:

// Configure wolfSSL CTX functionality
    WOLFSSL_METHOD *wolfSslMethod = wolfTLSv1_3_server_method();
    if (wolfSslMethod) == NULL) {
        Log_Debug("Unable to allocate TLS v1.3 method\n");
        goto cleanupLabel;
    }

    WOLFSSL_CTX *wolfSslCtx = wolfSSL_CTX_new(wolfSslMethod);
    if (wolfSslCtx == NULL) {
        Log_Debug("Unable to create SSL context.\n");
        goto cleanupLabel;
    }

使用 wolfSSL TLS 服务器接受传入连接

接受从客户端到 Azure Sphere 服务器的传入连接。

    // Call Accept for incoming connections
    if (wolfSSL_accept(ssl) != WOLFSSL_SUCCESS) {
        Log_Debug("Error establishing TLS connection to host.\n");
        goto cleanupLabel;
    }

清理

当应用程序使用连接完成时,它应释放相关资源。

    free(certificatePath);

    if (ssl) {
        wolfSSL_free(ssl);
    }
    if (ctx) {
        wolfSSL_CTX_free(ctx);
        wolfSSL_Cleanup();
    }

样品

有关 Azure Sphere 平台上的 WolfSSL 功能示例,请参阅 WolfSSL_HighLevelApp