Ejemplo n.º 1
0
def sign(xml, certContent, rsaKeyContent, signIdValue=None):
    """Return xmldsig XML string from xml_string of XML.
    Args:
      xml: str of bytestring xml to sign
      certContent: str content of certificate file
      rsaKeyContent: RSA key private content
      signIdValue: str of signature id value
    Returns:
      str: signed bytestring xml
    """
    keyInfoXml = """<KeyInfo><X509Data/></KeyInfo>"""

    constSignatureXml = \
        """<Signature %(signatureId)sxmlns="http://www.w3.org/2000/09/xmldsig#">%(signedInfoXml)s<SignatureValue>%(signatureValue)s</SignatureValue>%(keyInfoXml)s</Signature>"""

    signedInfoXml = _signedInfo(xml)
    signatureValue = signedWithRSA(signedInfoXml, rsaKeyContent)

    if signIdValue is None:
        signatureId = ""
    else:
        signatureId = "Id='%s' " % signIdValue

    signatureXml = constSignatureXml % {
        "signedInfoXml": signedInfoXml,
        "signatureValue": b64e(signatureValue),
        "keyInfoXml": keyInfoXml,
        "signatureId": signatureId,
    }

    prefix = "</p1:"
    foo = xml.split(prefix)
    after = prefix + foo[1]
    signedXml = foo[0] + signatureXml + after

    ns = {"ns": "http://www.w3.org/2000/09/xmldsig#"}

    signedXml = etree.fromstring(signedXml)
    tagX509Data = signedXml.find(".//ns:X509Data", namespaces=ns)

    etree.SubElement(tagX509Data, "X509Certificate").text = certContent
    xmlEnvelope = etree.tostring(signedXml)

    return xmlEnvelope
Ejemplo n.º 2
0
    def signCancelWithRsa(cls, bufferXml, rsaKeyContent, certContent):
        ns = {}

        signInscricaoPrestador = bufferXml.find('.//InscricaoPrestador', namespaces=ns).text
        signNumeroNFe = bufferXml.find('.//NumeroNFe', namespaces=ns).text
        stringConcat = signInscricaoPrestador + signNumeroNFe.zfill(12)

        digest = SHA.new(stringConcat)

        rsaKey = RSA.importKey(rsaKeyContent)
        signer = PKCS1_v1_5.new(rsaKey)
        sign = signer.sign(digest)
        b64Signed = b64e(sign)

        cls.verifySignature(rsaKey, digest, sign)

        tagCancelSignatureX509Data = bufferXml.find('.//Detalhe', namespaces=ns)
        etree.SubElement(tagCancelSignatureX509Data, 'AssinaturaCancelamento').text = b64Signed
        return cls.signWithA1Cert(bufferXml, certContent=certContent, rsaKeyContent=rsaKeyContent)
Ejemplo n.º 3
0
def _signedInfo(xml):
    """Return <SignedInfo> for bytestring xml.
    Args:
      xml: str of bytestring
    Returns:
      str: xml bytestring of <SignedInfo> computed from "xml"
    """
    signedInfoXml = \
        """<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#"%(xmlnsAttr)s><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></CanonicalizationMethod><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform><Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></Transform></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod><DigestValue>%(digestValue)s</DigestValue></Reference></SignedInfo>"""

    xmlnsAttr = getXmlnsPrefixes(xml)
    if xmlnsAttr:
        xmlnsAttr = " %s" % xmlnsAttr

    signedInfoXml = signedInfoXml % {
        "digestValue": b64e(_digest(xml)),
        "xmlnsAttr": xmlnsAttr
    }

    return signedInfoXml
Ejemplo n.º 4
0
    def signRpsWithRsa(cls, bufferXml, rsaKeyContent, certContent):
        ns = {}

        signInscricaoPrestador = bufferXml.find('.//InscricaoPrestador', namespaces=ns).text
        signSerieRPS = bufferXml.find('.//SerieRPS', namespaces=ns).text
        signNumeroRPS = bufferXml.find('.//NumeroRPS', namespaces=ns).text
        signDataEmissao = bufferXml.find('.//DataEmissao', namespaces=ns).text
        signStatusRPS = bufferXml.find('.//StatusRPS', namespaces=ns).text
        signValorServicos = bufferXml.find('.//ValorServicos', namespaces=ns).text
        signValorDeducoes = bufferXml.find('.//ValorDeducoes', namespaces=ns).text
        signCodigoServico = bufferXml.find('.//CodigoServico', namespaces=ns).text
        signISSRetido = bufferXml.find('.//ISSRetido', namespaces=ns).text
        signCPFCNPJTomador = bufferXml.find('.//CPFCNPJTomador/CNPJ', namespaces=ns).text

        if signISSRetido == "false":
            signISSRetido = "N"
        else:
            signISSRetido = "S"
        stringConcat = '%s%s%s%sT%s%s%015d%015d%05d%s%s' % (
            str(signInscricaoPrestador).zfill(8),
            str(signSerieRPS.ljust(5)).upper(),
            str(signNumeroRPS).zfill(12),
            str(signDataEmissao.replace("-", "")),
            str(signStatusRPS),
            str(signISSRetido),
            int(float(signValorServicos) * 100),
            int(float(signValorDeducoes) * 100),
            int(signCodigoServico),
            str(2),
            str(signCPFCNPJTomador).zfill(14))

        digest = SHA.new(stringConcat)
        rsaKey = RSA.importKey(rsaKeyContent)
        signer = PKCS1_v1_5.new(rsaKey)
        sign = signer.sign(digest)
        b64Signed = b64e(sign)

        cls.verifySignature(rsaKey, digest, sign)

        bufferXml.find(".//Assinatura", namespaces=ns).text = b64Signed
        return cls.signWithA1Cert(bufferXml, certContent=certContent, rsaKeyContent=rsaKeyContent)
