Explorar el Código

Update OCSPCache

Motivation:
OCSPCache now offers code for evaluating auth
challenges which provides control over how OCSP
requests are made.

Modifications:
- Remove AuthURLSessionTaskDelegate
- Use OCSPAuthURLSessionDelegate

Result:
Auth challenges are now evaulated with code provided
by OCSPCache.
mirokuratczyk hace 6 años
padre
commit
fd9652c7ed

+ 0 - 66
MobileLibrary/iOS/SampleApps/Common/AuthURLSessionTaskDelegate.h

@@ -1,66 +0,0 @@
-//
-//  AuthURLSessionTaskDelegate.h
-//  TunneledWebRequest
-//
-/*
- Licensed under Creative Commons Zero (CC0).
- https://creativecommons.org/publicdomain/zero/1.0/
- */
-
-
-// NOTE: this file is shared by TunneledWebRequest and TunneledWebView
-
-#import <Foundation/Foundation.h>
-#import "OCSPCache.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-/*!
- * AuthURLSessionTaskDelegate implements URLSession:task:didReceiveChallenge:completionHandler:
- * of the NSURLSessionTaskDelegate protocol.
- *
- * The main motivation of AuthURLSessionTaskDelegate is to ensure that OCSP requests are not
- * sent in plaintext outside of the tunnel.
- *
- * If the policy object for checking the revocation of certificates is created with
- * SecPolicyCreateRevocation(kSecRevocationOCSPMethod | ...), and network access is allowed
- * (the kSecRevocationNetworkAccessDisabled flag is not provided), a plaintext OCSP request over
- * HTTP is triggered when SecTrustEvaluate() is called. This request does not respect NSURLProtocol
- * subclassing.
- *
- * The solution is to inspect each X.509 certificate for the Online Certificate Status Protocol
- * (1.3.6.1.5.5.7.48.1) Authority Information Access Method, which contains the locations (URLs) of
- * the OCSP servers; then OCSP requests are then made to these servers through the local HTTP proxy.
- *
- * Note: AuthURLSessionTaskDelegate only checks revocation status with OCSP.
- *
- * Note: The OCSP Authority Information Access Method is found in the Certificate Authority
- *       Information Access (1.3.6.1.5.5.7.1.1) X.509v3 extension --
- *       https://tools.ietf.org/html/rfc2459#section-4.2.2.1.
- */
-@interface AuthURLSessionTaskDelegate : NSObject <NSURLSessionDelegate>
-
-/*!
- * Logger for errors.
- */
-@property (nonatomic, strong) void (^logger)(NSString*);
-
-/*!
- * Local HTTP proxy port.
- *
- * OCSP request URL is constructed as:
- *   http://127.0.0.1:<HTTP proxy port>/tunneled/<URL encoded OCSP request>
- */
-@property (atomic, assign) NSInteger localHTTPProxyPort;
-
--  (id)initWithLogger:(void (^)(NSString*))logger
-andLocalHTTPProxyPort:(NSInteger)port;
-
-- (void)URLSession:(NSURLSession *)session
-              task:(NSURLSessionTask *)task
-didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
- completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 160
MobileLibrary/iOS/SampleApps/Common/AuthURLSessionTaskDelegate.m

