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
};
@@ -83,17 +94,56 @@ constexpr const char * kErrorSSLContextCreate = "Failed to create SSL context
83
94
constexpr const char * kErrorSSLObjectCreate = " Failed to create SSL object" ;
84
95
constexpr const char * kErrorSSLHandshake = " SSL handshake failed" ;
85
96
constexpr const char * kErrorDigestMismatch = " The response digest does not match the expected digest" ;
97
+ class AddressInfoHolder
98
+ {
99
+ public:
100
+ AddressInfoHolder (std::string & hostname, uint16_t port)
101
+ {
102
+ struct addrinfo hints = {};
103
+ hints.ai_family = AF_INET;
104
+ hints.ai_socktype = SOCK_STREAM;
105
+ int err = getaddrinfo (hostname.c_str (), std::to_string (port).c_str (), &hints, &mRes );
106
+
107
+ #if CHIP_ERROR_LOGGING
108
+ constexpr const char * kErrorGetAddressInfo = " Failed to get address info: " ;
109
+ VerifyOrDo (nullptr != mRes , ChipLogError (chipTool, " %s%s" , kErrorGetAddressInfo , gai_strerror (err)));
110
+ #else
111
+ (void ) err;
112
+ #endif
113
+ }
114
+
115
+ ~AddressInfoHolder ()
116
+ {
117
+ if (mRes != nullptr )
118
+ {
119
+ freeaddrinfo (mRes );
120
+ }
121
+ }
122
+
123
+ bool HasInfo () const { return mRes != nullptr ; }
124
+ struct addrinfo * Get () const { return mRes ; }
125
+
126
+ private:
127
+ struct addrinfo * mRes = nullptr ;
128
+ };
129
+
86
130
class HTTPSSessionHolder
87
131
{
88
132
public:
89
133
HTTPSSessionHolder (){};
90
134
91
135
~HTTPSSessionHolder ()
92
136
{
93
- VerifyOrReturn (nullptr != mContext );
94
- SSL_free (mSSL );
95
- SSL_CTX_free (mContext );
96
- close (mSock );
137
+ if (nullptr != mContext )
138
+ {
139
+ SSL_free (mSSL );
140
+ SSL_CTX_free (mContext );
141
+ }
142
+
143
+ if (mSock >= 0 )
144
+ {
145
+ close (mSock );
146
+ }
97
147
98
148
#if !defined(OPENSSL_IS_BORINGSSL)
99
149
EVP_cleanup ();
@@ -134,23 +184,30 @@ class HTTPSSessionHolder
134
184
private:
135
185
CHIP_ERROR InitSocket (std::string & hostname, uint16_t port, int & sock)
136
186
{
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 );
187
+ AddressInfoHolder addressInfoHolder (hostname, port);
188
+ VerifyOrReturnError (addressInfoHolder.HasInfo (), CHIP_ERROR_NOT_CONNECTED);
148
189
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));
190
+ auto * res = addressInfoHolder.Get ();
191
+ for (struct addrinfo * p = res; p != nullptr ; p = p->ai_next )
192
+ {
193
+ sock = socket (p->ai_family , p->ai_socktype , p->ai_protocol );
194
+ if (sock < 0 )
195
+ {
196
+ continue ; // Try the next address
197
+ }
198
+
199
+ if (connect (sock, p->ai_addr , p->ai_addrlen ) != 0 )
200
+ {
201
+ close (sock);
202
+ sock = -1 ;
203
+ continue ; // Try the next address
204
+ }
205
+
206
+ return CHIP_NO_ERROR;
207
+ }
152
208
153
- return CHIP_NO_ERROR;
209
+ ChipLogError (chipTool, " %s%s:%u" , kErrorConnection , hostname.c_str (), port);
210
+ return CHIP_ERROR_NOT_CONNECTED;
154
211
}
155
212
156
213
CHIP_ERROR InitSSL (int sock)
0 commit comments