#include "torture/util.h"
#include "source4/librpc/rpc/dcerpc.h"
#include "source3/rpc_client/init_samr.h"
+#include "lib/crypto/gnutls_helpers.h"
+
+#undef strcasecmp
#define TEST_ACCOUNT_NAME "samrtorturetest"
#define TEST_ACCOUNT_NAME_PWD "samrpwdlastset"
DATA_BLOB in,out;
in = data_blob_const(nt_hash, 16);
out = data_blob_talloc_zero(tctx, 16);
- sess_crypt_blob(&out, &in, &session_key, true);
+ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
memcpy(u.info18.nt_pwd.hash, out.data, out.length);
}
{
DATA_BLOB in,out;
in = data_blob_const(lm_hash, 16);
out = data_blob_talloc_zero(tctx, 16);
- sess_crypt_blob(&out, &in, &session_key, true);
+ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
memcpy(u.info18.lm_pwd.hash, out.data, out.length);
}
in = data_blob_const(u.info21.lm_owf_password.array,
u.info21.lm_owf_password.length);
out = data_blob_talloc_zero(tctx, 16);
- sess_crypt_blob(&out, &in, &session_key, true);
+ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
u.info21.lm_owf_password.array = (uint16_t *)out.data;
}
in = data_blob_const(u.info21.nt_owf_password.array,
u.info21.nt_owf_password.length);
out = data_blob_talloc_zero(tctx, 16);
- sess_crypt_blob(&out, &in, &session_key, true);
+ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
u.info21.nt_owf_password.array = (uint16_t *)out.data;
}
DATA_BLOB in,out;
in = data_blob_const(u.info18.nt_pwd.hash, 16);
out = data_blob_talloc_zero(tctx, 16);
- sess_crypt_blob(&out, &in, &session_key, true);
+ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
memcpy(u.info18.nt_pwd.hash, out.data, out.length);
}
{
DATA_BLOB in,out;
in = data_blob_const(u.info18.lm_pwd.hash, 16);
out = data_blob_talloc_zero(tctx, 16);
- sess_crypt_blob(&out, &in, &session_key, true);
+ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
memcpy(u.info18.lm_pwd.hash, out.data, out.length);
}
in = data_blob_const(u.info21.lm_owf_password.array,
u.info21.lm_owf_password.length);
out = data_blob_talloc_zero(tctx, 16);
- sess_crypt_blob(&out, &in, &session_key, true);
+ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
u.info21.lm_owf_password.array = (uint16_t *)out.data;
}
if (fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) {
in = data_blob_const(u.info21.nt_owf_password.array,
u.info21.nt_owf_password.length);
out = data_blob_talloc_zero(tctx, 16);
- sess_crypt_blob(&out, &in, &session_key, true);
+ sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
u.info21.nt_owf_password.array = (uint16_t *)out.data;
}
break;
if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)
&& !NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD)) {
- torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
+ torture_result(tctx, TORTURE_FAIL, "OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrypted password - %s\n",
nt_errstr(r.out.result));
ret = false;
}
struct lsa_String domain_name;
NTSTATUS status;
+ gnutls_cipher_hd_t cipher_hnd = NULL;
+ gnutls_datum_t old_lm_key = {
+ .data = old_lm_hash,
+ .size = sizeof(old_lm_hash),
+ };
+
domain_name.string = "";
dom_pw_info.in.domain_name = &domain_name;
dom_pw_info.out.info = &info;
E_deshash(newpass, new_lm_hash);
encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
- arcfour_crypt(lm_pass.data, old_lm_hash, 516);
+
+ gnutls_cipher_init(&cipher_hnd,
+ GNUTLS_CIPHER_ARCFOUR_128,
+ &old_lm_key,
+ NULL);
+ gnutls_cipher_encrypt(cipher_hnd,
+ lm_pass.data,
+ 516);
+ gnutls_cipher_deinit(cipher_hnd);
+
E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
status = init_samr_CryptPassword(newpass,
uint8_t old_lm_hash[16], new_lm_hash[16];
DATA_BLOB old_nt_hash_blob
= data_blob_const(old_nt_hash, sizeof(old_nt_hash));
+ gnutls_cipher_hd_t cipher_hnd = NULL;
+ gnutls_datum_t old_lm_key = {
+ .data = old_lm_hash,
+ .size = sizeof(old_lm_hash),
+ };
struct samr_GetDomPwInfo dom_pw_info;
struct samr_PwInfo info;
E_deshash(newpass, new_lm_hash);
encode_pw_buffer(lm_pass.data, newpass, STR_ASCII|STR_TERMINATE);
- arcfour_crypt(lm_pass.data, old_lm_hash, 516);
+
+ gnutls_cipher_init(&cipher_hnd,
+ GNUTLS_CIPHER_ARCFOUR_128,
+ &old_lm_key,
+ NULL);
+ gnutls_cipher_encrypt(cipher_hnd,
+ lm_pass.data,
+ 516);
+ gnutls_cipher_deinit(cipher_hnd);
+
E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
crypt_status = init_samr_CryptPassword(newpass,
NTTIME t;
struct samr_DomInfo1 *dominfo = NULL;
struct userPwdChangeFailureInformation *reject = NULL;
+ DATA_BLOB old_nt_hash_blob = data_blob_const(old_nt_hash, 16);
+ NTSTATUS status;
torture_comment(tctx, "Testing ChangePasswordUser3\n");
E_deshash(oldpass, old_lm_hash);
E_deshash(newpass, new_lm_hash);
- encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
- arcfour_crypt(lm_pass.data, old_nt_hash, 516);
+ /*
+ * The new plaintext password is encrypted using RC4 with the
+ * old NT password hash (directly, with no confounder). The
+ * password is at the end of the random padded buffer,
+ * offering a little protection.
+ *
+ * This is almost certainly wrong, it should be the old LM
+ * hash, it was switched in an unrelated commit
+ * 579c13da43d5b40ac6d6c1436399fbc1d8dfd054 in 2004.
+ */
+ status = init_samr_CryptPassword(newpass,
+ &old_nt_hash_blob,
+ &lm_pass);
+ torture_assert_ntstatus_ok(tctx,
+ status,
+ "init_samr_CryptPassword");
+
+ /*
+ * Now we prepare a DES cross-hash of the old LM and new NT
+ * passwords to link the two buffers
+ */
E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
- encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
- arcfour_crypt(nt_pass.data, old_nt_hash, 516);
+ /*
+ * The new plaintext password is also encrypted using RC4 with
+ * the old NT password hash (directly, with no confounder).
+ * The password is at the end of the random padded buffer,
+ * offering a little protection.
+ */
+ status = init_samr_CryptPassword(newpass,
+ &old_nt_hash_blob,
+ &nt_pass);
+ torture_assert_ntstatus_ok(tctx,
+ status,
+ "init_samr_CryptPassword");
+
+ /*
+ * Another DES based cross-hash
+ */
E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
/* Break the verification */
ret = false;
}
- encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
- arcfour_crypt(lm_pass.data, old_nt_hash, 516);
+ status = init_samr_CryptPassword(newpass,
+ &old_nt_hash_blob,
+ &lm_pass);
+ torture_assert_ntstatus_ok(tctx,
+ status,
+ "init_samr_CryptPassword");
+
E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
- encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
- /* Break the NT hash */
+ /* Break the NT Hash */
old_nt_hash[0]++;
- arcfour_crypt(nt_pass.data, old_nt_hash, 516);
+
+ status = init_samr_CryptPassword(newpass,
+ &old_nt_hash_blob,
+ &nt_pass);
+ torture_assert_ntstatus_ok(tctx,
+ status,
+ "init_samr_CryptPassword");
+
/* Unbreak it again */
old_nt_hash[0]--;
+
E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
r.in.server = &server;
oldpass, newpass, nt_errstr(r.out.result));
if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION) &&
(!NT_STATUS_EQUAL(r.out.result, NT_STATUS_WRONG_PASSWORD))) {
- torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n",
+ torture_result(tctx, TORTURE_FAIL, "ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrypted password - %s\n",
nt_errstr(r.out.result));
ret = false;
}
E_deshash(oldpass, old_lm_hash);
E_deshash(newpass, new_lm_hash);
- encode_pw_buffer(lm_pass.data, newpass, STR_UNICODE);
- arcfour_crypt(lm_pass.data, old_nt_hash, 516);
+ status = init_samr_CryptPassword(newpass,
+ &old_nt_hash_blob,
+ &lm_pass);
+ torture_assert_ntstatus_ok(tctx,
+ status,
+ "init_samr_CryptPassword");
+
E_old_pw_hash(new_nt_hash, old_lm_hash, lm_verifier.hash);
- encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
- arcfour_crypt(nt_pass.data, old_nt_hash, 516);
+ status = init_samr_CryptPassword(newpass,
+ &old_nt_hash_blob,
+ &nt_pass);
+ torture_assert_ntstatus_ok(tctx,
+ status,
+ "init_samr_CryptPassword");
+
E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
r.in.server = &server;
struct samr_SetUserInfo s;
union samr_UserInfo u;
DATA_BLOB session_key;
- DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
- uint8_t confounder[16];
- gnutls_hash_hd_t hash_hnd;
bool ret = true;
struct lsa_String server, account;
char *oldpass;
struct dcerpc_binding_handle *b = p->binding_handle;
uint8_t old_nt_hash[16], new_nt_hash[16];
+ DATA_BLOB old_nt_hash_blob
+ = data_blob_const(old_nt_hash,
+ sizeof(old_nt_hash));
NTTIME t;
struct samr_DomInfo1 *dominfo = NULL;
struct userPwdChangeFailureInformation *reject = NULL;
+ gnutls_cipher_hd_t cipher_hnd = NULL;
+ uint8_t _confounder[16] = {0};
+ DATA_BLOB confounder
+ = data_blob_const(_confounder,
+ sizeof(_confounder));
+ DATA_BLOB pw_data;
+ gnutls_datum_t old_nt_key = {
+ .data = old_nt_hash,
+ .size = sizeof(old_nt_hash),
+ };
new_random_pass = samr_very_rand_pass(tctx, 128);
set_pw_in_buffer(u.info25.password.data, &new_random_pass);
+ pw_data = data_blob_const(u.info25.password.data, 516);
+
status = dcerpc_fetch_session_key(p, &session_key);
if (!NT_STATUS_IS_OK(status)) {
torture_result(tctx, TORTURE_FAIL, "SetUserInfo level %u - no session key - %s\n",
return false;
}
- generate_random_buffer((uint8_t *)confounder, 16);
+ generate_random_buffer(_confounder,
+ sizeof(_confounder));
- gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5);
- gnutls_hash(hash_hnd, confounder, 16);
- gnutls_hash(hash_hnd, session_key.data, session_key.length);
- gnutls_hash_deinit(hash_hnd, confounded_session_key.data);
+ samba_gnutls_arcfour_confounded_md5(&confounder,
+ &session_key,
+ &pw_data,
+ SAMBA_GNUTLS_ENCRYPT);
- arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
- memcpy(&u.info25.password.data[516], confounder, 16);
+ memcpy(&u.info25.password.data[516], _confounder, sizeof(_confounder));
torture_comment(tctx, "Testing SetUserInfo level 25 (set password ex) with a password made up of only random bytes\n");
mdfour(new_nt_hash, new_random_pass.data, new_random_pass.length);
set_pw_in_buffer(nt_pass.data, &new_random_pass);
- arcfour_crypt(nt_pass.data, old_nt_hash, 516);
+
+ gnutls_cipher_init(&cipher_hnd,
+ GNUTLS_CIPHER_ARCFOUR_128,
+ &old_nt_key,
+ NULL);
+ gnutls_cipher_encrypt(cipher_hnd,
+ nt_pass.data,
+ 516);
+ gnutls_cipher_deinit(cipher_hnd);
+
E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
r.in.server = &server;
E_md4hash(newpass, new_nt_hash);
- encode_pw_buffer(nt_pass.data, newpass, STR_UNICODE);
- arcfour_crypt(nt_pass.data, old_nt_hash, 516);
+ status = init_samr_CryptPassword(newpass,
+ &old_nt_hash_blob,
+ &nt_pass);
+ torture_assert_ntstatus_ok(tctx,
+ status,
+ "init_samr_CryptPassword failed");
+
E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
r.in.server = &server;