Condividi tramite


Connettersi a servizi Web

Importante

Questa è la documentazione di Azure Sphere (legacy). Azure Sphere (legacy) viene ritirato il 27 settembre 2027 e gli utenti devono eseguire la migrazione ad Azure Sphere (integrato) entro questo periodo. Usare il selettore di versione posizionato sopra il sommario per visualizzare la documentazione di Azure Sphere (integrata).

Azure Sphere SDK include la libreria libcurl, utilizzabile dalle applicazioni di alto livello per connettersi ed eseguire l'autenticazione ai servizi Web HTTP e HTTPS. Sono supportate sia l'autenticazione server che l'autenticazione client, in modo che le applicazioni possano verificare di comunicare con il server previsto e provare al server la legittimità del loro dispositivo e del loro tenant di Azure Sphere. Le due funzionalità sono combinate nell'autenticazione reciproca.

Il repository di esempi per Azure Sphere in GitHub include gli esempi curl seguenti:

Anche se l'approccio sincrono all'autenticazione server in HTTPS_Curl_Easy è piuttosto semplice, le applicazioni di Azure Sphere in genere dovrebbero usare la tecnica asincrona più complessa mostrata nell'esempio HTTPS_Curl_Multi, insieme a un modello guidato dagli eventi a thread singolo basato su epoll.

Il sito Web di libcurl fornisce una documentazione completa dell'API C di libcurl e molti esempi. Le differenze tra la libreria cURL e la libreria di runtime di Azure Sphere SDK sono le seguenti:

Nome costante
(definizione)
Limiti di intervallo cURL Limiti dell'intervallo di Azure Sphere
CURLOPT_BUFFERSIZE
(dimensioni del buffer)
Impostazione predefinita: 16 KB Impostazione predefinita: 1536 KB
CURLOPT_UPLOAD_BUFFERSIZE
(dimensioni del buffer di caricamento)
Impostazione predefinita: 64 KB
Massimo: 2 MB
Minimo: 16 KB
Impostazione predefinita: 1536 KB
Massimo: 64 KB
Minimo: 1536 KB
CURLOPT_HEADERFUNCTION
(intestazione HTTP completa passata a questa funzione)
Massimo: 100 KB Massimo: 16 KB
CURLOPT_DNS_CACHE_TIMEOUT Impostazione predefinita: risultati della cache per 60 secondi
Massimo: risultati della cache per sempre
Minimo: 0 (non memorizzare nella cache i risultati)
Tutti i valori vengono sottoposti a override su 0 e i risultati non vengono memorizzati nella cache.

Requisiti per le applicazioni che usano curl

Le applicazioni che usano la libreria curl devono includere i file di intestazione appropriati e fornire le informazioni su tenant e host Internet nel manifesto dell'applicazione.

File di intestazione

Per usare curl, includere questi file di intestazione all'interno dell'applicazione:

#include <applibs/storage.h>  // required only if you supply a certificate in the image package
#include <tlsutils/deviceauth_curl.h> // required only for mutual authentication
#include <curl/curl.h>
#include <applibs/networking_curl.h>  // required only if using proxy to connect to the internet

Il file di intestazione storage.h è necessario solo se si specificano uno o più certificati nel pacchetto immagine dell'applicazione. L'intestazione deviceauth_curl.h è necessaria per eseguire l'autenticazione reciproca. L'intestazione networking_curl.h è necessaria se l'applicazione usa un proxy per connettersi a Internet.

Manifesto dell'applicazione

Il campo AllowedConnections del manifesto dell'applicazione deve specificare gli host a cui si connette l'applicazione. Deve contenere anche il nome di ogni dominio che la connessione può incontrare se reindirizzata. Ad esempio, sia microsoft.com che www.microsoft.com sono necessari per un'applicazione che si connette alla home page di Microsoft.

Se l'applicazione usa l'autenticazione reciproca, il campo DeviceAuthentication del manifesto deve includere l'ID tenant di Azure Sphere. I certificati di autenticazione del dispositivo vengono emessi solo se l'ID tenant del dispositivo corrisponde all'ID tenant nel manifesto dell'applicazione. Questa limitazione offre un meccanismo di difesa avanzato: un'applicazione in esecuzione su un dispositivo in un tenant diverso (ad esempio, quello di un altro cliente o di un'entità non autorizzata) non può eseguire l'autenticazione al server.

Se l'applicazione usa un proxy, il campo ReadNetworkProxyConfig indica se l'applicazione dispone dell'autorizzazione per recuperare la configurazione del proxy.

Durante lo sviluppo, è possibile trovare l'ID del tenant di Azure Sphere corrente usando il comando azsphere tenant show-selected.

