コード例 #1
0
def compress_message(data_to_compress):
    """Function compresses data and returns the generated ASN.1
    
    :param data_to_compress: A byte string of the data to be compressed
    
    :return: A CMS ASN.1 byte string of the compressed data.    
    """
    compressed_content = cms.ParsableOctetString(
        zlib.compress(data_to_compress))
    return cms.ContentInfo({
        'content_type':
        cms.ContentType('compressed_data'),
        'content':
        cms.CompressedData({
            'version':
            cms.CMSVersion('v0'),
            'compression_algorithm':
            cms.CompressionAlgorithm(
                {'algorithm': cms.CompressionAlgorithmId('zlib')}),
            'encap_content_info':
            cms.EncapsulatedContentInfo({
                'content_type': cms.ContentType('data'),
                'content': compressed_content
            })
        })
    }).dump()
コード例 #2
0
def compress_message(data_to_compress):
    """Function compresses data and returns the generated ASN.1

    :param data_to_compress: A byte string of the data to be compressed

    :return: A CMS ASN.1 byte string of the compressed data.
    """
    compressed_content = cms.ParsableOctetString(
        zlib.compress(data_to_compress))
    return cms.ContentInfo({
        "content_type":
        cms.ContentType("compressed_data"),
        "content":
        cms.CompressedData({
            "version":
            cms.CMSVersion("v0"),
            "compression_algorithm":
            cms.CompressionAlgorithm(
                {"algorithm": cms.CompressionAlgorithmId("zlib")}),
            "encap_content_info":
            cms.EncapsulatedContentInfo({
                "content_type": cms.ContentType("data"),
                "content": compressed_content,
            }),
        }),
    }).dump()
コード例 #3
0
def compress_message(data_to_compress):
    compressed_content = cms.ParsableOctetString(
        zlib.compress(data_to_compress))
    return cms.ContentInfo({
        'content_type':
        cms.ContentType('compressed_data'),
        'content':
        cms.CompressedData({
            'version':
            cms.CMSVersion(0),
            'compression_algorithm':
            cms.CompressionAlgorithm(
                {'algorithm': cms.CompressionAlgorithmId('zlib')}),
            'encap_content_info':
            cms.EncapsulatedContentInfo({
                'content_type': cms.ContentType('data'),
                'content': compressed_content
            })
        })
    })
コード例 #4
0
 def _generate_cades_bes_signature(self, eta_invoice, signing_time, signature):
     cert = x509.Certificate.load(base64.b64decode(self.certificate))
     signed_data = {
         'version': 'v3',
         'digest_algorithms': cms.DigestAlgorithms((
             algos.DigestAlgorithm({'algorithm': 'sha256'}),
         )),
         'encap_content_info': {
             'content_type': 'digested_data',
         },
         'certificates': [cert],
         'signer_infos': [
             self._generate_signer_info(eta_invoice, signing_time, signature),
         ],
     }
     return cms.ContentInfo({'content_type': cms.ContentType('signed_data'), 'content': cms.SignedData(signed_data),})
コード例 #5
0
def encrypt_message(data_to_encrypt, enc_alg, encryption_cert):
    """Function encrypts data and returns the generated ASN.1

    :param data_to_encrypt: A byte string of the data to be encrypted
    
    :param enc_alg: The algorithm to be used for encrypting the data
    
    :param encryption_cert: The certificate to be used for encrypting the data

    :return: A CMS ASN.1 byte string of the encrypted data.    
    """

    enc_alg_list = enc_alg.split('_')
    cipher, key_length, mode = enc_alg_list[0], enc_alg_list[1], enc_alg_list[
        2]
    enc_alg_asn1, encrypted_content = None, None

    # Generate the symmetric encryption key and encrypt the message
    key = util.rand_bytes(int(key_length) // 8)
    if cipher == 'tripledes':
        algorithm_id = '1.2.840.113549.3.7'
        iv, encrypted_content = symmetric.tripledes_cbc_pkcs5_encrypt(
            key, data_to_encrypt, None)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            'algorithm':
            algorithm_id,
            'parameters':
            cms.OctetString(iv)
        })

    elif cipher == 'rc2':
        algorithm_id = '1.2.840.113549.3.2'
        iv, encrypted_content = symmetric.rc2_cbc_pkcs5_encrypt(
            key, data_to_encrypt, None)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            'algorithm':
            algorithm_id,
            'parameters':
            algos.Rc2Params({'iv': cms.OctetString(iv)})
        })

    elif cipher == 'rc4':
        algorithm_id = '1.2.840.113549.3.4'
        encrypted_content = symmetric.rc4_encrypt(key, data_to_encrypt)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            'algorithm': algorithm_id,
        })

    elif cipher == 'aes':
        if key_length == '128':
            algorithm_id = '2.16.840.1.101.3.4.1.2'
        elif key_length == '192':
            algorithm_id = '2.16.840.1.101.3.4.1.22'
        else:
            algorithm_id = '2.16.840.1.101.3.4.1.42'

        iv, encrypted_content = symmetric.aes_cbc_pkcs7_encrypt(
            key, data_to_encrypt, None)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            'algorithm':
            algorithm_id,
            'parameters':
            cms.OctetString(iv)
        })

    # Encrypt the key and build the ASN.1 message
    encrypted_key = asymmetric.rsa_pkcs1v15_encrypt(encryption_cert, key)

    return cms.ContentInfo({
        'content_type':
        cms.ContentType('enveloped_data'),
        'content':
        cms.EnvelopedData({
            'version':
            cms.CMSVersion('v0'),
            'recipient_infos': [
                cms.KeyTransRecipientInfo({
                    'version':
                    cms.CMSVersion('v0'),
                    'rid':
                    cms.RecipientIdentifier({
                        'issuer_and_serial_number':
                        cms.IssuerAndSerialNumber({
                            'issuer':
                            encryption_cert.asn1['tbs_certificate']['issuer'],
                            'serial_number':
                            encryption_cert.asn1['tbs_certificate']
                            ['serial_number']
                        })
                    }),
                    'key_encryption_algorithm':
                    cms.KeyEncryptionAlgorithm(
                        {'algorithm': cms.KeyEncryptionAlgorithmId('rsa')}),
                    'encrypted_key':
                    cms.OctetString(encrypted_key)
                })
            ],
            'encrypted_content_info':
            cms.EncryptedContentInfo({
                'content_type': cms.ContentType('data'),
                'content_encryption_algorithm': enc_alg_asn1,
                'encrypted_content': encrypted_content
            })
        })
    }).dump()
