1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

auth/credentials: Make cli_credentials_get_aes256_key into generic key access

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Jo Sutton <josutton@catalyst.net.nz>
This commit is contained in:
Andrew Bartlett 2023-12-21 22:25:25 +13:00
parent 13d346ce0c
commit b8308f3fe0
5 changed files with 57 additions and 30 deletions

View File

@ -348,11 +348,6 @@ NTSTATUS netlogon_creds_session_encrypt(
struct netlogon_creds_CredentialState *state,
DATA_BLOB data);
int cli_credentials_get_aes256_key(struct cli_credentials *cred,
TALLOC_CTX *mem_ctx,
struct loadparm_context *lp_ctx,
DATA_BLOB *aes_256);
/**
* Kerberos FAST handling
*/

View File

@ -1504,10 +1504,11 @@ _PUBLIC_ void cli_credentials_set_target_service(struct cli_credentials *cred, c
cred->target_service = talloc_strdup(cred, target_service);
}
_PUBLIC_ int cli_credentials_get_aes256_key(struct cli_credentials *cred,
TALLOC_CTX *mem_ctx,
struct loadparm_context *lp_ctx,
DATA_BLOB *aes_256)
_PUBLIC_ int cli_credentials_get_kerberos_key(struct cli_credentials *cred,
TALLOC_CTX *mem_ctx,
struct loadparm_context *lp_ctx,
krb5_enctype enctype,
DATA_BLOB *key_blob)
{
struct smb_krb5_context *smb_krb5_context = NULL;
krb5_error_code krb5_ret;
@ -1522,8 +1523,26 @@ _PUBLIC_ int cli_credentials_get_aes256_key(struct cli_credentials *cred,
TALLOC_CTX *frame = talloc_stackframe();
if ((int)enctype == (int)ENCTYPE_ARCFOUR_HMAC) {
struct samr_Password *nt_hash
= cli_credentials_get_nt_hash(cred, frame);
if (nt_hash == NULL) {
TALLOC_FREE(frame);
return EINVAL;
}
*key_blob = data_blob_talloc(mem_ctx,
nt_hash->hash,
sizeof(nt_hash->hash));
if (key_blob->data == NULL) {
TALLOC_FREE(frame);
return ENOMEM;
}
TALLOC_FREE(frame);
return 0;
}
if (cred->password_will_be_nt_hash) {
DEBUG(1,("cli_credentials_get_aes256_key: cannot generate AES256 key using NT hash\n"));
DEBUG(1,("cli_credentials_get_kerberos_key: cannot generate Kerberos key using NT hash\n"));
TALLOC_FREE(frame);
return EINVAL;
}
@ -1554,14 +1573,14 @@ _PUBLIC_ int cli_credentials_get_aes256_key(struct cli_credentials *cred,
salt_data.length = strlen(salt);
/*
* create ENCTYPE_AES256_CTS_HMAC_SHA1_96 key out of
* create Kerberos key out of
* the salt and the cleartext password
*/
krb5_ret = smb_krb5_create_key_from_string(smb_krb5_context->krb5_context,
NULL,
&salt_data,
&cleartext_data,
ENCTYPE_AES256_CTS_HMAC_SHA1_96,
enctype,
&key);
if (krb5_ret != 0) {
DEBUG(1,("cli_credentials_get_aes256_key: "
@ -1571,15 +1590,15 @@ _PUBLIC_ int cli_credentials_get_aes256_key(struct cli_credentials *cred,
TALLOC_FREE(frame);
return EINVAL;
}
*aes_256 = data_blob_talloc(mem_ctx,
*key_blob = data_blob_talloc(mem_ctx,
KRB5_KEY_DATA(&key),
KRB5_KEY_LENGTH(&key));
krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &key);
if (aes_256->data == NULL) {
if (key_blob->data == NULL) {
TALLOC_FREE(frame);
return ENOMEM;
}
talloc_keep_secret(aes_256->data);
talloc_keep_secret(key_blob->data);
TALLOC_FREE(frame);
return 0;

View File

@ -41,5 +41,11 @@ int cli_credentials_set_client_gss_creds(struct cli_credentials *cred,
struct cli_credentials *cli_credentials_shallow_copy(TALLOC_CTX *mem_ctx,
struct cli_credentials *src);
int cli_credentials_get_kerberos_key(struct cli_credentials *cred,
TALLOC_CTX *mem_ctx,
struct loadparm_context *lp_ctx,
krb5_enctype enctype,
DATA_BLOB *key_blob);
#endif /* __CREDENTIALS_KRB5_H__ */

View File

@ -23,6 +23,7 @@
#include "pycredentials.h"
#include "param/param.h"
#include "auth/credentials/credentials_internal.h"
#include "auth/credentials/credentials_krb5.h"
#include "librpc/gen_ndr/samr.h" /* for struct samr_Password */
#include "librpc/gen_ndr/netlogon.h"
#include "libcli/util/pyerrors.h"
@ -1014,13 +1015,14 @@ static PyObject *py_creds_get_kerberos_salt_principal(PyObject *self, PyObject *
return ret;
}
static PyObject *py_creds_get_aes256_key(PyObject *self, PyObject *args)
static PyObject *py_creds_get_kerberos_key(PyObject *self, PyObject *args)
{
struct loadparm_context *lp_ctx = NULL;
TALLOC_CTX *mem_ctx = NULL;
PyObject *py_lp_ctx = Py_None;
DATA_BLOB aes_256;
DATA_BLOB key;
int code;
int enctype;
PyObject *ret = NULL;
struct cli_credentials *creds = PyCredentials_AsCliCredentials(self);
if (creds == NULL) {
@ -1028,7 +1030,7 @@ static PyObject *py_creds_get_aes256_key(PyObject *self, PyObject *args)
return NULL;
}
if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
if (!PyArg_ParseTuple(args, "i|O", &enctype, &py_lp_ctx))
return NULL;
mem_ctx = talloc_new(NULL);
@ -1043,19 +1045,20 @@ static PyObject *py_creds_get_aes256_key(PyObject *self, PyObject *args)
return NULL;
}
code = cli_credentials_get_aes256_key(creds,
mem_ctx,
lp_ctx,
&aes_256);
code = cli_credentials_get_kerberos_key(creds,
mem_ctx,
lp_ctx,
enctype,
&key);
if (code != 0) {
PyErr_SetString(PyExc_RuntimeError,
"Failed to generate AES256 key");
"Failed to generate Kerberos key");
talloc_free(mem_ctx);
return NULL;
}
ret = PyBytes_FromStringAndSize((const char *)aes_256.data,
aes_256.length);
ret = PyBytes_FromStringAndSize((const char *)key.data,
key.length);
talloc_free(mem_ctx);
return ret;
}
@ -1636,11 +1639,11 @@ static PyMethodDef py_creds_methods[] = {
.ml_flags = METH_VARARGS,
},
{
.ml_name = "get_aes256_key",
.ml_meth = py_creds_get_aes256_key,
.ml_name = "get_kerberos_key",
.ml_meth = py_creds_get_kerberos_key,
.ml_flags = METH_VARARGS,
.ml_doc = "S.get_aes256_key([lp]) -> bytes\n"
"Generate an AES256 key using the current password and\n"
.ml_doc = "S.get_kerberos_key(enctype, [lp]) -> bytes\n"
"Generate a Kerberos key using the current password and\n"
"the salt on this credentials object",
},
{
@ -1809,6 +1812,10 @@ MODULE_INIT_FUNC(credentials)
PyModule_AddObject(m, "SMB_ENCRYPTION_DESIRED", PyLong_FromLong(SMB_ENCRYPTION_DESIRED));
PyModule_AddObject(m, "SMB_ENCRYPTION_REQUIRED", PyLong_FromLong(SMB_ENCRYPTION_REQUIRED));
PyModule_AddObject(m, "ENCTYPE_ARCFOUR_HMAC", PyLong_FromLong(ENCTYPE_ARCFOUR_HMAC));
PyModule_AddObject(m, "ENCTYPE_AES128_CTS_HMAC_SHA1_96", PyLong_FromLong(ENCTYPE_AES128_CTS_HMAC_SHA1_96));
PyModule_AddObject(m, "ENCTYPE_AES256_CTS_HMAC_SHA1_96", PyLong_FromLong(ENCTYPE_AES256_CTS_HMAC_SHA1_96));
Py_INCREF(&PyCredentials);
PyModule_AddObject(m, "Credentials", (PyObject *)&PyCredentials);
Py_INCREF(&PyCredentialCacheContainer);

View File

@ -490,7 +490,7 @@ class GetPasswordCommand(Command):
current_hash = unicodePwd
elif aes256_key is not None and kerberos_salt is not None:
tmp.set_kerberos_salt_principal(kerberos_salt)
decrypted = tmp.get_aes256_key()
decrypted = tmp.get_kerberos_key(credentials.ENCTYPE_AES256_CTS_HMAC_SHA1_96)
current_hash = aes256_key.value
if current_hash is not None and current_hash == decrypted: