scapy.layers.tls.cert

High-level methods for PKI objects (X.509 certificates, CRLs, CSR, Keys, CMS). Supported keys include RSA, ECDSA and EdDSA.

The classes below are wrappers for the ASN.1 objects defined in x509.py.

Example 1: Certificate & Private key

For instance, here is what you could do in order to modify the subject public key info of a ‘cert’ and then resign it with whatever ‘key’:

>>> from scapy.layers.tls.cert import *
>>> cert = Cert("cert.der")
>>> k = PrivKeyRSA()  # generate a private key
>>> cert.setSubjectPublicKeyFromPrivateKey(k)
>>> cert.resignWith(k)
>>> cert.export("newcert.pem")
>>> k.export("mykey.pem")

One could also edit arguments like the serial number, as such:

>>> from scapy.layers.tls.cert import *
>>> c = Cert("mycert.pem")
>>> c.tbsCertificate.serialNumber = 0x4B1D
>>> k = PrivKey("mykey.pem")  # import an existing private key
>>> c.resignWith(k)
>>> c.export("newcert.pem")

To export the public key of a private key:

>>> k = PrivKey("mykey.pem")
>>> k.pubkey.export("mypubkey.pem")

Example 2: CertList and CertTree

Load a .pem file that contains multiple certificates:

>>> l = CertList("ca_chain.pem")
>>> l.show()
0000 [X.509 Cert Subject:/C=FR/OU=Scapy Test PKI/CN=Scapy Test CA...]
0001 [X.509 Cert Subject:/C=FR/OU=Scapy Test PKI/CN=Scapy Test Client...]

Use ‘CertTree’ to organize the certificates in a tree:

>>> tree = CertTree("ca_chain.pem")  # or tree = CertTree(l)
>>> tree.show()
/C=Ulaanbaatar/OU=Scapy Test PKI/CN=Scapy Test CA [Self Signed]
    /C=FR/OU=Scapy Test PKI/CN=Scapy Test Client [Not Self Signed]

Example 3: Certificate Signing Request (CSR)

Scapy’s CSR class supports both PKCS#10 and CMC formats.

Load and display a CSR:

>>> csr = CSR("cert.req")
>>> csr
[CSR Format: CMC, Subject:/O=TestOrg/CN=TestCN, Verified: True]
>>> csr.certReq.show()
###[ PKCS10_CertificationRequest ]###
   \certificationRequestInfo\
    |###[ PKCS10_CertificationRequestInfo ]###
    |  version   = 0x0 <ASN1_INTEGER[0]
    |  \subject   \
    |   |###[ X509_RDN ]###
    |   |  \rdn       \
    |   |   |###[ X509_AttributeTypeAndValue ]###
    |   |   |  type      = <ASN1_OID['organizationName']>
    |   |   |  value     = <ASN1_UTF8_STRING[b'TestOrg']>
    [...]

Get its public key and verify its signature:

>>> csr.pubkey
<scapy.layers.tls.cert.PubKeyRSA at 0x7f3481149310>
>>> csr.verifySelf()
True

No need for obnoxious openssl tweaking anymore. :)

class scapy.layers.tls.cert.CMS_Engine(store: CertList, crls: List[X509_CRL] = [])[source]

Bases: object

A utility class to perform CMS/PKCS7 operations, as specified by RFC3852.

Parameters:
  • store – a ROOT CA certificate list to trust.

  • crls – a list of CRLs to include. This is currently not checked.

sign(message: bytes | Packet, eContentType: ASN1_OID, cert: Cert, key: PrivKey, dhash: str | None = 'sha256')[source]

Sign a message using CMS.

Parameters:
  • message – the inner content to sign.

  • eContentType – the OID of the inner content.

  • cert – the certificate whose key to use use for signing.

  • key – the private key to use for signing.

  • dhash – the hash to use for message digest (ECDSA only).

We currently only support X.509 certificates !

verify(contentInfo: CMS_ContentInfo, eContentType: ASN1_OID | None = None, eContent: bytes | None = None, no_verify_cert: bool = False)[source]

Verify a CMS message against the list of trusted certificates, and return the unpacked message if the verification succeeds.

Parameters:
  • contentInfo – the ContentInfo whose signature to verify

  • eContentType – if provided, verifies that the content type is valid

  • eContent – in PKCS 7.1, provide the content to verify

  • no_verify_cert – do not check the remote certificate (unsafe)

class scapy.layers.tls.cert.CRL(cert_path)[source]

Bases: object

Wrapper for the X509_CRL from layers/x509.py. Use the ‘x509CRL’ attribute to access original object.

import_from_asn1pkt(crl)[source]
isIssuer(other)[source]
show()[source]
verify(anchors)[source]
class scapy.layers.tls.cert.CSR(cert_path)[source]

Bases: object

Wrapper for the CSR formats. This can handle both PKCS#10 and CMC formats.