コード例 #6
0
def sign_message(data_to_sign,
                 digest_alg,
                 sign_key,
                 use_signed_attributes=True):
    """Function signs the data and returns the generated ASN.1

    :param data_to_sign: A byte string of the data to be signed.

    :param digest_alg: 
        The digest algorithm to be used for generating the signature.

    :param sign_key: The key to be used for generating the signature.
    
    :param use_signed_attributes: Optional attribute to indicate weather the 
    CMS signature attributes should be included in the signature or not.

    :return: A CMS ASN.1 byte string of the signed data.    
    """
    if use_signed_attributes:
        digest_func = hashlib.new(digest_alg)
        digest_func.update(data_to_sign)
        message_digest = digest_func.digest()

        class SmimeCapability(core.Sequence):
            _fields = [('0', core.Any, {
                'optional': True
            }), ('1', core.Any, {
                'optional': True
            }), ('2', core.Any, {
                'optional': True
            }), ('3', core.Any, {
                'optional': True
            }), ('4', core.Any, {
                'optional': True
            })]

        class SmimeCapabilities(core.Sequence):
            _fields = [
                ('0', SmimeCapability),
                ('1', SmimeCapability, {
                    'optional': True
                }),
                ('2', SmimeCapability, {
                    'optional': True
                }),
                ('3', SmimeCapability, {
                    'optional': True
                }),
                ('4', SmimeCapability, {
                    'optional': True
                }),
                ('5', SmimeCapability, {
                    'optional': True
                }),
            ]

        smime_cap = OrderedDict([
            ('0',
             OrderedDict([('0', core.ObjectIdentifier('1.2.840.113549.3.7'))
                          ])),
            ('1',
             OrderedDict([('0', core.ObjectIdentifier('1.2.840.113549.3.2')),
                          ('1', core.Integer(128))])),
            ('2',
             OrderedDict([('0', core.ObjectIdentifier('1.2.840.113549.3.4')),
                          ('1', core.Integer(128))])),
        ])

        signed_attributes = cms.CMSAttributes([
            cms.CMSAttribute({
                'type':
                cms.CMSAttributeType('content_type'),
                'values':
                cms.SetOfContentType([cms.ContentType('data')])
            }),
            cms.CMSAttribute({
                'type':
                cms.CMSAttributeType('signing_time'),
                'values':
                cms.SetOfTime(
                    [cms.Time({'utc_time': core.UTCTime(datetime.now())})])
            }),
            cms.CMSAttribute({
                'type':
                cms.CMSAttributeType('message_digest'),
                'values':
                cms.SetOfOctetString([core.OctetString(message_digest)])
            }),
            cms.CMSAttribute({
                'type':
                cms.CMSAttributeType('1.2.840.113549.1.9.15'),
                'values':
                cms.SetOfAny([core.Any(SmimeCapabilities(smime_cap))])
            }),
        ])
        signature = asymmetric.rsa_pkcs1v15_sign(sign_key[0],
                                                 signed_attributes.dump(),
                                                 digest_alg)
    else:
        signed_attributes = None
        signature = asymmetric.rsa_pkcs1v15_sign(sign_key[0], data_to_sign,
                                                 digest_alg)

    return cms.ContentInfo({
        'content_type':
        cms.ContentType('signed_data'),
        'content':
        cms.SignedData({
            'version':
            cms.CMSVersion('v1'),
            'digest_algorithms':
            cms.DigestAlgorithms([
                algos.DigestAlgorithm(
                    {'algorithm': algos.DigestAlgorithmId(digest_alg)})
            ]),
            'encap_content_info':
            cms.ContentInfo({'content_type': cms.ContentType('data')}),
            'certificates':
            cms.CertificateSet(
                [cms.CertificateChoices({'certificate': sign_key[1].asn1})]),
            'signer_infos':
            cms.SignerInfos([
                cms.SignerInfo({
                    'version':
                    cms.CMSVersion('v1'),
                    'sid':
                    cms.SignerIdentifier({
                        'issuer_and_serial_number':
                        cms.IssuerAndSerialNumber({
                            'issuer':
                            sign_key[1].asn1['tbs_certificate']['issuer'],
                            'serial_number':
                            sign_key[1].asn1['tbs_certificate']
                            ['serial_number']
                        })
                    }),
                    'digest_algorithm':
                    algos.DigestAlgorithm(
                        {'algorithm': algos.DigestAlgorithmId(digest_alg)}),
                    'signed_attrs':
                    signed_attributes,
                    'signature_algorithm':
                    algos.SignedDigestAlgorithm({
                        'algorithm':
                        algos.SignedDigestAlgorithmId('rsassa_pkcs1v15')
                    }),
                    'signature':
                    core.OctetString(signature)
                })
            ])
        })
    }).dump()
