Forum: PC-Programmierung OpenSSl (unable to get local issuer certificate) mit gSOAP (Linux geht, Windows nicht)


von A. C. (michael1988)


Lesenswert?

Hallo,
ich arbeite mit der Paypal api mit gsoap in C++.

Unter Linux funktioniert mein Programm, unter Windows bekomme ich immer 
"unable to get local issuer certificate" von meiner Apifunktion 
("paypalProxy.GetBalance") zurück.

Das Problem hängt damit zusammen, dass OpenSSL keine passende Liste der 
trusted CAs hat, weil wenn ich folgendes unter Windows und Linux laufen 
lasse:
1
openssl s_client -connect api-3t.sandbox.paypal.com:443 -showcerts | egrep -wi "G5|return"

- linux: 'Verify return code: 0 (ok)'.
- windows 'unable to get local issuer certificate'.

Mit zusätzlicher Option '-CAfile .\cabundle.crt' in windows:
'Verify return code: 0 (ok)',

dabei ist "cabundle.crt" das mozilla certificate bundle von: 
http://curl.haxx.se/docs/caextract.html

Ich muss openssl also klar machen, wo das crt File liegt, am besten 
Systemweit, weil unter Linux geht es ja auch.

Ich habe auch schon versucht, das .crt unter "C:\OpenSSL-Win32\certs" zu 
den anderen Zertifikaten von openSSL zu legen, leider ohne Erfolg
1
    int main(int argc, char* argv[])
2
    {
3
      std::string strSignature;
4
      PayPalAPISoapBindingProxy paypalProxy("https://api-3t.sandbox.paypal.com/2.0/");
5
      struct soap *soap = soap_new(); // create a new context
6
      soap_init(soap);
7
    
8
      paypalProxy.header = new SOAP_ENV__Header;
9
      paypalProxy.header->ns1__RequesterCredentials = new ns3__CustomSecurityHeaderType;
10
      paypalProxy.header->ns1__RequesterCredentials->eBayAuthToken = NULL;
11
      paypalProxy.header->ns1__RequesterCredentials->Credentials = new ns3__UserIdPasswordType;
12
      paypalProxy.header->ns1__RequesterCredentials->Credentials->AppId = NULL;
13
      paypalProxy.header->ns1__RequesterCredentials->Credentials->DevId = NULL;
14
      paypalProxy.header->ns1__RequesterCredentials->Credentials->AuthCert = NULL;
15
    
16
      paypalProxy.header->ns1__RequesterCredentials->Credentials->Username = soap_strdup(soap, "XXXXXX");
17
      paypalProxy.header->ns1__RequesterCredentials->Credentials->Password = soap_strdup(soap, "XXXXXX");
18
      strSignature = soap_strdup(soap, "XXXXXX"); // Sandbox env
19
      paypalProxy.header->ns1__RequesterCredentials->Credentials->Signature = &strSignature;
20
    
21
      _ns1__GetBalanceReq ns1__GetBalanceReq;
22
      ns1__GetBalanceResponseType ns1__GetBalanceResponse;
23
    
24
      ns1__GetBalanceReq.GetBalanceRequest = new ns1__GetBalanceRequestType; 
25
      ns1__GetBalanceReq.GetBalanceRequest->DetailLevel.push_back(ns3__DetailLevelCodeType__ReturnAll);
26
    
27
      soap_ssl_init();
28
29
      if (soap_ssl_client_context(soap, SOAP_SSL_DEFAULT, NULL, NULL, "cacert.crt", NULL, NULL))
30
      {
31
        soap_print_fault(soap, stderr);
32
        exit(1);
33
      }
34
      char buf[1024];
35
      int res = paypalProxy.GetBalance(&ns1__GetBalanceReq, ns1__GetBalanceResponse);
36
      if (res != SOAP_OK)
37
      {
38
        soap_sprint_fault(soap, buf, 1024);
39
      }
40
      else
41
      {
42
        std::ostringstream oss;
43
        oss << ns1__GetBalanceResponse.Balance << std::endl;
44
        std::cout << oss.str() << std::endl;
45
        oss << ns1__GetBalanceResponse.BalanceTimeStamp;
46
        std::cout << oss.str() << std::endl;
47
        //std::cout << ns1__GetBalanceResponse.BalanceHoldings. ->soap_serialize << std::endl;
48
        //std::cout << ns1__GetBalanceResponse.BalanceTimeStamp soap_serialize << std::endl;
49
      }

von A. C. (michael1988)


Lesenswert?

Also keine Idee. Scheint kein spezielles gsoap Problem zu sein, sondern 
eher OpenSSL.

Wie gesagt, wenn ich das CAfile angebe, habe ich die gleiche Kette an 
trusted CAs wie unter Linux

von Hmmm (Gast)


Lesenswert?

A. C. schrieb:
> Ich muss openssl also klar machen, wo das crt File liegt, am besten
> Systemweit, weil unter Linux geht es ja auch.

Im Source Code von OpenSSL solltest Du die Defaults beider Plattformen 
finden.

Ansonsten gibt es noch openssl.conf/openssl.cfg.

von Thomas Z. (thomas_z41)


Lesenswert?

OpenSSL bietet dir die Möglichkeit ein CA Bundle anzugeben: 
https://www.openssl.org/docs/man1.1.0/ssl/SSL_load_client_CA_file.html

Guck mal ob du an den OpenSSL Context herankommst, dann kannst du das 
darüber lösen.

von bluppdidupp (Gast)


Lesenswert?

Unter Windows kann man normalerweise per Umgebungsvariable OPENSSL_CONF 
den Pfad zur openssl-Konfigurationsdatei vorgeben.

von A. C. (michael1988)


Lesenswert?

Das mit OPENSSL_CONF  habe ich schon versucht, das klappt leider nicht.

Das OPENSSLDIR wird auch nicht übernommen, wenn man es per 
UMgebungsvariable setzt. Wenn ich openssl version -d mache, kommt immer 
/etc/ssl. Erst nachdem ich OpenSSL selbst von Source gebaut habe und 
dabei openssl-dir angegeben hatte, hat sich der Wert geändert.

von Dr. Google (Gast)


Lesenswert?

Die Microsoft Implementierung der SOAP-Schnittstelle weicht deutlich vom 
Standard ab. Namespaces werden anders behandelt und auch v.a. der 
"AnyType"für variant Datentypen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.