WolfSSL gebruiken voor TLS-verbindingen

De Azure Sphere SDK bevat een subset van de wolfSSL-bibliotheek voor TLS (Transport Layer Security), die toepassingen op hoog niveau kunnen gebruiken om beveiligde TLS-verbindingen te maken.

De wolfSSL API-verwijzing biedt uitgebreide documentatie van de wolfSSL-API, samen met vele voorbeelden. Azure Sphere ondersteunt een subset van de API die binaire compatibiliteit garandeert.

Vereisten voor toepassingen die gebruikmaken van de wolfSSL-bibliotheek

Toepassingen die gebruikmaken van de wolfSSL-bibliotheek moeten de benodigde headerbestanden en buildconfiguratie bevatten.

De wolfSSL TLS API vereist geen mogelijkheden in het toepassingsmanifest. Als de toepassing echter verbinding maakt met een interneteindpunt, moet het toepassingsmanifest informatie over de verbinding bevatten. Zie Verbinding maken met webservices voor meer informatie over het inschakelen van connectiviteit.

Koptekstbestanden

Toepassingen die gebruikmaken van de wolfSSL-API moeten het ssl.h headerbestand bevatten en kunnen een of meer extra headerbestanden vereisen, afhankelijk van de wolfSSL-functies die worden gebruikt:

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

Raadpleeg de wolfSSL-documentatie om te bepalen welke headerbestanden uw toepassing nodig heeft.

Configuratie bouwen

Als u een toepassing wilt bouwen met ondersteuning voor wolfSSL TLS API, bewerkt u de CMakePresets.json- en CMakeLists.txt-bestanden om respectievelijk de doel-API-set op te geven en de wolfSSL-bibliotheek te koppelen.

  1. Stel de TARGET_API_SET in CMakePresets.json in op 6 of hoger.

    "AZURE_SPHERE_TARGET_API_SET": "6"
    
  2. Voeg toe wolfssl aan de lijst met target_link_libraries in CMakeLists.txt om de wolfSSL-bibliotheek te koppelen aan het project:

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

Ondersteunde functies

De Azure Sphere SDK ondersteunt wolfSSL TLS aan de clientzijde met behulp van een door Microsoft opgegeven clientcertificaat of een certificaat of uw keuze. De Azure Sphere SDK ondersteunt wolfSSL TLS aan de serverzijde met alleen een certificaat van uw keuze. Belangrijke niet-ondersteunde scenario's zijn:

  • Alleen tls-verbindingen aan de clientzijde van wolfSSL worden ondersteund met het door Microsoft verstrekte clientcertificaat. TLS-verbindingen aan de serverzijde kunnen het door Microsoft opgegeven clientcertificaat niet gebruiken.

  • Een toepassing kan de ingebouwde ondersteuning voor wolfSSL TLS gebruiken of een koppeling gebruiken in een andere wolfSSL-bibliotheek-implementatie. Gemengd gebruik van de ingebouwde ondersteuning met een andere wolfSSL-bibliotheek wordt echter niet ondersteund.

wolfSSL gebruiken in Azure Sphere

Azure Sphere-toepassingen op hoog niveau kunnen wolfSSL gebruiken om een TLS-verbinding te maken en te communiceren. Toepassingen moeten doorgaans een combinatie van de technieken gebruiken om deze verbindingen te maken en te communiceren.

Opmerking

Voor verbeterde beveiliging moeten toepassingen wolfSSL_CTX_set_verify() gebruiken om de host te valideren. Zie de wolfSSL-documentatie voor meer informatie.

WolfSSL initialiseren voor client-TLS-verbindingen

Als u een TLS-verbinding met wolfSSL wilt maken, moet de toepassing eerst de bibliotheek en de SSL-context (CTX) initialiseren, zoals in het volgende codefragment:

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

Het certificaat laden

Nadat wolfSSL is geïnitialiseerd, kan het een certificaat laden voor gebruik met de TLS-verbinding. U kunt het certificaat opnemen in het installatiekopieënpakket van de toepassing, zoals beschreven in CA-certificaten toevoegen aan het installatiekopieënpakket.

In het volgende voorbeeld ziet u hoe een app Storage_GetAbsolutePathInImagePackage kan gebruiken om het pad naar een clientcertificaat op te halen dat deel uitmaakt van het toepassingsinstallatiekopieënpakket en vervolgens wolfSSL_CTX_load_verify_locations aanroept om het certificaat in wolfSSL te laden. Houd er rekening mee dat de app het storage.h headerbestand moet bevatten om Storage_GetAbsolutePathInImagePackage te gebruiken.

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

Een verbinding aan de clientzijde maken

Nadat het certificaat is geladen, kan de app de TLS-verbinding tot stand brengen. Deze stap omvat het maken van een SSL-object, het koppelen aan een socketdescriptor en vervolgens het maken van de verbinding, zoals in dit voorbeeld:

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

Gegevens lezen en schrijven vanuit de verbinding

Voor het schrijven en lezen van gegevens vanuit de verbinding kan de toepassing respectievelijk wolfSSL_write en wolfSSL_read gebruiken, zoals in het volgende voorbeeld wordt weergegeven. In dit voorbeeld bevat het schrijven naar de server een standaard HTTP/1.1-aanvraag om de inhoud van de pagina op te halen. De documentatie op HTTP/1.1: Request (w3.org) biedt een goed overzicht van deze structuur. Houd er echter rekening mee dat dit document is vervangen en dat u meer details over de aanvraagstructuur kunt vinden in de vervangende RFC 9110: HTTP Semantics (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 initialiseren voor verbindingen aan de serverzijde

Als u een TLS-server met wolfSSL wilt maken, moet de toepassing eerst de bibliotheek en de SSL-context (CTX) initialiseren, zoals in het volgende codefragment:

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

Binnenkomende verbindingen accepteren met behulp van wolfSSL TLS-server

Accepteer binnenkomende verbindingen van een client naar de 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;
    }

Cleanup

Wanneer de toepassing is voltooid met behulp van de verbinding, moeten de gerelateerde resources worden vrijgemaakt.

    free(certificatePath);

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

Monster

Zie WolfSSL_HighLevelApp voor een voorbeeld van de WolfSSL-functionaliteit op het Azure Sphere-platform.