Handling SSL certificates as they are renewed on the server - ios

I have a cert signed by a CA (Geotrust) on my server. I have the same cert installed in my app. I compare the two certs in URLSession:didReceiveChallenge:completionHandler:. But I was notified by my hosting service that I need to 'renew' the cert each year. That creates a new and different cert for me to handle in the app. Since the certs are not self-signed, do I need to embed the cert in the app for comparison with the cert as it comes from the server or does iOS's SSL handling take care of the challenge for me. Maybe I can just use server trust without looking at the cert?

I have the same cert installed in my app.
Why?
I compare the two certs in URLSession:didReceiveChallenge:completionHandler.
Why?
What you should be doing is comparing the subjectDN. That's what the signer is verifying. It's all you need.
Maybe I can just use server trust without looking at the cert?
It sounds like you're trying to do the correct thing and add an authorization step. Relying on 'server trust' just gives you authentication, i.e. the subject DN is who he says he is. Authorization checks whether that DN is authorised to use this part of the application. But you don't need to check the entire certificate for that.

Related

Self signed certificate in production environment for internal HTTPS calls?

I have generated a self signed certificate .This self signed certificate is stored in server and accepts request only from clients which is having this self signed certificate is this acceptable. since this HTTPS endpoint is supposed to be used only from our custom HTTPS client I strongly feel that CA signing is not required .
But my colleagues are warning that Self signed certificate should not be used in production environment no matter what .what should I do ??
There is a whole infrastructure in place to manage the life-cycle of the certificates, it is called PKI (Public Key Infrastructure). The CA's are part of it, and help you manage the certificate issuance and revocation.
It is not advised to use self-signed certificates in production environment, because you loose the life-cycle management of the certificate. Lets say if the client is compromised, any one in possession of that self-signed certificate can talk to the server. There is no way you can manage to revoke that certificate or maintain the CRL.
The ideal solution/implementation in your case, will actually be issuing the clients their own PKCS12 from the CA as well, which means they will have their own private key (this might get expensive, if you have many clients). But this is most secure way of doing it. If you know a client is compromised, you can revoke that client's certificate from the CA, and if the client does certificate validation (ideally should), it should no longer be able to communicate with the server. You can simply decommission that client.
Just an idea
But if you are looking for cost effective way (since you mentioned internal calls), you could have your server issue P12's to the clients, and your server maintaining a record of which client has what certificate. This gives you little control of managing the clients. You could enable certificate based authentication on the server side for those services (the server will receive the subjectDN of the client), and by referring to the stored record, you can identify which client is trying to communicate. And if you want to disable that client from being served by the server, simple update the record.
But to answer your concern, it is not ideal to use self-signed certificate because, in real world, you should be able to manage the certificates in real time or near to real time, which will not be possible if you use self-signed certificates.

I need to purchase an SSL certificate to use through a heroku server and iOS app. What exactly do I need?

I have created an iOS app, and rails server, that communicate with each other back and forth. I am using login capabilities, so I want SSL.
It appears an SSL endpoint on heroku is $20/mo. Adding that seems simple. heroku addons:create ssl:endpoint.
Now, I need to purchase an SSL certificate.
1) Where's the cheapest place I can get an SSL certificate for my needs? There seems to be varying degrees of options. Do I just require the most basic?
2) What exactly do I receive with my purchase? A private key, and the certificate? I'm not too sure exactly what happens though. Is it like this... When the iOS client hits my server, and hits any https link, my server will return the certificate. The iOS app receives the certificate, and send it to a Certificate Authority(CA). The CA will return the certificate along with the public key to the iOS app. The iOS app will then encrypt the data with the public key, and send it back to the server. The server will then use the private key to decrypt the data.
3) Where exactly do I store the private key on my rails server? In my db? In a .secrets file? In the heroku config?
#1: The SSL certificate you need depends on how many domains you want to secure. If it's jus www.yourdomain.com and yourdomain.com most certs (i.e. a Comodo PositiveSSL) will do the trick.
In addition:
DNSimple, who won't be the absolute cheapest, can do a lot of the work for you (key generation, CSR generation, and generating the certificate)
I (currently) use Namecheap for single-domain PositiveSSL and/or multi-domain PositiveSSL certs. Relatively cheap, two-factor authentication on their login, their UI is "usable" if not great.
#2: Heroku has an article on how to set up the endpoint once you have a cert: https://devcenter.heroku.com/articles/ssl-endpoint - which shows how to add the signed certificate and private key via heroku certs:add yourcert.crt yourkey.key
#3: Your iOS app should use the NSURLSession method to make calls to your Heroku application remotely. This handles the TLS (SSL) handshake and you don't have to worry about the particulars.
As an additional tip, you can also pin the certificate of your Heroku application in your iOS app. Your iOS app effectively matches its' hardcoded signature against the signature in the certificate of your Heroku app so that it knows it's not just talking to some other HTTPS server.
Hopefully that's clear.
Added IRT comment
Note that when you add the SSL addon, you will get an SSL endpoint - e.g. sushi-bento-2141.herokussl.com - which already has SSL through Heroku's wildcard certificate. Your app can listen to requests on the non-SSL endpoint morning-evergreen-9385.herokuapp.com and re-direct them (301 permanent). You don't need to buy your own cert for this.
However, it's typically much nicer to have your own domain name (more recognisable for users!), for which you do have to buy a certificate for (as per my answers above).

Would iOS AFNetwork SSL Pinning mode provide additional security bonus if valid certificate deployed