コード例 #7
0
ファイル: timestamps.py プロジェクト: ooguz/pyHanko
    def request_tsa_response(self, req: tsp.TimeStampReq) -> tsp.TimeStampResp:
        # We pretend that certReq is always true in the request

        # TODO generalise my detached signature logic to include cases like this
        #  (see § 5.4 in RFC 5652)
        # TODO does the RFC
        status = tsp.PKIStatusInfo({'status': tsp.PKIStatus('granted')})
        message_imprint: tsp.MessageImprint = req['message_imprint']
        md_algorithm = message_imprint['hash_algorithm']['algorithm'].native
        digest_algorithm_obj = algos.DigestAlgorithm({
            'algorithm': md_algorithm
        })
        dt = self.fixed_dt or datetime.now(tz=tzlocal.get_localzone())
        tst_info = {
            'version': 'v1',
            # See http://oidref.com/1.3.6.1.4.1.4146.2.2
            # I don't really care too much, this is a testing device anyway
            'policy': tsp.ObjectIdentifier('1.3.6.1.4.1.4146.2.2'),
            'message_imprint': message_imprint,
            # should be sufficiently random (again, this is a testing class)
            'serial_number': get_nonce(),
            'gen_time': dt,
            'tsa': x509.GeneralName(
                name='directory_name', value=self.tsa_cert.subject
            )
        }
        try:
            tst_info['nonce'] = req['nonce']
        except KeyError:
            pass

        tst_info = tsp.TSTInfo(tst_info)
        tst_info_data = tst_info.dump()
        message_digest = getattr(hashlib, md_algorithm)(tst_info_data).digest()
        signed_attrs = cms.CMSAttributes([
            simple_cms_attribute('content_type', 'tst_info'),
            simple_cms_attribute(
                'signing_time', cms.Time({'utc_time': core.UTCTime(dt)})
            ),
            simple_cms_attribute(
                'signing_certificate',
                general.as_signing_certificate(self.tsa_cert)
            ),
            simple_cms_attribute('message_digest', message_digest),
        ])
        signature = asymmetric.rsa_pkcs1v15_sign(
            asymmetric.load_private_key(self.tsa_key),
            signed_attrs.dump(), md_algorithm
        )
        sig_info = cms.SignerInfo({
            'version': 'v1',
            'sid': cms.SignerIdentifier({
                'issuer_and_serial_number': cms.IssuerAndSerialNumber({
                    'issuer': self.tsa_cert.issuer,
                    'serial_number': self.tsa_cert.serial_number,
                })
            }),
            'digest_algorithm': digest_algorithm_obj,
            'signature_algorithm': algos.SignedDigestAlgorithm(
                {'algorithm': 'rsassa_pkcs1v15'}
            ),
            'signed_attrs': signed_attrs,
            'signature': signature
        })
        certs = set(self.certs_to_embed)
        certs.add(self.tsa_cert)
        signed_data = {
            # must use v3 to get access to the EncapsulatedContentInfo construct
            'version': 'v3',
            'digest_algorithms': cms.DigestAlgorithms((digest_algorithm_obj,)),
            'encap_content_info': cms.EncapsulatedContentInfo({
                'content_type': cms.ContentType('tst_info'),
                'content': cms.ParsableOctetString(tst_info_data)
            }),
            'certificates': certs,
            'signer_infos': [sig_info]
        }
        tst = cms.ContentInfo({
            'content_type': cms.ContentType('signed_data'),
            'content': cms.SignedData(signed_data)
        })
        return tsp.TimeStampResp({'status': status, 'time_stamp_token': tst})
