Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python SSL certificate check hostname according to common name

I want to check if an hostname and a port according to a SSL certificate. I created this function :

@staticmethod
def common_name_check(hostname, port):
    try:
        ctx = ssl.create_default_context()
        s = ctx.wrap_socket(socket.socket(), server_hostname=hostname)
        s.connect((hostname, int(port)))
        cert = s.getpeercert()
        ssl.match_hostname(cert, hostname)
    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        print(exc_type, fname, exc_tb.tb_lineno)
        return False
    else:
        return True

My problem is : When a certificate is expired the verification failed. But the exception is ambiguous :

<class 'ssl.SSLError'>

I can't know if error is due to certificate expired or bad common name

How can I only check if hostname/port is valid for certificate ?

like image 561
Samuel Dauzon Avatar asked Jan 18 '26 13:01

Samuel Dauzon


1 Answers

Exactly. SSL Error is too generic. I struggled with this too. So you might want to checkout this link.

Verifying SSL certificates in python

Here is a code only answer.

from OpenSSL import SSL
from socket import socket

context = SSL.Context(SSL.TLSv1_METHOD) # Use TLS Method
context.set_options(SSL.OP_NO_SSLv2) # Don't accept SSLv2
context.set_verify(SSL.VERIFY_NONE, callback)
context.load_verify_locations(ca_file, ca_path)

host = "google.com"
port = 443    #ssl
sock = socket()
ssl_sock = SSL.Connection(context, sock)
ssl_sock.connect((host, port))
ssl_sock.do_handshake()

def callback(self, conn, certificate, err, depth, valid):
    # err here is the error code ([List of error codes and what they mean][2].
    if err == 62:
        print("HOSTNAME MISMATCH!!!")
like image 192
vishal Avatar answered Jan 20 '26 04:01

vishal