Exemple #1
0
    def assina_xml(self, xml):
        self._checar_certificado()
        self._inicializar_cripto()
        try:
            doc_xml = libxml2.parseMemory(xml.encode('utf-8'),
                                          len(xml.encode('utf-8')))

            signNode = xmlsec.TmplSignature(doc_xml,
                                            xmlsec.transformInclC14NId(),
                                            xmlsec.transformRsaSha1Id(), None)

            doc_xml.getRootElement().addChild(signNode)
            refNode = signNode.addReference(
                xmlsec.transformSha1Id(), None,
                '#NFe43150602261542000143550010000000761792265342', None)

            refNode.addTransform(xmlsec.transformEnvelopedId())
            refNode.addTransform(xmlsec.transformInclC14NId())
            keyInfoNode = signNode.ensureKeyInfo()
            keyInfoNode.addX509Data()

            dsig_ctx = xmlsec.DSigCtx()
            chave = xmlsec.cryptoAppKeyLoad(filename=str(self.arquivo),
                                            format=xmlsec.KeyDataFormatPkcs12,
                                            pwd=str(self.senha),
                                            pwdCallback=None,
                                            pwdCallbackCtx=None)

            dsig_ctx.signKey = chave
            dsig_ctx.sign(signNode)

            status = dsig_ctx.status
            dsig_ctx.destroy()

            if status != xmlsec.DSigStatusSucceeded:
                raise RuntimeError(
                    'Erro ao realizar a assinatura do arquivo; status: "' +
                    str(status) + '"')

            xpath = doc_xml.xpathNewContext()
            xpath.xpathRegisterNs('sig', NAMESPACE_SIG)
            certificados = xpath.xpathEval(
                '//sig:X509Data/sig:X509Certificate')
            for i in range(len(certificados) - 1):
                certificados[i].unlinkNode()
                certificados[i].freeNode()

            xml = doc_xml.serialize()
            return xml
        finally:
            doc_xml.freeDoc()
            self._finalizar_cripto()
    def assina_xml(self, xml, reference):
        self._checar_certificado()
        self._inicializar_cripto()
        try:
            doc_xml = libxml2.parseMemory(
                xml, len(xml))

            signNode = xmlsec.TmplSignature(doc_xml,
                                            xmlsec.transformInclC14NId(),
                                            xmlsec.transformRsaSha1Id(), None)

            doc_xml.getRootElement().addChild(signNode)
            refNode = signNode.addReference(xmlsec.transformSha1Id(),
                                            None, reference, None)

            refNode.addTransform(xmlsec.transformEnvelopedId())
            refNode.addTransform(xmlsec.transformInclC14NId())
            keyInfoNode = signNode.ensureKeyInfo()
            keyInfoNode.addX509Data()

            dsig_ctx = xmlsec.DSigCtx()
            chave = xmlsec.cryptoAppKeyLoad(filename=str(self.arquivo),
                                            format=xmlsec.KeyDataFormatPkcs12,
                                            pwd=str(self.senha),
                                            pwdCallback=None,
                                            pwdCallbackCtx=None)

            dsig_ctx.signKey = chave
            dsig_ctx.sign(signNode)

            status = dsig_ctx.status
            dsig_ctx.destroy()

            if status != xmlsec.DSigStatusSucceeded:
                raise RuntimeError(
                    'Erro ao realizar a assinatura do arquivo; status: "' +
                    str(status) +
                    '"')

            xpath = doc_xml.xpathNewContext()
            xpath.xpathRegisterNs('sig', NAMESPACE_SIG)
            certificados = xpath.xpathEval(
                '//sig:X509Data/sig:X509Certificate')
            for i in range(len(certificados) - 1):
                certificados[i].unlinkNode()
                certificados[i].freeNode()

            xml = doc_xml.serialize()
            return xml
        finally:
            doc_xml.freeDoc()
