Utiliser wolfSSL pour les connexions TLS

Le Kit de développement logiciel (SDK) Azure Sphere inclut un sous-ensemble de la bibliothèque wolfSSL pour la sécurité de la couche de transport (TLS), que les applications de haut niveau peuvent utiliser pour créer des connexions TLS sécurisées.

La référence de l’API wolfSSL fournit une documentation complète de l’API wolfSSL, ainsi que de nombreux exemples. Azure Sphere prend en charge un sous-ensemble de l’API qui garantit la compatibilité binaire.

Configuration requise pour les applications qui utilisent la bibliothèque wolfSSL

Les applications qui utilisent la bibliothèque wolfSSL doivent inclure les fichiers d’en-tête et la configuration de build nécessaires.

L’API TLS wolfSSL ne nécessite pas de fonctionnalités dans le manifeste de l’application. Toutefois, si l’application se connecte à un point de terminaison Internet, le manifeste de l’application doit inclure des informations sur la connexion. Pour plus d’informations sur l’activation de la connectivité, consultez Se connecter aux services web .

Fichiers d’en-tête

Les applications qui utilisent l’API wolfSSL doivent inclure le ssl.h fichier d’en-tête et peuvent nécessiter un ou plusieurs fichiers d’en-tête supplémentaires, en fonction des fonctionnalités wolfSSL utilisées :

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

Consultez la documentation wolfSSL pour déterminer les fichiers d’en-tête dont votre application a besoin.

Configuration de build

Pour créer une application avec la prise en charge de l’API TLS wolfSSL, modifiez les fichiers CMakePresets.json et CMakeLists.txt pour spécifier le jeu d’API cible et lier la bibliothèque wolfSSL, respectivement.

  1. Définissez la TARGET_API_SET dans CMakePresets.json sur 6 ou plus.

    "AZURE_SPHERE_TARGET_API_SET": "6"
    
  2. Ajoutez wolfssl à la liste des target_link_libraries dans CMakeLists.txt pour lier la bibliothèque wolfSSL au projet :

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

Fonctionnalités prises en charge

Le Kit de développement logiciel (SDK) Azure Sphere prend en charge le protocole TLS wolfSSL côté client à l’aide d’un certificat client fourni par Microsoft ou d’un certificat ou de votre choix. Le Kit de développement logiciel (SDK) Azure Sphere prend en charge wolfSSL TLS côté serveur en utilisant uniquement un certificat de votre choix. Les scénarios notables non pris en charge sont les suivants :

  • Seules les connexions TLS côté client wolfSSL sont prises en charge avec le certificat client fourni par Microsoft. Les connexions TLS côté serveur ne peuvent pas utiliser le certificat client fourni par Microsoft.

  • Une application peut utiliser la prise en charge tls wolfSSL intégrée ou utiliser et lier dans une autre implémentation de bibliothèque wolfSSL. Toutefois, l’utilisation mixte de la prise en charge intégrée avec une autre bibliothèque wolfSSL n’est pas prise en charge.

Utiliser wolfSSL dans Azure Sphere

Les applications Azure Sphere de haut niveau peuvent utiliser wolfSSL pour créer et communiquer via une connexion TLS. Les applications doivent généralement utiliser une combinaison des techniques pour créer et communiquer sur ces connexions.

Note

Pour renforcer la sécurité, les applications doivent utiliser wolfSSL_CTX_set_verify() pour valider l’hôte. Pour plus d’informations, consultez la documentation wolfSSL .

Initialiser wolfSSL pour les connexions TLS clientes

Pour créer une connexion TLS avec wolfSSL, l’application doit d’abord initialiser la bibliothèque et le contexte SSL (CTX), comme dans l’extrait de code suivant :

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

Charger le certificat

Une fois wolfSSL initialisé, il peut charger un certificat à utiliser avec la connexion TLS. Vous pouvez inclure le certificat dans le package d’image d’application, comme décrit dans Ajouter des certificats d’autorité de certification au package d’images.

L’exemple suivant montre comment une application peut utiliser Storage_GetAbsolutePathInImagePackage pour obtenir le chemin d’accès à un certificat client qui fait partie du package d’image d’application, puis appeler wolfSSL_CTX_load_verify_locations pour charger le certificat dans wolfSSL. Notez que l’application doit inclure le fichier d’en-tête storage.h pour utiliser 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;
    }

Créer une connexion côté client

Après avoir chargé le certificat, l’application peut établir la connexion TLS. Cette étape implique la création d’un objet SSL, son association à un descripteur de socket, puis la création de la connexion, comme dans cet exemple :

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

Lire et écrire des données à partir de la connexion

Pour écrire et lire des données à partir de la connexion, l’application peut utiliser wolfSSL_write et wolfSSL_read, respectivement, comme le montre l’exemple suivant. Dans cet exemple, l’écriture sur le serveur contient une requête HTTP/1.1 standard pour récupérer le contenu de la page. La documentation http/1.1 : Requête (w3.org) fournit une bonne vue d’ensemble de cette structure. Toutefois, notez que ce document a été remplacé et que vous trouverez plus d’informations sur la structure des demandes dans sa RFC 9110 de remplacement : sémantique 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);

Initialiser wolfSSL pour les connexions côté serveur

Pour créer un serveur TLS avec wolfSSL, l’application doit d’abord initialiser la bibliothèque et le contexte SSL (CTX), comme dans l’extrait de code suivant :

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

Accepter les connexions entrantes à l’aide du serveur TLS wolfSSL

Accepter les connexions entrantes d’un client vers le serveur Azure Sphere.

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

Nettoyage

Lorsque l’application a terminé l’utilisation de la connexion, elle doit libérer les ressources associées.

    free(certificatePath);

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

Échantillon

Pour obtenir un exemple de la fonctionnalité WolfSSL sur la plateforme Azure Sphere, consultez WolfSSL_HighLevelApp.