Documentation.

This commit is contained in:
Fredrik Thulin
2013-03-11 15:37:05 +01:00
parent 269909acc0
commit 593d35cb6a

View File

@@ -646,6 +646,10 @@ class CryptoBackend():
class CryptoBackendXmlSec1(CryptoBackend):
"""
CryptoBackend implementation using external binary xmlsec1 to sign
and verify XML documents.
"""
__DEBUG = 0
@@ -680,6 +684,17 @@ class CryptoBackendXmlSec1(CryptoBackend):
def sign_statement(self, statement, class_name, key_file, node_id,
id_attr):
"""
Sign an XML statement.
:param statement: The statement to be signed
:param class_name: string like 'urn:oasis:names:...:Assertion'
:param key_file: The file where the key can be found
:param node_id:
:param id_attr: The attribute name for the identifier, normally one of
'id','Id' or 'ID'
:return: The signed statement
"""
_, fil = make_temp("%s" % statement, decode=False)
@@ -705,9 +720,20 @@ class CryptoBackendXmlSec1(CryptoBackend):
except DecryptError:
raise Exception("Signing failed")
def validate_signature(self, enctext, cert_file, cert_type, node_name,
def validate_signature(self, signedtext, cert_file, cert_type, node_name,
node_id, id_attr):
_, fil = make_temp(enctext, decode=False)
"""
Validate signature on XML document.
:param signedtext: The XML document as a string
:param cert_file: The public key that was used to sign the document
:param cert_type: The file type of the certificate
:param node_name: The name of the class that is signed
:param node_id: The identifier of the node
:param id_attr: Should normally be one of "id", "Id" or "ID"
:return: Boolean True if the signature was correct otherwise False.
"""
_, fil = make_temp(signedtext, decode=False)
com_list = [self.xmlsec, "--verify",
"--pubkey-cert-%s" % cert_type, cert_file,
@@ -767,25 +793,63 @@ class CryptoBackendXmlSec1(CryptoBackend):
return p_out, p_err, ntf.read()
class CryptoBackendXMLSecurity(CryptoBackend):
"""
CryptoBackend implementation using pyXMLSecurity to sign and verify
XML documents.
Encrypt and decrypt is currently unsupported by pyXMLSecurity.
pyXMLSecurity uses lxml (libxml2) to parse XML data, but otherwise
try to get by with native Python code. It does native Python RSA
signatures, or alternatively PyKCS11 to offload cryptographic work
to an external PKCS#11 module.
"""
def __init__(self, debug=False):
CryptoBackend.__init__(self)
self.debug = debug
def sign_statement(self, statement, _class_name, key_file, _nodeid,
_id_attr):
"""
Sign an XML statement.
The parameters actually used in this CryptoBackend
implementation are :
:param statement: XML as string
:param key_file: xmlsec key_spec string(), filename,
"pkcs11://" URI or PEM data
:returns: Signed XML as string
"""
import xmlsec
import lxml.etree
xml = xmlsec.parse_xml(statement)
signed = xmlsec.sign(xml, key_file)
return lxml.etree.tostring(signed, xml_declaration=True)
def validate_signature(self, enctext, cert_file, cert_type, _node_name,
def validate_signature(self, signedtext, cert_file, cert_type, _node_name,
_node_id, _id_attr):
"""
Validate signature on XML document.
The parameters actually used in this CryptoBackend
implementation are :
:param signedtext: The signed XML data as string
:param cert_file: xmlsec key_spec string(), filename,
"pkcs11://" URI or PEM data
:param cert_type: string, must be 'pem' for now
:returns: True on successful validation, False otherwise
"""
if cert_type != "pem":
raise Unsupported("Only PEM certs supported here")
import xmlsec
xml = xmlsec.parse_xml(enctext)
return xmlsec.verify(xml, cert_file)
xml = xmlsec.parse_xml(signedtext)
try:
return xmlsec.verify(xml, cert_file)
except xmlsec.XMLSigException:
return False
def security_context(conf, debug=None):
""" Creates a security context based on the configuration
@@ -843,7 +907,7 @@ class SecurityContext(object):
else:
self.template = template
self.key_type = encrypt_key_type
self.encrypt_key_type = encrypt_key_type
def correctly_signed(self, xml, must=False):
logger.info("verify correct signature")
@@ -862,7 +926,7 @@ class SecurityContext(object):
:result: An encrypted XML text
"""
if not key_type:
key_type = self.key_type
key_type = self.encrypt_key_type
if not template:
template = self.template
@@ -876,11 +940,11 @@ class SecurityContext(object):
"""
return self.crypto.decrypt(enctext, self.key_file)
def verify_signature(self, enctext, cert_file=None, cert_type="pem",
def verify_signature(self, signedtext, cert_file=None, cert_type="pem",
node_name=NODE_NAME, node_id=None, id_attr=""):
""" Verifies the signature of a XML document.
:param enctext: The XML document as a string
:param signedtext: The XML document as a string
:param cert_file: The public key that was used to sign the document
:param cert_type: The file type of the certificate
:param node_name: The name of the class that is signed
@@ -894,7 +958,7 @@ class SecurityContext(object):
cert_file = self.cert_file
cert_type = self.cert_type
return verify_signature(enctext, self.crypto, cert_file, cert_type,
return verify_signature(signedtext, self.crypto, cert_file, cert_type,
node_name, self.debug, node_id, id_attr)
def _check_signature(self, decoded_xml, item, node_name=NODE_NAME,
@@ -971,9 +1035,9 @@ class SecurityContext(object):
the entity that sent the info use that, if not use the key that are in
the message if any.
:param decoded_xml:
:param decoded_xml: The SAML message as a XML string
:param msgtype:
:param must:
:param must: Whether there must be a signature
:param origdoc:
:return:
"""
@@ -1087,6 +1151,7 @@ class SecurityContext(object):
:param decoded_xml: The SAML message as a XML string
:param must: Whether there must be a signature
:param origdoc:
:return: None if the signature can not be verified otherwise an instance
"""
@@ -1130,8 +1195,10 @@ class SecurityContext(object):
"""Sign a SAML statement.
:param statement: The statement to be signed
:param class_name: string like 'urn:oasis:names:...:Assertion'
:param key: The key to be used for the signing, either this or
:param key_file: The file where the key can be found
:param node_id:
:param id_attr: The attribute name for the identifier, normally one of
'id','Id' or 'ID'
:return: The signed statement
@@ -1218,6 +1285,7 @@ def pre_signature_part(ident, public_key=None, identifier=None):
:param ident: The identifier of the assertion, so you know which assertion
was signed
:param public_key: The base64 part of a PEM file
:param identifier:
:return: A preset signature part
"""