Skip to content

Instantly share code, notes, and snippets.

@pedroburon
Created November 19, 2018 03:51
Show Gist options
  • Save pedroburon/a26eb7bf9f8c4c09a8526214d3b41cf4 to your computer and use it in GitHub Desktop.
Save pedroburon/a26eb7bf9f8c4c09a8526214d3b41cf4 to your computer and use it in GitHub Desktop.
class ZeepWsseSignature(object):
def apply(self, envelope, headers):
sign_envelope(envelope, self.key)
return envelope, headers
def verify(self, envelope):
if not verify_envelope(envelope, self.tbk_cert):
raise InvalidSignatureResponse()
return envelope
def sign_envelope(envelope, key):
# Create the Signature node.
signature = xmlsec.template.create(
envelope,
xmlsec.Transform.EXCL_C14N,
xmlsec.Transform.RSA_SHA1,
)
# Add a KeyInfo node with X509Data child to the Signature. XMLSec will fill
# in this template with the actual certificate details when it signs.
key_info = xmlsec.template.ensure_key_info(signature)
x509_data = xmlsec.template.add_x509_data(key_info)
xmlsec.template.x509_data_add_issuer_serial(x509_data)
xmlsec.template.x509_data_add_certificate(x509_data)
# Insert the Signature node in the wsse:Security header.
security = get_or_create_security_header(envelope)
security.insert(0, signature)
# Perform the actual signing.
ctx = xmlsec.SignatureContext()
ctx.key = key
sign_node(ctx, signature, envelope.find(ns(SOAP_NS, 'Body')))
ctx.sign(signature)
# Place the X509 data inside a WSSE SecurityTokenReference within
# KeyInfo. The recipient expects this structure, but we can't rearrange
# like this until after signing, because otherwise xmlsec won't populate
# the X509 data (because it doesn't understand WSSE).
sec_token_ref = create_xml_element(ns(WSSE_NS, 'SecurityTokenReference'))
sec_token_ref.append(x509_data)
key_info.append(sec_token_ref)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment