4

I have a root certificate that is used to sign with different sub-domain names on the server which is basically implementation of SNI in backend. Now How can I use that certificate and sub-domain name to validate the request.

Manish Agrawal
  • 10,958
  • 6
  • 44
  • 76

1 Answers1

2

SNI is supported out of the box. And from my experience it works (two second-level domains on single IP)

I see 3 reasons if it doesn't work for you:

  1. Your backend is not configured properly. You can check if the server returns an expected certificate with Safari.
  2. Your certificate is self-signed. In this case you should check AFSecurityPolicy for pinned certificates, there's nothing special with SNI.
  3. Your certificate is not valid for sub-domains. This also could be checked with AFSecurityPolicy.
std.denis
  • 317
  • 3
  • 10
  • I have confirmed my backend is configured properly, as same certificate with host name is working on Android Webservice call. certificate is valid for domain name and for validating sub-domain we have define host name. Also pinned the certificate correctly. you have any idea how it can be achieved in iOS. – Manish Agrawal May 21 '15 at 05:11
  • If you're use a certificate pinning, I would start with breakpoint in AFSecurityPolicy.evaluateServerTrust where you can check many aspects of the connection establishing: if the certificate checking started at all; which certificate received by the client; which step of the method returns NO. And by the way, which the error you're getting currently? – std.denis May 21 '15 at 09:20
  • Also evaluateServerTrust return NO, this line of code return NO, if (!AFServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) { return NO; } let me know if you have any idea why its returning NO. – Manish Agrawal May 25 '15 at 04:53
  • @WildFire so your case is #3 - like a domain is example1.com and certificate is valid for *.example2.com? In this case it's obvious that you should set allowInvalidCertificates to YES, to ignore domain's validation. Then your app will rely on pinned certificate - just add it in DER format into the project with ".cer" extension, it will be consumed automagically inside -defaultPinnedCertificates. Suitable file could be obtained by this command: `openssl s_client -servername api.example.org -connect api.example.org:443 /dev/null | openssl x509 -outform DER > ~/api.example.org.cer` – std.denis May 25 '15 at 14:18
  • I have done everything as you have described but it still not working, Basically i have root certificate for domain example.com and API is hosted on sub-domain domainname.example.com. Basically we have different sub-domains for the same base name. we want to use the same root certificate for all the sub-domains by using support of SNI. – Manish Agrawal May 26 '15 at 04:33
  • Here it is https://github.com/dstd/CertExample - the example working with self-signed certificate with non-valid domain name (it also was tested with our SNI-enabled server). It uses AFSSLPinningModePublicKey mode if the certificate is not valid for the domain. If it still not working, try to set a breakpoint to `NSArray *publicKeys = AFPublicKeyTrustChainForServerTrust(serverTrust);` in `-evaluateServerTrust:` and check length of this chain. All certificates of the chain should be included into your project and their public keys are visible in `pinnedPublicKeys` property in debugger. – std.denis May 26 '15 at 11:09
  • Certificate you are using in sample code is same on server as well on client. That's why its working. If i put my root certificate and do all the things it still fails in for (id trustChainPublicKey in publicKeys) { for (id pinnedPublicKey in self.pinnedPublicKeys) { if (AFSecKeyIsEqualToKey((__bridge SecKeyRef)trustChainPublicKey, (__bridge SecKeyRef)pinnedPublicKey)) { trustedPublicKeyCount += 1; } } } in matching the key. – Manish Agrawal May 27 '15 at 04:53