예제 #1
0
def optimal_pss_params(cert: x509.Certificate, digest_algorithm: str) \
        -> algos.RSASSAPSSParams:
    """
    Figure out the optimal RSASSA-PSS parameters for a given certificate.
    The subject's public key must be an RSA key.

    :param cert:
        An RSA X.509 certificate.
    :param digest_algorithm:
        The digest algorithm to use.
    :return:
        RSASSA-PSS parameters.
    """

    digest_algorithm = digest_algorithm.lower()

    key: RSAPublicKey = serialization.load_der_public_key(
        cert.public_key.dump())
    md = get_pyca_cryptography_hash(digest_algorithm)
    # the PSS salt calculation function is not in the .pyi file, apparently.
    # noinspection PyUnresolvedReferences
    optimal_salt_len = padding.calculate_max_pss_salt_length(key, md)
    return algos.RSASSAPSSParams({
        'hash_algorithm':
        algos.DigestAlgorithm({'algorithm': digest_algorithm}),
        'mask_gen_algorithm':
        algos.MaskGenAlgorithm({
            'algorithm':
            'mgf1',
            'parameters':
            algos.DigestAlgorithm({'algorithm': digest_algorithm}),
        }),
        'salt_length':
        optimal_salt_len
    })
예제 #2
0
def _get_rsa_pss_salt_length(pss, key, hash_algorithm):
    salt = pss._salt_length

    if salt is MGF1.MAX_LENGTH or salt is PSS.MAX_LENGTH:
        return calculate_max_pss_salt_length(key, hash_algorithm)
    else:
        return salt
예제 #3
0
    def optimal_pss_params(self, key: keys.PublicKeyInfo,
                           digest_algo: str) -> algos.RSASSAPSSParams:
        from cryptography.hazmat.primitives.asymmetric import rsa, padding
        from cryptography.hazmat.primitives import serialization, hashes
        digest_algo = digest_algo.lower()

        if key.algorithm == 'rsassa_pss':
            # again, pretend that we're working with a normal RSA key
            key = key.copy()
            key['algorithm'] = {'algorithm': 'rsa'}

        loaded_key: rsa.RSAPublicKey \
            = serialization.load_der_public_key(key.dump())
        md = getattr(hashes, digest_algo.upper())
        # the PSS salt calculation function is not in the .pyi file, apparently.
        # noinspection PyUnresolvedReferences
        optimal_salt_len = padding.calculate_max_pss_salt_length(
            loaded_key, md())
        return algos.RSASSAPSSParams({
            'hash_algorithm':
            algos.DigestAlgorithm({'algorithm': digest_algo}),
            'mask_gen_algorithm':
            algos.MaskGenAlgorithm({
                'algorithm':
                'mgf1',
                'parameters':
                algos.DigestAlgorithm({'algorithm': digest_algo}),
            }),
            'salt_length':
            optimal_salt_len
        })
예제 #4
0
파일: rsa.py 프로젝트: DamirAinullin/PTVS
def _get_rsa_pss_salt_length(pss, key, hash_algorithm):
    salt = pss._salt_length

    if salt is MGF1.MAX_LENGTH or salt is PSS.MAX_LENGTH:
        return calculate_max_pss_salt_length(key, hash_algorithm)
    else:
        return salt
예제 #5
0
def optimal_pss_params(cert: x509.Certificate, digest_algorithm: str):

    digest_algorithm = digest_algorithm.lower()

    try:
        from cryptography.hazmat.primitives import hashes, serialization
        from cryptography.hazmat.primitives.asymmetric import padding
        from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
    except ImportError:  # pragma: nocover
        raise SigningError("pyca/cryptography is required for generic PSS")

    key: RSAPublicKey = serialization.load_der_public_key(
        cert.public_key.dump())
    md = getattr(hashes, digest_algorithm.upper())
    # the PSS salt calculation function is not in the .pyi file, apparently.
    # noinspection PyUnresolvedReferences
    optimal_salt_len = padding.calculate_max_pss_salt_length(key, md())
    return algos.RSASSAPSSParams({
        'hash_algorithm':
        algos.DigestAlgorithm({'algorithm': digest_algorithm}),
        'mask_gen_algorithm':
        algos.MaskGenAlgorithm({
            'algorithm':
            'mgf1',
            'parameters':
            algos.DigestAlgorithm({'algorithm': digest_algorithm}),
        }),
        'salt_length':
        optimal_salt_len
    })
