Install TLS 1.2 Certificate on iOS App - ios

How do I install a certified TLS certificate on an iOS app?
I assume there also needs to be the ability to send a new certificate over the network to the app in the future, if need be, and how exactly would that work?
I assume once it's installed that Apple will handle the entire handshake process of the device side?
Had some trouble finding explicit answers to these questions online.

Assuming that what you are describing is a signed SSL certificate for your domain name, the only thing you will need to do is install it on your web server. When your application makes a request to your web server, the server will send the certificate to the client during the initial HTTPS handshake, and the client will verify it automatically.

Related

With iOS push certificates, why does having an SSL certificate allow Apple to know that its your server they're connecting with?

I'm reading this article on iOS push certificates, and I'm confused about this paragraph:
Your backend sends notifications through Apple's servers to your application. To ensure that unwanted parties are not sending notifications to your application, Apple needs to know that only your servers can connect with theirs. Apple therefore requires you to create an SSL certificate to be able to send push notifications.
My understanding of SSL certificates is that if a server has one, that server is able to encrypt data that it sends to a device. But it says here Apple needs to know that only your servers can connect with theirs. I don't understand how having an SSL certificate ensures that. Does anyone have any insight?
The article shouldn't have used the term SSL Certificate. SSL is the Secure Sockets Layer (which was superseded by TLS many years ago). SSL and TLS define the handshake that is used to negotiate encryption on a connection.
Enabling SSL on a web server required you to have a certificate to verify your server's identity and so this became known colloquially as an "SSL certificate".
While it isn't often used on the web, in SSL/TLS both parties can present a certificate so that there is mutual authentication.
What you typically have is actually an x.509 certificate. This is the case with the push notification service.
An x.509 certificate contains some information including the identity of the certificate holder, their private key and a signature from a trusted party that can be used to verify the information.
For push notifications, the developer generates a certificate request and submits this to Apple who sign it with their private key. Apple is the trusted party in this case.
When this certificate is subsequently presented to Apple's server they can verify that signature using their public key to confirm the identity of the connecting party.
You have has encrypted the message with their private key (Apple can decrypt it with the public key included in the certificate).
What this means is, that as long as the developer has kept their private key secure (which is why you wouldn't connect directly to the push service from your app, for example) then Apple can be sure of the identity of the server making the connection.
If someone was trying to impersonate your server then, as long as you have kept your private key secure, they can't encrypt the data properly. If they use a forged certificate that uses a public/private key pair known to them then the signature on the certificate won't be valid and Apple will reject it.

Could not establish trust relationship for the SSL/TLS secure channel: The remote certificate is invalid according to the validation procedure

I have an asp.net mvc web app that has been running in production for about 4 years. Suddenly since about a week ago, I am getting this error being returned for all calls to 3rd-party secure API's:
System.Net.WebException: The underlying connection was closed: Could
not establish trust relationship for the SSL/TLS secure channel. --->
System.Security.Authentication.AuthenticationException: The remote
certificate is invalid according to the validation procedure.
This is for calls to SendGrid for sending emails, calls to Azure Blob Storage for uploading of documents, calls to Connect.io for logging.
I have managed to resolve the Azure Blob Storage problem temporarily by changing the connection string to use http instead of https.
Clearly something has broken on my app server, and I have no idea where to start looking.
Please help.
Edit:
Turns out I was using a sample library provided by one of my (lesser-used) 3rd party API's, and this library had an override of
System.Net.ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors)
which had it's own logic about what constitutes a valid certificate!!! AARGH!
This part become key information for your problem:
I am getting this error being returned for all calls to 3rd-party
secure API's
According to MSDN blog:
This error message is caused because the process is not being able to
validate the Server Certificate supplied by the Server during an HTTPS
(SSL) request. The very first troubleshooting step should be to see
if the server supplied certificate and every certificate in the chain
is trouble free.
Because it seems that one or more third party certificates are rejected, you may configure Trusted Roots part of your certificate trust lists to include all required third party CA as part of chain to work with secure APIs from trusted sources, including reissued certificates if any.
Further details: https://technet.microsoft.com/en-us/library/dn265983.aspx
NB (Optional):
As temporary measure, you can implement this certificate validation handler in WebRole.cs until all related third-party certificates has reissued (remember this setting will trust all issued certificates, hence it's not recommended for long term usage):
System.Net.ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
Additional reference: http://robertgreiner.com/2013/03/could-not-establish-trust-relationship-for-the-ssl-tls-secure-channel/
Similar thing happened in our system. Our problem was TLS version. The SSL offload appliance was configured to accept only TLS 1.2. One week ago this configuration accepted all TLS versions 1.0 to 1.2.
We had to reconfigure .NET's SecurityProtocol settings like:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12;
You can use this site to test which TLS version you are using: https://www.ssllabs.com/ssltest/index.html
Try to get some information about the certificate of the servers and see if you need to install any specific certs.
The server(s) may had a cert signed by a 3rd party CA which you hadn't trusted yet. The solution is to add that CA to the Trusted Root CA list.

Can NSURLConnection use a client certificate installed in profiles on the device?

I have this setup:
A tomcat server configured to use ssl client certificate authentication (clientAuth=true)
An ipad with a valid client certificate installed on it (emailed as a .p12 file and visible under profiles)
When browsing via ios safari, the ipad uses the client cert and authenticates against the server fine.
However in code, using a NSURLConnection, it won't connect. Debugging on the server shows the client isnt sending and cert at all.
On the client I get an error like this:
Request(https://192.168.1.5:8443/device/security/policy>, 0, 0)) didFailWithError:Error Domain=NSURLErrorDomain Code=-1205 "The server “192.168.1.5” did not accept the certificate." UserInfo=0xe2eae30
{NSErrorFailingURLStringKey=https://192.168.1.5:8443/device/security/policy>, NSErrorFailingURLKey=https://192.168.1.5:8443/device/security/policy>, NSLocalizedDescription=The server “192.168.1.5” did not accept the certificate.,
NSUnderlyingError=0xe2eb250 "The server “192.168.1.5” did not accept the certificate.", NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0xe6ab010>}
I understand I can implement the delegate method for the challenge for the NSURLAuthenticationMethodClientCertificate protection space, but if I do that I dont have the certificate to send, its installed on the device and that isnt accessible via code (is it??)
I tried calling [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge] but that appeared to have no effect.
I was expecting that NSURLConnection would behave as per safari and access the installed certificate, but it appears not. I dont want to have to install the certificate into my app somehow - thats what the built in certificate management is for!
Or am I missing something? Any help appreciated.
Fundamentally you can't get at globally installed certificates from within an app in iOS (as of iOS 8), and the operating system won't help you out by sending them with an NSURLConnection. Safari has special rights to access the certificates. So the only way to use them from within an app is to install them into the app somehow, which makes the whole thing difficult.

How to accept trusted certificate added to iOS device via iPhone Configuration Utility in application

I want my application to have the ability to accept trusted root certificates that have been added to an iOS device by using the iPhone Configuration Utility.
I added a trusted certificate to an iOS device using the iPhone Configuration Utility and confirmed that Safari accepts my self-signed certificate by sending my server a https request. However, when I make a simple test app that uses NSURLConnection to make a GET request to my server using HTTPS, I get the following error message:
"
Error - The certificate for this server is invalid. You might be connecting to a server enter code here`that is pretending to be “myserver” which could put your confidential information at risk.
"
I imagine that my iOS app is sandboxed, and does not accept the self-signed certificate by default. I've tried manipulating code in willSendRequestForAuthenticationChallenge to accept the self signed certificate without success. I was hoping that someone else has figured out how to do this. I do not want to accept all self-signed certificates. I only want to accept self-signed certificates that have been configured to be trusted on the device.

If a server has a trusted certificate, What steps are needed to hit that link on IOS using NSURLConnection?

The Application i am working on needs to connect to a webservice over https, The certificate is trusted and valid.
I have used NSURLConnection is previous projects to use soap over http
Can anybody please point the difference between the two above mentioned scenarios,
I also need to understand what exactly happens when connecting over https, is the certificate stored automatically on the device, how does ssl handshake happen.
Any Pointers in this direction will be really helpful.
Regards,
Ishan
I need some clarification. Is the certificate signed by Apple for use with notifications or is it signed by an SSL root certificate authority (like VeriSign)?
Apple signed certificates are only to be used with WebServer to Apple Server communications like the Apple Push Notification Service. They are not intended for iOS device to WebServer.
A SSL certificate signed by a SSL root certificate authority should just work.
I think you are looking for an HTTP over SSL/TLS primer. So, here it goes.
HTTP is an unencrypted channel. The request and response are in a plain text data stream. HTTPS is an encrypted channel. The request and response are in a data stream encrypted using a shared master key. The magic of SSL/TLS is how this encrypted channel is created.
First, the client and server say hello to each other (in a clear channel).
Next, the client downloads the server's public certificate (in a clear channel).
At this point, the client has some work to do. It needs to verify the certificate. It needs to know that it understands the certificate, that the date range is valid, that the certificate is signed by a trusted certificate authority, and that the certificate has not been revoked.
Now, the client knows that it can trust the server.
Next, It sends a few short messages encrypted with the public key of the server (which is in the server's public certificate). These messages can only be decrypted by the server's private key (which only the server knows about). These messages allow the client and the server to negotiate a master key.
Finally, the client and the server begin the normal HTTP request and response using the newly created encrypted channel.
I hope this is what you are looking for. For a more detailed description see: http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html
If the certificate was issued by a chain of certificate authorities whose root is trusted by Apple, then there is nothing to do. The iOS device will accept the certificate, as long as it is otherwise valid (ie not expired, not revoked, etc).
If the CA chain's root is not trusted by Apple, you will need to download the root's certificate to the phone. This can be done (I think) via the iPhone Configuration Utility. Enterprise provisioning scenarios undoubtedly support this also.

Resources