summaryrefslogtreecommitdiff
path: root/src/saml2
diff options
context:
space:
mode:
authorIvan Kanakarakis <ivan.kanak@gmail.com>2018-08-03 23:02:42 +0300
committerIvan Kanakarakis <ivan.kanak@gmail.com>2018-08-04 02:09:07 +0300
commitc3f6311651ea05347a0b308a023c4c3e8dd23469 (patch)
tree68654c5e6df02eee6f0bc30dc686206c18dc1713 /src/saml2
parentc9f4bf209816afeb525041f636c88a1fccd1cea6 (diff)
downloadpysaml2-c3f6311651ea05347a0b308a023c4c3e8dd23469.tar.gz
Allow configuration and specification of id attribute name
The id attribute name is used by xmlsec1 to find the correct attribute in the given element that contains the id of the node that will be signed. Signed-off-by: Ivan Kanakarakis <ivan.kanak@gmail.com>
Diffstat (limited to 'src/saml2')
-rw-r--r--src/saml2/config.py2
-rw-r--r--src/saml2/sigver.py43
2 files changed, 31 insertions, 14 deletions
diff --git a/src/saml2/config.py b/src/saml2/config.py
index 2631d51d..8f90afc8 100644
--- a/src/saml2/config.py
+++ b/src/saml2/config.py
@@ -66,6 +66,7 @@ COMMON_ARGS = [
"extensions",
"allow_unknown_attributes",
"crypto_backend",
+ "id_attr_name",
]
SP_ARGS = [
@@ -221,6 +222,7 @@ class Config(object):
self.name_qualifier = ""
self.entity_category = ""
self.crypto_backend = 'xmlsec1'
+ self.id_attr_name = None
self.scope = ""
self.allow_unknown_attributes = False
self.extension_schema = {}
diff --git a/src/saml2/sigver.py b/src/saml2/sigver.py
index 918a23cb..576993be 100644
--- a/src/saml2/sigver.py
+++ b/src/saml2/sigver.py
@@ -205,7 +205,6 @@ def _get_xmlsec_cryptobackend(path=None, search_paths=None):
return CryptoBackendXmlSec1(path)
-ID_ATTR = 'ID'
NODE_NAME = 'urn:oasis:names:tc:SAML:2.0:assertion:Assertion'
ENC_NODE_NAME = 'urn:oasis:names:tc:SAML:2.0:assertion:EncryptedAssertion'
ENC_KEY_CLASS = 'EncryptedKey'
@@ -653,7 +652,7 @@ class CryptoBackend(object):
def encrypt_assertion(self, statement, enc_key, template, key_type, node_xpath):
raise NotImplementedError()
- def decrypt(self, enctext, key_file):
+ def decrypt(self, enctext, key_file, id_attr):
raise NotImplementedError()
def sign_statement(self, statement, node_name, key_file, node_id, id_attr):
@@ -779,7 +778,7 @@ class CryptoBackendXmlSec1(CryptoBackend):
return output.decode()
- def decrypt(self, enctext, key_file):
+ def decrypt(self, enctext, key_file, id_attr):
"""
:param enctext: XML document containing an encrypted part
@@ -794,7 +793,7 @@ class CryptoBackendXmlSec1(CryptoBackend):
self.xmlsec,
'--decrypt',
'--privkey-pem', key_file,
- '--id-attr:{id_attr}'.format(id_attr=ID_ATTR),
+ '--id-attr:{id_attr}'.format(id_attr=id_attr),
ENC_KEY_CLASS,
]
@@ -1011,6 +1010,11 @@ def security_context(conf):
except AttributeError:
metadata = None
+ try:
+ id_attr = conf.id_attr_name
+ except AttributeError:
+ id_attr = None
+
sec_backend = None
if conf.crypto_backend == 'xmlsec1':
@@ -1069,7 +1073,8 @@ def security_context(conf):
validate_certificate=conf.validate_certificate,
enc_key_files=enc_key_files,
encryption_keypairs=conf.encryption_keypairs,
- sec_backend=sec_backend)
+ sec_backend=sec_backend,
+ id_attr=id_attr)
def encrypt_cert_from_item(item):
@@ -1239,6 +1244,7 @@ class CertHandler(object):
# openssl x509 -inform pem -noout -in server.crt -pubkey > publickey.pem
# openssl rsa -inform pem -noout -in publickey.pem -pubin -modulus
class SecurityContext(object):
+ DEFAULT_ID_ATTR_NAME = 'ID'
my_cert = None
def __init__(
@@ -1257,7 +1263,10 @@ class SecurityContext(object):
enc_key_files=None, enc_key_type='pem',
encryption_keypairs=None,
enc_cert_type='pem',
- sec_backend=None):
+ sec_backend=None,
+ id_attr=''):
+
+ self.id_attr = id_attr or SecurityContext.DEFAULT_ID_ATTR_NAME
self.crypto = crypto
assert (isinstance(self.crypto, CryptoBackend))
@@ -1348,7 +1357,7 @@ class SecurityContext(object):
return self.crypto.encrypt_assertion(
statement, enc_key, template, key_type, node_xpath)
- def decrypt_keys(self, enctext, keys=None):
+ def decrypt_keys(self, enctext, keys=None, id_attr=''):
""" Decrypting an encrypted text by the use of a private key.
:param enctext: The encrypted text as a string
@@ -1356,12 +1365,15 @@ class SecurityContext(object):
"""
_enctext = None
+ if not id_attr:
+ id_attr = self.id_attr
+
if not isinstance(keys, list):
keys = [keys]
if self.enc_key_files is not None:
for _enc_key_file in self.enc_key_files:
- _enctext = self.crypto.decrypt(enctext, _enc_key_file)
+ _enctext = self.crypto.decrypt(enctext, _enc_key_file, id_attr)
if _enctext is not None and len(_enctext) > 0:
return _enctext
@@ -1370,13 +1382,13 @@ class SecurityContext(object):
if not isinstance(_key, six.binary_type):
_key = str(_key).encode('ascii')
_, key_file = make_temp(_key, decode=False)
- _enctext = self.crypto.decrypt(enctext, key_file)
+ _enctext = self.crypto.decrypt(enctext, key_file, id_attr)
if _enctext is not None and len(_enctext) > 0:
return _enctext
return enctext
- def decrypt(self, enctext, key_file=None):
+ def decrypt(self, enctext, key_file=None, id_attr=''):
""" Decrypting an encrypted text by the use of a private key.
:param enctext: The encrypted text as a string
@@ -1384,14 +1396,17 @@ class SecurityContext(object):
"""
_enctext = None
+ if not id_attr:
+ id_attr = self.id_attr
+
if self.enc_key_files is not None:
for _enc_key_file in self.enc_key_files:
- _enctext = self.crypto.decrypt(enctext, _enc_key_file)
+ _enctext = self.crypto.decrypt(enctext, _enc_key_file, id_attr)
if _enctext is not None and len(_enctext) > 0:
return _enctext
if key_file is not None and len(key_file.strip()) > 0:
- _enctext = self.crypto.decrypt(enctext, key_file)
+ _enctext = self.crypto.decrypt(enctext, key_file, id_attr)
if _enctext is not None and len(_enctext) > 0:
return _enctext
@@ -1415,7 +1430,7 @@ class SecurityContext(object):
cert_type = self.cert_type
if not id_attr:
- id_attr = ID_ATTR
+ id_attr = self.id_attr
return self.crypto.validate_signature(
signedtext,
@@ -1650,7 +1665,7 @@ class SecurityContext(object):
:return: The signed statement
"""
if not id_attr:
- id_attr = ID_ATTR
+ id_attr = self.id_attr
if not key_file and key:
_, key_file = make_temp(str(key).encode(), '.pem')