@@ -1,160 +0,0 @@
-//
-//  AuthURLSessionTaskDelegate.m
-//  TunneledWebRequest
-//
-/*
- Licensed under Creative Commons Zero (CC0).
- https://creativecommons.org/publicdomain/zero/1.0/
- */
-
-
-// NOTE: this file is shared by TunneledWebRequest and TunneledWebView
-
-#import "AuthURLSessionTaskDelegate.h"
-
-#import "OCSPCache.h"
-#import "OCSPURLEncode.h"
-
-@implementation AuthURLSessionTaskDelegate {
-    OCSPCache *ocspCache;
-}
-
--  (id)initWithLogger:(void (^)(NSString*))logger
-andLocalHTTPProxyPort:(NSInteger)port {
-    self = [super init];
-
-    if (self) {
-        self.logger = logger;
-        self.localHTTPProxyPort = port;
-        self->ocspCache = [[OCSPCache alloc] initWithLogger:^(NSString * _Nonnull logLine) {
-            [self logWithFormat:@"[OCSPCache] %@", logLine];
-        }];
-    }
-
-    return self;
-}
-
-- (void)logWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1, 2) {
-    if (self.logger != nil) {
-        va_list arguments;
-        
-        va_start(arguments, format);
-        NSString *message = [[NSString alloc] initWithFormat:format arguments:arguments];
-        va_end(arguments);
-        
-        self.logger(message);
-    }
-}
-
-- (void)URLSession:(NSURLSession *)session
-              task:(NSURLSessionTask *)task
-didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
- completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
-{
-#pragma unused(session)
-#pragma unused(task)
-    assert(challenge != nil);
-    assert(completionHandler != nil);
-    
-    // Resolve NSURLAuthenticationMethodServerTrust ourselves
-    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
-        [self logWithFormat:@"Got SSL certificate for %@, mainDocumentURL: %@, URL: %@",
-         challenge.protectionSpace.host,
-         [task.currentRequest mainDocumentURL],
-         [task.currentRequest URL]];
-
-        SecTrustRef trust = challenge.protectionSpace.serverTrust;
-        if (trust == nil) {
-            assert(NO);
-        }
-
-        SecPolicyRef policy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod |
-                                                        kSecRevocationRequirePositiveResponse |
-                                                        kSecRevocationNetworkAccessDisabled);
-        SecTrustSetPolicies(trust, policy);
-        CFRelease(policy);
-
-        // Check if there is a pinned or cached OCSP response
-
-        SecTrustResultType trustResultType;
-        SecTrustEvaluate(trust, &trustResultType);
-
-        if (   trustResultType == kSecTrustResultProceed
-            || trustResultType == kSecTrustResultUnspecified) {
-            [self logWithFormat:@"Pinned or cached OCSP response found by the system"];
-            NSURLCredential *credential = [NSURLCredential credentialForTrust:trust];
-            assert(credential != nil);
-            completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
-            return;
-        }
-
-        // No pinned OCSP response, try fetching one
-
-        [self logWithFormat:@"Fetching OCSP response through OCSPCache"];
-
-        NSURL* (^modifyOCSPURL)(NSURL *url) = ^NSURL*(NSURL *url) {
-            return [self modifyOCSPURL:url];
-        };
-
-        [ocspCache lookup:trust
-               andTimeout:0
-            modifyOCSPURL:modifyOCSPURL
-               completion:
-         ^(OCSPCacheLookupResult * _Nonnull result) {
-
-             assert(result.response != nil);
-             assert(result.err == nil);
-
-             if (result.cached) {
-                 [self logWithFormat:@"Got cached OCSP response from OCSPCache"];
-             } else {
-                 [self logWithFormat:@"Fetched OCSP response from remote"];
-             }
-
-             CFDataRef d = (__bridge CFDataRef)result.response.data;
-
-             SecTrustSetOCSPResponse(trust, d);
-
-             SecTrustResultType trustResultType;
-             SecTrustEvaluate(trust, &trustResultType);
-
-             if (   trustResultType == kSecTrustResultProceed
-                 || trustResultType == kSecTrustResultUnspecified) {
-                 NSURLCredential *credential = [NSURLCredential credentialForTrust:trust];
-                 assert(credential != nil);
-                 completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
-                 return;
-             }
-
-             // Reject the protection space.
-             // Do not use NSURLSessionAuthChallengePerformDefaultHandling because it can trigger
-             // plaintext OCSP requests.
-             completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
-             return;
-        }];
-
-        return;
-    }
-
-    completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
-}
-
-// Modify the OCSP URLs so they use the local HTTP proxy
-- (nonnull NSURL *)modifyOCSPURL:(nonnull NSURL *)url {
-
-    // The target URL must be encoded, so as to be valid within a query parameter.
-    NSString *encodedTargetUrl = [URLEncode encode:url.absoluteString];
-
-    NSNumber *httpProxyPort = [NSNumber numberWithInt:(int)self.localHTTPProxyPort];
-
-    NSString *proxiedURLString = [NSString stringWithFormat:@"http://127.0.0.1:%@/tunneled/%@",
-                                                            httpProxyPort,
-                                                            encodedTargetUrl];
-    NSURL *proxiedURL = [NSURL URLWithString:proxiedURLString];
-
-    [self logWithFormat:@"[OCSPCache] updated OCSP URL %@ to %@", url, proxiedURL];
-
-    return proxiedURL;
-}
-
-@end

