def create_proxy_cert(loaded_cert, loaded_private_key,
loaded_public_key, lifetime_hours):
"""
Given cryptography objects for an issuing certificate, a public_key,
a private_key, and an int for lifetime in hours, creates a proxy
cert from the issuer and public key signed by the private key.
"""
builder = x509.CertificateBuilder()
# create a serial number for the new proxy
# Under RFC 3820 there are many ways to generate the serial number. However
# making the number unpredictable has security benefits, e.g. it can make
# this style of attack more difficult:
# http://www.win.tue.nl/hashclash/rogue-ca
serial = struct.unpack("<Q", os.urandom(8))[0]
builder = builder.serial_number(serial)
# set the new proxy as valid from now until lifetime_hours have passed
builder = builder.not_valid_before(datetime.datetime.utcnow())
builder = builder.not_valid_after(
datetime.datetime.utcnow() + datetime.timedelta(hours=lifetime_hours))
# set the public key of the new proxy to the given public key
builder = builder.public_key(loaded_public_key)
# set the issuer of the new cert to the subject of the issuing cert
builder = builder.issuer_name(loaded_cert.subject)
# set the new proxy's subject
# append a CommonName to the new proxy's subject
# with the serial as the value of the CN
new_atribute = x509.NameAttribute(
x509.oid.NameOID.COMMON_NAME, six.u(str(serial)))
subject_attributes = list(loaded_cert.subject)
subject_attributes.append(new_atribute)
builder = builder.subject_name(x509.Name(subject_attributes))
# add proxyCertInfo extension to the new proxy (We opt not to add keyUsage)
# For RFC proxies the effective usage is defined as the intersection
# of the usage of each cert in the chain. See section 4.2 of RFC 3820.
# the constants 'oid' and 'value' are gotten from
# examining output from a call to the open ssl function:
# X509V3_EXT_conf(NULL, ctx, name, value)
# ctx set by X509V3_set_nconf(&ctx, NCONF_new(NULL))
# name = "proxyCertInfo"
# value = "critical,language:Inherit all"
oid = x509.ObjectIdentifier("1.3.6.1.5.5.7.1.14")
value = b"0\x0c0\n\x06\x08+\x06\x01\x05\x05\x07\x15\x01"
extension = x509.extensions.UnrecognizedExtension(oid, value)
builder = builder.add_extension(extension, critical=True)
# sign the new proxy with the issuer's private key
new_certificate = builder.sign(
private_key=loaded_private_key, algorithm=hashes.SHA256(),
backend=default_backend())
# return the new proxy as a cryptography object
return new_certificate
评论列表
文章目录