Exemplo n.º 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
Exemplo n.º 2
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
def _signXML(xml):
    dsigctx = None
    doc = None
    try:
        # initialization
        libxml2.initParser()
        libxml2.substituteEntitiesDefault(1)
        if xmlsec.init() < 0:
            raise SignatureError('xmlsec init failed')
        if xmlsec.checkVersion() != 1:
            raise SignatureError('incompatible xmlsec library version %s' %
                                 str(xmlsec.checkVersion()))
        if xmlsec.cryptoAppInit(None) < 0:
            raise SignatureError('crypto initialization failed')
        if xmlsec.cryptoInit() < 0:
            raise SignatureError('xmlsec-crypto initialization failed')

        # load the input
        doc = libxml2.parseDoc(xml)
        if not doc or not doc.getRootElement():
            raise SignatureError('error parsing input xml')
        node = xmlsec.findNode(doc.getRootElement(), xmlsec.NodeSignature,
                               xmlsec.DSigNs)
        if not node:
            raise SignatureError("couldn't find root node")

        dsigctx = xmlsec.DSigCtx()

        key = xmlsec.cryptoAppKeyLoad(key_file, xmlsec.KeyDataFormatPem,
                                      key_pwd, None, None)

        if not key:
            raise SignatureError('failed to load the private key %s' %
                                 key_file)
        dsigctx.signKey = key

        if key.setName(key_file) < 0:
            raise SignatureError('failed to set key name')

        if xmlsec.cryptoAppKeyCertLoad(key, cert_file,
                                       xmlsec.KeyDataFormatPem) < 0:
            print "Error: failed to load pem certificate \"%s\"" % cert_file
            return cleanup(doc, dsigctx)

        # sign
        if dsigctx.sign(node) < 0:
            raise SignatureError('signing failed')
        signed_xml = doc.serialize()

    finally:
        if dsigctx:
            dsigctx.destroy()
        if doc:
            doc.freeDoc()
        xmlsec.cryptoShutdown()
        xmlsec.shutdown()
        libxml2.cleanupParser()

    return signed_xml
Exemplo n.º 4
0
def sign_xml(xml, key_file, cert_file=None):

  # Load template
  doc = libxml2.parseDoc(xml)
  if doc is None or doc.getRootElement() is None:
    cleanup(doc)
    raise saml2.Error("Error: unable to parse string \"%s\"" % xml)

  node = xmlsec.findNode(doc.getRootElement(), xmlsec.NodeSignature,
                         xmlsec.DSigNs)

  if node is None:
    cleanup(doc)
    raise saml2.Error("Error: start node not found.")

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

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

  if cert_file is not None:
    if xmlsec.cryptoAppKeyCertLoad(
      dsig_ctx.signKey, cert_file, xmlsec.KeyDataFormatPem) < 0:
      cleanup(doc, dsig_ctx)
      raise saml2.Error(
        "Error: failed to load cert pem from \"%s\"" % cert_file)
  else:
    pass
    
  # Set key name to the file name, this is just an example!
  if key.setName(key_file) < 0:
    cleanup(doc, dsig_ctx)
    raise saml2.Error(
      "Error: failed to set key name for key from \"%s\"" % key_file)
    return cleanup(doc, dsig_ctx)

  # Sign the template
  if dsig_ctx.sign(node) < 0:
    cleanup(doc, dsig_ctx)
    raise saml2.Error("Error: signature failed")

  # signed document to string
  ret = doc.__str__()

  # Success
  cleanup(doc, dsig_ctx, 1)

  return ret
