Python and TLS/SSL
We first remark that it is possible to use an unverified context, which is an SSL context that disables certificate verification.
Python’s urllib.request for HTTP Requests - Real Python
import ssl
from urllib.request import urlopen
unverified_context = ssl._create_unverified_context()
urlopen("https://expired.badssl.com/", context=unverified_context)
We make a self signed certificate openssl-req.
ubuntu@LAPTOP-JBell:~$ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out req.pem
.......+......+...+....+......+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*............+.+...+.........+...+.....+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*........+.+..+.......+..+...+.+.....+.+...........+.............+............+..+.......+.....+...+.......+...+........+.......+.....................+............+.....+....+..............+.+.....+....+..+...+....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
......+...+..........+..+....+....................+.+......+.................+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+..............+....+.....+.......+...........+.......+..+....+..+....+.........+.....+.......+..+...............+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+..........+......+..+...............+......+.+.....+....+.....+.......+..+.+.........+.....+.+......+......+...+.....+.......+...+......+.........+......+..................+..+.+..............+......+.............+.....+.+........+......+....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CA
State or Province Name (full name) [Some-State]:Ontario
Locality Name (eg, city) []:Toronto
Organization Name (eg, company) [Internet Widgits Pty Ltd]:jordanbell.info
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:Jordan Bell
Email Address []:
In one terminal we run openssl-s_server
ubuntu@LAPTOP-JBell:~$ openssl s_server -accept 60100 -key key.pem -cert req.pem
Enter pass phrase for key.pem:
Using default temp DH parameters
ACCEPT
Then in another terminal we run openssl-s_client
ubuntu@LAPTOP-JBell:~$ openssl s_client -connect 127.0.0.1:60100
CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 C = CA, ST = Ontario, L = Toronto, O = jordanbell.info, CN = Jordan Bell
verify error:num=18:self-signed certificate
verify return:1
depth=0 C = CA, ST = Ontario, L = Toronto, O = jordanbell.info, CN = Jordan Bell
verify return:1
---
Certificate chain
0 s:C = CA, ST = Ontario, L = Toronto, O = jordanbell.info, CN = Jordan Bell
i:C = CA, ST = Ontario, L = Toronto, O = jordanbell.info, CN = Jordan Bell
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
v:NotBefore: Oct 6 01:31:34 2025 GMT; NotAfter: Nov 5 01:31:34 2025 GMT
---
...
---
read R BLOCK
Using the option -verifyCAfile req.pem
, we avoid the error/warning caused by the
server using a self-signed certificate.
ubuntu@LAPTOP-JBell:~$ openssl s_client -verifyCAfile req.pem -connect 127.0.0.1:60100
CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 C = CA, ST = Ontario, L = Toronto, O = jordanbell.info, CN = Jordan Bell
verify return:1
---
Certificate chain
0 s:C = CA, ST = Ontario, L = Toronto, O = jordanbell.info, CN = Jordan Bell
i:C = CA, ST = Ontario, L = Toronto, O = jordanbell.info, CN = Jordan Bell
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
v:NotBefore: Oct 6 01:31:34 2025 GMT; NotAfter: Nov 5 01:31:34 2025 GMT
---
Server certificate
cf. https://www.liquidweb.com/blog/how-to-test-ssl-connection-using-openssl/
ubuntu@LAPTOP-JBell:~$ ncat -C --ssl httpbin.org 443
GET / HTTP/1.1
Host: httpbin.org
Content-Type: text/html
HTTP/1.1 200 OK
Date: Mon, 06 Oct 2025 01:56:27 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 9593
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>httpbin.org</title>
...