Search code examples
ioscertificatealamofirecaauthority

iOS mobile app certificate authority


I apologize in advance if i made a duplicate of this question. I'm working on a mobile app that communicates with an API on a .local domain. I'm stuck at trying to establish a secure connection (using Alamofire). I Tried to write a custom ServerTrustPolicy just as Alamofire wiki suggests, and include my certificate chain, but it always fails. The only way to get the app to connect is by configuring App Transport Security in .plist file and adding the domain as exception. Does anyone have experiance with using certificates trough alamofire with .local domains? Would really appreciate any advice. Thank you in advance.

This is my Alamofire.Manger:

static let sharedInstance: Manager = {

    var apiObject = ApiBaseService()

    //let domainName = apiObject.getDomain()
    let pathToCert = NSBundle.mainBundle().pathForResource("certca", ofType: "der")
    let localCertificate:NSData = NSData(contentsOfFile: pathToCert!)!

    let serverTrustPolicy = ServerTrustPolicy.PinCertificates(
        certificates: ServerTrustPolicy.certificatesInBundle(),
        validateCertificateChain: true,
        validateHost: true
    )

    let value = GlobalConstants.APICallErrorLocations.actionsGetActions
    let serverTrustPolicies: [String: ServerTrustPolicy] = [
        "test.ex01.local": serverTrustPolicy
    ]

    let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
    configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders
    configuration.timeoutIntervalForRequest = NSTimeInterval(12.0)


    return Manager(configuration: configuration,
    serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies))
    }()

Am I doing something wrong?

Kristian

EDIT:

The thing was TLS version was v1.0 which i discovered with this command:

openssl s_client -connect test.ex01.local:5000

After updating TLS version and including certificate chain in ServerTrustPolicy object, everything works.

Hope this will help someone in the future.


Solution

  • If your certificate chain is not valid and is self-signed (assuming this is the case), then you MUST disable ATS for that host, or you'll never be able to use the Alamofire cert pinning logic. ATS will never even give Alamofire a chance to evaluate the cert chain.

    The reason for this behavior is that ATS first evaluates the connection challenge before giving the NSURLSessionDelegate a chance to evaluate the challenge. If ATS evaluates the properties of the challenge and determines it should not trust the connection, it stops there and the request will not succeed. It doesn't call the NSURLSessionDelegate to give you a second chance to override it.

    However, when you disable ATS, the first ATS checks no longer happen, and the challenge is sent to the NSURLSessionDelegate for evaluation which is where Alamofire kicks in.