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