25
25
#include < lib/support/logging/CHIPLogging.h>
26
26
#include < system/SystemError.h>
27
27
28
+ #ifdef CONFIG_ENABLE_HTTPS_REQUESTS
28
29
#if (CHIP_CRYPTO_OPENSSL || CHIP_CRYPTO_BORINGSSL)
29
30
#include < netdb.h>
30
31
#include < openssl/ssl.h>
33
34
#define USE_CHIP_CRYPTO 1
34
35
#endif
35
36
#endif // (CHIP_CRYPTO_OPENSSL || CHIP_CRYPTO_BORINGSSL)
37
+ #endif // CONFIG_ENABLE_HTTPS_REQUESTS
36
38
37
39
namespace {
38
40
constexpr const char * kHttpsPrefix = " https://" ;
@@ -68,9 +70,18 @@ class HTTPSSessionHolder
68
70
private:
69
71
CHIP_ERROR LogNotImplementedError () const
70
72
{
73
+ #ifndef CONFIG_ENABLE_HTTPS_REQUESTS
74
+ ChipLogError (chipTool, " HTTPS requests are disabled via build configuration (config_enable_https_requests=false)." );
75
+ #elif !(CHIP_CRYPTO_OPENSSL || CHIP_CRYPTO_BORINGSSL)
71
76
ChipLogError (chipTool,
72
77
" HTTPS requests are not available because neither OpenSSL nor BoringSSL is enabled. Contributions for "
73
78
" alternative implementations are welcome!" );
79
+ #elif !defined(SHA256_DIGEST_LENGTH)
80
+ ChipLogError (chipTool,
81
+ " HTTPS requests are not available because SHA256_DIGEST_LENGTH is not defined, meaning response integrity "
82
+ " verification via SHA-256 digest checking cannot be performed." );
83
+ #endif
84
+
74
85
return CHIP_ERROR_NOT_IMPLEMENTED;
75
86
}
76
87
};
@@ -79,21 +90,56 @@ constexpr uint16_t kResponseBufferSize = 4096;
79
90
constexpr const char * kErrorSendHTTPRequest = " Failed to send HTTP request" ;
80
91
constexpr const char * kErrorReceiveHTTPResponse = " Failed to read HTTP response" ;
81
92
constexpr const char * kErrorConnection = " Failed to connect to: " ;
93
+ constexpr const char * kErrorGetAddressInfo = " Failed to get address info: " ;
82
94
constexpr const char * kErrorSSLContextCreate = " Failed to create SSL context" ;
83
95
constexpr const char * kErrorSSLObjectCreate = " Failed to create SSL object" ;
84
96
constexpr const char * kErrorSSLHandshake = " SSL handshake failed" ;
85
97
constexpr const char * kErrorDigestMismatch = " The response digest does not match the expected digest" ;
98
+ class AddressInfoHolder
99
+ {
100
+ public:
101
+ AddressInfoHolder (std::string & hostname, uint16_t port)
102
+ {
103
+ struct addrinfo hints = {};
104
+ hints.ai_family = AF_INET;
105
+ hints.ai_socktype = SOCK_STREAM;
106
+
107
+ int err = getaddrinfo (hostname.c_str (), std::to_string (port).c_str (), &hints, &mRes );
108
+ VerifyOrDo (nullptr != mRes , ChipLogError (chipTool, " %s%s" , kErrorGetAddressInfo , gai_strerror (err)));
109
+ }
110
+
111
+ ~AddressInfoHolder ()
112
+ {
113
+ if (mRes != nullptr )
114
+ {
115
+ freeaddrinfo (mRes );
116
+ }
117
+ }
118
+
119
+ bool HasInfo () const { return mRes != nullptr ; }
120
+ struct addrinfo * Get () const { return mRes ; }
121
+
122
+ private:
123
+ struct addrinfo * mRes = nullptr ;
124
+ };
125
+
86
126
class HTTPSSessionHolder
87
127
{
88
128
public:
89
129
HTTPSSessionHolder (){};
90
130
91
131
~HTTPSSessionHolder ()
92
132
{
93
- VerifyOrReturn (nullptr != mContext );
94
- SSL_free (mSSL );
95
- SSL_CTX_free (mContext );
96
- close (mSock );
133
+ if (nullptr != mContext )
134
+ {
135
+ SSL_free (mSSL );
136
+ SSL_CTX_free (mContext );
137
+ }
138
+
139
+ if (mSock >= 0 )
140
+ {
141
+ close (mSock );
142
+ }
97
143
98
144
#if !defined(OPENSSL_IS_BORINGSSL)
99
145
EVP_cleanup ();
@@ -134,23 +180,30 @@ class HTTPSSessionHolder
134
180
private:
135
181
CHIP_ERROR InitSocket (std::string & hostname, uint16_t port, int & sock)
136
182
{
137
- auto * server = gethostbyname (hostname.c_str ());
138
- VerifyOrReturnError (nullptr != server, CHIP_ERROR_NOT_CONNECTED);
139
-
140
- sock = socket (AF_INET, SOCK_STREAM, 0 );
141
- VerifyOrReturnError (sock >= 0 , CHIP_ERROR_NOT_CONNECTED);
142
-
143
- struct sockaddr_in server_addr;
144
- memset (&server_addr, 0 , sizeof (server_addr));
145
- server_addr.sin_family = AF_INET;
146
- server_addr.sin_port = htons (port);
147
- memcpy (&server_addr.sin_addr .s_addr , server->h_addr , (size_t ) server->h_length );
183
+ AddressInfoHolder addressInfoHolder (hostname, port);
184
+ VerifyOrReturnError (addressInfoHolder.HasInfo (), CHIP_ERROR_NOT_CONNECTED);
148
185
149
- int rv = connect (sock, (struct sockaddr *) &server_addr, sizeof (server_addr));
150
- VerifyOrReturnError (rv >= 0 , CHIP_ERROR_POSIX (errno),
151
- ChipLogError (chipTool, " %s%s:%u" , kErrorConnection , hostname.c_str (), port));
186
+ auto * res = addressInfoHolder.Get ();
187
+ for (struct addrinfo * p = res; p != nullptr ; p = p->ai_next )
188
+ {
189
+ sock = socket (p->ai_family , p->ai_socktype , p->ai_protocol );
190
+ if (sock < 0 )
191
+ {
192
+ continue ; // Try the next address
193
+ }
194
+
195
+ if (connect (sock, p->ai_addr , p->ai_addrlen ) != 0 )
196
+ {
197
+ close (sock);
198
+ sock = -1 ;
199
+ continue ; // Try the next address
200
+ }
201
+
202
+ return CHIP_NO_ERROR;
203
+ }
152
204
153
- return CHIP_NO_ERROR;
205
+ ChipLogError (chipTool, " %s%s:%u" , kErrorConnection , hostname.c_str (), port);
206
+ return CHIP_ERROR_NOT_CONNECTED;
154
207
}
155
208
156
209
CHIP_ERROR InitSSL (int sock)
0 commit comments