コード例 #8
0
def encrypt_message(data_to_encrypt, enc_alg, encryption_cert):
    """Function encrypts data and returns the generated ASN.1

    :param data_to_encrypt: A byte string of the data to be encrypted
    :param enc_alg: The algorithm to be used for encrypting the data
    :param encryption_cert: The certificate to be used for encrypting the data

    :return: A CMS ASN.1 byte string of the encrypted data.
    """

    enc_alg_list = enc_alg.split("_")
    cipher, key_length, _ = enc_alg_list[0], enc_alg_list[1], enc_alg_list[2]

    # Generate the symmetric encryption key and encrypt the message
    key = util.rand_bytes(int(key_length) // 8)
    if cipher == "tripledes":
        algorithm_id = "1.2.840.113549.3.7"
        iv, encrypted_content = symmetric.tripledes_cbc_pkcs5_encrypt(
            key, data_to_encrypt, None)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            "algorithm":
            algorithm_id,
            "parameters":
            cms.OctetString(iv)
        })

    elif cipher == "rc2":
        algorithm_id = "1.2.840.113549.3.2"
        iv, encrypted_content = symmetric.rc2_cbc_pkcs5_encrypt(
            key, data_to_encrypt, None)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            "algorithm":
            algorithm_id,
            "parameters":
            algos.Rc2Params({"iv": cms.OctetString(iv)}),
        })

    elif cipher == "rc4":
        algorithm_id = "1.2.840.113549.3.4"
        encrypted_content = symmetric.rc4_encrypt(key, data_to_encrypt)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            "algorithm": algorithm_id,
        })

    elif cipher == "aes":
        if key_length == "128":
            algorithm_id = "2.16.840.1.101.3.4.1.2"
        elif key_length == "192":
            algorithm_id = "2.16.840.1.101.3.4.1.22"
        else:
            algorithm_id = "2.16.840.1.101.3.4.1.42"

        iv, encrypted_content = symmetric.aes_cbc_pkcs7_encrypt(
            key, data_to_encrypt, None)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            "algorithm":
            algorithm_id,
            "parameters":
            cms.OctetString(iv)
        })
    elif cipher == "des":
        algorithm_id = "1.3.14.3.2.7"
        iv, encrypted_content = symmetric.des_cbc_pkcs5_encrypt(
            key, data_to_encrypt, None)
        enc_alg_asn1 = algos.EncryptionAlgorithm({
            "algorithm":
            algorithm_id,
            "parameters":
            cms.OctetString(iv)
        })
    else:
        raise AS2Exception("Unsupported Encryption Algorithm")

    # Encrypt the key and build the ASN.1 message
    encrypted_key = asymmetric.rsa_pkcs1v15_encrypt(encryption_cert, key)

    return cms.ContentInfo({
        "content_type":
        cms.ContentType("enveloped_data"),
        "content":
        cms.EnvelopedData({
            "version":
            cms.CMSVersion("v0"),
            "recipient_infos": [
                cms.KeyTransRecipientInfo({
                    "version":
                    cms.CMSVersion("v0"),
                    "rid":
                    cms.RecipientIdentifier({
                        "issuer_and_serial_number":
                        cms.IssuerAndSerialNumber({
                            "issuer":
                            encryption_cert.asn1["tbs_certificate"]["issuer"],
                            "serial_number":
                            encryption_cert.asn1["tbs_certificate"]
                            ["serial_number"],
                        })
                    }),
                    "key_encryption_algorithm":
                    cms.KeyEncryptionAlgorithm(
                        {"algorithm": cms.KeyEncryptionAlgorithmId("rsa")}),
                    "encrypted_key":
                    cms.OctetString(encrypted_key),
                })
            ],
            "encrypted_content_info":
            cms.EncryptedContentInfo({
                "content_type": cms.ContentType("data"),
                "content_encryption_algorithm": enc_alg_asn1,
                "encrypted_content": encrypted_content,
            }),
        }),
    }).dump()
コード例 #9
0
    def request_tsa_response(self, req: tsp.TimeStampReq) \
            -> tsp.TimeStampResp:
        # We pretend that certReq is always true in the request

        # TODO generalise my detached signature logic to include cases like this
        #  (see § 5.4 in RFC 5652)
        # TODO does the RFC
        status = tsp.PKIStatusInfo({'status': tsp.PKIStatus('granted')})
        message_imprint: tsp.MessageImprint = req['message_imprint']
        md_algorithm = self.override_md
        if md_algorithm is None:
            md_algorithm = message_imprint['hash_algorithm'][
                'algorithm'].native
        digest_algorithm_obj = algos.DigestAlgorithm(
            {'algorithm': md_algorithm})
        dt = self.fixed_dt or datetime.now(tz=tzlocal.get_localzone())
        tst_info = {
            'version':
            'v1',
            # See http://oidref.com/1.3.6.1.4.1.4146.2.2
            # I don't really care too much, this is a testing device anyway
            'policy':
            tsp.ObjectIdentifier('1.3.6.1.4.1.4146.2.2'),
            'message_imprint':
            message_imprint,
            # should be sufficiently random (again, this is a testing class)
            'serial_number':
            get_nonce(),
            'gen_time':
            dt,
            'tsa':
            x509.GeneralName(name='directory_name',
                             value=self.tsa_cert.subject)
        }
        if req['nonce'].native is not None:
            tst_info['nonce'] = req['nonce']

        tst_info = tsp.TSTInfo(tst_info)
        tst_info_data = tst_info.dump()
        md_spec = get_pyca_cryptography_hash(md_algorithm)
        md = hashes.Hash(md_spec)
        md.update(tst_info_data)
        message_digest_value = md.finalize()
        signed_attrs = cms.CMSAttributes([
            simple_cms_attribute('content_type', 'tst_info'),
            simple_cms_attribute('signing_time',
                                 cms.Time({'utc_time': core.UTCTime(dt)})),
            simple_cms_attribute('signing_certificate',
                                 general.as_signing_certificate(
                                     self.tsa_cert)),
            simple_cms_attribute('message_digest', message_digest_value),
        ])
        priv_key = serialization.load_der_private_key(self.tsa_key.dump(),
                                                      password=None)
        if not isinstance(priv_key, RSAPrivateKey):
            raise NotImplementedError("Dummy timestamper is RSA-only.")
        signature = priv_key.sign(
            signed_attrs.dump(), PKCS1v15(),
            get_pyca_cryptography_hash(md_algorithm.upper()))
        sig_info = cms.SignerInfo({
            'version':
            'v1',
            'sid':
            cms.SignerIdentifier({
                'issuer_and_serial_number':
                cms.IssuerAndSerialNumber({
                    'issuer':
                    self.tsa_cert.issuer,
                    'serial_number':
                    self.tsa_cert.serial_number,
                })
            }),
            'digest_algorithm':
            digest_algorithm_obj,
            'signature_algorithm':
            algos.SignedDigestAlgorithm({'algorithm': 'rsassa_pkcs1v15'}),
            'signed_attrs':
            signed_attrs,
            'signature':
            signature
        })
        certs = set(self.certs_to_embed)
        certs.add(self.tsa_cert)
        signed_data = {
            # must use v3 to get access to the EncapsulatedContentInfo construct
            'version':
            'v3',
            'digest_algorithms':
            cms.DigestAlgorithms((digest_algorithm_obj, )),
            'encap_content_info':
            cms.EncapsulatedContentInfo({
                'content_type':
                cms.ContentType('tst_info'),
                'content':
                cms.ParsableOctetString(tst_info_data)
            }),
            'certificates':
            certs,
            'signer_infos': [sig_info]
        }
        tst = cms.ContentInfo({
            'content_type': cms.ContentType('signed_data'),
            'content': cms.SignedData(signed_data)
        })
        return tsp.TimeStampResp({'status': status, 'time_stamp_token': tst})