Exemplo n.º 5
0
    def load_key(self,
                 path,
                 password=None,
                 name=None,
                 cert_path=None,
                 key_format='pem',
                 cert_format='pem'):
        """Loads a key into the key store of the class.
        
        path       -- The path to a keyfile used to sign the XML.
        password   -- The key password, or None if no password is set.
        name       -- The name to be set for the key, or None if none should be set
        cert_path  -- The path to the certificate belonging to this key, or None
        key_format -- The format of the key as string. Defaults to pem
        cert_format-- The format of the certificate as string. Defaults to pem
        """

        key_format = XMLDSIG._determine_key_format(key_format)
        cert_format = XMLDSIG._determine_key_format(cert_format)

        try:
            # Load key
            key = xmlsec.cryptoAppKeyLoad(path, key_format, password, None,
                                          None)
            if key is None:
                raise XMLDSIGError('Failed loading private key %s' % path)

            # Set key name
            if name and key.setName(name) < 0:
                raise XMLDSIGError('Failed setting key name of %s to %s' %
                                   (path, name))

            # Link certificate to key
            if cert_path and xmlsec.cryptoAppKeyCertLoad(
                    key, cert_path, cert_format) < 0:
                raise XMLDSIGError('Failed loading certificate %s' % cert_path)

            # Load certificate into store
            if xmlsec.cryptoAppDefaultKeysMngrAdoptKey(self.key_manager,
                                                       key) < 0:
                raise XMLDSIGError("Failed loading key %s into key manager." %
                                   path)

        except XMLDSIGError:
            raise
        except Exception as e:
            raise XMLDSIGError('Something went wrong loading key %s: %s' %
                               (path, e))
Exemplo n.º 6
0
    def load(self, key_file=None, cert_file=None, password='', key_name=None):
        """
        load a private key and/or a public certificate for signature and verification

        - key_file: str, filename of PEM file containing the private key.
                    (the file should NOT be password-protected)
        - cert_file: str, filename of PEM file containing the X509 certificate.
                     (optional: can be None)
        - password: str, password to open key file, or None if no password.
        """
        #TODO: try except block to destroy key if error
        if key_file is not None:
            # Load private key, with optional password
            #print 'PASSWORD: %s' % password
            key = xmlsec.cryptoAppKeyLoad(filename=key_file,
                                          format=xmlsec.KeyDataFormatPem,
                                          pwd=password,
                                          pwdCallback=None,
                                          pwdCallbackCtx=None)
            # API references:
            # http://pyxmlsec.labs.libre-entreprise.org/docs/html/xmlsec-module.html#cryptoAppKeyLoad
            # http://www.aleksey.com/xmlsec/api/xmlsec-app.html#XMLSECCRYPTOAPPKEYLOAD
            # http://www.aleksey.com/xmlsec/api/xmlsec-keysdata.html#XMLSECKEYDATAFORMAT
            if key is None:
                raise RuntimeError, "Error: failed to load private PEM key from \"%s\"" % key_file
            if key_name is not None:
                # Set key name
                if key.setName(key_name) < 0:
                    raise RuntimeError, "Error: failed to set key name to \"%s\"" % key_name
            if cert_file is not None:
                # Load certificate and add to the key
                if xmlsec.cryptoAppKeyCertLoad(key, cert_file,
                                               xmlsec.KeyDataFormatPem) < 0:
                    raise RuntimeError, "Error: failed to load PEM certificate \"%s\"" % cert_file
            # load key into manager:
            if xmlsec.cryptoAppDefaultKeysMngrAdoptKey(self.keysmngr, key) < 0:
                raise RuntimeError, "Error: failed to load key into keys manager"

        elif cert_file is not None:
            # case when we only want to load a cert without private key
            if self.keysmngr.certLoad(cert_file, xmlsec.KeyDataFormatPem,
                                      xmlsec.KeyDataTypeTrusted) < 0:
                # is it better to keep the keys manager if an error occurs?
                #self.keysmngr.destroy()
                raise RuntimeError, "Error: failed to load PEM certificate from \"%s\"" % cert_file
