2

I have been fighting this issue for a while and cannot seem to get it right. To preface, this is my first experience having to work with SSL. The server I am working on is using PHP 5.6.30 and Laravel 5.1.46, and I'm trying to use GuzzleHttp 6.2.3 to post JSON to a third party. Up until now, I've been disabling ssl verification by specifying 'verify' => false within the client, and have been able to get successful responses. The third party provided me with a certificate to use, and gave me both .pem and .cer formats. They stated the certificate is not password protected since it is the public key. According to GuzzleHttp's documentation, my request should look like this:

$response = $client->request('POST', $endpoint, [
    'cert' => /path/to/new/cert.pem,
    'headers' => [
      'Content-type' => 'application/json'
    ],
    'body' => $request_body,
    'connect_timeout' => 5,
]);

I cannot connect using this method, and unfortunately I can't get the low level error detail due to the design of the server I'm working on (it's a large pre-existing codebase I'm having to update, it will hopefully eventually be completely rewritten).

In order to get more detail, I decided to send the request using cURL. First I sent the request without the certificate:

// REQUEST
curl -v -H "Content-Type: application/json" -X POST -d '{"some_json_request": "value"}' https://sometargeturl.com:8443/dosomething

// OUTPUT
*   Trying 204.71.178.10...
* TCP_NODELAY set
* Connected to sometargeturl.com (204.71.178.10) port 8443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* Server certificate:
*   subject: CN=sometargeturl.com,OU=OU,O="Some Company Name, Inc",L=Pleasanton,ST=California,C=US
*   start date: May 13 00:00:00 2016 GMT
*   expire date: May 14 23:59:59 2018 GMT
*   common name: sometargeturl.com
*   issuer: CN=Symantec Class 3 Secure Server CA - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US
* NSS error -8179 (SEC_ERROR_UNKNOWN_ISSUER)
* Peer's Certificate issuer is not recognized.
* Curl_http_done: called premature == 1
* Closing connection 0
curl: (60) Peer's Certificate issuer is not recognized.

Then, with the certificate:

// REQUEST
curl -v --cert /path/to/the/cert.pem -H "Content-Type: application/json" -X POST -d '{"some_json_request": "value"}' https://sometargeturl.com:8443/dosomething

// OUTPUT
*   Trying 204.71.178.10...
* TCP_NODELAY set
* Connected to sometargeturl.com (204.71.178.10) port 8443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* unable to load client key: -8178 (SEC_ERROR_BAD_KEY)
* NSS error -8178 (SEC_ERROR_BAD_KEY)
* Peer's public key is invalid.
* Curl_http_done: called premature == 0
* Closing connection 0
curl: (58) unable to load client key: -8178 (SEC_ERROR_BAD_KEY)

I've done a ton of research and have not been able to find a solution. I'm really just unsure of next steps at this point. I ultimately will need to use GuzzleHttp to send the request, but I don't what I'm missing. I have read about adding the new cert to an existing CA bundle, however I'm not sure if that is the right solution/how I would do that if so. Any help would be appreciated, thanks!

nhuesmann
  • 437
  • 3
  • 10
  • If you can install it globally, my answer on getting certs to Guzzle might help: https://stackoverflow.com/a/31253824/3854385 (and/or the answer above it) – Loren Oct 04 '17 at 20:02
  • @Loren - I surprisingly never saw that thread. I'll give it a try probably first thing tomorrow morning and will update this thread if it helps. Thank you! – nhuesmann Oct 04 '17 at 22:11

1 Answers1

0

what are you exactly trying to do ?

  • Verifying remote server certificate with 'verify' => true
  • Authenticating yourself by presenting your certificate to remote ?

That being said, your curl is compiled against NSS and not openssl. The NSS error -8178 (SEC_ERROR_BAD_KEY) comes from NSS that does not support providing the private key as a file