From 489cdefa6ab1bf7bd5cf3ea0ea64c03dc08fa8bd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 17 Mar 2022 14:46:55 +0100 Subject: [PATCH] tests/krb5/s4u_tests.py: add test_constrained_delegation_with_enc_auth_data_[no_]subkey() This demonstrates that we use the correct key for EncAuthorizationData together with constrained delegation. The actual fix for the problem is already in place via commit 75ec66c729faad60fa18b9504ba4053b3e2f47bc third_party/heimdal: Import lorikeet-heimdal-202306091507 (commit 7d8afc9d7e3d309ddccc2aea6405a8ca6280f6de) The related patches are: 38c47c54f0c78fed5afc1aea9c5f6683e06ec842 kdc: fix memory leak when decryption AuthorizationData 61c0089ea3f5387953818a3ac99fb529244196e6 kdc: decrypt b->enc_authorization_data in tgs_build_reply() fed5579814108ee90f701ca6bfb5500f7d839bc4 kdc: if we don't have an authenticator subkey for S4U2Proxy we need to use the keys from evidence_tkt BUG: https://bugzilla.samba.org/show_bug.cgi?id=13131 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett --- python/samba/tests/krb5/s4u_tests.py | 92 +++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/python/samba/tests/krb5/s4u_tests.py b/python/samba/tests/krb5/s4u_tests.py index 83ca06e4577..4620070c8e6 100755 --- a/python/samba/tests/krb5/s4u_tests.py +++ b/python/samba/tests/krb5/s4u_tests.py @@ -37,6 +37,7 @@ from samba.tests.krb5.raw_testcase import ( ) from samba.tests.krb5.rfc4120_constants import ( AES256_CTS_HMAC_SHA1_96, + AD_IF_RELEVANT, ARCFOUR_HMAC_MD5, KDC_ERR_BADMATCH, KDC_ERR_BADOPTION, @@ -49,7 +50,9 @@ from samba.tests.krb5.rfc4120_constants import ( KU_PA_ENC_TIMESTAMP, KU_AS_REP_ENC_PART, KU_TGS_REP_ENC_PART_SUB_KEY, - NT_PRINCIPAL + KU_TGS_REQ_AUTH_DAT_SESSION, + KU_TGS_REQ_AUTH_DAT_SUBKEY, + NT_PRINCIPAL, ) import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1 @@ -722,7 +725,11 @@ class S4UKerberosTests(KDCBaseTest): pac_options = kdc_dict.pop('pac_options', None) - authenticator_subkey = self.RandomKey(Enctype.AES256) + use_authenticator_subkey = kdc_dict.pop('use_authenticator_subkey', True) + if use_authenticator_subkey: + authenticator_subkey = self.RandomKey(Enctype.AES256) + else: + authenticator_subkey = None expected_proxy_target = service2_creds.get_spn() @@ -759,22 +766,64 @@ class S4UKerberosTests(KDCBaseTest): expected_transited_services=expected_transited_services, expect_pac=expect_pac) + EncAuthorizationData = kdc_dict.pop('enc-authorization-data', None) + + if EncAuthorizationData is not None: + if authenticator_subkey is not None: + EncAuthorizationData_key = authenticator_subkey + EncAuthorizationData_usage = KU_TGS_REQ_AUTH_DAT_SUBKEY + else: + EncAuthorizationData_key = client_service_tkt.session_key + EncAuthorizationData_usage = KU_TGS_REQ_AUTH_DAT_SESSION + else: + EncAuthorizationData_key = None + EncAuthorizationData_usage = None + self._generic_kdc_exchange(kdc_exchange_dict, cname=None, realm=service2_realm, sname=service2_sname, etypes=etypes, - additional_tickets=additional_tickets) + additional_tickets=additional_tickets, + EncAuthorizationData=EncAuthorizationData, + EncAuthorizationData_key=EncAuthorizationData_key, + EncAuthorizationData_usage=EncAuthorizationData_usage) if not expected_error_mode: # Check whether the ticket contains a PAC. ticket = kdc_exchange_dict['rep_ticket_creds'] pac = self.get_ticket_pac(ticket, expect_pac=expect_pac) + ticket_auth_data = ticket.ticket_private.get('authorization-data') + expected_num_ticket_auth_data = 0 if expect_pac: self.assertIsNotNone(pac) + expected_num_ticket_auth_data += 1 else: self.assertIsNone(pac) + if EncAuthorizationData is not None: + expected_num_ticket_auth_data += len(EncAuthorizationData) + + if expected_num_ticket_auth_data == 0: + self.assertIsNone(ticket_auth_data) + else: + self.assertIsNotNone(ticket_auth_data) + self.assertEqual(len(ticket_auth_data), + expected_num_ticket_auth_data) + + if EncAuthorizationData is not None: + enc_ad_plain = self.der_encode( + EncAuthorizationData, + asn1Spec=krb5_asn1.AuthorizationData()) + req_EncAuthorizationData = self.der_decode( + enc_ad_plain, + asn1Spec=krb5_asn1.AuthorizationData()) + + rep_EncAuthorizationData = ticket_auth_data.copy() + if expect_pac: + rep_EncAuthorizationData.pop(0) + self.assertEqual(rep_EncAuthorizationData, req_EncAuthorizationData) + # Ensure we used all the parameters given to us. self.assertEqual({}, kdc_dict) @@ -793,6 +842,43 @@ class S4UKerberosTests(KDCBaseTest): 'allow_delegation': True }) + def test_constrained_delegation_with_enc_auth_data_subkey(self): + # Test constrained delegation. + EncAuthorizationData = [] + relevant_elems = [] + auth_data777 = self.AuthorizationData_create(777, b'AuthorizationData777') + relevant_elems.append(auth_data777) + auth_data999 = self.AuthorizationData_create(999, b'AuthorizationData999') + relevant_elems.append(auth_data999) + ad_relevant = self.der_encode(relevant_elems, asn1Spec=krb5_asn1.AD_IF_RELEVANT()) + ad_data = self.AuthorizationData_create(AD_IF_RELEVANT, ad_relevant) + EncAuthorizationData.append(ad_data) + self._run_delegation_test( + { + 'expected_error_mode': 0, + 'allow_delegation': True, + 'enc-authorization-data': EncAuthorizationData, + }) + + def test_constrained_delegation_with_enc_auth_data_no_subkey(self): + # Test constrained delegation. + EncAuthorizationData = [] + relevant_elems = [] + auth_data777 = self.AuthorizationData_create(777, b'AuthorizationData777') + relevant_elems.append(auth_data777) + auth_data999 = self.AuthorizationData_create(999, b'AuthorizationData999') + relevant_elems.append(auth_data999) + ad_relevant = self.der_encode(relevant_elems, asn1Spec=krb5_asn1.AD_IF_RELEVANT()) + ad_data = self.AuthorizationData_create(AD_IF_RELEVANT, ad_relevant) + EncAuthorizationData.append(ad_data) + self._run_delegation_test( + { + 'expected_error_mode': 0, + 'allow_delegation': True, + 'enc-authorization-data': EncAuthorizationData, + 'use_authenticator_subkey': False, + }) + def test_constrained_delegation_authentication_asserted_identity(self): # Test constrained delegation and check asserted identity is the # authentication authority. Note that we should always find this -- 2.34.1