2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Guenther Deschner 2008.
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.
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.
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/>.
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"
27 #include <gnutls/gnutls.h>
28 #include <gnutls/crypto.h>
30 /*******************************************************************
32 ********************************************************************/
34 void init_lsa_String(struct lsa_String
*name
, const char *s
)
37 name
->size
= 2 * strlen_m(s
);
38 name
->length
= name
->size
;
41 /*******************************************************************
43 ********************************************************************/
45 void init_lsa_StringLarge(struct lsa_StringLarge
*name
, const char *s
)
50 /*******************************************************************
52 ********************************************************************/
54 void init_lsa_AsciiString(struct lsa_AsciiString
*name
, const char *s
)
59 /*******************************************************************
61 ********************************************************************/
63 void init_lsa_AsciiStringLarge(struct lsa_AsciiStringLarge
*name
, const char *s
)
68 bool rpc_lsa_encrypt_trustdom_info(
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
)
77 struct timeval tv_now
= timeval_current();
78 NTTIME now
= timeval_to_nttime(&tv_now
);
80 struct lsa_TrustDomainInfoAuthInfoInternal
*authinfo_internal
= NULL
;
81 struct AuthenticationInformation in_cur_td_info
= {
82 .AuthType
= TRUST_AUTH_TYPE_CLEAR
,
83 .LastUpdateTime
= now
,
85 struct AuthenticationInformation in_prev_td_buf
= {
86 .AuthType
= TRUST_AUTH_TYPE_CLEAR
,
87 .LastUpdateTime
= now
,
89 struct AuthenticationInformation out_cur_td_info
= {
90 .AuthType
= TRUST_AUTH_TYPE_CLEAR
,
91 .LastUpdateTime
= now
,
93 struct AuthenticationInformation out_prev_td_buf
= {
94 .AuthType
= TRUST_AUTH_TYPE_CLEAR
,
95 .LastUpdateTime
= now
,
99 * This corresponds to MS-LSAD 2.2.7.16 LSAPR_TRUSTED_DOMAIN_AUTH_BLOB.
101 struct trustDomainPasswords dom_auth_info
= {
106 .array
= &in_prev_td_buf
,
111 .array
= &in_cur_td_info
,
119 .array
= &out_prev_td_buf
,
124 .array
= &out_cur_td_info
,
129 size_t converted_size
= 0;
130 DATA_BLOB dom_auth_blob
= data_blob_null
;
131 enum ndr_err_code ndr_err
;
133 gnutls_cipher_hd_t cipher_hnd
= NULL
;
134 gnutls_datum_t _session_key
= {
135 .data
= session_key
.data
,
136 .size
= session_key
.length
,
139 authinfo_internal
= talloc_zero(
140 mem_ctx
, struct lsa_TrustDomainInfoAuthInfoInternal
);
141 if (authinfo_internal
== NULL
) {
145 ok
= convert_string_talloc(mem_ctx
,
149 strlen(incoming_new
),
150 &in_cur_td_info
.AuthInfo
.clear
.password
,
155 in_cur_td_info
.AuthInfo
.clear
.size
= converted_size
;
157 ok
= convert_string_talloc(mem_ctx
,
161 strlen(incoming_old
),
162 &in_prev_td_buf
.AuthInfo
.clear
.password
,
167 in_prev_td_buf
.AuthInfo
.clear
.size
= converted_size
;
169 ok
= convert_string_talloc(mem_ctx
,
173 strlen(outgoing_new
),
174 &out_cur_td_info
.AuthInfo
.clear
.password
,
179 out_cur_td_info
.AuthInfo
.clear
.size
= converted_size
;
181 ok
= convert_string_talloc(mem_ctx
,
185 strlen(outgoing_old
),
186 &out_prev_td_buf
.AuthInfo
.clear
.password
,
191 out_prev_td_buf
.AuthInfo
.clear
.size
= converted_size
;
193 generate_random_buffer(dom_auth_info
.confounder
,
194 sizeof(dom_auth_info
.confounder
));
196 ndr_err
= ndr_push_struct_blob(
200 (ndr_push_flags_fn_t
)ndr_push_trustDomainPasswords
);
201 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
204 generate_random_buffer(dom_auth_info
.confounder
,
205 sizeof(dom_auth_info
.confounder
));
207 gnutls_cipher_init(&cipher_hnd
,
208 GNUTLS_CIPHER_ARCFOUR_128
,
211 gnutls_cipher_encrypt(cipher_hnd
,
213 dom_auth_blob
.length
);
214 gnutls_cipher_deinit(cipher_hnd
);
216 authinfo_internal
->auth_blob
.size
= dom_auth_blob
.length
;
217 authinfo_internal
->auth_blob
.data
= dom_auth_blob
.data
;
219 *_authinfo_internal
= authinfo_internal
;
224 bool rpc_lsa_encrypt_trustdom_info_aes(
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
)
233 struct timeval tv_now
= timeval_current();
234 NTTIME now
= timeval_to_nttime(&tv_now
);
236 struct AuthenticationInformation in_cur_td_info
= {
237 .AuthType
= TRUST_AUTH_TYPE_CLEAR
,
238 .LastUpdateTime
= now
,
240 struct AuthenticationInformation in_prev_td_buf
= {
241 .AuthType
= TRUST_AUTH_TYPE_CLEAR
,
242 .LastUpdateTime
= now
,
244 struct AuthenticationInformation out_cur_td_info
= {
245 .AuthType
= TRUST_AUTH_TYPE_CLEAR
,
246 .LastUpdateTime
= now
,
248 struct AuthenticationInformation out_prev_td_buf
= {
249 .AuthType
= TRUST_AUTH_TYPE_CLEAR
,
250 .LastUpdateTime
= now
,
254 * This corresponds to MS-LSAD 2.2.7.16 LSAPR_TRUSTED_DOMAIN_AUTH_BLOB.
256 struct trustDomainPasswords dom_auth_info
= {
261 .array
= &in_prev_td_buf
,
266 .array
= &in_cur_td_info
,
274 .array
= &out_prev_td_buf
,
279 .array
= &out_cur_td_info
,
284 struct lsa_TrustDomainInfoAuthInfoInternalAES
*authinfo_internal
= NULL
;
285 size_t converted_size
= 0;
286 DATA_BLOB dom_auth_blob
= data_blob_null
;
287 enum ndr_err_code ndr_err
;
293 gnutls_datum_t iv_datum
= {
296 /* Encrypted ciphertext */
297 DATA_BLOB ciphertext
= data_blob_null
;
300 authinfo_internal
= talloc_zero(
301 mem_ctx
, struct lsa_TrustDomainInfoAuthInfoInternalAES
);
302 if (authinfo_internal
== NULL
) {
306 ok
= convert_string_talloc(mem_ctx
,
310 strlen(incoming_new
),
311 &in_cur_td_info
.AuthInfo
.clear
.password
,
316 in_cur_td_info
.AuthInfo
.clear
.size
= converted_size
;
318 ok
= convert_string_talloc(mem_ctx
,
322 strlen(incoming_old
),
323 &in_prev_td_buf
.AuthInfo
.clear
.password
,
328 in_prev_td_buf
.AuthInfo
.clear
.size
= converted_size
;
330 ok
= convert_string_talloc(mem_ctx
,
334 strlen(outgoing_new
),
335 &out_cur_td_info
.AuthInfo
.clear
.password
,
340 out_cur_td_info
.AuthInfo
.clear
.size
= converted_size
;
342 ok
= convert_string_talloc(mem_ctx
,
346 strlen(outgoing_old
),
347 &out_prev_td_buf
.AuthInfo
.clear
.password
,
352 out_prev_td_buf
.AuthInfo
.clear
.size
= converted_size
;
354 generate_random_buffer(dom_auth_info
.confounder
,
355 sizeof(dom_auth_info
.confounder
));
357 ndr_err
= ndr_push_struct_blob(
361 (ndr_push_flags_fn_t
)ndr_push_trustDomainPasswords
);
362 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
367 iv
.data
= iv_datum
.data
= authinfo_internal
->salt
;
368 iv
.length
= iv_datum
.size
= sizeof(authinfo_internal
->salt
);
369 generate_nonce_buffer(authinfo_internal
->salt
,
370 sizeof(authinfo_internal
->salt
));
372 /* Create encryption key */
373 status
= samba_gnutls_aead_aes_256_cbc_hmac_sha512_encrypt(
377 &lsa_aes256_enc_key_salt
,
378 &lsa_aes256_mac_key_salt
,
381 authinfo_internal
->auth_data
);
382 if (!NT_STATUS_IS_OK(status
)) {
386 if (ciphertext
.length
< 520) {
390 authinfo_internal
->cipher
.data
= ciphertext
.data
;
391 authinfo_internal
->cipher
.size
= ciphertext
.length
;
393 *pauthinfo_internal
= authinfo_internal
;