1

I want to work with PayPal api with gsoap in C++. I got my example working on linux, but in windows, I got from 'paypalProxy.GetBalance' "unable to get local issuer certificate".

I already know, that this is a problem, that openssl does not know the trusted CAs. When I issue:

openssl s_client -connect api-3t.sandbox.paypal.com:443 -showcerts | egrep -wi "G5|return"

in linux, I get 'Verify return code: 0 (ok)'. On windows I get 'unable to get local issuer certificate'.

Adding the option '-CAfile .\cabundle.crt' in windows, I also get 'Verify return code: 0 (ok)', where cabundle.crt the mozilla certificate bundle feom here is.

So I wonder, where I have to tell openssl the location of the crt file with gsoap (or even better, systemwide, because the problem does not seem to be in the code)

int main(int argc, char* argv[])
{
    std::string strSignature;
    PayPalAPISoapBindingProxy paypalProxy("https://api-3t.sandbox.paypal.com/2.0/");
    struct soap *soap = soap_new(); // create a new context
    soap_init(soap);

    paypalProxy.header = new SOAP_ENV__Header;
    paypalProxy.header->ns1__RequesterCredentials = new ns3__CustomSecurityHeaderType;
    paypalProxy.header->ns1__RequesterCredentials->eBayAuthToken = NULL;
    paypalProxy.header->ns1__RequesterCredentials->Credentials = new ns3__UserIdPasswordType;
    paypalProxy.header->ns1__RequesterCredentials->Credentials->AppId = NULL;
    paypalProxy.header->ns1__RequesterCredentials->Credentials->DevId = NULL;
    paypalProxy.header->ns1__RequesterCredentials->Credentials->AuthCert = NULL;

    paypalProxy.header->ns1__RequesterCredentials->Credentials->Username = soap_strdup(soap, "XXXXXX");
    paypalProxy.header->ns1__RequesterCredentials->Credentials->Password = soap_strdup(soap, "XXXXXX");
    strSignature = soap_strdup(soap, "XXXXXX"); // Sandbox env
    paypalProxy.header->ns1__RequesterCredentials->Credentials->Signature = &strSignature;

    _ns1__GetBalanceReq ns1__GetBalanceReq;
    ns1__GetBalanceResponseType ns1__GetBalanceResponse;

    ns1__GetBalanceReq.GetBalanceRequest = new ns1__GetBalanceRequestType; 
    ns1__GetBalanceReq.GetBalanceRequest->DetailLevel.push_back(ns3__DetailLevelCodeType__ReturnAll);

    soap_ssl_init();

    if (soap_ssl_client_context(soap, SOAP_SSL_DEFAULT, NULL, NULL, "cacert.crt", NULL, NULL))
    {
        soap_print_fault(soap, stderr);
        exit(1);
    }
    char buf[1024];
    int res = paypalProxy.GetBalance(&ns1__GetBalanceReq, ns1__GetBalanceResponse);
    if (res != SOAP_OK)
    {
        soap_sprint_fault(soap, buf, 1024);
    }
    else
    {
        std::ostringstream oss;
        oss << ns1__GetBalanceResponse.Balance << std::endl;
        std::cout << oss.str() << std::endl;
        oss << ns1__GetBalanceResponse.BalanceTimeStamp;
        std::cout << oss.str() << std::endl;
        //std::cout << ns1__GetBalanceResponse.BalanceHoldings. ->soap_serialize << std::endl;
        //std::cout << ns1__GetBalanceResponse.BalanceTimeStamp soap_serialize << std::endl;
    }
Mich Ael
  • 11
  • 2
  • *"So I wonder, where I have to tell openssl the location of the crt file with gsoap (or even better, systemwide..."* - If gSOAP does not have an explicit API call, then you need to create a `cert.pem` with all the CA's you need, and copy it to OpenSSL's `X509_CERT_FILE` directory. Also see [How can I set up a bundle of commercial root CA certificates?](https://mta.openssl.org/pipermail/openssl-users/2015-December/002553.html) on the mailing list. – jww Oct 30 '17 at 21:08
  • I seem to recall Unix paths show up on Windows, so I'm wondering how well it is going to work. You may need to use another variable, too. You may need to use `OPENSSL_CONF` to specify an `openssl.cnf` file, and then specify the CA certs file in the conf file. Also see [How to determine the default location for openssl.cnf?](https://stackoverflow.com/q/37035300/608639) – jww Oct 30 '17 at 21:09
  • Hm, does not owrk – Mich Ael Nov 02 '17 at 19:37

0 Answers0