In the past most of my components where first developed for a need that either we had for our own apps for for a client. With the new DTCertificateViewer I want to try something new: Request for Comments (RFC).
Historically those RFCs are the documents that describe how everything on the internet works. But I see no reason why we couldn’t use the term as well to use it what the name describes, namely soliciting comments about the usefulness of an idea.
In this article I would like to show you some prototyping work I have done on this component, where it could go and then I am asking you to comment on this. Do you think this will be something that developers would buy and use for their apps? What should we charge for it? Any other things that go through your mind?
The Motivation
If people want to add a layer of security to HTTP connections they switch to HTTPS. For this they need a certificate. Often people chose to create their own so called “self-signed certificates” because they don’t need to secure the identity of their server, but only look to encrypt HTTP communication. The “proper” way would be to pay a couple of hundred dollars to have a big Certificate Authority create a certificate for you and sign that. This way the SSL certificate would be valid because its trust can be inferred from the CA certificate.
Public web sites generally would opt for the “official” approach because it does not instill much confidence if your browser shows the users some red warning that the identity of the server they try to connect to might be compromised. However there are many use cases where shelling out cash for an official certificate just does not make sense.
The concrete example we have at the moment is that one of our apps uses a web API that connects to company networks via HTTP. Those companies don’t want to have to get a public expensive trusted certificate, but nevertheless they want the added security that HTTPS provides.
If you connect to such a site, like https://test.at Safari presents you with an alert like this:
Then if you click on Details you get an overview of the certificates in doubt:
Clicking on “More Details”…
So the User Interface basically lets the user cancel, proceed while ignoring the “Identity Crisis” or permanently accept the certificate. The last option is the most convenient in the long run. By inspecting the certificate details and making a conscious decision to trust the certificate the user gets the security and is only bothered once. A small price to pay.
I previously wrote about how developers can basically get the Continue functionality with NSURLConnection. It boils down to implementing connection:didReceiveAuthenticationChallenge: in the NSURLConnection delegate protocol.
But there is no public API in iOS that would let the developer show information about the certificate. Because of this many developers choose to simply ignore the certificate identity for a hard-coded domain. But the big problem with this is that this opens up the possibility of Man-in-the-Middle attacks. If you trust all certificates that claim to be *.test.at then you will also trust a certificate that a debugging proxy like Charles might create on the fly to spy on your traffic.
The Goal
The aim of DTCertificateViewer is to close this gap. The UI that we want to have would closely resemble (or even improve upon) the one used by Safari. Then instead of hard-coding trust into your app you would present this certificate viewer to the user and only in case he accepts you would remember the certificate thumbprint for future reference.
The available public interfaces in the Security.framework allow you to get the certificate data, but there is no Apple-provided mechanism to decode the information contained in it. This is why I developed an ASN.1 parser. The BER (Basic Encoding Rules) and DER (Distinguished Encoding Rules) used for representing certificates are both ASN.1 subsets.
The component would create a DTCertificate instance from certificate data and then give you the information needed to fill a table view controller with the certificate details.
In my research so far I have come to a stage where I can get the version, serial number, issuer, validity and subject of a certificate that I can get from a SecTrustRef.
Those number sequences are keys that specify the meaning of the values. For example 2.5.4.6. is a country code, you can see that being used for both the Issuer as well as the Subject.
Now What?
A few steps are still missing to get from the current state of my prototyping to a finished component:
- Decode the public key and algorithms
- Decode the extensions which specify restrictions that this certificate can be used for
- Test a wide variety of certificates to make sure that we covered most special cases
- Create a method that converts the number codes into human readable and localized headings
- Build the UI similar (or better) than the one from Safari
There are risks …
In theory – and this is a certain risk to the commercial viability of this – the decoding functionality of this component can also be fulfilled by an uptodate version of OpenSSL. Though in my tests I already found a certificate that cannot be decoded by it.
Another risk involves the ASN.1 parser possibly not covering certain special cases that are rarely used for encoding certificates. If licensees of this would find such a special case they would need to provide the problematic file to us for implementing the missing features or better yet send a pull request for the open source DTASN1Parser.
I therefore believe that with a certain amount of unit testing and error resilience we can create something that is easy to add to a project but add great value for your users.
And now I need your opinion.
Do you think that this is worthwhile? Would you want to license and use this component? Would you maybe only take the certificate reading parts and make your own UI? Or do you think that this is a bad idea anyway because it is too much of a niche product? Would you want to collaborate on this in exchange for a free license? Or put all up as Open Source because you think that nobody would buy this anyway?
Please comment either on Twitter or directly below this article.
Categories: RFC
Hi Oliver,
i don’t have a need for this special component but I want to see it get used in other Apps that rely on certificates to protect the transported data and to verify the endpoint. So I would like see this on Cocoapods as an open source component.
I would be glad to contribute my part if you start this component. Just let me know. It’s @objectivex on twitter 🙂
I would pay for the full solution. didReceiveAuthenticationChallenge is called, user is prompted with a certificate viewer (as above), user accepts cert, signature of cert stored so that user is not prompted again. This stuff is a pain to get right. The example in Apple’s developer docs crashes sometimes, is buggy and hard to follow the code.
I want this for iOS and Cocoa.