+ 1 - 1
MobileLibrary/iOS/SampleApps/TunneledWebRequest/Podfile

@@ -3,7 +3,7 @@ platform :ios, '10.0'
 target 'TunneledWebRequest' do
     pod 'OpenSSL-Universal', '1.0.2.17'
     pod 'PsiphonTunnel', :git => 'https://github.com/Psiphon-Labs/psiphon-tunnel-core-iOS-library.git'
-    pod 'OCSPCache', :git => "https://github.com/Psiphon-Labs/OCSPCache.git", :commit => '647c7b0'
+    pod 'OCSPCache', :git => "https://github.com/Psiphon-Labs/OCSPCache.git", :commit => '9d7820e'
     #pod 'OCSPCache', :path => "../../../../../OCSPCache/"
 end
 

+ 4 - 4
MobileLibrary/iOS/SampleApps/TunneledWebRequest/Podfile.lock

@@ -7,20 +7,20 @@ PODS:
   - ReactiveObjC (3.1.1)
 
 DEPENDENCIES:
-  - OCSPCache (from `https://github.com/Psiphon-Labs/OCSPCache.git`, commit `647c7b0`)
+  - OCSPCache (from `https://github.com/Psiphon-Labs/OCSPCache.git`, commit `9d7820e`)
   - OpenSSL-Universal (= 1.0.2.17)
   - PsiphonTunnel (from `https://github.com/Psiphon-Labs/psiphon-tunnel-core-iOS-library.git`)
 
 EXTERNAL SOURCES:
   OCSPCache:
-    :commit: 647c7b0
+    :commit: 9d7820e
     :git: https://github.com/Psiphon-Labs/OCSPCache.git
   PsiphonTunnel:
     :git: https://github.com/Psiphon-Labs/psiphon-tunnel-core-iOS-library.git
 
 CHECKOUT OPTIONS:
   OCSPCache:
-    :commit: 647c7b0
+    :commit: 9d7820e
     :git: https://github.com/Psiphon-Labs/OCSPCache.git
   PsiphonTunnel:
     :commit: c9af3bab93637163e117de9d1e77435baa7646c0
@@ -32,6 +32,6 @@ SPEC CHECKSUMS:
   PsiphonTunnel: 0c3f8677e4b26316beba57df78ed9c75634ce091
   ReactiveObjC: 011caa393aa0383245f2dcf9bf02e86b80b36040
 
-PODFILE CHECKSUM: 7ea04fcb82030754b54bcd4129e9c93671a6c15d
+PODFILE CHECKSUM: e2f36d288d3199ef090bf05356b5f9b08ed0671b
 
 COCOAPODS: 1.4.0

+ 0 - 14
MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest.xcodeproj/project.pbxproj

@@ -16,7 +16,6 @@
 		6626590E1DCB8CF400872F6C /* TunneledWebRequestUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6626590D1DCB8CF400872F6C /* TunneledWebRequestUITests.swift */; };
 		6682D90E1EB1334000329958 /* psiphon-embedded-server-entries.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6682D90D1EB1334000329958 /* psiphon-embedded-server-entries.txt */; };
 		6688DBB61DCD684B00721A9E /* psiphon-config.json in Resources */ = {isa = PBXBuildFile; fileRef = 6688DBB51DCD684B00721A9E /* psiphon-config.json */; };
-		CEFA7EDD2295A5530078E41E /* AuthURLSessionTaskDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFA7EDB2295A5530078E41E /* AuthURLSessionTaskDelegate.m */; };
 		DEB1E38A2E15C48277D2E61E /* libPods-TunneledWebRequest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 37F726750F0082A9B17447DC /* libPods-TunneledWebRequest.a */; };
 /* End PBXBuildFile section */
 
