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

CURLOPT_PINNEDPUBLICKEY does not work on iOS #57

Closed
jahngordon opened this issue Nov 28, 2018 · 4 comments
Closed

CURLOPT_PINNEDPUBLICKEY does not work on iOS #57

jahngordon opened this issue Nov 28, 2018 · 4 comments

Comments

@jahngordon
Copy link

Not sure if this is a curl issue or an issue with the build, but CURLOPT_PINNEDPUBLICKEY doesn't work on iOS pre-built binaries, but works fine on Android (with OpenSSL).

I'm trying to enable pinning in our apps that use this library for both iOS and Android and the Android one works fine - correct public key it works as before we added the setting, wrong public key and it gives me an error saying I cannot connect.

Code is as follows:

      CURLcode c = curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
        fprintf(stderr, "Set Fail on Error: %s\n",
                curl_easy_strerror(c));
        c = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
        fprintf(stderr, "Set verify peer: %s\n",
                curl_easy_strerror(c));
        c = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2);
        fprintf(stderr, "Set verify host: %s\n",
                curl_easy_strerror(c));
        c = curl_easy_setopt(curl, CURLOPT_PINNEDPUBLICKEY,
                             "sha256//nhEOGkhMcl5uqf13KxUPoCgXYXCKA8A4E+j9JiL+UB8=");
        fprintf(stderr, "Set pinned key: %s\n",
                curl_easy_strerror(c));

The output from this on iOS is:

ENABLING PINNING
Set Fail on Error: No error
Set verify peer: No error
Set verify host: No error
Set pinned key: Error

When I look at the curl return code where I'm setting the pinned key, it's CURLE_NOT_BUILT_IN.

Digging into the curl source, I can see this section in lib/setopt.c:

  case CURLOPT_PINNEDPUBLICKEY:
    /*
     * Set pinned public key for SSL connection.
     * Specify file name of the public key in DER format.
     */
#ifdef USE_SSL
    if(Curl_ssl->supports & SSLSUPP_PINNEDPUBKEY)
      result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG],
                              va_arg(param, char *));
    else
#endif
      result = CURLE_NOT_BUILT_IN;
    break;

As far as I can tell, the enabling of the DarwinSSL backend in the prebuilt binaries build script should define USE_SSL (curl_setup.h) which leads me to the Curl_ssl->supports bit for SSLSUPP_PINNEDPUBKEY is not set. The docs for this feature (https://curl.haxx.se/libcurl/c/CURLOPT_PINNEDPUBLICKEY.html) say that support should be from 7.54.1: SecureTransport/DarwinSSL on macOS 10.7+/iOS 10+ and I'm using the 7.60 release.

I've confirmed this by pulling the curl version info that reports as follows:

screenshot 2018-11-28 at 18 04 37

My attempts to manually build here to try things have been scuppered by this error:

url.c:55:2: error: "We can't compile without socket() support!"

..but I've seen the other tickets (e.g. #19 ) where you point people to run xcode-select --install, which just says:

xcode-select: error: command line tools are already installed, use "Software Update" to install updates

I assume this difficulty in checking anything is an Xcode / Mojave issue but I see from #56 you can't upgrade until the new year.

In the meantime, any ideas where the issue for this lies?

@gustavogenovese
Copy link
Owner

You could try Xcode 9 and see if it builds. Sorry that's the only tip I have for you at this moment

@jahngordon
Copy link
Author

Thanks - will give it a try and if I get to the bottom of it, will add to this.

@jahngordon
Copy link
Author

Looks like the build issue is referred to upstream and comment curl/curl#3189 (comment) recommends installing the following package:

/Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg

This seems to be added to the machine by the xcode-select --install step.

Installing this package, deleting curl/configure and re-running the build gets the iOS build running on Mojave (possibly solving #56 ).

In my case I encountered this error:

ld: warning: ignoring file /opt/local/lib/libz.dylib, file was built for x86_64 which is not the architecture being linked (armv7): /opt/local/lib/libz.dylib

It seems that I have a libz in /opt/local for something or other and the only way I could prevent attempts to link against this was by renaming libz.dylib and libz.a to libz.dylib.unused and libz.a.unused. After that, this project happily builds on Mojave... I'm now digging deeper on the pinning issue.

@jahngordon
Copy link
Author

jahngordon commented Nov 29, 2018

The answer is right there in my initial post... it's the supported iOS version. Curl sets or resets SSLSUPP_PINNEDPUBKEY based on the compile time version, not at runtime; this is consistent with documentation and resulting error codes.

Setting IPHONEOS_DEPLOYMENT_TARGET="10" in the build_iOS.sh script enables the support and when I run...

ENABLING PINNING
Set Fail on Error: No error
Set verify peer: No error
Set verify host: No error
Set pinned key: No error

Closing issue as this is intended and expected operation for iOS 9 which is the current spec for the prebuilt binaries.

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

No branches or pull requests

2 participants