I am trying to determine if an SSL certificate is self signed or not. Currently I have the following code which compares the issuer CN and the subject CN and if they are the same, marks the result as self signed.
with open(cert_file, "r") as f:
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, f.read())
result = {
'subject': dict(x509.get_subject().get_components()),
'issuer': dict(x509.get_issuer().get_components()),
'serialNumber': x509.get_serial_number(),
'version': x509.get_version(),
'notBefore': datetime.strptime(x509.get_notBefore(), '%Y%m%d%H%M%SZ'),
'notAfter': datetime.strptime(x509.get_notAfter(), '%Y%m%d%H%M%SZ'),
}
extensions = (x509.get_extension(i) for i in range(x509.get_extension_count()))
extension_data = {e.get_short_name(): str(e) for e in extensions}
result.update(extension_data)
if result['issuer']['CN'] == result['subject']['CN']:
result.update({'self-signed': True})
else:
result.update({'self-signed': False})
This comparison is very simplistic, but works in a lot of cases. I'm not trying to verify SSL certs or reimplement OpenSSL. How can I make this better and be roughly 95% sure if a certificate is self signed or not?
My one requirement is that I would like to do this in Python and not call other processes or use shell commands.
A certificate is self-signed if the subject and issuer match. A certificate is signed by a Certificate Authority (CA) if they are different. To validate a CA-signed certificate, you also need a CA certificate. The Details tab (not shown here) sections can be expanded to show each field in a certificate.
By default the SSL certificate that would be configured on your server would be a self-signed one, essentially meaning that it has not been issued by a CA, but instead your own server has signed the certificate as being valid.
Open IIS manager (inetmgr) on your web server. Click on the server node (one of the root nodes) in the left panel, and double click "Server certificates". Click on "Create Self-Signed Certificate" on the right panel and type in anything you want for the friendly name.
SSL Certificate Verification – Python requests Last Updated : 05 Mar, 2020 Requests verifies SSL certificates for HTTPS requests, just like a web browser. SSL Certificates are small data files that digitally bind a cryptographic key to an organization’s details.
SSL certificate_verify_failed errors typically occur as a result of outdated Python default certificates or invalid root certificates. We will cover how to fix this issue in 4 ways in this article. Why certificate_verify_failed happen? The SSL connection will be established based on the following process.
SSL Certificates are small data files that digitally bind a cryptographic key to an organization’s details. Often, a website with a SSL certificate is termed as secure website. By default, SSL verification is enabled, and Requests will throw a SSLError if it’s unable to verify the certificate.
However, browsers do not consider self-signed certificates to be as trustworthy as SSL certificates issued by a certificate authority. Server certificates are known as SSL/TLS certificates.
The OpenSSL definition of self-signed is:
The subject and issuer names match and extension values imply it is self signed.
The code that determines whether a cert is self-signed is:
/* Return 1 is a certificate is self signed */
static int cert_self_signed(X509 *x)
{
X509_check_purpose(x, -1, 0);
if (x->ex_flags & EXFLAG_SS)
return 1;
else
return 0;
}
And the code that sets EXFLAG_SS
:
/* Does subject name match issuer ? */
if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
x->ex_flags |= EXFLAG_SI;
/* If SKID matches AKID also indicate self signed */
if (X509_check_akid(x, x->akid) == X509_V_OK &&
!ku_reject(x, KU_KEY_CERT_SIGN))
x->ex_flags |= EXFLAG_SS;
}
So basically three things to check:
KU_KEY_CERT_SIGN
bit setYou are already comparing the subject name and the issuer name. The next important thing to do would be to compare the SKID and the AKID. After a cursory glance at pyopenssl it doesn't look like it provides a way to check this, so if you want a pure Python solution you might have to extend the library. However even the code you have would probably cover you in 95% of cases you said you wanted it to cover.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With