Пример #1
0
    def sending(self, context):
        msgtype = "RacunZahtjev"
        if "PoslovniProstorZahtjev" in context.envelope: msgtype = "PoslovniProstorZahtjev"
    
        doc2 = libxml2.parseDoc(context.envelope)

        zahtjev = doc2.xpathEval('//*[local-name()="%s"]' % msgtype)[0]
        doc2.setRootElement(zahtjev)

        x = doc2.getRootElement().newNs('http://www.apis-it.hr/fin/2012/types/f73', 'tns')
 
        for i in doc2.xpathEval('//*'):
            i.setNs(x)

        libxml2.initParser()
        libxml2.substituteEntitiesDefault(1)

        xmlsec.init()
        xmlsec.cryptoAppInit(None)
        xmlsec.cryptoInit()

        doc2.getRootElement().setProp('Id', msgtype)
        xmlsec.addIDs(doc2, doc2.getRootElement(), ['Id'])    

        signNode = xmlsec.TmplSignature(doc2, xmlsec.transformExclC14NId(), xmlsec.transformRsaSha1Id(), None)

        doc2.getRootElement().addChild(signNode)
    
        refNode = signNode.addReference(xmlsec.transformSha1Id(), None, None, None)
        refNode.setProp('URI', '#%s' % msgtype)
        refNode.addTransform(xmlsec.transformEnvelopedId())
        refNode.addTransform(xmlsec.transformExclC14NId())
 
        dsig_ctx = xmlsec.DSigCtx()
        key = xmlsec.cryptoAppKeyLoad(keyFile, xmlsec.KeyDataFormatPem, None, None, None)
        dsig_ctx.signKey = key

        xmlsec.cryptoAppKeyCertLoad(key, certFile, xmlsec.KeyDataFormatPem)
        key.setName(keyFile)

        keyInfoNode = signNode.ensureKeyInfo(None)
        x509DataNode = keyInfoNode.addX509Data()
        xmlsec.addChild(x509DataNode, "X509IssuerSerial")
        xmlsec.addChild(x509DataNode, "X509Certificate")

        dsig_ctx.sign(signNode)
    
        if dsig_ctx is not None: dsig_ctx.destroy()
        context.envelope = """<?xml version="1.0" encoding="UTF-8"?>
        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <soapenv:Body>""" + doc2.serialize().replace('<?xml version="1.0" encoding="UTF-8"?>','') + """</soapenv:Body></soapenv:Envelope>""" # Ugly hack
    
        # Shutdown xmlsec-crypto library, ako ne radi HTTPS onda ovo treba zakomentirati da ga ne ugasi prije reda
        xmlsec.cryptoShutdown()
        xmlsec.shutdown()
        libxml2.cleanupParser()

        return context
Пример #2
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()
Пример #3
0
def sign_file(xml_file, key_file):
    assert (xml_file)
    assert (key_file)

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

    # Create signature template for RSA-SHA1 enveloped signature
    signNode = xmlsec.TmplSignature(doc, xmlsec.transformExclC14NId(),
                                    xmlsec.transformRsaSha1Id(), None)
    if signNode is None:
        print "Error: failed to create signature template"
        return cleanup(doc)

    # Add <dsig:Signature/> node to the doc
    doc.getRootElement().addChild(signNode)

    # Add reference
    refNode = signNode.addReference(xmlsec.transformSha1Id(), None, None, None)
    if refNode is None:
        print "Error: failed to add reference to signature template"
        return cleanup(doc)

    # Add enveloped transform
    if refNode.addTransform(xmlsec.transformEnvelopedId()) is None:
        print "Error: failed to add enveloped transform to reference"
        return cleanup(doc)

    # Add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to put key name
    # in the signed document
    keyInfoNode = signNode.ensureKeyInfo(None)
    if keyInfoNode is None:
        print "Error: failed to add key info"
        return cleanup(doc)

    keyNameInfo = keyInfoNode.addKeyName(None)
    if keyNameInfo is None:
        print "Error: failed to add key name"
        return cleanup(doc)

    # Create signature context, we don't need keys manager in this example
    dsig_ctx = xmlsec.DSigCtx()
    if dsig_ctx is None:
        print "Error: failed to create signature context"
        return cleanup(doc)

    # Load private key, assuming that there is not password
    key = xmlsec.cryptoAppKeyLoad(key_file, xmlsec.KeyDataFormatPem, None,
                                  None, None)
    if key is None:
        print "Error: failed to load private pem key from \"%s\"" % key_file
        return cleanup(doc, dsig_ctx)
    dsig_ctx.signKey = key

    # Set key name to the file name, this is just an example!
    if key.setName(key_file) < 0:
        print "Error: failed to set key name for key from \"%s\"" % key_file
        return cleanup(doc, dsig_ctx)

    # Sign the template
    if dsig_ctx.sign(signNode) < 0:
        print "Error: signature failed"
        return cleanup(doc, dsig_ctx)

    # Print signed document to stdout
    doc.dump("-")

    # Success
    return cleanup(doc, dsig_ctx, 1)