Exemplo n.º 7
0
    def load_key(self, path, password=None, name=None,
                       cert_path=None, key_format='pem', cert_format='pem'):
        """Loads a key into the key store of the class.

        path       -- The path to a keyfile used to sign the XML.
        password   -- The key password, or None if no password is set.
        name       -- The name to be set for the key, or None if none should be set
        cert_path  -- The path to the certificate belonging to this key, or None
        key_format -- The format of the key as string. Defaults to pem
        cert_format-- The format of the certificate as string. Defaults to pem
        """

        key_format = XMLDSIG._determine_key_format(key_format)
        cert_format = XMLDSIG._determine_key_format(cert_format)

        try:
            # Load key
            key = xmlsec.cryptoAppKeyLoad(path, key_format, password, None, None)
            if key is None:
                raise XMLDSIGError('Failed loading private key %s' % path)

            # Set key name
            if name and key.setName(name) < 0:
                raise XMLDSIGError('Failed setting key name of %s to %s' % (path, name))

            # Link certificate to key
            if cert_path and xmlsec.cryptoAppKeyCertLoad(key, cert_path, cert_format) < 0:
                raise XMLDSIGError('Failed loading certificate %s' % cert_path)

            # Load certificate into store
            if xmlsec.cryptoAppDefaultKeysMngrAdoptKey(self.key_manager, key) < 0:
                raise XMLDSIGError("Failed loading key %s into key manager." % path)

        except XMLDSIGError:
            raise
        except Exception as e:
            raise XMLDSIGError('Something went wrong loading key %s: %s' % (path, e))
Exemplo n.º 8
0
def sign_file(xml_file, key_file, cert_file):
    assert(xml_file)
    assert(key_file)
    assert(cert_file)

    # Load template
    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\"" % 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:X509Data/>
    keyInfoNode = signNode.ensureKeyInfo(None)
    if keyInfoNode is None:
        print "Error: failed to add key info"
        return cleanup(doc)
    
    if keyInfoNode.addX509Data() is None:
        print "Error: failed to add X509Data node"
        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
    if not check_filename(key_file):
        return cleanup(doc, dsig_ctx)
    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

    # Load certificate and add to the key
    if not check_filename(cert_file):
        return cleanup(doc, dsig_ctx)
    if xmlsec.cryptoAppKeyCertLoad(key, cert_file, xmlsec.KeyDataFormatPem) < 0:
        print "Error: failed to load pem certificate \"%s\"" % cert_file
        return cleanup(doc, dsig_ctx)

    # 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)
Exemplo n.º 9
0
    def assina_xml(self, xml):
        self._inicia_funcoes_externas()
        xml = self._prepara_doc_xml(xml)

        #
        # Colocamos o texto no avaliador XML
        #
        doc_xml = libxml2.parseMemory(xml.encode('utf-8'),
                                      len(xml.encode('utf-8')))

        #
        # Separa o nó da assinatura
        #
        noh_assinatura = xmlsec.findNode(doc_xml.getRootElement(),
                                         xmlsec.NodeSignature, xmlsec.DSigNs)

        #
        # Arquivos temporários são criados com o certificado no formato PEM
        #
        temp_chave = tempfile.NamedTemporaryFile('w')
        temp_chave.write(self.chave)
        temp_chave.flush()

        temp_certificado = tempfile.NamedTemporaryFile('w')
        temp_certificado.write(self.certificado)
        temp_certificado.flush()

        #
        # Buscamos chave e certificado no arquivo temporário e inserimos no "chaveiro"
        #
        chaveiro = xmlsec.KeysMngr()
        xmlsec.cryptoAppDefaultKeysMngrInit(chaveiro)

        chave = xmlsec.cryptoAppKeyLoad(filename=temp_chave.name,
                                        format=xmlsec.KeyDataFormatPem,
                                        pwd=None,
                                        pwdCallback=None,
                                        pwdCallbackCtx=None)
        certificado = xmlsec.cryptoAppKeyCertLoad(
            chave,
            filename=temp_certificado.name,
            format=xmlsec.KeyDataFormatPem)
        xmlsec.cryptoAppDefaultKeysMngrAdoptKey(chaveiro, chave)

        #
        # Cria a variável de chamada (callable) da função de assinatura, usando o "chaveiro"
        #
        assinador = xmlsec.DSigCtx(chaveiro)

        #
        # Atribui a chave ao assinador
        #
        assinador.signKey = chave

        #
        # Realiza a assinatura
        #
        assinador.sign(noh_assinatura)

        #
        # Guarda o status
        #
        status = assinador.status

        #
        # Libera a memória ocupada pelo assinador manualmente
        #
        assinador.destroy()

        #
        # Arquivos temporários são deletados do disco
        #
        temp_chave.close()
        temp_certificado.close()

        if status != xmlsec.DSigStatusSucceeded:
            #
            # Libera a memória ocupada pelo documento xml manualmente
            #
            doc_xml.freeDoc()
            self._finaliza_funcoes_externas()
            raise RuntimeError(
                'Erro ao realizar a assinatura do arquivo; status: "' +
                str(status) + '"')

        #
        # Elimina do xml assinado a cadeia certificadora, deixando somente
        # o certificado que assinou o documento
        #
        xpath = doc_xml.xpathNewContext()
        xpath.xpathRegisterNs(u'sig', NAMESPACE_SIG)
        certificados = xpath.xpathEval(u'//sig:X509Data/sig:X509Certificate')
        for i in range(len(certificados) - 1):
            certificados[i].unlinkNode()
            certificados[i].freeNode()

        #
        # Retransforma o documento xml em texto
        #
        xml = doc_xml.serialize()

        #
        # Libera a memória ocupada pelo documento xml manualmente
        #
        doc_xml.freeDoc()
        self._finaliza_funcoes_externas()

        xml = self._finaliza_xml(xml)

        return xml
