From: Douglas Bagnall Date: Thu, 22 Feb 2024 03:17:37 +0000 (+1300) Subject: pytest:gkdi: shift create_root_key into a function X-Git-Tag: tdb-1.4.11~1629 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c6208a3b0ec1d8a6c76755d66846d28deb274123;p=thirdparty%2Fsamba.git pytest:gkdi: shift create_root_key into a function This is so the samba-tool domain kds root_key tests can use it as a function. Signed-off-by: Douglas Bagnall Reviewed-by: Andrew Bartlett --- diff --git a/python/samba/tests/gkdi.py b/python/samba/tests/gkdi.py index 3ea8afd8146..30ddd78025a 100644 --- a/python/samba/tests/gkdi.py +++ b/python/samba/tests/gkdi.py @@ -511,138 +511,169 @@ class GkdiBaseTest(TestCase): guid: Optional[misc.GUID] = None, data: Optional[bytes] = None, ) -> misc.GUID: - # [MS-GKDI] 3.1.4.1.1, “Creating a New Root Key”, states that if the - # server receives a GetKey request and the root keys container in Active - # Directory is empty, the the server must create a new root key object - # based on the default Server Configuration object. Additional root keys - # are to be created based on either the default Server Configuration - # object or an updated one specifying optional configuration values. - - guid_specified = guid is not None - if not guid_specified: - guid = misc.GUID(secrets.token_bytes(16)) - - if data is None: - data = secrets.token_bytes(KEY_LEN_BYTES) - - create_time = current_nt_time = self.current_nt_time() - - if use_start_time is None: - # Root keys created by Windows without the ‘-EffectiveImmediately’ - # parameter have an effective time of exactly ten days in the - # future, presumably to allow time for replication. - # - # Microsoft’s documentation on creating a KDS root key, located at - # https://learn.microsoft.com/en-us/windows-server/security/group-managed-service-accounts/create-the-key-distribution-services-kds-root-key, - # claims to the contrary that domain controllers will only wait up - # to ten hours before allowing Group Managed Service Accounts to be - # created. - # - # The same page includes instructions for creating a root key with - # an effective time of ten hours in the past (for testing purposes), - # but I’m not sure why — the KDS will consider a key valid for use - # immediately after its start time has passed, without bothering to - # wait ten hours first. In fact, it will consider a key to be valid - # a full ten hours (plus clock skew) *before* its declared start - # time — intentional, or (conceivably) the result of an accidental - # negation? - current_interval_start_nt_time = Gkid.from_nt_time( - current_nt_time - ).start_nt_time() - use_start_time = NtTime( - current_interval_start_nt_time + KEY_CYCLE_DURATION + MAX_CLOCK_SKEW - ) - - if isinstance(use_start_time, datetime.datetime): - use_start_nt_time = nt_time_from_datetime(use_start_time) - else: - self.assertIsInstance(use_start_time, int) - use_start_nt_time = use_start_time - - kdf_parameters = None - if hash_algorithm is not None: - kdf_parameters = gkdi.KdfParameters() - kdf_parameters.hash_algorithm = hash_algorithm.value - kdf_parameters = ndr_pack(kdf_parameters) - - # These are the encoded p and g values, respectively, of the “2048‐bit - # MODP Group with 256‐bit Prime Order Subgroup” from RFC 5114 section - # 2.3. - field_order = ( - b"\x87\xa8\xe6\x1d\xb4\xb6f<\xff\xbb\xd1\x9ce\x19Y\x99\x8c\xee\xf6\x08" - b"f\r\xd0\xf2],\xee\xd4C^;\x00\xe0\r\xf8\xf1\xd6\x19W\xd4\xfa\xf7\xdfE" - b"a\xb2\xaa0\x16\xc3\xd9\x114\to\xaa;\xf4)m\x83\x0e\x9a|" - b" \x9e\x0cd\x97Qz\xbd" - b'Z\x8a\x9d0k\xcfg\xed\x91\xf9\xe6r[GX\xc0"\xe0\xb1\xefBu\xbf{l[\xfc\x11' - b"\xd4_\x90\x88\xb9A\xf5N\xb1\xe5\x9b\xb8\xbc9\xa0\xbf\x120\x7f\\O\xdbp\xc5" - b"\x81\xb2?v\xb6:\xca\xe1\xca\xa6\xb7\x90-RRg5H\x8a\x0e\xf1 Tuple[misc.GUID, ldb.Dn]: + # [MS-GKDI] 3.1.4.1.1, “Creating a New Root Key”, states that if the + # server receives a GetKey request and the root keys container in Active + # Directory is empty, the the server must create a new root key object + # based on the default Server Configuration object. Additional root keys + # are to be created based on either the default Server Configuration + # object or an updated one specifying optional configuration values. + + if guid is None: + guid = misc.GUID(secrets.token_bytes(16)) + + if data is None: + data = secrets.token_bytes(KEY_LEN_BYTES) + + create_time = current_nt_time + + if use_start_time is None: + # Root keys created by Windows without the ‘-EffectiveImmediately’ + # parameter have an effective time of exactly ten days in the + # future, presumably to allow time for replication. + # + # Microsoft’s documentation on creating a KDS root key, located at + # https://learn.microsoft.com/en-us/windows-server/security/group-managed-service-accounts/create-the-key-distribution-services-kds-root-key, + # claims to the contrary that domain controllers will only wait up + # to ten hours before allowing Group Managed Service Accounts to be + # created. + # + # The same page includes instructions for creating a root key with + # an effective time of ten hours in the past (for testing purposes), + # but I’m not sure why — the KDS will consider a key valid for use + # immediately after its start time has passed, without bothering to + # wait ten hours first. In fact, it will consider a key to be valid + # a full ten hours (plus clock skew) *before* its declared start + # time — intentional, or (conceivably) the result of an accidental + # negation? + current_interval_start_nt_time = Gkid.from_nt_time( + current_nt_time + ).start_nt_time() + use_start_time = NtTime( + current_interval_start_nt_time + KEY_CYCLE_DURATION + MAX_CLOCK_SKEW + ) + + if isinstance(use_start_time, datetime.datetime): + use_start_nt_time = nt_time_from_datetime(use_start_time) + elif isinstance(use_start_time, int): + use_start_nt_time = use_start_time + else: + raise ValueError("use_start_time should be a datatime or int") + + kdf_parameters = None + if hash_algorithm is not None: + kdf_parameters = gkdi.KdfParameters() + kdf_parameters.hash_algorithm = hash_algorithm.value + kdf_parameters = ndr_pack(kdf_parameters) + + # These are the encoded p and g values, respectively, of the “2048‐bit + # MODP Group with 256‐bit Prime Order Subgroup” from RFC 5114 section + # 2.3. + field_order = ( + b"\x87\xa8\xe6\x1d\xb4\xb6f<\xff\xbb\xd1\x9ce\x19Y\x99\x8c\xee\xf6\x08" + b"f\r\xd0\xf2],\xee\xd4C^;\x00\xe0\r\xf8\xf1\xd6\x19W\xd4\xfa\xf7\xdfE" + b"a\xb2\xaa0\x16\xc3\xd9\x114\to\xaa;\xf4)m\x83\x0e\x9a|" + b" \x9e\x0cd\x97Qz\xbd" + b'Z\x8a\x9d0k\xcfg\xed\x91\xf9\xe6r[GX\xc0"\xe0\xb1\xefBu\xbf{l[\xfc\x11' + b"\xd4_\x90\x88\xb9A\xf5N\xb1\xe5\x9b\xb8\xbc9\xa0\xbf\x120\x7f\\O\xdbp\xc5" + b"\x81\xb2?v\xb6:\xca\xe1\xca\xa6\xb7\x90-RRg5H\x8a\x0e\xf1