class FORMAT(*values)[source]

Bases: Enum

The format used by the CSR.

CMC = 'CMC'
PKCS10 = 'PKCS#10'
property certReq
property der
export(filename, fmt=None)[source]

Export certificate in ‘fmt’ format (DER or PEM) to file ‘filename’

import_from_asn1pkt(csr)[source]
isIssuer(other)[source]
isSelfSigned()[source]
property pem
show()[source]
verify(msg, sig, t='pkcs', h='sha256', mgf=None, L=None)[source]
verifySelf() bool[source]

Verify the signatures of the CSR

class scapy.layers.tls.cert.Cert(cert_path=None, cryptography_obj=None)[source]

Bases: object

Wrapper for the X509_Cert from layers/x509.py. Use the ‘x509Cert’ attribute to access original object.

property der
encrypt(msg, t='pkcs', h='sha256', mgf=None, L=None)[source]
export(filename, fmt=None)[source]

Export certificate in ‘fmt’ format (DER or PEM) to file ‘filename’

property extensions
getCertSignatureHash()[source]

Return the hash cryptography object used by the ‘signatureAlgorithm’

import_from_asn1pkt(cert)[source]
isIssuer(other)[source]
True if ‘other’ issued ‘self’, i.e.:
  • self.issuer == other.subject

  • self is signed by other

isIssuerCert(other)[source]
isRevoked(crl_list)[source]

Given a list of trusted CRL (their signature has already been verified with trusted anchors), this function returns True if the certificate is marked as revoked by one of those CRL.

Note that if the Certificate was on hold in a previous CRL and is now valid again in a new CRL and bot are in the list, it will be considered revoked: this is because _all_ CRLs are checked (not only the freshest) and revocation status is not handled.

Also note that the check on the issuer is performed on the Authority Key Identifier if available in _both_ the CRL and the Cert. Otherwise, the issuers are simply compared.

isSelfSigned()[source]
Return True if the certificate is self-signed:
  • issuer and subject are the same

  • the signature of the certificate is valid.

property pem
property pubKey
remainingDays(now=None)[source]

Based on the value of notAfter field, returns the number of days the certificate will still be valid. The date used for the comparison is the current and local date, as returned by time.localtime(), except if ‘now’ argument is provided another one. ‘now’ argument can be given as either a time tuple or a string representing the date. Accepted format for the string version are:

  • ‘%b %d %H:%M:%S %Y %Z’ e.g. ‘Jan 30 07:38:59 2008 GMT’

  • ‘%m/%d/%y’ e.g. ‘01/30/08’ (less precise)

If the certificate is no more valid at the date considered, then a negative value is returned representing the number of days since it has expired.

The number of days is returned as a float to deal with the unlikely case of certificates that are still just valid.

resignWith(key)[source]

Resign a certificate with a specific key

setSubjectPublicKeyFromPrivateKey(key)[source]

Replace the subjectPublicKeyInfo of this certificate with the one from the provided key.

show()[source]
property tbsCertificate
verify(msg, sig, t='pkcs', h='sha256', mgf=None, L=None)[source]
class scapy.layers.tls.cert.CertList(certList: Self | List[Cert] | List[CSR] | Cert | str)[source]

Bases: list

An object that can store a list of Cert objects, load them and export them into DER/PEM format.

property der
export(filename, fmt=None)[source]

Export a list of certificates ‘fmt’ format (DER or PEM) to file ‘filename’

findCertBySid(sid)[source]

Find a certificate in the list by SubjectIDentifier.

property pem
show()[source]
class scapy.layers.tls.cert.CertTree(certList: List[Cert] | CertList | str, rootCAs: List[Cert] | CertList | Cert | str | None = None)[source]

Bases: CertList

An extension to CertList that additionally has a list of ROOT CAs that are trusted.

Example:

>>> tree = CertTree("ca_chain.pem")
>>> tree.show()
/CN=DOMAIN-DC1-CA/dc=DOMAIN [Self Signed]
    /CN=Administrator/dc=DOMAIN [Not Self Signed]
frmt
getchain(cert)[source]

Return a chain of certificate that points from a ROOT CA to a certificate.

rootCAs
show(ret: bool = False)[source]

Return the CertTree as a string certificate tree

property tree

Get a tree-like object of the certificate list

verify(cert)[source]

Verify that a certificate is properly signed.

class scapy.layers.tls.cert.PrivKey(key_path=None, cryptography_obj=None)[source]

Bases: object

Parent class for PrivKeyRSA, PrivKeyECDSA and PrivKeyEdDSA. Provides common signTBSCert(), resignCert(), verifyCert() and export() methods.

property der
export(filename, fmt=None)[source]

Export private key in ‘fmt’ format (DER or PEM) to file ‘filename’

property pem
resignCert(cert)[source]

Rewrite the signature of either a Cert or an X509_Cert.