@@ -68,8 +67,6 @@
 		6688DBB51DCD684B00721A9E /* psiphon-config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "psiphon-config.json"; sourceTree = "<group>"; };
 		6BA09789075034B337A791DA /* Pods-TunneledWebRequest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TunneledWebRequest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TunneledWebRequest/Pods-TunneledWebRequest.debug.xcconfig"; sourceTree = "<group>"; };
 		CEFA7EB82294A9BB0078E41E /* TunneledWebRequest-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TunneledWebRequest-Bridging-Header.h"; sourceTree = "<group>"; };
-		CEFA7EDB2295A5530078E41E /* AuthURLSessionTaskDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AuthURLSessionTaskDelegate.m; path = ../../../Common/AuthURLSessionTaskDelegate.m; sourceTree = "<group>"; };
-		CEFA7EDC2295A5530078E41E /* AuthURLSessionTaskDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AuthURLSessionTaskDelegate.h; path = ../../../Common/AuthURLSessionTaskDelegate.h; sourceTree = "<group>"; };
 		FC00C7E45B17A3FDBDC1BF85 /* Pods-TunneledWebRequest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TunneledWebRequest.release.xcconfig"; path = "Pods/Target Support Files/Pods-TunneledWebRequest/Pods-TunneledWebRequest.release.xcconfig"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
@@ -135,7 +132,6 @@
 			children = (
 				662658ED1DCB8CF300872F6C /* AppDelegate.swift */,
 				662658EF1DCB8CF300872F6C /* ViewController.swift */,
-				CEFA7EC22294B2D20078E41E /* URLSessionDelegate */,
 				662658F11DCB8CF300872F6C /* Main.storyboard */,
 				662658F41DCB8CF300872F6C /* Assets.xcassets */,
 				662658F61DCB8CF300872F6C /* LaunchScreen.storyboard */,
@@ -173,15 +169,6 @@
 			name = Frameworks;
 			sourceTree = "<group>";
 		};
