From: Andrew Bartlett Date: Thu, 21 Dec 2023 09:25:25 +0000 (+1300) Subject: auth/credentials: Make cli_credentials_get_aes256_key into generic key access X-Git-Tag: tdb-1.4.11~1460 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b8308f3fe06f2d97b04554d79f321cd62dd01a2c;p=thirdparty%2Fsamba.git auth/credentials: Make cli_credentials_get_aes256_key into generic key access Signed-off-by: Andrew Bartlett Reviewed-by: Jo Sutton --- diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 57166e29c82..584d556411b 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -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 */ diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c index 3e8d4651b44..ce5a5a3fadd 100644 --- a/auth/credentials/credentials_krb5.c +++ b/auth/credentials/credentials_krb5.c @@ -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; diff --git a/auth/credentials/credentials_krb5.h b/auth/credentials/credentials_krb5.h index ae601047606..6ee2e139a4d 100644 --- a/auth/credentials/credentials_krb5.h +++ b/auth/credentials/credentials_krb5.h @@ -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__ */ diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c index 75cd2909a4c..517b4757f1c 100644 --- a/auth/credentials/pycredentials.c +++ b/auth/credentials/pycredentials.c @@ -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); diff --git a/python/samba/netcmd/user/readpasswords/common.py b/python/samba/netcmd/user/readpasswords/common.py index 2b888c4f0f7..0aa1f237dc0 100644 --- a/python/samba/netcmd/user/readpasswords/common.py +++ b/python/samba/netcmd/user/readpasswords/common.py @@ -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: