tests/gkdi: Remove implicit clock skew offset
[Samba.git] / python / samba / lsa_utils.py
bloba56675d6b63dfd3d9a491e26c1f15d53505f7239
1 # trust utils
3 # Copyright Isaac Boukris 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 from samba.dcerpc import lsa, drsblobs, misc
20 from samba.ndr import ndr_pack
21 from samba import (
22 NTSTATUSError,
23 aead_aes_256_cbc_hmac_sha512,
24 arcfour_encrypt,
25 string_to_byte_array
27 from samba.ntstatus import (
28 NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE
30 from samba import crypto
31 from secrets import token_bytes
34 def OpenPolicyFallback(
35 conn: lsa.lsarpc,
36 system_name: str,
37 in_version: int,
38 in_revision_info: lsa.revision_info1,
39 sec_qos: bool = False,
40 access_mask: int = 0,
42 attr = lsa.ObjectAttribute()
43 if sec_qos:
44 qos = lsa.QosInfo()
45 qos.len = 0xc
46 qos.impersonation_level = 2
47 qos.context_mode = 1
48 qos.effective_only = 0
50 attr.sec_qos = qos
52 try:
53 out_version, out_rev_info, policy = conn.OpenPolicy3(
54 system_name,
55 attr,
56 access_mask,
57 in_version,
58 in_revision_info
60 except NTSTATUSError as e:
61 if e.args[0] == NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE:
62 out_version = 1
63 out_rev_info = lsa.revision_info1()
64 out_rev_info.revision = 1
65 out_rev_info.supported_features = 0
67 policy = conn.OpenPolicy2(system_name, attr, access_mask)
68 else:
69 raise
71 return out_version, out_rev_info, policy
74 def CreateTrustedDomainRelax(
75 lsaconn: lsa.lsarpc,
76 policy: misc.policy_handle,
77 trust_info: lsa.TrustDomainInfoInfoEx,
78 mask: int,
79 in_blob: drsblobs.trustAuthInOutBlob,
80 out_blob: drsblobs.trustAuthInOutBlob
83 def generate_AuthInfoInternal(session_key, incoming=None, outgoing=None):
84 confounder = string_to_byte_array(token_bytes(512))
86 trustpass = drsblobs.trustDomainPasswords()
88 trustpass.confounder = confounder
89 trustpass.outgoing = outgoing
90 trustpass.incoming = incoming
92 trustpass_blob = ndr_pack(trustpass)
94 encrypted_trustpass = arcfour_encrypt(session_key, trustpass_blob)
96 auth_blob = lsa.DATA_BUF2()
97 auth_blob.size = len(encrypted_trustpass)
98 auth_blob.data = string_to_byte_array(encrypted_trustpass)
100 auth_info = lsa.TrustDomainInfoAuthInfoInternal()
101 auth_info.auth_blob = auth_blob
103 return auth_info
105 session_key = lsaconn.session_key
107 try:
108 if lsaconn.transport_encrypted():
109 crypto.set_relax_mode()
110 auth_info = generate_AuthInfoInternal(session_key,
111 incoming=in_blob,
112 outgoing=out_blob)
113 finally:
114 crypto.set_strict_mode()
116 return lsaconn.CreateTrustedDomainEx2(policy, trust_info, auth_info, mask)
119 def CreateTrustedDomainFallback(
120 conn: lsa.lsarpc,
121 policy_handle: misc.policy_handle,
122 trust_info: lsa.TrustDomainInfoInfoEx,
123 access_mask: int,
124 srv_version: int,
125 srv_revision_info1: lsa.revision_info1,
126 in_blob: drsblobs.trustAuthInOutBlob,
127 out_blob: drsblobs.trustAuthInOutBlob
129 def generate_AuthInfoInternalAES(
130 session_key,
131 incoming=None,
132 outgoing=None
134 trustpass = drsblobs.trustDomainPasswords()
136 trustpass.outgoing = outgoing
137 trustpass.incoming = incoming
139 trustpass_blob = ndr_pack(trustpass)
141 lsa_aes256_enc_key = (
142 "Microsoft LSAD encryption key AEAD-AES-256-CBC-HMAC-SHA512 16".encode()
143 + b'\x00'
145 lsa_aes256_mac_key = (
146 "Microsoft LSAD MAC key AEAD-AES-256-CBC-HMAC-SHA512 16".encode()
147 + b'\x00'
150 iv = token_bytes(16)
151 ciphertext, auth_data = aead_aes_256_cbc_hmac_sha512(
152 trustpass_blob,
153 session_key,
154 lsa_aes256_enc_key,
155 lsa_aes256_mac_key,
159 return ciphertext, iv, auth_data
161 if (srv_version == 1
162 and srv_revision_info1.revision == 1
163 and (srv_revision_info1.supported_features
164 & lsa.LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER)):
166 ciphertext, iv, auth_data = generate_AuthInfoInternalAES(
167 conn.session_key, in_blob, out_blob
170 auth_blob = lsa.DATA_BUF2()
171 auth_blob.size = len(ciphertext)
172 auth_blob.data = string_to_byte_array(ciphertext)
174 auth_info = lsa.TrustDomainInfoAuthInfoInternalAES()
175 auth_info.cipher = auth_blob
176 auth_info.salt = string_to_byte_array(iv)
177 auth_info.auth_data = string_to_byte_array(auth_data)
179 return conn.CreateTrustedDomainEx3(
180 policy_handle,
181 trust_info,
182 auth_info,
183 access_mask
186 return CreateTrustedDomainRelax(
187 conn,
188 policy_handle,
189 trust_info,
190 access_mask,
191 in_blob,
192 out_blob