59
59
constexpr const char * kErrorConnectionTimeout = " Timeout connecting to: " ;
60
60
constexpr const char * kErrorConnectionUnknowState = " Unknown connection state" ;
61
61
constexpr const char * kErrorDigestMismatch = " The response digest does not match the expected digest" ;
62
+
63
+ constexpr sec_protocol_verify_t NULL_VERIFIER = ^(sec_protocol_metadata_t metadata,
64
+ sec_trust_t trust_ref,
65
+ sec_protocol_verify_complete_t complete) {
66
+ complete (true );
67
+ };
68
+
62
69
class HTTPSSessionHolder {
63
70
public:
64
71
HTTPSSessionHolder () {};
70
77
mConnection = nullptr ;
71
78
}
72
79
73
- CHIP_ERROR Init (std::string & hostname, uint16_t port)
80
+ CHIP_ERROR Init (std::string & hostname, uint16_t port, HttpsSecurityMode securityMode )
74
81
{
75
82
__auto_type semaphore = dispatch_semaphore_create (0 );
76
83
__block CHIP_ERROR result = CHIP_NO_ERROR;
84
+ __auto_type queue = dispatch_queue_create (kDispatchQueueName , DISPATCH_QUEUE_SERIAL);
77
85
78
86
__auto_type endpoint = nw_endpoint_create_host (hostname.c_str (), std::to_string (port).c_str ());
79
- nw_parameters_t parameters = nw_parameters_create_secure_tcp (NW_PARAMETERS_DEFAULT_CONFIGURATION, NW_PARAMETERS_DEFAULT_CONFIGURATION);
87
+
88
+ nw_parameters_configure_protocol_block_t tls_options;
89
+ switch (securityMode) {
90
+ case HttpsSecurityMode::kDefault : {
91
+ tls_options = NW_PARAMETERS_DEFAULT_CONFIGURATION;
92
+ break ;
93
+ }
94
+ case HttpsSecurityMode::kDisableValidation : {
95
+ tls_options = ^(nw_protocol_options_t tls_options) {
96
+ sec_protocol_options_t sec_options = nw_tls_copy_sec_protocol_options (tls_options);
97
+ sec_protocol_options_set_verify_block (sec_options, NULL_VERIFIER, queue);
98
+ };
99
+ break ;
100
+ }
101
+ case HttpsSecurityMode::kDisableHttps : {
102
+ tls_options = NW_PARAMETERS_DISABLE_PROTOCOL;
103
+ break ;
104
+ }
105
+ }
106
+
107
+ // NW_PARAMETERS_DISABLE_PROTOCOL
108
+ nw_parameters_t parameters = nw_parameters_create_secure_tcp (tls_options, NW_PARAMETERS_DEFAULT_CONFIGURATION);
80
109
81
110
mConnection = nw_connection_create (endpoint, parameters);
82
111
VerifyOrReturnError (nullptr != mConnection , CHIP_ERROR_INTERNAL);
@@ -101,7 +130,6 @@ CHIP_ERROR Init(std::string & hostname, uint16_t port)
101
130
}
102
131
});
103
132
104
- __auto_type queue = dispatch_queue_create (kDispatchQueueName , DISPATCH_QUEUE_SERIAL);
105
133
nw_connection_set_queue (mConnection , queue);
106
134
nw_connection_start (mConnection );
107
135
@@ -185,6 +213,7 @@ CHIP_ERROR ReceiveResponse(std::string & response)
185
213
186
214
CHIP_ERROR RemoveHeader (std::string & response)
187
215
{
216
+ // TODO: Parse the response status. Why are we doing HTTP by hand?
188
217
size_t headerEnd = response.find (" \r\n\r\n " );
189
218
VerifyOrReturnError (std::string::npos != headerEnd, CHIP_ERROR_INVALID_ARGUMENT);
190
219
@@ -290,27 +319,40 @@ CHIP_ERROR ExtractHostNamePortPath(std::string url, std::string & outHostName, u
290
319
} // namespace
291
320
292
321
CHIP_ERROR Request (std::string url, Json::Value & jsonResponse, const Optional<uint32_t > & optionalExpectedSize,
293
- const Optional<const char *> & optionalExpectedDigest)
322
+ const Optional<const char *> & optionalExpectedDigest, HttpsSecurityMode securityMode )
294
323
{
295
324
std::string hostname;
296
325
uint16_t port;
297
326
std::string path;
298
327
ReturnErrorOnFailure (ExtractHostNamePortPath (url, hostname, port, path));
299
- return Request (hostname, port, path, jsonResponse, optionalExpectedSize, optionalExpectedDigest);
328
+ return Request (hostname, port, path, jsonResponse, optionalExpectedSize, optionalExpectedDigest, securityMode );
300
329
}
301
330
302
331
CHIP_ERROR Request (std::string hostname, uint16_t port, std::string path, Json::Value & jsonResponse,
303
- const Optional<uint32_t > & optionalExpectedSize, const Optional<const char *> & optionalExpectedDigest)
332
+ const Optional<uint32_t > & optionalExpectedSize, const Optional<const char *> & optionalExpectedDigest,
333
+ HttpsSecurityMode securityMode)
304
334
{
305
335
VerifyOrDo (port != 0 , port = kHttpsPort );
306
336
307
- ChipLogDetail (chipTool, " HTTPS request to %s:%u%s" , hostname.c_str (), port, path.c_str ());
337
+ char const * protocol;
338
+ switch (securityMode) {
339
+ case HttpsSecurityMode::kDefault :
340
+ protocol = " HTTPS" ;
341
+ break ;
342
+ case HttpsSecurityMode::kDisableValidation :
343
+ protocol = " HTTPS (no validation)" ;
344
+ break ;
345
+ case HttpsSecurityMode::kDisableHttps :
346
+ protocol = " HTTP" ;
347
+ break ;
348
+ }
349
+ ChipLogDetail (chipTool, " %s request to %s:%u%s" , protocol, hostname.c_str (), port, path.c_str ());
308
350
309
351
std::string request = BuildRequest (hostname, path);
310
352
std::string response;
311
353
312
354
HTTPSSessionHolder session;
313
- ReturnErrorOnFailure (session.Init (hostname, port));
355
+ ReturnErrorOnFailure (session.Init (hostname, port, securityMode ));
314
356
ReturnErrorOnFailure (session.SendRequest (request));
315
357
ReturnErrorOnFailure (session.ReceiveResponse (response));
316
358
ReturnErrorOnFailure (RemoveHeader (response));
0 commit comments