Пример #4
0
    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)
Пример #5
0
    def template_sign(self,
                      body,
                      canonicalization,
                      signing,
                      references,
                      key_name=None,
                      key_x509=False):
        """Signs a XML file and creates a template based on the information 
        provided. This information generally can be found in the documentation.
        
        body             -- The XML body string.
        canonicalization -- The c14n method, e.g. enc-c14n
        signing          -- The signing method, e.g. rsa-sha256
        references       -- A dict containing mappings of reference methods to
                            an iterable of transforms, e.g. 
                            {'sha256': ('enveloped-signature', )}
        key_name         -- The key name, or None if not required
        key_x509         -- Boolean indicating whether X509 data is required.
        """

        # Translate c14n and signing arguments
        canonicalization = XMLDSIG._determine_transform_format(
            canonicalization)
        signing = XMLDSIG._determine_transform_format(signing)

        doc = dsig_ctx = None

        try:

            # Reparse using libxml2
            doc = libxml2.parseDoc(body)
            if doc is None or doc.getRootElement() is None:
                raise XMLDSIGError("Failed feeding xml to libxml2")

            # Create signature template
            sign_node = xmlsec.TmplSignature(doc, canonicalization, signing,
                                             None)
            if sign_node is None:
                raise XMLDSIGError('Failed creating a signature template.')

            doc.getRootElement().addChild(sign_node)

            # Create references
            for (reference, transforms) in references.items():
                ref = XMLDSIG._determine_transform_format(reference)

                ref_node = sign_node.addReference(ref, None, None, None)
                if ref_node is None:
                    raise XMLDSIGError(
                        'Failed adding reference %s to template.' % reference)

                # add transforms
                for transform in transforms:
                    trans = XMLDSIG._determine_transform_format(transform)

                    if ref_node.addTransform(trans) is None:
                        raise XMLDSIGError(
                            'Failed adding transform %s to template.' %
                            transform)

            # Add keyinfo
            if key_name or key_x509:
                keyinfo_node = sign_node.ensureKeyInfo(None)
                if keyinfo_node is None:
                    raise XMLDSIGError('Failed adding key info to template.')

                if key_name:
                    if keyinfo_node.addKeyName(key_name) is None:
                        raise XMLDSIGError(
                            'Failed adding key name to template.')

                if key_x509:
                    if keyinfo_node.addX509Data() is None:
                        raise XMLDSIGError(
                            'Failed adding X509 data to template.')

            # create a signing context
            dsig_ctx = self._create_dsig_ctx()

            # Sign
            if dsig_ctx.sign(sign_node) < 0:
                raise XMLDSIGError('Failed signing the xml.')

            return doc.serialize('UTF-8', 0)  # 0 = not pretty

        except XMLDSIGError:
            raise
        except Exception as e:
            raise XMLDSIGError('Something went wrong signing the xml: %s' % e)

        finally:
            # Clear some space, it is a C API after all
            if dsig_ctx is not None:
                dsig_ctx.destroy()
            if doc is not None:
                doc.freeDoc()