使用 wolfSSL 進行 TLS 連線

Azure 球體 SDK 包含一個 wolfSSL 文檔庫子集,用於傳輸層安全性 (TLS) ,高層級應用程式可以使用它來建立安全的 TLS 連線。

WolfSSL API 參考提供 WolfSSL API 的詳盡檔,以及許多範例。 Azure 球體支援 API 子集 ,可確保二進位相容性。

使用 wolfSSL 文件庫的應用程式需求

使用 wolfSSL 文件庫的應用程式必須包含必要的頁首檔案和組建設定。

WolfSSL TLS API 不需要應用程式指令清單中的功能。 不過,如果應用程式連線到因特網端點,應用程式指令清單必須包含連線的相關信息。 如需啟用連線的詳細數據,請參閱 連線到 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 球體 SDK 支援用戶端 wolfSSL TLS,使用 Microsoft 提供的用戶端憑證或憑證或您的選擇。 Azure 球體 SDK 僅使用您選擇的憑證來支援伺服器端 wolfSSL TLS。 值得注意的不支援案例包括:

  • 只有 WolfSSL 用戶端 TLS 連線受 Microsoft 提供的客戶端憑證支援。 伺服器端 TLS 連線無法使用 Microsoft 提供的客戶端憑證。

  • 應用程式可以使用內建的 wolfSSL TLS 支援,或在另一個 WolfSSL 文件庫實作中使用和連結。 不過,不支援與其他 WolfSSL 文件庫混合使用內建支援。

在 Azure 球體中使用 wolfSSL

高階 Azure 球體應用程式可以使用 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 球體伺服器的內送連線。

    // 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 球體平臺上 WolfSSL 功能的範例,請參 閱WolfSSL_HighLevelApp