tests/krb5: Add more AS-REQ ENC-TIMESTAMP tests with different encryption types
[Samba.git] / python / samba / tests / krb5 / as_req_tests.py
bloba69278214ccc53432d2c4a83a84138ff6cce93b4
1 #!/usr/bin/env python3
2 # Unix SMB/CIFS implementation.
3 # Copyright (C) Stefan Metzmacher 2020
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 import sys
20 import os
22 sys.path.insert(0, "bin/python")
23 os.environ["PYTHONUNBUFFERED"] = "1"
25 from samba.tests import DynamicTestCase
26 from samba.tests.krb5.kdc_base_test import KDCBaseTest
27 import samba.tests.krb5.kcrypto as kcrypto
28 import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1
29 from samba.tests.krb5.rfc4120_constants import (
30 KDC_ERR_ETYPE_NOSUPP,
31 KDC_ERR_PREAUTH_REQUIRED,
32 KU_PA_ENC_TIMESTAMP,
33 NT_PRINCIPAL,
34 NT_SRV_INST,
35 PADATA_ENC_TIMESTAMP
38 global_asn1_print = False
39 global_hexdump = False
42 class AsReqBaseTest(KDCBaseTest):
43 def _run_as_req_enc_timestamp(self, client_creds):
44 client_account = client_creds.get_username()
45 client_as_etypes = self.get_default_enctypes()
46 client_kvno = client_creds.get_kvno()
47 krbtgt_creds = self.get_krbtgt_creds(require_strongest_key=True)
48 krbtgt_account = krbtgt_creds.get_username()
49 realm = krbtgt_creds.get_realm()
51 cname = self.PrincipalName_create(name_type=NT_PRINCIPAL,
52 names=[client_account])
53 sname = self.PrincipalName_create(name_type=NT_SRV_INST,
54 names=[krbtgt_account, realm])
56 expected_crealm = realm
57 expected_cname = cname
58 expected_srealm = realm
59 expected_sname = sname
60 expected_salt = client_creds.get_salt()
62 till = self.get_KerberosTime(offset=36000)
64 initial_etypes = client_as_etypes
65 initial_kdc_options = krb5_asn1.KDCOptions('forwardable')
66 initial_error_mode = KDC_ERR_PREAUTH_REQUIRED
68 rep, kdc_exchange_dict = self._test_as_exchange(cname,
69 realm,
70 sname,
71 till,
72 client_as_etypes,
73 initial_error_mode,
74 expected_crealm,
75 expected_cname,
76 expected_srealm,
77 expected_sname,
78 expected_salt,
79 initial_etypes,
80 None,
81 initial_kdc_options,
82 pac_request=True)
83 etype_info2 = kdc_exchange_dict['preauth_etype_info2']
84 self.assertIsNotNone(etype_info2)
86 preauth_key = self.PasswordKey_from_etype_info2(client_creds,
87 etype_info2[0],
88 kvno=client_kvno)
90 (patime, pausec) = self.get_KerberosTimeWithUsec()
91 pa_ts = self.PA_ENC_TS_ENC_create(patime, pausec)
92 pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.PA_ENC_TS_ENC())
94 enc_pa_ts_usage = KU_PA_ENC_TIMESTAMP
95 pa_ts = self.EncryptedData_create(preauth_key, enc_pa_ts_usage, pa_ts)
96 pa_ts = self.der_encode(pa_ts, asn1Spec=krb5_asn1.EncryptedData())
98 pa_ts = self.PA_DATA_create(PADATA_ENC_TIMESTAMP, pa_ts)
100 preauth_padata = [pa_ts]
101 preauth_etypes = client_as_etypes
102 preauth_kdc_options = krb5_asn1.KDCOptions('forwardable')
103 preauth_error_mode = 0 # AS-REP
105 krbtgt_decryption_key = (
106 self.TicketDecryptionKey_from_creds(krbtgt_creds))
108 as_rep, kdc_exchange_dict = self._test_as_exchange(
109 cname,
110 realm,
111 sname,
112 till,
113 client_as_etypes,
114 preauth_error_mode,
115 expected_crealm,
116 expected_cname,
117 expected_srealm,
118 expected_sname,
119 expected_salt,
120 preauth_etypes,
121 preauth_padata,
122 preauth_kdc_options,
123 preauth_key=preauth_key,
124 ticket_decryption_key=krbtgt_decryption_key,
125 pac_request=True)
126 self.assertIsNotNone(as_rep)
128 return etype_info2
131 @DynamicTestCase
132 class AsReqKerberosTests(AsReqBaseTest):
134 @classmethod
135 def setUpDynamicTestCases(cls):
136 for (name, idx) in cls.etype_test_permutation_name_idx():
137 for pac in [None, True, False]:
138 tname = "%s_pac_%s" % (name, pac)
139 targs = (idx, pac)
140 cls.generate_dynamic_test("test_as_req_no_preauth", tname, *targs)
142 def setUp(self):
143 super(AsReqKerberosTests, self).setUp()
144 self.do_asn1_print = global_asn1_print
145 self.do_hexdump = global_hexdump
147 def _test_as_req_nopreauth(self,
148 initial_etypes,
149 pac=None,
150 initial_kdc_options=None):
151 client_creds = self.get_client_creds()
152 client_account = client_creds.get_username()
153 client_as_etypes = self.get_default_enctypes()
154 krbtgt_creds = self.get_krbtgt_creds(require_keys=False)
155 krbtgt_account = krbtgt_creds.get_username()
156 realm = krbtgt_creds.get_realm()
158 cname = self.PrincipalName_create(name_type=NT_PRINCIPAL,
159 names=[client_account])
160 sname = self.PrincipalName_create(name_type=NT_SRV_INST,
161 names=[krbtgt_account, realm])
163 expected_crealm = realm
164 expected_cname = cname
165 expected_srealm = realm
166 expected_sname = sname
167 expected_salt = client_creds.get_salt()
169 if any(etype in client_as_etypes and etype in initial_etypes
170 for etype in (kcrypto.Enctype.AES256,
171 kcrypto.Enctype.AES128,
172 kcrypto.Enctype.RC4)):
173 expected_error_mode = KDC_ERR_PREAUTH_REQUIRED
174 else:
175 expected_error_mode = KDC_ERR_ETYPE_NOSUPP
177 kdc_exchange_dict = self.as_exchange_dict(
178 expected_crealm=expected_crealm,
179 expected_cname=expected_cname,
180 expected_srealm=expected_srealm,
181 expected_sname=expected_sname,
182 generate_padata_fn=None,
183 check_error_fn=self.generic_check_kdc_error,
184 check_rep_fn=None,
185 expected_error_mode=expected_error_mode,
186 client_as_etypes=client_as_etypes,
187 expected_salt=expected_salt,
188 kdc_options=str(initial_kdc_options),
189 pac_request=pac)
191 self._generic_kdc_exchange(kdc_exchange_dict,
192 cname=cname,
193 realm=realm,
194 sname=sname,
195 etypes=initial_etypes)
197 def _test_as_req_no_preauth_with_args(self, etype_idx, pac):
198 name, etypes = self.etype_test_permutation_by_idx(etype_idx)
199 self._test_as_req_nopreauth(
200 pac=pac,
201 initial_etypes=etypes,
202 initial_kdc_options=krb5_asn1.KDCOptions('forwardable'))
204 def test_as_req_enc_timestamp(self):
205 client_creds = self.get_client_creds()
206 self._run_as_req_enc_timestamp(client_creds)
208 def test_as_req_enc_timestamp_mac(self):
209 client_creds = self.get_mach_creds()
210 self._run_as_req_enc_timestamp(client_creds)
212 def test_as_req_enc_timestamp_rc4(self):
213 client_creds = self.get_client_creds()
214 self._run_as_req_enc_timestamp(
215 client_creds,
216 etypes={kcrypto.Enctype.RC4})
218 def test_as_req_enc_timestamp_mac_rc4(self):
219 client_creds = self.get_mach_creds()
220 self._run_as_req_enc_timestamp(
221 client_creds,
222 etypes={kcrypto.Enctype.RC4})
224 def test_as_req_enc_timestamp_rc4_dummy(self):
225 client_creds = self.get_client_creds()
226 self._run_as_req_enc_timestamp(
227 client_creds,
228 etypes={kcrypto.Enctype.RC4,
229 -1111})
231 def test_as_req_enc_timestamp_mac_rc4_dummy(self):
232 client_creds = self.get_mach_creds()
233 self._run_as_req_enc_timestamp(
234 client_creds,
235 etypes={kcrypto.Enctype.RC4,
236 -1111})
238 def test_as_req_enc_timestamp_aes128_rc4(self):
239 client_creds = self.get_client_creds()
240 self._run_as_req_enc_timestamp(
241 client_creds,
242 etypes={kcrypto.Enctype.AES128,
243 kcrypto.Enctype.RC4})
245 def test_as_req_enc_timestamp_mac_aes128_rc4(self):
246 client_creds = self.get_mach_creds()
247 self._run_as_req_enc_timestamp(
248 client_creds,
249 etypes={kcrypto.Enctype.AES128,
250 kcrypto.Enctype.RC4})
253 if __name__ == "__main__":
254 global_asn1_print = False
255 global_hexdump = False
256 import unittest
257 unittest.main()