Exemplo n.º 10
0
def sign_file(xml_file, key_file, cert_file):
    assert (xml_file)
    assert (key_file)
    assert (cert_file)

    # Load template
    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\"" % 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:X509Data/>
    keyInfoNode = signNode.ensureKeyInfo(None)
    if keyInfoNode is None:
        print "Error: failed to add key info"
        return cleanup(doc)

    if keyInfoNode.addX509Data() is None:
        print "Error: failed to add X509Data node"
        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
    if not check_filename(key_file):
        return cleanup(doc, dsig_ctx)
    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

    # Load certificate and add to the key
    if not check_filename(cert_file):
        return cleanup(doc, dsig_ctx)
    if xmlsec.cryptoAppKeyCertLoad(key, cert_file,
                                   xmlsec.KeyDataFormatPem) < 0:
        print "Error: failed to load pem certificate \"%s\"" % cert_file
        return cleanup(doc, dsig_ctx)

    # 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)
    def assina_xml(self, xml):
        self._inicia_funcoes_externas()
        xml = self._prepara_doc_xml(xml)

        #
        # Colocamos o texto no avaliador XML
        #
        doc_xml = libxml2.parseMemory(xml.encode("utf-8"), len(xml.encode("utf-8")))

        #
        # Separa o nó da assinatura
        #
        noh_assinatura = xmlsec.findNode(doc_xml.getRootElement(), xmlsec.NodeSignature, xmlsec.DSigNs)

        #
        # Arquivos temporários são criados com o certificado no formato PEM
        #
        temp_chave = tempfile.NamedTemporaryFile("w")
        temp_chave.write(self.chave)
        temp_chave.flush()

        temp_certificado = tempfile.NamedTemporaryFile("w")
        temp_certificado.write(self.certificado)
        temp_certificado.flush()

        #
        # Buscamos chave e certificado no arquivo temporário e inserimos no "chaveiro"
        #
        chaveiro = xmlsec.KeysMngr()
        xmlsec.cryptoAppDefaultKeysMngrInit(chaveiro)

        chave = xmlsec.cryptoAppKeyLoad(
            filename=temp_chave.name, format=xmlsec.KeyDataFormatPem, pwd=None, pwdCallback=None, pwdCallbackCtx=None
        )
        certificado = xmlsec.cryptoAppKeyCertLoad(chave, filename=temp_certificado.name, format=xmlsec.KeyDataFormatPem)
        xmlsec.cryptoAppDefaultKeysMngrAdoptKey(chaveiro, chave)

        #
        # Cria a variável de chamada (callable) da função de assinatura, usando o "chaveiro"
        #
        assinador = xmlsec.DSigCtx(chaveiro)

        #
        # Atribui a chave ao assinador
        #
        assinador.signKey = chave

        #
        # Realiza a assinatura
        #
        assinador.sign(noh_assinatura)

        #
        # Guarda o status
        #
        status = assinador.status

        #
        # Libera a memória ocupada pelo assinador manualmente
        #
        assinador.destroy()

        #
        # Arquivos temporários são deletados do disco
        #
        temp_chave.close()
        temp_certificado.close()

        if status != xmlsec.DSigStatusSucceeded:
            #
            # Libera a memória ocupada pelo documento xml manualmente
            #
            doc_xml.freeDoc()
            self._finaliza_funcoes_externas()
            raise RuntimeError('Erro ao realizar a assinatura do arquivo; status: "' + str(status) + '"')

        #
        # Elimina do xml assinado a cadeia certificadora, deixando somente
        # o certificado que assinou o documento
        #
        xpath = doc_xml.xpathNewContext()
        xpath.xpathRegisterNs(u"sig", NAMESPACE_SIG)
        certificados = xpath.xpathEval(u"//sig:X509Data/sig:X509Certificate")
        for i in range(len(certificados) - 1):
            certificados[i].unlinkNode()
            certificados[i].freeNode()

        #
        # Retransforma o documento xml em texto
        #
        xml = doc_xml.serialize()

        #
        # Libera a memória ocupada pelo documento xml manualmente
        #
        doc_xml.freeDoc()
        self._finaliza_funcoes_externas()

        xml = self._finaliza_xml(xml)

        return xml
