Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pinned certificate works on Android but not iOS #514

Open
halindrome opened this issue Jul 14, 2023 · 2 comments
Open

Pinned certificate works on Android but not iOS #514

halindrome opened this issue Jul 14, 2023 · 2 comments
Labels

Comments

@halindrome
Copy link

This is a weird one - sorry! We are using Ionic Capacitor. Because of a complex network topology, one of the things we need to support is accessing a backend (REST) server by IP address (not name) on private local networks. Until recently we have been doing this via HTTP, but a customer has requested we update that connection to use TLS. Unfortunately, getting a real TLS certificate for a server that is not on the Internet is challenging. Fortunately, this plugin exists!

First we set up a tiered private Certificate Authority. So we have a self-signed master (root) CA certificate. That certificate was used to sign a number of intermediate CA certificates. Then we set up a service to generate certificates for the servers that are not on the Internet (and do not have a way to register a name via local DNS) with their IP address in a Subject Alternative Name. Finally, we generated .cer files for each of the intermediate certificates and put them into the www/certificates folder for our app.

On Android this works really well. We set the server trust mode to pinned and we can see it connecting and verifying the connection against the embedded pinned keys. On iOS (16.5.1) it always fails. The specific error we see in the debugging output in XCode is:

⚡️  [debug] - %c2023-07-14T11:14:06.933Z DEBUG [./src/app/services/comms/comms.service.ts:1094:0] color:teal testing TLS with pinned certificate
To Native Cordova ->  CordovaHttpPlugin get CordovaHttpPlugin362646755 ["options": [https://192.168.2.246/scripts/corvex.cgi, {
}, 60, 60, 1, text, 2]]
2023-07-14 06:14:06.999893-0500 App[448:9471] Connection 6: default TLS Trust evaluation failed(-9807)
2023-07-14 06:14:06.999944-0500 App[448:9471] Connection 6: TLS Trust encountered error 3:-9807
2023-07-14 06:14:06.999962-0500 App[448:9471] Connection 6: encountered error(3:-9807)
2023-07-14 06:14:07.000786-0500 App[448:9471] Task <587CDBB3-AE1E-46B7-8F4F-02245E292B4F>.<1> HTTP load failed, 0/0 bytes (error code: -1202 [3:-9807])
2023-07-14 06:14:07.002354-0500 App[448:9124] Task <587CDBB3-AE1E-46B7-8F4F-02245E292B4F>.<1> finished with error [-1202] Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “192.168.2.246” which could put your confidential information at risk." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=(
    "<cert(0x102821a00) s: Self-signed Certificate for gateway i: CCW Delegated Certificate delegate_1>"
), NSErrorClientCertificateStateKey=0, NSErrorFailingURLKey=https://192.168.2.246/scripts/corvex.cgi, NSErrorFailingURLStringKey=https://192.168.2.246/scripts/corvex.cgi, NSUnderlyingError=0x28371e280 {Error Domain=kCFErrorDomainCFNetwork Code=-1202 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x28082cb40>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9807, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9807, kCFStreamPropertySSLPeerCertificates=(
    "<cert(0x102821a00) s: Self-signed Certificate for gateway i: CCW Delegated Certificate delegate_1>"
)}}, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <587CDBB3-AE1E-46B7-8F4F-02245E292B4F>.<1>"
), _kCFStreamErrorCodeKey=-9807, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <587CDBB3-AE1E-46B7-8F4F-02245E292B4F>.<1>, NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x28082cb40>, NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “192.168.2.246” which could put your confidential information at risk.}

We have worked around this already by testing the connection pinned, then falling back to nocheck if the pinned connection fails. This is "working", but is not ideal.

We have 2 questions:

  1. Does this plugin actually support pinning to certificates with a SAN that is an IP address on iOS?
  2. If so, what are we doing wrong?

Thanks!

@UlricW
Copy link

UlricW commented Aug 9, 2023

We encountered the same issue here

@saranrajui
Copy link

same issue here too, got any workaround?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants