示例#1
0
 def _generate_signed_attrs(self, eta_invoice, signing_time):
     cert = x509.Certificate.load(base64.b64decode(self.certificate))
     data = hashlib.sha256(self._serialize_for_signing(eta_invoice).encode()).digest()
     return cms.CMSAttributes([
         cms.CMSAttribute({
             'type': cms.CMSAttributeType('content_type'),
             'values': ('digested_data',),
         }),
         cms.CMSAttribute({
             'type': cms.CMSAttributeType('message_digest'),
             'values': (data,),
         }),
         cms.CMSAttribute({
             'type': tsp.CMSAttributeType('signing_certificate_v2'),
             'values': ({
                            'certs': (tsp.ESSCertIDv2({
                                'hash_algorithm': algos.DigestAlgorithm({'algorithm': 'sha256'}),
                                'cert_hash': hashlib.sha256(cert.dump()).digest()
                            }),)
                        },),
         }),
         cms.CMSAttribute({
             'type': cms.CMSAttributeType('signing_time'),
             'values': (
             cms.Time({'utc_time': core.UTCTime(signing_time.replace(tzinfo=pytz.UTC))}),)
         }),
     ])
示例#2
0
def as_signing_certificate_v2(cert: x509.Certificate, hash_algo='sha256') \
        -> tsp.SigningCertificateV2:
    """
    Format an ASN.1 ``SigningCertificateV2`` value, where the certificate
    is identified by the hash algorithm specified.

    :param cert:
        An X.509 certificate.
    :param hash_algo:
        Hash algorithm to use to digest the certificate.
        Default is SHA-256.
    :return:
        A :class:`tsp.SigningCertificateV2` object referring to the original
        certificate.
    """

    # see RFC 5035
    hash_spec = get_pyca_cryptography_hash(hash_algo)
    md = hashes.Hash(hash_spec)
    md.update(cert.dump())
    digest_value = md.finalize()
    return tsp.SigningCertificateV2({
        'certs': [
            tsp.ESSCertIDv2({
                'hash_algorithm': {
                    'algorithm': hash_algo
                },
                'cert_hash': digest_value,
                'issuer_serial': {
                    'issuer':
                    [x509.GeneralName({'directory_name': cert.issuer})],
                    'serial_number': cert['tbs_certificate']['serial_number']
                }
            })
        ]
    })
示例#3
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()
示例#4
0
    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()