Nell'esempio seguente il campo AllowedConnections specifica che l'applicazione si connette solo a www.example.com, il campo DeviceAuthentication specifica l'ID tenant di Azure Sphere, consentendo all'applicazione di usare il certificato del dispositivo per l'autenticazione reciproca e il campo ReadNetworkProxyConfig specifica che l'applicazione può ripristinare le informazioni di configurazione del proxy.

  "Capabilities": {
    "AllowedConnections": [ "www.example.com" ],
    "Gpio": [],
    "Uart": [],
    "WifiConfig": false,
    "DeviceAuthentication": "00000000-0000-0000-0000-000000000000",
    "ReadNetworkProxyConfig": true
  }

Funzionalità supportate

Libcurl per Azure Sphere supporta solo i protocolli HTTP e HTTPS. Inoltre, il sistema operativo Azure Sphere non supporta alcune funzionalità, come i file scrivibili (cookie) o i socket UNIX. Le funzionalità che non saranno supportate nelle versioni future di libcurl, ad esempio la famiglia mprintf(), non sono disponibili.

Libcurl per Azure Sphere supporta TLS 1.2 e TLS 1.3 e ha ritirato TLS 1.0 e TLS 1.1 in linea con la strategia di sicurezza Di Microsoft TLS più ampia.

Di seguito sono riportati i pacchetti di crittografia supportati:

  • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  • TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
  • TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
  • TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
  • TLS_DHE_RSA_WITH_AES_128_CBC_SHA256

I tentativi di usare una versione non supportata di TLS restituiscono l'errore CyaSSL does not support <version>.

Autenticazione server

Azure Sphere supporta l'autenticazione server tramite libcurl. Il certificato del server deve essere firmato da un'autorità di certificazione (CA) considerata attendibile dal dispositivo. Per permettere l'autenticazione di un server da parte di libcurl, l'applicazione deve fornire il percorso del file dell'autorità di certificazione.

Aggiungere certificati della CA al pacchetto immagine

Per usare una o più CA, è necessario aggiungere i certificati al pacchetto immagine. Ogni certificato deve essere con codifica Base64. L'approccio più semplice consiste nel creare un singolo file contenente tutti i certificati aggiuntivi. Il file deve avere .pem come estensione del file. Per aggiungere i certificati:

  1. Creare una cartella certs nella cartella del progetto per l'applicazione. La cartella del progetto contiene il file CMakeLists per l'applicazione.
  2. Nella cartella certs creare un file di testo con l'estensione pem, quindi copiare tutti i certificati nel file e salvarlo.
  3. Nel file CMakeLists.txt aggiungere il file di certificato al pacchetto immagine come file di risorse. Ad esempio:
azsphere_target_add_image_package(${PROJECT_NAME} RESOURCE_FILES "certs/DigiCertGlobalRootCA.pem")

A questo punto, il file del certificato dovrebbe essere visibile nella cartella certs nel pacchetto immagine.

Impostare le posizioni dei certificati

Nell'applicazione usare le opzioni CURLOPT_CAPATH e CURLOPT_CAINFO per impostare le posizioni dei certificati. Chiamare Storage_GetAbsolutePathInImagePackage per recuperare il percorso assoluto dei certificati nel pacchetto immagine e quindi chiamare curl_easy_setopt.

CURLOPT_CAPATH imposta una cartella predefinita per i certificati. Il codice seguente, ad esempio, indica a curl di cercare i certificati solo nella cartella certs nell'immagine:

char *path = Storage_GetAbsolutePathInImagePackage("certs");
curl_easy_setopt(curl_handle, CURLOPT_CAPATH, path);

CURLOPT_CAINFO imposta il percorso di un file che contiene uno o più certificati. Curl cerca in questo file oltre che nel set di cartelle predefinito in CURLOPT_CAPATH. Ad esempio:

char *path = Storage_GetAbsolutePathInImagePackage("CAs/mycertificates.pem");
curl_easy_setopt(curl_handle, CURLOPT_CAINFO, path);

Questo codice indica a curl di considerare attendibile tutte le autorità di certificazione definite nel file mycertificates.pem, oltre a quelle definite nella directory impostata in CURLOPT_CAPATH.

Autenticazione reciproca

L'autenticazione reciproca verifica che il server e il dispositivo client siano entrambi legittimi. Il processo si articola in più passaggi:

  1. L'applicazione autentica il server usando un certificato dell'autorità di certificazione, come descritto in Autenticazione del server.
  2. L'applicazione presenta un certificato di autenticazione client x509 al server in modo che quest'ultimo possa autenticare il dispositivo.
  3. Il server usa la catena di certificati del tenant di Azure Sphere per verificare che il dispositivo appartenga al tenant.

Un'applicazione può configurare il lato autenticazione dispositivo dell'autenticazione reciproca in uno dei due modi seguenti.

  • Configurare la funzione DeviceAuth_CurlSslFunc di Azure Sphere come funzione SSL che esegue l'autenticazione.
  • Creare una funzione SSL personalizzata che chiama la funzione DeviceAuth_SslCtxFunc di Azure Sphere per l'autenticazione.

