Bagikan melalui


Menyambungkan ke layanan web

Azure Sphere SDK menyertakan pustaka libcurl, yang dapat digunakan aplikasi tingkat tinggi untuk menyambungkan dan mengautentikasi dengan layanan web HTTP dan HTTPS. Autentikasi server dan klien didukung, sehingga aplikasi dapat memverifikasi bahwa mereka berkomunikasi dengan server yang diharapkan dan dapat membuktikan kepada server bahwa perangkat mereka dan katalog Azure Sphere sah. Autentikasi bersama menggabungkan keduanya.

Repo sampel Azure Sphere di GitHub menyertakan sampel lengkung berikut:

Meskipun pendekatan sinkronisasi untuk autentikasi server di HTTPS_Curl_Easy cukup sederhana, aplikasi Azure Sphere umumnya harus menggunakan teknik asinkron yang lebih kompleks yang ditunjukkan dalam sampel HTTPS_Curl_Multi, bersama dengan pola berbasis epoll berbasis kejadian beralur tunggal.

Situs web libcurl menyediakan dokumentasi menyeluruh tentang API libcurl C dan banyak contoh. Perbedaan antara Pustaka cURL dan pustaka runtime Azure Sphere SDK adalah sebagai berikut:

Nama Konstanta
(definisi)
batas rentang cURL Batas rentang Azure Sphere
CURLOPT_BUFFERSIZE
(ukuran buffer)
Default: 16 KB Default: 1536 KB
CURLOPT_UPLOAD_BUFFERSIZE
(ukuran buffer unggahan)
Default: 64 KB
Maksimum: 2MB
Minimum: 16 KB
Default: 1536 KB
Maksimum: 64 KB
Minimum: 1536 KB
CURLOPT_HEADERFUNCTION
(header HTTP lengkap dikirim ke fungsi ini)
Maksimum: 100 KB Maksimum: 16 KB
CURLOPT_DNS_CACHE_TIMEOUT Default: hasil cache selama 60 detik
Maksimum: hasil cache selamanya
Minimum: 0 (jangan cache hasil)
Semua nilai ditimpa menjadi 0, dan hasilnya tidak disinggahkan.

Persyaratan untuk aplikasi yang menggunakan curl

Aplikasi yang menggunakan pustaka lengkung harus menyertakan file header yang sesuai, dan menyediakan UUID penyewa Azure Sphere (Warisan) dan informasi host internet dalam manifes aplikasi.

File header

Untuk menggunakan lengkung, sertakan file header ini dalam aplikasi Anda:

#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

File header storage.h diperlukan hanya jika Anda memasukkan satu atau beberapa sertifikat dalam paket gambar aplikasi. Header deviceauth_curl.h diperlukan untuk melakukan autentikasi bersama. Header networking_curl.h diperlukan jika aplikasi menggunakan proksi untuk tersambung ke internet.

Manifes aplikasi

Bidang AllowedConnections dari manifes aplikasi harus menentukan host tempat aplikasi tersambung. Ini juga harus berisi nama setiap domain yang mungkin ditemui koneksi jika dialihkan. Misalnya, keduanya microsoft.com dan www.microsoft.com diperlukan untuk aplikasi yang tersambung ke laman Microsoft.

Jika aplikasi menggunakan autentikasi bersama, bidang DeviceAuthentication manifes harus menyertakan UUID penyewa Azure Sphere (Legacy). Sertifikat autentikasi perangkat hanya dikeluarkan jika katalog perangkat ditautkan ke UUID penyewa Azure Sphere (Warisan) yang cocok dengan UUID penyewa dalam manifes aplikasi. Pembatasan ini memberikan pertahanan secara mendalam: aplikasi yang berjalan pada perangkat dalam katalog yang berbeda (misalnya, pelanggan lain atau entitas nakal) tidak dapat mengautentikasi ke server.

Selama pengembangan, Anda bisa menemukan UUID penyewa warisan dengan menggunakan perintah peragaanMigratedCatalogId katalog bola az dan mengekstrak nilai dari tags objek.

