Set Up Certificate Pinning | raywenderlich.com


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/9261385-alamofire/lessons/8

Hi Oxtim,

I’m at p08- ssl certificate tutorial. The api.imagga.com is no longer working. Seems like imagga change to “v2”. I am not sure how I can construct the shell script. Can you please help?

It returns error “verify error:num=10:certificate has expired” when I entered openssl s_client -connect [api.imagga.com:443] < /dev/null | openssl x509 -outform DER -out imagga.com.der.

I am currently stuck here, great tutorial! My work requires me to add ssl certificate and using alamofire, thanks for producing this class!

1 Like

Hi, Tim,

I think I am a bit stuck here at Lesson 8 & 9

(Xcode 11.4.1 Swift 5.2.2. Alamofire 5.0.0-rc.3)

I followed the tutorial and get cert successfully for both wikimedia.org and api.imagga.com but I saw the poll error at the end of both of responses. Also, it says certificate has expired for the api.imagga.com.

xxxxx Certificates % openssl s_client -connect upload.wikimedia.org:443 < /dev/null | openssl x509 -outform DER -out wikimedia.org.der
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let’s Encrypt, CN = Let’s Encrypt Authority X3
verify return:1
depth=0 CN = *.wikipedia.org
verify return:1
poll error%
xxxxx Certificates % ls
wikimedia.org.der

xxxxxxx Certificates % openssl s_client -connect api.imagga.com:443 < /dev/null | openssl x509 -outform DER -out imagga.com.der
depth=1 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify error:num=10:certificate has expired
notAfter=May 30 10:48:38 2020 GMT
verify return:0
depth=1 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify error:num=10:certificate has expired
notAfter=May 30 10:48:38 2020 GMT
verify return:0
depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify error:num=10:certificate has expired
notAfter=May 30 10:48:38 2020 GMT
verify return:0
poll error%
xxxxxx Certificates % ls
imagga.com.der wikimedia.org.der

I ignored those errors and finished typing in the code of Lesson8 & 9, ran it and I got the following error in Xcode console

Error while fetching the image: serverTrustEvaluationFailed(reason: Alamofire.AFError.ServerTrustFailureReason.certificatePinningFailed(host: “upload.wikimedia.org”, trust: <SecTrustRef: 0x2829c0360>, pinnedCertificates: [<cert(0x101907560) s: *.wikipedia.org i: DigiCert SHA2 High Assurance Server CA>], serverCertificates: [<cert(0x10281de00) s: *.wikipedia.org i: Let’s Encrypt Authority X3>, <cert(0x105019800) s: Let’s Encrypt Authority X3 i: DST Root CA X3>, <cert(0x10501b000) s: DST Root CA X3 i: DST Root CA X3>]))

Error uploading file: serverTrustEvaluationFailed(reason: Alamofire.AFError.ServerTrustFailureReason.certificatePinningFailed(host: “api.imagga.com”, trust: <SecTrustRef: 0x2829d2b50>, pinnedCertificates: [<cert(0x101905ba0) s: *.imagga.com i: Sectigo RSA Domain Validation Secure Server CA>], serverCertificates: [<cert(0x104111e00) s: *.api.imagga.com i: Amazon>, <cert(0x1038a2400) s: Amazon i: Amazon Root CA 1>, <cert(0x103888000) s: Amazon Root CA 1 i: Amazon Root CA 1>]))

I tried the final project provided with lesson it’s the same result, so would you please help out?

Thanks

Jing

