2024-02-13 16:09:57 +13:00
/*
Unix SMB / CIFS implementation .
Group Key Distribution Protocol functions
Copyright ( C ) Catalyst . Net Ltd 2024
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < https : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include <ldb.h>
# include <ldb_errors.h>
# include <ldb_module.h>
# include "lib/crypto/gkdi.h"
# include "lib/util/data_blob.h"
# include "lib/util/samba_util.h"
# include "lib/util/util_str_hex.h"
# include "librpc/ndr/libndr.h"
# include "dsdb/gmsa/gkdi.h"
# include "dsdb/samdb/ldb_modules/util.h"
# include "dsdb/samdb/samdb.h"
2024-03-22 14:08:22 +13:00
# include "dsdb/common/proto.h"
2024-03-22 16:58:40 +13:00
# include "librpc/gen_ndr/gkdi.h"
# include "librpc/gen_ndr/ndr_gkdi.h"
2024-02-13 16:09:57 +13:00
2024-02-13 16:09:57 +13:00
NTSTATUS gkdi_root_key_from_msg ( TALLOC_CTX * mem_ctx ,
const struct GUID root_key_id ,
const struct ldb_message * const msg ,
const struct ProvRootKey * * const root_key_out )
{
NTSTATUS status = NT_STATUS_OK ;
struct ldb_val root_key_data = { } ;
struct KdfAlgorithm kdf_algorithm = { } ;
const int version = ldb_msg_find_attr_as_int ( msg , " msKds-Version " , 0 ) ;
const NTTIME create_time = samdb_result_nttime ( msg ,
" msKds-CreateTime " ,
0 ) ;
const NTTIME use_start_time = samdb_result_nttime ( msg ,
" msKds-UseStartTime " ,
0 ) ;
const char * domain_id = ldb_msg_find_attr_as_string ( msg ,
" msKds-DomainID " ,
NULL ) ;
{
const struct ldb_val * root_key_val = ldb_msg_find_ldb_val (
msg , " msKds-RootKeyData " ) ;
if ( root_key_val ! = NULL ) {
root_key_data = * root_key_val ;
}
}
{
const char * algorithm_id = ldb_msg_find_attr_as_string (
msg , " msKds-KDFAlgorithmID " , NULL ) ;
const struct ldb_val * kdf_param_val = ldb_msg_find_ldb_val (
msg , " msKds-KDFParam " ) ;
status = kdf_algorithm_from_params ( algorithm_id ,
kdf_param_val ,
& kdf_algorithm ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto out ;
}
}
status = ProvRootKey ( mem_ctx ,
root_key_id ,
version ,
root_key_data ,
create_time ,
use_start_time ,
domain_id ,
kdf_algorithm ,
root_key_out ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto out ;
}
out :
return status ;
}
/*
* Calculate an appropriate useStartTime for a root key created at
* ‘ current_time ’ .
*
* This function goes unused .
*/
NTTIME gkdi_root_key_use_start_time ( const NTTIME current_time )
{
const NTTIME start_time = gkdi_get_interval_start_time ( current_time ) ;
return start_time + gkdi_key_cycle_duration + gkdi_max_clock_skew ;
}
2024-02-13 16:09:57 +13:00
static int gkdi_create_root_key ( TALLOC_CTX * mem_ctx ,
struct ldb_context * const ldb ,
const NTTIME current_time ,
const NTTIME use_start_time ,
struct GUID * const root_key_id_out ,
struct ldb_dn * * const root_key_dn_out )
{
TALLOC_CTX * tmp_ctx = NULL ;
struct GUID root_key_id ;
2024-03-22 14:08:22 +13:00
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 ;
2024-03-22 16:58:40 +13:00
DATA_BLOB kdf_parameters_blob = data_blob_null ;
2024-02-13 16:09:57 +13:00
struct ldb_message * add_msg = NULL ;
s4:dsdb: Fix stack use after scope in gkdi_create_root_key()
==20978==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7f4f91ff51a0 at pc 0x7f4f94cf93d6 bp 0x7ffdb90fc510 sp 0x7ffdb90fbcd0
READ of size 64 at 0x7f4f91ff51a0 thread T0
#0 0x7f4f94cf93d5 in memcpy ../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc:115
#1 0x7f4f933bdb67 in ldb_val_dup ../../lib/ldb/common/ldb_msg.c:325
#2 0x7f4f933c11d1 in ldb_msg_copy ../../lib/ldb/common/ldb_msg.c:1182
#3 0x7f4f933c13d2 in ldb_msg_normalize ../../lib/ldb/common/ldb_msg.c:1235
#4 0x7f4f933ab556 in ldb_request ../../lib/ldb/common/ldb.c:1196
#5 0x7f4f8e82b1d4 in dsdb_autotransaction_request ../../source4/dsdb/common/util.c:1220
#6 0x7f4f8e831c8a in dsdb_add ../../source4/dsdb/common/util.c:5354
#7 0x7f4f8e853a01 in gkdi_create_root_key ../../source4/dsdb/gmsa/gkdi.c:493
#8 0x7f4f8e853a01 in gkdi_new_root_key ../../source4/dsdb/gmsa/gkdi.c:551
#9 0x7f4f8cd4ca52 in py_dsdb_create_gkdi_root_key ../../source4/dsdb/pydsdb.c:1388
#10 0x7f4f947ce01c (/lib64/libpython3.11.so.1.0+0x1ce01c) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#11 0x7f4f947de4c0 in _PyObject_Call (/lib64/libpython3.11.so.1.0+0x1de4c0) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#12 0x7f4f947be6ca in _PyEval_EvalFrameDefault (/lib64/libpython3.11.so.1.0+0x1be6ca) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#13 0x7f4f947b6e79 (/lib64/libpython3.11.so.1.0+0x1b6e79) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#14 0x7f4f947de5d8 (/lib64/libpython3.11.so.1.0+0x1de5d8) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#15 0x7f4f947be6ca in _PyEval_EvalFrameDefault (/lib64/libpython3.11.so.1.0+0x1be6ca) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#16 0x7f4f947b6e79 (/lib64/libpython3.11.so.1.0+0x1b6e79) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#17 0x7f4f947edabb (/lib64/libpython3.11.so.1.0+0x1edabb) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#18 0x7f4f947de5d8 (/lib64/libpython3.11.so.1.0+0x1de5d8) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#19 0x7f4f947be6ca in _PyEval_EvalFrameDefault (/lib64/libpython3.11.so.1.0+0x1be6ca) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#20 0x7f4f947b6e79 (/lib64/libpython3.11.so.1.0+0x1b6e79) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#21 0x7f4f947ed9fb (/lib64/libpython3.11.so.1.0+0x1ed9fb) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#22 0x7f4f947be6ca in _PyEval_EvalFrameDefault (/lib64/libpython3.11.so.1.0+0x1be6ca) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#23 0x7f4f947b6e79 (/lib64/libpython3.11.so.1.0+0x1b6e79) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#24 0x7f4f947be6ca in _PyEval_EvalFrameDefault (/lib64/libpython3.11.so.1.0+0x1be6ca) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#25 0x7f4f947b6e79 (/lib64/libpython3.11.so.1.0+0x1b6e79) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#26 0x7f4f94839997 in PyEval_EvalCode (/lib64/libpython3.11.so.1.0+0x239997) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#27 0x7f4f94856862 (/lib64/libpython3.11.so.1.0+0x256862) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#28 0x7f4f94852e59 (/lib64/libpython3.11.so.1.0+0x252e59) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#29 0x7f4f94868fb1 (/lib64/libpython3.11.so.1.0+0x268fb1) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#30 0x7f4f948687a3 in _PyRun_SimpleFileObject (/lib64/libpython3.11.so.1.0+0x2687a3) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#31 0x7f4f94868453 in _PyRun_AnyFileObject (/lib64/libpython3.11.so.1.0+0x268453) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#32 0x7f4f94861c53 in Py_RunMain (/lib64/libpython3.11.so.1.0+0x261c53) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#33 0x7f4f94829996 in Py_BytesMain (/lib64/libpython3.11.so.1.0+0x229996) (BuildId: 170cbf941d17f6c2ac4f784129b31ebaa10c44a7)
#34 0x7f4f9422a1ef in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#35 0x7f4f9422a2b8 in __libc_start_main_impl ../csu/libc-start.c:360
#36 0x5604497e3084 in _start (/usr/bin/python3.11+0x1084) (BuildId: f5d6e3bdbf9098a6ddde0b7f2e07ffc9ad1b1dc3)
Address 0x7f4f91ff51a0 is located in stack of thread T0 at offset 416 in frame
#0 0x7f4f8e852b37 in gkdi_new_root_key ../../source4/dsdb/gmsa/gkdi.c:537
This frame has 12 object(s):
[32, 40) 'root_key_dn' (line 539)
[64, 72) 'res' (line 540)
[96, 104) 'server_config_res' (line 118)
[128, 136) 'kdf_algorithm' (line 128)
[160, 168) 'domain_dn' (line 388)
[192, 208) 'kdf_parameters_blob' (line 129)
[224, 240) 'root_key_data_blob' (line 353)
[256, 272) 'guid_blob' (line 467)
[288, 312) 'kdf_parameters' (line 226)
[352, 368) 'root_key_id' (line 116)
[384, 400) 'guid_buf' (line 466)
[416, 480) 'root_key_data' (line 352) <== Memory access at offset 416 is inside this variable
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Joseph Sutton <jsutton@samba.org>
Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Fri May 3 12:20:55 UTC 2024 on atb-devel-224
2024-04-30 09:16:40 +02:00
uint8_t root_key_data [ GKDI_KEY_LEN ] ;
2024-02-13 16:09:57 +13:00
NTSTATUS status = NT_STATUS_OK ;
int ret = LDB_SUCCESS ;
2024-03-22 14:08:22 +13:00
static const char * server_config_attrs [ ] = {
" msKds-Version " ,
" msKds-KDFAlgorithmID " ,
" msKds-SecretAgreementAlgorithmID " ,
" msKds-SecretAgreementParam " ,
" msKds-PublicKeyLength " ,
" msKds-PrivateKeyLength " ,
" msKds-KDFParam " ,
NULL
} ;
2024-02-13 16:09:57 +13:00
* root_key_dn_out = NULL ;
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
ret = ldb_oom ( ldb ) ;
goto out ;
}
2024-03-22 14:08:22 +13:00
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 ,
2024-04-16 13:49:04 +12:00
0 ) ;
2024-03-22 14:08:22 +13:00
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 ) {
2024-03-22 16:58:40 +13:00
struct KdfParameters kdf_parameters = {
. hash_algorithm = " SHA512 "
2024-03-22 14:08:22 +13:00
} ;
2024-03-22 16:58:40 +13:00
enum ndr_err_code err ;
err = ndr_push_struct_blob ( & kdf_parameters_blob ,
tmp_ctx ,
& kdf_parameters ,
( ndr_push_flags_fn_t )
ndr_push_KdfParameters ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( err ) ) {
status = ndr_map_error2ntstatus ( err ) ;
ldb_asprintf_errstring ( ldb ,
" KdfParameters pull failed: %s \n " ,
nt_errstr ( status ) ) ;
ret = LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE ;
goto out ;
}
2024-03-22 14:08:22 +13:00
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 [ ] = {
2024-03-22 16:43:38 +13:00
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 ,
2024-03-22 14:08:22 +13:00
224 , 13 , 248 , 241 , 214 , 25 , 87 , 212 , 250 , 247 , 223 ,
2024-03-22 16:43:38 +13:00
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 ,
2024-03-22 14:08:22 +13:00
107 , 207 , 103 , 237 , 145 , 249 , 230 , 114 , 91 , 71 , 88 ,
192 , 34 , 224 , 177 , 239 , 66 , 117 , 191 , 123 , 108 , 91 ,
2024-03-22 16:43:38 +13:00
252 , 17 , 212 , 95 , 144 , 136 , 185 , 65 , 245 , 78 , 177 ,
229 , 155 , 184 , 188 , 57 , 160 , 191 , 18 , 48 , 127 , 92 ,
2024-03-22 14:08:22 +13:00
79 , 219 , 112 , 197 , 129 , 178 , 63 , 118 , 182 , 58 , 202 ,
2024-03-22 16:43:38 +13:00
225 , 202 , 166 , 183 , 144 , 45 , 82 , 82 , 103 , 53 , 72 ,
2024-03-22 14:08:22 +13:00
138 , 14 , 241 , 60 , 109 , 154 , 81 , 191 , 164 , 171 , 58 ,
2024-03-22 16:43:38 +13:00
216 , 52 , 119 , 150 , 82 , 77 , 142 , 246 , 161 , 103 , 181 ,
164 , 24 , 37 , 217 , 103 , 225 , 68 , 229 , 20 , 5 , 100 ,
2024-03-22 14:08:22 +13:00
37 , 28 , 202 , 203 , 131 , 230 , 180 , 134 , 246 , 179 , 202 ,
2024-03-22 16:43:38 +13:00
63 , 121 , 113 , 80 , 96 , 38 , 192 , 184 , 87 , 246 , 137 ,
2024-03-22 14:08:22 +13:00
150 , 40 , 86 , 222 , 212 , 1 , 10 , 189 , 11 , 230 , 33 ,
2024-03-22 16:43:38 +13:00
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 ,
2024-03-22 14:08:22 +13:00
56 , 119 , 250 , 215 , 239 , 9 , 202 , 219 , 9 , 74 , 233 ,
2024-03-22 16:43:38 +13:00
30 , 26 , 21 , 151 , 63 , 179 , 44 , 155 , 115 , 19 , 77 ,
2024-03-22 14:08:22 +13:00
11 , 46 , 119 , 80 , 102 , 96 , 237 , 189 , 72 , 76 , 167 ,
2024-03-22 16:43:38 +13:00
177 , 143 , 33 , 239 , 32 , 84 , 7 , 244 , 121 , 58 , 26 ,
2024-03-22 14:08:22 +13:00
11 , 161 , 37 , 16 , 219 , 193 , 80 , 119 , 190 , 70 , 63 ,
2024-03-22 16:43:38 +13:00
255 , 79 , 237 , 74 , 172 , 11 , 181 , 85 , 190 , 58 , 108 ,
2024-03-22 14:08:22 +13:00
27 , 12 , 107 , 71 , 177 , 188 , 55 , 115 , 191 , 126 , 140 ,
2024-03-22 16:43:38 +13:00
111 , 98 , 144 , 18 , 40 , 248 , 194 , 140 , 187 , 24 , 165 ,
90 , 227 , 19 , 65 , 0 , 10 , 101 , 1 , 150 , 249 , 49 ,
2024-03-22 14:08:22 +13:00
199 , 122 , 87 , 242 , 221 , 244 , 99 , 229 , 233 , 236 , 20 ,
2024-03-22 16:43:38 +13:00
75 , 119 , 125 , 230 , 42 , 170 , 184 , 168 , 98 , 138 , 195 ,
2024-03-22 14:08:22 +13:00
118 , 210 , 130 , 214 , 237 , 56 , 100 , 230 , 121 , 130 , 66 ,
2024-03-22 16:43:38 +13:00
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 ,
2024-03-22 14:08:22 +13:00
156 , 128 , 208 , 82 , 185 , 133 , 209 , 130 , 234 , 10 , 219 ,
42 , 59 , 115 , 19 , 211 , 254 , 20 , 200 , 72 , 75 , 30 ,
2024-03-22 16:43:38 +13:00
5 , 37 , 136 , 185 , 183 , 210 , 187 , 210 , 223 , 1 , 97 ,
153 , 236 , 208 , 110 , 21 , 87 , 205 , 9 , 21 , 179 , 53 ,
2024-03-22 14:08:22 +13:00
59 , 187 , 100 , 224 , 236 , 55 , 127 , 208 , 40 , 55 , 13 ,
249 , 43 , 82 , 199 , 137 , 20 , 40 , 205 , 198 , 126 , 182 ,
2024-03-22 16:43:38 +13:00
24 , 75 , 82 , 61 , 29 , 178 , 70 , 195 , 47 , 99 , 7 ,
2024-03-22 14:08:22 +13:00
132 , 144 , 240 , 14 , 248 , 214 , 71 , 209 , 72 , 212 , 121 ,
2024-03-22 16:43:38 +13:00
84 , 81 , 94 , 35 , 39 , 207 , 239 , 152 , 197 , 130 , 102 ,
2024-03-22 14:08:22 +13:00
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 ) ;
2024-02-13 16:09:57 +13:00
add_msg = ldb_msg_new ( tmp_ctx ) ;
if ( add_msg = = NULL ) {
ret = ldb_oom ( ldb ) ;
goto out ;
}
ret = ldb_msg_append_string ( add_msg ,
" objectClass " ,
" msKds-ProvRootKey " ,
LDB_FLAG_MOD_ADD ) ;
if ( ret ) {
goto out ;
}
{
const DATA_BLOB root_key_data_blob = {
. data = root_key_data , . length = sizeof root_key_data } ;
generate_secret_buffer ( root_key_data , sizeof root_key_data ) ;
ret = ldb_msg_append_value ( add_msg ,
" msKds-RootKeyData " ,
& root_key_data_blob ,
LDB_FLAG_MOD_ADD ) ;
if ( ret ) {
goto out ;
}
}
ret = samdb_msg_append_uint64 ( ldb ,
tmp_ctx ,
add_msg ,
" msKds-CreateTime " ,
current_time ,
LDB_FLAG_MOD_ADD ) ;
if ( ret ) {
goto out ;
}
ret = samdb_msg_append_uint64 ( ldb ,
tmp_ctx ,
add_msg ,
" msKds-UseStartTime " ,
use_start_time ,
LDB_FLAG_MOD_ADD ) ;
if ( ret ) {
goto out ;
}
{
struct ldb_dn * domain_dn = NULL ;
ret = samdb_server_reference_dn ( ldb , tmp_ctx , & domain_dn ) ;
if ( ret ) {
goto out ;
}
ret = ldb_msg_append_linearized_dn ( add_msg ,
" msKds-DomainID " ,
domain_dn ,
LDB_FLAG_MOD_ADD ) ;
if ( ret ) {
goto out ;
}
}
2024-03-22 14:08:22 +13:00
ret = samdb_msg_append_uint64 ( ldb ,
tmp_ctx ,
add_msg ,
" msKds-Version " ,
server_config_version ,
LDB_FLAG_MOD_ADD ) ;
2024-02-13 16:09:57 +13:00
if ( ret ) {
goto out ;
}
ret = ldb_msg_append_string ( add_msg ,
" msKds-KDFAlgorithmID " ,
2024-03-22 14:08:22 +13:00
server_config_KDFAlgorithmID ,
2024-02-13 16:09:57 +13:00
LDB_FLAG_MOD_ADD ) ;
if ( ret ) {
goto out ;
}
ret = ldb_msg_append_string ( add_msg ,
2024-03-22 14:08:22 +13:00
" msKds-SecretAgreementAlgorithmID " ,
server_config_SecretAgreementAlgorithmID ,
LDB_FLAG_MOD_ADD ) ;
2024-02-13 16:09:57 +13:00
if ( ret ) {
goto out ;
}
2024-03-22 14:08:22 +13:00
if ( server_config_SecretAgreementParam ! = NULL ) {
2024-02-13 16:09:57 +13:00
ret = ldb_msg_append_value ( add_msg ,
" msKds-SecretAgreementParam " ,
2024-03-22 14:08:22 +13:00
server_config_SecretAgreementParam ,
2024-02-13 16:09:57 +13:00
LDB_FLAG_MOD_ADD ) ;
if ( ret ) {
goto out ;
}
}
2024-03-22 14:08:22 +13:00
ret = samdb_msg_append_uint64 ( ldb ,
tmp_ctx ,
add_msg ,
" msKds-PublicKeyLength " ,
server_config_PublicKeyLength ,
LDB_FLAG_MOD_ADD ) ;
2024-02-13 16:09:57 +13:00
if ( ret ) {
goto out ;
}
2024-03-22 14:08:22 +13:00
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 ) ;
2024-02-13 16:09:57 +13:00
if ( ret ) {
goto out ;
}
{
uint8_t guid_buf [ sizeof ( ( struct GUID_ndr_buf ) { } . buf ) ] ;
const DATA_BLOB guid_blob = { . data = guid_buf ,
. length = sizeof guid_buf } ;
generate_secret_buffer ( guid_buf , sizeof guid_buf ) ;
status = GUID_from_ndr_blob ( & guid_blob , & root_key_id ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
ret = ldb_operr ( ldb ) ;
goto out ;
}
}
{
struct ldb_dn * root_key_dn = NULL ;
root_key_dn = samdb_gkdi_root_key_dn ( ldb ,
tmp_ctx ,
& root_key_id ) ;
if ( root_key_dn = = NULL ) {
ret = ldb_operr ( ldb ) ;
goto out ;
}
add_msg - > dn = root_key_dn ;
}
ret = dsdb_add ( ldb , add_msg , 0 ) ;
if ( ret ) {
goto out ;
}
* root_key_id_out = root_key_id ;
* root_key_dn_out = talloc_steal ( mem_ctx , add_msg - > dn ) ;
out :
talloc_free ( tmp_ctx ) ;
return ret ;
}
/*
* The PrivateKey , PublicKey , and SecretAgreement attributes are related to the
* public ‐ key functionality in GKDI . Samba doesn ’ t try to implement any of that ,
* so we don ’ t bother looking at these attributes .
*/
static const char * const root_key_attrs [ ] = {
" msKds-CreateTime " ,
" msKds-DomainID " ,
" msKds-KDFAlgorithmID " ,
" msKds-KDFParam " ,
/* "msKds-PrivateKeyLength", */
/* "msKds-PublicKeyLength", */
" msKds-RootKeyData " ,
/* "msKds-SecretAgreementAlgorithmID", */
/* "msKds-SecretAgreementParam", */
" msKds-UseStartTime " ,
" msKds-Version " ,
NULL ,
} ;
/*
* Create and return a new GKDI root key .
*
* This function goes unused .
*/
int gkdi_new_root_key ( TALLOC_CTX * mem_ctx ,
struct ldb_context * const ldb ,
const NTTIME current_time ,
const NTTIME use_start_time ,
struct GUID * const root_key_id_out ,
const struct ldb_message * * const root_key_out )
{
TALLOC_CTX * tmp_ctx = NULL ;
struct ldb_dn * root_key_dn = NULL ;
struct ldb_result * res = NULL ;
int ret = LDB_SUCCESS ;
* root_key_out = NULL ;
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
ret = ldb_oom ( ldb ) ;
goto out ;
}
ret = gkdi_create_root_key ( tmp_ctx ,
ldb ,
current_time ,
use_start_time ,
root_key_id_out ,
& root_key_dn ) ;
if ( ret ) {
goto out ;
}
ret = dsdb_search_dn (
ldb , tmp_ctx , & res , root_key_dn , root_key_attrs , 0 ) ;
if ( ret ) {
goto out ;
}
if ( res - > count ! = 1 ) {
ret = LDB_ERR_NO_SUCH_OBJECT ;
goto out ;
}
* root_key_out = talloc_steal ( mem_ctx , res - > msgs [ 0 ] ) ;
out :
talloc_free ( tmp_ctx ) ;
return ret ;
}
2024-02-13 16:09:57 +13:00
int gkdi_root_key_from_id ( TALLOC_CTX * mem_ctx ,
struct ldb_context * const ldb ,
const struct GUID * const root_key_id ,
const struct ldb_message * * const root_key_out )
{
TALLOC_CTX * tmp_ctx = NULL ;
struct ldb_dn * root_key_dn = NULL ;
struct ldb_result * res = NULL ;
int ret = LDB_SUCCESS ;
* root_key_out = NULL ;
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
ret = ldb_oom ( ldb ) ;
goto out ;
}
root_key_dn = samdb_gkdi_root_key_dn ( ldb , tmp_ctx , root_key_id ) ;
if ( root_key_dn = = NULL ) {
ret = ldb_operr ( ldb ) ;
goto out ;
}
ret = dsdb_search_dn (
ldb , tmp_ctx , & res , root_key_dn , root_key_attrs , 0 ) ;
if ( ret ) {
goto out ;
}
if ( res - > count ! = 1 ) {
ret = dsdb_werror ( ldb ,
LDB_ERR_NO_SUCH_OBJECT ,
W_ERROR ( HRES_ERROR_V ( HRES_NTE_NO_KEY ) ) ,
" failed to find root key " ) ;
goto out ;
}
* root_key_out = talloc_steal ( mem_ctx , res - > msgs [ 0 ] ) ;
out :
talloc_free ( tmp_ctx ) ;
return ret ;
}
int gkdi_most_recently_created_root_key (
TALLOC_CTX * mem_ctx ,
struct ldb_context * const ldb ,
_UNUSED_ const NTTIME current_time ,
const NTTIME not_after ,
struct GUID * const root_key_id_out ,
const struct ldb_message * * const root_key_out )
{
TALLOC_CTX * tmp_ctx = NULL ;
struct ldb_result * res = NULL ;
int ret = LDB_SUCCESS ;
* root_key_out = NULL ;
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
ret = ldb_oom ( ldb ) ;
goto out ;
}
{
struct ldb_dn * root_key_container_dn = NULL ;
root_key_container_dn = samdb_gkdi_root_key_container_dn (
ldb , tmp_ctx ) ;
if ( root_key_container_dn = = NULL ) {
ret = ldb_operr ( ldb ) ;
goto out ;
}
ret = dsdb_search ( ldb ,
tmp_ctx ,
& res ,
root_key_container_dn ,
LDB_SCOPE_ONELEVEL ,
root_key_attrs ,
0 ,
" (msKds-UseStartTime<=% " PRIu64 " ) " ,
not_after ) ;
if ( ret ) {
goto out ;
}
}
/*
* Windows just gives up if there are more than 1000 root keys in the
* container .
*/
{
struct root_key_candidate {
struct GUID id ;
const struct ldb_message * key ;
NTTIME create_time ;
} most_recent_key = {
. key = NULL ,
} ;
unsigned i ;
for ( i = 0 ; i < res - > count ; + + i ) {
struct root_key_candidate key = {
. key = res - > msgs [ i ] ,
} ;
const struct ldb_val * rdn_val = NULL ;
bool ok ;
key . create_time = samdb_result_nttime (
key . key , " msKds-CreateTime " , 0 ) ;
if ( key . create_time < most_recent_key . create_time ) {
/* We already have a more recent key. */
continue ;
}
rdn_val = ldb_dn_get_rdn_val ( key . key - > dn ) ;
if ( rdn_val = = NULL ) {
continue ;
}
if ( rdn_val - > length ! = 36 ) {
/*
* Check the RDN is the right length — 36 is the
* length of a UUID .
*/
continue ;
}
ok = parse_guid_string ( ( const char * ) rdn_val - > data ,
& key . id ) ;
if ( ! ok ) {
/* The RDN is not a correctly formatted GUID. */
continue ;
}
/*
* We ’ ve found a new candidate for the most recent root
* key .
*/
most_recent_key = key ;
}
if ( most_recent_key . key = = NULL ) {
/*
* We were not able to find a suitable root key , but
* there is a possibility that a key we create now will
* do : if gkdi_root_key_use_start_time ( current_time ) ≤
* not_after , then a newly ‐ created key will satisfy our
* caller ’ s requirements .
*
* Unfortunately , with gMSAs this ( I believe ) will never
* be the case . It ’ s too late to call
* gkdi_new_root_key ( ) — the new key will be a bit * too *
* new to be usable for a gMSA .
*/
ret = dsdb_werror ( ldb ,
LDB_ERR_NO_SUCH_OBJECT ,
W_ERROR ( HRES_ERROR_V (
HRES_NTE_NO_KEY ) ) ,
" failed to find a suitable root key " ) ;
goto out ;
}
/* Return the root key that we found. */
* root_key_id_out = most_recent_key . id ;
* root_key_out = talloc_steal ( mem_ctx , most_recent_key . key ) ;
}
out :
talloc_free ( tmp_ctx ) ;
return ret ;
}