Search code examples
iossslafnetworking-2pinning

How do I allow a user to trust and pin a self-signed SSL Certificate using AFNetworking in iOS


I'm working on an iOS application that will be used by enterprises. Our app will be talking to a server that may be configured with a self-signed certificate generated by the company that has deployed our server software.

Our iOS application is using AFNetworking which allows for SSL Pinning. But I get the impression that this only pins SSL certificates that were included as part of the app bundle when it was created. It does not allow you to work with a certificate that the iOS device becomes aware of later.

I'm looking for a way for the customer to push out (perhaps via a profile) the self-signed cert so that our application can securely talk to the server. Is there a way? Or do I need to skip AFNetworking and use the Foundation classes directly.

I welcome any comments to help clarify this question as well.

UPDATE: For others who may have been confused as I was. While I understand pinning to be an important topic, I was confusing it with my first priority: removing support for invalid certificates from our prototype app. What I wanted was a way for a user to explicitly trust a self-signed cert. This is simple. Just add it as a profile to your iOS device. But I was also being tripped up by the fact that the self-signed certs we were using in development weren't quite right so iOS would not trust them. See http://blog.httpwatch.com/2013/12/12/five-tips-for-using-self-signed-ssl-certificates-with-ios/ on how to generate a "good" self-signed cert. Now that I have self-signed certs being trusted, I will follow up on how to use pinning.


Solution

  • You're right, AFSecurityPolicy has a property pinnedCertificates which defaults to using any certificate in the app bundle if you use the policyWithPinningMode: factory method.

    To use your own certificates, set this property to an NSArray containing the NSData representations of each user certificate:

    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    NSData *certificateData = [NSData dataWithContentsOfFile...
    securityPolicy.pinnedCertificates = @[ certificateData ];