Jika aplikasi menggunakan proksi, bidang ReadNetworkProxyConfig menunjukkan apakah aplikasi memiliki izin untuk mengambil konfigurasi proksi.

Dalam contoh berikut, bidang AllowedConnections menentukan bahwa aplikasi hanya tersambung ke www.example.com, bidang DeviceAuthentication menentukan UUID penyewa Azure Sphere (Legacy), memungkinkan aplikasi menggunakan sertifikat perangkat untuk autentikasi bersama, dan bidang ReadNetworkProxyConfig menentukan bahwa aplikasi dapat melakukan perulangan informasi konfigurasi proksi.

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

Fungsionalitas yang didukung

Libcurl untuk Azure Sphere hanya mendukung protokol HTTP dan HTTPS. Selain itu, Azure Sphere OS tidak mendukung beberapa fungsionalitas, seperti file yang dapat ditulis (cookie) atau soket UNIX. Fitur yang tidak akan didukung dalam rilis libcurl mendatang, seperti keluarga mprintf(), tidak tersedia.

Libcurl untuk Azure Sphere mendukung TLS 1.2 dan TLS 1.3, dan telah menghentikan TLS 1.0 dan TLS 1.1 sesuai dengan strategi keamanan TLS Microsoft yang lebih luas.

Berikut ini adalah suite sandi yang didukung:

  • 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

Mencoba menggunakan versi TLS yang tidak didukung mengembalikan kesalahan CyaSSL does not support <version>.

Autentikasi server

Azure Sphere mendukung autentikasi server melalui libcurl. Sertifikat server harus ditandatangani oleh Otoritas Sertifikat (CA) yang dipercaya perangkat. Agar libcurl mengautentikasi server, aplikasi harus menyediakan jalur ke file CA.

Menambahkan sertifikat CA ke paket gambar

Untuk menggunakan satu atau beberapa CD, Anda harus menambahkan sertifikat ke paket gambar Anda. Setiap sertifikat harus berkode basis 64. Pendekatan paling sederhana adalah dengan membuat satu file yang berisi semua sertifikat tambahan. File harus memiliki ekstensi nama file .pem. Untuk menambahkan sertifikat:

  1. Buat folder sert di folder proyek untuk aplikasi Anda. Folder proyek berisi file CMakeLists untuk aplikasi Anda.
  2. Dalam folder sert, buat file teks dengan ekstensi .pem, salin setiap sertifikat ke dalamnya, dan simpan file.
  3. Dalam file CMakeLists.txt, tambahkan file sertifikat ke paket gambar sebagai file sumber daya. Misalnya:
azsphere_target_add_image_package(${PROJECT_NAME} RESOURCE_FILES "certs/DigiCertGlobalRootCA.pem")

File sertifikat sekarang akan muncul di folder sert dalam paket gambar.

Mengatur lokasi sertifikat

Dalam aplikasi Anda, gunakan opsi CURLOPT_CAPATH dan CURLOPT_CAINFO untuk mengatur lokasi sertifikat. Hubungi Storage_GetAbsolutePathInImagePackage untuk mengambil jalur mutlak ke sertifikat dalam paket gambar lalu hubungi curl_easy_setopt.

CURLOPT_CAPATH mengatur folder default untuk sertifikat. Misalnya, kode berikut ini memberi tahu lengkung untuk mencari sertifikat dalam folder sert dalam gambar:

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

CURLOPT_CAINFO mengatur jalur ke file yang berisi satu atau beberapa sertifikat. Curl mencari file ini selain kumpulan folder default di CURLOPT_CAPATH. Misalnya:

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

Kode ini memberi tahu curl untuk mempercayai SETIAP CAS yang ditentukan dalam file mycertificates.pem, selain CD yang ditentukan dalam direktori yang diatur dalam CURLOPT_CAPATH.

Autentikasi bersama

