Ligar a serviços Web
Importante
Esta é a documentação do Azure Sphere (Legado). O Azure Sphere (Legado) será desativado em 27 de setembro de 2027 e os usuários devem migrar para o Azure Sphere (Integrado) até esse momento. Use o seletor de versão localizado acima do sumário para exibir a documentação do Azure Sphere (Integrado).
O SDK do Azure Sphere inclui a biblioteca libcurl, que os aplicativos de alto nível podem usar para se conectar e autenticar com serviços Web HTTP e HTTPS. Há suporte para autenticação de servidor e cliente, para que os aplicativos possam verificar se estão se comunicando com o servidor esperado e possam provar ao servidor que seu dispositivo e locatário do Azure Sphere são legítimos. A autenticação mútua combina os dois.
O repositório de exemplos do Azure Sphere no GitHub inclui os seguintes exemplos de curl:
- HTTPS_Curl_Easy usa uma API síncrona (bloqueio) para autenticação do servidor.
- HTTPS_Curl_Multi exemplo usa uma API assíncrona (sem bloqueio) para autenticação do servidor.
Embora a abordagem síncrona para autenticação de servidor no HTTPS_Curl_Easy seja bastante simples, os aplicativos do Azure Sphere geralmente devem usar a técnica assíncrona mais complexa mostrada no exemplo de HTTPS_Curl_Multi, juntamente com um padrão controlado por evento de thread único baseado em epoll.
O site libcurl fornece documentação completa da API libcurl C e muitos exemplos. As diferenças entre a biblioteca cURL e a biblioteca de tempo de execução do SDK do Azure Sphere são as seguintes:
Nome constante (definição) |
Limites de intervalo de cURL | Limites de intervalo do Azure Sphere |
---|---|---|
CURLOPT_BUFFERSIZE (tamanho do buffer) |
Padrão: 16 KB | Padrão: 1536 KB |
CURLOPT_UPLOAD_BUFFERSIZE (tamanho do buffer de upload) |
Padrão: 64 KB Máximo: 2MB Mínimo: 16 KB |
Padrão: 1536 KB Máximo: 64 KB Mínimo: 1536 KB |
CURLOPT_HEADERFUNCTION (cabeçalho HTTP completo passado para esta função) |
Máximo: 100 KB | Máximo: 16 KB |
CURLOPT_DNS_CACHE_TIMEOUT | Padrão: resultados de cache por 60 segundos Máximo: resultados de cache para sempre Mínimo: 0 (não armazenar resultados em cache) |
Todos os valores são substituídos por 0 e os resultados não são armazenados em cache. |
Requisitos para aplicações que usam ondulação
Os aplicativos que usam a biblioteca curl devem incluir os arquivos de cabeçalho apropriados e fornecer informações de locatário e host da Internet no manifesto do aplicativo.
Arquivos de cabeçalho
Para usar curl, inclua estes arquivos de cabeçalho em seu aplicativo:
#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
O arquivo de cabeçalho storage.h é necessário somente se você fornecer um ou mais certificados no pacote de imagem do aplicativo. O cabeçalho deviceauth_curl.h é necessário para executar a autenticação mútua. O cabeçalho networking_curl.h é necessário se o aplicativo estiver usando um proxy para se conectar à Internet.
Manifesto de aplicação
O campo AllowedConnections do manifesto do aplicativo deve especificar os hosts aos quais o aplicativo se conecta. Ele também deve conter o nome de cada domínio que a conexão pode encontrar se for redirecionada. Por exemplo, ambos microsoft.com
e www.microsoft.com
são necessários para um aplicativo que se conecta à home page da Microsoft.
Se o aplicativo usa autenticação mútua, o campo DeviceAuthentication do manifesto deve incluir a ID do locatário do Azure Sphere. Os certificados de autenticação de dispositivo são emitidos somente se a ID do locatário do dispositivo corresponder à ID do locatário no manifesto do aplicativo. Essa restrição fornece defesa em profundidade: um aplicativo em execução em um dispositivo em um locatário diferente (digamos, o de um cliente diferente ou uma entidade não autorizada) não pode se autenticar no servidor.
Se o aplicativo usa um proxy, o campo ReadNetworkProxyConfig indica se o aplicativo tem permissão para recuperar a configuração de proxy.
Durante o desenvolvimento, você pode encontrar a ID do locatário atual do Azure Sphere usando o comando azsphere tenant show-selected .
No exemplo a seguir, o campo AllowedConnections especifica que o aplicativo se conecta somente ao www.example.com
, o campo DeviceAuthentication especifica a ID do locatário do Azure Sphere, permitindo que o aplicativo use o certificado de dispositivo para autenticação mútua, e o campo ReadNetworkProxyConfig especifica que o aplicativo pode recuperar informações de configuração de proxy.
"Capabilities": {
"AllowedConnections": [ "www.example.com" ],
"Gpio": [],
"Uart": [],
"WifiConfig": false,
"DeviceAuthentication": "00000000-0000-0000-0000-000000000000",
"ReadNetworkProxyConfig": true
}
Funcionalidade suportada
A Libcurl for Azure Sphere suporta apenas os protocolos HTTP e HTTPS. Além disso, o sistema operacional Azure Sphere não oferece suporte a algumas funcionalidades, como arquivos graváveis (cookies) ou soquetes UNIX. Recursos que não serão suportados em versões libcurl futuras, como a família mprintf(), não estão disponíveis.
A Libcurl para Azure Sphere suporta TLS 1.2 e TLS 1.3 e desativou o TLS 1.0 e o TLS 1.1 em alinhamento com a estratégia de segurança mais ampla do Microsoft TLS.
A seguir estão os pacotes de codificação suportados:
- 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
As tentativas de usar uma versão não suportada do TLS retornam o erro CyaSSL does not support <version>
.
Autenticação de servidor
O Azure Sphere dá suporte à autenticação de servidor por meio da libcurl. O certificado do servidor deve ser assinado por uma Autoridade de Certificação (CA) na qual o dispositivo confia. Para que libcurl autentique um servidor, o aplicativo deve fornecer o caminho para o arquivo CA.
Adicionar certificados de autoridade de certificação ao pacote de imagem
Para usar uma ou mais autoridades de certificação, você deve adicionar os certificados ao seu pacote de imagem. Cada certificado deve ser codificado em base 64. A abordagem mais simples é criar um único arquivo que contenha todos os certificados adicionais. O arquivo deve ter a extensão de nome de arquivo .pem. Para adicionar certificados:
- Crie uma pasta certs na pasta do projeto para seu aplicativo. A pasta do projeto contém o arquivo CMakeLists para seu aplicativo.
- Na pasta certs, crie um arquivo de texto com a extensão .pem, copie cada certificado para ele e salve o arquivo.
- No arquivo CMakeLists.txt, adicione o arquivo de certificado ao pacote de imagem como um arquivo de recurso. Por exemplo:
azsphere_target_add_image_package(${PROJECT_NAME} RESOURCE_FILES "certs/DigiCertGlobalRootCA.pem")
O arquivo de certificado agora deve aparecer na pasta certs no pacote de imagens.
Definir locais de certificado
Em seu aplicativo, use as opções CURLOPT_CAPATH e CURLOPT_CAINFO para definir os locais dos certificados. Chame Storage_GetAbsolutePathInImagePackage para recuperar o caminho absoluto para os certificados no pacote de imagem e, em seguida, chame curl_easy_setopt.
CURLOPT_CAPATH define uma pasta padrão para os certificados. Por exemplo, o código a seguir diz ao curl para procurar certificados na pasta certs na imagem:
char *path = Storage_GetAbsolutePathInImagePackage("certs");
curl_easy_setopt(curl_handle, CURLOPT_CAPATH, path);
CURLOPT_CAINFO define um caminho para um arquivo que contém um ou mais certificados. Curl pesquisa este arquivo, além da pasta padrão definida em CURLOPT_CAPATH. Por exemplo:
char *path = Storage_GetAbsolutePathInImagePackage("CAs/mycertificates.pem");
curl_easy_setopt(curl_handle, CURLOPT_CAINFO, path);
Esse código diz ao curl para confiar em qualquer CA definida no arquivo mycertificates.pem, além das CAs definidas no diretório definido em CURLOPT_CAPATH.
Autenticação mútua
A autenticação mútua verifica se o servidor e o dispositivo cliente são legítimos. É um processo de várias etapas:
- O aplicativo autentica o servidor usando um certificado de autoridade de certificação, conforme descrito em Autenticação do servidor.
- O aplicativo apresenta um certificado de autenticação de cliente x509 para o servidor para que o servidor possa autenticar o dispositivo.
- O servidor usa a cadeia de certificados do locatário do Azure Sphere para verificar se o dispositivo pertence ao locatário.
Um aplicativo pode configurar o lado da autenticação de dispositivo da autenticação mútua de duas maneiras:
- Configure a função Azure Sphere DeviceAuth_CurlSslFunc como a função SSL que executa a autenticação.
- Crie uma função SSL personalizada que chame a função DeviceAuth_SslCtxFunc do Azure Sphere para autenticação.
Nota
O Azure Sphere não suporta a renegociação SSL/TLS.
Antes de usar qualquer uma das funções, você deve atualizar o arquivo de CMakeLists.txt do seu aplicativo para adicionar curl e tlsutils ao TARGET_LINK_LIBRARIES:
TARGET_LINK_LIBRARIES(${PROJECT_NAME} applibs pthread gcc_s c curl tlsutils)
Utilizar DeviceAuth_CurlSslFunc
A maneira mais simples de executar a autenticação de dispositivo é configurá DeviceAuth_CurlSslFunc como a função de retorno de chamada para autenticação 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;
}
A função DeviceAuth_CurlSslFunc recupera a cadeia de certificados para o locatário atual do Azure Sphere e configura a conexão curl para executar a autenticação mútua. Se a autenticação falhar, a função retornará CURLE_SSL_CERTPROBLEM.
Use DeviceAuth_SslCtxFunc
Um aplicativo também pode usar uma função de retorno de chamada SSL personalizada que chama a função DeviceAuth_SslCtxFunc do Azure Sphere para autenticação.
Sua função SSL personalizada deve chamar DeviceAuth_SslCtxFunc para executar a autenticação, mas também pode fazer outras tarefas relacionadas à autenticação. DeviceAuth_SslCtxFunc retorna um valor da DeviceAuthSslResult
enumeração, que fornece informações detalhadas sobre a falha. Por exemplo:
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;
}
Usar a cadeia de certificados de locatário no servidor
Para executar a autenticação mútua, o servidor deve ser capaz de verificar se o dispositivo pertence ao seu locatário do Azure Sphere e se o próprio locatário é legítimo. Para executar essa autenticação, o servidor requer a cadeia de certificados do locatário do Azure Sphere, que assina todos os seus dispositivos do Azure Sphere:
Para obter a cadeia de certificados para seu locatário, baixe-a para um arquivo .p7b, como no exemplo a seguir:
azsphere ca-certificate download-chain --destination CA-cert-chain.p7b
Em seguida, você pode usar o arquivo .p7b no servidor.
Dicas adicionais para usar a ondulação
Aqui estão algumas dicas adicionais para usar curl em um aplicativo do Azure Sphere.
Se você planeja armazenar o conteúdo da página em RAM ou flash, lembre-se de que o armazenamento no dispositivo Azure Sphere é limitado.
Para garantir que o curl siga os redirecionamentos, adicione o seguinte ao seu código:
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
Para adicionar informações detalhadas sobre operações curl que podem ser úteis durante a depuração:
curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
Alguns servidores retornam erros se uma solicitação não contiver um agente de usuário. Para definir um agente de usuário:
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
Ao lidar com retornos de chamada de temporizador curl_multi, evite chamadas recursivas quando o tempo limite relatado for de 0ms, pois isso pode levar a um comportamento imprevisível. Em vez disso, trate 0ms como 1ms acionando um EventLoopTimer (0ms EventLoopTimers também são recursivos e devem ser evitados).
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; }