예제 #6
0
파일: rsa.py 프로젝트: Ma233/cryptography
def _get_rsa_pss_salt_length(
    pss: PSS,
    key: typing.Union[RSAPrivateKey, RSAPublicKey],
    hash_algorithm: hashes.HashAlgorithm,
) -> int:
    salt = pss._salt_length

    if salt is MGF1.MAX_LENGTH or salt is PSS.MAX_LENGTH:
        return calculate_max_pss_salt_length(key, hash_algorithm)
    else:
        return salt
예제 #7
0
파일: rsa.py 프로젝트: simo5/cryptography
def _get_rsa_pss_salt_length(
    pss: PSS,
    key: typing.Union[RSAPrivateKey, RSAPublicKey],
    hash_algorithm: hashes.HashAlgorithm,
) -> typing.Union[int, _MaxLength]:
    salt = pss._salt_length

    if isinstance(salt, _MaxLength):
        return calculate_max_pss_salt_length(key, hash_algorithm)
    else:
        return salt
예제 #8
0
def _get_rsa_pss_salt_length(
    backend: "Backend",
    pss: PSS,
    key: typing.Union[RSAPrivateKey, RSAPublicKey],
    hash_algorithm: hashes.HashAlgorithm,
) -> int:
    salt = pss._salt_length

    if isinstance(salt, _MaxLength):
        return calculate_max_pss_salt_length(key, hash_algorithm)
    elif isinstance(salt, _DigestLength):
        return hash_algorithm.digest_size
    elif isinstance(salt, _Auto):
        if isinstance(key, RSAPrivateKey):
            raise ValueError(
                "PSS salt length can only be set to AUTO when verifying")
        return backend._lib.RSA_PSS_SALTLEN_AUTO
    else:
        return salt
예제 #9
0
파일: general.py 프로젝트: gchehab/pyHanko
def optimal_pss_params(cert: x509.Certificate, digest_algorithm: str):

    digest_algorithm = digest_algorithm.lower()

    key: RSAPublicKey = serialization.load_der_public_key(
        cert.public_key.dump())
    md = get_pyca_cryptography_hash(digest_algorithm)
    # the PSS salt calculation function is not in the .pyi file, apparently.
    # noinspection PyUnresolvedReferences
    optimal_salt_len = padding.calculate_max_pss_salt_length(key, md)
    return algos.RSASSAPSSParams({
        'hash_algorithm':
        algos.DigestAlgorithm({'algorithm': digest_algorithm}),
        'mask_gen_algorithm':
        algos.MaskGenAlgorithm({
            'algorithm':
            'mgf1',
            'parameters':
            algos.DigestAlgorithm({'algorithm': digest_algorithm}),
        }),
        'salt_length':
        optimal_salt_len
    })