Exemple #3
0
def verify_file(mngr, xml_file):
    assert(mngr)
    assert(xml_file)

    # Load XML file
    if not check_filename(xml_file):
        return -1
    doc = libxml2.parseFile(xml_file)
    if doc is None or doc.getRootElement() is None:
	print "Error: unable to parse file \"%s\"" % tmpl_file
        return cleanup(doc)

    # Find start node
    node = xmlsec.findNode(doc.getRootElement(),
                           xmlsec.NodeSignature, xmlsec.DSigNs)
    if node is None:
        print "Error: start node not found in \"%s\"", xml_file

    # Create signature context
    dsig_ctx = xmlsec.DSigCtx(mngr)
    if dsig_ctx is None:
        print "Error: failed to create signature context"
        return cleanup(doc)

    # Limit the Reference URI attributes to empty or None
    dsig_ctx.enabledReferenceUris = xmlsec.TransformUriTypeEmpty

    # Limit allowed transforms for signature and reference processing
    if (dsig_ctx.enableSignatureTransform(xmlsec.transformInclC14NId()) < 0 or
        dsig_ctx.enableSignatureTransform(xmlsec.transformExclC14NId()) < 0 or
        dsig_ctx.enableSignatureTransform(xmlsec.transformSha1Id())     < 0 or
        dsig_ctx.enableSignatureTransform(xmlsec.transformRsaSha1Id())  < 0):
        print "Error: failed to limit allowed signature transforms"
        return cleanup(doc, dsig_ctx)
    if (dsig_ctx.enableReferenceTransform(xmlsec.transformInclC14NId()) < 0 or
        dsig_ctx.enableReferenceTransform(xmlsec.transformExclC14NId()) < 0 or
        dsig_ctx.enableReferenceTransform(xmlsec.transformSha1Id())     < 0 or
        dsig_ctx.enableReferenceTransform(xmlsec.transformEnvelopedId())< 0):
        print "Error: failed to limit allowed reference transforms"
        return cleanup(doc, dsig_ctx)

    # In addition, limit possible key data to valid X509 certificates only
    if dsig_ctx.keyInfoReadCtx.enabledKeyData.add(xmlsec.keyDataX509Id()) < 0:
        print "Error: failed to limit allowed key data"
        return cleanup(doc, dsig_ctx)

    # Verify signature
    if dsig_ctx.verify(node) < 0:
        print "Error: signature verify"
        return cleanup(doc, dsig_ctx)

    # Check that we have only one Reference
    if (dsig_ctx.status == xmlsec.DSigStatusSucceeded and
        dsig_ctx.signedInfoReferences.getSize() != 1):
        print "Error: only one reference is allowed"
        return cleanup(doc, dsig_ctx)

    # Print verification result to stdout
    if dsig_ctx.status == xmlsec.DSigStatusSucceeded:
        print "Signature is OK"
    else:
        print "Signature is INVALID"

    # Success
    return cleanup(doc, dsig_ctx, 1)
    def sign_file(self, xml_file, signed_xml_file, pkcs_file, password):
        assert(xml_file)
        assert(pkcs_file)
        assert(password)
        
        # Load template
        if not self.check_filename(xml_file):
            return -1
        
        doc = libxml2.parseFile(xml_file)
        if doc is None or doc.getRootElement() is None:
            log.error(" unable to parse file \"%s\"" % xml_file)
            return self.cleanup(doc)
        
        log.debug("Signing file %s using %s " % (xml_file, pkcs_file))

        if self._use_template: 
            # If the template is already in the text ready to be filled 
            signNode = xmlsec.findNode(doc.getRootElement(),
                                       xmlsec.NodeSignature, 
                                       xmlsec.DSigNs);
            if signNode is None:
                log.error(" failed to find signature template")
                return self.cleanup(doc)
                
        else:
            # If the signature structure has to be constructed and added.
            
            # Create signature template for RSA-SHA256 enveloped signature
            signNode = xmlsec.TmplSignature(doc, 
                                            xmlsec.transformInclC14NId(), 
                                            xmlsec.transformRsaSha1Id(), None)
            
            # Add <dsig:Signature/> node to the doc
            doc.getRootElement().addChild(signNode)
            
            # Add reference
            refNode = signNode.addReference(xmlsec.transformSha1Id(),
                                            None, "", None)
            if refNode is None:
                log.error("Failed to add reference to signature template")
                return self.cleanup(doc)
            
            # Add enveloped transform
            if refNode.addTransform(xmlsec.transformEnvelopedId()) is None:
                log.error("Failed to add enveloped transform to reference")
                return self.cleanup(doc)
        
            # Add <dsig:KeyInfo/> and <dsig:X509Data/>
            keyInfoNode = signNode.ensureKeyInfo(None)
            if keyInfoNode is None:
                log.error("Failed to add key info")
                return self.cleanup(doc)
            
            x509DataNode = keyInfoNode.addX509Data() 
            if x509DataNode is None:
                log.error("Failed to add X509Data node")
                return self.cleanup(doc)

            if xmlsec.addChild(x509DataNode,
                               xmlsec.NodeX509SubjectName) is None:
                log.error("Failed to X509SubjectName to x509DataNode")
                return self.cleanup(doc)

            # Sample code from here.
            # http://ndg-security.ceda.ac.uk/browser/TI12-security/trunk/python/NDG/XMLSecDoc.py?rev=920
            if xmlsec.addChild(x509DataNode,
                               xmlsec.NodeX509Certificate) is None:
                log.error("Failed to X509certificate to x509DataNode")
                return self.cleanup(doc)

        # endif (if use_template..) 
    
        # Create signature context, we don't need keys manager in this
        # example
        dsig_ctx = xmlsec.DSigCtx()
        if dsig_ctx is None:
            log.error("Failed to create signature context")
            return self.cleanup(doc)
        
        # Store the context..
        self.dsig_ctx = dsig_ctx 

        # Load private key, assuming that there is not password
        if not self.check_filename(pkcs_file):
            return self.cleanup(doc, dsig_ctx)
        
        #key = xmlsec.cryptoAppKeyLoad(key_file, xmlsec.KeyDataFormatPem,
        #                              None, None, None)
        key = xmlsec.cryptoAppPkcs12Load(pkcs_file, password, None, None)
        if key is None:
            log.error("Failed to load private pem key from \"%s\"" % pkcs_file)
            return self.cleanup(doc, dsig_ctx)

        dsig_ctx.signKey = key
        
        # Load certificate and add to the key
        # if not check_filename(cert_file):
        #    return self.cleanup(doc, dsig_ctx)
        # if xmlsec.cryptoAppKeyCertLoad(key, cert_file, xmlsec.KeyDataFormatPem) < 0:
        #    log.error(" failed to load pem certificate \"%s\"" % cert_file
        #    return self.cleanup(doc, dsig_ctx)
        
        # Set key name to the file name, this is just an example!
        if key.setName(pkcs_file) < 0:
            log.error("Failed to set key name for key from \"%s\"" % pkcs_file)
            return self.cleanup(doc, dsig_ctx)
        
        # Sign the template
        if dsig_ctx.sign(signNode) < 0:
            log.error("Signature failed")
            return self.cleanup(doc, dsig_ctx)
        
        # Print signed document to stdout
        #doc.dump("-")
        #doc.formatDump("-", 0)
        import libxml2mod
        
        fp = file(signed_xml_file, "w")
        libxml2mod.xmlDocFormatDump(fp, doc._o, 0)
        fp.close()
        
        # Success
        return self.cleanup(doc, dsig_ctx, 1)