Nota

Azure Sphere non supporta la rinegoziazione SSL/TLS.

Prima di usare una delle due funzioni, è necessario aggiornare il file CMakeLists.txt per l'applicazione per aggiungere curl e tlsutils a TARGET_LINK_LIBRARIES:

TARGET_LINK_LIBRARIES(${PROJECT_NAME} applibs pthread gcc_s c curl tlsutils)

Usare DeviceAuth_CurlSslFunc

Il modo più semplice per eseguire l'autenticazione del dispositivo consiste nel configurare DeviceAuth_CurlSslFunc come funzione di callback per l'autenticazione SSL di curl:

// Set DeviceAuth_CurlSslFunc to perform authentication
CURLcode err = curl_easy_setopt(_curl, CURLOPT_SSL_CTX_FUNCTION, DeviceAuth_CurlSslFunc);
if (err) {
	// Set ssl function failed
	return err;
}

La funzione DeviceAuth_CurlSslFunc recupera la catena di certificati per il tenant corrente di Azure Sphere e imposta la connessione curl per l'esecuzione dell'autenticazione reciproca. Se l'autenticazione non riesce, la funzione restituisce CURLE_CERTPROBLEM.

Usare DeviceAuth_SslCtxFunc

Un'applicazione può anche usare una funzione di callback SSL che chiama la funzione DeviceAuth_SslCtxFunc di Azure Sphere per l'autenticazione.

La funzione SSL personalizzata deve chiamare DeviceAuth_SslCtxFunc per eseguire l'autenticazione, ma può anche eseguire altre attività correlate. DeviceAuth_SslCtxFunc restituisce un valore dell'enumerazione DeviceAuthSslResult, che fornisce informazioni dettagliate sull'errore. Ad esempio:

static CURLcode MyCallback(CURL *curl, void *sslctx, void *userCtx)
{
    int err = DeviceAuth_SslCtxFunc(sslctx);
    Log_Debug("ssl func callback error %d\n", err);
    if (err) {
        // detailed error handling code goes here
    }
    return CURLE_OK;
}
...

err = curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, MyCallback);
    if (err) {
        goto cleanupLabel;
    }

Usare la catena di certificati del tenant sul server

Per eseguire l'autenticazione reciproca, il server deve essere in grado di verificare che il dispositivo appartenga al tenant di Azure Sphere e che il tenant stesso sia legittimo. Per eseguire questa autenticazione, il server richiede la catena di certificati del tenant di Azure Sphere, che firma tutti i dispositivi di Azure Sphere:

Per ottenere la catena di certificati per il tenant, scaricarla in un file con estensione p7b, come nell'esempio seguente:

azsphere ca-certificate download-chain --destination CA-cert-chain.p7b

È quindi possibile usare il file con estensione p7b nel server.

Ulteriori suggerimenti per l'uso di curl

Di seguito sono riportati alcuni suggerimenti aggiuntivi per l'uso di curl in un'applicazione di Azure Sphere.

  • Se si prevede di archiviare il contenuto della pagina nella RAM o nella memoria flash, tenere presente che l'archiviazione nel dispositivo Azure Sphere è limitata.

  • Per assicurarsi che curl segua i reindirizzamenti, aggiungere quanto segue al codice:

    curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
    
  • Per aggiungere informazioni dettagliate sulle operazioni di curl che possono risultare utili durante il debug:

    curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
    
  • Alcuni server restituiscono errori se una richiesta non contiene un agente utente. Per impostare un agente utente:

    curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
    
  • Quando si gestiscono curl_multi callback timer, evitare chiamate ricorsive quando il timeout segnalato è 0 ms, in quanto ciò può causare comportamenti imprevedibili. Considerare invece 0 ms come 1 ms attivando un EventLoopTimer (0ms EventLoopTimers sono ricorsivi e devono essere evitati).

    static int CurlTimerCallback(CURLM *multi, long timeoutMillis, void *unused)
    {
         // A value of -1 means the timer does not need to be started.
         if (timeoutMillis != -1) {
    
             if (timeoutMillis == 0) {
                 // We cannot queue an event for 0ms in the future (the timer never fires)
                 // So defer it very slightly (see https://curl.se/libcurl/c/multi-event.html)
                 timeoutMillis = 1;
             }
    
             // Start a single shot timer with the period as provided by cURL.
             // The timer handler will invoke cURL to process the web transfers.
             const struct timespec timeout = {.tv_sec = timeoutMillis / 1000,
                                              .tv_nsec = (timeoutMillis % 1000) * 1000000};
             SetEventLoopTimerOneShot(curlTimer, &timeout);
         }
    
         return 0;
    }