Web hizmetlerine bağlanma

Azure Sphere SDK'sı, üst düzey uygulamaların HTTP ve HTTPS web hizmetlerine bağlanmak ve kimlik doğrulaması yapmak için kullanabileceği libcurl kitaplığını içerir. Hem sunucu hem de istemci kimlik doğrulaması desteklenir, böylece uygulamalar beklenen sunucuyla iletişimde olduklarını doğrulayabilir ve sunucuya cihazlarının ve Azure Sphere kataloğunun meşru olduğunu kanıtlayabilir. Karşılıklı kimlik doğrulaması ikisini birleştirir.

GitHub'da Azure Sphere örnek deposu aşağıdaki curl örneklerini içerir:

  • HTTPS_Curl_Easy , sunucu kimlik doğrulaması için zaman uyumlu (engelleme) API'sini kullanır.
  • HTTPS_Curl_Multi örnek , sunucu kimlik doğrulaması için zaman uyumsuz (engelleyici olmayan) bir API kullanır.

HTTPS_Curl_Easy'da sunucu kimlik doğrulamasına yönelik zaman uyumlu yaklaşım oldukça basit olsa da, Azure Sphere uygulamaları genellikle HTTPS_Curl_Multi örneğinde gösterilen daha karmaşık zaman uyumsuz tekniği ve epoll tabanlı, tek iş parçacıklı olay temelli deseni kullanmalıdır.

libcurl web sitesi,libcurl C API'sinin kapsamlı belgelerini ve birçok örneği sağlar. cURL Kitaplığı ile Azure Sphere SDK çalışma zamanı kitaplığı arasındaki farklar şunlardır:

Sabit Ad
(tanım)
cURL aralık sınırları Azure Sphere aralık sınırları
CURLOPT_BUFFERSIZE
(arabellek boyutu)
Varsayılan: 16 KB Varsayılan: 1536 KB
CURLOPT_UPLOAD_BUFFERSIZE
(karşıya yükleme arabellek boyutu)
Varsayılan: 64 KB
Maksimum: 2 MB
Minimum: 16 KB
Varsayılan: 1536 KB
Maksimum: 64 KB
Minimum: 1536 KB
CURLOPT_HEADERFUNCTION
(bu işleve geçirilen tam HTTP üst bilgisi)
Maksimum: 100 KB Maksimum: 16 KB
CURLOPT_DNS_CACHE_TIMEOUT Varsayılan: 60 saniye boyunca sonuçları önbelleğe alma
Maksimum: sonuçları sonsuza kadar önbelleğe alma
Minimum: 0 (sonuçları önbelleğe alma)
Tüm değerler 0 olarak geçersiz kılınır ve sonuçlar önbelleğe alınmaz.

Curl kullanan uygulamalar için gereksinimler

Curl kitaplığını kullanan uygulamaların uygun üst bilgi dosyalarını içermesi ve uygulama bildiriminde Azure Sphere (Eski) kiracı UUID ve internet ana bilgisayar bilgilerini sağlaması gerekir.

Üst bilgi dosyaları

Curl kullanmak için uygulamanıza şu üst bilgi dosyalarını ekleyin:

#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

Storage.h üst bilgi dosyası yalnızca uygulama görüntüsü paketinde bir veya daha fazla sertifika sağladığınızda gereklidir. Karşılıklı kimlik doğrulaması gerçekleştirmek için deviceauth_curl.h üst bilgisi gereklidir. Uygulama İnternet'e bağlanmak için ara sunucu kullanıyorsa networking_curl.h üst bilgisi gereklidir.

Uygulama bildirimi

Uygulama bildiriminin AllowedConnections alanı, uygulamanın bağlandığı konakları belirtmelidir. Ayrıca yeniden yönlendirildiğinde bağlantının karşılaşabileceği her etki alanının adını içermelidir. Örneğin, Microsoft giriş sayfasına bağlanan bir uygulama için hem hem de microsoft.comwww.microsoft.com gereklidir.

Uygulama karşılıklı kimlik doğrulaması kullanıyorsa bildirimin DeviceAuthentication alanı Azure Sphere (Eski) kiracı UUID'sini içermelidir. Cihaz kimlik doğrulama sertifikaları, yalnızca cihazın kataloğu uygulama bildirimindeki kiracı UUID'sine uyan bir Azure Sphere (Eski) kiracı UUID'sine bağlıysa verilir. Bu kısıtlama derinlemesine savunma sağlar: Farklı bir katalogdaki bir cihazda çalışan bir uygulama (örneğin, farklı bir müşterinin veya düzen dışı bir varlığın) sunucuda kimlik doğrulaması yapamaz.