Ejemplo n.º 5
0
    def signLoteRps(cls, stringXml, certContent, rsaKeyContent):
        ns = {}

        bufferXml = etree.fromstring(stringXml)
        signInscricaoPrestador = bufferXml.find('.//InscricaoPrestador', namespaces=ns).text
        signSerieRPS = bufferXml.find('.//SerieRPS', namespaces=ns).text
        signNumeroRPS = bufferXml.find('.//NumeroRPS', namespaces=ns).text
        signDataEmissao = bufferXml.find('.//DataEmissao', namespaces=ns).text
        signStatusRPS = bufferXml.find('.//StatusRPS', namespaces=ns).text
        signTributacaoRPS = bufferXml.find('.//TributacaoRPS', namespaces=ns).text
        signValorServicos = bufferXml.find('.//ValorServicos', namespaces=ns).text
        signValorDeducoes = bufferXml.find('.//ValorDeducoes', namespaces=ns).text
        signCodigoServico = bufferXml.find('.//CodigoServico', namespaces=ns).text
        signISSRetido = bufferXml.find('.//ISSRetido', namespaces=ns).text
        signCPFCNPJTomador = bufferXml.find('.//CPFCNPJTomador/CNPJ', namespaces=ns).text

        if "false" in signISSRetido:
            signISSRetido = "N"
        else:
            signISSRetido = "S"
        signNumeroRPS = signNumeroRPS.rjust(12, "0")
        signDataEmissao = signDataEmissao.replace("-", "")
        signValorServicos = signValorServicos.replace("R$", "")
        signValorServicos = signValorServicos.rjust(15, "0")
        signValorDeducoes = signValorDeducoes.replace("R$", "")
        signValorDeducoes = signValorDeducoes.rjust(15, "0")
        signCodigoServico + signCodigoServico.rjust(5, "0")

        signCPFCNPJIntermediario = bufferXml.find(".//CPFCNPJIntermediario", namespaces=ns).text

        if signCPFCNPJIntermediario != None:
            signISSRetidoIntermediario = bufferXml.find(".//ISSRetidoIntermediario", namespaces=ns).text
            signInscricaoMunicipalIntermediario = bufferXml.find(".//InscricaoMunicipalIntermediario", namespaces=ns).text
            if "false" in signISSRetidoIntermediario:
                stringConcat = str(signInscricaoPrestador + signSerieRPS + " " + signNumeroRPS + signDataEmissao
                                   + signTributacaoRPS + signStatusRPS + signValorServicos + signValorDeducoes + "0"
                                   + signCodigoServico + signISSRetido + signCPFCNPJTomador)
            else:
                signISSRetidoIntermediario = "S"
                signCPFCNPJIntermediario = "2" + signCPFCNPJIntermediario
                stringConcat = str(signInscricaoPrestador + signSerieRPS + " " + signNumeroRPS + signDataEmissao
                                   + signTributacaoRPS + signStatusRPS + signValorServicos + signValorDeducoes + "0"
                                   + signCodigoServico + signISSRetido + signCPFCNPJTomador + signCPFCNPJIntermediario
                                   + signInscricaoMunicipalIntermediario + signISSRetidoIntermediario)

        message = str(stringConcat).encode("ascii")

        digest = SHA.new(message)

        RSAKey = RSA.importKey(rsaKeyContent)
        signer = PKCS1_v1_5.new(RSAKey)
        sign = signer.sign(digest)
        b64Signed = b64e(sign)

        cls.verifySignature(rsaKeyContent, digest, sign)

        ns = {}
        bufferXml = etree.fromstring(stringXml)
        bufferXml.find(".//Assinatura", namespaces=ns).text = b64Signed

        return cls.signWithA1Cert(bufferXml, certContent=certContent, rsaKeyContent=rsaKeyContent)