Skip to content

Instantly share code, notes, and snippets.

@tiran
Created January 8, 2019 23:16
Show Gist options
  • Select an option

  • Save tiran/e32e03ebeedc3d219b980089d2f8c2c1 to your computer and use it in GitHub Desktop.

Select an option

Save tiran/e32e03ebeedc3d219b980089d2f8c2c1 to your computer and use it in GitHub Desktop.
Generate X.509 cert with bad serial number encoding
#!/usr/bin/env python3
"""Generate X.509 cert with bad serial number encoding
Christian Heimes
"""
from asn1crypto.x509 import Certificate
from asn1crypto.core import Integer
from asn1crypto.pem import armor, unarmor
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
import trustme
rootca = trustme.CA()
eecert = rootca.issue_cert('localhost')
rootca.cert_pem.write_to_path('rootca.pem')
eecert.private_key_pem.write_to_path('server.key')
ee_pem = eecert.cert_chain_pems[0].bytes()
class BadInteger(Integer):
def set(self, value):
super(BadInteger, self).set(value)
self.contents = b'\x00\x00\x00' + self.contents
self._header = None
cert = Certificate.load(unarmor(ee_pem)[2])
assert cert['signature_algorithm']['algorithm'].native == 'sha256_rsa'
tbs_cert = cert['tbs_certificate']
tbs_cert['serial_number'] = BadInteger(0x42)
pkey = rootca._private_key
new_sig = pkey.sign(tbs_cert.dump(), padding.PKCS1v15(), hashes.SHA256())
cert['signature_value'].set(new_sig)
with open('server.pem', 'wb') as f:
f.write(eecert.private_key_pem.bytes())
f.write(armor('CERTIFICATE', cert.dump()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment