def encode(self, template): """ Signs the message. """ if not isinstance(template, basestring): raise Exception('This codec requires a string') pemcert = self.getProperty('signing_certificate') if not pemcert: pemcert = DEFAULT_SIGNING_CERTIFICATE pemkey = self.getProperty('signing_key') if not pemkey: pemkey = DEFAULT_SIGNING_PRIVATE_KEY cert, ski = SoapSecurity.loadCertFromPem(pemcert) privkey = SoapSecurity.loadKeyFromPem(pemkey) self.log("Signing certificate & private keys loaded") doc = libxml2.parseDoc(template) # Sign the body only xpc = doc.xpathNewContext() xpc.xpathRegisterNs("soap", SoapSecurity.NS_SOAP) tbs = xpc.xpathEval("/soap:Envelope/soap:Body") signedMessage = SoapSecurity.signMessage(doc, cert, privkey, tbsElements = tbs) self.log("Message signed") root = signedMessage.getRootElement() self.log("Serializing signed message") encoding = self.getProperty('encoding', 'utf-8') ret = '' if self.getProperty('write_prolog', True): ret = '<?xml version="1.0" encoding="%s"?>\n' % encoding ret += root.serialize(encoding = encoding, format = (self.getProperty('prettyprint', False) and 1 or 0)) return (ret, "Signed XML data")
def decode(self, data): """ Verifies a signature. """ doc = libxml2.parseDoc(data) certificates = self.getProperty("expected_certificates", [ DEFAULT_SIGNING_CERTIFICATE ]) certificatesDb = {} for c in certificates: cert, ski = SoapSecurity.loadCertFromPem(c) certificatesDb[ski] = cert cert = SoapSecurity.verifyMessage(doc, certificatesDb = certificatesDb) if not cert: raise Exception("This message has not been signed by the claimed party.") ret = {} ret['message'] = data ret['signedBy'] = ('certificate', cert.as_pem().strip()) return (ret, "XML data verified as signed by '%s'" % cert.get_subject().as_text())