Exemplo n.º 12
0
  def _signXML(self, xml):
    import libxml2
    import xmlsec
    dsigctx = None
    doc = None
    try:
      # initialization
      libxml2.initParser()
      libxml2.substituteEntitiesDefault(1)
      if xmlsec.init() < 0:
        raise SignatureError('xmlsec init failed')
      if xmlsec.checkVersion() != 1:
        raise SignatureError('incompatible xmlsec library version %s' %
                             str(xmlsec.checkVersion()))
      if xmlsec.cryptoAppInit(None) < 0:
        raise SignatureError('crypto initialization failed')
      if xmlsec.cryptoInit() < 0:
        raise SignatureError('xmlsec-crypto initialization failed')

      # load the input
      doc = libxml2.parseDoc(xml)
      if not doc or not doc.getRootElement():
        raise SignatureError('error parsing input xml')
      node = xmlsec.findNode(doc.getRootElement(), xmlsec.NodeSignature,
                             xmlsec.DSigNs)
      if not node:
        raise SignatureError("couldn't find root node")

      # load the private key
      key = xmlsec.cryptoAppKeyLoad(self.key_file, xmlsec.KeyDataFormatPem,
                                    self.key_pwd, None, None)
      if not key:
        raise SignatureError('failed to load the private key %s' % self.key_file)

      if xmlsec.cryptoAppKeyCertLoad(key, self.cert_file, xmlsec.KeyDataFormatPem) < 0:
        print "Error: failed to load pem certificate \"%s\"" % self.cert_file
        return self.cleanup(doc, dsigctx)

      keymngr = xmlsec.KeysMngr()
      xmlsec.cryptoAppDefaultKeysMngrInit(keymngr)
      xmlsec.cryptoAppDefaultKeysMngrAdoptKey(keymngr, key)
      dsigctx = xmlsec.DSigCtx(keymngr)

      if key.setName(self.key_file) < 0:
        raise SignatureError('failed to set key name')

      # sign
      if dsigctx.sign(node) < 0:
        raise SignatureError('signing failed')
      signed_xml = doc.serialize()

    finally:
      if dsigctx:
        dsigctx.destroy()
      if doc:
        doc.freeDoc()
      xmlsec.cryptoShutdown()
      xmlsec.shutdown()
      libxml2.cleanupParser()

    return signed_xml
