1

I'm using Python's requests library to perform client side authentication with certificates. The scenario is the following: CA1 has issued a certificate for an intermediate CA (CA2) and CA2 has issued my client's certificate CLIENT. The server I'm connecting to trusts CA1's cert (but does not have CA2's cert). When I use:

requests.get('https:..', cert=('/path/CLIENT.cert', '/path/CLIENT.key'))

I get an error "certificate verify failed". I assumed that's because the server can not retrieve CA2's cert.

However, I'm unable to find a way to send CA2's cert to the server. If I include it in CLIENT, I get an error about private key and cert mismatch. I have also tried to include the chain of certificates in the verify parameter but there does not seem to be any difference on the result (as far as I understand, certs in the verify parameter are used for server side authentication).

Although I think this must be a quite common scenario, I'm unable to find a solution...

PD: If I verify CLIENT's cert with openssl and the full chain of certificates the validation is successful (so there is no problem with the certificates themselves).

cpsola
  • 111
  • 1
  • 3
  • How about passing _path to the directory containing certs of trusted CAs_ to `verify`? – Oluwafemi Sule Jul 21 '17 at 11:54
  • Thnks @OluwafemiSule Indeed, I have already tried that without any success (as far as I understand, certs in the verify parameter are used for server side authentication, but not for client side auth.) – cpsola Jul 21 '17 at 14:42
  • Is `'/path/CLIENT.cert'` a **chained Certificate**? Read about: [How does an SSL certificate chain bundle work?](https://stackoverflow.com/questions/20409534/how-does-an-ssl-certificate-chain-bundle-work) – stovfl Jul 21 '17 at 17:10
  • Yes, I have tried to include the chain into CLIENT.cert, but I obtain an error about private key and cert mismatch whenever I include the intermediate CA's certs into CLIENT.cert. Currently I think there is a problem with the CA's certificate (even though openssl validates them correctly...) – cpsola Jul 26 '17 at 09:31
  • @stovfl Indeed, `/path/CLIENT.cert` had to be a chained certificate with the first certificate being the client one. In my case, there was a problem with the intermediate CA's cert (openssl validated it correctly but the server was more sensitive and failed to do so). If you want, write this as an answer and I would accept it! Thanks for the help. – cpsola Jul 28 '17 at 07:52

1 Answers1

0

Requests recommends using certifi as a CA bundle. Have you tried installing certifi, adding CA1, and passing the certifi bundle path to requests?

F. Stephen Q
  • 4,208
  • 1
  • 19
  • 42
  • Thanks! As far as I know certifi is used to verify the server's cert in the client machine (the one using requests to make the petition), but the problem I have is with client authentication (that is, the server needs to be able to verify my client's cert). – cpsola Jul 21 '17 at 15:30
  • So you get this error on the server side? What are you using to receive requests on the server side, then? – F. Stephen Q Jul 21 '17 at 15:59
  • Yes, the server says the certificate is not valid, and I can see it both in the server logs and the response I get from the server (in the client). The server is running java spring. The server trusts `CA1` cert (but does not have the intermediate CA `CA2` cert). I don't know how I can send CA2 to the server so that it can properly validate my client's cert. – cpsola Jul 21 '17 at 16:12