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