Exemple #5
0
def verify_file(mngr, xml_file):
    assert (mngr)
    assert (xml_file)

    # Load XML file
    if not check_filename(xml_file):
        return -1
    doc = libxml2.parseFile(xml_file)
    if doc is None or doc.getRootElement() is None:
        print "Error: unable to parse file \"%s\"" % tmpl_file
        return cleanup(doc)

    # Find start node
    node = xmlsec.findNode(doc.getRootElement(), xmlsec.NodeSignature,
                           xmlsec.DSigNs)
    if node is None:
        print "Error: start node not found in \"%s\"", xml_file

    # Create signature context
    dsig_ctx = xmlsec.DSigCtx(mngr)
    if dsig_ctx is None:
        print "Error: failed to create signature context"
        return cleanup(doc)

    # Limit the Reference URI attributes to empty or None
    dsig_ctx.enabledReferenceUris = xmlsec.TransformUriTypeEmpty

    # Limit allowed transforms for signature and reference processing
    if (dsig_ctx.enableSignatureTransform(xmlsec.transformInclC14NId()) < 0 or
            dsig_ctx.enableSignatureTransform(xmlsec.transformExclC14NId()) < 0
            or dsig_ctx.enableSignatureTransform(xmlsec.transformSha1Id()) < 0
            or dsig_ctx.enableSignatureTransform(
                xmlsec.transformRsaSha1Id()) < 0):
        print "Error: failed to limit allowed signature transforms"
        return cleanup(doc, dsig_ctx)
    if (dsig_ctx.enableReferenceTransform(xmlsec.transformInclC14NId()) < 0 or
            dsig_ctx.enableReferenceTransform(xmlsec.transformExclC14NId()) < 0
            or dsig_ctx.enableReferenceTransform(xmlsec.transformSha1Id()) < 0
            or dsig_ctx.enableReferenceTransform(
                xmlsec.transformEnvelopedId()) < 0):
        print "Error: failed to limit allowed reference transforms"
        return cleanup(doc, dsig_ctx)

    # In addition, limit possible key data to valid X509 certificates only
    if dsig_ctx.keyInfoReadCtx.enabledKeyData.add(xmlsec.keyDataX509Id()) < 0:
        print "Error: failed to limit allowed key data"
        return cleanup(doc, dsig_ctx)

    # Verify signature
    if dsig_ctx.verify(node) < 0:
        print "Error: signature verify"
        return cleanup(doc, dsig_ctx)

    # Check that we have only one Reference
    if (dsig_ctx.status == xmlsec.DSigStatusSucceeded
            and dsig_ctx.signedInfoReferences.getSize() != 1):
        print "Error: only one reference is allowed"
        return cleanup(doc, dsig_ctx)

    # Print verification result to stdout
    if dsig_ctx.status == xmlsec.DSigStatusSucceeded:
        print "Signature is OK"
    else:
        print "Signature is INVALID"

    # Success
    return cleanup(doc, dsig_ctx, 1)
