<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 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