-		CEFA7EC22294B2D20078E41E /* URLSessionDelegate */ = {
-			isa = PBXGroup;
-			children = (
-				CEFA7EDC2295A5530078E41E /* AuthURLSessionTaskDelegate.h */,
-				CEFA7EDB2295A5530078E41E /* AuthURLSessionTaskDelegate.m */,
-			);
-			path = URLSessionDelegate;
-			sourceTree = "<group>";
-		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
@@ -382,7 +369,6 @@
 			buildActionMask = 2147483647;
 			files = (
 				662658F01DCB8CF300872F6C /* ViewController.swift in Sources */,
-				CEFA7EDD2295A5530078E41E /* AuthURLSessionTaskDelegate.m in Sources */,
 				662658EE1DCB8CF300872F6C /* AppDelegate.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;

+ 19 - 5
MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/AppDelegate.swift

@@ -22,10 +22,25 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
     // The instance of PsiphonTunnel we'll use for connecting.
     var psiphonTunnel: PsiphonTunnel?
 
+    // OCSP cache for making OCSP requests in certificate revocation checking
+    var ocspCache: OCSPCache = OCSPCache.init(logger: {print("[OCSPCache]:", $0)})
+
     // Delegate for handling certificate validation.
-    var authURLSessionTaskDelegate: AuthURLSessionTaskDelegate =
-        AuthURLSessionTaskDelegate.init(logger: {print("[AuthURLSessionTaskDelegate]:", $0)},
-                                        andLocalHTTPProxyPort: 0)
+    lazy var authURLSessionDelegate: OCSPAuthURLSessionDelegate =
+        OCSPAuthURLSessionDelegate.init(logger: {print("[AuthURLSessionTaskDelegate]:", $0)},
+                                        ocspCache: self.ocspCache,
+                                        modifyOCSPURL:{
+                                            assert(self.httpProxyPort > 0)
+
+                                            let encodedTargetURL = URLEncode.encode($0.absoluteString)
+                                            let proxiedURLString = "http://127.0.0.1:\(self.httpProxyPort)/tunneled/\(encodedTargetURL!)"
+                                            let proxiedURL = URL.init(string: proxiedURLString)
+
+                                            print("[OCSP] Updated OCSP URL \($0) to \(proxiedURL!)")
+
+                                            return proxiedURL!
+                                        },
+                                        sessionConfig:nil)
 
     @objc public class func sharedDelegate() -> AppDelegate {
         var delegate: AppDelegate?
@@ -119,7 +134,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
         // config.connectionProxyDictionary?[kCFStreamPropertyHTTPSProxyHost as String] = "127.0.0.1"
         // config.connectionProxyDictionary?[kCFStreamPropertyHTTPSProxyPort as String] = self.httpProxyPort
 
-        let session = URLSession.init(configuration: config, delegate: authURLSessionTaskDelegate, delegateQueue: OperationQueue.current)
+        let session = URLSession.init(configuration: config, delegate: authURLSessionDelegate, delegateQueue: OperationQueue.current)
 
         // Create the URLSession task that will make the request via the tunnel proxy.
         let task = session.dataTask(with: request) {
@@ -364,7 +379,6 @@ extension AppDelegate: TunneledAppDelegate {
 
     func onListeningHttpProxyPort(_ port: Int) {
         DispatchQueue.main.async {
-            self.authURLSessionTaskDelegate.localHTTPProxyPort = port
             self.httpProxyPort = port
         }
     }

+ 1 - 1
MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/TunneledWebRequest-Bridging-Header.h

@@ -2,5 +2,5 @@
 //  Use this file to import your target's public headers that you would like to expose to Swift.
 //
 
-#import "AuthURLSessionTaskDelegate.h"
+#import "OCSPAuthURLSessionDelegate.h"
 #import "OCSPURLEncode.h"

+ 2 - 2
MobileLibrary/iOS/SampleApps/TunneledWebView/External/JiveAuthenticatingHTTPProtocol/JAHPAuthenticatingHTTPProtocol.m

@@ -51,7 +51,7 @@
 #import "JAHPCacheStoragePolicy.h"
 #import "JAHPQNSURLSessionDemux.h"
 
-#import "AuthURLSessionTaskDelegate.h"
+#import "OCSPAuthURLSessionDelegate.h"
 #import "TunneledWebView-Swift.h"
 
 // I use the following typedef to keep myself sane in the face of the wacky
@@ -795,7 +795,7 @@ didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
     if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
         // Delegate for handling certificate validation.
         // Makes OCSP requests through local HTTP proxy.
-        AuthURLSessionTaskDelegate *authHandler = [[AppDelegate sharedDelegate] authURLSessionTaskDelegate];
+        OCSPAuthURLSessionDelegate *authHandler = [[AppDelegate sharedDelegate] authURLSessionDelegate];
 
         [authHandler URLSession:session
                                 task:task

+ 1 - 1
MobileLibrary/iOS/SampleApps/TunneledWebView/Podfile

@@ -3,7 +3,7 @@ platform :ios, '10.0'
 target 'TunneledWebView' do
     pod 'OpenSSL-Universal', '1.0.2.17'
     pod 'PsiphonTunnel', :git => 'https://github.com/Psiphon-Labs/psiphon-tunnel-core-iOS-library.git'
-    pod 'OCSPCache', :git => "https://github.com/Psiphon-Labs/OCSPCache.git", :commit => '647c7b0'
+    pod 'OCSPCache', :git => "https://github.com/Psiphon-Labs/OCSPCache.git", :commit => '9d7820e'
     #pod 'OCSPCache', :path => "../../../../../OCSPCache/"
 end
 

+ 4 - 4
MobileLibrary/iOS/SampleApps/TunneledWebView/Podfile.lock

@@ -7,20 +7,20 @@ PODS:
   - ReactiveObjC (3.1.1)
 
 DEPENDENCIES:
-  - OCSPCache (from `https://github.com/Psiphon-Labs/OCSPCache.git`, commit `647c7b0`)
+  - OCSPCache (from `https://github.com/Psiphon-Labs/OCSPCache.git`, commit `9d7820e`)
   - OpenSSL-Universal (= 1.0.2.17)
   - PsiphonTunnel (from `https://github.com/Psiphon-Labs/psiphon-tunnel-core-iOS-library.git`)
 
 EXTERNAL SOURCES:
   OCSPCache:
-    :commit: 647c7b0
+    :commit: 9d7820e
     :git: https://github.com/Psiphon-Labs/OCSPCache.git
   PsiphonTunnel:
     :git: https://github.com/Psiphon-Labs/psiphon-tunnel-core-iOS-library.git
 
 CHECKOUT OPTIONS:
   OCSPCache:
-    :commit: 647c7b0
+    :commit: 9d7820e
     :git: https://github.com/Psiphon-Labs/OCSPCache.git
   PsiphonTunnel:
     :commit: c9af3bab93637163e117de9d1e77435baa7646c0
@@ -32,6 +32,6 @@ SPEC CHECKSUMS:
   PsiphonTunnel: 0c3f8677e4b26316beba57df78ed9c75634ce091
   ReactiveObjC: 011caa393aa0383245f2dcf9bf02e86b80b36040
 
-PODFILE CHECKSUM: 8a870dda0fa972bb0b856484a40170d5bb9da4c7
+PODFILE CHECKSUM: 4abc8555e10ac6f8a1ae5ad3eacff557c0c5b0fa
 
 COCOAPODS: 1.4.0

+ 0 - 6
MobileLibrary/iOS/SampleApps/TunneledWebView/TunneledWebView.xcodeproj/project.pbxproj

@@ -21,7 +21,6 @@
 		6626590E1DCB8CF400872F6C /* TunneledWebViewUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6626590D1DCB8CF400872F6C /* TunneledWebViewUITests.swift */; };
 		6682D90E1EB1334000329958 /* psiphon-embedded-server-entries.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6682D90D1EB1334000329958 /* psiphon-embedded-server-entries.txt */; };
 		6688DBB61DCD684B00721A9E /* psiphon-config.json in Resources */ = {isa = PBXBuildFile; fileRef = 6688DBB51DCD684B00721A9E /* psiphon-config.json */; };
