You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
OCSP requests do not follow NSURLProtocol subclassing. Therefore OCSP requests are not proxied when using an NSURLProtocol subclass to proxy all traffic.
Our current workaround is to inspect the X.509v3 certificate being authenticated for OCSP URLs and then make the requests ourselves; subsequently attaching the response with SecTrustSetOCSPResponse(). Reference: https://github.com/Psiphon-Labs/OCSPCache.
Our Solution
In our implementation we do the following:
Check if there is a pinned OCSP response
Call SecTrustEvaluate with revocation policy SecPolicyCreateRevocation(kSecRevocationOCSPMethod|kSecRevocationRequirePositiveResponse|kSecRevocationNetworkAccessDisabled)
If SecTrustEvaluate succeeds, assume there was a pinned OCSP response
Make OCSP request manually through local proxy
Inspect leaf X.509v3 certificate of serverTrust in URLSession:task:didReceiveChallenge:completionHandler: for OCSP URLs
Make OCSP requests and attach OCSP response to trust
Call SecTrustEvaluate with revocation policy SecPolicyCreateRevocation(kSecRevocationOCSPMethod|kSecRevocationRequirePositiveResponse|kSecRevocationNetworkAccessDisabled)
We are only attaching the OCSP response for the leaf certificate being authenticated. Will plaintext OCSP requests be made by the system for intermediate certificates?
Description
DESCRIPTION OF PROBLEM
OCSP requests do not follow NSURLProtocol subclassing. Therefore OCSP requests are not proxied when using an NSURLProtocol subclass to proxy all traffic.
Issue in more detail: OnionBrowser/OnionBrowser#178.
Our current workaround is to inspect the X.509v3 certificate being authenticated for OCSP URLs and then make the requests ourselves; subsequently attaching the response with
SecTrustSetOCSPResponse()
. Reference: https://github.com/Psiphon-Labs/OCSPCache.Our Solution
In our implementation we do the following:
SecPolicyCreateRevocation(kSecRevocationOCSPMethod|kSecRevocationRequirePositiveResponse|kSecRevocationNetworkAccessDisabled)
SecTrustEvaluate
succeeds, assume there was a pinned OCSP responseURLSession:task:didReceiveChallenge:completionHandler:
for OCSP URLsSecTrustEvaluate
with revocation policySecPolicyCreateRevocation(kSecRevocationOCSPMethod|kSecRevocationRequirePositiveResponse|kSecRevocationNetworkAccessDisabled)
Note: Since we are caching OCSP responses, but do not know when iOS considers responses valid/invalid we only evict responses when
SecTrustEvaluate
fails with an OCSP response fetched out of band. If the response we attach was cached then we make another remote request for a new response. This can be seen here: https://github.com/Psiphon-Labs/OCSPCache/blob/b945a5784cd88ed5693a62a931617bd371f3c9a8/OCSPCache/Classes/OCSPAuthURLSessionDelegate.m#L196-L216.Questions
Is the assumption above regarding pinned OCSP responses correct?
Are the revocation checks in https://github.com/Psiphon-Labs/OCSPCache/blob/b945a5784cd88ed5693a62a931617bd371f3c9a8/OCSPCache/Classes/OCSPAuthURLSessionDelegate.m#L138 performed correctly?
We are only attaching the OCSP response for the leaf certificate being authenticated. Will plaintext OCSP requests be made by the system for intermediate certificates?
STEPS TO REPRODUCE
Create NSURLProtocol subclass which proxies all traffic through a SOCKS or HTTP proxy by setting connection proxy dictionary (https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1411499-connectionproxydictionary?language=objc)
Note: There are tests in https://github.com/Psiphon-Labs/OCSPCache which shed some light on implementation details and expected behaviour.
Product Version: iOS 8+
Created: 2019-07-09T15:46:04.950021
Originated: 2019-07-09T00:00:00
Open Radar Link: http://www.openradar.me/716337334
The text was updated successfully, but these errors were encountered: