Instabug/Instabug-iOS

NetworkLogger breaks client certificate authorization

davidblazek opened this issue · 8 comments

Steps to Reproduce the Problem

We're using a client certificate to authorize API calls. Using Alamofire session to provide client certificate in Alamofire SessionDelegate method like this works fine:

func urlSession(
        _ session: URLSession,
        didReceive challenge: URLAuthenticationChallenge,
        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
    ) {
        switch challenge.protectionSpace.authenticationMethod {
        case NSURLAuthenticationMethodClientCertificate:
            guard let identity = pkiService.identity, let certificate = pkiService.certificate else {
                return completionHandler(.performDefaultHandling, nil)
            }
            let urlCredential = URLCredential(
                identity: identity,
                certificates: [certificate],
                persistence: .none
            )
            return completionHandler(.useCredential, urlCredential)
        default:
            return completionHandler(.performDefaultHandling, nil)
        }
    }

Using NetworkLogger.enableLogging(for: configuration) breaks the delegate method above (method is not called). We've found in other related issues that this is a known behaviour and we should use setCanAuthenticateAgainstProtectionSpaceHandler method as an alternative. Nevertheless providing client certificate via this method is not working.

Expected Behavior

Authentication flow using Alamofire session delegate method has these two steps:

  1. method is called with challenge NSURLAuthenticationMethodServerTrust, code above returns .performDefaultHandling
  2. method is called again with challenge NSURLAuthenticationMethodClientCertificate, code above provides URLCredential with client certificate and all is fine

We expect the same flow in setCanAuthenticateAgainstProtectionSpaceHandler

Actual Behavior

Authentication flow using setCanAuthenticateAgainstProtectionSpaceHandler has only one step (referring to the Instabug integration code below) :

  1. method is called with challenge NSURLAuthenticationMethodServerTrust
  2. method is not called again with challenge NSURLAuthenticationMethodClientCertificate, therefore we're unable to provide client certificate

Note: no matter what we return from the first call (nil, empty URLCredential, challenge.proposedCredential), the second call never comes.

Instabug integration code

Here is our Instabug integration code snippet:

let configuration = URLSessionConfiguration.default
NetworkLogger.enableLogging(for: configuration)
NetworkLogger.setCanAuthenticateAgainstProtectionSpaceHandler { (urlProtectionSpace) -> Bool in
    return true
}
NetworkLogger.setDidReceiveAuthenticationChallengeHandler { challenge in
    switch challenge.protectionSpace.authenticationMethod {
    case NSURLAuthenticationMethodClientCertificate:
        guard let identity = pkiService.identity, let certificate = pkiService.certificate else {
            return nil
        }
        return URLCredential(
            identity: identity,
            certificates: [certificate],
            persistence: .none
        )
    default:
        return nil
    }
}
let alamoSession = Session(configuration: configuration)

SDK Version

11.0.2

iOS Version

iOS 15.5

Device Model

all

Other

Method setCanAuthenticateAgainstProtectionSpaceHandler is deprecated without any reference to an alternative.

Hello @davidblazek,
I need your confirmation that the issue still happens if you totally remove setCanAuthenticateAgainstProtectionSpaceHandler.

Regarding your question about an alternative API: There is no alternative, SSL pinning is handled automatically

Hi @ahmedsalah196 ,
I followed your advice and it actually helped, removing setCanAuthenticateAgainstProtectionSpaceHandler causes that SessionDelegate is called properly.

So to sum it up this snippet is problematic:

let configuration = URLSessionConfiguration.default
NetworkLogger.enableLogging(for: configuration)
NetworkLogger.setCanAuthenticateAgainstProtectionSpaceHandler { (urlProtectionSpace) -> Bool in
    return true
}
let alamoSession = Session(configuration: configuration)

It can be fixed using your advice (removing setCanAuthenticateAgainstProtectionSpaceHandler):

let configuration = URLSessionConfiguration.default
NetworkLogger.enableLogging(for: configuration)
let alamoSession = Session(configuration: configuration)

EDIT: Fix above caused that SessionDelegate is called properly, but the network logs don't appear in Bug Reporting tool. I'll investigate it more.

@davidblazek Glad that the initial issue has been resolved and we'd love to assist you more with any other issues that you're facing

@ahmedsalah196 OK, let me correct my previous answer.
We're using Alamofire (along with Moya), we can provide client certificate using two ways:

  1. via Moya CredentialsPlugin (https://github.com/Moya/Moya/blob/master/docs/Authentication.md#basic-http-auth)
  2. via Alamofire SessionDelegate (like in the very first code snippet in this issue).

Both ways are working until we enable logging. After that both ways mentioned above break.

Using provided setDidReceiveAuthenticationChallengeHandler method isn't helpful because

  1. removing setCanAuthenticateAgainstProtectionSpaceHandler causes that setDidReceiveAuthenticationChallengeHandler isn't called at all
  2. after returning true from setCanAuthenticateAgainstProtectionSpaceHandler, closure in setDidReceiveAuthenticationChallengeHandler is called but never with NSURLAuthenticationMethodClientCertificate so we can't provide the client certificate.

So basically the original issue description still stands.

@davidblazek May you reach out to support@instabug.com to further investigate this in a debugging call?

stale commented

This issue has been automatically marked as stale due to inactivity. It will be closed if no further activity occurs. Thank you for your contributions.

stale commented

This issue has been automatically marked as stale due to inactivity. It will be closed if no further activity occurs. Thank you for your contributions.

stale commented

This issue has been automatically closed due to inactivity.