10

This is my C++ code that I am using in Obj-C and JAVA projects.

string readBuffer;
string certificateBeingUsed;
CURL *curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_URL, "https://apiServer");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 120);
curl_easy_setopt(curl, CURLOPT_ENCODING, GZIP);

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER , true);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST , 2);
curl_easy_setopt(curl, CURLOPT_CAINFO,certificateBeingUsed);

CURLcode res;
res = curl_easy_perform(curl);

--------------------------------------------------------------------

In Xcode, I have my ceritificate "certificatePinning.der" stored in Resources/Certificates folder.

To use the code above, I set certificateBeingUsed to my certificate path:

certificateBeingUsed = "/Users/graceo/Library/Developer/CoreSimulator/Devices/1BB154CB-276B-4DDC-86C8-4975213D7E3B/data/Containers/Bundle/Application/4819EC2A-CA18-46BF-815F-445B5E3E519F/TestStoryBoardWithLibraryAndSwift.app/certificatePinning.der" 

and res returns success with readBuffer containing the response sent from the server.

--------------------------------------------------------------------

In Android Studio, I have my ceritificate "certificatePinning.der" stored in assets folder. (I copy it to the data folder before using it)

To use the code above, I set certificateBeingUsed to my certificate path:

certificateBeingUsed = "/data/data/packageName/certificatePinning.der" 

but res returns CURLE_SSL_CACERT_BADFILE (77) and readBuffer is empty

--------------------------------------------------------------------

What is it that I am missing in Android that could not validate the certificate stored with the server's ??

NB:

  1. I have SSL supported in libCurl.
  2. In android if I set it to the certificate cacert.pem it will return success, but I want to use my certificate instead.
Grace
  • 1,265
  • 21
  • 47
  • I don't know about cURL, but there's a few example of pinning at OWASP's [Certificate and Public Key Pinning](https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning). They provide examples for Android, OpenSSL, and .Net. No cURL, however. – jww Oct 06 '15 at 13:07
  • What version of `libcurl` is provided for iOS and Android? – jww Oct 06 '15 at 15:29
  • Android: libcurl/7.43.0-DEV OpenSSL/1.0.1o zlib/1.2.8 – Grace Oct 07 '15 at 06:15
  • iPhone: libcurl/7.40.0 SecureTransport zlib/1.2.5 – Grace Oct 07 '15 at 06:15
  • From the question, it wasn't clear whether you have added code to copy the certificatePinning.der file from your app assets to the data folder so it can be accessed using the "/data/data/packageName" path that you are using. It seems you have (since you mentioned it works if you use the cacert.pem file) but just in case you haven't, here's one way to do it: http://stackoverflow.com/a/16984117/1023092 – Joe Oct 13 '15 at 15:13
  • @Joe, yeah I am copying to the data folder before using it. – Grace Oct 14 '15 at 07:08
  • Could you give additional information on how you build and link libcurl and openssl for Android? On the Android emulator have you verified that the file "/data/data/packageName/certificatePinning.der" actually exists e.g. through the adb shell? One possibility to debug is to strace the app, to see what files it opens, http://stackoverflow.com/questions/12166917/android-how-to-strace-an-app-using-adb-shell-am-start – revau.lt Oct 14 '15 at 16:34
  • @revau.lt : For libcurl this is my reference: https://github.com/gcesarmza/curl-android-ios (I use the libraries in the prebuilt with ssl folder). As when building my project I have this in Androidn.mk: #COMPILE LIBCURL include $(CLEAR_VARS) LOCAL_MODULE:= libcurl LOCAL_SRC_FILES := /Users/graceo/AndroidStudioProjects/MyApplication2/app/src/main/jniLibs/$(TARGET_ARCH_ABI)/libcurl.a LOCAL_EXPORT_LDLIBS := -lz LOCAL_EXPORT_C_INCLUDES := /Users/graceo/AndroidStudioProjects/MyApplication2/app/src/main/jniLibs/include/curl include $(PREBUILT_STATIC_LIBRARY) – Grace Oct 15 '15 at 06:38
  • @revau.lt the thing is it verifies with cacert.pem but not with my own certificate (the same certificate that i use from ios) – Grace Oct 15 '15 at 06:40
  • Would you be able to share a stripped down project on github? – revau.lt Oct 15 '15 at 13:17
  • @revau.lt Although this is the whole code I'm trying to run, I will try to post a MWE – Grace Oct 15 '15 at 14:04
  • @revau.lt I think it will not make any difference, since i will not be able to send you my certificate, it might work with your certificate – Grace Oct 15 '15 at 14:41
  • @revau.lt You can also find my question on how I am sending the certificate http://stackoverflow.com/questions/32648577/libcurl-curle-ssl-cacert-badfile-error-on-android – Grace Oct 15 '15 at 14:44
  • Ok. To have the fully configured project would make it much easier for discussion and to reproduce the problem. Here a couple of pointers what I would check: 1) the cert is correctly copied to the location on the device, check with adb and compare md5sum, 2) libssl for android supports the DER format, check configure output of curl-android-ios, 3) libssl is reading from the right location, trace the open system calls with strace described in previous comment 4) the date and time are correctly set on the device you test and lies in between start and enddate of the certificate – revau.lt Oct 16 '15 at 05:58
  • @revau.lt okay so for 2 - I converted my file to .pem format, it gives error no 60, for 4 - the date and time are correct, as for 1 and 3 I will check them now, I need to see how, I am no expert in adb and md5sum – Grace Oct 16 '15 at 06:12
  • Adb lets you connect to a device or simulator. I would recommend the simulator since you have more rights, adb shell should do the trick. Copy the file from the simulator with adb and compare it with the one expect. E.g. diff copied.der expected.der – revau.lt Oct 16 '15 at 06:33

1 Answers1

1

This may be a problem with encoding, try to convert your .der file to .pem format using this:

openssl x509 -in cert.crt -inform der -outform pem -out cert.pem
Dominick Navarro
  • 752
  • 6
  • 20
  • yeah I've tried that also. It gives me error no 60 --- CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ – Grace Oct 16 '15 at 05:14