As per my understanding, SSL Pinning is to compare the public key or certification of a server with the copies bundled in the client beforehand.
I saw in Stackoverflow that many developers use SSL Pinning by AFNetwork libraries, but most of them use it along with a self-signed certificate.
I have bought a valid certificate from a CA and passed the test to verify it worked fine. I mean, I set the following and it worked
...
_sharedHttpsInstance.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
_sharedHttpsInstance.securityPolicy.allowInvalidCertificates = NO;
...
What I am wondering is that if set the Pinning mode to AFSSLPinningModePulicKey, my application would be more secure in communication with the server in addition to what the valid certificate have provided?
thanks a lot.
I'm don't know the exact implementation of SSL pinning in iOS, but in principle pinning provides definitely more security than the default verification against a set of builtin certificate agencies. By default systems trust more than 100 different CA from all over the world and each of the CA has the ability to issue any certificate it wants, even if another CA has already issued the same or a similar certificate. So if any of these 100+ CAs gets compromised they can issue a certificate for your domain, which would pass the checks in your application unless you use certificate pinning. Such compromises happened in 2011 with DigiNotar (no longer existent because of that) and Comodo (was too big to fail).
Probably the most prominent user of certificate pinning is Google Chrome, where it is used for the google domains and this helped to detect the compromises of DigiNotar and Comodo.
A downside of certificate pinning might be, that the application will stop working inside networks which do SSL interception for security reasons. Google Chrome seems to deal with this situation by accepting the certificate if it is signed by a CA explicitly added by the user (i.e. no builtin) alternatively to the pinning checks.
Another question which might be interesting is if SSL pinning is secure 'ENOUTH' for 'Most' of the application, even if working along with self-signed certification?
Checking against a fixed certificate or public key (e.g. certificate pinning with or without self-signed) is more secure than only checking if the certificate is signed by any of the 100s CAs trusted by the system. And as long as the developer has full control about both sides (e.g. application and server) it also scales well. The only advantage of additionally using the usual infrastructure is the use of the certificate revocation mechanism. But because the developer has control of the application (s)he could just replace the appplication in case the certificate gets compromised. So yes, in most cases it is secure enough do do SSL pinning with a self-signed certificate and it is more secure than using the standard certificate validation without pinning.
It's very difficult to say categorically whether pinning is better or worse, since it shifts the risk to a different party.
Pinning will essentially protect you better against a potential breach in any of the CA you trust. If a CA is compromised and made to issue a certificate for the host you're trying to contact, pinning will protect you against that because you will compare with the specific reference you've pinned, instead of going through the CA.
The downside is that it will prevent you from using the mechanisms in place at the CA to deal with a compromised host: certificate revocation. If the host's private key is compromised, going through the PKI verification mechanism should allow you to check for revocation, and be warned that such a problem happen. In contrast, you won't be able to know that with pinning, since you're not going through the CA to check the certificate at all.
Of course, you could combine both approaches, but this could cause additional problems (you'd need a strategy to deal with conflicting outcomes in both evaluations, otherwise a compromised CA revoking a valid cert could cause a DoS).
I don't know whethet AFNetworking's pinning mechanism replaces the PKI validation or complements it.
In general, choosing between using pinning or PKI validation depends on whether you think that particular host's private key is more or less likely to be compromised than the CAs you trust.
Another downside of pinning is that you need to update the application (or let the user "re-pin") every time the server certificate (or at least the key-pair, depending on what you've pinned) is changed legitimately. It's probably not a bad idea to re-key once in a while.
(To be clear, I'm not saying that CAs are better, just that pinning changes the set of problems.)

RESTful Service with Self Signed SSL

We are building an end to end solution that will allow our customers to access their ERP data hosted in their own servers through mobile applications. Version 1 will be an iOS app.
We need to make sure the traffic between the client and the server is encrypted with SSL. The problem lies in that we want the installation of the server to be as seamless as possible, hence we don't want the customer to go through the process of buying and installing SSL Certificates. Not even mentioning having to renew that certificate every year.
We were thinking of creating a self signed CA certificate and use it to create child certificates for each client to install on their servers (along with the public CA certificate). We would automate the process of creating the child certificate and include it as part of the setup process. The certificate will also have a very long expiration date as to not dealing with expirations. But if we use this certificate the requests from the client won't be trusted as the CA won't be trusted.
Can the CA be added to the iOS app or device?
Is there a security concern with this implementation?
I have a very similar situation. So far I have just created self signed certificates and just programmed the clients to ignore allow untrusted SSL certificates. If there is a better answer I'd love to hear it.
It is 2017 and letsencrypt now exists, which provides free domain validation and signing of TLS certificates such that browsers / OS HTTPS or TLS libraries and frameworks will accept them, and through certbot it is relatively easy to set up auto-renewal. I won't describe it here because it's deployment specific, but they have good docs. Combined they're probably the best solution out there.
Bundling and using self-signed certificates is seriously sub-optimal for various reasons, and there's no reason to do it anymore (except perhaps gross laziness), so don't.
Free is only for basic domain-validated certificates, i.e. where letsencrypt.org validates that you own the domain that you say you do (and certbot is used to automate that process). You still need to pay for extra verification steps if you want them. However, for internal TLS connections between your app and your server, you only really need domain validated, because you only have to be sure you are talking to your server. The extra steps are more focussed on giving a customer confidence in a company, so they can give over sensitive data with greater peace of mind. Generally speaking if they are using you app, that suggests they trust your company already, so the extra validation is not important (and probably invisible to the customer anyway).
In development if you want to use self-signed certificates this may still make sense. Check out my answer to this question on how to install self-signed certificates for all apps on your iOS 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