Skip to content

Commit

Permalink
[chip-tool] Add config_enable_https_requests flag to examples/chip-to…
Browse files Browse the repository at this point in the history
…ol/BUILD.gn and replace gethostbyname by getaddrinfo
  • Loading branch information
vivien-apple committed Feb 5, 2025
1 parent 0d27f42 commit b25a399
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 19 deletions.
4 changes: 4 additions & 0 deletions examples/chip-tool/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ config("config") {
defines += [ "CONFIG_USE_LOCAL_STORAGE" ]
}

if (config_enable_https_requests) {
defines += [ "CONFIG_ENABLE_HTTPS_REQUESTS" ]
}

cflags = [ "-Wconversion" ]
}

Expand Down
1 change: 1 addition & 0 deletions examples/chip-tool/chip-tool.gni
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ declare_args() {
config_use_interactive_mode = true
config_enable_yaml_tests = true
config_use_local_storage = true
config_enable_https_requests = true
}
94 changes: 75 additions & 19 deletions examples/chip-tool/commands/dcl/HTTPSRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <lib/support/logging/CHIPLogging.h>
#include <system/SystemError.h>

#ifdef CONFIG_ENABLE_HTTPS_REQUESTS
#if (CHIP_CRYPTO_OPENSSL || CHIP_CRYPTO_BORINGSSL)
#include <netdb.h>
#include <openssl/ssl.h>
Expand All @@ -33,6 +34,7 @@
#define USE_CHIP_CRYPTO 1
#endif
#endif //(CHIP_CRYPTO_OPENSSL || CHIP_CRYPTO_BORINGSSL)
#endif // CONFIG_ENABLE_HTTPS_REQUESTS

namespace {
constexpr const char * kHttpsPrefix = "https://";
Expand Down Expand Up @@ -68,9 +70,18 @@ class HTTPSSessionHolder
private:
CHIP_ERROR LogNotImplementedError() const
{
#ifndef CONFIG_ENABLE_HTTPS_REQUESTS
ChipLogError(chipTool, "HTTPS requests are disabled via build configuration (config_enable_https_requests=false).");
#elif !(CHIP_CRYPTO_OPENSSL || CHIP_CRYPTO_BORINGSSL)
ChipLogError(chipTool,
"HTTPS requests are not available because neither OpenSSL nor BoringSSL is enabled. Contributions for "
"alternative implementations are welcome!");
#elif !defined(SHA256_DIGEST_LENGTH)
ChipLogError(chipTool,
"HTTPS requests are not available because SHA256_DIGEST_LENGTH is not defined, meaning response integrity "
"verification via SHA-256 digest checking cannot be performed.");
#endif

return CHIP_ERROR_NOT_IMPLEMENTED;
}
};
Expand All @@ -83,17 +94,55 @@ constexpr const char * kErrorSSLContextCreate = "Failed to create SSL context
constexpr const char * kErrorSSLObjectCreate = "Failed to create SSL object";
constexpr const char * kErrorSSLHandshake = "SSL handshake failed";
constexpr const char * kErrorDigestMismatch = "The response digest does not match the expected digest";
class AddressInfoHolder
{
public:
AddressInfoHolder(std::string & hostname, uint16_t port)
{
struct addrinfo hints = {};
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
int err = getaddrinfo(hostname.c_str(), std::to_string(port).c_str(), &hints, &mRes);
#if CHIP_ERROR_LOGGING
constexpr const char * kErrorGetAddressInfo = "Failed to get address info: ";
VerifyOrDo(nullptr != mRes, ChipLogError(chipTool, "%s%s", kErrorGetAddressInfo, gai_strerror(err)));
#else
(void) err;
#endif
}

~AddressInfoHolder()
{
if (mRes != nullptr)
{
freeaddrinfo(mRes);
}
}

bool HasInfo() const { return mRes != nullptr; }
struct addrinfo * Get() const { return mRes; }

private:
struct addrinfo * mRes = nullptr;
};

class HTTPSSessionHolder
{
public:
HTTPSSessionHolder(){};

~HTTPSSessionHolder()
{
VerifyOrReturn(nullptr != mContext);
SSL_free(mSSL);
SSL_CTX_free(mContext);
close(mSock);
if (nullptr != mContext)
{
SSL_free(mSSL);
SSL_CTX_free(mContext);
}

if (mSock >= 0)
{
close(mSock);
}

#if !defined(OPENSSL_IS_BORINGSSL)
EVP_cleanup();
Expand Down Expand Up @@ -134,23 +183,30 @@ class HTTPSSessionHolder
private:
CHIP_ERROR InitSocket(std::string & hostname, uint16_t port, int & sock)
{
auto * server = gethostbyname(hostname.c_str());
VerifyOrReturnError(nullptr != server, CHIP_ERROR_NOT_CONNECTED);

sock = socket(AF_INET, SOCK_STREAM, 0);
VerifyOrReturnError(sock >= 0, CHIP_ERROR_NOT_CONNECTED);

struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
memcpy(&server_addr.sin_addr.s_addr, server->h_addr, (size_t) server->h_length);
AddressInfoHolder addressInfoHolder(hostname, port);
VerifyOrReturnError(addressInfoHolder.HasInfo(), CHIP_ERROR_NOT_CONNECTED);

int rv = connect(sock, (struct sockaddr *) &server_addr, sizeof(server_addr));
VerifyOrReturnError(rv >= 0, CHIP_ERROR_POSIX(errno),
ChipLogError(chipTool, "%s%s:%u", kErrorConnection, hostname.c_str(), port));
auto * res = addressInfoHolder.Get();
for (struct addrinfo * p = res; p != nullptr; p = p->ai_next)
{
sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (sock < 0)
{
continue; // Try the next address
}

if (connect(sock, p->ai_addr, p->ai_addrlen) != 0)
{
close(sock);
sock = -1;
continue; // Try the next address
}

return CHIP_NO_ERROR;
}

return CHIP_NO_ERROR;
ChipLogError(chipTool, "%s%s:%u", kErrorConnection, hostname.c_str(), port);
return CHIP_ERROR_NOT_CONNECTED;
}

CHIP_ERROR InitSSL(int sock)
Expand Down

0 comments on commit b25a399

Please sign in to comment.