From ecee1998034b84026ab604dbe4400d9e53dcafd4 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Thu, 7 Nov 2019 18:40:03 +0100 Subject: [PATCH] smbdes: convert sam_rid_crypt() to use gnutls Signed-off-by: Isaac Boukris Reviewed-by: Andrew Bartlett --- libcli/auth/proto.h | 3 ++- libcli/auth/smbdes.c | 11 +++++++--- libcli/auth/tests/test_gnutls.c | 7 +++++-- libcli/drsuapi/repl_decrypt.c | 16 +++++++++++++-- libcli/samsync/decrypt.c | 36 +++++++++++++++++++++++++-------- 5 files changed, 57 insertions(+), 16 deletions(-) diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h index b7a976c048b..7dad549fc43 100644 --- a/libcli/auth/proto.h +++ b/libcli/auth/proto.h @@ -230,7 +230,8 @@ void E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out); void des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16]); void des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14], int forw); void des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14], int forw); -void sam_rid_crypt(unsigned int rid, const uint8_t *in, uint8_t *out, int forw); +int sam_rid_crypt(unsigned int rid, const uint8_t *in, uint8_t *out, + enum samba_gnutls_direction encrypt); #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) diff --git a/libcli/auth/smbdes.c b/libcli/auth/smbdes.c index f384ef132a7..fe397592fbb 100644 --- a/libcli/auth/smbdes.c +++ b/libcli/auth/smbdes.c @@ -418,15 +418,20 @@ void des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14 /* Decode a sam password hash into a password. The password hash is the same method used to store passwords in the NT registry. The DES key used is based on the RID of the user. */ -void sam_rid_crypt(unsigned int rid, const uint8_t *in, uint8_t *out, int forw) +int sam_rid_crypt(unsigned int rid, const uint8_t *in, uint8_t *out, + enum samba_gnutls_direction encrypt) { uint8_t s[14]; + int ret; s[0] = s[4] = s[8] = s[12] = (uint8_t)(rid & 0xFF); s[1] = s[5] = s[9] = s[13] = (uint8_t)((rid >> 8) & 0xFF); s[2] = s[6] = s[10] = (uint8_t)((rid >> 16) & 0xFF); s[3] = s[7] = s[11] = (uint8_t)((rid >> 24) & 0xFF); - des_crypt56(out, in, s, forw); - des_crypt56(out+8, in+8, s+7, forw); + ret = des_crypt56_gnutls(out, in, s, encrypt); + if (ret != 0) { + return ret; + } + return des_crypt56_gnutls(out+8, in+8, s+7, encrypt); } diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c index 5bb75c2bab2..f603fa819e8 100644 --- a/libcli/auth/tests/test_gnutls.c +++ b/libcli/auth/tests/test_gnutls.c @@ -422,11 +422,14 @@ static void torture_gnutls_sam_rid_crypt(void **state) uint8_t crypt[16]; uint8_t decrypt[16]; int rid = 500; + int rc; - sam_rid_crypt(rid, clear, crypt, 1); + rc = sam_rid_crypt(rid, clear, crypt, SAMBA_GNUTLS_ENCRYPT); + assert_int_equal(rc, 0); assert_memory_equal(crypt, crypt_expected, 16); - sam_rid_crypt(rid, crypt, decrypt, 0); + rc = sam_rid_crypt(rid, crypt, decrypt, SAMBA_GNUTLS_DECRYPT); + assert_int_equal(rc, 0); assert_memory_equal(decrypt, clear, 16); } diff --git a/libcli/drsuapi/repl_decrypt.c b/libcli/drsuapi/repl_decrypt.c index 83275360c7d..30b3c64379f 100644 --- a/libcli/drsuapi/repl_decrypt.c +++ b/libcli/drsuapi/repl_decrypt.c @@ -135,7 +135,13 @@ static WERROR drsuapi_decrypt_attribute_value(TALLOC_CTX *mem_ctx, num_hashes = plain_buffer.length / 16; for (i = 0; i < num_hashes; i++) { uint32_t offset = i * 16; - sam_rid_crypt(rid, checked_buffer.data + offset, plain_buffer.data + offset, 0); + rc = sam_rid_crypt(rid, checked_buffer.data + offset, + plain_buffer.data + offset, + SAMBA_GNUTLS_DECRYPT); + if (rc != 0) { + result = gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); + goto out; + } } } @@ -255,7 +261,13 @@ static WERROR drsuapi_encrypt_attribute_value(TALLOC_CTX *mem_ctx, num_hashes = rid_crypt_out.length / 16; for (i = 0; i < num_hashes; i++) { uint32_t offset = i * 16; - sam_rid_crypt(rid, in->data + offset, rid_crypt_out.data + offset, 1); + rc = sam_rid_crypt(rid, in->data + offset, + rid_crypt_out.data + offset, + SAMBA_GNUTLS_ENCRYPT); + if (rc != 0) { + result = gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR); + goto out; + } } in = &rid_crypt_out; } diff --git a/libcli/samsync/decrypt.c b/libcli/samsync/decrypt.c index 5cda966fb42..77ef93251bc 100644 --- a/libcli/samsync/decrypt.c +++ b/libcli/samsync/decrypt.c @@ -25,6 +25,7 @@ #include "../libcli/auth/libcli_auth.h" #include "../libcli/samsync/samsync.h" #include "librpc/gen_ndr/ndr_netlogon.h" +#include "lib/crypto/gnutls_helpers.h" /** * Decrypt and extract the user's passwords. @@ -43,13 +44,19 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, struct netr_DELTA_USER *user = delta->delta_union.user; struct samr_Password lm_hash; struct samr_Password nt_hash; + int rc; /* Note that win2000 may send us all zeros * for the hashes if it doesn't * think this channel is secure enough. */ if (user->lm_password_present) { if (!all_zero(user->lmpassword.hash, 16)) { - sam_rid_crypt(rid, user->lmpassword.hash, lm_hash.hash, 0); + rc = sam_rid_crypt(rid, user->lmpassword.hash, + lm_hash.hash, SAMBA_GNUTLS_DECRYPT); + if (rc != 0) { + return gnutls_error_to_ntstatus(rc, + NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + } } else { memset(lm_hash.hash, '\0', sizeof(lm_hash.hash)); } @@ -58,7 +65,12 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, if (user->nt_password_present) { if (!all_zero(user->ntpassword.hash, 16)) { - sam_rid_crypt(rid, user->ntpassword.hash, nt_hash.hash, 0); + rc = sam_rid_crypt(rid, user->ntpassword.hash, + nt_hash.hash, SAMBA_GNUTLS_DECRYPT); + if (rc != 0) { + return gnutls_error_to_ntstatus(rc, + NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + } } else { memset(nt_hash.hash, '\0', sizeof(nt_hash.hash)); } @@ -97,9 +109,13 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, if (keys.keys.keys2.lmpassword.length == 16) { if (!all_zero(keys.keys.keys2.lmpassword.pwd.hash, 16)) { - sam_rid_crypt(rid, - keys.keys.keys2.lmpassword.pwd.hash, - lm_hash.hash, 0); + rc = sam_rid_crypt(rid, + keys.keys.keys2.lmpassword.pwd.hash, + lm_hash.hash, SAMBA_GNUTLS_DECRYPT); + if (rc != 0) { + return gnutls_error_to_ntstatus(rc, + NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + } } else { memset(lm_hash.hash, '\0', sizeof(lm_hash.hash)); } @@ -109,9 +125,13 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, if (keys.keys.keys2.ntpassword.length == 16) { if (!all_zero(keys.keys.keys2.ntpassword.pwd.hash, 16)) { - sam_rid_crypt(rid, - keys.keys.keys2.ntpassword.pwd.hash, - nt_hash.hash, 0); + rc = sam_rid_crypt(rid, + keys.keys.keys2.ntpassword.pwd.hash, + nt_hash.hash, SAMBA_GNUTLS_DECRYPT); + if (rc != 0) { + return gnutls_error_to_ntstatus(rc, + NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + } } else { memset(nt_hash.hash, '\0', sizeof(nt_hash.hash)); }