Sdílet prostřednictvím


Připojení k webovým službám

Důležité

Toto je dokumentace k Azure Sphere (starší verze). Azure Sphere (starší verze) se vyřazuje 27. září 2027 a uživatelé musí do této doby migrovat do Azure Sphere (integrované). K zobrazení dokumentace k Azure Sphere (integrované) použijte selektor verzí umístěný nad obsahem.

Sada Azure Sphere SDK obsahuje knihovnu libcurl, kterou můžou aplikace vysoké úrovně používat k připojení a ověřování pomocí webových služeb HTTP a HTTPS. Podporuje se ověřování serveru i klienta, aby aplikace mohly ověřit, že komunikují s očekávaným serverem, a můžou prokázat, že jejich zařízení a tenant Azure Sphere jsou legitimní. Vzájemné ověřování kombinuje tyto dva.

Úložiště ukázek Azure Sphere na GitHubu obsahuje následující ukázky curl:

  • HTTPS_Curl_Easy pro ověřování serveru používá synchronní (blokující) rozhraní API.
  • HTTPS_Curl_Multi ukázka používá pro ověřování serveru asynchronní (neblokující) rozhraní API.

I když synchronní přístup k ověřování serverů v HTTPS_Curl_Easy je poměrně jednoduchý, aplikace Azure Sphere by obecně měly používat složitější asynchronní techniku zobrazenou v ukázce HTTPS_Curl_Multi spolu s modelem založeným na událostech založeným na epollu.

Web libcurl poskytuje důkladnou dokumentaci k rozhraní API libcurl C a mnoho příkladů. Rozdíly mezi knihovnou cURL a knihovnou modulu runtime sady Azure Sphere SDK jsou následující:

Název konstanty
(definice)
Omezení rozsahu cURL Omezení rozsahu Azure Sphere
CURLOPT_BUFFERSIZE
(velikost vyrovnávací paměti)
Výchozí: 16 kB Výchozí: 1536 kB
CURLOPT_UPLOAD_BUFFERSIZE
(velikost vyrovnávací paměti pro nahrávání)
Výchozí: 64 kB
Maximum: 2 MB
Minimum: 16 KB
Výchozí: 1536 kB
Maximum: 64 KB
Minimum: 1536 KB
CURLOPT_HEADERFUNCTION
(kompletní hlavička HTTP předaná této funkci)
Maximum: 100 KB Maximum: 16 KB
CURLOPT_DNS_CACHE_TIMEOUT Výchozí: Výsledky mezipaměti po dobu 60 sekund
Maximum: Výsledky mezipaměti navždy
Minimum: 0 (neukánět výsledky mezipaměti)
Všechny hodnoty se přepíše na 0 a výsledky se neukládají do mezipaměti.

Požadavky pro aplikace, které používají curl

Aplikace, které používají knihovnu curl, musí obsahovat příslušné soubory hlaviček a poskytovat informace o tenantovi a hostiteli internetu v manifestu aplikace.

Soubory hlaviček

Pokud chcete použít curl, zahrňte do své aplikace tyto soubory hlaviček:

#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

Soubor hlavičky storage.h se vyžaduje pouze v případě, že do balíčku image aplikace zadáte jeden nebo více certifikátů. Hlavička deviceauth_curl.h se vyžaduje pro provádění vzájemného ověřování. Hlavička networking_curl.h se vyžaduje, pokud aplikace používá proxy server pro připojení k internetu.

Manifest aplikace

Pole AllowedConnections manifestu aplikace musí určovat hostitele, ke kterým se aplikace připojuje. Musí také obsahovat název každé domény, na kterou se připojení může při přesměrování setkat. Například aplikace microsoft.com , která se připojuje k domovské stránce Microsoftu, a www.microsoft.com jsou vyžadovány.

