Search code examples
phpapachesslrhel

SSL Verify Server Certificate error when calling API on same localhost (tls_process_server_certificate:certificate verify failed)


My dilemma is that I have two domains running on localhost, domain_a and domain_b. They're both running nginx, apache, and php-fpm. domain_a is running CodeIgniter 3.0.0, and domain_b is running CodeIgniter 4. In another VM, I had domain_a in a Docker container, and was able to hit the API endpoints in domain_b without any issues. Development work made it a requirement to have them both be on the same server, as it's close to how it will be in other environments.

For specifics, we're using the PHP oAuth module, and it throws an error that "making the request failed (dunno why)", which is extremely helpful. After some digging, I found that I could hit other endpoints without issue (such as google.com and a known endpoint outside these domains). I attempted to use cURL in place of oAuth (just a simple test to hit the endpoint), and I consistently get the same error.

tls_process_server_certificate:certificate verify failed

The certs I use are all self-signed for both domains, and I'm able to reach both domains from within the browser without issue. If it matters, both domains have user certs when logging in, but the users aren't the same, as each domain has their own self-signed CA.

My current code is this:

$conn = new OAuth($consumer_key, $consumer_secret, $oauth_sig_method);
$conn->enableDebug();
/*
if (is_on_local()) {
  $conn->setCAPath('path/to/cert.cert');
}*/
$conn->disableSSLChecks();
$token = $conn->getRequestToken($auth_url);

I left the commented out part in to show what I've tried - I've tried pointing that to the system cert, domain_a CA, and domain_b CA, none of which worked. It looks like (for some reason) $conn->disableSSLChecks() isn't working, but I'm not sure of that. The error thrown is in the call to getRequestToken().

My etc/hosts file:

127.0.0.1 domain_a.tld
127.0.0.1 domain_b.tld

The actual TLD isn't tld, but again, they work in the browser and it worked before when domain_a was in Docker.

I've already tweaked domain_a enough so CI 3 works with PHP 8, so I'm convinced the problem is talking from one domain to the other. I'm running RHEL 8, and I've already got SELinux set to Permissive (actually disabled, I think, for development). There's nothing in httpd, nginx, php-fpm, or firewall logs. The only indicator I have is what I get from CI 3 logs in domain_a:

Severity: Warning --> OAuth::getRequestToken(): SSL operation failed with code 1. 
   OpenSSL Error messages:error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed in /path/to/file
Severity: Warning --> OAuth::getRequestToken(): Failed to enable crypto in /path/to/file
Severity: Warning --> OAuth::getRequestToken(domain_b/oauth/access): Failed to open stream: operation failed in /path/to/file

I feel like the answer is right there, I'm just not seeing it.


Solution

  • As usual, shortly after explaining my issue I found the fix. Currently, I have the endpoint as https://domain_b.tld/oauth/access. After some tinkering, I got a different error about SSL version. That put me on the track to the correct answer: http://domain_b.tld:port/oauth/access. I'm able to hit the endpoint now without issue. I've got a virtual hosts file that, even though both domains are on the same port, I had to specify it or the call fails. If anyone else runs into this issue, check the base URL. I never would have thought about hitting http rather than https as a solution.