예제 #10
0
파일: signer.py 프로젝트: seneca-c/endesive
def sign(datau,
         key,
         cert,
         othercerts,
         hashalgo,
         attrs=True,
         signed_value=None,
         hsm=None,
         pss=False,
         timestampurl=None,
         timestampcredentials=None,
         timestamp_req_options=None):
    if signed_value is None:
        signed_value = getattr(hashlib, hashalgo)(datau).digest()
    signed_time = datetime.now(tz=util.timezone.utc)

    if hsm is not None:
        keyid, cert = hsm.certificate()
        cert = cert2asn(cert, False)
    else:
        cert = cert2asn(cert)

    certificates = []
    certificates.append(cert)
    for i in range(len(othercerts)):
        certificates.append(cert2asn(othercerts[i]))

    hashalgo = unicode(hashalgo) if sys.version[0] < '3' else hashalgo

    signer = {
        'version':
        'v1',
        'sid':
        cms.SignerIdentifier({
            'issuer_and_serial_number':
            cms.IssuerAndSerialNumber({
                'issuer': cert.issuer,
                'serial_number': cert.serial_number,
            }),
        }),
        'digest_algorithm':
        algos.DigestAlgorithm({'algorithm': hashalgo}),
        'signature':
        signed_value,
    }
    if not pss:
        signer['signature_algorithm'] = algos.SignedDigestAlgorithm(
            {'algorithm': 'rsassa_pkcs1v15'})
    else:
        if isinstance(key, keys.PrivateKeyInfo):
            salt_length = key.byte_size - hashes.SHA512.digest_size - 2
            salt_length = hashes.SHA512.digest_size
        else:
            salt_length = padding.calculate_max_pss_salt_length(
                key, hashes.SHA512)
        signer['signature_algorithm'] = algos.SignedDigestAlgorithm({
            'algorithm':
            'rsassa_pss',
            'parameters':
            algos.RSASSAPSSParams({
                'hash_algorithm':
                algos.DigestAlgorithm({'algorithm': 'sha512'}),
                'mask_gen_algorithm':
                algos.MaskGenAlgorithm({
                    'algorithm':
                    algos.MaskGenAlgorithmId('mgf1'),
                    'parameters': {
                        'algorithm': algos.DigestAlgorithmId('sha512'),
                    }
                }),
                'salt_length':
                algos.Integer(salt_length),
                'trailer_field':
                algos.TrailerField(1)
            })
        })

    if attrs:
        if attrs is True:
            signer['signed_attrs'] = [
                cms.CMSAttribute({
                    'type': cms.CMSAttributeType('content_type'),
                    'values': ('data', ),
                }),
                cms.CMSAttribute({
                    'type': cms.CMSAttributeType('message_digest'),
                    'values': (signed_value, ),
                }),
                cms.CMSAttribute({
                    'type':
                    cms.CMSAttributeType('signing_time'),
                    'values':
                    (cms.Time({'utc_time': core.UTCTime(signed_time)}), )
                }),
            ]
        else:
            signer['signed_attrs'] = attrs

    config = {
        'version':
        'v1',
        'digest_algorithms':
        cms.DigestAlgorithms((algos.DigestAlgorithm({'algorithm':
                                                     hashalgo}), )),
        'encap_content_info': {
            'content_type': 'data',
        },
        'certificates':
        certificates,
        # 'crls': [],
        'signer_infos': [
            signer,
        ],
    }
    datas = cms.ContentInfo({
        'content_type': cms.ContentType('signed_data'),
        'content': cms.SignedData(config),
    })
    if attrs:
        tosign = datas['content']['signer_infos'][0]['signed_attrs'].dump()
        tosign = b'\x31' + tosign[1:]
    else:
        tosign = datau
    if hsm is not None:
        signed_value_signature = hsm.sign(keyid, tosign, hashalgo)
    elif isinstance(key, keys.PrivateKeyInfo):
        key = asymmetric.load_private_key(key)
        if pss:
            signed_value_signature = asymmetric.rsa_pss_sign(
                key, tosign, 'sha512')
        else:
            signed_value_signature = asymmetric.rsa_pkcs1v15_sign(
                key, tosign, hashalgo.lower())
    else:
        if pss:
            hasher = hashes.Hash(hashes.SHA512(),
                                 backend=backends.default_backend())
            hasher.update(tosign)
            digest = hasher.finalize()
            signed_value_signature = key.sign(
                digest,
                padding.PSS(mgf=padding.MGF1(hashes.SHA512()),
                            salt_length=salt_length),
                utils.Prehashed(hashes.SHA512()))
        else:
            signed_value_signature = key.sign(
                tosign, padding.PKCS1v15(),
                getattr(hashes, hashalgo.upper())())

    if timestampurl is not None:
        datas['content']['signer_infos'][0]['unsigned_attrs'] = timestamp(
            signed_value_signature,
            hashalgo,
            timestampurl,
            timestampcredentials,
            timestamp_req_options,
        )

    # signed_value_signature = core.OctetString(signed_value_signature)
    datas['content']['signer_infos'][0]['signature'] = signed_value_signature

    #open('signed-content-info', 'wb').write(datas.dump())
    return datas.dump()
예제 #11
0
def sign(datau,
         key,
         cert,
         othercerts,
         hashalgo,
         attrs=True,
         signed_value=None,
         hsm=None,
         pss=False,
         timestampurl=None,
         timestampcredentials=None):
    if signed_value is None:
        signed_value = getattr(hashlib, hashalgo)(datau).digest()
    signed_time = datetime.now(tz=util.timezone.utc)

    if hsm is not None:
        keyid, cert = hsm.certificate()
        cert = cert2asn(cert, False)
    else:
        cert = cert2asn(cert)

    certificates = []
    certificates.append(cert)
    for i in range(len(othercerts)):
        certificates.append(cert2asn(othercerts[i]))

    hashalgo = unicode(hashalgo) if sys.version[0] < '3' else hashalgo

    signer = {
        'version':
        'v1',
        'sid':
        cms.SignerIdentifier({
            'issuer_and_serial_number':
            cms.IssuerAndSerialNumber({
                'issuer': cert.issuer,
                'serial_number': cert.serial_number,
            }),
        }),
        'digest_algorithm':
        algos.DigestAlgorithm({'algorithm': hashalgo}),
        'signature':
        signed_value,
    }
    if not pss:
        signer['signature_algorithm'] = algos.SignedDigestAlgorithm(
            {'algorithm': 'rsassa_pkcs1v15'})
    else:
        if isinstance(key, keys.PrivateKeyInfo):
            salt_length = key.byte_size - hashes.SHA512.digest_size - 2
            salt_length = hashes.SHA512.digest_size
        else:
            salt_length = padding.calculate_max_pss_salt_length(
                key, hashes.SHA512)
        signer['signature_algorithm'] = algos.SignedDigestAlgorithm({
            'algorithm':
            'rsassa_pss',
            'parameters':
            algos.RSASSAPSSParams({
                'hash_algorithm':
                algos.DigestAlgorithm({'algorithm': 'sha512'}),
                'mask_gen_algorithm':
                algos.MaskGenAlgorithm({
                    'algorithm':
                    algos.MaskGenAlgorithmId('mgf1'),
                    'parameters': {
                        'algorithm': algos.DigestAlgorithmId('sha512'),
                    }
                }),
                'salt_length':
                algos.Integer(salt_length),
                'trailer_field':
                algos.TrailerField(1)
            })
        })

    if attrs:
        if attrs is True:
            signer['signed_attrs'] = [
                cms.CMSAttribute({
                    'type': cms.CMSAttributeType('content_type'),
                    'values': ('data', ),
                }),
                cms.CMSAttribute({
                    'type': cms.CMSAttributeType('message_digest'),
                    'values': (signed_value, ),
                }),
                cms.CMSAttribute({
                    'type':
                    cms.CMSAttributeType('signing_time'),
                    'values':
                    (cms.Time({'utc_time': core.UTCTime(signed_time)}), )
                }),
            ]
        else:
            signer['signed_attrs'] = attrs

    config = {
        'version':
        'v1',
        'digest_algorithms':
        cms.DigestAlgorithms((algos.DigestAlgorithm({'algorithm':
                                                     hashalgo}), )),
        'encap_content_info': {
            'content_type': 'data',
        },
        'certificates':
        certificates,
        # 'crls': [],
        'signer_infos': [
            signer,
        ],
    }
    datas = cms.ContentInfo({
        'content_type': cms.ContentType('signed_data'),
        'content': cms.SignedData(config),
    })
    if attrs:
        tosign = datas['content']['signer_infos'][0]['signed_attrs'].dump()
        tosign = b'\x31' + tosign[1:]
    else:
        tosign = datau
    if hsm is not None:
        signed_value_signature = hsm.sign(keyid, tosign, hashalgo)
    elif isinstance(key, keys.PrivateKeyInfo):
        key = asymmetric.load_private_key(key)
        if pss:
            signed_value_signature = asymmetric.rsa_pss_sign(
                key, tosign, 'sha512')
        else:
            signed_value_signature = asymmetric.rsa_pkcs1v15_sign(
                key, tosign, hashalgo.lower())
    else:
        if pss:
            hasher = hashes.Hash(hashes.SHA512(),
                                 backend=backends.default_backend())
            hasher.update(tosign)
            digest = hasher.finalize()
            signed_value_signature = key.sign(
                digest,
                padding.PSS(mgf=padding.MGF1(hashes.SHA512()),
                            salt_length=salt_length),
                utils.Prehashed(hashes.SHA512()))
        else:
            signed_value_signature = key.sign(
                tosign, padding.PKCS1v15(),
                getattr(hashes, hashalgo.upper())())

    if timestampurl is not None:
        signed_value = getattr(hashlib,
                               hashalgo)(signed_value_signature).digest()
        tspreq = tsp.TimeStampReq({
            "version":
            1,
            "message_imprint":
            tsp.MessageImprint({
                "hash_algorithm":
                algos.DigestAlgorithm({'algorithm': hashalgo}),
                "hashed_message":
                signed_value,
            }),
            #'req_policy', ObjectIdentifier, {'optional': True}),
            "nonce":
            int(time.time() * 1000),
            "cert_req":
            True,
            #'extensions': tsp.Extensions()
        })
        tspreq = tspreq.dump()

        tspheaders = {"Content-Type": "application/timestamp-query"}
        if timestampcredentials is not None:
            username = timestampcredentials.get("username", None)
            password = timestampcredentials.get("password", None)
            if username and password:
                auth_header_value = b64encode(
                    bytes(username + ':' + password, "utf-8")).decode("ascii")
                tspheaders["Authorization"] = f"Basic {auth_header_value}"
        tspresp = requests.post(timestampurl, data=tspreq, headers=tspheaders)
        if tspresp.headers.get('Content-Type',
                               None) == 'application/timestamp-reply':
            tspresp = tsp.TimeStampResp.load(tspresp.content)

            if tspresp['status']['status'].native == 'granted':
                attrs = [
                    cms.CMSAttribute({
                        'type':
                        cms.CMSAttributeType('signature_time_stamp_token'),
                        'values':
                        cms.SetOfContentInfo([
                            cms.ContentInfo({
                                'content_type':
                                cms.ContentType('signed_data'),
                                'content':
                                tspresp["time_stamp_token"]["content"],
                            })
                        ])
                    })
                ]
                datas['content']['signer_infos'][0]['unsigned_attrs'] = attrs

            else:
                raise ValueError("TimeStampResponse status is not granted")

        else:
            raise ValueError("TimeStampResponse has invalid content type")

    # signed_value_signature = core.OctetString(signed_value_signature)
    datas['content']['signer_infos'][0]['signature'] = signed_value_signature

    #open('signed-content-info', 'wb').write(datas.dump())
    return datas.dump()
