2

I'm trying to learn how to deal with an authentication challenge using NSURLSession. I've never previously done anything related to secure networking. I've been reading the Authentication Challenges and TLS Chain Validation section in Apple's NSURLSession Programming Guide and there the object NSURLCredentialStorage is mentioned, but in its reference I get no further description about why should I use it.

What is the difference between NSURLCredentialStorage and the Keychain? What should be the best of them to handle username and passwords securely? I've looking for an example of authentication challenge with NSURLSession and either NSURLCredentialStorage and Keychain with no success, could somebody tell me where could I find one?

Thanks in advance

AppsDev
  • 12,319
  • 23
  • 93
  • 186

1 Answers1

2

If you don't want to do your own authentication for the server trust or client SSL (rarely used) you can ignore the delegate callback backs related to SSL auth callbacks and instead the system will use the default certificate chains on your keychain to authenticate the request.

If you want to do your own authentication such as verifying that the server trust is proper and if you want to do certificate pinning then you can override the didReceiveChallenge delegate callback and check the server trust explicitly.

To do certificate pinning refer https://gist.github.com/mdelete/d9dbc320d5de347c2a85

If you want to just do normal server trust check assuming that the server has certificate issued by a trusted CA that is part of the System you can use this.

OSStatus err = noErr;
BOOL trusted = NO;
NSURLProtectionSpace *  protectionSpace = challenge.protectionSpace;
SecTrustRef serverTrustRef = protectionSpace.serverTrust;
SecTrustResultType trustResult;

//check if the server trust that we got from the server can be trusted by default
err = SecTrustEvaluate(serverTrustRef, &trustResult);
trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed) || (trustResult == kSecTrustResultUnspecified));
if (trusted)
{
    [challenge.sender useCredential:[NSURLCredential credentialForTrust:protectionSpace.serverTrust]
          forAuthenticationChallenge:challenge];
}
else //if not then warn the user about this and let the user make a decision
{
     //Cancel conneciton
     [challenge.sender cancelAuthenticationChallenge:challenge];

}
Pradeep K
  • 3,671
  • 1
  • 11
  • 15
  • If you are using webviews or then you can use the NSURLCredentialStorage. But if you are other sensitive data such as tokens or even username, passwords for native screens then you can use Keychain. What is it exactly that you are trying to achieve? Do you want to store just the username and password? – Pradeep K Feb 16 '16 at 10:33
  • I just want to store username and password securely – AppsDev Feb 16 '16 at 10:38
  • 1
    Then you should use Keychain. NSURLCredentialStorage is used by the URLLoading system and is used to set the credential on a url session. Reading of such credentials is done internal by the URL loading system and you cannot read it on your own as and when you require. So you should use Keychain – Pradeep K Feb 16 '16 at 10:40
  • So, can I use Keychain in an authentication challenge as well? – AppsDev Feb 16 '16 at 10:43
  • Yes, you can read the credential from the kechain and create a NSURLCredential and use it in your authentication challenge callback – Pradeep K Feb 16 '16 at 10:44