I've installed a certificate into my iOS device by downloading it using Safari. But when I run my app and query site needs client certificate, it will show message "No required SSL certificate was sent". How can I find client certificate and send it to server?
How to get client certificate from application
iOS apps do not have access to credentials stored in the Apple ‘slice’ of the keychain. QA1745 Making Certificates and Keys Available To Your App explains this in more depth.
As to what you can do about this, that depends on your specific requirements. First up, are you working in a managed environment?
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
The most important scenario is to fix enertprise user's requirement. They are managed accounts.
QA1745 Making Certificates and Keys Available To Your App explains to use digital identities in our apps, we need to write code to import them. Is there a detail guideline about how to import them to non-apple-provided apps and support client certificate based authentication in our app? How to automatically know which certificate should be used for target site?
You can import a digital identity using
SecPKCS12Import
. There’s a bunch of examples on how to use that routine, so I’m going to skip on to the hard part, which is getting the PKCS#12 data that you want to import. This is tricky, and is very dependent on the environment in which your app is running.
Ideally, there would be a way for admins to push a digital identity to a specific keychain access group via a configuration profile. This is a commonly-requested feature but, alas, there’s no sign of it being implemented. If you feel like adding your voice to the choir, please file an enhancement request describing your requirements.
In the absence of such a feature, you need to come up with a different way to get your PKCS#12 data. There’s a bunch of ways you can do this but in managed environments the best option IMO is to use Kerberos SSO. You have two ways to approach that:
You can configure your origin server to support Kerberos SSO and then you’re done.
If that’s not feasible — for example, because your origin server software doesn’t support Kerberos SSO — you can configure a second server that supports Kerberos SSO and, once authenticated, hands out the digital identity required to access the origin server. Your app can then first talk to that server to get the digital identity, and then use that to talk to the origin server.
Beyond that, there’s a bunch of less-than-ideal approaches. For example, many folks use managed app configuration for this [1], despite the fact that, when we introduced that feature, we specifically warned folks not to use it for credentials.
[1] See WWDC 2013 Session 301 Extending Your Apps for Enterprise and Education Use.
With regards your other questions:
Is there a detail guideline about how to … support client certificate based authentication in our app?
How you do that depends on the networking API you’re using. If you’re using
NSURLSession
(or
WKWebView
) you have to deal with the
NSURLAuthenticationMethodClientCertificate
authentication challenge. See
Handling an Authentication Challenge for the background on this.
How to automatically know which certificate should be used for target site?
The only automatic way of doing that is to rely on an obscure feature of the authentication challenge, namely the
distinguishedNames
property of the protection space associated with the challenge. If the server supports this feature, and it’s correctly configured, you can use it to filter the list of available client digital identities.
Doing that is quite tricky, and thus very few apps implement it. The alternative is to implement some less automatic mechanism:
You can ask the user, à la Safari.
You can document a managed app configuration preference that lets admins configure this.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
Hello,
I'm currently facing a similar situation.
We're using WKWebView. In its delegate method didReceiveAuthenticationChallenge, I managed to access distinguishedNames.
The problem is, I don't know how to get credential from certificate that is installed by MDM.
Apparently our website managed to work when accessing with
SFSafariViewController.
>The only automatic way of doing that is to rely on an obscure feature of the authentication challenge, namely the
distinguishedNames
property of the protection space associated with the challenge.I appreciate so much if you could show my how to let this done.
The
distinguishedNames
property is only relevant if you need to choose between multiple different client digital identities. It won’t help if you if you can’t access the digital identities at all. And that’s exactly what’s happening here. As explained in QA1745
Making Certificates and Keys Available To Your App, digital identities installed via a configuration profile (and hence via MDM) are placed in an Apple-only keychain access group that third-party apps can’t access. There is no direct way around this, although my post on 30 Jul suggests various ways you can authenticate in a managed environment without it.
Apparently our website managed to work when accessing with
.SFSafariViewController
Right, because
SFSafariViewController
acts Just Like Safari™ and, being Apple code built in to the OS, it can access the Apple-only keychain access group.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
Thank you for detailed information.
We made some modification on server side respondings, and decided to use SFAuthenticationSession instead of WKWebView.