From: Andreas Schneider Date: Tue, 27 Feb 2024 08:24:52 +0000 (+0100) Subject: s3:rpc_client: Implement rpc_lsa_encrypt_trustdom_info_aes() X-Git-Tag: tdb-1.4.11~1241 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d078ee6af61528f509c4242c19b64591fe897549;p=thirdparty%2Fsamba.git s3:rpc_client: Implement rpc_lsa_encrypt_trustdom_info_aes() Signed-off-by: Andreas Schneider Reviewed-by: Andrew Bartlett --- diff --git a/source3/rpc_client/init_lsa.c b/source3/rpc_client/init_lsa.c index 3d59183b901..a59a0b71e27 100644 --- a/source3/rpc_client/init_lsa.c +++ b/source3/rpc_client/init_lsa.c @@ -21,6 +21,8 @@ #include "librpc/gen_ndr/lsa.h" #include "librpc/gen_ndr/ndr_drsblobs.h" #include "rpc_client/init_lsa.h" +#include "lib/crypto/gnutls_helpers.h" +#include "librpc/rpc/dcerpc_lsa.h" #include #include @@ -218,3 +220,177 @@ bool rpc_lsa_encrypt_trustdom_info( return true; } + +bool rpc_lsa_encrypt_trustdom_info_aes( + TALLOC_CTX *mem_ctx, + const char *incoming_old, + const char *incoming_new, + const char *outgoing_old, + const char *outgoing_new, + DATA_BLOB session_key, + struct lsa_TrustDomainInfoAuthInfoInternalAES **pauthinfo_internal) +{ + struct timeval tv_now = timeval_current(); + NTTIME now = timeval_to_nttime(&tv_now); + + struct AuthenticationInformation in_cur_td_info = { + .AuthType = TRUST_AUTH_TYPE_CLEAR, + .LastUpdateTime = now, + }; + struct AuthenticationInformation in_prev_td_buf = { + .AuthType = TRUST_AUTH_TYPE_CLEAR, + .LastUpdateTime = now, + }; + struct AuthenticationInformation out_cur_td_info = { + .AuthType = TRUST_AUTH_TYPE_CLEAR, + .LastUpdateTime = now, + }; + struct AuthenticationInformation out_prev_td_buf = { + .AuthType = TRUST_AUTH_TYPE_CLEAR, + .LastUpdateTime = now, + }; + + /* + * This corresponds to MS-LSAD 2.2.7.16 LSAPR_TRUSTED_DOMAIN_AUTH_BLOB. + */ + struct trustDomainPasswords dom_auth_info = { + .incoming = { + .count = 1, + .previous = { + .count = 1, + .array = &in_prev_td_buf, + + }, + .current = { + .count = 1, + .array = &in_cur_td_info, + }, + }, + + .outgoing = { + .count = 1, + .previous = { + .count = 1, + .array = &out_prev_td_buf, + + }, + .current = { + .count = 1, + .array = &out_cur_td_info, + }, + } + }; + + struct lsa_TrustDomainInfoAuthInfoInternalAES *authinfo_internal = NULL; + size_t converted_size = 0; + DATA_BLOB dom_auth_blob = data_blob_null; + enum ndr_err_code ndr_err; + bool ok; + /* Salt */ + DATA_BLOB iv = { + .length = 0, + }; + gnutls_datum_t iv_datum = { + .size = 0, + }; + /* Encrypted ciphertext */ + DATA_BLOB ciphertext = data_blob_null; + NTSTATUS status; + + authinfo_internal = talloc_zero( + mem_ctx, struct lsa_TrustDomainInfoAuthInfoInternalAES); + if (authinfo_internal == NULL) { + return false; + } + + ok = convert_string_talloc(mem_ctx, + CH_UNIX, + CH_UTF16, + incoming_new, + strlen(incoming_new), + &in_cur_td_info.AuthInfo.clear.password, + &converted_size); + if (!ok) { + return false; + } + in_cur_td_info.AuthInfo.clear.size = converted_size; + + ok = convert_string_talloc(mem_ctx, + CH_UNIX, + CH_UTF16, + incoming_old, + strlen(incoming_old), + &in_prev_td_buf.AuthInfo.clear.password, + &converted_size); + if (!ok) { + return false; + } + in_prev_td_buf.AuthInfo.clear.size = converted_size; + + ok = convert_string_talloc(mem_ctx, + CH_UNIX, + CH_UTF16, + outgoing_new, + strlen(outgoing_new), + &out_cur_td_info.AuthInfo.clear.password, + &converted_size); + if (!ok) { + return false; + } + out_cur_td_info.AuthInfo.clear.size = converted_size; + + ok = convert_string_talloc(mem_ctx, + CH_UNIX, + CH_UTF16, + outgoing_old, + strlen(outgoing_old), + &out_prev_td_buf.AuthInfo.clear.password, + &converted_size); + if (!ok) { + return false; + } + out_prev_td_buf.AuthInfo.clear.size = converted_size; + + generate_random_buffer(dom_auth_info.confounder, + sizeof(dom_auth_info.confounder)); + + ndr_err = ndr_push_struct_blob( + &dom_auth_blob, + authinfo_internal, + &dom_auth_info, + (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return false; + } + + /* Create salt */ + iv.data = iv_datum.data = authinfo_internal->salt; + iv.length = iv_datum.size = sizeof(authinfo_internal->salt); + generate_nonce_buffer(authinfo_internal->salt, + sizeof(authinfo_internal->salt)); + + /* Create encryption key */ + status = samba_gnutls_aead_aes_256_cbc_hmac_sha512_encrypt( + authinfo_internal, + &dom_auth_blob, + &session_key, + &lsa_aes256_enc_key_salt, + &lsa_aes256_mac_key_salt, + &iv, + &ciphertext, + authinfo_internal->auth_data); + if (!NT_STATUS_IS_OK(status)) { + return false; + } + + if (ciphertext.length < 520) { + return false; + } + + authinfo_internal->cipher.data = ciphertext.data; + authinfo_internal->cipher.size = ciphertext.length; + + *pauthinfo_internal = authinfo_internal; + + return true; +} diff --git a/source3/rpc_client/init_lsa.h b/source3/rpc_client/init_lsa.h index a549343d8b5..a95bf94846b 100644 --- a/source3/rpc_client/init_lsa.h +++ b/source3/rpc_client/init_lsa.h @@ -41,4 +41,13 @@ bool rpc_lsa_encrypt_trustdom_info( DATA_BLOB session_key, struct lsa_TrustDomainInfoAuthInfoInternal **_authinfo_internal); +bool rpc_lsa_encrypt_trustdom_info_aes( + TALLOC_CTX *mem_ctx, + const char *incoming_old, + const char *incoming_new, + const char *outgoing_old, + const char *outgoing_new, + DATA_BLOB session_key, + struct lsa_TrustDomainInfoAuthInfoInternalAES **pauthinfo_internal); + #endif /* _RPC_CLIENT_INIT_LSA_H_ */ diff --git a/source3/wscript_build b/source3/wscript_build index 3fcdb5505be..50f79c2cb29 100644 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -1088,7 +1088,7 @@ bld.SAMBA3_SUBSYSTEM('RPCCLI_WSP', bld.SAMBA3_SUBSYSTEM('INIT_LSA', source='rpc_client/init_lsa.c', - deps='samba-util') + deps='samba-util GNUTLS_HELPERS') bld.SAMBA3_SUBSYSTEM('INIT_SAMR', source='rpc_client/init_samr.c',