Pokud aplikace používá vzájemné ověřování, musí pole DeviceAuthentication manifestu obsahovat ID tenanta Azure Sphere. Certifikáty ověřování zařízení se vydávají jenom v případě, že ID tenanta zařízení odpovídá ID tenanta v manifestu aplikace. Toto omezení poskytuje hloubkovou ochranu: aplikace spuštěná na zařízení v jiném tenantovi (například u jiného zákazníka nebo neautorizované entity) se nemůže ověřit na serveru.

Pokud aplikace používá proxy server, pole ReadNetworkProxyConfig označuje, jestli má aplikace oprávnění k načtení konfigurace proxy serveru.

Během vývoje můžete id aktuálního tenanta Azure Sphere najít pomocí příkazu azsphere tenant show-selected.

V následujícím příkladu pole AllowedConnections určuje, že se aplikace připojuje pouze k www.example.com, pole DeviceAuthentication určuje ID tenanta Azure Sphere, které aplikaci umožní používat certifikát zařízení pro vzájemné ověřování, a pole ReadNetworkProxyConfig určuje, že aplikace může retrektivní informace o konfiguraci proxy serveru.

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

Podporované funkce

Libcurl pro Azure Sphere podporuje pouze protokoly HTTP a HTTPS. Kromě toho operační systém Azure Sphere nepodporuje některé funkce, jako jsou zapisovatelné soubory (soubory cookie) nebo sokety UNIX. Funkce, které nebudou podporovány v budoucích verzích libcurl, jako je řada mprintf(), nejsou k dispozici.

Libcurl pro Azure Sphere podporuje protokoly TLS 1.2 a TLS 1.3 a vyřadil protokoly TLS 1.0 a TLS 1.1 v souladu s širší strategií zabezpečení protokolu MICROSOFT TLS.

Podporované šifrovací sady jsou následující:

  • 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

Pokusy o použití nepodporované verze protokolu TLS vrátí chybu CyaSSL does not support <version>.

Ověřování serveru

Azure Sphere podporuje ověřování serveru prostřednictvím knihovny libcurl. Certifikát serveru musí být podepsaný certifikační autoritou (CA), kterou zařízení důvěřuje. Aby služba libcurl ověřila server, musí aplikace zadat cestu k souboru certifikační autority.

Přidání certifikátů certifikační autority do balíčku image

Pokud chcete použít jeden nebo více certifikačních autorit, musíte přidat certifikáty do balíčku image. Každý certifikát musí mít kódování base-64. Nejjednodušším přístupem je vytvoření jednoho souboru, který obsahuje všechny další certifikáty. Soubor musí mít příponu souboru .pem. Přidání certifikátů:

  1. Vytvořte složku certifikátů ve složce projektu pro vaši aplikaci. Složka projektu obsahuje soubor CMakeLists pro vaši aplikaci.
  2. Ve složce certs vytvořte textový soubor s příponou .pem, zkopírujte do něj každý certifikát a uložte soubor.
  3. Do souboru CMakeLists.txt přidejte soubor certifikátu do balíčku image jako soubor prostředku. Příklad:
azsphere_target_add_image_package(${PROJECT_NAME} RESOURCE_FILES "certs/DigiCertGlobalRootCA.pem")

Soubor certifikátu by se teď měl zobrazit ve složce certs v balíčku image.

Nastavení umístění certifikátů

V aplikaci nastavte umístění certifikátů pomocí možností CURLOPT_CAPATH a CURLOPT_CAINFO . Voláním Storage_GetAbsolutePathInImagePackage načtěte absolutní cestu k certifikátům v balíčku image a pak volejte curl_easy_setopt.

CURLOPT_CAPATH nastaví výchozí složku pro certifikáty. Například následující kód říká curl, aby hledal certifikáty ve složce certs na obrázku:

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

CURLOPT_CAINFO nastaví cestu k souboru, který obsahuje jeden nebo více certifikátů. Curl prohledá tento soubor kromě výchozí složky nastavené v CURLOPT_CAPATH. Například:

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

Tento kód říká curl, aby důvěřoval všem certifikačním autoritám definovaným v souboru mycertificates.pem a také certifikačním autoritám definovaným v adresáři nastaveným v CURLOPT_CAPATH.

