Ansluta till webbtjänster
Viktigt!
Det här är dokumentationen om Azure Sphere (Legacy). Azure Sphere (Legacy) upphör den 27 september 2027 och användarna måste migrera till Azure Sphere (integrerad) vid den här tiden. Använd versionsväljaren ovanför TOC för att visa dokumentationen om Azure Sphere (integrerad).
Azure Sphere SDK innehåller biblioteket libcurl, som högnivåprogram kan använda för att ansluta och autentisera med HTTP- och HTTPS-webbtjänster. Både server- och klientautentisering stöds, så att program kan verifiera att de kommunicerar med den förväntade servern och kan bevisa för servern att deras enhet och Azure Sphere-klientorganisation är legitima. Ömsesidig autentisering kombinerar de två.
Lagringsplatsen Azure Sphere-exempel på GitHub innehåller följande curl-exempel:
- HTTPS_Curl_Easy använder ett synkront (blockerande) API för serverautentisering.
- HTTPS_Curl_Multi exempel använder ett asynkront (icke-blockerande) API för serverautentisering.
Även om den synkrona metoden för serverautentisering i HTTPS_Curl_Easy är ganska enkel bör Azure Sphere-program i allmänhet använda den mer komplexa asynkrona tekniken som visas i HTTPS_Curl_Multi-exemplet, tillsammans med ett epollbaserat, entrådat händelsedrivet mönster.
Webbplatsen libcurl innehåller omfattande dokumentation om libcurl C API och många exempel. Skillnaderna mellan cURL-biblioteket och Azure Sphere SDK-körningsbiblioteket är följande:
Konstant namn (definition) |
cURL-intervallgränser | Gränser för Azure Sphere-intervall |
---|---|---|
CURLOPT_BUFFERSIZE (buffertstorlek) |
Standard: 16 KB | Standard: 1536 KB |
CURLOPT_UPLOAD_BUFFERSIZE (uppladdningsbuffertstorlek) |
Standard: 64 KB Maximalt: 2 MB Minimum: 16 KB |
Standard: 1536 KB Maximalt: 64 KB Minimum: 1536 KB |
CURLOPT_HEADERFUNCTION (fullständigt HTTP-huvud skickas till den här funktionen) |
Maximalt: 100 kB | Maximalt: 16 kB |
CURLOPT_DNS_CACHE_TIMEOUT | Standard: cacheresultat i 60 sekunder Maximalt: cacheresultat för evigt Minimum: 0 (cachelagra inte resultat) |
Alla värden överskrids till 0 och resultaten cachelagras inte. |
Krav för program som använder curl
Program som använder curl-biblioteket måste innehålla lämpliga huvudfiler och ange information om klient- och Internetvärdar i programmanifestet.
Rubrikfiler
Om du vill använda curl inkluderar du dessa huvudfiler i ditt program:
#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
Huvudfilen storage.h krävs endast om du anger ett eller flera certifikat i programavbildningspaketet. Huvudet deviceauth_curl.h krävs för ömsesidig autentisering. Huvudet networking_curl.h krävs om programmet använder en proxy för att ansluta till Internet.
Programmanifest
Fältet AllowedConnections i programmanifestet måste ange de värdar som programmet ansluter till. Den måste också innehålla namnet på varje domän som anslutningen kan stöta på om den omdirigeras. Både och www.microsoft.com
krävs till exempel microsoft.com
för ett program som ansluter till Microsofts startsida.
Om programmet använder ömsesidig autentisering måste fältet DeviceAuthentication i manifestet innehålla Klient-ID:t för Azure Sphere. Certifikat för enhetsautentisering utfärdas endast om enhetens klient-ID matchar klient-ID:t i programmanifestet. Den här begränsningen ger skydd på djupet: ett program som körs på en enhet i en annan klientorganisation (t.ex. en annan kunds eller en falsk entitets) kan inte autentisera till servern.
Om programmet använder en proxy anger fältet ReadNetworkProxyConfig om programmet har behörighet att hämta proxykonfigurationen.
Under utvecklingen kan du hitta ID:t för den aktuella Azure Sphere-klientorganisationen med kommandot azsphere tenant show-selected.
I följande exempel anger fältet AllowedConnections att programmet endast ansluter till www.example.com
, fältet DeviceAuthentication anger Klient-ID för Azure Sphere, vilket gör att programmet kan använda enhetscertifikatet för ömsesidig autentisering, och fältet ReadNetworkProxyConfig anger att programmet kan retreive proxykonfigurationsinformation.
"Capabilities": {
"AllowedConnections": [ "www.example.com" ],
"Gpio": [],
"Uart": [],
"WifiConfig": false,
"DeviceAuthentication": "00000000-0000-0000-0000-000000000000",
"ReadNetworkProxyConfig": true
}
Funktioner som stöds
Libcurl för Azure Sphere stöder endast HTTP- och HTTPS-protokollen. Dessutom har Azure Sphere OS inte stöd för vissa funktioner, till exempel skrivbara filer (cookies) eller UNIX-socketar. Funktioner som inte kommer att stödjas i framtida libcurl-versioner, till exempel mprintf() -familjen, är inte tillgängliga.
Libcurl för Azure Sphere stöder TLS 1.2 och TLS 1.3 och har dragit tillbaka TLS 1.0 och TLS 1.1 i linje med den bredare Microsoft TLS-säkerhetsstrategin.
Följande är de chiffersviter som stöds:
- 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
Försök att använda en version av TLS som inte stöds returnerar felet CyaSSL does not support <version>
.
Serverautentisering
Azure Sphere stöder serverautentisering via libcurl. Serverns certifikat måste signeras av en certifikatutfärdare (CA) som enheten litar på. För att libcurl ska kunna autentisera en server måste programmet ange sökvägen till CA-filen.
Lägga till CA-certifikat i avbildningspaketet
Om du vill använda en eller flera certifikatutfärdare måste du lägga till certifikaten i avbildningspaketet. Varje certifikat måste vara base-64-kodat. Den enklaste metoden är att skapa en enda fil som innehåller alla ytterligare certifikat. Filen måste ha filnamnstillägget .pem. Så här lägger du till certifikat:
- Skapa en certifikatmapp i projektmappen för ditt program. Projektmappen innehåller filen CMakeLists för ditt program.
- I mappen certs skapar du en textfil med .pem-tillägget, kopierar varje certifikat till den och sparar filen.
- I CMakeLists.txt-filen lägger du till certifikatfilen i avbildningspaketet som en resursfil. Till exempel:
azsphere_target_add_image_package(${PROJECT_NAME} RESOURCE_FILES "certs/DigiCertGlobalRootCA.pem")
Certifikatfilen bör nu visas i certifikatmappen i avbildningspaketet.
Ange certifikatplatser
I programmet använder du alternativen CURLOPT_CAPATH och CURLOPT_CAINFO för att ange platserna för certifikaten. Anropa Storage_GetAbsolutePathInImagePackage för att hämta den absoluta sökvägen till certifikaten i avbildningspaketet och anropa sedan curl_easy_setopt.
CURLOPT_CAPATH anger en standardmapp för certifikaten. Följande kod uppmanar till exempel curl att söka efter certifikat i certifikatmappen i bilden:
char *path = Storage_GetAbsolutePathInImagePackage("certs");
curl_easy_setopt(curl_handle, CURLOPT_CAPATH, path);
CURLOPT_CAINFO anger en sökväg till en fil som innehåller ett eller flera certifikat. Curl söker i den här filen utöver standardmappen som anges i CURLOPT_CAPATH. Till exempel:
char *path = Storage_GetAbsolutePathInImagePackage("CAs/mycertificates.pem");
curl_easy_setopt(curl_handle, CURLOPT_CAINFO, path);
Den här koden instruerar curl att lita på eventuella certifikatutfärdare som definieras i filen mycertificates.pem, förutom certifikatutfärdare som definieras i katalogen som anges i CURLOPT_CAPATH.
Ömsesidig autentisering
Ömsesidig autentisering verifierar att både servern och klientenheten är legitima. Det är en process i flera steg:
- Programmet autentiserar servern med hjälp av ett CA-certifikat enligt beskrivningen i Serverautentisering.
- Programmet visar ett x509-klientautentiseringscertifikat till servern så att servern kan autentisera enheten.
- Servern använder Azure Sphere-klientorganisationens certifikatkedja för att verifiera att enheten tillhör klientorganisationen.
Ett program kan konfigurera enhetsautentiseringssidan för ömsesidig autentisering på något av två sätt:
- Konfigurera funktionen Azure Sphere DeviceAuth_CurlSslFunc som den SSL-funktion som utför autentisering.
- Skapa en anpassad SSL-funktion som anropar funktionen Azure Sphere DeviceAuth_SslCtxFunc för autentisering.
Kommentar
Azure Sphere stöder inte SSL/TLS-omförhandling.
Innan du använder någon av funktionerna måste du uppdatera CMakeLists.txt-filen för ditt program för att lägga till curl och tlsutils i TARGET_LINK_LIBRARIES:
TARGET_LINK_LIBRARIES(${PROJECT_NAME} applibs pthread gcc_s c curl tlsutils)
Använda DeviceAuth_CurlSslFunc
Det enklaste sättet att utföra enhetsautentisering är att konfigurera DeviceAuth_CurlSslFunc som återanropsfunktion för curl SSL-autentisering:
// 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;
}
Funktionen DeviceAuth_CurlSslFunc hämtar certifikatkedjan för den aktuella Azure Sphere-klientorganisationen och konfigurerar curl-anslutningen för att utföra ömsesidig autentisering. Om autentiseringen misslyckas returnerar funktionen CURLE_SSL_CERTPROBLEM.
Använd DeviceAuth_SslCtxFunc
Ett program kan också använda en anpassad SSL-återanropsfunktion som anropar funktionen Azure Sphere DeviceAuth_SslCtxFunc för autentisering.
Din anpassade SSL-funktion måste anropa DeviceAuth_SslCtxFunc för att utföra autentiseringen, men kan också utföra andra uppgifter som rör autentisering. DeviceAuth_SslCtxFunc returnerar ett värde för DeviceAuthSslResult
uppräkningen, som innehåller detaljerad information om felet. Till exempel:
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;
}
Använda klientcertifikatkedjan på servern
För att kunna utföra ömsesidig autentisering måste servern kunna verifiera att enheten tillhör din Azure Sphere-klientorganisation och att själva klientorganisationen är legitim. För att utföra den här autentiseringen kräver servern Azure Sphere-klientorganisationens certifikatkedja, som signerar alla dina Azure Sphere-enheter:
Hämta certifikatkedjan för din klientorganisation genom att ladda ned den till en .p7b-fil, som i följande exempel:
azsphere ca-certificate download-chain --destination CA-cert-chain.p7b
Du kan sedan använda .p7b-filen på servern.
Ytterligare tips för att använda curl
Här följer några ytterligare tips för att använda curl i ett Azure Sphere-program.
Om du planerar att lagra sidinnehåll i RAM-minne eller flash bör du tänka på att lagringen på Azure Sphere-enheten är begränsad.
För att säkerställa att curl följer omdirigeringar lägger du till följande i koden:
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
Så här lägger du till utförlig information om curl-åtgärder som kan vara till hjälp vid felsökning:
curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
Vissa servrar returnerar fel om en begäran inte innehåller någon användaragent. Så här anger du en användaragent:
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
När du hanterar curl_multi timeråteranrop bör du undvika rekursiva anrop när den rapporterade tidsgränsen är 0 ms, eftersom detta kan leda till oförutsägbart beteende. Behandla i stället 0ms som 1ms genom att utlösa en EventLoopTimer (0ms EventLoopTimers är också rekursiva och bör undvikas).
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; }