15

In my app I'm using https and a self-signed SSL certificate to secure the connection between my client and the server.

I was trying to have the AFNetworking library do SSL Pinning on a copy of my certificate bundled in the app.

In the AFURLConnectionOperation header I defined both:

#define _AFNETWORKING_ALLOW_INVALID_SSL_CERTIFICATES_ =1
#define _AFNETWORKING_PIN_SSL_CERTIFICATES_ =1

And before calling the start on my AFJSONRequestOperation I set the SSLPinningMode property to AFSSLPinningModeCertificate.

But when trying to perform a JSON request I keep getting the following error:

Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed. 
(NSURLErrorDomain error -1012.)" UserInfo=0x758f120 
{NSErrorFailingURLKey=https://mydomain.com,
NSErrorFailingURLStringKey=https://mydomain.com}

In the AFURLConnectionOperation header I read that the SSL Pinning works with .cer certificates but in my self-hosted OS X webserver I have a .crt certificate.

Is this the problem? Is there a way to make AFNetworking work with .crt?

On a windows box I converted my .crt to .cer and tried to bundle that into my app but I still get the same error. Should I try to switch the .crt file with the newly created .cer even on the server side?

BigLex
  • 2,978
  • 5
  • 19
  • 27
  • Did you find the answer? Mind to share it? – jAckOdE Jun 06 '13 at 17:05
  • I just gave up on using `AFNetworking` and wrote a class that utilizes the standard `NSURLConnection` (and acts as a delegate for the connection itself) to make the request and I manually handled the comparing stuff in the `- (void)connection: NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge` method that is part of the `NSURLConnectionDelegate` protocol if you want to take a look at the code please feel free to ask. – BigLex Jun 08 '13 at 15:17
  • i haven't tried it myself. but in the AFNetworking sample project. the SSL pinning mode is set to AFSSLPinningModePublicKey, not AFSSLPinningModeCertificate. Have you tried it? – jAckOdE Jun 10 '13 at 15:56
  • http://stackoverflow.com/questions/22695625/afhttprequestoperation-with-self-signed-ssl-and-http-basic-auth-1012-error/22696193#22696193 – k06a Mar 27 '14 at 18:29

3 Answers3

20

I got it working.

I was in the situation where I had created a self-signed cert for to hit my own server API from my iOS App. I created my cert with OpenSSL. When I was done creating it, I had several files, one of which was "server.crt". Initially, I tried just renaming it to "server.cer", and using "AFSSLPinningModeCertificate" for my AFURLConnectionOperation objects. That did not work, and I noticed the example uses "AFSSLPinningModePublicKey", so I tried that, still no luck.

So I compared my file (that was the renamed ".crt" file) to his.
I noticed that "server.crt" was base64-encoded, and like this:

-----BEGIN CERTIFICATE-----
394230AFDFD... 
-----END CERTIFICATE-----

I noticed from Mattt's example in AFNetworking that the "adn.cer" file he uses is not base64-encoded. It is just raw bytes. So, I did this:

$ base64 -D -i ./server.crt -o ./server.cer

I set my AFURLConnectionOperation to AFSSLPinningModePublicKey.
I put that back in the project and did a clean and build of my iOS project, and everything worked fine.

Hope this helps!!

Btw, you may notice that Xcode will display info for for your ".crt" or ".cer" key whether it is the base64 or the raw one, so don't let that confuse you. You should be able to see the certificate data in either case, it's just that AF will only accept the raw (non-base64) one.

UPDATE:
Anyone having trouble with base64, this what works for me on OS X using OpenSSL:

$ openssl base64 -d -in ./server.crt -out ./server.cer
jpswain
  • 14,642
  • 8
  • 58
  • 63
  • 1
    Your work around is correct one but, how to make it work without any .cer files? This is the question! – Voda Ion Oct 10 '13 at 12:48
  • 8
    FYI, I had a problem using base64 to do the conversion. Instead I used 'openssl x509 -in test.crt -outform der -out test.cer'. – CharlesA Nov 04 '13 at 15:35
  • Anyone getting confused regarding .cer | .crt etc., there is a [nice post](http://www.gtopia.org/blog/2010/02/der-vs-crt-vs-cer-vs-pem-certificates/) about it which will certainly clear your doubts. It also shows how to convert certificates to different formats. – nefarianblack Dec 11 '13 at 07:47
  • 2
    @tanmaykhandelwal: That link is now broken, but I noticed [the content was reposted on support.ssl.com](https://support.ssl.com/Knowledgebase/Article/View/19/0/der-vs-crt-vs-cer-vs-pem-certificates-and-how-to-convert-them). – Matt Kantor Feb 26 '14 at 22:16
  • I got an error when using base64 to do the conversion. localhost:pvk firebear$ base64 -D -i WS_CA1_xs_UTN-SGC.crt -o WS_CA1_xs_UTN-SGC.cer Invalid character in input stream. I also tried openssl, but still not work. :( – firebear Jun 27 '14 at 11:50
  • 1
    @firebear I added an update to my post, hopefully that helps! – jpswain Jun 27 '14 at 16:47
  • I tried 'openssl base64 -d -in ./server.crt -out ./server.cer' in Mac. Yes, it worked! thanks. – firebear Jul 05 '14 at 06:00
  • @orange80 What if you have more than one certificate; would that work in the bundle ? – lifemoveson May 21 '15 at 17:33
  • @lifemoveson for the same host or different hosts? if they are all for the same host, i believe pinning to your own intermediate CA is probably the best solution, but that would require additional process for your organization to manage the CA signing. – jpswain May 25 '15 at 00:33
3

If you're using AFNetworking 2.x, and you're using the correct .cer but still receiving error code -1012 on your calls, you should disable validatesCertificateChain:

AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];
securityPolicy.validatesCertificateChain = NO;

or you can pass it all in the entire certificate chain in pinnedCertificates.

junjie
  • 7,946
  • 2
  • 26
  • 26
0

Your certificate must have the extension cer not crt and should be in .der format. Add output file to your Xcode project.

You can use following command:

openssl x509 -in your.crt -out certificate_cer.cer -outform der

Zeeshan
  • 4,194
  • 28
  • 32