]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s4:kdc: Add helper function to extract AES256 key and salt
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Wed, 18 May 2022 08:12:36 +0000 (20:12 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Sun, 26 Jun 2022 22:10:29 +0000 (22:10 +0000)
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/kdc/db-glue.c
source4/kdc/db-glue.h

index 172a34194c69dd48df842a18c87d6c6c0392bb97..95cbf90d3f5cd0f65949d36dd23deff3a716e161 100644 (file)
@@ -3337,3 +3337,97 @@ NTSTATUS samba_kdc_setup_db_ctx(TALLOC_CTX *mem_ctx, struct samba_kdc_base_conte
        *kdc_db_ctx_out = kdc_db_ctx;
        return NT_STATUS_OK;
 }
+
+krb5_error_code dsdb_extract_aes_256_key(krb5_context context,
+                                        TALLOC_CTX *mem_ctx,
+                                        const struct ldb_message *msg,
+                                        uint32_t user_account_control,
+                                        const uint32_t *kvno,
+                                        uint32_t *kvno_out,
+                                        DATA_BLOB *aes_256_key,
+                                        DATA_BLOB *salt)
+{
+       krb5_error_code krb5_ret;
+       uint32_t supported_enctypes;
+       unsigned flags = SDB_F_GET_CLIENT;
+       struct sdb_entry sentry = {};
+
+       if (kvno != NULL) {
+               flags |= SDB_F_KVNO_SPECIFIED;
+       }
+
+       krb5_ret = samba_kdc_message2entry_keys(context,
+                                               mem_ctx,
+                                               msg,
+                                               false, /* is_krbtgt */
+                                               false, /* is_rodc */
+                                               user_account_control,
+                                               SAMBA_KDC_ENT_TYPE_CLIENT,
+                                               flags,
+                                               (kvno != NULL) ? *kvno : 0,
+                                               &sentry,
+                                               ENC_HMAC_SHA1_96_AES256,
+                                               &supported_enctypes);
+       if (krb5_ret != 0) {
+               DBG_ERR("Failed to parse supplementalCredentials "
+                       "of %s with %s kvno using "
+                       "ENCTYPE_HMAC_SHA1_96_AES256 "
+                       "Kerberos Key: %s\n",
+                       ldb_dn_get_linearized(msg->dn),
+                       (kvno != NULL) ? "previous" : "current",
+                       krb5_get_error_message(context,
+                                              krb5_ret));
+               return krb5_ret;
+       }
+
+       if ((supported_enctypes & ENC_HMAC_SHA1_96_AES256) == 0 ||
+           sentry.keys.len != 1) {
+               DBG_INFO("Failed to find a ENCTYPE_HMAC_SHA1_96_AES256 "
+                        "key in supplementalCredentials "
+                        "of %s at KVNO %u (got %u keys, expected 1)\n",
+                        ldb_dn_get_linearized(msg->dn),
+                        sentry.kvno,
+                        sentry.keys.len);
+               sdb_entry_free(&sentry);
+               return ENOENT;
+       }
+
+       if (sentry.keys.val[0].salt == NULL) {
+               DBG_INFO("Failed to find a salt in "
+                        "supplementalCredentials "
+                        "of %s at KVNO %u\n",
+                        ldb_dn_get_linearized(msg->dn),
+                        sentry.kvno);
+               sdb_entry_free(&sentry);
+               return ENOENT;
+       }
+
+       if (aes_256_key != NULL) {
+               *aes_256_key = data_blob_talloc(mem_ctx,
+                                               KRB5_KEY_DATA(&sentry.keys.val[0].key),
+                                               KRB5_KEY_LENGTH(&sentry.keys.val[0].key));
+               if (aes_256_key->data == NULL) {
+                       sdb_entry_free(&sentry);
+                       return ENOMEM;
+               }
+               talloc_keep_secret(aes_256_key->data);
+       }
+
+       if (salt != NULL) {
+               *salt = data_blob_talloc(mem_ctx,
+                                        sentry.keys.val[0].salt->salt.data,
+                                        sentry.keys.val[0].salt->salt.length);
+               if (salt->data == NULL) {
+                       sdb_entry_free(&sentry);
+                       return ENOMEM;
+               }
+       }
+
+       if (kvno_out != NULL) {
+               *kvno_out = sentry.kvno;
+       }
+
+       sdb_entry_free(&sentry);
+
+       return 0;
+}
index b8d936ba662bc6e7f3345daaa6aa2e04477d6d70..3a59d6a421ade5be0b1ff5c4540aa43435205aa4 100644 (file)
@@ -100,3 +100,12 @@ krb5_error_code samba_kdc_check_s4u2proxy_rbcd(
 
 NTSTATUS samba_kdc_setup_db_ctx(TALLOC_CTX *mem_ctx, struct samba_kdc_base_context *base_ctx,
                                struct samba_kdc_db_context **kdc_db_ctx_out);
+
+krb5_error_code dsdb_extract_aes_256_key(krb5_context context,
+                                        TALLOC_CTX *mem_ctx,
+                                        const struct ldb_message *msg,
+                                        uint32_t user_account_control,
+                                        const uint32_t *kvno,
+                                        uint32_t *kvno_out,
+                                        DATA_BLOB *aes_256_key,
+                                        DATA_BLOB *salt);