Skip to content

Commit 2648e32

Browse files
committed
Improved encrypted assertion.
1 parent d8a03cb commit 2648e32

File tree

2 files changed

+64
-29
lines changed

2 files changed

+64
-29
lines changed

src/saml2/entity.py

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
from saml2.s_utils import success_status_factory
3737
from saml2.s_utils import decode_base64_and_inflate
3838
from saml2.s_utils import UnsupportedBinding
39-
from saml2.samlp import AuthnRequest, SessionIndex
39+
from saml2.samlp import AuthnRequest, SessionIndex, response_from_string
4040
from saml2.samlp import AuthzDecisionQuery
4141
from saml2.samlp import AuthnQuery
4242
from saml2.samlp import AssertionIDRequest
@@ -504,7 +504,7 @@ def _add_info(self, msg, **kwargs):
504504
def _response(self, in_response_to, consumer_url=None, status=None,
505505
issuer=None, sign=False, to_sign=None,
506506
encrypt_assertion=False, encrypt_assertion_self_contained=False, encrypted_advice_attributes=False,
507-
encrypt_cert=None, **kwargs):
507+
encrypt_cert=None,sign_assertion=None, **kwargs):
508508
""" Create a Response.
509509
Encryption:
510510
encrypt_assertion must be true for encryption to be performed. If encrypted_advice_attributes also is
@@ -541,13 +541,14 @@ def _response(self, in_response_to, consumer_url=None, status=None,
541541
if not sign and to_sign and not encrypt_assertion:
542542
return signed_instance_factory(response, self.sec, to_sign)
543543

544-
if encrypt_assertion:
545-
node_xpath = None
544+
if encrypt_assertion or (encrypted_advice_attributes and response.assertion.advice is not None and
545+
len(response.assertion.advice.assertion) == 1):
546546
if sign:
547547
response.signature = pre_signature_part(response.id,
548548
self.sec.my_cert, 1)
549549
sign_class = [(class_name(response), response.id)]
550550
cbxs = CryptoBackendXmlSec1(self.config.xmlsec_binary)
551+
encrypt_advice = False
551552
if encrypted_advice_attributes and response.assertion.advice is not None \
552553
and len(response.assertion.advice.assertion) == 1:
553554
tmp_assertion = response.assertion.advice.assertion[0]
@@ -558,26 +559,59 @@ def _response(self, in_response_to, consumer_url=None, status=None,
558559
else:
559560
response.assertion.advice.encrypted_assertion[0].add_extension_element(tmp_assertion)
560561
response.assertion.advice.assertion = []
562+
to_sign_advice = []
563+
if sign_assertion is not None and sign_assertion:
564+
if response.assertion.advice and response.assertion.advice.assertion:
565+
for tmp_assertion in response.assertion.advice.assertion:
566+
tmp_assertion.signature = pre_signature_part(tmp_assertion.id, self.sec.my_cert, 1)
567+
to_sign_advice.append((class_name(tmp_assertion), tmp_assertion.id))
561568
if encrypt_assertion_self_contained:
562569
advice_tag = response.assertion.advice._to_element_tree().tag
563570
assertion_tag = tmp_assertion._to_element_tree().tag
564-
response = response.get_xml_string_with_self_contained_assertion_within_advice_encrypted_assertion(
565-
assertion_tag, advice_tag)
571+
response = response.\
572+
get_xml_string_with_self_contained_assertion_within_advice_encrypted_assertion(assertion_tag,
573+
advice_tag)
566574
node_xpath = ''.join(["/*[local-name()=\"%s\"]" % v for v in
567575
["Response", "Assertion", "Advice", "EncryptedAssertion", "Assertion"]])
568-
elif encrypt_assertion_self_contained:
569-
assertion_tag = response.assertion._to_element_tree().tag
570-
response = pre_encrypt_assertion(response)
571-
response = response.get_xml_string_with_self_contained_assertion_within_encrypted_assertion(
572-
assertion_tag)
573-
else:
574-
response = pre_encrypt_assertion(response)
575-
if to_sign:
576-
response = signed_instance_factory(response, self.sec, to_sign)
577-
_, cert_file = make_temp("%s" % encrypt_cert, decode=False)
578-
response = cbxs.encrypt_assertion(response, cert_file,
579-
pre_encryption_part(), node_xpath=node_xpath)
580-
# template(response.assertion.id))
576+
577+
if to_sign_advice:
578+
response = signed_instance_factory(response, self.sec, to_sign_advice)
579+
_, cert_file = make_temp("%s" % encrypt_cert, decode=False)
580+
response = cbxs.encrypt_assertion(response, cert_file,
581+
pre_encryption_part(), node_xpath=node_xpath)
582+
encrypt_advice = True
583+
if encrypt_assertion:
584+
response = response_from_string(response)
585+
if encrypt_assertion:
586+
if encrypt_assertion_self_contained:
587+
assertion_tag = None
588+
try:
589+
assertion_tag = response.assertion._to_element_tree().tag
590+
except:
591+
assertion_tag = response.assertion[0]._to_element_tree().tag
592+
response = pre_encrypt_assertion(response)
593+
response = response.get_xml_string_with_self_contained_assertion_within_encrypted_assertion(
594+
assertion_tag)
595+
else:
596+
response = pre_encrypt_assertion(response)
597+
to_sign_assertion = []
598+
if sign_assertion is not None and sign_assertion:
599+
response.assertion.signature = pre_signature_part(response.assertion.id, self.sec.my_cert, 1)
600+
to_sign_assertion.append((class_name(response.assertion), response.assertion.id))
601+
if to_sign_assertion:
602+
response = signed_instance_factory(response, self.sec, to_sign_assertion)
603+
if encrypt_cert is not None and not encrypt_advice:
604+
_, cert_file = make_temp("%s" % encrypt_cert, decode=False)
605+
else:
606+
tmp_cert_str = "%s" % self.sec.my_cert
607+
if "-----BEGIN CERTIFICATE-----" not in tmp_cert_str:
608+
tmp_cert_str = "-----BEGIN CERTIFICATE-----\n" + tmp_cert_str
609+
if "-----END CERTIFICATE-----" not in tmp_cert_str:
610+
tmp_cert_str = tmp_cert_str + "\n-----END CERTIFICATE-----\n"
611+
_, cert_file = make_temp(tmp_cert_str, decode=False)
612+
response = cbxs.encrypt_assertion(response, cert_file,
613+
pre_encryption_part())
614+
# template(response.assertion.id))
581615
if sign:
582616
return signed_instance_factory(response, self.sec, sign_class)
583617
else:

src/saml2/server.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ def _authn_response(self, in_response_to, consumer_url,
357357
# tmp_authn_statement = authn_statement
358358
# authn_statement = None
359359

360-
if encrypt_assertion and encrypted_advice_attributes:
360+
if encrypted_advice_attributes:
361361
assertion_attributes = self.setup_assertion(None, sp_entity_id, None, None, None, policy,
362362
None, None, identity, best_effort, sign_response, False)
363363
assertion = self.setup_assertion(authn, sp_entity_id, in_response_to, consumer_url,
@@ -374,15 +374,15 @@ def _authn_response(self, in_response_to, consumer_url,
374374
sign_response)
375375

376376
to_sign = []
377-
if sign_assertion is not None and sign_assertion:
378-
if assertion.advice and assertion.advice.assertion:
379-
for tmp_assertion in assertion.advice.assertion:
380-
tmp_assertion.signature = pre_signature_part(tmp_assertion.id, self.sec.my_cert, 1)
381-
to_sign.append((class_name(tmp_assertion), tmp_assertion.id))
382-
assertion.signature = pre_signature_part(assertion.id,
383-
self.sec.my_cert, 1)
377+
#if sign_assertion is not None and sign_assertion:
378+
# if assertion.advice and assertion.advice.assertion:
379+
# for tmp_assertion in assertion.advice.assertion:
380+
# tmp_assertion.signature = pre_signature_part(tmp_assertion.id, self.sec.my_cert, 1)
381+
# to_sign.append((class_name(tmp_assertion), tmp_assertion.id))
382+
# assertion.signature = pre_signature_part(assertion.id,
383+
# self.sec.my_cert, 1)
384384
# Just the assertion or the response and the assertion ?
385-
to_sign.append((class_name(assertion), assertion.id))
385+
# to_sign.append((class_name(assertion), assertion.id))
386386

387387

388388
# Store which assertion that has been sent to which SP about which
@@ -401,7 +401,8 @@ def _authn_response(self, in_response_to, consumer_url,
401401
sign_response, to_sign, encrypt_assertion=encrypt_assertion,
402402
encrypt_cert=encrypt_cert,
403403
encrypt_assertion_self_contained=encrypt_assertion_self_contained,
404-
encrypted_advice_attributes=encrypted_advice_attributes, **args)
404+
encrypted_advice_attributes=encrypted_advice_attributes,sign_assertion=sign_assertion,
405+
**args)
405406

406407
# ------------------------------------------------------------------------
407408

0 commit comments

Comments
 (0)