diff options
author | peppelinux <giuseppe.demarco@unical.it> | 2021-03-02 23:58:36 +0100 |
---|---|---|
committer | Ivan Kanakarakis <ivan.kanak@gmail.com> | 2021-05-18 15:20:29 +0300 |
commit | fc6e532264b78020c1321610242beee6a5b89ca4 (patch) | |
tree | aa20f885c1fbfcca671f846ccd2cadfe15a0a045 /src/saml2 | |
parent | 3d54fc7e9694f3fe2a91b19a57ee634cb1501af4 (diff) | |
download | pysaml2-fc6e532264b78020c1321610242beee6a5b89ca4.tar.gz |
[Strengthen Encryption] PySAML2 Encrypted Assertions now works with Shibboleth SP 3
- Fixed: "ERROR Shibboleth.SSO.SAML2 [6] [default]: failed to decrypt assertion: Unable to resolve any key decryption keys."
- Fixed: "WARN XMLTooling.Decrypter [7] [default]: XMLSecurity exception while decrypting key: XSECAlgorithmMapper::mapURIToHandler - URI http://www.w3.org/2001/04/xmlenc#rsa-1_5 disallowed by whitelist/blacklist policy"
Diffstat (limited to 'src/saml2')
-rw-r--r-- | src/saml2/data/templates/template_enc.xml | 6 | ||||
-rw-r--r-- | src/saml2/entity.py | 21 | ||||
-rw-r--r-- | src/saml2/sigver.py | 35 |
3 files changed, 41 insertions, 21 deletions
diff --git a/src/saml2/data/templates/template_enc.xml b/src/saml2/data/templates/template_enc.xml index 0b962e55..d581485e 100644 --- a/src/saml2/data/templates/template_enc.xml +++ b/src/saml2/data/templates/template_enc.xml @@ -2,12 +2,10 @@ <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Element"> - <EncryptionMethod Algorithm= - "http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/> + <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#"> - <EncryptionMethod Algorithm= - "http://www.w3.org/2001/04/xmlenc#rsa-1_5"/> + <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <KeyName/> </KeyInfo> diff --git a/src/saml2/entity.py b/src/saml2/entity.py index d2d6ec5c..21ce516a 100644 --- a/src/saml2/entity.py +++ b/src/saml2/entity.py @@ -65,6 +65,7 @@ from saml2.sigver import security_context from saml2.sigver import SigverError from saml2.sigver import SignatureError from saml2.sigver import make_temp +from saml2.sigver import get_pem_wrapped_unwrapped from saml2.sigver import pre_encryption_part from saml2.sigver import pre_signature_part from saml2.sigver import pre_encrypt_assertion @@ -654,18 +655,22 @@ class Entity(HTTPBase): _certs = self.metadata.certs(sp_entity_id, "any", "encryption") exception = None for _cert in _certs: + wrapped_cert, unwrapped_cert = get_pem_wrapped_unwrapped(_cert) try: - begin_cert = "-----BEGIN CERTIFICATE-----\n" - end_cert = "\n-----END CERTIFICATE-----\n" - if begin_cert not in _cert: - _cert = "%s%s" % (begin_cert, _cert) - if end_cert not in _cert: - _cert = "%s%s" % (_cert, end_cert) - tmp = make_temp(_cert.encode('ascii'), + tmp = make_temp(wrapped_cert.encode('ascii'), decode=False, delete_tmpfiles=self.config.delete_tmpfiles) + + # it would be possibile to handle many other args here ... + pre_enc_part_dict = dict() + if encrypt_cert: + pre_enc_part_dict['encrypt_cert'] = unwrapped_cert + pre_enc_part = pre_encryption_part(**pre_enc_part_dict) + # end pre_enc_part + + response = self.sec.encrypt_assertion(response, tmp.name, - pre_encryption_part(), + pre_enc_part, node_xpath=node_xpath) return response except Exception as ex: diff --git a/src/saml2/sigver.py b/src/saml2/sigver.py index b950d18d..fff03897 100644 --- a/src/saml2/sigver.py +++ b/src/saml2/sigver.py @@ -7,6 +7,7 @@ import hashlib import itertools import logging import os +import re import six from uuid import uuid4 as gen_random_key from time import mktime @@ -59,9 +60,11 @@ logger = logging.getLogger(__name__) SIG = '{{{ns}#}}{attribute}'.format(ns=ds.NAMESPACE, attribute='Signature') -RSA_1_5 = 'http://www.w3.org/2001/04/xmlenc#rsa-1_5' -TRIPLE_DES_CBC = 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc' +# DEPRECATED +# RSA_1_5 = 'http://www.w3.org/2001/04/xmlenc#rsa-1_5' +TRIPLE_DES_CBC = 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc' +RSA_OAEP_MGF1P = "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" class SigverError(SAMLError): pass @@ -100,6 +103,14 @@ class CertificateError(SigverError): pass +def get_pem_wrapped_unwrapped(cert): + begin_cert = "-----BEGIN CERTIFICATE-----\n" + end_cert = "\n-----END CERTIFICATE-----\n" + unwrapped_cert = re.sub(f'{begin_cert}|{end_cert}', '', cert) + wrapped_cert = f'{begin_cert}{unwrapped_cert}{end_cert}' + return wrapped_cert, unwrapped_cert + + def read_file(*args, **kwargs): with open(*args, **kwargs) as handler: return handler.read() @@ -1085,10 +1096,8 @@ def encrypt_cert_from_item(item): pass if _encrypt_cert is not None: - if _encrypt_cert.find('-----BEGIN CERTIFICATE-----\n') == -1: - _encrypt_cert = '-----BEGIN CERTIFICATE-----\n' + _encrypt_cert - if _encrypt_cert.find('\n-----END CERTIFICATE-----') == -1: - _encrypt_cert = _encrypt_cert + '\n-----END CERTIFICATE-----' + wrapped_cert, unwrapped_cert = get_pem_wrapped_unwrapped(_encrypt_cert) + _encrypt_cert = wrapped_cert return _encrypt_cert @@ -1872,8 +1881,10 @@ def pre_signature_part( # </EncryptedData> -def pre_encryption_part(msg_enc=TRIPLE_DES_CBC, key_enc=RSA_1_5, key_name='my-rsa-key', - encrypted_key_id=None, encrypted_data_id=None): +def pre_encryption_part(msg_enc=TRIPLE_DES_CBC, key_enc=RSA_OAEP_MGF1P, + key_name='my-rsa-key', + encrypted_key_id=None, encrypted_data_id=None, + encrypt_cert=None): """ :param msg_enc: @@ -1885,10 +1896,16 @@ def pre_encryption_part(msg_enc=TRIPLE_DES_CBC, key_enc=RSA_1_5, key_name='my-rs ed_id = encrypted_data_id or "ED_{id}".format(id=gen_random_key()) msg_encryption_method = EncryptionMethod(algorithm=msg_enc) key_encryption_method = EncryptionMethod(algorithm=key_enc) + + enc_key_dict= dict(key_name=ds.KeyName(text=key_name)) + enc_key_dict['x509_data'] = ds.X509Data( + x509_certificate=ds.X509Certificate(text=encrypt_cert)) + key_info = ds.KeyInfo(**enc_key_dict) + encrypted_key = EncryptedKey( id=ek_id, encryption_method=key_encryption_method, - key_info=ds.KeyInfo(key_name=ds.KeyName(text=key_name)), + key_info=key_info, cipher_data=CipherData(cipher_value=CipherValue(text='')), ) key_info = ds.KeyInfo(encrypted_key=encrypted_key) |