LCOV - code coverage report
Current view: top level - source4/dsdb/gmsa - gkdi.c (source / functions) Hit Total Coverage
Test: coverage report for master 7edf5467 Lines: 80 106 75.5 %
Date: 2024-03-23 18:40:31 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Group Key Distribution Protocol functions
       4             : 
       5             :    Copyright (C) Catalyst.Net Ltd 2024
       6             : 
       7             :    This program is free software: you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation, either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <https://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include <ldb.h>
      23             : #include <ldb_errors.h>
      24             : #include <ldb_module.h>
      25             : #include "lib/crypto/gkdi.h"
      26             : #include "lib/util/data_blob.h"
      27             : #include "lib/util/samba_util.h"
      28             : #include "lib/util/util_str_hex.h"
      29             : #include "librpc/ndr/libndr.h"
      30             : #include "dsdb/gmsa/gkdi.h"
      31             : #include "dsdb/samdb/ldb_modules/util.h"
      32             : #include "dsdb/samdb/samdb.h"
      33             : 
      34          95 : static int gkdi_create_root_key(TALLOC_CTX *mem_ctx,
      35             :                                 struct ldb_context *const ldb,
      36             :                                 const NTTIME current_time,
      37             :                                 const NTTIME use_start_time,
      38             :                                 struct GUID *const root_key_id_out,
      39             :                                 struct ldb_dn **const root_key_dn_out)
      40             : {
      41          95 :         TALLOC_CTX *tmp_ctx = NULL;
      42          22 :         struct GUID root_key_id;
      43          95 :         struct ldb_message *add_msg = NULL;
      44          95 :         NTSTATUS status = NT_STATUS_OK;
      45          95 :         int ret = LDB_SUCCESS;
      46             : 
      47          95 :         *root_key_dn_out = NULL;
      48             : 
      49          95 :         tmp_ctx = talloc_new(mem_ctx);
      50          95 :         if (tmp_ctx == NULL) {
      51           0 :                 ret = ldb_oom(ldb);
      52           0 :                 goto out;
      53             :         }
      54             : 
      55          95 :         add_msg = ldb_msg_new(tmp_ctx);
      56          95 :         if (add_msg == NULL) {
      57           0 :                 ret = ldb_oom(ldb);
      58           0 :                 goto out;
      59             :         }
      60             : 
      61          95 :         ret = ldb_msg_append_string(add_msg,
      62             :                                     "objectClass",
      63             :                                     "msKds-ProvRootKey",
      64             :                                     LDB_FLAG_MOD_ADD);
      65          95 :         if (ret) {
      66           0 :                 goto out;
      67             :         }
      68             : 
      69             :         {
      70          22 :                 uint8_t root_key_data[GKDI_KEY_LEN];
      71          95 :                 const DATA_BLOB root_key_data_blob = {
      72             :                         .data = root_key_data, .length = sizeof root_key_data};
      73             : 
      74          95 :                 generate_secret_buffer(root_key_data, sizeof root_key_data);
      75             : 
      76          95 :                 ret = ldb_msg_append_value(add_msg,
      77             :                                            "msKds-RootKeyData",
      78             :                                            &root_key_data_blob,
      79             :                                            LDB_FLAG_MOD_ADD);
      80          95 :                 if (ret) {
      81           0 :                         goto out;
      82             :                 }
      83             :         }
      84             : 
      85          95 :         ret = samdb_msg_append_uint64(ldb,
      86             :                                       tmp_ctx,
      87             :                                       add_msg,
      88             :                                       "msKds-CreateTime",
      89             :                                       current_time,
      90             :                                       LDB_FLAG_MOD_ADD);
      91          95 :         if (ret) {
      92           0 :                 goto out;
      93             :         }
      94             : 
      95          95 :         ret = samdb_msg_append_uint64(ldb,
      96             :                                       tmp_ctx,
      97             :                                       add_msg,
      98             :                                       "msKds-UseStartTime",
      99             :                                       use_start_time,
     100             :                                       LDB_FLAG_MOD_ADD);
     101          95 :         if (ret) {
     102           0 :                 goto out;
     103             :         }
     104             : 
     105             :         {
     106          95 :                 struct ldb_dn *domain_dn = NULL;
     107             : 
     108          95 :                 ret = samdb_server_reference_dn(ldb, tmp_ctx, &domain_dn);
     109          95 :                 if (ret) {
     110           0 :                         goto out;
     111             :                 }
     112             : 
     113          95 :                 ret = ldb_msg_append_linearized_dn(add_msg,
     114             :                                                    "msKds-DomainID",
     115             :                                                    domain_dn,
     116             :                                                    LDB_FLAG_MOD_ADD);
     117          95 :                 if (ret) {
     118           0 :                         goto out;
     119             :                 }
     120             :         }
     121             : 
     122          95 :         ret = ldb_msg_append_string(add_msg,
     123             :                                     "msKds-Version",
     124             :                                     "1",
     125             :                                     LDB_FLAG_MOD_ADD);
     126          95 :         if (ret) {
     127           0 :                 goto out;
     128             :         }
     129             : 
     130          95 :         ret = ldb_msg_append_string(add_msg,
     131             :                                     "msKds-KDFAlgorithmID",
     132             :                                     "SP800_108_CTR_HMAC",
     133             :                                     LDB_FLAG_MOD_ADD);
     134          95 :         if (ret) {
     135           0 :                 goto out;
     136             :         }
     137             : 
     138          95 :         ret = ldb_msg_append_string(add_msg,
     139             :                                     "msKds-SecretAgreementAlgorithmID",
     140             :                                     "DH",
     141             :                                     LDB_FLAG_MOD_ADD);
     142          95 :         if (ret) {
     143           0 :                 goto out;
     144             :         }
     145             : 
     146             :         {
     147          22 :                 static const uint8_t ffc_dh_parameters[] = {
     148             :                         12,  2,   0,   0,   68,  72,  80,  77,  0,   1,   0,
     149             :                         0,   135, 168, 230, 29,  180, 182, 102, 60,  255, 187,
     150             :                         209, 156, 101, 25,  89,  153, 140, 238, 246, 8,   102,
     151             :                         13,  208, 242, 93,  44,  238, 212, 67,  94,  59,  0,
     152             :                         224, 13,  248, 241, 214, 25,  87,  212, 250, 247, 223,
     153             :                         69,  97,  178, 170, 48,  22,  195, 217, 17,  52,  9,
     154             :                         111, 170, 59,  244, 41,  109, 131, 14,  154, 124, 32,
     155             :                         158, 12,  100, 151, 81,  122, 189, 90,  138, 157, 48,
     156             :                         107, 207, 103, 237, 145, 249, 230, 114, 91,  71,  88,
     157             :                         192, 34,  224, 177, 239, 66,  117, 191, 123, 108, 91,
     158             :                         252, 17,  212, 95,  144, 136, 185, 65,  245, 78,  177,
     159             :                         229, 155, 184, 188, 57,  160, 191, 18,  48,  127, 92,
     160             :                         79,  219, 112, 197, 129, 178, 63,  118, 182, 58,  202,
     161             :                         225, 202, 166, 183, 144, 45,  82,  82,  103, 53,  72,
     162             :                         138, 14,  241, 60,  109, 154, 81,  191, 164, 171, 58,
     163             :                         216, 52,  119, 150, 82,  77,  142, 246, 161, 103, 181,
     164             :                         164, 24,  37,  217, 103, 225, 68,  229, 20,  5,   100,
     165             :                         37,  28,  202, 203, 131, 230, 180, 134, 246, 179, 202,
     166             :                         63,  121, 113, 80,  96,  38,  192, 184, 87,  246, 137,
     167             :                         150, 40,  86,  222, 212, 1,   10,  189, 11,  230, 33,
     168             :                         195, 163, 150, 10,  84,  231, 16,  195, 117, 242, 99,
     169             :                         117, 215, 1,   65,  3,   164, 181, 67,  48,  193, 152,
     170             :                         175, 18,  97,  22,  210, 39,  110, 17,  113, 95,  105,
     171             :                         56,  119, 250, 215, 239, 9,   202, 219, 9,   74,  233,
     172             :                         30,  26,  21,  151, 63,  179, 44,  155, 115, 19,  77,
     173             :                         11,  46,  119, 80,  102, 96,  237, 189, 72,  76,  167,
     174             :                         177, 143, 33,  239, 32,  84,  7,   244, 121, 58,  26,
     175             :                         11,  161, 37,  16,  219, 193, 80,  119, 190, 70,  63,
     176             :                         255, 79,  237, 74,  172, 11,  181, 85,  190, 58,  108,
     177             :                         27,  12,  107, 71,  177, 188, 55,  115, 191, 126, 140,
     178             :                         111, 98,  144, 18,  40,  248, 194, 140, 187, 24,  165,
     179             :                         90,  227, 19,  65,  0,   10,  101, 1,   150, 249, 49,
     180             :                         199, 122, 87,  242, 221, 244, 99,  229, 233, 236, 20,
     181             :                         75,  119, 125, 230, 42,  170, 184, 168, 98,  138, 195,
     182             :                         118, 210, 130, 214, 237, 56,  100, 230, 121, 130, 66,
     183             :                         142, 188, 131, 29,  20,  52,  143, 111, 47,  145, 147,
     184             :                         181, 4,   90,  242, 118, 113, 100, 225, 223, 201, 103,
     185             :                         193, 251, 63,  46,  85,  164, 189, 27,  255, 232, 59,
     186             :                         156, 128, 208, 82,  185, 133, 209, 130, 234, 10,  219,
     187             :                         42,  59,  115, 19,  211, 254, 20,  200, 72,  75,  30,
     188             :                         5,   37,  136, 185, 183, 210, 187, 210, 223, 1,   97,
     189             :                         153, 236, 208, 110, 21,  87,  205, 9,   21,  179, 53,
     190             :                         59,  187, 100, 224, 236, 55,  127, 208, 40,  55,  13,
     191             :                         249, 43,  82,  199, 137, 20,  40,  205, 198, 126, 182,
     192             :                         24,  75,  82,  61,  29,  178, 70,  195, 47,  99,  7,
     193             :                         132, 144, 240, 14,  248, 214, 71,  209, 72,  212, 121,
     194             :                         84,  81,  94,  35,  39,  207, 239, 152, 197, 130, 102,
     195             :                         75,  76,  15,  108, 196, 22,  89};
     196          95 :                 const DATA_BLOB ffc_dh_parameters_blob = {
     197             :                         discard_const_p(uint8_t, ffc_dh_parameters),
     198             :                         sizeof ffc_dh_parameters};
     199             : 
     200          95 :                 ret = ldb_msg_append_value(add_msg,
     201             :                                            "msKds-SecretAgreementParam",
     202             :                                            &ffc_dh_parameters_blob,
     203             :                                            LDB_FLAG_MOD_ADD);
     204          95 :                 if (ret) {
     205           0 :                         goto out;
     206             :                 }
     207             :         }
     208             : 
     209          95 :         ret = ldb_msg_append_string(add_msg,
     210             :                                     "msKds-PublicKeyLength",
     211             :                                     "2048",
     212             :                                     LDB_FLAG_MOD_ADD);
     213          95 :         if (ret) {
     214           0 :                 goto out;
     215             :         }
     216             : 
     217          95 :         ret = ldb_msg_append_string(add_msg,
     218             :                                     "msKds-PrivateKeyLength",
     219             :                                     "512",
     220             :                                     LDB_FLAG_MOD_ADD);
     221          95 :         if (ret) {
     222           0 :                 goto out;
     223             :         }
     224             : 
     225             :         {
     226          22 :                 static const uint8_t kdf_parameters[] = {
     227             :                         0,   0, 0,   0, 1,   0, 0,   0, 14,  0,
     228             :                         0,   0, 0,   0, 0,   0, 'S', 0, 'H', 0,
     229             :                         'A', 0, '5', 0, '1', 0, '2', 0, 0,   0,
     230             :                 };
     231          95 :                 const DATA_BLOB kdf_parameters_blob = {
     232             :                         discard_const_p(uint8_t, kdf_parameters),
     233             :                         sizeof kdf_parameters};
     234             : 
     235          95 :                 ret = ldb_msg_append_value(add_msg,
     236             :                                            "msKds-KDFParam",
     237             :                                            &kdf_parameters_blob,
     238             :                                            LDB_FLAG_MOD_ADD);
     239          95 :                 if (ret) {
     240           0 :                         goto out;
     241             :                 }
     242             :         }
     243             : 
     244             :         {
     245          22 :                 uint8_t guid_buf[sizeof((struct GUID_ndr_buf){}.buf)];
     246          95 :                 const DATA_BLOB guid_blob = {.data = guid_buf,
     247             :                                              .length = sizeof guid_buf};
     248             : 
     249          95 :                 generate_secret_buffer(guid_buf, sizeof guid_buf);
     250             : 
     251          95 :                 status = GUID_from_ndr_blob(&guid_blob, &root_key_id);
     252          95 :                 if (!NT_STATUS_IS_OK(status)) {
     253           0 :                         ret = ldb_operr(ldb);
     254           0 :                         goto out;
     255             :                 }
     256             :         }
     257             : 
     258             :         {
     259          95 :                 struct ldb_dn *root_key_dn = NULL;
     260             : 
     261          95 :                 root_key_dn = samdb_gkdi_root_key_dn(ldb,
     262             :                                                      tmp_ctx,
     263             :                                                      &root_key_id);
     264          95 :                 if (root_key_dn == NULL) {
     265           0 :                         ret = ldb_operr(ldb);
     266           0 :                         goto out;
     267             :                 }
     268             : 
     269          95 :                 add_msg->dn = root_key_dn;
     270             :         }
     271             : 
     272          95 :         ret = dsdb_add(ldb, add_msg, 0);
     273          95 :         if (ret) {
     274           1 :                 goto out;
     275             :         }
     276             : 
     277          94 :         *root_key_id_out = root_key_id;
     278          94 :         *root_key_dn_out = talloc_steal(mem_ctx, add_msg->dn);
     279             : 
     280          95 : out:
     281          95 :         talloc_free(tmp_ctx);
     282          95 :         return ret;
     283             : }
     284             : 
     285             : /*
     286             :  * The PrivateKey, PublicKey, and SecretAgreement attributes are related to the
     287             :  * public‐key functionality in GKDI. Samba doesn’t try to implement any of that,
     288             :  * so we don’t bother looking at these attributes.
     289             :  */
     290             : static const char *const root_key_attrs[] = {
     291             :         "msKds-CreateTime",
     292             :         "msKds-DomainID",
     293             :         "msKds-KDFAlgorithmID",
     294             :         "msKds-KDFParam",
     295             :         /* "msKds-PrivateKeyLength", */
     296             :         /* "msKds-PublicKeyLength", */
     297             :         "msKds-RootKeyData",
     298             :         /* "msKds-SecretAgreementAlgorithmID", */
     299             :         /* "msKds-SecretAgreementParam", */
     300             :         "msKds-UseStartTime",
     301             :         "msKds-Version",
     302             :         NULL,
     303             : };
     304             : 
     305             : /*
     306             :  * Create and return a new GKDI root key.
     307             :  *
     308             :  * This function goes unused.
     309             :  */
     310          95 : int gkdi_new_root_key(TALLOC_CTX *mem_ctx,
     311             :                       struct ldb_context *const ldb,
     312             :                       const NTTIME current_time,
     313             :                       const NTTIME use_start_time,
     314             :                       struct GUID *const root_key_id_out,
     315             :                       const struct ldb_message **const root_key_out)
     316             : {
     317          95 :         TALLOC_CTX *tmp_ctx = NULL;
     318          95 :         struct ldb_dn *root_key_dn = NULL;
     319          95 :         struct ldb_result *res = NULL;
     320          95 :         int ret = LDB_SUCCESS;
     321             : 
     322          95 :         *root_key_out = NULL;
     323             : 
     324          95 :         tmp_ctx = talloc_new(mem_ctx);
     325          95 :         if (tmp_ctx == NULL) {
     326           0 :                 ret = ldb_oom(ldb);
     327           0 :                 goto out;
     328             :         }
     329             : 
     330          95 :         ret = gkdi_create_root_key(tmp_ctx,
     331             :                                    ldb,
     332             :                                    current_time,
     333             :                                    use_start_time,
     334             :                                    root_key_id_out,
     335             :                                    &root_key_dn);
     336          95 :         if (ret) {
     337           1 :                 goto out;
     338             :         }
     339             : 
     340          94 :         ret = dsdb_search_dn(
     341             :                 ldb, tmp_ctx, &res, root_key_dn, root_key_attrs, 0);
     342          94 :         if (ret) {
     343           0 :                 goto out;
     344             :         }
     345             : 
     346          94 :         if (res->count != 1) {
     347           0 :                 ret = LDB_ERR_NO_SUCH_OBJECT;
     348           0 :                 goto out;
     349             :         }
     350             : 
     351          94 :         *root_key_out = talloc_steal(mem_ctx, res->msgs[0]);
     352             : 
     353          95 : out:
     354          95 :         talloc_free(tmp_ctx);
     355          95 :         return ret;
     356             : }

Generated by: LCOV version 1.14