diff --git a/include/mbgl/ios/MGLMapboxEvents.h b/include/mbgl/ios/MGLMapboxEvents.h index 2c6f8151b..7a4c45fe1 100644 --- a/include/mbgl/ios/MGLMapboxEvents.h +++ b/include/mbgl/ios/MGLMapboxEvents.h @@ -25,7 +25,7 @@ extern NSString *const MGLEventGesturePanStart; extern NSString *const MGLEventGesturePinchStart; extern NSString *const MGLEventGestureRotateStart; -@interface MGLMapboxEvents : NSObject +@interface MGLMapboxEvents : NSObject // You must call these methods from the main thread. // diff --git a/platform/ios/MGLMapboxEvents.m b/platform/ios/MGLMapboxEvents.m index 4b010463d..42fcaba30 100644 --- a/platform/ios/MGLMapboxEvents.m +++ b/platform/ios/MGLMapboxEvents.m @@ -73,6 +73,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; @property (atomic) NSUInteger flushAt; @property (atomic) NSDateFormatter *rfc3339DateFormatter; @property (atomic) CGFloat scale; +@property (atomic) NSURLSession *session; @property (atomic) NSData *geoTrustCert; @@ -135,6 +136,8 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; // Configure Events Infrastructure // =============================== + _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil]; + // Load Local Copy of Server's Public Key NSString *cerPath = nil; NSArray *bundles = [NSBundle allFrameworks]; @@ -417,9 +420,17 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; [request setHTTPBody:jsonData]; // Send non blocking HTTP Request to server - NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:strongSelf startImmediately:NO]; - [connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; - [connection start]; + NSURLSessionDataTask *task = [_session dataTaskWithRequest:request + completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) { + + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + NSLog(@"Response Code = %ld", (long)httpResponse.statusCode); + }]; + [task resume]; + +// NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:strongSelf startImmediately:NO]; +// [connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; +// [connection start]; } }); } @@ -660,6 +671,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; return result; } +/* #pragma mark NSURLConnectionDelegate - (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { @@ -703,5 +715,53 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; [[challenge sender] cancelAuthenticationChallenge:challenge]; } } +*/ + +#pragma mark NSURLSessionDelegate +- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^) (NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { + + if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { + + SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust]; + NSString *domain = [[challenge protectionSpace] host]; + SecTrustResultType trustResult; + + // Validate the certificate chain with the device's trust store anyway + // This *might* give use revocation checking + SecTrustEvaluate(serverTrust, &trustResult); + if (trustResult == kSecTrustResultUnspecified) + { + // Look for a pinned certificate in the server's certificate chain + long numKeys = SecTrustGetCertificateCount(serverTrust); + + BOOL found = false; + for (int lc = 0; lc < numKeys; lc++) { + SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, lc); + NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate)); + + // Compare Remote Key With Local Version + if ([remoteCertificateData isEqualToData:_geoTrustCert]) { + // Found the certificate; continue connecting + completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + found = true; + break; + } + } + + if (!found) { + // The certificate wasn't found in the certificate chain; cancel the connection + completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + } + NSLog(@"challenge result = %hhd", found); + } + else + { + // Certificate chain validation failed; cancel the connection + completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + NSLog(@"challenge chain validation failed"); + } + } + +} @end