]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s4-dsdb: Populate new GKDI root keys from the server configuration object
authorAndrew Bartlett <abartlet@samba.org>
Fri, 22 Mar 2024 01:08:22 +0000 (14:08 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 28 Mar 2024 01:50:41 +0000 (01:50 +0000)
This honours MS-GKDI 3.1.4.1.1 Creating a New Root Key

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
lib/crypto/gkdi.h
selftest/knownfail.d/gkdi
source4/dsdb/common/util.c
source4/dsdb/gmsa/gkdi.c

index 244563d18b66aa427e6414387d657ba65bed691c..ea0f8b9357fb0ed8bca213c3f3121277fbb41fa7 100644 (file)
@@ -37,6 +37,8 @@ enum KdfAlgorithmId {
        KDF_ALGORITHM_SP800_108_CTR_HMAC,
 };
 
+#define SP800_108_CTR_HMAC "SP800_108_CTR_HMAC"
+
 enum KdfSp800_108Param {
        KDF_PARAM_SHA1,
        KDF_PARAM_SHA256,
index 387bbfa277458497226c462a99837948308bee72..fbea302922fd472a0acc4d67c8f43640df063a78 100644 (file)
@@ -17,7 +17,3 @@
 ^samba\.tests\.krb5\.gkdi_tests\.samba\.tests\.krb5\.gkdi_tests\.GkdiImplicitRootKeyTests\.test_request_default_seed_key\(ad_dc\)$
 ^samba\.tests\.krb5\.gkdi_tests\.samba\.tests\.krb5\.gkdi_tests\.GkdiImplicitRootKeyTests\.test_request_l0_seed_key\(ad_dc\)$
 ^samba\.tests\.krb5\.gkdi_tests\.samba\.tests\.krb5\.gkdi_tests\.GkdiImplicitRootKeyTests\.test_request_l1_seed_key\(ad_dc\)$
-^samba.tests.dsdb_quiet_provision_tests.samba.tests.dsdb_quiet_provision_tests.DsdbQuietProvisionTests.test_gkdi_create_root_key_4096
-^samba.tests.dsdb_quiet_provision_tests.samba.tests.dsdb_quiet_provision_tests.DsdbQuietProvisionTests.test_gkdi_create_root_key_bad_alg
-^samba.tests.dsdb_quiet_provision_tests.samba.tests.dsdb_quiet_provision_tests.DsdbQuietProvisionTests.test_gkdi_create_root_key_priv_1024
-^samba.tests.dsdb_quiet_provision_tests.samba.tests.dsdb_quiet_provision_tests.DsdbQuietProvisionTests.test_gkdi_create_root_key_wrong_version
index d31d7d94f2d6985ec598d8fe02dfa7b952e21a17..7cdfca8da198129f40ff05379db99fd2b932ea64 100644 (file)
@@ -1325,9 +1325,9 @@ struct ldb_dn *samdb_extended_rights_dn(struct ldb_context *sam_ctx, TALLOC_CTX
        return new_dn;
 }
 
-static struct ldb_dn *samdb_configuration_dn(struct ldb_context *sam_ctx,
-                                            TALLOC_CTX *mem_ctx,
-                                            const char *dn_str)
+struct ldb_dn *samdb_configuration_dn(struct ldb_context *sam_ctx,
+                                     TALLOC_CTX *mem_ctx,
+                                     const char *dn_str)
 {
        struct ldb_dn *config_dn = NULL;
        struct ldb_dn *child_dn = NULL;
index dfb9be892267e4a98f1b793c665a034b0dd3ba2b..49d05801037ad7dca7ec2371d9393b9d1d1729c8 100644 (file)
@@ -30,6 +30,7 @@
 #include "dsdb/gmsa/gkdi.h"
 #include "dsdb/samdb/ldb_modules/util.h"
 #include "dsdb/samdb/samdb.h"
+#include "dsdb/common/proto.h"
 
 static int gkdi_create_root_key(TALLOC_CTX *mem_ctx,
                                struct ldb_context *const ldb,
@@ -40,10 +41,33 @@ static int gkdi_create_root_key(TALLOC_CTX *mem_ctx,
 {
        TALLOC_CTX *tmp_ctx = NULL;
        struct GUID root_key_id;
+       struct ldb_dn *server_config_dn = NULL;
+       struct ldb_result *server_config_res = NULL;
+       struct ldb_message *server_config_msg = NULL;
+       uint64_t server_config_version;
+       const struct ldb_val *server_config_version_val = NULL;
+       const char *server_config_KDFAlgorithmID = NULL;
+       const struct ldb_val *server_config_KDFParam = NULL;
+       const char *server_config_SecretAgreementAlgorithmID = NULL;
+       const struct ldb_val *server_config_SecretAgreementParam = NULL;
+       uint64_t server_config_PublicKeyLength;
+       uint64_t server_config_PrivateKeyLength;
+       struct KdfAlgorithm kdf_algorithm;
        struct ldb_message *add_msg = NULL;
        NTSTATUS status = NT_STATUS_OK;
        int ret = LDB_SUCCESS;
 
+       static const char *server_config_attrs[] = {
+               "msKds-Version",
+               "msKds-KDFAlgorithmID",
+               "msKds-SecretAgreementAlgorithmID",
+               "msKds-SecretAgreementParam",
+               "msKds-PublicKeyLength",
+               "msKds-PrivateKeyLength",
+               "msKds-KDFParam",
+               NULL
+       };
+
        *root_key_dn_out = NULL;
 
        tmp_ctx = talloc_new(mem_ctx);
@@ -52,6 +76,179 @@ static int gkdi_create_root_key(TALLOC_CTX *mem_ctx,
                goto out;
        }
 
+       server_config_dn = samdb_configuration_dn(ldb,
+                                                 mem_ctx,
+                                                 "CN=Group Key Distribution Service Server Configuration,"
+                                                 "CN=Server Configuration,"
+                                                 "CN=Group Key Distribution Service,"
+                                                 "CN=Services");
+       if (server_config_dn == NULL) {
+               ret = ldb_oom(ldb);
+               goto out;
+       }
+
+       ret = dsdb_search_dn(ldb,
+                            tmp_ctx,
+                            &server_config_res,
+                            server_config_dn,
+                            server_config_attrs,
+                            DSDB_SEARCH_ONE_ONLY);
+
+       if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+               ldb_asprintf_errstring(ldb, "Unable to create new GKDI root key as we do not have a GKDI server configuration at %s",
+                                 ldb_dn_get_linearized(server_config_dn));
+               goto out;
+       }
+
+       if (ret != LDB_SUCCESS) {
+               goto out;
+       }
+
+       server_config_msg = server_config_res->msgs[0];
+
+       server_config_version_val
+               = ldb_msg_find_ldb_val(server_config_msg,
+                                      "msKds-Version");
+       server_config_version
+               = ldb_msg_find_attr_as_uint64(server_config_msg,
+                                             "msKds-Version",
+                                             0);
+
+       /* These values we assert on, so we don't create keys we can't use */
+       if (server_config_version_val == NULL) {
+               /*
+                * The systemMustContain msKds-Version attribute
+                * cannot be read, so if absent we just fail with
+                * permission denied, as that is all that this can
+                * mean
+                */
+               ldb_asprintf_errstring(ldb,
+                                      "Unwilling to create new GKDI root key as "
+                                      "msKds-Version is not readable on %s\n",
+                                      ldb_dn_get_linearized(server_config_dn));
+               ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
+               goto out;
+       } else if (server_config_version != 1) {
+               ldb_asprintf_errstring(ldb,
+                                      "Unwilling to create new GKDI root key as "
+                                      "%s has msKds-Version = %s "
+                                      "and we only support version 1\n",
+                                      ldb_dn_get_linearized(server_config_dn),
+                                      ldb_msg_find_attr_as_string(server_config_msg, "msKds-Version", "(missing)"));
+               ret = LDB_ERR_CONSTRAINT_VIOLATION;
+               goto out;
+       }
+
+       server_config_KDFAlgorithmID
+               = ldb_msg_find_attr_as_string(server_config_msg,
+                                             "msKds-KDFAlgorithmID",
+                                             SP800_108_CTR_HMAC
+                                             );
+
+       server_config_KDFParam
+               = ldb_msg_find_ldb_val(server_config_msg,
+                                      "msKds-KDFParam");
+       if (server_config_KDFParam == NULL) {
+               static const uint8_t kdf_parameters[] = {
+                       0,   0, 0,   0, 1,   0, 0,   0, 14,  0,
+                       0,   0, 0,   0, 0,   0, 'S', 0, 'H', 0,
+                       'A', 0, '5', 0, '1', 0, '2', 0, 0,   0,
+               };
+               static const DATA_BLOB kdf_parameters_blob = {
+                       discard_const_p(uint8_t, kdf_parameters),
+                       sizeof kdf_parameters};
+               server_config_KDFParam = &kdf_parameters_blob;
+       }
+
+       status = kdf_algorithm_from_params(server_config_KDFAlgorithmID,
+                                          server_config_KDFParam,
+                                          &kdf_algorithm);
+       if (!NT_STATUS_IS_OK(status)) {
+               ldb_asprintf_errstring(ldb,
+                                      "Unwilling to create new GKDI root key as "
+                                      "%s has an unsupported msKds-KDFAlgorithmID / msKds-KDFParam combination set: %s\n",
+                                      ldb_dn_get_linearized(server_config_dn),
+                                      nt_errstr(status));
+               ret = LDB_ERR_CONSTRAINT_VIOLATION;
+               goto out;
+       }
+
+       server_config_SecretAgreementAlgorithmID
+               = ldb_msg_find_attr_as_string(server_config_msg,
+                                             "msKds-SecretAgreementAlgorithmID",
+                                             "DH");
+
+       /* Optional in msKds-ProvRootKey */
+       server_config_SecretAgreementParam
+               = ldb_msg_find_ldb_val(server_config_msg,
+                                      "msKds-SecretAgreementParam");
+       if (server_config_SecretAgreementParam == NULL) {
+               static const uint8_t ffc_dh_parameters[] = {
+                       12,  2,   0,   0,   68,  72,  80,  77,  0,   1,   0,
+                       0,   135, 168, 230, 29,  180, 182, 102, 60,  255, 187,
+                       209, 156, 101, 25,  89,  153, 140, 238, 246, 8,   102,
+                       13,  208, 242, 93,  44,  238, 212, 67,  94,  59,  0,
+                       224, 13,  248, 241, 214, 25,  87,  212, 250, 247, 223,
+                       69,  97,  178, 170, 48,  22,  195, 217, 17,  52,  9,
+                       111, 170, 59,  244, 41,  109, 131, 14,  154, 124, 32,
+                       158, 12,  100, 151, 81,  122, 189, 90,  138, 157, 48,
+                       107, 207, 103, 237, 145, 249, 230, 114, 91,  71,  88,
+                       192, 34,  224, 177, 239, 66,  117, 191, 123, 108, 91,
+                       252, 17,  212, 95,  144, 136, 185, 65,  245, 78,  177,
+                       229, 155, 184, 188, 57,  160, 191, 18,  48,  127, 92,
+                       79,  219, 112, 197, 129, 178, 63,  118, 182, 58,  202,
+                       225, 202, 166, 183, 144, 45,  82,  82,  103, 53,  72,
+                       138, 14,  241, 60,  109, 154, 81,  191, 164, 171, 58,
+                       216, 52,  119, 150, 82,  77,  142, 246, 161, 103, 181,
+                       164, 24,  37,  217, 103, 225, 68,  229, 20,  5,   100,
+                       37,  28,  202, 203, 131, 230, 180, 134, 246, 179, 202,
+                       63,  121, 113, 80,  96,  38,  192, 184, 87,  246, 137,
+                       150, 40,  86,  222, 212, 1,   10,  189, 11,  230, 33,
+                       195, 163, 150, 10,  84,  231, 16,  195, 117, 242, 99,
+                       117, 215, 1,   65,  3,   164, 181, 67,  48,  193, 152,
+                       175, 18,  97,  22,  210, 39,  110, 17,  113, 95,  105,
+                       56,  119, 250, 215, 239, 9,   202, 219, 9,   74,  233,
+                       30,  26,  21,  151, 63,  179, 44,  155, 115, 19,  77,
+                       11,  46,  119, 80,  102, 96,  237, 189, 72,  76,  167,
+                       177, 143, 33,  239, 32,  84,  7,   244, 121, 58,  26,
+                       11,  161, 37,  16,  219, 193, 80,  119, 190, 70,  63,
+                       255, 79,  237, 74,  172, 11,  181, 85,  190, 58,  108,
+                       27,  12,  107, 71,  177, 188, 55,  115, 191, 126, 140,
+                       111, 98,  144, 18,  40,  248, 194, 140, 187, 24,  165,
+                       90,  227, 19,  65,  0,   10,  101, 1,   150, 249, 49,
+                       199, 122, 87,  242, 221, 244, 99,  229, 233, 236, 20,
+                       75,  119, 125, 230, 42,  170, 184, 168, 98,  138, 195,
+                       118, 210, 130, 214, 237, 56,  100, 230, 121, 130, 66,
+                       142, 188, 131, 29,  20,  52,  143, 111, 47,  145, 147,
+                       181, 4,   90,  242, 118, 113, 100, 225, 223, 201, 103,
+                       193, 251, 63,  46,  85,  164, 189, 27,  255, 232, 59,
+                       156, 128, 208, 82,  185, 133, 209, 130, 234, 10,  219,
+                       42,  59,  115, 19,  211, 254, 20,  200, 72,  75,  30,
+                       5,   37,  136, 185, 183, 210, 187, 210, 223, 1,   97,
+                       153, 236, 208, 110, 21,  87,  205, 9,   21,  179, 53,
+                       59,  187, 100, 224, 236, 55,  127, 208, 40,  55,  13,
+                       249, 43,  82,  199, 137, 20,  40,  205, 198, 126, 182,
+                       24,  75,  82,  61,  29,  178, 70,  195, 47,  99,  7,
+                       132, 144, 240, 14,  248, 214, 71,  209, 72,  212, 121,
+                       84,  81,  94,  35,  39,  207, 239, 152, 197, 130, 102,
+                       75,  76,  15,  108, 196, 22,  89};
+               static const DATA_BLOB ffc_dh_parameters_blob = {
+                       discard_const_p(uint8_t, ffc_dh_parameters),
+                       sizeof ffc_dh_parameters};
+
+               server_config_SecretAgreementParam = &ffc_dh_parameters_blob;
+       }
+
+       server_config_PublicKeyLength
+               = ldb_msg_find_attr_as_uint64(server_config_msg,
+                                             "msKds-PublicKeyLength",
+                                             2048);
+
+       server_config_PrivateKeyLength
+               = ldb_msg_find_attr_as_uint64(server_config_msg,
+                                             "msKds-PrivateKeyLength",
+                                             256);
+
        add_msg = ldb_msg_new(tmp_ctx);
        if (add_msg == NULL) {
                ret = ldb_oom(ldb);
@@ -119,128 +316,67 @@ static int gkdi_create_root_key(TALLOC_CTX *mem_ctx,
                }
        }
 
-       ret = ldb_msg_append_string(add_msg,
-                                   "msKds-Version",
-                                   "1",
-                                   LDB_FLAG_MOD_ADD);
+       ret = samdb_msg_append_uint64(ldb,
+                                     tmp_ctx,
+                                     add_msg,
+                                     "msKds-Version",
+                                     server_config_version,
+                                     LDB_FLAG_MOD_ADD);
        if (ret) {
                goto out;
        }
 
        ret = ldb_msg_append_string(add_msg,
                                    "msKds-KDFAlgorithmID",
-                                   "SP800_108_CTR_HMAC",
+                                   server_config_KDFAlgorithmID,
                                    LDB_FLAG_MOD_ADD);
        if (ret) {
                goto out;
        }
 
        ret = ldb_msg_append_string(add_msg,
-                                   "msKds-SecretAgreementAlgorithmID",
-                                   "DH",
-                                   LDB_FLAG_MOD_ADD);
+                                  "msKds-SecretAgreementAlgorithmID",
+                                  server_config_SecretAgreementAlgorithmID,
+                                  LDB_FLAG_MOD_ADD);
        if (ret) {
                goto out;
        }
 
-       {
-               static const uint8_t ffc_dh_parameters[] = {
-                       12,  2,   0,   0,   68,  72,  80,  77,  0,   1,   0,
-                       0,   135, 168, 230, 29,  180, 182, 102, 60,  255, 187,
-                       209, 156, 101, 25,  89,  153, 140, 238, 246, 8,   102,
-                       13,  208, 242, 93,  44,  238, 212, 67,  94,  59,  0,
-                       224, 13,  248, 241, 214, 25,  87,  212, 250, 247, 223,
-                       69,  97,  178, 170, 48,  22,  195, 217, 17,  52,  9,
-                       111, 170, 59,  244, 41,  109, 131, 14,  154, 124, 32,
-                       158, 12,  100, 151, 81,  122, 189, 90,  138, 157, 48,
-                       107, 207, 103, 237, 145, 249, 230, 114, 91,  71,  88,
-                       192, 34,  224, 177, 239, 66,  117, 191, 123, 108, 91,
-                       252, 17,  212, 95,  144, 136, 185, 65,  245, 78,  177,
-                       229, 155, 184, 188, 57,  160, 191, 18,  48,  127, 92,
-                       79,  219, 112, 197, 129, 178, 63,  118, 182, 58,  202,
-                       225, 202, 166, 183, 144, 45,  82,  82,  103, 53,  72,
-                       138, 14,  241, 60,  109, 154, 81,  191, 164, 171, 58,
-                       216, 52,  119, 150, 82,  77,  142, 246, 161, 103, 181,
-                       164, 24,  37,  217, 103, 225, 68,  229, 20,  5,   100,
-                       37,  28,  202, 203, 131, 230, 180, 134, 246, 179, 202,
-                       63,  121, 113, 80,  96,  38,  192, 184, 87,  246, 137,
-                       150, 40,  86,  222, 212, 1,   10,  189, 11,  230, 33,
-                       195, 163, 150, 10,  84,  231, 16,  195, 117, 242, 99,
-                       117, 215, 1,   65,  3,   164, 181, 67,  48,  193, 152,
-                       175, 18,  97,  22,  210, 39,  110, 17,  113, 95,  105,
-                       56,  119, 250, 215, 239, 9,   202, 219, 9,   74,  233,
-                       30,  26,  21,  151, 63,  179, 44,  155, 115, 19,  77,
-                       11,  46,  119, 80,  102, 96,  237, 189, 72,  76,  167,
-                       177, 143, 33,  239, 32,  84,  7,   244, 121, 58,  26,
-                       11,  161, 37,  16,  219, 193, 80,  119, 190, 70,  63,
-                       255, 79,  237, 74,  172, 11,  181, 85,  190, 58,  108,
-                       27,  12,  107, 71,  177, 188, 55,  115, 191, 126, 140,
-                       111, 98,  144, 18,  40,  248, 194, 140, 187, 24,  165,
-                       90,  227, 19,  65,  0,   10,  101, 1,   150, 249, 49,
-                       199, 122, 87,  242, 221, 244, 99,  229, 233, 236, 20,
-                       75,  119, 125, 230, 42,  170, 184, 168, 98,  138, 195,
-                       118, 210, 130, 214, 237, 56,  100, 230, 121, 130, 66,
-                       142, 188, 131, 29,  20,  52,  143, 111, 47,  145, 147,
-                       181, 4,   90,  242, 118, 113, 100, 225, 223, 201, 103,
-                       193, 251, 63,  46,  85,  164, 189, 27,  255, 232, 59,
-                       156, 128, 208, 82,  185, 133, 209, 130, 234, 10,  219,
-                       42,  59,  115, 19,  211, 254, 20,  200, 72,  75,  30,
-                       5,   37,  136, 185, 183, 210, 187, 210, 223, 1,   97,
-                       153, 236, 208, 110, 21,  87,  205, 9,   21,  179, 53,
-                       59,  187, 100, 224, 236, 55,  127, 208, 40,  55,  13,
-                       249, 43,  82,  199, 137, 20,  40,  205, 198, 126, 182,
-                       24,  75,  82,  61,  29,  178, 70,  195, 47,  99,  7,
-                       132, 144, 240, 14,  248, 214, 71,  209, 72,  212, 121,
-                       84,  81,  94,  35,  39,  207, 239, 152, 197, 130, 102,
-                       75,  76,  15,  108, 196, 22,  89};
-               const DATA_BLOB ffc_dh_parameters_blob = {
-                       discard_const_p(uint8_t, ffc_dh_parameters),
-                       sizeof ffc_dh_parameters};
-
+       if (server_config_SecretAgreementParam != NULL) {
                ret = ldb_msg_append_value(add_msg,
                                           "msKds-SecretAgreementParam",
-                                          &ffc_dh_parameters_blob,
+                                          server_config_SecretAgreementParam,
                                           LDB_FLAG_MOD_ADD);
                if (ret) {
                        goto out;
                }
        }
 
-       ret = ldb_msg_append_string(add_msg,
-                                   "msKds-PublicKeyLength",
-                                   "2048",
-                                   LDB_FLAG_MOD_ADD);
+       ret = samdb_msg_append_uint64(ldb,
+                                     tmp_ctx,
+                                     add_msg,
+                                     "msKds-PublicKeyLength",
+                                     server_config_PublicKeyLength,
+                                     LDB_FLAG_MOD_ADD);
        if (ret) {
                goto out;
        }
 
-       ret = ldb_msg_append_string(add_msg,
-                                   "msKds-PrivateKeyLength",
-                                   "512",
-                                   LDB_FLAG_MOD_ADD);
+       ret = samdb_msg_append_uint64(ldb,
+                                     tmp_ctx,
+                                     add_msg,
+                                     "msKds-PrivateKeyLength",
+                                     server_config_PrivateKeyLength,
+                                     LDB_FLAG_MOD_ADD);
+
+       ret = ldb_msg_append_value(add_msg,
+                                  "msKds-KDFParam",
+                                  server_config_KDFParam,
+                                  LDB_FLAG_MOD_ADD);
        if (ret) {
                goto out;
        }
 
-       {
-               static const uint8_t kdf_parameters[] = {
-                       0,   0, 0,   0, 1,   0, 0,   0, 14,  0,
-                       0,   0, 0,   0, 0,   0, 'S', 0, 'H', 0,
-                       'A', 0, '5', 0, '1', 0, '2', 0, 0,   0,
-               };
-               const DATA_BLOB kdf_parameters_blob = {
-                       discard_const_p(uint8_t, kdf_parameters),
-                       sizeof kdf_parameters};
-
-               ret = ldb_msg_append_value(add_msg,
-                                          "msKds-KDFParam",
-                                          &kdf_parameters_blob,
-                                          LDB_FLAG_MOD_ADD);
-               if (ret) {
-                       goto out;
-               }
-       }
-
        {
                uint8_t guid_buf[sizeof((struct GUID_ndr_buf){}.buf)];
                const DATA_BLOB guid_blob = {.data = guid_buf,