Why is Python’s Removing Certificate Extensions Complicated
This guide will walk through removing certificate extensions in Python. Unfortunately, Python’s popular libraries, like PyOpenSSL and cryptography, don’t provide a direct way to delete these extensions from a certificate. This phenomenon is due to developers’ vision that this action is not the best practice. However, we can make a workaround using Python’s cryptography library.
Affiliate: Experience limitless no-code automation, streamline your workflows, and effortlessly transfer data between apps with Make.com.
The Idea
We create a new certificate to address Python’s removing certificate extensions. This new one will retain all the original attributes of the old certificate except for the undesired extensions.
The first step in executing Python remove certificate extensions is to load the original certificate. After this, we initialize a new certificate builder and copy all the fields from the original certificate.
Then we iterate through all the extensions of the original certificate. Each extension, except for the unwanted one, is added to the new certificate.
Removing certificate extensions in Python doesn’t end with creating a new certificate; we must also sign it. This signing process needs a private key, which belongs to the issuer. For our demonstration, we generate a new RSA private key. However, practical scenarios require the actual issuer’s private key.
Once signed, the certificate is serialized into the PEM format, completing Python’s removing certificate extensions procedure.
Here’s a vital point: the unwanted extension is identified by its Object Identifier (OID). For example, we provide the corresponding OID to remove the “subjectKeyIdentifier” extension. The standard is to use OIDs because not all the names of the extensions are standard, so the default usage of the extensions is by their OIDs.
Several OID public databases can show you the OID of the specific extension and vice versa. On the OID Repository website, you can search for OID, which will give you information about it. On the OID Reference website, you can use their domain and add an OID to get the information easier. Here is an example of TLS Web Client Authentication on the OID Reference site: oidref.com/1.3.6.1.5.5.7.3.2
Atomicshop Python Module to Remove Certificate Extensions
The Atomicshop Python module can do this out of the box. You can also check the Atomicshop GitHub page.
Install the atomicshop python library with Python’s PIP package manager:
pip install atomicshop
Usage of the library:
from atomicshop.wrappers import cryptographyw
skip_extensions: list = ['1.3.6.1.5.5.7.3.2', '2.5.29.31', '1.3.6.1.5.5.7.1.1']
# Copy extensions from the old certificate to the new certificate, without specified extensions.
certificate_cryptography_object_no_extensions, new_private_key = \
cryptographyw.copy_extensions_from_old_cert_to_new_cert(
certificate_cryptography_object,
skip_extensions=skip_extensions)
Functionality Breakdown
Here’s a detailed breakdown:
from atomicshop.wrappers import cryptographyw: This line imports the cryptographyw module from the atomicshop.wrappers package. The cryptographyw module contains wrapper functions related to the cryptography python module.
skip_extensions: list = [‘1.3.6.1.5.5.7.3.2’, ‘2.5.29.31’, ‘1.3.6.1.5.5.7.1.1’]: This line initializes a list of extension identifiers that the function will skip when creating the new certificate. The values in the list are in the format of an OID (Object Identifier) string, which the cryptography module uses for identifying objects such as extension types.
The next part is a function call that’s spread across multiple lines for readability:
certificate_cryptography_object_no_extensions, new_private_key = \
cryptographyw.copy_extensions_from_old_cert_to_new_cert(
certificate_cryptography_object,
skip_extensions=skip_extensions)
This function, copy_extensions_from_old_cert_to_new_cert(), is called with two arguments:
certificate_cryptography_object: a representation of the old certificate from which to copy extensions in a cryptography library format.
skip_extensions: the list of string extensions in OID format to skip.
The function returns two values: “certificate_cryptography_object_no_extensions” and “new_private_key.” The former represents the new certificate in a cryptography library format, now without the skipped extensions, and the latter is a new private key associated with the new certificate.
More Details About the Atomicshop Function to Python’s Removing Certificate Extensions
The function “copy_extensions_from_old_cert_to_new_cert()” has three input keyword arguments: certificate, skip_extensions, and _use_extension_names. We still didn’t discuss the “_use_extension_names” argument.
Since not all names of the extensions are standard, this private Boolean argument takes the ‘skip_extenions’ list of strings as names of extensions and not OID strings. This functionality uses another private property of the cryptography certificate object: extension.oid_name.
Since this feature is experimental and for reference only, you should refrain from using it in production.
Skipping Usages in Iterable Extensions
Not all extensions are iterable or standard. For example “extendedKeyUsage” extension has two iterable options called “usages,” and they’re “clientAuth,” and “serverAuth.” The function “copy_extensions_from_old_cert_to_new_cert()” currently can remove any of the usages of the “extendedKeyUsage” extension. There are plans to add more sub-properties of extensions through this function.
Check the Function Content
You can check the function on Cryptography Wrapper on AtomicShop GitHub Page.
Find there the function: copy_extensions_from_old_cert_to_new_cert.
There are enough comments to understand what each section is doing in case you want to make your implementation.