Skip to content

Commit 596803a

Browse files
Merge pull request #902 from timofey-barmin/xmlsec1_1_3_support
Add support for xmlsec1 1.3
2 parents 94ffddf + 6aaf1ec commit 596803a

File tree

2 files changed

+57
-19
lines changed

2 files changed

+57
-19
lines changed

src/saml2/sigver.py

+33-11
Original file line numberDiff line numberDiff line change
@@ -471,18 +471,25 @@ def import_rsa_key_from_file(filename):
471471
return key
472472

473473

474-
def parse_xmlsec_output(output):
474+
def parse_xmlsec_verify_output(output, version=None):
475475
"""Parse the output from xmlsec to try to find out if the
476476
command was successfull or not.
477477
478478
:param output: The output from Popen
479479
:return: A boolean; True if the command was a success otherwise False
480480
"""
481-
for line in output.splitlines():
482-
if line == "OK":
483-
return True
484-
elif line == "FAIL":
485-
raise XmlsecError(output)
481+
if version is None or version < (1, 3):
482+
for line in output.splitlines():
483+
if line == "OK":
484+
return True
485+
elif line == "FAIL":
486+
raise XmlsecError(output)
487+
else:
488+
for line in output.splitlines():
489+
if line == 'Verification status: OK':
490+
return True
491+
elif line == 'Verification status: FAILED':
492+
raise XmlsecError(output)
486493
raise XmlsecError(output)
487494

488495

@@ -593,9 +600,18 @@ def verify_redirect_signature(saml_msg, crypto, cert=None, sigkey=None):
593600

594601

595602
class CryptoBackend:
603+
@property
596604
def version(self):
597605
raise NotImplementedError()
598606

607+
@property
608+
def version_nums(self):
609+
try:
610+
vns = tuple(int(t) for t in self.version)
611+
except ValueError:
612+
vns = (0, 0, 0)
613+
return vns
614+
599615
def encrypt(self, text, recv_key, template, key_type):
600616
raise NotImplementedError()
601617

@@ -634,6 +650,7 @@ def __init__(self, xmlsec_binary, delete_tmpfiles=True, **kwargs):
634650
except KeyError:
635651
pass
636652

653+
@property
637654
def version(self):
638655
com_list = [self.xmlsec, "--version"]
639656
pof = Popen(com_list, stderr=PIPE, stdout=PIPE)
@@ -642,7 +659,7 @@ def version(self):
642659
try:
643660
return content.split(" ")[1]
644661
except IndexError:
645-
return ""
662+
return "0.0.0"
646663

647664
def encrypt(self, text, recv_key, template, session_key_type, xpath=""):
648665
"""
@@ -824,7 +841,7 @@ def validate_signature(self, signedtext, cert_file, cert_type, node_name, node_i
824841
except XmlsecError as e:
825842
raise SignatureError(com_list) from e
826843

827-
return parse_xmlsec_output(stderr)
844+
return parse_xmlsec_verify_output(stderr, self.version_nums)
828845

829846
def _run_xmlsec(self, com_list, extra_args):
830847
"""
@@ -836,6 +853,8 @@ def _run_xmlsec(self, com_list, extra_args):
836853
"""
837854
with NamedTemporaryFile(suffix=".xml") as ntf:
838855
com_list.extend(["--output", ntf.name])
856+
if self.version_nums >= (1, 3):
857+
com_list.extend(['--lax-key-search'])
839858
com_list += extra_args
840859

841860
logger.debug("xmlsec command: %s", " ".join(com_list))
@@ -870,10 +889,13 @@ class CryptoBackendXMLSecurity(CryptoBackend):
870889
def __init__(self):
871890
CryptoBackend.__init__(self)
872891

892+
@property
873893
def version(self):
874-
# XXX if XMLSecurity.__init__ included a __version__, that would be
875-
# better than static 0.0 here.
876-
return "XMLSecurity 0.0"
894+
try:
895+
import xmlsec
896+
return xmlsec.__version__
897+
except (ImportError, AttributeError):
898+
return "0.0.0"
877899

878900
def sign_statement(self, statement, node_name, key_file, node_id):
879901
"""