-		CEFA7ED72294BC0C0078E41E /* AuthURLSessionTaskDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CEFA7ED62294BC0C0078E41E /* AuthURLSessionTaskDelegate.m */; };
 		DDFD23795085E5852A8F4DD5 /* libPods-TunneledWebView.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E472F80E34E361EB72B2FD0C /* libPods-TunneledWebView.a */; };
 /* End PBXBuildFile section */
 
@@ -82,8 +81,6 @@
 		6688DBB51DCD684B00721A9E /* psiphon-config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "psiphon-config.json"; sourceTree = "<group>"; };
 		76C8CF5D2CF9F4228B9CD56E /* Pods-TunneledWebView.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TunneledWebView.release.xcconfig"; path = "Pods/Target Support Files/Pods-TunneledWebView/Pods-TunneledWebView.release.xcconfig"; sourceTree = "<group>"; };
 		85795C6590EED64B7A6684AA /* Pods-TunneledWebView.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TunneledWebView.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TunneledWebView/Pods-TunneledWebView.debug.xcconfig"; sourceTree = "<group>"; };
-		CEFA7ED52294BC0C0078E41E /* AuthURLSessionTaskDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AuthURLSessionTaskDelegate.h; path = ../../../Common/AuthURLSessionTaskDelegate.h; sourceTree = "<group>"; };
-		CEFA7ED62294BC0C0078E41E /* AuthURLSessionTaskDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AuthURLSessionTaskDelegate.m; path = ../../../Common/AuthURLSessionTaskDelegate.m; sourceTree = "<group>"; };
 		E472F80E34E361EB72B2FD0C /* libPods-TunneledWebView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-TunneledWebView.a"; sourceTree = BUILT_PRODUCTS_DIR; };
 /* End PBXFileReference section */
 