Exemplo n.º 13
0
def signXml(xmlStr, key_file,cert_file, id=None ):
    init()
    result = None
    doc = libxml2.parseDoc(xmlStr)
    if doc is None or doc.getRootElement() is None:
	print "Error: unable to parse file \"%s\"" % xml_file
        cleanup(doc)
        return result

    # Create signature template for RSA-SHA1 enveloped signature
    signNode = xmlsec.TmplSignature(doc, xmlsec.transformExclC14NId(),
                                    xmlsec.transformRsaSha1Id(), id)
    #signNode.setNs('ds')
    if signNode is None:
        print "Error: failed to create signature template"
        cleanup(doc)
        return result
    
    # 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"
        cleanup(doc)
        return result

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

    # Add <dsig:KeyInfo/> and <dsig:X509Data/>
    keyInfoNode = signNode.ensureKeyInfo(None)
    if keyInfoNode is None:
        print "Error: failed to add key info"
        cleanup(doc)
        return result
    
    if keyInfoNode.addX509Data() is None:
        print "Error: failed to add X509Data node"
        cleanup(doc)
        return result

    # 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"
        cleanup(doc)
        return result

    # 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
        cleanup(doc, dsig_ctx)
        return result
    dsig_ctx.signKey = key

    # Load certificate and add to the key
    if xmlsec.cryptoAppKeyCertLoad(key, cert_file, xmlsec.KeyDataFormatPem) < 0:
        print "Error: failed to load pem certificate \"%s\"" % cert_file
        cleanup(doc, dsig_ctx)
        return result

    # 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
    #    cleanup(doc, dsig_ctx)
    #   return result

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

    # Print signed document to stdout
    #doc.dump("-")
    result = doc.serialize()
    # Success
    cleanup(doc, dsig_ctx, 1)
    return result
Exemplo n.º 14
0
  def _verifyXML(self, xml):
    import libxml2
    import xmlsec
    dsigctx = None
    doc = None
    try:
      # initialization
      libxml2.initParser()
      libxml2.substituteEntitiesDefault(1)
      if xmlsec.init() < 0:
        raise SignatureError('xmlsec init failed')
      if xmlsec.checkVersion() != 1:
        raise SignatureError('incompatible xmlsec library version %s' %
                             str(xmlsec.checkVersion()))
      if xmlsec.cryptoAppInit(None) < 0:
        raise SignatureError('crypto initialization failed')
      if xmlsec.cryptoInit() < 0:
        raise SignatureError('xmlsec-crypto initialization failed')

      # load the input
      doc = libxml2.parseDoc(xml)
      if not doc or not doc.getRootElement():
        raise SignatureError('error parsing input xml')
      node = xmlsec.findNode(doc.getRootElement(), xmlsec.NodeSignature,
                             xmlsec.DSigNs)
      if not node:
        raise SignatureError("couldn't find root node")

      dsigctx = xmlsec.DSigCtx()
         
      key = xmlsec.cryptoAppKeyLoad(self.key_file, xmlsec.KeyDataFormatPem,
                                    self.key_pwd, None, None)

      if not key:
        raise SignatureError('failed to load the private key %s' % self.key_file)
      dsigctx.signKey = key

      if key.setName(self.key_file) < 0:
        raise SignatureError('failed to set key name')

      if xmlsec.cryptoAppKeyCertLoad(key, self.cert_file, xmlsec.KeyDataFormatPem) < 0:
        print "Error: failed to load pem certificate \"%s\"" % self.cert_file
        return self.cleanup(doc, dsigctx)

      # verify
      if dsigctx.verify(node) < 0:
        raise SignatureError('verification failed')
      if dsigctx.status == xmlsec.DSigStatusSucceeded:
          self.log("Signature is OK")
          is_valid = True
      else:
          self.log("*****************  Signature is INVALID ********************")
          is_valid = False

    finally:
      if dsigctx:
        dsigctx.destroy()
      if doc:
        doc.freeDoc()
      xmlsec.cryptoShutdown()
      xmlsec.shutdown()
      libxml2.cleanupParser()

    return is_valid