]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:rpc_client: Implement rpc_lsa_encrypt_trustdom_info_aes()
authorAndreas Schneider <asn@samba.org>
Tue, 27 Feb 2024 08:24:52 +0000 (09:24 +0100)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 9 Apr 2024 22:52:38 +0000 (22:52 +0000)
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source3/rpc_client/init_lsa.c
source3/rpc_client/init_lsa.h
source3/wscript_build

index 3d59183b90114137527213e4f2218156ede58c35..a59a0b71e27b81e7df791ae253c5166822bc36af 100644 (file)
@@ -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 <gnutls/gnutls.h>
 #include <gnutls/crypto.h>
@@ -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;
+}
index a549343d8b5d6a475400c029f07e58e9b686103d..a95bf94846bbe9b60bd3394a29c8a83a276eb235 100644 (file)
@@ -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_ */
index 3fcdb5505be5c794595f71242eafb841eb358f22..50f79c2cb290941ad1e2d6fd2463b1a6339695a9 100644 (file)
@@ -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',