Vzájemné ověřování

Vzájemné ověřování ověřuje, že server i klientské zařízení jsou legitimní. Jedná se o vícekrokový proces:

  1. Aplikace ověřuje server pomocí certifikátu certifikační autority, jak je popsáno v ověřování serveru.
  2. Aplikace na server zobrazí ověřovací certifikát klienta x509, aby server mohl zařízení ověřit.
  3. Server používá řetěz certifikátů tenanta Azure Sphere k ověření, že zařízení patří do tenanta.

Aplikace může nastavit stranu ověřování zařízení vzájemného ověřování jedním ze dvou způsobů:

  • Nakonfigurujte funkci DeviceAuth_CurlSslFunc Azure Sphere jako funkci SSL, která provádí ověřování.
  • Vytvořte vlastní funkci SSL, která volá funkci DeviceAuth_SslCtxFunc Azure Sphere pro ověřování.

Poznámka:

Azure Sphere nepodporuje nové vyjednávání SSL/TLS.

Než použijete některou z funkcí, musíte aktualizovat soubor CMakeLists.txt aplikace, aby se TARGET_LINK_LIBRARIES přidaly nástroje curl a tlsutils:

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

Použití DeviceAuth_CurlSslFunc

Nejjednodušší způsob, jak provést ověřování zařízení, je nakonfigurovat DeviceAuth_CurlSslFunc jako funkci zpětného volání pro ověřování SSL 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;
}

Funkce DeviceAuth_CurlSslFunc načte řetěz certifikátů pro aktuálního tenanta Azure Sphere a nastaví připojení curl k provedení vzájemného ověřování. Pokud ověřování selže, vrátí funkce CURLE_SSL_CERTPROBLEM.

Použití DeviceAuth_SslCtxFunc

Aplikace může také použít vlastní funkci zpětného volání SSL, která volá funkci DeviceAuth_SslCtxFunc Azure Sphere pro ověřování.

Vaše vlastní funkce SSL musí volat DeviceAuth_SslCtxFunc k provedení ověřování, ale může také provádět další úlohy související s ověřováním. DeviceAuth_SslCtxFunc vrátí hodnotu výčtuDeviceAuthSslResult, která poskytuje podrobné informace o selhání. Příklad:

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

Použití řetězu certifikátů tenanta na serveru

Aby bylo možné provést vzájemné ověřování, musí být server schopný ověřit, že zařízení patří do vašeho tenanta Azure Sphere a že samotný tenant je legitimní. K provedení tohoto ověřování vyžaduje server řetěz certifikátů tenanta Azure Sphere, který podepíše všechna vaše zařízení Azure Sphere:

Pokud chcete získat řetěz certifikátů pro vašeho tenanta, stáhněte si ho do souboru .p7b, jak je znázorněno v následujícím příkladu:

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

Pak můžete použít soubor .p7b na serveru.

Další tipy pro použití curl

Tady je několik dalších tipů pro použití nástroje curl v aplikaci Azure Sphere.

  • Pokud máte v úmyslu ukládat obsah stránky v paměti RAM nebo flash, mějte na paměti, že úložiště na zařízení Azure Sphere je omezené.

  • Pokud chcete zajistit, aby se curl přesměrovává, přidejte do kódu následující:

    curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
    
  • Přidání podrobných informací o operacích curl, které můžou být užitečné při ladění:

    curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
    
  • Některé servery vrací chyby, pokud požadavek neobsahuje uživatelského agenta. Nastavení uživatelského agenta:

    curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
    
  • Při zpracování curl_multi zpětných volání časovače se vyhněte rekurzivním voláním, pokud je hlášený časový limit 0 ms, protože to může vést k nepředvídatelnému chování. Místo toho zacházet s 0ms jako s 1ms aktivací EventLoopTimer (0ms EventLoopTimers jsou také rekurzivní a měly by se vyhnout).

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