Verwenden von wolfSSL für TLS-Verbindungen

Das Azure Sphere SDK enthält eine Teilmenge der wolfSSL-Bibliothek für Transport Layer Security (TLS), die allgemeine Anwendungen verwenden können, um sichere TLS-Verbindungen zu erstellen.

Die wolfSSL-API-Referenz enthält eine ausführliche Dokumentation der wolfSSL-API sowie viele Beispiele. Azure Sphere unterstützt eine Teilmenge der API , die binäre Kompatibilität sicherstellt.

Anforderungen für Anwendungen, die die wolfSSL-Bibliothek verwenden

Anwendungen, die die wolfSSL-Bibliothek verwenden, müssen die erforderlichen Headerdateien und die Buildkonfiguration enthalten.

Die wolfSSL-TLS-API erfordert keine Funktionen im Anwendungsmanifest. Wenn die Anwendung jedoch eine Verbindung mit einem Internetendpunkt herstellt, muss das Anwendungsmanifest Informationen zur Verbindung enthalten. Weitere Informationen zum Aktivieren der Konnektivität finden Sie unter Herstellen einer Verbindung mit Webdiensten .

Headerdateien

Anwendungen, die die wolfSSL-API verwenden, müssen die ssl.h Headerdatei enthalten und benötigen je nach den verwendeten wolfSSL-Features möglicherweise eine oder mehrere zusätzliche Headerdateien:

#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>

In der wolfSSL-Dokumentation erfahren Sie, welche Headerdateien Ihre Anwendung benötigt.

Buildkonfiguration

Um eine Anwendung mit wolfSSL TLS-API-Unterstützung zu erstellen, bearbeiten Sie die CMakePresets.json- und CMakeLists.txt-Dateien, um den ZIEL-API-Satz anzugeben bzw. die wolfSSL-Bibliothek zu verknüpfen.

  1. Legen Sie die TARGET_API_SET in CMakePresets.json auf 6 oder höher fest.

    "AZURE_SPHERE_TARGET_API_SET": "6"
    
  2. Fügen Sie wolfssl der Liste der target_link_libraries in CMakeLists.txt hinzu, um die wolfSSL-Bibliothek mit dem Projekt zu verknüpfen:

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

Unterstützte Features

Das Azure Sphere SDK unterstützt clientseitige wolfSSL-TLS mithilfe eines von Microsoft bereitgestellten Clientzertifikats oder eines Zertifikats ihrer Wahl. Das Azure Sphere SDK unterstützt serverseitiges wolfSSL-TLS nur mit einem Zertifikat Ihrer Wahl. Zu den wichtigsten nicht unterstützten Szenarien gehören:

  • Nur clientseitige TLS-Verbindungen von wolfSSL werden mit dem von Microsoft bereitgestellten Clientzertifikat unterstützt. Serverseitige TLS-Verbindungen können das von Microsoft bereitgestellte Clientzertifikat nicht verwenden.

  • Eine Anwendung kann entweder die integrierte wolfSSL-TLS-Unterstützung verwenden oder eine verknüpfung in einer anderen wolfSSL-Bibliotheksimplementierung verwenden. Die gemischte Verwendung der integrierten Unterstützung mit einer anderen wolfSSL-Bibliothek wird jedoch nicht unterstützt.

Verwenden von wolfSSL in Azure Sphere

Allgemeine Azure Sphere-Anwendungen können wolfSSL verwenden, um eine TLS-Verbindung zu erstellen und zu kommunizieren. Anwendungen müssen in der Regel eine Kombination der Techniken verwenden, um diese Verbindungen zu erstellen und über diese zu kommunizieren.

Hinweis

Aus Sicherheitsgründen sollten Anwendungen wolfSSL_CTX_set_verify() verwenden, um den Host zu überprüfen. Weitere Informationen finden Sie in der wolfSSL-Dokumentation .

Initialisieren von wolfSSL für TLS-Clientverbindungen

Um eine TLS-Verbindung mit wolfSSL zu erstellen, muss die Anwendung zunächst die Bibliothek und den SSL-Kontext (CTX) initialisieren, wie im folgenden Codeausschnitt gezeigt:

    // 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;
    }

Laden des Zertifikats

Nach der Initialisierung von wolfSSL kann ein Zertifikat zur Verwendung mit der TLS-Verbindung geladen werden. Sie können das Zertifikat in das Anwendungsimagepaket einschließen, wie unter Hinzufügen von Zertifizierungsstellenzertifikaten zum Imagepaket beschrieben.

Das folgende Beispiel zeigt, wie eine App Storage_GetAbsolutePathInImagePackage verwenden kann, um den Pfad zu einem Clientzertifikat abzurufen, das Teil des Anwendungsimagepakets ist, und dann wolfSSL_CTX_load_verify_locations aufrufen kann, um das Zertifikat in wolfSSL zu laden. Beachten Sie, dass die App die storage.h Headerdatei enthalten muss, um Storage_GetAbsolutePathInImagePackage verwenden zu können.

   #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;
    }

Erstellen einer clientseitigen Verbindung

Nach dem Laden des Zertifikats kann die App die TLS-Verbindung herstellen. Dieser Schritt umfasst das Erstellen eines SSL-Objekts, das Zuordnen zu einem Socketdeskriptor und das anschließende Erstellen der Verbindung, wie in diesem Beispiel gezeigt:

    // 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;
    }

Lesen und Schreiben von Daten aus der Verbindung

Zum Schreiben und Lesen von Daten aus der Verbindung kann die Anwendung wolfSSL_write bzw. wolfSSL_read verwenden, wie im folgenden Beispiel gezeigt. In diesem Beispiel enthält der Schreibvorgang auf den Server eine HTTP/1.1-Standardanforderung zum Abrufen des Seiteninhalts. Die Dokumentation unter HTTP/1.1: Request (w3.org) bietet einen guten Überblick über diese Struktur. Beachten Sie jedoch, dass dieses Dokument abgelöst wurde und Sie weitere Details zur Anforderungsstruktur in der Ersetzung RFC 9110: HTTP-Semantik (rfc-editor.org) finden.

    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);

Initialisieren von wolfSSL für serverseitige Verbindungen

Um einen TLS-Server mit wolfSSL zu erstellen, muss die Anwendung zunächst die Bibliothek und den SSL-Kontext (CTX) initialisieren, wie im folgenden Codeausschnitt dargestellt:

// 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;
    }

Akzeptieren eingehender Verbindungen mithilfe des wolfSSL-TLS-Servers

Akzeptieren eingehender Verbindungen von einem Client zum Azure Sphere-Server.

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

Bereinigung

Wenn die Anwendung die Verbindung verwendet, sollten die zugehörigen Ressourcen freigegeben werden.

    free(certificatePath);

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

Beispiel

Ein Beispiel für die WolfSSL-Funktionalität auf der Azure Sphere-Plattform finden Sie unter WolfSSL_HighLevelApp.