Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "components/cronet/ios/Cronet.h" | 5 #import "components/cronet/ios/Cronet.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 41 QuicHintVector gQuicHints; | 41 QuicHintVector gQuicHints; |
| 42 NSString* gExperimentalOptions = @"{}"; | 42 NSString* gExperimentalOptions = @"{}"; |
| 43 NSString* gUserAgent = nil; | 43 NSString* gUserAgent = nil; |
| 44 BOOL gUserAgentPartial = NO; | 44 BOOL gUserAgentPartial = NO; |
| 45 NSString* gSslKeyLogFileName = nil; | 45 NSString* gSslKeyLogFileName = nil; |
| 46 std::vector<std::unique_ptr<cronet::URLRequestContextConfig::Pkp>> gPkpList; | 46 std::vector<std::unique_ptr<cronet::URLRequestContextConfig::Pkp>> gPkpList; |
| 47 RequestFilterBlock gRequestFilterBlock = nil; | 47 RequestFilterBlock gRequestFilterBlock = nil; |
| 48 base::LazyInstance<std::unique_ptr<CronetHttpProtocolHandlerDelegate>>::Leaky | 48 base::LazyInstance<std::unique_ptr<CronetHttpProtocolHandlerDelegate>>::Leaky |
| 49 gHttpProtocolHandlerDelegate = LAZY_INSTANCE_INITIALIZER; | 49 gHttpProtocolHandlerDelegate = LAZY_INSTANCE_INITIALIZER; |
| 50 NSURLCache* gPreservedSharedURLCache = nil; | 50 NSURLCache* gPreservedSharedURLCache = nil; |
| 51 BOOL gEnableTestCertVerifierForTesting = FALSE; | 51 BOOL gEnableTestCertVerifierForTesting = NO; |
| 52 std::unique_ptr<net::CertVerifier> gMockCertVerifier; | 52 std::unique_ptr<net::CertVerifier> gMockCertVerifier; |
| 53 NSString* gAcceptLanguages = nil; | 53 NSString* gAcceptLanguages = nil; |
| 54 BOOL gEnablePKPBypassForLocalTrustAnchors = YES; | |
| 54 | 55 |
| 55 // CertVerifier, which allows any certificates for testing. | 56 // CertVerifier, which allows any certificates for testing. |
| 56 class TestCertVerifier : public net::CertVerifier { | 57 class TestCertVerifier : public net::CertVerifier { |
| 57 int Verify(const RequestParams& params, | 58 int Verify(const RequestParams& params, |
| 58 net::CRLSet* crl_set, | 59 net::CRLSet* crl_set, |
| 59 net::CertVerifyResult* verify_result, | 60 net::CertVerifyResult* verify_result, |
| 60 const net::CompletionCallback& callback, | 61 const net::CompletionCallback& callback, |
| 61 std::unique_ptr<Request>* out_req, | 62 std::unique_ptr<Request>* out_req, |
| 62 const net::NetLogWithSource& net_log) override { | 63 const net::NetLogWithSource& net_log) override { |
| 63 net::Error result = net::OK; | 64 net::Error result = net::OK; |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 gRequestFilterBlock = block; | 219 gRequestFilterBlock = block; |
| 219 } | 220 } |
| 220 | 221 |
| 221 + (BOOL)addPublicKeyPinsForHost:(NSString*)host | 222 + (BOOL)addPublicKeyPinsForHost:(NSString*)host |
| 222 pinHashes:(NSSet<NSData*>*)pinHashes | 223 pinHashes:(NSSet<NSData*>*)pinHashes |
| 223 includeSubdomains:(BOOL)includeSubdomains | 224 includeSubdomains:(BOOL)includeSubdomains |
| 224 expirationDate:(NSDate*)expirationDate | 225 expirationDate:(NSDate*)expirationDate |
| 225 error:(NSError**)outError { | 226 error:(NSError**)outError { |
| 226 [self checkNotStarted]; | 227 [self checkNotStarted]; |
| 227 | 228 |
| 229 // Pinning a key only makes sense if pin bypassing has been disabled | |
| 230 if (gEnablePKPBypassForLocalTrustAnchors) { | |
| 231 *outError = | |
| 232 [self createUnsupportedConfigurationError: | |
| 233 @"Cannot pin keys while public key pinning is bypassed"]; | |
| 234 return NO; | |
| 235 } | |
| 236 | |
| 228 auto pkp = base::MakeUnique<cronet::URLRequestContextConfig::Pkp>( | 237 auto pkp = base::MakeUnique<cronet::URLRequestContextConfig::Pkp>( |
| 229 base::SysNSStringToUTF8(host), includeSubdomains, | 238 base::SysNSStringToUTF8(host), includeSubdomains, |
| 230 base::Time::FromCFAbsoluteTime( | 239 base::Time::FromCFAbsoluteTime( |
| 231 [expirationDate timeIntervalSinceReferenceDate])); | 240 [expirationDate timeIntervalSinceReferenceDate])); |
| 232 | 241 |
| 233 for (NSData* hash in pinHashes) { | 242 for (NSData* hash in pinHashes) { |
| 234 net::SHA256HashValue hashValue = net::SHA256HashValue(); | 243 net::SHA256HashValue hashValue = net::SHA256HashValue(); |
| 235 if (sizeof(hashValue.data) != hash.length) { | 244 if (sizeof(hashValue.data) != hash.length) { |
| 236 *outError = | 245 *outError = |
| 237 [self createIllegalArgumentErrorWithArgument:@"pinHashes" | 246 [self createIllegalArgumentErrorWithArgument:@"pinHashes" |
| 238 reason: | 247 reason: |
| 239 @"The length of PKP SHA256 " | 248 @"The length of PKP SHA256 " |
| 240 @"hash should be 256 bits"]; | 249 @"hash should be 256 bits"]; |
| 241 return NO; | 250 return NO; |
| 242 } | 251 } |
| 243 memcpy((void*)(hashValue.data), [hash bytes], sizeof(hashValue.data)); | 252 memcpy((void*)(hashValue.data), [hash bytes], sizeof(hashValue.data)); |
| 244 pkp->pin_hashes.push_back(net::HashValue(hashValue)); | 253 pkp->pin_hashes.push_back(net::HashValue(hashValue)); |
| 245 } | 254 } |
| 246 gPkpList.push_back(std::move(pkp)); | 255 gPkpList.push_back(std::move(pkp)); |
| 247 if (outError) { | 256 if (outError) { |
| 248 *outError = nil; | 257 *outError = nil; |
| 249 } | 258 } |
| 250 return YES; | 259 return YES; |
| 251 } | 260 } |
| 252 | 261 |
| 262 + (void)setEnablePublicKeyPinningBypassForLocalTrustAnchors:(BOOL)enable { | |
| 263 gEnablePKPBypassForLocalTrustAnchors = enable; | |
| 264 } | |
| 265 | |
| 253 + (void)startInternal { | 266 + (void)startInternal { |
| 254 std::string user_agent = base::SysNSStringToUTF8(gUserAgent); | 267 std::string user_agent = base::SysNSStringToUTF8(gUserAgent); |
| 255 | 268 |
| 256 gChromeNet.Get().reset( | 269 gChromeNet.Get().reset( |
| 257 new cronet::CronetEnvironment(user_agent, gUserAgentPartial)); | 270 new cronet::CronetEnvironment(user_agent, gUserAgentPartial)); |
| 258 | 271 |
| 259 gChromeNet.Get()->set_accept_language( | 272 gChromeNet.Get()->set_accept_language( |
| 260 base::SysNSStringToUTF8(gAcceptLanguages ?: [self getAcceptLanguages])); | 273 base::SysNSStringToUTF8(gAcceptLanguages ?: [self getAcceptLanguages])); |
| 261 | 274 |
| 262 gChromeNet.Get()->set_http2_enabled(gHttp2Enabled); | 275 gChromeNet.Get()->set_http2_enabled(gHttp2Enabled); |
| 263 gChromeNet.Get()->set_quic_enabled(gQuicEnabled); | 276 gChromeNet.Get()->set_quic_enabled(gQuicEnabled); |
| 264 gChromeNet.Get()->set_experimental_options( | 277 gChromeNet.Get()->set_experimental_options( |
| 265 base::SysNSStringToUTF8(gExperimentalOptions)); | 278 base::SysNSStringToUTF8(gExperimentalOptions)); |
| 266 gChromeNet.Get()->set_http_cache(gHttpCache); | 279 gChromeNet.Get()->set_http_cache(gHttpCache); |
| 267 gChromeNet.Get()->set_ssl_key_log_file_name( | 280 gChromeNet.Get()->set_ssl_key_log_file_name( |
| 268 base::SysNSStringToUTF8(gSslKeyLogFileName)); | 281 base::SysNSStringToUTF8(gSslKeyLogFileName)); |
| 269 gChromeNet.Get()->set_pkp_list(std::move(gPkpList)); | 282 gChromeNet.Get()->set_pkp_list(std::move(gPkpList)); |
| 283 gChromeNet.Get() | |
| 284 ->set_enable_public_key_pinning_bypass_for_local_trust_anchors( | |
| 285 gEnablePKPBypassForLocalTrustAnchors); | |
| 270 for (const auto& quicHint : gQuicHints) { | 286 for (const auto& quicHint : gQuicHints) { |
| 271 gChromeNet.Get()->AddQuicHint(quicHint->host, quicHint->port, | 287 gChromeNet.Get()->AddQuicHint(quicHint->host, quicHint->port, |
| 272 quicHint->alternate_port); | 288 quicHint->alternate_port); |
| 273 } | 289 } |
| 274 | 290 |
| 275 [self configureCronetEnvironmentForTesting:gChromeNet.Get().get()]; | 291 [self configureCronetEnvironmentForTesting:gChromeNet.Get().get()]; |
| 276 gChromeNet.Get()->Start(); | 292 gChromeNet.Get()->Start(); |
| 277 gHttpProtocolHandlerDelegate.Get().reset( | 293 gHttpProtocolHandlerDelegate.Get().reset( |
| 278 new CronetHttpProtocolHandlerDelegate( | 294 new CronetHttpProtocolHandlerDelegate( |
| 279 gChromeNet.Get()->GetURLRequestContextGetter(), gRequestFilterBlock)); | 295 gChromeNet.Get()->GetURLRequestContextGetter(), gRequestFilterBlock)); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 405 [NSString stringWithFormat:@"Invalid argument: %@", argumentName], | 421 [NSString stringWithFormat:@"Invalid argument: %@", argumentName], |
| 406 CRNInvalidArgumentKey : argumentName | 422 CRNInvalidArgumentKey : argumentName |
| 407 }]; | 423 }]; |
| 408 if (reason) { | 424 if (reason) { |
| 409 errorDictionary[NSLocalizedFailureReasonErrorKey] = reason; | 425 errorDictionary[NSLocalizedFailureReasonErrorKey] = reason; |
| 410 } | 426 } |
| 411 return [self createCronetErrorWith:CRNErrorInvalidArgument | 427 return [self createCronetErrorWith:CRNErrorInvalidArgument |
| 412 userInfo:errorDictionary]; | 428 userInfo:errorDictionary]; |
| 413 } | 429 } |
| 414 | 430 |
| 431 + (NSError*)createUnsupportedConfigurationError:(NSString*)contradiction { | |
| 432 NSMutableDictionary* errorDictionary = | |
|
kapishnikov
2017/06/28 15:32:23
Could we also add |NSLocalizedFailureReasonErrorKe
lilyhoughton
2017/06/28 15:52:06
Done.
| |
| 433 [[NSMutableDictionary alloc] initWithDictionary:@{ | |
| 434 NSLocalizedDescriptionKey : @"Unsupported configuration", | |
| 435 NSLocalizedRecoverySuggestionErrorKey : | |
| 436 @"Try disabling Public Key Pinning Bypass before pinning keys.", | |
| 437 }]; | |
| 438 if (contradiction) { | |
| 439 errorDictionary[NSLocalizedFailureReasonErrorKey] = contradiction; | |
| 440 } | |
| 441 | |
| 442 return [self createCronetErrorWith:CRNErrorUnsupportedConfig | |
| 443 userInfo:errorDictionary]; | |
| 444 } | |
| 445 | |
| 415 + (NSError*)createCronetErrorWith:(int)errorCode | 446 + (NSError*)createCronetErrorWith:(int)errorCode |
|
kapishnikov
2017/06/28 15:32:24
Could you rename this method from "createCronetErr
lilyhoughton
2017/06/28 15:52:06
Done.
| |
| 416 userInfo:(NSDictionary*)userInfo { | 447 userInfo:(NSDictionary*)userInfo { |
| 417 return [NSError errorWithDomain:CRNCronetErrorDomain | 448 return [NSError errorWithDomain:CRNCronetErrorDomain |
| 418 code:errorCode | 449 code:errorCode |
| 419 userInfo:userInfo]; | 450 userInfo:userInfo]; |
| 420 } | 451 } |
| 421 | 452 |
| 422 @end | 453 @end |
| OLD | NEW |