Skip to content

Commit

Permalink
Merge pull request #550 from johanlundberg/non_ascii_ava_encryption_d…
Browse files Browse the repository at this point in the history
…ecryption

Support non-ascii attribute values for encryption and decryption
  • Loading branch information
c00kiemon5ter committed Oct 10, 2018
2 parents c5c7e2d + 35fc1dc commit 691e981
Show file tree
Hide file tree
Showing 6 changed files with 2,976 additions and 94 deletions.
11 changes: 6 additions & 5 deletions src/saml2/response.py
@@ -1,10 +1,11 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#

from future.utils import python_2_unicode_compatible
import calendar
import logging
import six

from saml2.samlp import STATUS_VERSION_MISMATCH
from saml2.samlp import STATUS_AUTHN_FAILED
from saml2.samlp import STATUS_INVALID_ATTR_NAME_OR_VALUE
Expand Down Expand Up @@ -460,7 +461,7 @@ def __init__(self, sec_context, return_addrs=None, timeslack=0,

# ----------------------------------------------------------------------------


@python_2_unicode_compatible
class AuthnResponse(StatusResponse):
""" This is where all the profile compliance is checked.
This one does saml2int compliance. """
Expand Down Expand Up @@ -1081,9 +1082,9 @@ def session_info(self):
"session_index": authn_statement.session_index}

def __str__(self):
if not isinstance(self.xmlstr, six.string_types):
return "%s" % self.xmlstr.decode("utf-8")
return "%s" % self.xmlstr
if isinstance(self.xmlstr, six.string_types):
return self.xmlstr
return str(self.xmlstr)

def verify_recipient(self, recipient):
"""
Expand Down
2 changes: 1 addition & 1 deletion src/saml2/saml.py
Expand Up @@ -171,7 +171,7 @@ def _wrong_type_value(xsd, value):
# only work with six.string_types
_str = unicode if six.PY2 else str
if isinstance(value, six.binary_type):
value = value.decode()
value = value.decode('utf-8')

type_to_xsd = {
_str: 'string',
Expand Down
28 changes: 16 additions & 12 deletions src/saml2/sigver.py
Expand Up @@ -310,7 +310,9 @@ def signed_instance_factory(instance, seccont, elements_to_sign=None):
:return: A class instance if not signed otherwise a string
"""
if elements_to_sign:
signed_xml = str(instance)
signed_xml = instance
if not isinstance(instance, six.string_types):
signed_xml = instance.to_string()
for (node_name, nodeid) in elements_to_sign:
signed_xml = seccont.sign_statement(
signed_xml, node_name=node_name, node_id=nodeid)
Expand All @@ -336,7 +338,7 @@ def make_temp(string, suffix='', decode=True, delete=True):
ntf = NamedTemporaryFile(suffix=suffix, delete=delete)
# Python3 tempfile requires byte-like object
if not isinstance(string, six.binary_type):
string = string.encode()
string = string.encode('utf-8')

if decode:
ntf.write(base64.b64decode(string))
Expand Down Expand Up @@ -712,7 +714,7 @@ def encrypt(self, text, recv_key, template, session_key_type, xpath=''):
:return:
"""
logger.debug('Encryption input len: %d', len(text))
_, fil = make_temp(str(text).encode(), decode=False)
_, fil = make_temp(text, decode=False)

com_list = [
self.xmlsec,
Expand Down Expand Up @@ -743,13 +745,17 @@ def encrypt_assertion(self, statement, enc_key, template, key_type='des-192', no
:param key_type: The type of session key to use.
:return: The encrypted text
"""
if six.PY2:
_str = unicode
else:
_str = str

if isinstance(statement, SamlBase):
statement = pre_encrypt_assertion(statement)

_, fil = make_temp(str(statement).encode(), decode=False,
_, fil = make_temp(_str(statement), decode=False,
delete=False)
_, tmpl = make_temp(str(template).encode(), decode=False)
_, tmpl = make_temp(_str(template), decode=False)

if not node_xpath:
node_xpath = ASSERT_XPATH
Expand All @@ -776,7 +782,7 @@ def encrypt_assertion(self, statement, enc_key, template, key_type='des-192', no
if not output:
raise EncryptError(_stderr)

return output.decode()
return output.decode('utf-8')

def decrypt(self, enctext, key_file, id_attr):
"""
Expand All @@ -787,7 +793,7 @@ def decrypt(self, enctext, key_file, id_attr):
"""

logger.debug('Decrypt input len: %d', len(enctext))
_, fil = make_temp(str(enctext).encode(), decode=False)
_, fil = make_temp(enctext, decode=False)

com_list = [
self.xmlsec,
Expand All @@ -802,8 +808,7 @@ def decrypt(self, enctext, key_file, id_attr):
[fil],
exception=DecryptError,
validate_output=False)

return output.decode()
return output.decode('utf-8')

def sign_statement(self, statement, node_name, key_file, node_id, id_attr):
"""
Expand Down Expand Up @@ -846,7 +851,7 @@ def sign_statement(self, statement, node_name, key_file, node_id, id_attr):
# this doesn't work if --store-signatures are used
if stdout == '':
if signed_statement:
return signed_statement.decode()
return signed_statement.decode('utf-8')

logger.error('Signing operation failed :\nstdout : %s\nstderr : %s', stdout, stderr)
raise SigverError(stderr)
Expand All @@ -866,7 +871,7 @@ def validate_signature(self, signedtext, cert_file, cert_type, node_name, node_i
:return: Boolean True if the signature was correct otherwise False.
"""
if not isinstance(signedtext, six.binary_type):
signedtext = signedtext.encode()
signedtext = signedtext.encode('utf-8')

_, fil = make_temp(
signedtext,
Expand Down Expand Up @@ -1409,7 +1414,6 @@ def decrypt(self, enctext, key_file=None, id_attr=''):
_enctext = self.crypto.decrypt(enctext, key_file, id_attr)
if _enctext is not None and len(_enctext) > 0:
return _enctext

return enctext

def verify_signature(self, signedtext, cert_file=None, cert_type='pem', node_name=NODE_NAME, node_id=None, id_attr=''):
Expand Down

0 comments on commit 691e981

Please sign in to comment.