コード例 #10
0
ファイル: signer.py プロジェクト: seneca-c/endesive
def timestamp(unhashed,
              hashalgo,
              url,
              credentials,
              req_options,
              prehashed=None):
    if prehashed:
        hashed_value = prehashed
    else:
        hashed_value = getattr(hashlib, hashalgo)(unhashed).digest()
    tspreq = tsp.TimeStampReq({
        "version":
        1,
        "message_imprint":
        tsp.MessageImprint({
            "hash_algorithm":
            algos.DigestAlgorithm({'algorithm': hashalgo}),
            "hashed_message":
            hashed_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 credentials is not None:
        username = credentials.get("username", None)
        password = credentials.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}"
    if req_options is None:
        req_options = {}

    tspresp = requests.post(url,
                            data=tspreq,
                            headers=tspheaders,
                            **req_options)
    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"],
                        })
                    ])
                })
            ]
            return attrs
        else:
            raise ValueError("TimeStampResponse status is not granted")
    else:
        raise ValueError("TimeStampResponse has invalid content type")
コード例 #11
0
ファイル: selfsigned.py プロジェクト: powerdefy/WeasySign
    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()
コード例 #12
0
ファイル: signer.py プロジェクト: shiayx/endesive
def sign(datau, key, cert, othercerts, hashalgo, attrs=True, signed_value=None, hsm=None):
    if signed_value is None:
        signed_value = getattr(hashlib, hashalgo)(datau).digest()
    signed_time = datetime.now(tz=pytz.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]))

    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_algorithm': algos.SignedDigestAlgorithm({'algorithm': 'rsassa_pkcs1v15'}),
        'signature': signed_value,
    }
    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:
        signed_value_signature = key.sign(
            tosign,
            padding.PKCS1v15(),
            getattr(hashes, hashalgo.upper())()
        )
    # signed_value_signature = core.OctetString(signed_value_signature)
    datas['content']['signer_infos'][0]['signature'] = signed_value_signature

    return datas.dump()
コード例 #13
0
    def request_tsa_response(self, req: tsp.TimeStampReq) -> tsp.TimeStampResp:
        # We pretend that certReq is always true in the request

        status = tsp.PKIStatusInfo({'status': tsp.PKIStatus('granted')})
        message_imprint: tsp.MessageImprint = req['message_imprint']
        md_algorithm = self.md_algorithm
        digest_algorithm_obj = algos.DigestAlgorithm({
            'algorithm': md_algorithm
        })
        dt = self.fixed_dt or datetime.now(tz=tzlocal.get_localzone())
        tst_info = {
            'version': 'v1',
            'policy': self.policy,
            'message_imprint': message_imprint,
            'serial_number': get_nonce(),
            'gen_time': dt,
            'tsa': x509.GeneralName(
                name='directory_name', value=self.tsa_cert.subject
            )
        }
        try:
            tst_info['nonce'] = req['nonce']
        except KeyError:
            pass

        tst_info = tsp.TSTInfo(tst_info)
        tst_info_data = tst_info.dump()
        message_digest = getattr(hashlib, md_algorithm)(tst_info_data).digest()
        signing_cert_id = tsp.ESSCertID({
            'cert_hash': hashlib.sha1(self.tsa_cert.dump()).digest()
        })
        signed_attrs = cms.CMSAttributes([
            simple_cms_attribute('content_type', 'tst_info'),
            simple_cms_attribute(
                'signing_time', cms.Time({'utc_time': core.UTCTime(dt)})
            ),
            simple_cms_attribute(
                'signing_certificate',
                tsp.SigningCertificate({'certs': [signing_cert_id]})
            ),
            simple_cms_attribute('message_digest', message_digest),
        ])
        signature = generic_sign(
            self.tsa_key, signed_attrs.dump(), self.signature_algo
        )
        sig_info = cms.SignerInfo({
            'version': 'v1',
            'sid': cms.SignerIdentifier({
                'issuer_and_serial_number': cms.IssuerAndSerialNumber({
                    'issuer': self.tsa_cert.issuer,
                    'serial_number': self.tsa_cert.serial_number,
                })
            }),
            'digest_algorithm': digest_algorithm_obj,
            'signature_algorithm': self.signature_algo,
            'signed_attrs': signed_attrs,
            'signature': signature
        })
        certs = set(self.certs_to_embed)
        certs.add(self.tsa_cert)
        signed_data = {
            # must use v3 to get access to the EncapsulatedContentInfo construct
            'version': 'v3',
            'digest_algorithms': cms.DigestAlgorithms((digest_algorithm_obj,)),
            'encap_content_info': cms.EncapsulatedContentInfo({
                'content_type': cms.ContentType('tst_info'),
                'content': cms.ParsableOctetString(tst_info_data)
            }),
            'certificates': certs,
            'signer_infos': [sig_info]
        }
        tst = cms.ContentInfo({
            'content_type': cms.ContentType('signed_data'),
            'content': cms.SignedData(signed_data)
        })
        return tsp.TimeStampResp({'status': status, 'time_stamp_token': tst})
