Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : * RPC Pipe client / server routines
4 : * Copyright (C) Guenther Deschner 2008.
5 : *
6 : * This program is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU General Public License as published by
8 : * the Free Software Foundation; either version 3 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * This program is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License
17 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include "includes.h"
21 : #include "librpc/gen_ndr/lsa.h"
22 : #include "librpc/gen_ndr/ndr_drsblobs.h"
23 : #include "rpc_client/init_lsa.h"
24 : #include "lib/crypto/gnutls_helpers.h"
25 : #include "librpc/rpc/dcerpc_lsa.h"
26 :
27 : #include <gnutls/gnutls.h>
28 : #include <gnutls/crypto.h>
29 :
30 : /*******************************************************************
31 : inits a structure.
32 : ********************************************************************/
33 :
34 39312 : void init_lsa_String(struct lsa_String *name, const char *s)
35 : {
36 39312 : name->string = s;
37 39312 : name->size = 2 * strlen_m(s);
38 39312 : name->length = name->size;
39 39312 : }
40 :
41 : /*******************************************************************
42 : inits a structure.
43 : ********************************************************************/
44 :
45 1570 : void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
46 : {
47 1570 : name->string = s;
48 1570 : }
49 :
50 : /*******************************************************************
51 : inits a structure.
52 : ********************************************************************/
53 :
54 8 : void init_lsa_AsciiString(struct lsa_AsciiString *name, const char *s)
55 : {
56 8 : name->string = s;
57 8 : }
58 :
59 : /*******************************************************************
60 : inits a structure.
61 : ********************************************************************/
62 :
63 0 : void init_lsa_AsciiStringLarge(struct lsa_AsciiStringLarge *name, const char *s)
64 : {
65 0 : name->string = s;
66 0 : }
67 :
68 36 : bool rpc_lsa_encrypt_trustdom_info(
69 : TALLOC_CTX *mem_ctx,
70 : const char *incoming_old,
71 : const char *incoming_new,
72 : const char *outgoing_old,
73 : const char *outgoing_new,
74 : DATA_BLOB session_key,
75 : struct lsa_TrustDomainInfoAuthInfoInternal **_authinfo_internal)
76 : {
77 36 : struct timeval tv_now = timeval_current();
78 36 : NTTIME now = timeval_to_nttime(&tv_now);
79 :
80 36 : struct lsa_TrustDomainInfoAuthInfoInternal *authinfo_internal = NULL;
81 36 : struct AuthenticationInformation in_cur_td_info = {
82 : .AuthType = TRUST_AUTH_TYPE_CLEAR,
83 : .LastUpdateTime = now,
84 : };
85 36 : struct AuthenticationInformation in_prev_td_buf = {
86 : .AuthType = TRUST_AUTH_TYPE_CLEAR,
87 : .LastUpdateTime = now,
88 : };
89 36 : struct AuthenticationInformation out_cur_td_info = {
90 : .AuthType = TRUST_AUTH_TYPE_CLEAR,
91 : .LastUpdateTime = now,
92 : };
93 36 : struct AuthenticationInformation out_prev_td_buf = {
94 : .AuthType = TRUST_AUTH_TYPE_CLEAR,
95 : .LastUpdateTime = now,
96 : };
97 :
98 : /*
99 : * This corresponds to MS-LSAD 2.2.7.16 LSAPR_TRUSTED_DOMAIN_AUTH_BLOB.
100 : */
101 36 : struct trustDomainPasswords dom_auth_info = {
102 : .incoming = {
103 : .count = 1,
104 : .previous = {
105 : .count = 1,
106 : .array = &in_prev_td_buf,
107 :
108 : },
109 : .current = {
110 : .count = 1,
111 : .array = &in_cur_td_info,
112 : },
113 : },
114 :
115 : .outgoing = {
116 : .count = 1,
117 : .previous = {
118 : .count = 1,
119 : .array = &out_prev_td_buf,
120 :
121 : },
122 : .current = {
123 : .count = 1,
124 : .array = &out_cur_td_info,
125 : },
126 : }
127 : };
128 :
129 36 : size_t converted_size = 0;
130 36 : DATA_BLOB dom_auth_blob = data_blob_null;
131 0 : enum ndr_err_code ndr_err;
132 0 : bool ok;
133 36 : gnutls_cipher_hd_t cipher_hnd = NULL;
134 36 : gnutls_datum_t _session_key = {
135 36 : .data = session_key.data,
136 36 : .size = session_key.length,
137 : };
138 :
139 36 : authinfo_internal = talloc_zero(
140 : mem_ctx, struct lsa_TrustDomainInfoAuthInfoInternal);
141 36 : if (authinfo_internal == NULL) {
142 0 : return false;
143 : }
144 :
145 36 : ok = convert_string_talloc(mem_ctx,
146 : CH_UNIX,
147 : CH_UTF16,
148 : incoming_new,
149 : strlen(incoming_new),
150 : &in_cur_td_info.AuthInfo.clear.password,
151 : &converted_size);
152 36 : if (!ok) {
153 0 : return false;
154 : }
155 36 : in_cur_td_info.AuthInfo.clear.size = converted_size;
156 :
157 36 : ok = convert_string_talloc(mem_ctx,
158 : CH_UNIX,
159 : CH_UTF16,
160 : incoming_old,
161 : strlen(incoming_old),
162 : &in_prev_td_buf.AuthInfo.clear.password,
163 : &converted_size);
164 36 : if (!ok) {
165 0 : return false;
166 : }
167 36 : in_prev_td_buf.AuthInfo.clear.size = converted_size;
168 :
169 36 : ok = convert_string_talloc(mem_ctx,
170 : CH_UNIX,
171 : CH_UTF16,
172 : outgoing_new,
173 : strlen(outgoing_new),
174 : &out_cur_td_info.AuthInfo.clear.password,
175 : &converted_size);
176 36 : if (!ok) {
177 0 : return false;
178 : }
179 36 : out_cur_td_info.AuthInfo.clear.size = converted_size;
180 :
181 36 : ok = convert_string_talloc(mem_ctx,
182 : CH_UNIX,
183 : CH_UTF16,
184 : outgoing_old,
185 : strlen(outgoing_old),
186 : &out_prev_td_buf.AuthInfo.clear.password,
187 : &converted_size);
188 36 : if (!ok) {
189 0 : return false;
190 : }
191 36 : out_prev_td_buf.AuthInfo.clear.size = converted_size;
192 :
193 36 : generate_random_buffer(dom_auth_info.confounder,
194 : sizeof(dom_auth_info.confounder));
195 :
196 36 : ndr_err = ndr_push_struct_blob(
197 : &dom_auth_blob,
198 : authinfo_internal,
199 : &dom_auth_info,
200 : (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
201 36 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
202 0 : return false;
203 : }
204 36 : generate_random_buffer(dom_auth_info.confounder,
205 : sizeof(dom_auth_info.confounder));
206 :
207 36 : gnutls_cipher_init(&cipher_hnd,
208 : GNUTLS_CIPHER_ARCFOUR_128,
209 : &_session_key,
210 : NULL);
211 36 : gnutls_cipher_encrypt(cipher_hnd,
212 36 : dom_auth_blob.data,
213 : dom_auth_blob.length);
214 36 : gnutls_cipher_deinit(cipher_hnd);
215 :
216 36 : authinfo_internal->auth_blob.size = dom_auth_blob.length;
217 36 : authinfo_internal->auth_blob.data = dom_auth_blob.data;
218 :
219 36 : *_authinfo_internal = authinfo_internal;
220 :
221 36 : return true;
222 : }
223 :
224 36 : bool rpc_lsa_encrypt_trustdom_info_aes(
225 : TALLOC_CTX *mem_ctx,
226 : const char *incoming_old,
227 : const char *incoming_new,
228 : const char *outgoing_old,
229 : const char *outgoing_new,
230 : DATA_BLOB session_key,
231 : struct lsa_TrustDomainInfoAuthInfoInternalAES **pauthinfo_internal)
232 : {
233 36 : struct timeval tv_now = timeval_current();
234 36 : NTTIME now = timeval_to_nttime(&tv_now);
235 :
236 36 : struct AuthenticationInformation in_cur_td_info = {
237 : .AuthType = TRUST_AUTH_TYPE_CLEAR,
238 : .LastUpdateTime = now,
239 : };
240 36 : struct AuthenticationInformation in_prev_td_buf = {
241 : .AuthType = TRUST_AUTH_TYPE_CLEAR,
242 : .LastUpdateTime = now,
243 : };
244 36 : struct AuthenticationInformation out_cur_td_info = {
245 : .AuthType = TRUST_AUTH_TYPE_CLEAR,
246 : .LastUpdateTime = now,
247 : };
248 36 : struct AuthenticationInformation out_prev_td_buf = {
249 : .AuthType = TRUST_AUTH_TYPE_CLEAR,
250 : .LastUpdateTime = now,
251 : };
252 :
253 : /*
254 : * This corresponds to MS-LSAD 2.2.7.16 LSAPR_TRUSTED_DOMAIN_AUTH_BLOB.
255 : */
256 36 : struct trustDomainPasswords dom_auth_info = {
257 : .incoming = {
258 : .count = 1,
259 : .previous = {
260 : .count = 1,
261 : .array = &in_prev_td_buf,
262 :
263 : },
264 : .current = {
265 : .count = 1,
266 : .array = &in_cur_td_info,
267 : },
268 : },
269 :
270 : .outgoing = {
271 : .count = 1,
272 : .previous = {
273 : .count = 1,
274 : .array = &out_prev_td_buf,
275 :
276 : },
277 : .current = {
278 : .count = 1,
279 : .array = &out_cur_td_info,
280 : },
281 : }
282 : };
283 :
284 36 : struct lsa_TrustDomainInfoAuthInfoInternalAES *authinfo_internal = NULL;
285 36 : size_t converted_size = 0;
286 36 : DATA_BLOB dom_auth_blob = data_blob_null;
287 0 : enum ndr_err_code ndr_err;
288 0 : bool ok;
289 : /* Salt */
290 36 : DATA_BLOB iv = {
291 : .length = 0,
292 : };
293 36 : gnutls_datum_t iv_datum = {
294 : .size = 0,
295 : };
296 : /* Encrypted ciphertext */
297 36 : DATA_BLOB ciphertext = data_blob_null;
298 0 : NTSTATUS status;
299 :
300 36 : authinfo_internal = talloc_zero(
301 : mem_ctx, struct lsa_TrustDomainInfoAuthInfoInternalAES);
302 36 : if (authinfo_internal == NULL) {
303 0 : return false;
304 : }
305 :
306 36 : ok = convert_string_talloc(mem_ctx,
307 : CH_UNIX,
308 : CH_UTF16,
309 : incoming_new,
310 : strlen(incoming_new),
311 : &in_cur_td_info.AuthInfo.clear.password,
312 : &converted_size);
313 36 : if (!ok) {
314 0 : return false;
315 : }
316 36 : in_cur_td_info.AuthInfo.clear.size = converted_size;
317 :
318 36 : ok = convert_string_talloc(mem_ctx,
319 : CH_UNIX,
320 : CH_UTF16,
321 : incoming_old,
322 : strlen(incoming_old),
323 : &in_prev_td_buf.AuthInfo.clear.password,
324 : &converted_size);
325 36 : if (!ok) {
326 0 : return false;
327 : }
328 36 : in_prev_td_buf.AuthInfo.clear.size = converted_size;
329 :
330 36 : ok = convert_string_talloc(mem_ctx,
331 : CH_UNIX,
332 : CH_UTF16,
333 : outgoing_new,
334 : strlen(outgoing_new),
335 : &out_cur_td_info.AuthInfo.clear.password,
336 : &converted_size);
337 36 : if (!ok) {
338 0 : return false;
339 : }
340 36 : out_cur_td_info.AuthInfo.clear.size = converted_size;
341 :
342 36 : ok = convert_string_talloc(mem_ctx,
343 : CH_UNIX,
344 : CH_UTF16,
345 : outgoing_old,
346 : strlen(outgoing_old),
347 : &out_prev_td_buf.AuthInfo.clear.password,
348 : &converted_size);
349 36 : if (!ok) {
350 0 : return false;
351 : }
352 36 : out_prev_td_buf.AuthInfo.clear.size = converted_size;
353 :
354 36 : generate_random_buffer(dom_auth_info.confounder,
355 : sizeof(dom_auth_info.confounder));
356 :
357 36 : ndr_err = ndr_push_struct_blob(
358 : &dom_auth_blob,
359 : authinfo_internal,
360 : &dom_auth_info,
361 : (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
362 36 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
363 0 : return false;
364 : }
365 :
366 : /* Create salt */
367 36 : iv.data = iv_datum.data = authinfo_internal->salt;
368 36 : iv.length = iv_datum.size = sizeof(authinfo_internal->salt);
369 36 : generate_nonce_buffer(authinfo_internal->salt,
370 : sizeof(authinfo_internal->salt));
371 :
372 : /* Create encryption key */
373 36 : status = samba_gnutls_aead_aes_256_cbc_hmac_sha512_encrypt(
374 : authinfo_internal,
375 : &dom_auth_blob,
376 : &session_key,
377 : &lsa_aes256_enc_key_salt,
378 : &lsa_aes256_mac_key_salt,
379 : &iv,
380 : &ciphertext,
381 36 : authinfo_internal->auth_data);
382 36 : if (!NT_STATUS_IS_OK(status)) {
383 0 : return false;
384 : }
385 :
386 36 : if (ciphertext.length < 520) {
387 0 : return false;
388 : }
389 :
390 36 : authinfo_internal->cipher.data = ciphertext.data;
391 36 : authinfo_internal->cipher.size = ciphertext.length;
392 :
393 36 : *pauthinfo_internal = authinfo_internal;
394 :
395 36 : return true;
396 : }
|