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
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
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))
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
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))
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
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
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
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
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