36
36
from saml2 .s_utils import success_status_factory
37
37
from saml2 .s_utils import decode_base64_and_inflate
38
38
from saml2 .s_utils import UnsupportedBinding
39
- from saml2 .samlp import AuthnRequest , SessionIndex
39
+ from saml2 .samlp import AuthnRequest , SessionIndex , response_from_string
40
40
from saml2 .samlp import AuthzDecisionQuery
41
41
from saml2 .samlp import AuthnQuery
42
42
from saml2 .samlp import AssertionIDRequest
@@ -504,7 +504,7 @@ def _add_info(self, msg, **kwargs):
504
504
def _response (self , in_response_to , consumer_url = None , status = None ,
505
505
issuer = None , sign = False , to_sign = None ,
506
506
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 ):
508
508
""" Create a Response.
509
509
Encryption:
510
510
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,
541
541
if not sign and to_sign and not encrypt_assertion :
542
542
return signed_instance_factory (response , self .sec , to_sign )
543
543
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 ):
546
546
if sign :
547
547
response .signature = pre_signature_part (response .id ,
548
548
self .sec .my_cert , 1 )
549
549
sign_class = [(class_name (response ), response .id )]
550
550
cbxs = CryptoBackendXmlSec1 (self .config .xmlsec_binary )
551
+ encrypt_advice = False
551
552
if encrypted_advice_attributes and response .assertion .advice is not None \
552
553
and len (response .assertion .advice .assertion ) == 1 :
553
554
tmp_assertion = response .assertion .advice .assertion [0 ]
@@ -558,26 +559,59 @@ def _response(self, in_response_to, consumer_url=None, status=None,
558
559
else :
559
560
response .assertion .advice .encrypted_assertion [0 ].add_extension_element (tmp_assertion )
560
561
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 ))
561
568
if encrypt_assertion_self_contained :
562
569
advice_tag = response .assertion .advice ._to_element_tree ().tag
563
570
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 )
566
574
node_xpath = '' .join (["/*[local-name()=\" %s\" ]" % v for v in
567
575
["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))
581
615
if sign :
582
616
return signed_instance_factory (response , self .sec , sign_class )
583
617
else :
0 commit comments