Exemple #6
0
 def _determine_transform_format(formatstring):
     """Translates strings to all transform methods of the pyXMLsec library.
     This should actually sort out which value could be used where, but for 
     now, it works :-).
     """
     if formatstring == 'aes128-cbc':
         result = xmlsec.transformAes128CbcId()
     elif formatstring == 'aes192-cbc':
         result = xmlsec.transformAes192CbcId()
     elif formatstring == 'aes256-cbc':
         result = xmlsec.transformAes256CbcId()
     elif formatstring == 'kw-aes128':
         result = xmlsec.transformKWAes128Id()
     elif formatstring == 'kw-aes192':
         result = xmlsec.transformKWAes192Id()
     elif formatstring == 'kw-aes256':
         result = xmlsec.transformKWAes256Id()
     elif formatstring == 'des3-cbc':
         result = xmlsec.transformDes3CbcId()
     elif formatstring == 'kw-des3':
         result = xmlsec.transformKWDes3Id()
     elif formatstring == 'dsa-sha1':
         result = xmlsec.transformDsaSha1Id()
     elif formatstring == 'hmac-md5':
         result = xmlsec.transformHmacMd5Id()
     elif formatstring == 'hmac-ripemd160':
         result = xmlsec.transformHmacRipemd160Id()
     elif formatstring == 'hmac-sha1':
         result = xmlsec.transformHmacSha1Id()
     elif formatstring == 'hmac-sha224':
         result = xmlsec.transformHmacSha224Id()
     elif formatstring == 'hmac-sha256':
         result = xmlsec.transformHmacSha256Id()
     elif formatstring == 'hmac-sha384':
         result = xmlsec.transformHmacSha384Id()
     elif formatstring == 'hmac-sha512':
         result = xmlsec.transformHmacSha512Id()
     elif formatstring == 'hmac-md5':
         result = xmlsec.transformMd5Id()
     elif formatstring == 'ripemd160':
         result = xmlsec.transformRipemd160Id()
     elif formatstring == 'rsa-md5':
         result = xmlsec.transformRsaMd5Id()
     elif formatstring == 'rsa-ripemd160':
         result = xmlsec.transformRsaRipemd160Id()
     elif formatstring == 'rsa-sha1':
         result = xmlsec.transformRsaSha1Id()
     elif formatstring == 'rsa-sha224':
         result = xmlsec.transformRsaSha224Id()
     elif formatstring == 'rsa-sha256':
         result = xmlsec.transformRsaSha256Id()
     elif formatstring == 'rsa-sha384':
         result = xmlsec.transformRsaSha384Id()
     elif formatstring == 'rsa-sha512':
         result = xmlsec.transformRsaSha512Id()
     elif formatstring == 'rsa-pkcs1':
         result = xmlsec.transformRsaPkcs1Id()
     elif formatstring == 'rsa-oaep':
         result = xmlsec.transformRsaOaepId()
     elif formatstring == 'sha1':
         result = xmlsec.transformSha1Id()
     elif formatstring == 'sha224':
         result = xmlsec.transformSha224Id()
     elif formatstring == 'sha256':
         result = xmlsec.transformSha256Id()
     elif formatstring == 'sha384':
         result = xmlsec.transformSha384Id()
     elif formatstring == 'sha512':
         result = xmlsec.transformSha512Id()
     elif formatstring == 'base64':
         result = xmlsec.transformBase64Id()
     elif formatstring == 'inc-c14n':
         result = xmlsec.transformInclC14NId()
     elif formatstring == 'inc-c14n-with-comments':
         result = xmlsec.transformInclC14NWithCommentsId()
     elif formatstring == 'exc-c14n':
         result = xmlsec.transformExclC14NId()
     elif formatstring == 'exc-c14n-with-comments':
         result = xmlsec.transformExclC14NWithCommentsId()
     elif formatstring in ('enveloped', 'enveloped-signature'):
         result = xmlsec.transformEnvelopedId()
     elif formatstring in ('xpath', 'xpath-19991116', 'xmldsig-filter'):
         result = xmlsec.transformXPathId()
     elif formatstring in ('xpath2', 'xmldsig-filter2'):
         result = xmlsec.transformXPath2Id()
     elif formatstring == 'xpointer':
         result = xmlsec.transformXPointerId()
     elif formatstring in ('xslt', 'xslt-19991116'):
         result = xmlsec.transformXsltId()
     elif formatstring == 'remove-xml-tags-transform':
         result = xmlsec.transformRemoveXmlTagsC14NId()
     elif formatstring == 'visa3d-hack':
         result = xmlsec.transformVisa3DHackId()
     else:
         raise DSigError('Unknown transform: %s' % formatstring)
     
     if result is None:
         raise DSigError('Transform %s not available' % formatstring)
     else:
         return result
