auth/credentials: Add cli_credentials_get_aes256_key()
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Mon, 9 May 2022 02:35:05 +0000 (14:35 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Sun, 26 Jun 2022 22:10:29 +0000 (22:10 +0000)
This allows us to generate AES256 keys from a given password and salt.

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
auth/credentials/credentials.h
auth/credentials/credentials_krb5.c

index 551b16118268bbf8d282cb67c85249cb8504b431..e9d8b8a44b18e9e0e322ddb3d431986ae5a87437 100644 (file)
@@ -344,4 +344,10 @@ 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,
+                                  const char *salt,
+                                  DATA_BLOB *aes_256);
+
 #endif /* __CREDENTIALS_H__ */
index e69e1a83b3cc27d1478e4feb62988b08ede17df7..bd47113e60c3cc27d0795d48af996203ca285858 100644 (file)
@@ -1464,3 +1464,67 @@ _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,
+                                           const char *salt,
+                                           DATA_BLOB *aes_256)
+{
+       struct smb_krb5_context *smb_krb5_context = NULL;
+       krb5_error_code krb5_ret;
+       int ret;
+       const char *password = NULL;
+       krb5_data cleartext_data;
+       krb5_data salt_data;
+       krb5_keyblock key;
+
+       if (cred->password_will_be_nt_hash) {
+               DEBUG(1,("cli_credentials_get_aes256_key: cannot generate AES256 key using NT hash\n"));
+               return EINVAL;
+       }
+
+       password = cli_credentials_get_password(cred);
+       if (password == NULL) {
+               return EINVAL;
+       }
+
+       cleartext_data.data = discard_const_p(char, password);
+       cleartext_data.length = strlen(password);
+
+       ret = cli_credentials_get_krb5_context(cred, lp_ctx,
+                                              &smb_krb5_context);
+       if (ret != 0) {
+               return ret;
+       }
+
+       salt_data.data = discard_const_p(char, salt);
+       salt_data.length = strlen(salt);
+
+       /*
+        * create ENCTYPE_AES256_CTS_HMAC_SHA1_96 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,
+                                                  &key);
+       if (krb5_ret != 0) {
+               DEBUG(1,("cli_credentials_get_aes256_key: "
+                        "generation of a aes256-cts-hmac-sha1-96 key failed: %s",
+                        smb_get_krb5_error_message(smb_krb5_context->krb5_context,
+                                                   krb5_ret, mem_ctx)));
+               return EINVAL;
+       }
+       *aes_256 = 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) {
+               return ENOMEM;
+       }
+       talloc_keep_secret(aes_256->data);
+
+       return 0;
+}