Geliştirme sırasında , az sphere catalog show komutunu kullanarak ve nesneden değeri ayıklayarak eski kiracı UUID'sini MigratedCatalogIdtags bulabilirsiniz.

Uygulama ara sunucu kullanıyorsa ReadNetworkProxyConfig alanı, uygulamanın ara sunucu yapılandırmasını alma izni olup olmadığını gösterir.

Aşağıdaki örnekte AllowedConnections alanı, uygulamanın yalnızca öğesine www.example.combağlandığını belirtir, DeviceAuthentication alanı Azure Sphere (Eski) kiracı UUID'sini belirtir ve uygulamanın karşılıklı kimlik doğrulaması için cihaz sertifikasını kullanmasını sağlar ve ReadNetworkProxyConfig alanı uygulamanın ara sunucu yapılandırma bilgilerini yeniden işleyebileceğinizi belirtir.

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

Desteklenen işlevsellik

Azure Sphere için Libcurl yalnızca HTTP ve HTTPS protokollerini destekler. Ayrıca, Azure Sphere işletim sistemi yazılabilir dosyalar (tanımlama bilgileri) veya UNIX yuvaları gibi bazı işlevleri desteklemez. mprintf() ailesi gibi gelecekteki libcurl sürümlerinde desteklenmeyen özellikler kullanılamaz.

Azure Sphere için Libcurl, TLS 1.2 ve TLS 1.3'i destekler ve daha geniş Microsoft TLS güvenlik stratejisiyle uyumlu olarak TLS 1.0 ve TLS 1.1'i kullanımdan kaldırmıştır.

Desteklenen şifreleme paketleri şunlardır:

  • 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

TLS'nin desteklenmeyen bir sürümünü kullanma girişimleri hatasını CyaSSL does not support <version>döndürür.

Sunucu kimlik doğrulaması

Azure Sphere, libcurl aracılığıyla sunucu kimlik doğrulamayı destekler. Sunucunun sertifikası, cihazın güvendiği bir Sertifika Yetkilisi (CA) tarafından imzalanmalıdır. Libcurl'un bir sunucunun kimliğini doğrulaması için uygulamanın CA dosyasının yolunu sağlaması gerekir.

Görüntü paketine CA sertifikaları ekleme

Bir veya daha fazla CA kullanmak için, sertifikaları görüntü paketinize eklemeniz gerekir. Her sertifika base-64 kodlanmış olmalıdır. En basit yaklaşım, tüm ek sertifikaları içeren tek bir dosya oluşturmaktır. Dosya .pem dosya adı uzantısına sahip olmalıdır. Sertifika eklemek için:

  1. Uygulamanız için proje klasöründe bir sertifikalar klasörü oluşturun. Proje klasörü, uygulamanızın CMakeLists dosyasını içerir.
  2. certs klasöründe .pem uzantısına sahip bir metin dosyası oluşturun, her sertifikayı bu dosyaya kopyalayın ve dosyayı kaydedin.
  3. CMakeLists.txt dosyasında, sertifika dosyasını görüntü paketine kaynak dosyası olarak ekleyin. Örneğin:
azsphere_target_add_image_package(${PROJECT_NAME} RESOURCE_FILES "certs/DigiCertGlobalRootCA.pem")

Sertifika dosyası artık görüntü paketindeki certs klasöründe görünmelidir.

Sertifika konumlarını ayarlama

Uygulamanızda, sertifikaların konumlarını ayarlamak için CURLOPT_CAPATH ve CURLOPT_CAINFO seçeneklerini kullanın. Görüntü paketindeki sertifikaların mutlak yolunu almak için Storage_GetAbsolutePathInImagePackage çağırın ve ardından curl_easy_setopt çağırın.

CURLOPT_CAPATH sertifikalar için varsayılan bir klasör ayarlar. Örneğin, aşağıdaki kod curl'e görüntüdeki sertifikalar klasöründe sertifikaları aramasını söyler:

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

CURLOPT_CAINFO, bir veya daha fazla sertifika içeren bir dosyanın yolunu ayarlar. Curl, CURLOPT_CAPATH'de ayarlanan varsayılan klasöre ek olarak bu dosyayı arar. Örneğin:

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

Bu kod curl'e, CURLOPT_CAPATH dizininde tanımlanan CA'lara ek olarak mycertificates.pem dosyasında tanımlanan ca'lara güvenmesini söyler.

Karşılıklı kimlik doğrulaması

