I've been trying to start a websocket server with a certificate configured. Code is really basic, taken from the examples of the websockets library for python (the async one). Here it is:
import asyncio
import os
import ssl
import websockets
async def hello(websocket, path):
pass
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
localhost_pem = os.path.join("cert", "certificate.pem")
ssl_context.load_cert_chain(localhost_pem)
start_server = websockets.serve(
hello, "localhost", 8765, ssl=ssl_context
)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
I've tried generating a certificate via openssl (downloaded windows command line tool), with the script available at github (providing localhost as the hostname), and the answer here on stackoverflow, but all the time I'm getting the same error from within the ssl C code:
Traceback (most recent call last):
File "...", line 12, in <module>
ssl_context.load_cert_chain(localhost_pem)
ssl.SSLError: [SSL] PEM lib (_ssl.c:4065)
Line 12 of my script is the ssl_context.load_cert_chain(localhost_pem) part, which means, python is unable to import the certificate. I've looked over the source code of _ssl.c, line 4065, as the error suggests, which is available here.
There is a function, which is called _add_ca_certs(), which returns -1 on error (here is the source code of the function itself).
I suppose, CA means Certification Authority. I think the code itself cannot possibly know, that this certificate is not authorized properly, so it must be something else. The function itself provides some basic checks: if the certificate is too long (len > INT_MAX) or non existent at all (len == 0).
Every certificate I've generated has .pem extension and looks like this:
-----BEGIN CERTIFICATE-----
MIICzTCCAbWgAwIBAgICA+gwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJbG9j
YWxob3N0MB4XDTIxMDcxMjEwNDYwNloXDTMxMDcxMDEwNDYwNlowFDESMBAGA1UE
AwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt5v8
hD23wCNoJKgNCrd0aZIAngdFRj8I0G3orS5ShIHdhb7YjvV8efJYvbRh+nYQMQns
m5INJYw7n4z07UECiFFQj8HhWgdFjaR6FPVaJULkmu6ZVc2EOrSBytn6CbMCEtHP
6giCg8RcETrtxS63byNGaCMdoAPU8EC1TOKKEdYK9gq2kS2Xad2Oc2AFc6CCae7g
nbXA4yH81IApkxm9Yuus/+XDjLt5nDJB3MlTM/s/uG2T2DYBFJEstCOMvX8u0uql
T4biSKgTwYsxzKX5ZnqoAR9jNSnterfcPFjDZM63+ApMHOvTrNvr2JjWZJKr128Z
8M394gNnM2+8E2N/5QIDAQABoykwJzAPBgNVHRMECDAGAQH/AgEAMBQGA1UdEQQN
MAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAfKDrGvSX++GvoIRTf51W
fcXbdQS9sluNp3fn4VV2K2VamNVt3upYtq+vOp+hTa/At4Gku9feAxerirIVwcCF
wA0f6zFkHt/udT6Fb5X9yndOSR4PrFIJH/v3IvVs2R0zyVdYTC4o62EA27WdaNai
MjGoR0OlsYU/8RGMzTdnH6NRBC5lxSNhqNvFOHoLK6oDaMR9chhqE2BVQ+X14wvb
NnxpmVSlDc5XrcFMsGBtVbnzYWKnvzhgb/NlJ/gXpv825q7P3LqJkF6zaO20EZAW
AX2i/PwQ0Poy9bU/utwDWc5RCx9M90hXstGP4p9LnLAjMOG6ZAXd4ZgSVFlRF+3e
6Q==
-----END CERTIFICATE-----
This is the file I feed to the ssl_context.load_cert_chain function. I've tried feeding in the private key, too, but the same error persists. What could go wrong in the system?
The websocket server will be accessed by only authorized client-side applications written in the same python library, no clients from browsers.