2015-09-18 5 views
7

Also ich versuche, libcurl mit JNI verwenden, aber es gibt CURLE_SSL_CACERT_BADFILE Fehler zurück. Das ist mein Code.libcurl CURLE_SSL_CACERT_BADFILE Fehler auf Android

JNI Seite:

static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) 
{ 
    ((string*)userp)->append((char*)contents, size * nmemb); 
    return size * nmemb; 
} 


//jList is an array containing the certificate. 

Java_packageName_MainActivity_Test(JNIEnv *env, jobject thiz, jobject jList) 
    { 

     vector<string> certificatesPinning; 

     // Convert jobject to jobjectArray 
     // retrieve the java.util.List interface class 
     jclass cList = env->FindClass("java/util/List"); 
     // retrieve the toArray method and invoke it 
     jmethodID mToArray = env->GetMethodID(cList, "toArray", "()[Ljava/lang/Object;"); 
     jobjectArray stringArray = (jobjectArray)env->CallObjectMethod(jList, mToArray); 

     // Add each certificate to the list 
     int stringCount = (env)->GetArrayLength(stringArray); 
     for (int i=0; i < stringCount; i++) 
     { 
      jstring certificateString = (jstring)(env)-> GetObjectArrayElement(stringArray, i); 
      const char *cert = (env)->GetStringUTFChars(certificateString, 0); 
      const jsize len = env->GetStringUTFLength(certificateString); 

      string certificatePinningObj(cert,len); 

      certificatesPinning.push_back(certificatePinningObj); 
      (env)->ReleaseStringUTFChars(certificateString, cert); 
     } 

     string readBuffer; 
     CURL *curl = curl_easy_init(); 
     curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); 
     curl_easy_setopt(curl, CURLOPT_URL, "https://theapi.com"); 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);// Fill the response in the readBuffer 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); 
     curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 120); // 120 s connect timeout 
     curl_easy_setopt(curl, CURLOPT_ENCODING, GZIP); 
     curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"der"); 

     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER , 1); 
     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST , 2L); 
     curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); 
     curl_easy_setopt(curl, CURLOPT_CAINFO,certificatesPinning[0].c_str());//buf 


     CURLcode res; 
     res = curl_easy_perform(curl); 
     if(!readBuffer.empty()) 
     { 
      printf("success \n"); 
     } 
     else 
     { 
      printf("error \n"); 
     int a = (int)res;// this is 77 = CURLE_SSL_CACERT_BADFILE 

     } 
    } 

JAVA Seite:

// Define the function 
native void Test(ArrayList<String> certificates); 

// Prepare the certificate 
ArrayList<String> certificatesPinning = new ArrayList<String>(); 
certificatesPinning.add(saveCertPemFile()); 

// Call the function 
Test(certificatesPinning); 


// Helpers 
    private String saveCertPemFile() 
    { 
     Context context=getApplicationContext(); 
     String assetFileName="certificateName.der"; 

     if(context==null || !FileExistInAssets(assetFileName,context)) 
     { 
      Log.i("TestActivity", "Context is null or asset file doesnt exist"); 
      return null; 
     } 
     //destination path is data/data/packagename 
     String destPath=getApplicationContext().getApplicationInfo().dataDir; 
     String CertFilePath =destPath + "/" +assetFileName; 
     File file = new File(CertFilePath); 
     if(file.exists()) 
     { 
      //delete file 
      file.delete(); 
     } 
     //copy to internal storage 
     if(CopyAssets(context,assetFileName,CertFilePath)==1) return CertFilePath; 

     return CertFilePath=null; 

    } 

    private int CopyAssets(Context context,String assetFileName, String toPath) 
    { 
     AssetManager assetManager = context.getAssets(); 
     InputStream in = null; 
     OutputStream out = null; 
     try { 
      in = assetManager.open(assetFileName); 
      new File(toPath).createNewFile(); 
      out = new FileOutputStream(toPath); 
      byte[] buffer = new byte[1024]; 
      int read; 
      while ((read = in.read(buffer)) != -1) 
      { 
       out.write(buffer, 0, read); 
      } 
      in.close(); 
      in = null; 
      out.flush(); 
      out.close(); 
      out = null; 
      return 1; 
     } catch(Exception e) { 
      Log.e("tag", "CopyAssets"+e.getMessage()); 

     } 
     return 0; 

    } 

    private boolean FileExistInAssets(String fileName,Context context) 
    { 
     try { 
      return Arrays.asList(context.getResources().getAssets().list("")).contains(fileName); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 

      Log.e("tag", "FileExistInAssets"+e.getMessage()); 

     } 
     return false; 
    } 

"certificateName.der" ist das Zertifikat im Assets-Ordner gespeichert.

Und dies ist das Zertifikat Pfad zum jni gesendet werden:

/data/data/packageName/certificateName.der

Reference

Antwort

1

Sie haben voll, was Sie verwenden nicht erklärt hier, aber wie ich werde rate, dass Sie eine libcurl gegen OpenSSL unter gebaut haben. Die Option CURLOPT_CAINFO sollte dann der Dateiname sein, der das CA-Cert-Paket im PEM-Format identifiziert. Dieses Paket enthält alle Zertifikate für Ihre vertrauenswürdigen Zertifizierungsstellen.

Ihre Beschreibung klingt, als ob Sie eine DER-Datei haben, aber Sie können nicht DER für das CA-Cert-Bundle mit OpenSSL verwenden.

Eine gängige Möglichkeit, ein anständiges CA-Paket zu erhalten, ist das Herunterladen der in Firefox enthaltenen PEM version of the bundle that Mozilla ships.

+0

basierend auf meiner anderen Frage zu SO http://StackOverflow.com/Questions/32648577/Libcurl-Curle-SSL-Cacert-badfile-error-on-android/34312254#34312254 Wie kann ich senden die gleiche Datei vom iPhone, aber nicht von Android? Verwenden Sie den gleichen Code in beiden Plattform – Grace

+0

Sie meinen http://stackoverflow.com/questions/32963148/libcurl-certificate-pinning-working-on-iphone-but-not-on-android? Das ist keine _this_ Frage, also wäre es komisch, das hier zu beantworten, aber das scheint auch das falsche Dateiformat zu verwenden, wenn OpenSSL verwendet wird. –