Karşılıklı kimlik doğrulaması hem sunucunun hem de istemci cihazının meşru olduğunu doğrular. Bu çok adımlı bir işlemdir:

  1. Uygulama, Sunucu kimlik doğrulaması bölümünde açıklandığı gibi bir CA sertifikası kullanarak sunucunun kimliğini doğrular.
  2. Uygulama, sunucunun cihazın kimliğini doğru edebilmesi için sunucuya bir x509 istemci kimlik doğrulama sertifikası sunar.
  3. Sunucu, cihazın kataloğa ait olduğunu doğrulamak için Azure Sphere kataloğunun sertifika zincirini kullanır.

Bir uygulama, karşılıklı kimlik doğrulamasının cihaz kimlik doğrulaması tarafını iki yoldan biriyle ayarlayabilir:

  • Azure Sphere DeviceAuth_CurlSslFunc işlevini kimlik doğrulaması gerçekleştiren SSL işlevi olarak yapılandırın.
  • Kimlik doğrulaması için Azure Sphere DeviceAuth_SslCtxFunc işlevini çağıran özel bir SSL işlevi oluşturun.

Not

Azure Sphere, SSL/TLS yeniden anlaşmasını desteklemez.

her iki işlevi de kullanmadan önce uygulamanızın CMakeLists.txt dosyasını TARGET_LINK_LIBRARIES curl ve tlsutils ekleyecek şekilde güncelleştirmeniz gerekir:

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

DeviceAuth_CurlSslFunc kullanma

Cihaz kimlik doğrulamasını gerçekleştirmenin en basit yolu , DeviceAuth_CurlSslFunc curl SSL kimlik doğrulaması için geri çağırma işlevi olarak yapılandırmaktır:

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

DeviceAuth_CurlSslFunc işlevi, geçerli Azure Sphere kataloğu için sertifika zincirini alır ve karşılıklı kimlik doğrulaması gerçekleştirmek için curl bağlantısını ayarlar. Kimlik doğrulaması başarısız olursa işlev CURLE_SSL_CERTPROBLEM döndürür.

DeviceAuth_SslCtxFunc kullanma

Bir uygulama, kimlik doğrulaması için Azure Sphere DeviceAuth_SslCtxFunc işlevini çağıran özel bir SSL geri çağırma işlevi de kullanabilir.

Özel SSL işlevinizin kimlik doğrulamasını gerçekleştirmek için DeviceAuth_SslCtxFunc çağırması gerekir, ancak kimlik doğrulamasıyla ilgili diğer görevleri de gerçekleştirebilir. DeviceAuth_SslCtxFunc , hata hakkında ayrıntılı bilgi sağlayan sabit listesi değerini DeviceAuthSslResult döndürür. Örneğin:

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

Sunucunuzda katalog sertifika zincirini kullanma

Karşılıklı kimlik doğrulaması gerçekleştirmek için sunucunun cihazın Azure Sphere kataloğunuza ait olduğunu ve kataloğun kendisinin meşru olduğunu doğrulayabilmesi gerekir. Bu kimlik doğrulamasını gerçekleştirmek için sunucu, tüm Azure Sphere cihazlarınızı imzalayan Azure Sphere kataloğunun sertifika zincirini gerektirir:

Kataloğunuzun sertifika zincirini almak için aşağıdaki örnekte olduğu gibi bir .p7b dosyasına indirin:

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

Ardından sunucunuzda .p7b dosyasını kullanabilirsiniz.

Curl kullanmaya yönelik ek ipuçları

Azure Sphere uygulamasında curl kullanmaya yönelik bazı ek ipuçları aşağıdadır.

  • Sayfa içeriğini RAM veya flash olarak depolamayı planlıyorsanız Azure Sphere cihazındaki depolama alanının sınırlı olduğunu unutmayın.

  • Curl'in yeniden yönlendirmeleri izlediğinden emin olmak için kodunuza aşağıdakileri ekleyin:

    curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
    
  • Hata ayıklama sırasında yararlı olabilecek curl işlemleri hakkında ayrıntılı bilgi eklemek için:

    curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
    
  • İstek kullanıcı aracısı içermiyorsa bazı sunucular hata döndürür. Kullanıcı aracısı ayarlamak için:

    curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
    
  • curl_multi süreölçer geri çağrılarını işlerken, bildirilen zaman aşımı 0ms olduğunda özyinelemeli çağrılardan kaçının; bu durum öngörülemeyen davranışlara yol açabilir. Bunun yerine, bir EventLoopTimer tetikleyerek 0ms'yi 1ms olarak değerlendirin (0ms EventLoopTimers da özyinelemelidir ve kaçınılmalıdır).

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