コード例 #14
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()
コード例 #15
0
ファイル: globalsign.py プロジェクト: powerdefy/WeasySign
    def _sign(self,
              datau,
              key,
              signing_cert,
              trustchain,
              hashalgo,
              attrs=True,
              signed_value=None,
              hsm=None,
              pss=False,
              timestampurl=None,
              identity=None,
              s=None):
        if signed_value is None:
            signed_value = getattr(hashlib, hashalgo)(datau).digest()
        signed_time = datetime.datetime.now(tz=util.timezone.utc)

        esscert = signing_cert.public_bytes(serialization.Encoding.DER)
        esscert = getattr(hashlib, hashalgo)(esscert).digest()
        if hsm is not None:
            keyid, cert = hsm.certificate()
            cert = cert2asn(cert, False)
            trustchain = []
        else:
            signing_cert = cert2asn(signing_cert)

        certificates = []
        for c in trustchain:
            certificates.append(cert2asn(c))
        certificates.append(signing_cert)

        signer = {
            'version':
            'v1',
            'sid':
            cms.SignerIdentifier({
                'issuer_and_serial_number':
                cms.IssuerAndSerialNumber({
                    'issuer':
                    signing_cert.issuer,
                    'serial_number':
                    signing_cert.serial_number,
                }),
            }),
            'digest_algorithm':
            algos.DigestAlgorithm({'algorithm': hashalgo}),
            'signature':
            signed_value,
        }
        signer['signature_algorithm'] = algos.SignedDigestAlgorithm(
            {'algorithm': 'rsassa_pkcs1v15'})

        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_certificate_v2'),
                        'values': (tsp.SigningCertificateV2({
                            'certs': [
                                tsp.ESSCertIDv2({'cert_hash': esscert}),
                            ]
                        }), )
                    })
                    #cms.CMSAttribute({
                    #'type': cms.CMSAttributeType('signing_time'),
                    #'values': (cms.Time({'utc_time': core.UTCTime(signed_time)}),)
                    #}),
                ]
            else:
                signer['signed_attrs'] = attrs

        # TODO: Keep it all in one loop
        ocsp_revocation = []
        ocsp_revocation.append(
            cms.RevocationInfoChoice({
                'other':
                cms.OtherRevocationInfoFormat({
                    'other_rev_info_format':
                    cms.OtherRevInfoFormatId('ocsp_response'),
                    'other_rev_info':
                    self._ocsp_response
                })
            }))

        # TODO: Don't need this because I have a DSS now
        #for rev in self._revocation_info:
        #rev = base64.b64decode(rev)
        #rev = ocsp.OCSPResponse.load(rev)
        #ocsp_revocation.append(
        #cms.RevocationInfoChoice({
        #'other': cms.OtherRevocationInfoFormat({
        #'other_rev_info_format': cms.OtherRevInfoFormatId('ocsp_response'),
        #'other_rev_info': rev
        #})
        #})
        #)

        config = {
            'version':
            'v1',
            'digest_algorithms':
            cms.DigestAlgorithms(
                (algos.DigestAlgorithm({'algorithm': hashalgo}), )),
            'encap_content_info': {
                'content_type': 'data',
            },
            'certificates':
            certificates,
            'crls':
            ocsp_revocation,
            '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

        tosign = getattr(hashlib, hashalgo)(tosign).digest()
        # Fetch the actual signature
        r = s.get(
            self._signature_url.format(id=identity,
                                       digest=tosign.hex().upper()))
        if r.status_code != 200:
            raise APIError('Cannot retrieve the signature: {}\n{}'.format(
                r.status_code, r.json()))
        signed_value_signature = r.json()['signature']
        signed_value_signature = bytes.fromhex(signed_value_signature)
        signed_value = getattr(hashlib,
                               hashalgo)(signed_value_signature).digest()
        datas['content']['signer_infos'][0][
            'signature'] = signed_value_signature

        # Use globalsigns timestamp
        # TODO: uncomment next 17 lines  to have timestamped signature
        r = s.get(
            self._timestamp_url.format(digest=signed_value.hex().upper()))
        if r.status_code != 200:
            raise APIError('Cannot retrieve the timestamp: {}\n{}'.format(
                r.status_code, r.json()))
        timestamp_token = r.json()['token']
        timestamp_token = timestamp_token.encode('ascii')
        timestamp_token = base64.b64decode(timestamp_token)
        tsp_dict = cms.ContentInfo.load(timestamp_token)
        tsp_attrs = [
            cms.CMSAttribute({
                'type':
                cms.CMSAttributeType('signature_time_stamp_token'),
                'values':
                cms.SetOfContentInfo([
                    cms.ContentInfo({
                        'content_type':
                        cms.ContentType('signed_data'),
                        'content':
                        tsp_dict['content'],
                    })
                ])
            })
        ]
        datas['content']['signer_infos'][0]['unsigned_attrs'] = tsp_attrs

        # TODO: OCSP stuff - probably not necessary since we have a DSS

        #ocsp_seq = pdf.SequenceOfOCSPResponse((self._ocsp_response,))
        #ocsp_arc = pdf.RevocationInfoArchival({'ocsp': ocsp_seq})
        #revocation_info = pdf.SetOfRevocationInfoArchival()
        #revocation_info.append(ocsp_arc)
        #self._ocsp_response
        #ocsp_attribute = cms.CMSAttribute({  # basic_ocsp_response
        #'type': cms.CMSAttributeType('adobe_revocation_info_archival'),
        #'values': pdf.SetOfRevocationInfoArchival([
        #pdf.RevocationInfoArchival({
        #'ocsp': pdf.SequenceOfOCSPResponse(self._ocsp_response)
        #})#cert2asn(ocsp_resp.public_bytes(serialization.Encoding.DER), False)
        #])
        #}),
        #datas['content']['signer_infos'][0]['unsigned_attrs'].append(ocsp_attribute)

        return datas.dump()
コード例 #16
0
ファイル: signer.py プロジェクト: terminalkitten/endesive
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()
コード例 #17
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()
コード例 #18
0
def sign_message(
    data_to_sign,
    digest_alg,
    sign_key,
    sign_alg="rsassa_pkcs1v15",
    use_signed_attributes=True,
):
    """Function signs the data and returns the generated ASN.1

    :param data_to_sign: A byte string of the data to be signed.

    :param digest_alg: The digest algorithm to be used for generating the signature.

    :param sign_key: The key to be used for generating the signature.

    :param sign_alg: The algorithm to be used for signing the message.

    :param use_signed_attributes: Optional attribute to indicate weather the
    CMS signature attributes should be included in the signature or not.

    :return: A CMS ASN.1 byte string of the signed data.
    """
    if use_signed_attributes:
        digest_func = hashlib.new(digest_alg)
        digest_func.update(data_to_sign)
        message_digest = digest_func.digest()

        class SmimeCapability(core.Sequence):
            _fields = [
                ("0", core.Any, {
                    "optional": True
                }),
                ("1", core.Any, {
                    "optional": True
                }),
                ("2", core.Any, {
                    "optional": True
                }),
                ("3", core.Any, {
                    "optional": True
                }),
                ("4", core.Any, {
                    "optional": True
                }),
            ]

        class SmimeCapabilities(core.Sequence):
            _fields = [
                ("0", SmimeCapability),
                ("1", SmimeCapability, {
                    "optional": True
                }),
                ("2", SmimeCapability, {
                    "optional": True
                }),
                ("3", SmimeCapability, {
                    "optional": True
                }),
                ("4", SmimeCapability, {
                    "optional": True
                }),
                ("5", SmimeCapability, {
                    "optional": True
                }),
            ]

        smime_cap = OrderedDict([
            (
                "0",
                OrderedDict([
                    ("0", core.ObjectIdentifier("2.16.840.1.101.3.4.1.42"))
                ]),
            ),
            (
                "1",
                OrderedDict([
                    ("0", core.ObjectIdentifier("2.16.840.1.101.3.4.1.2"))
                ]),
            ),
            (
                "2",
                OrderedDict([("0", core.ObjectIdentifier("1.2.840.113549.3.7"))
                             ]),
            ),
            (
                "3",
                OrderedDict([
                    ("0", core.ObjectIdentifier("1.2.840.113549.3.2")),
                    ("1", core.Integer(128)),
                ]),
            ),
            (
                "4",
                OrderedDict([
                    ("0", core.ObjectIdentifier("1.2.840.113549.3.4")),
                    ("1", core.Integer(128)),
                ]),
            ),
        ])

        signed_attributes = cms.CMSAttributes([
            cms.CMSAttribute({
                "type":
                cms.CMSAttributeType("content_type"),
                "values":
                cms.SetOfContentType([cms.ContentType("data")]),
            }),
            cms.CMSAttribute({
                "type":
                cms.CMSAttributeType("signing_time"),
                "values":
                cms.SetOfTime([
                    cms.Time({
                        "utc_time":
                        core.UTCTime(
                            datetime.utcnow().replace(tzinfo=timezone.utc))
                    })
                ]),
            }),
            cms.CMSAttribute({
                "type":
                cms.CMSAttributeType("message_digest"),
                "values":
                cms.SetOfOctetString([core.OctetString(message_digest)]),
            }),
            cms.CMSAttribute({
                "type":
                cms.CMSAttributeType("1.2.840.113549.1.9.15"),
                "values":
                cms.SetOfAny([core.Any(SmimeCapabilities(smime_cap))]),
            }),
        ])
    else:
        signed_attributes = None

    # Generate the signature
    data_to_sign = signed_attributes.dump(
    ) if signed_attributes else data_to_sign
    if sign_alg == "rsassa_pkcs1v15":
        signature = asymmetric.rsa_pkcs1v15_sign(sign_key[0], data_to_sign,
                                                 digest_alg)
    elif sign_alg == "rsassa_pss":
        signature = asymmetric.rsa_pss_sign(sign_key[0], data_to_sign,
                                            digest_alg)
    else:
        raise AS2Exception("Unsupported Signature Algorithm")

    return cms.ContentInfo({
        "content_type":
        cms.ContentType("signed_data"),
        "content":
        cms.SignedData({
            "version":
            cms.CMSVersion("v1"),
            "digest_algorithms":
            cms.DigestAlgorithms([
                algos.DigestAlgorithm(
                    {"algorithm": algos.DigestAlgorithmId(digest_alg)})
            ]),
            "encap_content_info":
            cms.ContentInfo({"content_type": cms.ContentType("data")}),
            "certificates":
            cms.CertificateSet(
                [cms.CertificateChoices({"certificate": sign_key[1].asn1})]),
            "signer_infos":
            cms.SignerInfos([
                cms.SignerInfo({
                    "version":
                    cms.CMSVersion("v1"),
                    "sid":
                    cms.SignerIdentifier({
                        "issuer_and_serial_number":
                        cms.IssuerAndSerialNumber({
                            "issuer":
                            sign_key[1].asn1["tbs_certificate"]["issuer"],
                            "serial_number":
                            sign_key[1].asn1["tbs_certificate"]
                            ["serial_number"],
                        })
                    }),
                    "digest_algorithm":
                    algos.DigestAlgorithm(
                        {"algorithm": algos.DigestAlgorithmId(digest_alg)}),
                    "signed_attrs":
                    signed_attributes,
                    "signature_algorithm":
                    algos.SignedDigestAlgorithm(
                        {"algorithm":
                         algos.SignedDigestAlgorithmId(sign_alg)}),
                    "signature":
                    core.OctetString(signature),
                })
            ]),
        }),
    }).dump()
コード例 #19
0
def sign(datau,
         session,
         cert,
         cert_value,
         hashalgo,
         attrs=True,
         signed_value=None):
    if signed_value is None:
        signed_value = getattr(hashlib, hashalgo)(datau).digest()
    signed_time = datetime.now()

    x509 = Certificate.load(cert_value)
    certificates = []
    certificates.append(x509)

    cert_value_digest = bytes(
        session.digest(cert_value, Mechanism(LowLevel.CKM_SHA256)))
    MyLogger().my_logger().info('building signed attributes...')
    signer = {
        'version':
        'v1',
        'sid':
        cms.SignerIdentifier({
            'issuer_and_serial_number':
            cms.IssuerAndSerialNumber({
                'issuer': x509.issuer,
                'serial_number': x509.serial_number,
            }),
        }),
        'digest_algorithm':
        algos.DigestAlgorithm({'algorithm': hashalgo}),
        'signature_algorithm':
        algos.SignedDigestAlgorithm({'algorithm': 'rsassa_pkcs1v15'}),
        'signature':
        signed_value,
    }
    if attrs:
        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)}), )
            }),
            cms.CMSAttribute({
                'type':
                cms.CMSAttributeType('1.2.840.113549.1.9.16.2.47'),
                'values': (tsp.SigningCertificateV2({
                    'certs': (tsp.ESSCertIDv2({
                        'hash_algorithm':
                        algos.DigestAlgorithm({
                            'algorithm': hashalgo,
                            'parameters': None
                        }),
                        'cert_hash':
                        cert_value_digest,
                    }), ),
                }), )
            }),
        ]
    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

    MyLogger().my_logger().info('signed attributes ready')
    # fetching private key from smart card
    priv_key = SignatureUtils.fetch_private_key(session, cert)
    mechanism = Mechanism(LowLevel.CKM_SHA256_RSA_PKCS, None)
    MyLogger().my_logger().info('signing...')
    # signing bytes to be signed
    signature = session.sign(priv_key, tosign, mechanism)

    datas['content']['signer_infos'][0]['signature'] = bytes(signature)

    return datas.dump()