tests/test_40_sigver.py

+24-8
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ def test_sign_assertion(self):
192192
assert sass.id == "id-11111"
193193
assert time_util.str_to_time(sass.issue_instant)
194194

195-
print(f"Crypto version : {self.sec.crypto.version()}")
195+
print(f"Crypto version : {self.sec.crypto.version}")
196196

197197
item = self.sec.check_signature(sass, class_name(sass), sign_ass)
198198

@@ -209,7 +209,7 @@ def test_multiple_signatures_assertion(self):
209209
assert sass.id == "id-11111"
210210
assert time_util.str_to_time(sass.issue_instant)
211211

212-
print(f"Crypto version : {self.sec.crypto.version()}")
212+
print(f"Crypto version : {self.sec.crypto.version}")
213213

214214
item = self.sec.check_signature(sass, class_name(sass), sign_ass, must=True)
215215

@@ -498,7 +498,7 @@ def test_sign_assertion(self):
498498
assert sass.id == "id-11111"
499499
assert time_util.str_to_time(sass.issue_instant)
500500

501-
print(f"Crypto version : {self.sec.crypto.version()}")
501+
print(f"Crypto version : {self.sec.crypto.version}")
502502

503503
item = self.sec.check_signature(sass, class_name(sass), sign_ass)
504504

@@ -515,7 +515,7 @@ def test_multiple_signatures_assertion(self):
515515
assert sass.id == "id-11111"
516516
assert time_util.str_to_time(sass.issue_instant)
517517

518-
print(f"Crypto version : {self.sec.crypto.version()}")
518+
print(f"Crypto version : {self.sec.crypto.version}")
519519

520520
item = self.sec.check_signature(sass, class_name(sass), sign_ass, must=True)
521521

@@ -1079,18 +1079,34 @@ def test_sha256_signing_non_ascii_ava():
10791079

10801080
def test_xmlsec_output_line_parsing():
10811081
output1 = "prefix\nOK\npostfix"
1082-
assert sigver.parse_xmlsec_output(output1)
1082+
assert sigver.parse_xmlsec_verify_output(output1)
10831083

10841084
output2 = "prefix\nFAIL\npostfix"
10851085
with raises(sigver.XmlsecError):
1086-
sigver.parse_xmlsec_output(output2)
1086+
sigver.parse_xmlsec_verify_output(output2)
10871087

10881088
output3 = "prefix\r\nOK\r\npostfix"
1089-
assert sigver.parse_xmlsec_output(output3)
1089+
assert sigver.parse_xmlsec_verify_output(output3)
10901090

10911091
output4 = "prefix\r\nFAIL\r\npostfix"
10921092
with raises(sigver.XmlsecError):
1093-
sigver.parse_xmlsec_output(output4)
1093+
sigver.parse_xmlsec_verify_output(output4)
1094+
1095+
1096+
def test_xmlsec_v1_3_x_output_line_parsing():
1097+
output1 = "prefix\nVerification status: OK\npostfix"
1098+
assert sigver.parse_xmlsec_verify_output(output1, version=(1, 3))
1099+
1100+
output2 = "prefix\nVerification status: FAILED\npostfix"
1101+
with raises(sigver.XmlsecError):
1102+
sigver.parse_xmlsec_verify_output(output2, version=(1, 3))
1103+
1104+
output3 = "prefix\r\nVerification status: OK\r\npostfix"
1105+
assert sigver.parse_xmlsec_verify_output(output3, version=(1, 3))
1106+
1107+
output4 = "prefix\r\nVerification status: FAILED\r\npostfix"
1108+
with raises(sigver.XmlsecError):
1109+
sigver.parse_xmlsec_verify_output(output4, version=(1, 3))
10941110

10951111

10961112
def test_cert_trailing_newlines_ignored():

0 commit comments

Comments
 (0)