pythonsslpython-requestsssl-certificatehandshake

Python request with certificates error. Caused by SSLError(SSLError(9, '[SSL] PEM lib (_ssl.c:4027)


Here is my code:

import requests


url = 'https://ecomm.pashabank.az:18443/ecomm2/MerchantHandler'

headers = {'content-type' : 'application/json'}

data = { # some optional data
    "command": "v",
    "amount": "10",
    "currency": "932",
    "client_ip_addr": "167.992.139.153",
    "msg_type": "SMS"
}

# all certificates are in the current directory within this script file
psroot = "PSroot.pem"
cert_file = "certificate.0025598.der"
key_file = "certificate.0025598.pem"

certs = (cert_file, key_file, psroot)
response = requests.post(url, cert=certs)

raises this error:

Traceback (most recent call last):
  File "/Users/mammadaliyevmammadali/Desktop/bank/main.py", line 19, in <module>
    response = requests.post(url, cert=certs)
  File "/Users/mammadaliyevmammadali/.local/share/virtualenvs/bank-wIDLHQju/lib/python3.9/site-packages/requests/api.py", line 115, in post
    return request("post", url, data=data, json=json, **kwargs)
  File "/Users/mammadaliyevmammadali/.local/share/virtualenvs/bank-wIDLHQju/lib/python3.9/site-packages/requests/api.py", line 59, in request
    return session.request(method=method, url=url, **kwargs)
  File "/Users/mammadaliyevmammadali/.local/share/virtualenvs/bank-wIDLHQju/lib/python3.9/site-packages/requests/sessions.py", line 587, in request
    resp = self.send(prep, **send_kwargs)
  File "/Users/mammadaliyevmammadali/.local/share/virtualenvs/bank-wIDLHQju/lib/python3.9/site-packages/requests/sessions.py", line 701, in send
    r = adapter.send(request, **kwargs)
  File "/Users/mammadaliyevmammadali/.local/share/virtualenvs/bank-wIDLHQju/lib/python3.9/site-packages/requests/adapters.py", line 563, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='ecomm.pashabank.az', port=18443): Max retries exceeded with url: /ecomm2/MerchantHandler (Caused by SSLError(SSLError(9, '[SSL] PEM lib (_ssl.c:4027)')))

Pay attention to _ssl.c:4027 at the end of error. I couldn't find out how to fix this. I need to verify my 3 certificates proceeding the request. How to do that? All certificates are correctly formed and passed for security. All implementations are correct, but my script doesn't work. Please help!


Solution

  • cert_file = "certificate.0025598.der"
    

    Given the file extension this looks like a DER formatted certificate to me. But a PEM formatted is expected. Certificates can be converted from DER to PEM with

     openssl x509 -inform der -in certificate.0025598.der -out certificate.0025598.pem
    

    And then use certificate.0025598.pem instead.

    .... Caused by SSLError(SSLError(9, '[SSL] PEM lib (_ssl.c:4027)')))

    This error refers to the line 4027 in Modules/_ssl.c in the source code, but without having your exact Python version it is not known what code is at this line number. All what is known is that your are using some sort of Python 3.9. A relevant code near this line number is this though:

      4031      r = SSL_CTX_use_certificate_chain_file(self->ctx,
      4032          PyBytes_AS_STRING(certfile_bytes));
      4033      PySSL_END_ALLOW_THREADS_S(pw_info.thread_state);
      4034      if (r != 1) {
      ...
      4044              _setSSLError(NULL, 0, __FILE__, __LINE__);
    

    This is the code which tries to load the certificate given as client certificate, i.e. your certificate.0025598.der. PEM lib means that the error comes from a part in OpenSSL which tried to interpret the certificate as PEM - and failed. Thus it matches what I've speculated initially, i.e. that your certificate is not in the expected PEM format but in DER format.