コード例 #20
0
ファイル: commands.py プロジェクト: vhamersky/spsdk
    def _cms_signature(self, zulu: datetime, data: bytes) -> bytes:
        """Sign provided data and return CMS signature.

        :param zulu: current UTC time+date
        :param data: to be signed
        :return: CMS signature (binary)
        """
        assert self.certificate is not None
        assert self.private_key_pem_data is not None

        # signed data (main section)
        signed_data = cms.SignedData()
        signed_data['version'] = 'v1'
        signed_data['encap_content_info'] = util.OrderedDict([
            ('content_type', 'data')
        ])
        signed_data['digest_algorithms'] = [util.OrderedDict([
            ('algorithm', 'sha256'),
            ('parameters', None)])]

        # signer info sub-section
        signer_info = cms.SignerInfo()
        signer_info['version'] = 'v1'
        signer_info['digest_algorithm'] = util.OrderedDict([
            ('algorithm', 'sha256'),
            ('parameters', None)])
        signer_info['signature_algorithm'] = util.OrderedDict([
            ('algorithm', 'rsassa_pkcs1v15'),
            ('parameters', b'')])
        # signed identifier: issuer amd serial number
        asn1cert = x509.Certificate.load(self.certificate.public_bytes(Encoding.DER))
        signer_info['sid'] = cms.SignerIdentifier({
            'issuer_and_serial_number': cms.IssuerAndSerialNumber({
                'issuer': asn1cert.issuer,
                'serial_number': asn1cert.serial_number
            })
        })
        # signed attributes
        signed_attrs = cms.CMSAttributes()
        signed_attrs.append(cms.CMSAttribute({
            'type': 'content_type',
            'values': [cms.ContentType('data')],
        }))
        # check time-zone is assigned (expected UTC+0)
        assert zulu.tzinfo
        signed_attrs.append(cms.CMSAttribute({
            'type': 'signing_time',
            'values': [cms.Time(name='utc_time', value=zulu.strftime('%y%m%d%H%M%SZ'))],
        }))
        signed_attrs.append(cms.CMSAttribute({
            'type': 'message_digest',
            'values': [cms.OctetString(crypto_backend().hash(data))],  # digest
        }))
        signer_info['signed_attrs'] = signed_attrs

        # create signature
        signer_info['signature'] = crypto_backend().rsa_sign(self.private_key_pem_data, signed_attrs.dump())

        # Adding SignerInfo object to SignedData object
        signed_data['signer_infos'] = [signer_info]

        # content info
        content_info = cms.ContentInfo()
        content_info['content_type'] = 'signed_data'
        content_info['content'] = signed_data

        return content_info.dump()