예제 #12
0
    def _sign(self,
              datau,
              key,
              cert,
              othercerts,
              hashalgo,
              attrs=True,
              signed_value=None,
              hsm=None,
              pss=False,
              timestampurl=None):
        if signed_value is None:
            signed_value = getattr(hashlib, hashalgo)(datau).digest()
        signed_time = datetime.now(tz=util.timezone.utc)

        if hsm is not None:
            keyid, cert = hsm.certificate()
            cert = cert2asn(cert, False)
            othercerts = []
        else:
            cert = cert2asn(cert)

        certificates = []
        certificates.append(cert)
        for i in range(len(othercerts)):
            certificates.append(cert2asn(othercerts[i]))

        signer = {
            'version':
            'v1',
            'sid':
            cms.SignerIdentifier({
                'issuer_and_serial_number':
                cms.IssuerAndSerialNumber({
                    'issuer': cert.issuer,
                    'serial_number': cert.serial_number,
                }),
            }),
            'digest_algorithm':
            algos.DigestAlgorithm({'algorithm': hashalgo}),
            'signature':
            signed_value,
        }
        if not pss:
            signer['signature_algorithm'] = algos.SignedDigestAlgorithm(
                {'algorithm': 'rsassa_pkcs1v15'})
        else:
            salt_length = padding.calculate_max_pss_salt_length(
                key, hashes.SHA512)
            signer['signature_algorithm'] = algos.SignedDigestAlgorithm({
                'algorithm':
                'rsassa_pss',
                'parameters':
                algos.RSASSAPSSParams({
                    'hash_algorithm':
                    algos.DigestAlgorithm({'algorithm': 'sha512'}),
                    'mask_gen_algorithm':
                    algos.MaskGenAlgorithm({
                        'algorithm':
                        algos.MaskGenAlgorithmId('mgf1'),
                        'parameters': {
                            'algorithm': algos.DigestAlgorithmId('sha512'),
                        }
                    }),
                    'salt_length':
                    algos.Integer(salt_length),
                    'trailer_field':
                    algos.TrailerField(1)
                })
            })

        if attrs:
            if attrs is True:
                signer['signed_attrs'] = [
                    cms.CMSAttribute({
                        'type':
                        cms.CMSAttributeType('content_type'),
                        'values': ('data', ),
                    }),
                    cms.CMSAttribute({
                        'type':
                        cms.CMSAttributeType('message_digest'),
                        'values': (signed_value, ),
                    }),
                    cms.CMSAttribute({
                        'type':
                        cms.CMSAttributeType('signing_time'),
                        'values':
                        (cms.Time({'utc_time': core.UTCTime(signed_time)}), )
                    }),
                ]
            else:
                signer['signed_attrs'] = attrs

        config = {
            'version':
            'v1',
            'digest_algorithms':
            cms.DigestAlgorithms(
                (algos.DigestAlgorithm({'algorithm': hashalgo}), )),
            'encap_content_info': {
                'content_type': 'data',
            },
            'certificates':
            certificates,
            # 'crls': [],
            'signer_infos': [
                signer,
            ],
        }
        datas = cms.ContentInfo({
            'content_type': cms.ContentType('signed_data'),
            'content': cms.SignedData(config),
        })
        if attrs:
            tosign = datas['content']['signer_infos'][0]['signed_attrs'].dump()
            tosign = b'\x31' + tosign[1:]
        else:
            tosign = datau
        if hsm is not None:
            signed_value_signature = hsm.sign(keyid, tosign, hashalgo)
        else:
            if pss:
                hasher = hashes.Hash(hashes.SHA512(),
                                     backend=backends.default_backend())
                hasher.update(tosign)
                digest = hasher.finalize()
                signed_value_signature = key.sign(
                    digest,
                    padding.PSS(mgf=padding.MGF1(hashes.SHA512()),
                                salt_length=salt_length),
                    utils.Prehashed(hashes.SHA512()))
            else:
                signed_value_signature = key.sign(
                    tosign, padding.PKCS1v15(),
                    getattr(hashes, hashalgo.upper())())

        if timestampurl is not None:
            signed_value = getattr(hashlib,
                                   hashalgo)(signed_value_signature).digest()
            tspreq = tsp.TimeStampReq({
                "version":
                1,
                "message_imprint":
                tsp.MessageImprint({
                    "hash_algorithm":
                    algos.DigestAlgorithm({'algorithm': hashalgo}),
                    "hashed_message":
                    signed_value,
                }),
                "nonce":
                int(time.time() * 1000),
                "cert_req":
                True,
            })
            tspreq = tspreq.dump()

            tspheaders = {"Content-Type": "application/timestamp-query"}
            tspresp = requests.post(timestampurl,
                                    data=tspreq,
                                    headers=tspheaders)
            if tspresp.headers.get('Content-Type',
                                   None) == 'application/timestamp-reply':
                tspresp = tsp.TimeStampResp.load(tspresp.content)

                if tspresp['status']['status'].native == 'granted':
                    attrs = [
                        cms.CMSAttribute({
                            'type':
                            cms.CMSAttributeType('signature_time_stamp_token'),
                            'values':
                            cms.SetOfContentInfo([
                                cms.ContentInfo({
                                    'content_type':
                                    cms.ContentType('signed_data'),
                                    'content':
                                    tspresp["time_stamp_token"]["content"],
                                })
                            ])
                        })
                    ]
                    datas['content']['signer_infos'][0][
                        'unsigned_attrs'] = attrs

        # signed_value_signature = core.OctetString(signed_value_signature)
        datas['content']['signer_infos'][0][
            'signature'] = signed_value_signature

        return datas.dump()
