TJB
TJB

Reputation: 877

PEM Certificate & TLS Verification against REST api

I have been provided with a pem certificate to authenticate with a third party. Authenticating using certificates is a new concept for me.

Inside are two certificates and a private key.

The issuer has advised they do not support SSL verification but use TLS(1.1/1.2).

I have run a script as below:

import requests as req
import json

url = 'https://url.com/call'
certificate_file = "C:/certs/cert.pem"

headers = {"Content-Type": "application/json"}
 
req_body ={
    "network":{
                "network_id": 12345
    },
    "branch":{
                "branch_id": 12345,
    },
  "export_period":{
        "start_date_time": "16-11-2021 00:00:00",
        "end_date_time": "17-11-2021 00:00:00"
    }
}
 
jsonObject = json.dumps(req_body)
response = req.post(url,headers=headers,params=jsonObject,verify=certificate_file)

I'm getting the following error:

SSLError: HTTPSConnectionPool(host='url.com, port=443): Max retries exceeded with url: /call?%7B%22network%22:%20%7B%22network_id%22:%2012345%7D,%20%22branch%22:%20%7B%22branch_id%22:%2012345%7D,%20%22export_period%22:%20%7B%22start_date_time%22:%20%2216-11-2021%2000:00:00%22,%20%22end_date_time%22:%20%2217-11-2021%2000:00:00%22%7D%7D (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)')))

Would appreciate guidance, my gut says I should be doing something specific for TLS hence the SSL error.

Upvotes: 5

Views: 4373

Answers (3)

Reese Krome
Reese Krome

Reputation: 313

I found a similar question with answers. It looks like it is possible that the the system security library is failing to find the certificate in the chain because "only the certificates chains that are stored in cacert.pem are considered valid."

Upvotes: 0

Gary Archer
Gary Archer

Reputation: 29218

The issuer is using an up to date version of HTTPS - SSL is the commonly used term but TLS is the more correct one. Sounds like their setup is correct - meaning you need to call it with a trusted client certificate, as part of an HTTPS request.

I would recommend doing it with the curl tool first so that you can verify that the API works as expected.

curl -s -X GET "https://api.example.com/test" \
--cert ./certs/example.client.pem \
--key ./certs/example.client.key \
--cacert ./certs/ca.pem \
-H "Content-Type: application/json"

Split the certs into separate files as above. Sounds like one of them is a root certificate authority that you need to tell the client tech stack to trust - for curl this is done using the cacert parameter as above.

Once this is working you can follow the same approach in the Python requests library. I believe this uses cert and verify parameters like this. So it looks like your code is not far off.

result = requests.get(
    'https://api.example.com',
    cert=('example.pem', 'example.key'),
    verify='ca.pem')

MORE ABOUT MUTUAL TLS

Out of interest, if you ever want to demystify Mutual TLS and understand more, have a look at these advanced Curity resources:

These include an OpenSSL Script you can run, to see what the separated certificate files should look like.

Upvotes: 8

JustLudo
JustLudo

Reputation: 1790

The issuer has advised they do not support SSL verification

To me this sounds pretty risky, but if that is indeed the case a simple

verify=False

should do the trick. Note: this disables the verification of the SSL certs for this call entirely.

Furthermore, in case you still want the SSL certs in there (copy-pasted from my comment):

I don't think you need to do anything with TLS, this is usually picked up as the connection will be made. Instead it seems to be somewhere in either the certificate (not being correct or self-signed and not verified) or you are missing an intermediate certificate in the chain. Alternatively your list of CA (Certificate Authorities) might be incomplete. I have never used this in python but apparently there are ways to update this using certifi . Documentation on this can be found in this relevant SO question.

Upvotes: 0

Related Questions