Added more exception handling and some documentation

This commit is contained in:
Roland Hedberg
2011-04-16 22:07:53 +02:00
parent 76cc555239
commit d2f4d731ad

View File

@@ -289,13 +289,19 @@ def _parse_xmlsec_output(output):
__DEBUG = 0 __DEBUG = 0
def verify_signature(enctext, xmlsec_binary, cert_file=None, cert_type="pem", def verify_signature(enctext, xmlsec_binary, cert_file=None, cert_type="pem",
node_name=NODE_NAME, debug=False, node_id=None): node_name=NODE_NAME, debug=False, node_id=None,
log=None):
""" Verifies the signature of a XML document. """ Verifies the signature of a XML document.
:param enctext: The signed XML document
:param xmlsec_binary: The xmlsec1 binaries to be used :param xmlsec_binary: The xmlsec1 binaries to be used
:param input: The XML document as a string :param cert_file: The public key used to decrypt the signature
:param der_file: The public key that was used to sign the document :param cert_type: The cert format
:return: Boolean True if the signature was correct otherwise False. :param node_name: The SAML class of the root node in the signed document
:param debug: To debug or not
:param node_id: The identifier of the root node if any
:return: The signed document if all was OK otherwise will raise an
exception.
""" """
_, fil = make_temp(enctext, decode=False) _, fil = make_temp(enctext, decode=False)
@@ -330,6 +336,12 @@ def verify_signature(enctext, xmlsec_binary, cert_file=None, cert_type="pem",
try: try:
verified = _parse_xmlsec_output(pof.stderr.read()) verified = _parse_xmlsec_output(pof.stderr.read())
except XmlsecError, exc: except XmlsecError, exc:
if log:
log.error(60*"=")
log.error(p_out)
log.error(60*"-")
log.error("%s" % exc)
log.error(60*"=")
raise SignatureError("%s" % (exc,)) raise SignatureError("%s" % (exc,))
return verified return verified
@@ -337,6 +349,13 @@ def verify_signature(enctext, xmlsec_binary, cert_file=None, cert_type="pem",
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
def read_cert_from_file(cert_file, cert_type): def read_cert_from_file(cert_file, cert_type):
""" Reads a certificate from a file. The assumption is that there is
only one certificate in the file
:param cert_file: The name of the file
:param cert_type: The certificate type
:return: A base64 encoded certificate as a string or the empty string
"""
if not cert_file: if not cert_file:
return "" return ""
@@ -353,15 +372,25 @@ def read_cert_from_file(cert_file, cert_type):
else: else:
raise Exception("Strange end of PEM file") raise Exception("Strange end of PEM file")
return "".join(line) return "".join(line)
if cert_type in ["der", "cer", "crt"]: if cert_type in ["der", "cer", "crt"]:
data = open(cert_file).read() data = open(cert_file).read()
return base64.b64encode(data) return base64.b64encode(data)
def security_context(conf, log=None): def security_context(conf, log=None, debug=None):
""" Creates a security context based on the configuration
:param conf: The configuration
:param log: A logger if different from the one specified in the
configuration
:return: A SecurityContext instance
"""
if not conf: if not conf:
return None return None
debug = conf.debug if debug is None:
debug = conf.debug
metadata = conf.metadata metadata = conf.metadata
return SecurityContext(conf.xmlsec_binary, conf.key_file, "pem", return SecurityContext(conf.xmlsec_binary, conf.key_file, "pem",
@@ -372,6 +401,7 @@ class SecurityContext(object):
def __init__(self, xmlsec_binary, key_file="", key_type= "pem", def __init__(self, xmlsec_binary, key_file="", key_type= "pem",
cert_file="", cert_type="pem", metadata=None, log=None, cert_file="", cert_type="pem", metadata=None, log=None,
debug=False): debug=False):
self.xmlsec = xmlsec_binary self.xmlsec = xmlsec_binary
# Your private key # Your private key
@@ -473,13 +503,19 @@ class SecurityContext(object):
verified = False verified = False
for _, pem_file in certs: for _, pem_file in certs:
#print "=========================================================" try:
#print open(pem_file).read() if self.verify_signature(decoded_xml, pem_file, "pem", node_name,
#print "========================================================="
if self.verify_signature(decoded_xml, pem_file, "pem", node_name,
item.id): item.id):
verified = True verified = True
break break
except XmlsecError, exc:
if self.log:
self.log.error("check_sig: %s" % exc)
pass
except Exception, exc:
if self.log:
self.log.error("check_sig: %s" % exc)
raise
if not verified: if not verified:
raise SignatureError("Failed to verify signature") raise SignatureError("Failed to verify signature")
@@ -584,11 +620,17 @@ class SecurityContext(object):
if self.debug: if self.debug:
self.log.debug("signed") self.log.debug("signed")
self._check_signature(decoded_xml, assertion, try:
class_name(assertion)) self._check_signature(decoded_xml, assertion,
class_name(assertion))
except Exception, exc:
if self.log:
self.log.error("correctly_signed_response: %s" % exc)
raise
return response return response
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# SIGNATURE PART # SIGNATURE PART
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
@@ -757,4 +799,3 @@ def pre_signature_part(ident, public_key=None, identifier=None):
signature.key_info = key_info signature.key_info = key_info
return signature return signature