Note
The APIs for RFC 6125 verification beyond DNS-IDs (i.e. hostnames) aren't public yet. They are in place and used by the documented high-level APIs though. Eventually they will become public. If you'd like to play with them and provide feedback have a look at the verify_service_identity
function in the _common module.
service_identity.pyopenssl
verify_hostname
In practice, this may look like the following:
from __future__ import absolute_import, division, print_function
import socket
from OpenSSL import SSL
from service_identity import VerificationError
from service_identity.pyopenssl import verify_hostname
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.set_verify(SSL.VERIFY_PEER, lambda conn, cert, errno, depth, ok: ok)
ctx.set_default_verify_paths()
hostname = u"twistedmatrix.com"
conn = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
conn.connect((hostname, 443))
try:
conn.do_handshake()
verify_hostname(conn, hostname)
# Do your super-secure stuff here.
except SSL.Error as e:
print("TLS Handshake failed: {0!r}.".format(e.args[0]))
except VerificationError:
print("Presented certificate is not valid for {0}.".format(hostname))
finally:
conn.shutdown()
conn.close()
service_identity.cryptography
verify_certificate_hostname
service_identity
VerificationError
CertificateError
SubjectAltNameWarning