Autentikasi bersama memverifikasi bahwa server dan perangkat klien sah. Ini adalah proses multi-langkah:

  1. Aplikasi mengautentikasi server menggunakan sertifikat CA, seperti yang dijelaskan dalam Autentikasi server.
  2. Aplikasi menyajikan sertifikat autentikasi klien x509 ke server sehingga server dapat mengautentikasi perangkat.
  3. Server menggunakan rantai sertifikat katalog Azure Sphere untuk memverifikasi bahwa perangkat tersebut termasuk dalam katalog.

Aplikasi dapat menyiapkan sisi autentikasi perangkat dari autentikasi bersama dengan salah satu dari dua cara:

  • Mengonfigurasi fungsi Azure Sphere DeviceAuth_CurlSslFunc sebagai fungsi SSL yang menjalankan autentikasi.
  • Buat fungsi SSL kustom yang memanggil fungsi Azure Sphere DeviceAuth_SslCtxFunc untuk autentikasi.

Catatan

Azure Sphere tidak mendukung negosiasi ulang SSL/TLS.

Sebelum menggunakan salah satu fungsi, Anda harus memperbarui file CMakeLists.txt untuk aplikasi guna menambahkan lengkung dan tlsutil ke TARGET_LINK_LIBRARIES:

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

Menggunakan DeviceAuth_CurlSslFunc

Cara paling sederhana untuk melakukan autentikasi perangkat adalah dengan mengonfigurasi DeviceAuth_CurlSslFunc sebagai fungsi callback untuk autentikasi SSL lengkung:

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

Fungsi DeviceAuth_CurlSslFunc mengambil rantai sertifikat untuk katalog Azure Sphere saat ini dan menyiapkan koneksi lengkung untuk melakukan autentikasi bersama. Jika autentikasi gagal, fungsi akan mengembalikan CURLE_SSL_CERTPROBLEM.

Menggunakan DeviceAuth_SslCtxFunc

Aplikasi juga dapat menggunakan fungsi callback SSL kustom yang memanggil fungsi Azure Sphere DeviceAuth_SslCtxFunc untuk autentikasi.

Fungsi SSL kustom Anda harus memanggil DeviceAuth_SslCtxFunc untuk melakukan autentikasi, tetapi mungkin juga melakukan tugas lain yang terkait dengan autentikasi. DeviceAuth_SslCtxFunc mengembalikan nilai DeviceAuthSslResult enumerasi, yang menyediakan informasi mendetail tentang kegagalan. Misalnya:

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

Menggunakan rantai sertifikat katalog di server Anda

Untuk melakukan autentikasi bersama, server harus dapat memverifikasi bahwa perangkat tersebut adalah milik katalog Azure Sphere Anda dan katalog itu sendiri sah. Untuk melakukan autentikasi ini, server memerlukan rantai sertifikat katalog Azure Sphere, yang menandatangani semua perangkat Azure Sphere Anda:

Untuk mendapatkan rantai sertifikat katalog Anda, unduh ke file .p7b, seperti dalam contoh berikut:

az sphere ca-certificate download-chain --destination CA-cert-chain.p7b

Anda kemudian dapat menggunakan file .p7b di server Anda.

Tips tambahan untuk menggunakan lengkung

Berikut adalah beberapa tips tambahan untuk menggunakan lengkung di aplikasi Azure Sphere.

  • Jika Anda berencana untuk menyimpan konten halaman dalam RAM atau flash, ingatlah bahwa penyimpanan di perangkat Azure Sphere terbatas.

  • Untuk memastikan bahwa lengkungan mengikuti pengalihan, tambahkan hal berikut ke kode Anda:

    curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
    
  • Untuk menambahkan informasi verbose tentang operasi lengkung yang mungkin berguna selama proses debug:

    curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
    
  • Beberapa server mengembalikan kesalahan jika permintaan tidak berisi agen pengguna. Untuk mengatur agen pengguna:

    curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
    
  • Saat menangani curl_multi callback timer, hindari panggilan berulang ketika waktu habis yang dilaporkan adalah 0ms, karena hal ini dapat menyebabkan perilaku yang tidak dapat diprediksi. Sebagai gantinya, perlakukan 0ms sebagai 1ms dengan memicu EventLoopTimer (EventLoopTimers 0ms juga berulang dan harus dihindari).

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