2017-03-23 1 views
3

Ich versuche cppnetlib zu verwenden, oder auch die Boost Asio-Bibliotheken zu verbinden, um eine einfache URL zu tun und die resultierende Seite zu ziehen.https Client erhalten mit cpp-Netlib mit einem Client-Zertifikat und Passwort

Ich habe es mit http zu arbeiten, und sogar https usign cppnetlib, aber ich muss eine Client-Zertifikat liefern, die ein Passwort akzeptiert .. Unforntuntley Ich bin verpflichtet, die ältere v0.10 cppnetlib verwenden.

Ist dies möglich? Ich denke, die Antwort ist, meinen eigenen _io_service zu erstellen und custome es für die https-Anforderung mit Zertifikat und Kennwort zu konfigurieren und es dann an den boost :: network :: http: client-Konstruktor zu liefern. Das Folgende funktioniert in http und funktioniert für https ohne eine Cert-Anforderung.

std::string url = "http://www.boost.org"; 
std::string certFile = "C:\\cert\\mycert.p12"; 
std::string password = "MyPassWord"; 
try { 
     http::client client; 
     http::client::request request(url); 
     http::client::response response = client->get(request); 

     std::string resultText = static_cast<std::string>(body(response)); 
     std::cout << resultText << std::endl; 
     delete client; 
    } 
    catch (std::exception &e) { 
     std::cerr << "Caught something connecting " << e.what() << std::endl; 
    } 
+0

verwendet wird, schließt Ich würde auch Asio direkt für eine Ausnahme der Verwendung von https erhalten, die eine p12-Datei und das Passwort als Client-Zertifikat verwendet – Jim

+0

Es stellt sich heraus, dass es nicht mit getan werden kann, cppnetlib v0.10, würde ich eine Lösung mit einer Standard-PEM-Datei mit Asio von Boost 1.49 akzeptieren – Jim

Antwort

0

v0.10 cppnetlib unterstützt Client-Zertifizierungen nicht direkt. Da Ihr cppnetleb verwenden, können Sie Boost Asio mit 1,49 boost

Hier ist ein Beispiel-Code, der den größten Teil der Asio funktionierts https://github.com/alexandruc/SimpleHttpsClient/blob/master/https_client.cpp

Dieser Code ist sehr ähnlich http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio/example/ssl/client.cpp

ich setzen bin sowohl in Fall die Links brechen. Das übernimmt die https-Verbindung Zertifizierung zu tun Client benötigen Sie die folgenden Zeilen in der Hauptfunktion hinzuzufügen, bevor Sie den Client zu erstellen:

 std::string tempString = "test.pem"; //this is a pem file that contains a private key and a certificate. 

     boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23_client); 
     ctx.set_options(boost::asio::ssl::context::default_workarounds 
            | boost::asio::ssl::context::no_sslv2 
            | boost::asio::ssl::context::no_sslv3); 
     ctx.set_default_verify_paths(); 

     ctx.use_certificate_file(tempFileStr.c_str(), boost::asio::ssl::context_base::pem); 
     ctx.use_private_key_file(tempFileStr.c_str(), boost::asio::ssl::context_base::pem); 

jedoch in diesem Beispiel Sie nicht über eine PEM-Datei, sondern eine p12-Datei (pkcs12 Format). openssl kann verwendet werden, um die deisred pem-Datei zu entschlüsseln und zu erstellen. Ich habe den Code unten von How to load a PKCS#12 file in OpenSSL programmatically? angepasst Leider ist diese Version von Boost nicht unterstützt Zertifikate im Speicher, so dass es geschrieben werden muss, dycrypted in eine Datei. Ich lege das in das Temp-Verzeichnis und es sollte am Ende gelöscht werden.

std::string _certFile = "C:\\cert\\mycert.p12"; 
std::string password = "_certPassword"; 
boost::filesystem::path tempFile = boost::filesystem::temp_directory_path()/"temp.pem"; 
std::string tempFileStr = tempFile.generic_string(); 
std::cout<<"Using temp file " << tempFileStr<<std::endl; 
try 
    { 

     //read in the pksc12 file, decode it and write a PEM file 
     FILE *fp; 
     EVP_PKEY *pkey; 
     X509 *cert; 
     STACK_OF(X509) *ca = NULL; 
     PKCS12 *p12; 
     int i; 

     OpenSSL_add_all_algorithms(); 
     ERR_load_crypto_strings(); 
     if (!(fp = fopen(_certFile.c_str(), "rb"))) { 
      fprintf(stderr, "Error opening file %s\n", _certFile); 
      return false;  
     } 
     p12 = d2i_PKCS12_fp(fp, NULL); 
     fclose (fp); 
     if (!p12) { 
      fprintf(stderr, "Error reading PKCS#12 file\n"); 
      ERR_print_errors_fp(stderr); 
      return false; 
     } 
     if (!PKCS12_parse(p12, _certpPassword.c_str(), &pkey, &cert, &ca)) { 
      fprintf(stderr, "Error parsing PKCS#12 file\n"); 
      ERR_print_errors_fp(stderr); 
      return false; 

     } 
     PKCS12_free(p12); 
     if (!(fp = fopen(tempFileStr.c_str(), "w"))) { 
      fprintf(stderr, "Error opening file %s\n", tempFileStr.c_str()); 
      return false; 
     } 

     if (pkey) { 
      fprintf(fp, "***Private Key***\n"); 
      PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL); 
     } 
     if (cert) { 
      fprintf(fp, "***User Certificate***\n"); 
      PEM_write_X509(fp, cert); 
     } 
     if (ca && sk_X509_num(ca)) { 
      fprintf(fp, "***Other Certificates***\n"); 

      for (i = 0; i < sk_X509_num(ca); i++) 
      { 
       PEM_write_X509(fp, sk_X509_value(ca, i)); 
      } 

     } 

     sk_X509_pop_free(ca, X509_free); 
     X509_free(cert); 
     EVP_PKEY_free(pkey);  
     fclose(fp); 

    } 
    catch (std::exception &e) { 
     retVal = false; 
     std::cout <<"Error parsing/decrypting pkcs12 file into PEM or writing temporary pem file" << e.what() << std::endl;   
    } 

Hier sind die I

//for ssl connection 
#include <boost/asio.hpp> 
#include <boost/asio/ssl.hpp> 
#include <boost/asio/ssl/context_base.hpp> 

//for parsing key file 
#include <openssl/pkcs12.h> 
Verwandte Themen