Skip to content

Commit 2949fba

Browse files
committed
Partial commit.
Improved signing and added more testcases.
1 parent a7ed34c commit 2949fba

File tree

3 files changed

+310
-102
lines changed

3 files changed

+310
-102
lines changed

src/saml2/entity.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -512,8 +512,14 @@ def _encrypt_assertion(self, encrypt_cert, sp_entity_id, response, node_xpath=No
512512
exception = None
513513
for _cert in _certs:
514514
try:
515+
begin_cert = "-----BEGIN CERTIFICATE-----\n"
516+
end_cert = "\n-----END CERTIFICATE-----\n"
517+
if begin_cert not in _cert:
518+
_cert = "%s%s" % (begin_cert, _cert)
519+
if end_cert not in _cert:
520+
_cert = "%s%s" % (_cert, end_cert)
515521
_, cert_file = make_temp(_cert, decode=False)
516-
response = cbxs.encrypt_assertion(response, self.sec.cert_file,
522+
response = cbxs.encrypt_assertion(response, cert_file,
517523
pre_encryption_part(), node_xpath=node_xpath)
518524
return response
519525
except Exception as ex:
@@ -525,7 +531,7 @@ def _encrypt_assertion(self, encrypt_cert, sp_entity_id, response, node_xpath=No
525531
def _response(self, in_response_to, consumer_url=None, status=None,
526532
issuer=None, sign=False, to_sign=None, sp_entity_id=None,
527533
encrypt_assertion=False, encrypt_assertion_self_contained=False, encrypted_advice_attributes=False,
528-
encrypt_cert=None, encrypt_cert_assertion=None,sign_assertion=None, **kwargs):
534+
encrypt_cert_advice=None, encrypt_cert_assertion=None,sign_assertion=None, **kwargs):
529535
""" Create a Response.
530536
Encryption:
531537
encrypt_assertion must be true for encryption to be performed. If encrypted_advice_attributes also is
@@ -598,7 +604,7 @@ def _response(self, in_response_to, consumer_url=None, status=None,
598604

599605
if to_sign_advice:
600606
response = signed_instance_factory(response, self.sec, to_sign_advice)
601-
response = self._encrypt_assertion(encrypt_cert, sp_entity_id, response, node_xpath=node_xpath)
607+
response = self._encrypt_assertion(encrypt_cert_advice, sp_entity_id, response, node_xpath=node_xpath)
602608
if encrypt_assertion:
603609
response = response_from_string(response)
604610
if encrypt_assertion:

src/saml2/server.py

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ def _authn_response(self, in_response_to, consumer_url,
323323
status=None, authn=None, issuer=None, policy=None,
324324
sign_assertion=False, sign_response=False,
325325
best_effort=False, encrypt_assertion=False,
326-
encrypt_cert=None, authn_statement=None,
326+
encrypt_cert_advice=None, encrypt_cert_assertion=None, authn_statement=None,
327327
encrypt_assertion_self_contained=False, encrypted_advice_attributes=False):
328328
""" Create a response. A layer of indirection.
329329
@@ -375,16 +375,17 @@ def _authn_response(self, in_response_to, consumer_url,
375375
sign_response)
376376

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

383+
if not encrypted_advice_attributes:
384+
if sign_assertion:
385+
if assertion.advice and assertion.advice.assertion:
386+
for tmp_assertion in assertion.advice.assertion:
387+
tmp_assertion.signature = pre_signature_part(tmp_assertion.id, self.sec.my_cert, 1)
388+
to_sign.append((class_name(tmp_assertion), tmp_assertion.id))
388389

389390
# Store which assertion that has been sent to which SP about which
390391
# subject.
@@ -400,7 +401,8 @@ def _authn_response(self, in_response_to, consumer_url,
400401

401402
return self._response(in_response_to, consumer_url, status, issuer,
402403
sign_response, to_sign,sp_entity_id=sp_entity_id, encrypt_assertion=encrypt_assertion,
403-
encrypt_cert=encrypt_cert,
404+
encrypt_cert_advice=encrypt_cert_advice,
405+
encrypt_cert_assertion=encrypt_cert_assertion,
404406
encrypt_assertion_self_contained=encrypt_assertion_self_contained,
405407
encrypted_advice_attributes=encrypted_advice_attributes,sign_assertion=sign_assertion,
406408
**args)
@@ -477,8 +479,8 @@ def create_authn_response(self, identity, in_response_to, destination,
477479
sp_entity_id, name_id_policy=None, userid=None,
478480
name_id=None, authn=None, issuer=None,
479481
sign_response=None, sign_assertion=None,
480-
encrypt_cert=None, encrypt_assertion=None,
481-
encrypt_assertion_self_contained=False,
482+
encrypt_cert_advice=None, encrypt_cert_assertion=None, encrypt_assertion=None,
483+
encrypt_assertion_self_contained=True,
482484
encrypted_advice_attributes=False,
483485
**kwargs):
484486
""" Constructs an AuthenticationResponse
@@ -523,17 +525,35 @@ def create_authn_response(self, identity, in_response_to, destination,
523525
if encrypt_assertion is None:
524526
encrypt_assertion = False
525527

528+
529+
if encrypt_assertion_self_contained is None:
530+
encrypt_assertion_self_contained = self.config.getattr("encrypt_assertion_self_contained", "idp")
531+
if encrypt_assertion_self_contained is None:
532+
encrypt_assertion_self_contained = True
533+
534+
if encrypted_advice_attributes is None:
535+
encrypted_advice_attributes = self.config.getattr("encrypted_advice_attributes", "idp")
536+
if encrypted_advice_attributes is None:
537+
encrypted_advice_attributes = False
538+
539+
if encrypted_advice_attributes:
540+
verify_encrypt_cert = self.config.getattr("verify_encrypt_cert_advice", "idp")
541+
if verify_encrypt_cert is not None:
542+
if encrypt_cert_advice is None:
543+
raise CertificateError("No SPCertEncType certificate for encryption contained in authentication "
544+
"request.")
545+
if not verify_encrypt_cert(encrypt_cert_advice):
546+
raise CertificateError("Invalid certificate for encryption!")
547+
548+
526549
if encrypt_assertion:
527-
if encrypt_cert is not None:
528-
verify_encrypt_cert = self.config.getattr("verify_encrypt_cert", "idp")
529-
if verify_encrypt_cert is not None:
530-
if not verify_encrypt_cert(encrypt_cert):
531-
raise CertificateError("Invalid certificate for encryption!")
532-
else:
533-
raise CertificateError("No SPCertEncType certificate for encryption contained in authentication "
534-
"request.")
535-
else:
536-
encrypt_assertion = False
550+
verify_encrypt_cert = self.config.getattr("verify_encrypt_cert_assertion", "idp")
551+
if verify_encrypt_cert is not None:
552+
if encrypt_cert_assertion is None:
553+
raise CertificateError("No SPCertEncType certificate for encryption contained in authentication "
554+
"request.")
555+
if not verify_encrypt_cert(encrypt_cert_assertion):
556+
raise CertificateError("Invalid certificate for encryption!")
537557

538558
if not name_id:
539559
try:
@@ -593,7 +613,8 @@ def create_authn_response(self, identity, in_response_to, destination,
593613
encrypt_assertion=encrypt_assertion,
594614
encrypt_assertion_self_contained=encrypt_assertion_self_contained,
595615
encrypted_advice_attributes=encrypted_advice_attributes,
596-
encrypt_cert=encrypt_cert)
616+
encrypt_cert_advice=encrypt_cert_advice,
617+
encrypt_cert_assertion=encrypt_cert_assertion)
597618
return self._authn_response(in_response_to, # in_response_to
598619
destination, # consumer_url
599620
sp_entity_id, # sp_entity_id
@@ -608,7 +629,8 @@ def create_authn_response(self, identity, in_response_to, destination,
608629
encrypt_assertion=encrypt_assertion,
609630
encrypt_assertion_self_contained=encrypt_assertion_self_contained,
610631
encrypted_advice_attributes=encrypted_advice_attributes,
611-
encrypt_cert=encrypt_cert)
632+
encrypt_cert_advice=encrypt_cert_advice,
633+
encrypt_cert_assertion=encrypt_cert_assertion)
612634

613635
except MissingValue as exc:
614636
return self.create_error_response(in_response_to, destination,

0 commit comments

Comments
 (0)