|
@@ -650,10 +650,10 @@ class CryptoBackend(object):
|
|
|
def encrypt_assertion(self, statement, enc_key, template, key_type, node_xpath):
|
|
def encrypt_assertion(self, statement, enc_key, template, key_type, node_xpath):
|
|
|
raise NotImplementedError()
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
- def decrypt(self, enctext, key_file, id_attr):
|
|
|
|
|
|
|
+ def decrypt(self, enctext, key_file, id_attr, passphrase=None):
|
|
|
raise NotImplementedError()
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
- def sign_statement(self, statement, node_name, key_file, node_id, id_attr):
|
|
|
|
|
|
|
+ def sign_statement(self, statement, node_name, key_file, node_id, id_attr, passphrase=None):
|
|
|
raise NotImplementedError()
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
def validate_signature(self, enctext, cert_file, cert_type, node_name, node_id, id_attr):
|
|
def validate_signature(self, enctext, cert_file, cert_type, node_name, node_id, id_attr):
|
|
@@ -953,7 +953,7 @@ class CryptoBackendXMLSecurity(CryptoBackend):
|
|
|
# better than static 0.0 here.
|
|
# better than static 0.0 here.
|
|
|
return 'XMLSecurity 0.0'
|
|
return 'XMLSecurity 0.0'
|
|
|
|
|
|
|
|
- def sign_statement(self, statement, node_name, key_file, node_id, id_attr):
|
|
|
|
|
|
|
+ def sign_statement(self, statement, node_name, key_file, node_id, id_attr, passphrase=None):
|
|
|
"""
|
|
"""
|
|
|
Sign an XML statement.
|
|
Sign an XML statement.
|
|
|
|
|
|
|
@@ -969,6 +969,8 @@ class CryptoBackendXMLSecurity(CryptoBackend):
|
|
|
import xmlsec
|
|
import xmlsec
|
|
|
import lxml.etree
|
|
import lxml.etree
|
|
|
|
|
|
|
|
|
|
+ assert passphrase is None, "Encrypted key files is not supported"
|
|
|
|
|
+
|
|
|
xml = xmlsec.parse_xml(statement)
|
|
xml = xmlsec.parse_xml(statement)
|
|
|
signed = xmlsec.sign(xml, key_file)
|
|
signed = xmlsec.sign(xml, key_file)
|
|
|
signed_str = lxml.etree.tostring(signed, xml_declaration=False, encoding="UTF-8")
|
|
signed_str = lxml.etree.tostring(signed, xml_declaration=False, encoding="UTF-8")
|
|
@@ -1077,6 +1079,7 @@ def security_context(conf):
|
|
|
tmp_cert_file=conf.tmp_cert_file,
|
|
tmp_cert_file=conf.tmp_cert_file,
|
|
|
tmp_key_file=conf.tmp_key_file,
|
|
tmp_key_file=conf.tmp_key_file,
|
|
|
validate_certificate=conf.validate_certificate,
|
|
validate_certificate=conf.validate_certificate,
|
|
|
|
|
+ key_file_passphrase=conf.key_file_passphrase,
|
|
|
enc_key_files=enc_key_files,
|
|
enc_key_files=enc_key_files,
|
|
|
encryption_keypairs=conf.encryption_keypairs,
|
|
encryption_keypairs=conf.encryption_keypairs,
|
|
|
sec_backend=sec_backend,
|
|
sec_backend=sec_backend,
|
|
@@ -1267,6 +1270,7 @@ class SecurityContext(object):
|
|
|
generate_cert_info=None,
|
|
generate_cert_info=None,
|
|
|
tmp_cert_file=None, tmp_key_file=None,
|
|
tmp_cert_file=None, tmp_key_file=None,
|
|
|
validate_certificate=None,
|
|
validate_certificate=None,
|
|
|
|
|
+ key_file_passphrase=None,
|
|
|
enc_key_files=None, enc_key_type='pem',
|
|
enc_key_files=None, enc_key_type='pem',
|
|
|
encryption_keypairs=None,
|
|
encryption_keypairs=None,
|
|
|
enc_cert_type='pem',
|
|
enc_cert_type='pem',
|
|
@@ -1285,6 +1289,7 @@ class SecurityContext(object):
|
|
|
|
|
|
|
|
# Your private key for signing
|
|
# Your private key for signing
|
|
|
self.key_file = key_file
|
|
self.key_file = key_file
|
|
|
|
|
+ self.key_file_passphrase = key_file_passphrase
|
|
|
self.key_type = key_type
|
|
self.key_type = key_type
|
|
|
|
|
|
|
|
# Your public key for signing
|
|
# Your public key for signing
|
|
@@ -1371,6 +1376,7 @@ class SecurityContext(object):
|
|
|
:return: The decrypted text
|
|
:return: The decrypted text
|
|
|
"""
|
|
"""
|
|
|
key_files = []
|
|
key_files = []
|
|
|
|
|
+ passphrase = self.key_file_passphrase
|
|
|
|
|
|
|
|
if not isinstance(keys, list):
|
|
if not isinstance(keys, list):
|
|
|
keys = [keys]
|
|
keys = [keys]
|
|
@@ -1387,7 +1393,7 @@ class SecurityContext(object):
|
|
|
key_file_names = list(tmp.name for tmp in key_files)
|
|
key_file_names = list(tmp.name for tmp in key_files)
|
|
|
|
|
|
|
|
try:
|
|
try:
|
|
|
- dectext = self.decrypt(enctext, key_file=key_file_names, id_attr=id_attr)
|
|
|
|
|
|
|
+ dectext = self.decrypt(enctext, key_file=key_file_names, id_attr=id_attr, passphrase=passphrase)
|
|
|
except DecryptError as e:
|
|
except DecryptError as e:
|
|
|
raise
|
|
raise
|
|
|
else:
|
|
else:
|
|
@@ -1415,7 +1421,7 @@ class SecurityContext(object):
|
|
|
]
|
|
]
|
|
|
for key_file in key_files:
|
|
for key_file in key_files:
|
|
|
try:
|
|
try:
|
|
|
- dectext = self.crypto.decrypt(enctext, key_file, id_attr)
|
|
|
|
|
|
|
+ dectext = self.crypto.decrypt(enctext, key_file, id_attr, passphrase=passphrase)
|
|
|
except XmlsecError as e:
|
|
except XmlsecError as e:
|
|
|
continue
|
|
continue
|
|
|
else:
|
|
else:
|
|
@@ -1714,7 +1720,7 @@ class SecurityContext(object):
|
|
|
""" Deprecated function. See sign_statement(). """
|
|
""" Deprecated function. See sign_statement(). """
|
|
|
return self.sign_statement(statement, **kwargs)
|
|
return self.sign_statement(statement, **kwargs)
|
|
|
|
|
|
|
|
- def sign_statement(self, statement, node_name, key=None, key_file=None, node_id=None, id_attr=''):
|
|
|
|
|
|
|
+ def sign_statement(self, statement, node_name, key=None, key_file=None, node_id=None, id_attr='', passphrase=None):
|
|
|
"""Sign a SAML statement.
|
|
"""Sign a SAML statement.
|
|
|
|
|
|
|
|
:param statement: The statement to be signed
|
|
:param statement: The statement to be signed
|
|
@@ -1737,12 +1743,17 @@ class SecurityContext(object):
|
|
|
if not key and not key_file:
|
|
if not key and not key_file:
|
|
|
key_file = self.key_file
|
|
key_file = self.key_file
|
|
|
|
|
|
|
|
|
|
+ if not passphrase:
|
|
|
|
|
+ passphrase = self.key_file_passphrase
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
return self.crypto.sign_statement(
|
|
return self.crypto.sign_statement(
|
|
|
statement,
|
|
statement,
|
|
|
node_name,
|
|
node_name,
|
|
|
key_file,
|
|
key_file,
|
|
|
node_id,
|
|
node_id,
|
|
|
- id_attr)
|
|
|
|
|
|
|
+ id_attr,
|
|
|
|
|
+ passphrase=passphrase)
|
|
|
|
|
|
|
|
def sign_assertion_using_xmlsec(self, statement, **kwargs):
|
|
def sign_assertion_using_xmlsec(self, statement, **kwargs):
|
|
|
""" Deprecated function. See sign_assertion(). """
|
|
""" Deprecated function. See sign_assertion(). """
|
|
@@ -1775,7 +1786,7 @@ class SecurityContext(object):
|
|
|
return self.sign_statement(
|
|
return self.sign_statement(
|
|
|
statement, class_name(samlp.AttributeQuery()), **kwargs)
|
|
statement, class_name(samlp.AttributeQuery()), **kwargs)
|
|
|
|
|
|
|
|
- def multiple_signatures(self, statement, to_sign, key=None, key_file=None, sign_alg=None, digest_alg=None):
|
|
|
|
|
|
|
+ def multiple_signatures(self, statement, to_sign, key=None, key_file=None, sign_alg=None, digest_alg=None, passphrase=None):
|
|
|
"""
|
|
"""
|
|
|
Sign multiple parts of a statement
|
|
Sign multiple parts of a statement
|
|
|
|
|
|
|
@@ -1806,7 +1817,8 @@ class SecurityContext(object):
|
|
|
key=key,
|
|
key=key,
|
|
|
key_file=key_file,
|
|
key_file=key_file,
|
|
|
node_id=sid,
|
|
node_id=sid,
|
|
|
- id_attr=id_attr)
|
|
|
|
|
|
|
+ id_attr=id_attr,
|
|
|
|
|
+ passphrase=passphrase)
|
|
|
|
|
|
|
|
return statement
|
|
return statement
|
|
|
|
|
|