It looks like the Imagga API might have had an expired cert - it seems to be working now. (And the v2 URL doesn’t exist, according to the docs it should be https://api.imagga.com/v2, which is the same as the basePath in ImaggaRouter.swift

@oaktree Does it work now? It might have been an Imagga outage. From the looks of it, the certificates in the final project attached to the video are now out of date so would need updating before the sample projects work. You can ignore the poll error output

Hi Tim,

Sounds good. I’ll try again. Thanks for the prompt reply!

Btw, is this way (shell script) of generating the cert better than going to the website to grab the cert? I tried that, and it saved as “.crt” while I got “.der” cert from shell script. I googled the difference, it seems like .crt and .der are basically encoded the same way. I haven’t continued the rest of the code in Lesson 8 yet, so I may have to change the code there to accept “.crt” if I decide to grab certificate that way. But I first wanna check with you, if my way of grabbing certificate is not recommended…

Thanks!!
Nikki

Hi, Tim,

Thanks for getting me back. I gave it another shot. I checked out the material from Lesson 9 and re-generated both certs from terminal. I got the similar results.

Also, I tried to get the cert directly from the browser (.cer files), still no luck.

Do the version of Xcode and Alamofire that I am using matter? Or could it be that Apple changed something?

Best

Jing

2020-06-04 17:43:29.445618-0400 PhotoTagger-5[510:98371] Task <6B28F920-2099-4ADB-9AE3-CA73DFF6F0D7>.<2> HTTP load failed, 0/0 bytes (error code: -999 [1:89])**

Error uploading file: serverTrustEvaluationFailed(reason: Alamofire.AFError.ServerTrustFailureReason.certificatePinningFailed(host: “api.imagga.com”, trust: <SecTrustRef: 0x2820306c0>, pinnedCertificates: [<cert(0x10790e870) s: *.imagga.com i: Sectigo RSA Domain Validation Secure Server CA>], serverCertificates: [<cert(0x10682da00) s: *.api.imagga.com i: Amazon>, <cert(0x10a82dc00) s: Amazon i: Amazon Root CA 1>, <cert(0x10a82aa00) s: Amazon Root CA 1 i: Amazon Root CA 1>]))

Error uploading file: serverTrustEvaluationFailed(reason: Alamofire.AFError.ServerTrustFailureReason.certificatePinningFailed(host: “api.imagga.com”, trust: <SecTrustRef: 0x282039b00>, pinnedCertificates: [<cert(0x10790e870) s: *.imagga.com i: Sectigo RSA Domain Validation Secure Server CA>], serverCertificates: [<cert(0x105866c00) s: *.api.imagga.com i: Amazon>, <cert(0x105891a00) s: Amazon i: Amazon Root CA 1>, <cert(0x105892200) s: Amazon Root CA 1 i: Amazon Root CA 1>]))

2020-06-04 17:43:40.707184-0400 PhotoTagger-5[510:98365] Task .<3> HTTP load failed, 0/0 bytes (error code: -999 [1:89])

As long as the certificate matches then you should be fine.

@oaktree @spacenikki you were right, there’s another problem with Imagga. So it looks like they’ve moved their hosting onto a shared platform, which nows uses SNI, but the old connections were still working, which was why it was all failing. If you change the OpenSSL command to:

openssl s_client -connect api.imagga.com:443 -servername api.imagga.com < /dev/null | openssl x509 -outform DER -out imagga.com.der

Then it should pick the right certificate and work - I’ve just tested it in the final project from episode 9 with the new certs and it all works.

1 Like

Hi, @0xtim

Thanks for getting me back so quickly. Thumbs up, the new cert for imagga is working now! But just FYI, I mimicked the new command and try to make the wikimedia example work

openssl s_client -connect upload.wikimedia.org:443 -servername upload.wikimedia.org < /dev/null | openssl x509 -outform DER -out wikimedia.org.der

From the source control I think I got the same cert for wikimedia, so I still got -999 error for the upload example. But anyway and I got the idea of cert pinning. So I don’t have any more request on this. Thanks for the help and you have a great weekend.

(Btw, how do you post code with a scroll bar?)

Best

Jing

The wikimedia one won’t work because it’s server doesn’t use SNI which is what the server name flag looks for

As for the scrolling code, ``` on the line before and after is what you need!

HI, @0xtim,

I see, got it now, that makes sense. Also, thanks for the tips on markdown!

Best

Jing

1 Like

Hi @0xtim,

Yes, just tested, it works now. Thanks.

I’d need some help here, I am stuck with below error when doing some changes on my app, using Alamofire and SSL pinning.

My app has SSL pinning which worked the whole time (since last year). And now I need to update the new SSL and domain as the server has changed.

I went in and replace cert/ code change that is related to the cert. But it’s still showing me this error. It should just be a simple change. Can you please advise what may be an issue here?

**FAILURE: Error Domain=NSURLErrorDomain Code=-999 “cancelled” UserInfo={NSErrorFailingURLStringKey=https://website/DVSAPI_PROCESS_LOGIN?, NSErrorFailingURLKey=https://website/DVSAPI_PROCESS_LOGIN?, _NSURLErrorRelatedURLSessionTaskErrorKey=(**

**"LocalDataTask .<2>"**

**), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .<2>, NSLocalizedDescription=cancelled}*

Honestly I’m not sure what the error is. It could be because it’s rejecting the certificate, does it work if you don’t pin?

1 Like

@spacenikki Do you still have issues with this?

just use google for testing:

get certificate in terminal:
openssl s_client -connect google-search3.p.rapidapi.com:443 </dev/null | openssl x509 -outform DER -out google-search3.p.rapidapi.com.der

make a GET request for example:
https://google-search3.p.rapidapi.com/api/v1/search/q=elon+musk&num=100

should be fine