@@ -116,8 +113,6 @@
 		4E0CA95F1FDE554B00B48BCA /* JiveAuthenticatingHTTPProtocol */ = {
 			isa = PBXGroup;
 			children = (
-				CEFA7ED52294BC0C0078E41E /* AuthURLSessionTaskDelegate.h */,
-				CEFA7ED62294BC0C0078E41E /* AuthURLSessionTaskDelegate.m */,
 				4E0CA9601FDE554B00B48BCA /* JAHPAuthenticatingHTTPProtocol.h */,
 				4E0CA9611FDE554B00B48BCA /* JAHPAuthenticatingHTTPProtocol.m */,
 				4E0CA9621FDE554B00B48BCA /* JAHPCacheStoragePolicy.h */,
@@ -410,7 +405,6 @@
 				4E0CA96B1FDE554B00B48BCA /* JAHPQNSURLSessionDemux.m in Sources */,
 				662658EE1DCB8CF300872F6C /* AppDelegate.swift in Sources */,
 				4E0CA9681FDE554B00B48BCA /* JAHPAuthenticatingHTTPProtocol.m in Sources */,
-				CEFA7ED72294BC0C0078E41E /* AuthURLSessionTaskDelegate.m in Sources */,
 				4E0CA9691FDE554B00B48BCA /* JAHPCacheStoragePolicy.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;

+ 17 - 4
MobileLibrary/iOS/SampleApps/TunneledWebView/TunneledWebView/AppDelegate.swift

@@ -22,10 +22,24 @@ import PsiphonTunnel
     // The instance of PsiphonTunnel we'll use for connecting.
     var psiphonTunnel: PsiphonTunnel?
 
+    // OCSP cache for making OCSP requests in certificate revocation checking
+    var ocspCache: OCSPCache = OCSPCache.init(logger: {print("[OCSPCache]:", $0)})
+
     // Delegate for handling certificate validation.
-    @objc public var authURLSessionTaskDelegate: AuthURLSessionTaskDelegate =
-        AuthURLSessionTaskDelegate.init(logger: {print("[AuthURLSessionTaskDelegate]:", $0)},
-                                         andLocalHTTPProxyPort: 0)
+    @objc public lazy var authURLSessionDelegate: OCSPAuthURLSessionDelegate =
+        OCSPAuthURLSessionDelegate.init(logger: {print("[AuthURLSessionTaskDelegate]:", $0)},
+                                        ocspCache: self.ocspCache,
+                                        modifyOCSPURL:{
+                                            assert(self.httpProxyPort > 0)
+
+                                            let encodedTargetURL = URLEncode.encode($0.absoluteString)
+                                            let proxiedURLString = "http://127.0.0.1:\(self.httpProxyPort)/tunneled/\(encodedTargetURL!)"
+                                            let proxiedURL = URL.init(string: proxiedURLString)
+
+                                            print("[OCSP] Updated OCSP URL \($0) to \(proxiedURL!)")
+
+                                            return proxiedURL!},
+                                        sessionConfig:nil)
     
     @objc public class func sharedDelegate() -> AppDelegate {
         var delegate: AppDelegate?
@@ -183,7 +197,6 @@ extension AppDelegate: TunneledAppDelegate {
 
     func onListeningHttpProxyPort(_ port: Int) {
         DispatchQueue.main.async {
-            self.authURLSessionTaskDelegate.localHTTPProxyPort = port
             JAHPAuthenticatingHTTPProtocol.resetSharedDemux()
             self.httpProxyPort = port
         }

+ 2 - 1
MobileLibrary/iOS/SampleApps/TunneledWebView/TunneledWebView/TunneledWebView-Bridging-Header.h

@@ -9,7 +9,8 @@
 #ifndef TunneledWebView_Bridging_Header_h
 #define TunneledWebView_Bridging_Header_h
 
-#import "AuthURLSessionTaskDelegate.h"
 #import "JAHPAuthenticatingHTTPProtocol.h"
+#import "OCSPAuthURLSessionDelegate.h"
+#import "OCSPURLEncode.h"
 
 #endif /* TunneledWebView_Bridging_Header_h */