예제 #13
0
def sign(datau,
         key,
         cert,
         othercerts,
         hashalgo,
         attrs=True,
         signed_value=None,
         hsm=None,
         pss=False,
         timestampurl=None,
         timestampcredentials=None,
         timestamp_req_options=None,
         ocspurl=None,
         ocspissuer=None):
    if signed_value is None:
        signed_value = getattr(hashlib, hashalgo)(datau).digest()
    signed_time = datetime.now(tz=util.timezone.utc)

    if hsm is not None:
        keyid, cert = hsm.certificate()
        cert = cert2asn(cert, False)
    else:
        cert = cert2asn(cert)

    certificates = []
    certificates.append(cert)
    for i in range(len(othercerts)):
        certificates.append(cert2asn(othercerts[i]))

    hashalgo = unicode(hashalgo) if sys.version[0] < '3' else hashalgo

    signer = {
        'version':
        'v1',
        'sid':
        cms.SignerIdentifier({
            'issuer_and_serial_number':
            cms.IssuerAndSerialNumber({
                'issuer': cert.issuer,
                'serial_number': cert.serial_number,
            }),
        }),
        'digest_algorithm':
        algos.DigestAlgorithm({'algorithm': hashalgo}),
        'signature':
        signed_value,
    }
    if not pss:
        signer['signature_algorithm'] = algos.SignedDigestAlgorithm(
            {'algorithm': 'rsassa_pkcs1v15'})
    else:
        if isinstance(key, keys.PrivateKeyInfo):
            salt_length = key.byte_size - hashes.SHA512.digest_size - 2
            salt_length = hashes.SHA512.digest_size
        else:
            salt_length = padding.calculate_max_pss_salt_length(
                key, hashes.SHA512)
        signer['signature_algorithm'] = algos.SignedDigestAlgorithm({
            'algorithm':
            'rsassa_pss',
            'parameters':
            algos.RSASSAPSSParams({
                'hash_algorithm':
                algos.DigestAlgorithm({'algorithm': 'sha512'}),
                'mask_gen_algorithm':
                algos.MaskGenAlgorithm({
                    'algorithm':
                    algos.MaskGenAlgorithmId('mgf1'),
                    'parameters': {
                        'algorithm': algos.DigestAlgorithmId('sha512'),
                    }
                }),
                'salt_length':
                algos.Integer(salt_length),
                'trailer_field':
                algos.TrailerField(1)
            })
        })

    if attrs:
        if attrs is True:
            signer['signed_attrs'] = [
                cms.CMSAttribute({
                    'type': cms.CMSAttributeType('content_type'),
                    'values': ('data', ),
                }),
                cms.CMSAttribute({
                    'type': cms.CMSAttributeType('message_digest'),
                    'values': (signed_value, ),
                }),
                cms.CMSAttribute({
                    'type':
                    cms.CMSAttributeType('signing_time'),
                    'values':
                    (cms.Time({'utc_time': core.UTCTime(signed_time)}), )
                }),
            ]
        else:
            if isinstance(attrs, types.FunctionType):
                attrs = attrs(signed_value)
            signer['signed_attrs'] = attrs

    config = {
        'version':
        'v1',
        'digest_algorithms':
        cms.DigestAlgorithms((algos.DigestAlgorithm({'algorithm':
                                                     hashalgo}), )),
        'encap_content_info': {
            'content_type': 'data',
        },
        'certificates':
        certificates,
        'signer_infos': [
            signer,
        ],
    }
    if ocspurl and ocspissuer:
        from cryptography.hazmat.backends.openssl.backend import backend
        from cryptography.x509 import ocsp as cocsp
        from cryptography import x509 as cx509

        ocspuser = cert.dump()
        ocspuser = cx509.load_der_x509_certificate(ocspuser, backend=backend)

        builder = cocsp.OCSPRequestBuilder()
        builder = builder.add_certificate(ocspuser, ocspissuer, hashes.SHA1())
        req = builder.build()
        data = req.public_bytes(serialization.Encoding.DER)

        response = requests.post(
            ocspurl,
            headers={'Content-Type': 'application/ocsp-request'},
            data=data,
        )
        data = ocsp.OCSPResponse.load(response.content)
        other = cms.RevocationInfoChoice({
            'other':
            cms.OtherRevocationInfoFormat({
                'other_rev_info_format': 'ocsp_response',
                'other_rev_info': data
            })
        })
        config['crls'] = cms.RevocationInfoChoices([other])

    datas = cms.ContentInfo({
        'content_type': cms.ContentType('signed_data'),
        'content': cms.SignedData(config),
    })
    if attrs:
        tosign = datas['content']['signer_infos'][0]['signed_attrs'].dump()
        tosign = b'\x31' + tosign[1:]
    else:
        tosign = datau
    if hsm is not None:
        signed_value_signature = hsm.sign(keyid, tosign, hashalgo)
    elif isinstance(key, keys.PrivateKeyInfo):
        key = asymmetric.load_private_key(key)
        if pss:
            signed_value_signature = asymmetric.rsa_pss_sign(
                key, tosign, 'sha512')
        else:
            signed_value_signature = asymmetric.rsa_pkcs1v15_sign(
                key, tosign, hashalgo.lower())
    else:
        if pss:
            hasher = hashes.Hash(hashes.SHA512(),
                                 backend=backends.default_backend())
            hasher.update(tosign)
            digest = hasher.finalize()
            signed_value_signature = key.sign(
                digest,
                padding.PSS(mgf=padding.MGF1(hashes.SHA512()),
                            salt_length=salt_length),
                utils.Prehashed(hashes.SHA512()))
        else:
            signed_value_signature = key.sign(
                tosign, padding.PKCS1v15(),
                getattr(hashes, hashalgo.upper())())

    if timestampurl is not None:
        datas['content']['signer_infos'][0]['unsigned_attrs'] = timestamp(
            signed_value_signature,
            hashalgo,
            timestampurl,
            timestampcredentials,
            timestamp_req_options,
        )

    # signed_value_signature = core.OctetString(signed_value_signature)
    datas['content']['signer_infos'][0]['signature'] = signed_value_signature

    #open('signed-content-info', 'wb').write(datas.dump())
    return datas.dump()