Exemple #7
0
    def _determine_transform_format(formatstring):
        """Translates strings to all transform methods of the pyXMLsec library.
        This should actually sort out which value could be used where, but for 
        now, it works :-).
        """
        if formatstring == 'aes128-cbc':
            result = xmlsec.transformAes128CbcId()
        elif formatstring == 'aes192-cbc':
            result = xmlsec.transformAes192CbcId()
        elif formatstring == 'aes256-cbc':
            result = xmlsec.transformAes256CbcId()
        elif formatstring == 'kw-aes128':
            result = xmlsec.transformKWAes128Id()
        elif formatstring == 'kw-aes192':
            result = xmlsec.transformKWAes192Id()
        elif formatstring == 'kw-aes256':
            result = xmlsec.transformKWAes256Id()
        elif formatstring == 'des3-cbc':
            result = xmlsec.transformDes3CbcId()
        elif formatstring == 'kw-des3':
            result = xmlsec.transformKWDes3Id()
        elif formatstring == 'dsa-sha1':
            result = xmlsec.transformDsaSha1Id()
        elif formatstring == 'hmac-md5':
            result = xmlsec.transformHmacMd5Id()
        elif formatstring == 'hmac-ripemd160':
            result = xmlsec.transformHmacRipemd160Id()
        elif formatstring == 'hmac-sha1':
            result = xmlsec.transformHmacSha1Id()
        elif formatstring == 'hmac-sha224':
            result = xmlsec.transformHmacSha224Id()
        elif formatstring == 'hmac-sha256':
            result = xmlsec.transformHmacSha256Id()
        elif formatstring == 'hmac-sha384':
            result = xmlsec.transformHmacSha384Id()
        elif formatstring == 'hmac-sha512':
            result = xmlsec.transformHmacSha512Id()
        elif formatstring == 'hmac-md5':
            result = xmlsec.transformMd5Id()
        elif formatstring == 'ripemd160':
            result = xmlsec.transformRipemd160Id()
        elif formatstring == 'rsa-md5':
            result = xmlsec.transformRsaMd5Id()
        elif formatstring == 'rsa-ripemd160':
            result = xmlsec.transformRsaRipemd160Id()
        elif formatstring == 'rsa-sha1':
            result = xmlsec.transformRsaSha1Id()
        elif formatstring == 'rsa-sha224':
            result = xmlsec.transformRsaSha224Id()
        elif formatstring == 'rsa-sha256':
            result = xmlsec.transformRsaSha256Id()
        elif formatstring == 'rsa-sha384':
            result = xmlsec.transformRsaSha384Id()
        elif formatstring == 'rsa-sha512':
            result = xmlsec.transformRsaSha512Id()
        elif formatstring == 'rsa-pkcs1':
            result = xmlsec.transformRsaPkcs1Id()
        elif formatstring == 'rsa-oaep':
            result = xmlsec.transformRsaOaepId()
        elif formatstring == 'sha1':
            result = xmlsec.transformSha1Id()
        elif formatstring == 'sha224':
            result = xmlsec.transformSha224Id()
        elif formatstring == 'sha256':
            result = xmlsec.transformSha256Id()
        elif formatstring == 'sha384':
            result = xmlsec.transformSha384Id()
        elif formatstring == 'sha512':
            result = xmlsec.transformSha512Id()
        elif formatstring == 'base64':
            result = xmlsec.transformBase64Id()
        elif formatstring == 'inc-c14n':
            result = xmlsec.transformInclC14NId()
        elif formatstring == 'inc-c14n-with-comments':
            result = xmlsec.transformInclC14NWithCommentsId()
        elif formatstring == 'exc-c14n':
            result = xmlsec.transformExclC14NId()
        elif formatstring == 'exc-c14n-with-comments':
            result = xmlsec.transformExclC14NWithCommentsId()
        elif formatstring in ('enveloped', 'enveloped-signature'):
            result = xmlsec.transformEnvelopedId()
        elif formatstring in ('xpath', 'xpath-19991116', 'xmldsig-filter'):
            result = xmlsec.transformXPathId()
        elif formatstring in ('xpath2', 'xmldsig-filter2'):
            result = xmlsec.transformXPath2Id()
        elif formatstring == 'xpointer':
            result = xmlsec.transformXPointerId()
        elif formatstring in ('xslt', 'xslt-19991116'):
            result = xmlsec.transformXsltId()
        elif formatstring == 'remove-xml-tags-transform':
            result = xmlsec.transformRemoveXmlTagsC14NId()
        elif formatstring == 'visa3d-hack':
            result = xmlsec.transformVisa3DHackId()
        else:
            raise XMLDSIGError('Unknown transform: %s' % formatstring)

        if result is None:
            raise XMLDSIGError('Transform %s not available' % formatstring)
        else:
            return result