diff options
author | Joseph Sutton <josephsutton@catalyst.net.nz> | 2021-11-30 09:45:13 +1300 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2022-12-14 00:48:48 +0100 |
commit | 900c6e2268dbd2625e679af1550d4874247cd1b1 (patch) | |
tree | 84d7a1b228afcb5e9ee3ee4481e987c917129352 | |
parent | d10dfa85819750f4665dc5fa974f35ce7871acf8 (diff) | |
download | samba-900c6e2268dbd2625e679af1550d4874247cd1b1.tar.gz |
CVE-2022-37966 tests/krb5: Check encrypted-pa-data if present
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
(cherry picked from commit f94bdb41fccdb085d8f8f5a1a5e4a56581839e8e)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15237
[jsutton@samba.org Fixed MIT knownfail conflict; added import of PADATA_REQ_ENC_PA_REP constant]
-rw-r--r-- | python/samba/tests/krb5/raw_testcase.py | 82 | ||||
-rw-r--r-- | python/samba/tests/krb5/rfc4120_constants.py | 3 | ||||
-rw-r--r-- | selftest/knownfail_mit_kdc | 2 |
3 files changed, 69 insertions, 18 deletions
diff --git a/python/samba/tests/krb5/raw_testcase.py b/python/samba/tests/krb5/raw_testcase.py index 4a78a8eadf3..2dedccf6188 100644 --- a/python/samba/tests/krb5/raw_testcase.py +++ b/python/samba/tests/krb5/raw_testcase.py @@ -65,6 +65,7 @@ from samba.tests.krb5.rfc4120_constants import ( KU_AP_REQ_AUTH, KU_AS_REP_ENC_PART, KU_AP_REQ_ENC_PART, + KU_AS_REQ, KU_ENC_CHALLENGE_KDC, KU_FAST_ENC, KU_FAST_FINISHED, @@ -95,6 +96,7 @@ from samba.tests.krb5.rfc4120_constants import ( PADATA_PAC_REQUEST, PADATA_PK_AS_REQ, PADATA_PK_AS_REP_19, + PADATA_REQ_ENC_PA_REP, PADATA_SUPPORTED_ETYPES ) import samba.tests.krb5.kcrypto as kcrypto @@ -2306,6 +2308,8 @@ class RawKerberosTest(TestCaseInTempDir): req_body=req_body, asn1Spec=req_asn1Spec()) + kdc_exchange_dict['req_obj'] = req_obj + to_rodc = kdc_exchange_dict['to_rodc'] rep = self.send_recv_transaction(req_decoded, to_rodc=to_rodc) @@ -2689,6 +2693,8 @@ class RawKerberosTest(TestCaseInTempDir): rep_decpart, asn1Spec=krb5_asn1.EncTGSRepPart()) + kdc_exchange_dict['reply_key'] = encpart_decryption_key + self.assertIsNotNone(check_kdc_private_fn) if check_kdc_private_fn is not None: check_kdc_private_fn(kdc_exchange_dict, callback_dict, @@ -2855,15 +2861,35 @@ class RawKerberosTest(TestCaseInTempDir): sent_pac_options = self.get_sent_pac_options(kdc_exchange_dict) - if self.strict_checking: - if canonicalize or '1' in sent_pac_options: - self.assertElementPresent(encpart_private, + sent_enc_pa_rep = self.sent_enc_pa_rep(kdc_exchange_dict) + + enc_padata = self.getElementValue(encpart_private, 'encrypted-pa-data') - enc_pa_dict = self.get_pa_dict( - encpart_private['encrypted-pa-data']) - if canonicalize: - self.assertIn(PADATA_SUPPORTED_ETYPES, enc_pa_dict) + if (canonicalize or '1' in sent_pac_options or ( + rep_msg_type == KRB_AS_REP and sent_enc_pa_rep)): + if self.strict_checking: + self.assertIsNotNone(enc_padata) + if enc_padata is not None: + enc_pa_dict = self.get_pa_dict(enc_padata) + if self.strict_checking: + if canonicalize: + self.assertIn(PADATA_SUPPORTED_ETYPES, enc_pa_dict) + else: + self.assertNotIn(PADATA_SUPPORTED_ETYPES, + enc_pa_dict) + + if '1' in sent_pac_options: + self.assertIn(PADATA_PAC_OPTIONS, enc_pa_dict) + else: + self.assertNotIn(PADATA_PAC_OPTIONS, enc_pa_dict) + + if rep_msg_type == KRB_AS_REP and sent_enc_pa_rep: + self.assertIn(PADATA_REQ_ENC_PA_REP, enc_pa_dict) + else: + self.assertNotIn(PADATA_REQ_ENC_PA_REP, enc_pa_dict) + + if PADATA_SUPPORTED_ETYPES in enc_pa_dict: expected_supported_etypes = kdc_exchange_dict[ 'expected_supported_etypes'] expected_supported_etypes |= ( @@ -2877,24 +2903,39 @@ class RawKerberosTest(TestCaseInTempDir): self.assertEqual(supported_etypes, expected_supported_etypes) - else: - self.assertNotIn(PADATA_SUPPORTED_ETYPES, enc_pa_dict) - - if '1' in sent_pac_options: - self.assertIn(PADATA_PAC_OPTIONS, enc_pa_dict) + if PADATA_PAC_OPTIONS in enc_pa_dict: pac_options = self.der_decode( enc_pa_dict[PADATA_PAC_OPTIONS], asn1Spec=krb5_asn1.PA_PAC_OPTIONS()) self.assertElementEqual(pac_options, 'options', sent_pac_options) - else: - self.assertNotIn(PADATA_PAC_OPTIONS, enc_pa_dict) - else: - self.assertElementEqual(encpart_private, - 'encrypted-pa-data', - []) + + if PADATA_REQ_ENC_PA_REP in enc_pa_dict: + enc_pa_rep = enc_pa_dict[PADATA_REQ_ENC_PA_REP] + + enc_pa_rep = self.der_decode( + enc_pa_rep, + asn1Spec=krb5_asn1.Checksum()) + + reply_key = kdc_exchange_dict['reply_key'] + req_obj = kdc_exchange_dict['req_obj'] + req_asn1Spec = kdc_exchange_dict['req_asn1Spec'] + + req_obj = self.der_encode(req_obj, + asn1Spec=req_asn1Spec()) + + checksum = enc_pa_rep['checksum'] + ctype = enc_pa_rep['cksumtype'] + + reply_key.verify_checksum(KU_AS_REQ, + req_obj, + ctype, + checksum) + else: + if enc_padata is not None: + self.assertEqual(enc_padata, []) if ticket_session_key is not None and encpart_session_key is not None: self.assertEqual(ticket_session_key.etype, @@ -4052,6 +4093,11 @@ class RawKerberosTest(TestCaseInTempDir): return PADATA_ENCRYPTED_CHALLENGE in fast_pa_dict + def sent_enc_pa_rep(self, kdc_exchange_dict): + fast_pa_dict = self.get_fast_pa_dict(kdc_exchange_dict) + + return PADATA_REQ_ENC_PA_REP in fast_pa_dict + def get_sent_pac_options(self, kdc_exchange_dict): fast_pa_dict = self.get_fast_pa_dict(kdc_exchange_dict) diff --git a/python/samba/tests/krb5/rfc4120_constants.py b/python/samba/tests/krb5/rfc4120_constants.py index 7f0f44500c7..2af43557ad7 100644 --- a/python/samba/tests/krb5/rfc4120_constants.py +++ b/python/samba/tests/krb5/rfc4120_constants.py @@ -66,6 +66,8 @@ PADATA_PW_SALT = int( krb5_asn1.PADataTypeValues('kRB5-PADATA-PW-SALT')) PADATA_SUPPORTED_ETYPES = int( krb5_asn1.PADataTypeValues('kRB5-PADATA-SUPPORTED-ETYPES')) +PADATA_REQ_ENC_PA_REP = int( + krb5_asn1.PADataTypeValues('kRB5-PADATA-REQ-ENC-PA-REP')) # Error codes KDC_ERR_C_PRINCIPAL_UNKNOWN = 6 @@ -194,6 +196,7 @@ KU_FAST_REP = 52 KU_FAST_FINISHED = 53 KU_ENC_CHALLENGE_CLIENT = 54 KU_ENC_CHALLENGE_KDC = 55 +KU_AS_REQ = 56 # Armor types FX_FAST_ARMOR_AP_REQUEST = 1 diff --git a/selftest/knownfail_mit_kdc b/selftest/knownfail_mit_kdc index 6cad47701ae..680c637fbc5 100644 --- a/selftest/knownfail_mit_kdc +++ b/selftest/knownfail_mit_kdc @@ -347,9 +347,11 @@ samba.tests.krb5.as_canonicalization_tests.samba.tests.krb5.as_canonicalization_ ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_outer_no_sname.ad_dc ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_outer_no_sname.ad_dc ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_no_sname.ad_dc +^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_enc_pa_rep.ad_dc ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_no_sname.ad_dc ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_fast_no_etypes.ad_dc ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_no_sname.ad_dc +^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_enc_pa_rep.ad_dc ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_simple_tgs_no_sname.ad_dc ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_inner_no_sname.ad_dc ^samba.tests.krb5.fast_tests.samba.tests.krb5.fast_tests.FAST_Tests.test_fast_tgs_inner_no_sname.ad_dc |