LCOV - code coverage report
Current view: top level - source3/rpc_client - init_lsa.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 94 116 81.0 %
Date: 2024-05-31 13:13:24 Functions: 5 6 83.3 %

          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       39390 : void init_lsa_String(struct lsa_String *name, const char *s)
      35             : {
      36       39390 :         name->string = s;
      37       39390 :         name->size = 2 * strlen_m(s);
      38       39390 :         name->length = name->size;
      39       39390 : }
      40             : 
      41             : /*******************************************************************
      42             :  inits a structure.
      43             : ********************************************************************/
      44             : 
      45        1550 : void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
      46             : {
      47        1550 :         name->string = s;
      48        1550 : }
      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             : }

Generated by: LCOV version 1.14