sign(**kwargs: Any) Any[source]
signTBSCert(tbsCert, h='sha256')[source]

Note that this will always copy the signature field from the tbsCertificate into the signatureAlgorithm field of the result, regardless of the coherence between its contents (which might indicate ecdsa-with-SHA512) and the result (e.g. RSA signing MD2).

There is a small inheritance trick for the computation of sigVal below: in order to use a sign() method which would apply to both PrivKeyRSA and PrivKeyECDSA, the sign() methods of the subclasses accept any argument, be it from the RSA or ECDSA world, and then they keep the ones they’re interested in. Here, t will be passed eventually to pkcs1._DecryptAndSignRSA.sign().

verify(**kwargs: Any) Any[source]
verifyCert(cert)[source]

Verifies either a Cert or an X509_Cert.

verifyCsr(cert)[source]

Verifies either a CSR.

class scapy.layers.tls.cert.PrivKeyECDSA(key_path=None, cryptography_obj=None)[source]

Bases: PrivKey

Wrapper for ECDSA keys based on SigningKey from ecdsa library. Use the ‘key’ attribute to access original object.

fill_and_store(**kwargs: Any) Any[source]
import_from_asn1pkt(**kwargs: Any) Any[source]
sign(**kwargs: Any) Any[source]
verify(**kwargs: Any) Any[source]
class scapy.layers.tls.cert.PrivKeyEdDSA(key_path=None, cryptography_obj=None)[source]

Bases: PrivKey

Wrapper for EdDSA keys Use the ‘key’ attribute to access original object.

fill_and_store(**kwargs: Any) Any[source]
import_from_asn1pkt(**kwargs: Any) Any[source]
sign(**kwargs: Any) Any[source]
verify(**kwargs: Any) Any[source]
class scapy.layers.tls.cert.PrivKeyRSA(key_path=None, cryptography_obj=None)[source]

Bases: PrivKey, _DecryptAndSignRSA

Wrapper for RSA keys based on _DecryptAndSignRSA from crypto/pkcs1.py Use the ‘key’ attribute to access original object.

fill_and_store(**kwargs: Any) Any[source]
import_from_asn1pkt(privkey)[source]
sign(data, t='pkcs', h='sha256', mgf=None, L=None)[source]
verify(msg, sig, t='pkcs', h='sha256', mgf=None, L=None)[source]
class scapy.layers.tls.cert.PubKey(key_path=None, cryptography_obj=None)[source]

Bases: object

Parent class for PubKeyRSA, PubKeyECDSA and PubKeyEdDSA. Provides common verifyCert() and export() methods.

property der
export(filename, fmt=None)[source]

Export public key in ‘fmt’ format (DER or PEM) to file ‘filename’

property key_size
property pem
public_numbers(*args, **kwargs)[source]
verify(**kwargs: Any) Any[source]
verifyCert(cert)[source]

Verifies either a Cert or an X509_Cert.

verifyCsr(csr)[source]

Verifies a CSR.

class scapy.layers.tls.cert.PubKeyECDSA(key_path=None, cryptography_obj=None)[source]

Bases: PubKey

Wrapper for ECDSA keys based on the cryptography library. Use the ‘key’ attribute to access original object.

encrypt(msg, h='sha256', **kwargs)[source]
fill_and_store(**kwargs: Any) Any[source]
import_from_der(**kwargs: Any) Any[source]
verify(**kwargs: Any) Any[source]
class scapy.layers.tls.cert.PubKeyEdDSA(key_path=None, cryptography_obj=None)[source]

Bases: PubKey

Wrapper for EdDSA keys based on the cryptography library. Use the ‘key’ attribute to access original object.

encrypt(msg, **kwargs)[source]
fill_and_store(**kwargs: Any) Any[source]
import_from_der(**kwargs: Any) Any[source]
verify(**kwargs: Any) Any[source]
class scapy.layers.tls.cert.PubKeyRSA(key_path=None, cryptography_obj=None)[source]

Bases: PubKey, _EncryptAndVerifyRSA

Wrapper for RSA keys based on _EncryptAndVerifyRSA from crypto/pkcs1.py Use the ‘key’ attribute to access original object.

encrypt(msg, t='pkcs', h='sha256', mgf=None, L=None)[source]
fill_and_store(**kwargs: Any) Any[source]
import_from_asn1pkt(pubkey)[source]
import_from_tuple(**kwargs: Any) Any[source]
verify(msg, sig, t='pkcs', h='sha256', mgf=None, L=None)[source]
scapy.layers.tls.cert.der2pem(der_string, obj='UNKNOWN')[source]

Convert DER octet string to PEM format (with optional header)

scapy.layers.tls.cert.pem2der(pem_string)[source]

Convert PEM string to DER format

scapy.layers.tls.cert.split_pem(s)[source]

Split PEM objects. Useful to process concatenated certificates.