Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : endpoint server for the backupkey interface
5 :
6 : Copyright (C) Matthieu Patou <mat@samba.org> 2010
7 : Copyright (C) Andreas Schneider <asn@samba.org> 2015
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "includes.h"
24 : #include "rpc_server/dcerpc_server.h"
25 : #include "rpc_server/common/common.h"
26 : #include "librpc/gen_ndr/ndr_backupkey.h"
27 : #include "dsdb/common/util.h"
28 : #include "dsdb/samdb/samdb.h"
29 : #include "lib/ldb/include/ldb_errors.h"
30 : #include "../lib/util/util_ldb.h"
31 : #include "param/param.h"
32 : #include "auth/session.h"
33 : #include "system/network.h"
34 :
35 : #include "../lib/tsocket/tsocket.h"
36 : #include "../libcli/security/security.h"
37 : #include "librpc/gen_ndr/ndr_security.h"
38 : #include "libds/common/roles.h"
39 :
40 : #include <gnutls/gnutls.h>
41 : #include <gnutls/x509.h>
42 : #include <gnutls/crypto.h>
43 : #include <gnutls/abstract.h>
44 :
45 : #include "lib/crypto/gnutls_helpers.h"
46 :
47 : #undef strncasecmp
48 :
49 : #define DCESRV_INTERFACE_BACKUPKEY_BIND(context, iface) \
50 : dcesrv_interface_backupkey_bind(context, iface)
51 5 : static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_connection_context *context,
52 : const struct dcesrv_interface *iface)
53 : {
54 5 : return dcesrv_interface_bind_require_privacy(context, iface);
55 : }
56 :
57 4 : static NTSTATUS set_lsa_secret(TALLOC_CTX *mem_ctx,
58 : struct ldb_context *ldb,
59 : const char *name,
60 : const DATA_BLOB *lsa_secret)
61 : {
62 4 : TALLOC_CTX *frame = talloc_stackframe();
63 : struct ldb_message *msg;
64 : struct ldb_result *res;
65 4 : struct ldb_dn *system_dn = NULL;
66 : struct ldb_val val;
67 : int ret;
68 : char *name2;
69 4 : struct timeval now = timeval_current();
70 4 : NTTIME nt_now = timeval_to_nttime(&now);
71 4 : const char *attrs[] = {
72 : NULL
73 : };
74 :
75 4 : msg = ldb_msg_new(frame);
76 4 : if (msg == NULL) {
77 0 : talloc_free(frame);
78 0 : return NT_STATUS_NO_MEMORY;
79 : }
80 :
81 : /*
82 : * This function is a lot like dcesrv_lsa_CreateSecret
83 : * in the rpc_server/lsa directory
84 : * The reason why we duplicate the effort here is that:
85 : * * we want to keep the former function static
86 : * * we want to avoid the burden of doing LSA calls
87 : * when we can just manipulate the secrets directly
88 : * * taillor the function to the particular needs of backup protocol
89 : */
90 :
91 4 : system_dn = samdb_system_container_dn(ldb, frame);
92 4 : if (system_dn == NULL) {
93 0 : talloc_free(frame);
94 0 : return NT_STATUS_NO_MEMORY;
95 : }
96 :
97 4 : name2 = talloc_asprintf(msg, "%s Secret", name);
98 4 : if (name2 == NULL) {
99 0 : talloc_free(frame);
100 0 : return NT_STATUS_NO_MEMORY;
101 : }
102 :
103 4 : ret = ldb_search(ldb, mem_ctx, &res, system_dn, LDB_SCOPE_SUBTREE, attrs,
104 : "(&(cn=%s)(objectclass=secret))",
105 : ldb_binary_encode_string(mem_ctx, name2));
106 :
107 4 : if (ret != LDB_SUCCESS || res->count != 0 ) {
108 0 : DEBUG(2, ("Secret %s already exists !\n", name2));
109 0 : talloc_free(frame);
110 0 : return NT_STATUS_OBJECT_NAME_COLLISION;
111 : }
112 :
113 : /*
114 : * We don't care about previous value as we are
115 : * here only if the key didn't exists before
116 : */
117 :
118 4 : msg->dn = ldb_dn_copy(frame, system_dn);
119 4 : if (msg->dn == NULL) {
120 0 : talloc_free(frame);
121 0 : return NT_STATUS_NO_MEMORY;
122 : }
123 4 : if (!ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
124 0 : talloc_free(frame);
125 0 : return NT_STATUS_NO_MEMORY;
126 : }
127 :
128 4 : ret = ldb_msg_add_string(msg, "cn", name2);
129 4 : if (ret != LDB_SUCCESS) {
130 0 : talloc_free(frame);
131 0 : return NT_STATUS_NO_MEMORY;
132 : }
133 4 : ret = ldb_msg_add_string(msg, "objectClass", "secret");
134 4 : if (ret != LDB_SUCCESS) {
135 0 : talloc_free(frame);
136 0 : return NT_STATUS_NO_MEMORY;
137 : }
138 4 : ret = samdb_msg_add_uint64(ldb, frame, msg, "priorSetTime", nt_now);
139 4 : if (ret != LDB_SUCCESS) {
140 0 : talloc_free(frame);
141 0 : return NT_STATUS_NO_MEMORY;
142 : }
143 4 : val.data = lsa_secret->data;
144 4 : val.length = lsa_secret->length;
145 4 : ret = ldb_msg_add_value(msg, "currentValue", &val, NULL);
146 4 : if (ret != LDB_SUCCESS) {
147 0 : talloc_free(frame);
148 0 : return NT_STATUS_NO_MEMORY;
149 : }
150 4 : ret = samdb_msg_add_uint64(ldb, frame, msg, "lastSetTime", nt_now);
151 4 : if (ret != LDB_SUCCESS) {
152 0 : talloc_free(frame);
153 0 : return NT_STATUS_NO_MEMORY;
154 : }
155 :
156 : /*
157 : * create the secret with DSDB_MODIFY_RELAX
158 : * otherwise dsdb/samdb/ldb_modules/objectclass.c forbid
159 : * the create of LSA secret object
160 : */
161 4 : ret = dsdb_add(ldb, msg, DSDB_MODIFY_RELAX);
162 4 : if (ret != LDB_SUCCESS) {
163 0 : DEBUG(2,("Failed to create secret record %s: %s\n",
164 : ldb_dn_get_linearized(msg->dn),
165 : ldb_errstring(ldb)));
166 0 : talloc_free(frame);
167 0 : return NT_STATUS_ACCESS_DENIED;
168 : }
169 :
170 4 : talloc_free(frame);
171 4 : return NT_STATUS_OK;
172 : }
173 :
174 : /* This function is pretty much like dcesrv_lsa_QuerySecret */
175 81 : static NTSTATUS get_lsa_secret(TALLOC_CTX *mem_ctx,
176 : struct ldb_context *ldb,
177 : const char *name,
178 : DATA_BLOB *lsa_secret)
179 : {
180 : TALLOC_CTX *tmp_mem;
181 : struct ldb_result *res;
182 81 : struct ldb_dn *system_dn = NULL;
183 : const struct ldb_val *val;
184 : uint8_t *data;
185 81 : const char *attrs[] = {
186 : "currentValue",
187 : NULL
188 : };
189 : int ret;
190 :
191 81 : lsa_secret->data = NULL;
192 81 : lsa_secret->length = 0;
193 :
194 81 : tmp_mem = talloc_new(mem_ctx);
195 81 : if (tmp_mem == NULL) {
196 0 : return NT_STATUS_NO_MEMORY;
197 : }
198 :
199 81 : system_dn = samdb_system_container_dn(ldb, tmp_mem);
200 81 : if (system_dn == NULL) {
201 0 : talloc_free(tmp_mem);
202 0 : return NT_STATUS_NO_MEMORY;
203 : }
204 :
205 81 : ret = ldb_search(ldb, mem_ctx, &res, system_dn, LDB_SCOPE_SUBTREE, attrs,
206 : "(&(cn=%s Secret)(objectclass=secret))",
207 : ldb_binary_encode_string(tmp_mem, name));
208 :
209 81 : if (ret != LDB_SUCCESS) {
210 0 : talloc_free(tmp_mem);
211 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
212 : }
213 81 : if (res->count == 0) {
214 5 : talloc_free(tmp_mem);
215 5 : return NT_STATUS_RESOURCE_NAME_NOT_FOUND;
216 : }
217 76 : if (res->count > 1) {
218 0 : DEBUG(2, ("Secret %s collision\n", name));
219 0 : talloc_free(tmp_mem);
220 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
221 : }
222 :
223 76 : val = ldb_msg_find_ldb_val(res->msgs[0], "currentValue");
224 76 : if (val == NULL) {
225 : /*
226 : * The secret object is here but we don't have the secret value
227 : * The most common case is a RODC
228 : */
229 0 : *lsa_secret = data_blob_null;
230 0 : talloc_free(tmp_mem);
231 0 : return NT_STATUS_OK;
232 : }
233 :
234 76 : data = val->data;
235 76 : lsa_secret->data = talloc_move(mem_ctx, &data);
236 76 : lsa_secret->length = val->length;
237 :
238 76 : talloc_free(tmp_mem);
239 76 : return NT_STATUS_OK;
240 : }
241 :
242 64 : static int reverse_and_get_bignum(TALLOC_CTX *mem_ctx,
243 : DATA_BLOB blob,
244 : gnutls_datum_t *datum)
245 : {
246 : uint32_t i;
247 :
248 64 : datum->data = talloc_array(mem_ctx, uint8_t, blob.length);
249 64 : if (datum->data == NULL) {
250 0 : return -1;
251 : }
252 :
253 9312 : for(i = 0; i < blob.length; i++) {
254 9248 : datum->data[i] = blob.data[blob.length - i - 1];
255 : }
256 64 : datum->size = blob.length;
257 :
258 64 : return 0;
259 : }
260 :
261 8 : static NTSTATUS get_pk_from_raw_keypair_params(TALLOC_CTX *ctx,
262 : struct bkrp_exported_RSA_key_pair *keypair,
263 : gnutls_privkey_t *pk)
264 : {
265 8 : gnutls_x509_privkey_t x509_privkey = NULL;
266 8 : gnutls_privkey_t privkey = NULL;
267 : gnutls_datum_t m, e, d, p, q, u, e1, e2;
268 : int rc;
269 :
270 8 : rc = reverse_and_get_bignum(ctx, keypair->modulus, &m);
271 8 : if (rc != 0) {
272 0 : return NT_STATUS_INVALID_PARAMETER;
273 : }
274 8 : rc = reverse_and_get_bignum(ctx, keypair->public_exponent, &e);
275 8 : if (rc != 0) {
276 0 : return NT_STATUS_INVALID_PARAMETER;
277 : }
278 8 : rc = reverse_and_get_bignum(ctx, keypair->private_exponent, &d);
279 8 : if (rc != 0) {
280 0 : return NT_STATUS_INVALID_PARAMETER;
281 : }
282 :
283 8 : rc = reverse_and_get_bignum(ctx, keypair->prime1, &p);
284 8 : if (rc != 0) {
285 0 : return NT_STATUS_INVALID_PARAMETER;
286 : }
287 8 : rc = reverse_and_get_bignum(ctx, keypair->prime2, &q);
288 8 : if (rc != 0) {
289 0 : return NT_STATUS_INVALID_PARAMETER;
290 : }
291 :
292 8 : rc = reverse_and_get_bignum(ctx, keypair->coefficient, &u);
293 8 : if (rc != 0) {
294 0 : return NT_STATUS_INVALID_PARAMETER;
295 : }
296 :
297 8 : rc = reverse_and_get_bignum(ctx, keypair->exponent1, &e1);
298 8 : if (rc != 0) {
299 0 : return NT_STATUS_INVALID_PARAMETER;
300 : }
301 8 : rc = reverse_and_get_bignum(ctx, keypair->exponent2, &e2);
302 8 : if (rc != 0) {
303 0 : return NT_STATUS_INVALID_PARAMETER;
304 : }
305 :
306 8 : rc = gnutls_x509_privkey_init(&x509_privkey);
307 8 : if (rc != GNUTLS_E_SUCCESS) {
308 0 : DBG_ERR("gnutls_x509_privkey_init failed - %s\n",
309 : gnutls_strerror(rc));
310 0 : return NT_STATUS_INTERNAL_ERROR;
311 : }
312 :
313 8 : rc = gnutls_x509_privkey_import_rsa_raw2(x509_privkey,
314 : &m,
315 : &e,
316 : &d,
317 : &p,
318 : &q,
319 : &u,
320 : &e1,
321 : &e2);
322 8 : if (rc != GNUTLS_E_SUCCESS) {
323 0 : DBG_ERR("gnutls_x509_privkey_import_rsa_raw2 failed - %s\n",
324 : gnutls_strerror(rc));
325 0 : return NT_STATUS_INTERNAL_ERROR;
326 : }
327 :
328 8 : rc = gnutls_privkey_init(&privkey);
329 8 : if (rc != GNUTLS_E_SUCCESS) {
330 0 : DBG_ERR("gnutls_privkey_init failed - %s\n",
331 : gnutls_strerror(rc));
332 0 : gnutls_x509_privkey_deinit(x509_privkey);
333 0 : return NT_STATUS_INTERNAL_ERROR;
334 : }
335 :
336 8 : rc = gnutls_privkey_import_x509(privkey,
337 : x509_privkey,
338 : GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
339 8 : if (rc != GNUTLS_E_SUCCESS) {
340 0 : DBG_ERR("gnutls_privkey_import_x509 failed - %s\n",
341 : gnutls_strerror(rc));
342 0 : gnutls_x509_privkey_deinit(x509_privkey);
343 0 : return NT_STATUS_INTERNAL_ERROR;
344 : }
345 :
346 8 : *pk = privkey;
347 :
348 8 : return NT_STATUS_OK;
349 : }
350 :
351 6 : static WERROR get_and_verify_access_check(TALLOC_CTX *sub_ctx,
352 : uint32_t version,
353 : uint8_t *key_and_iv,
354 : uint8_t *access_check,
355 : uint32_t access_check_len,
356 : struct auth_session_info *session_info)
357 : {
358 : struct bkrp_access_check_v2 uncrypted_accesscheckv2;
359 : struct bkrp_access_check_v3 uncrypted_accesscheckv3;
360 6 : gnutls_cipher_hd_t cipher_handle = { 0 };
361 : gnutls_cipher_algorithm_t cipher_algo;
362 : DATA_BLOB blob_us;
363 : enum ndr_err_code ndr_err;
364 : gnutls_datum_t key;
365 : gnutls_datum_t iv;
366 :
367 6 : struct dom_sid *access_sid = NULL;
368 6 : struct dom_sid *caller_sid = NULL;
369 : int rc;
370 :
371 6 : switch (version) {
372 5 : case 2:
373 5 : cipher_algo = GNUTLS_CIPHER_3DES_CBC;
374 5 : break;
375 1 : case 3:
376 1 : cipher_algo = GNUTLS_CIPHER_AES_256_CBC;
377 1 : break;
378 0 : default:
379 0 : return WERR_INVALID_DATA;
380 : }
381 :
382 6 : key.data = key_and_iv;
383 6 : key.size = gnutls_cipher_get_key_size(cipher_algo);
384 :
385 6 : iv.data = key_and_iv + key.size;
386 6 : iv.size = gnutls_cipher_get_iv_size(cipher_algo);
387 :
388 : /* Allocate data structure for the plaintext */
389 6 : blob_us = data_blob_talloc_zero(sub_ctx, access_check_len);
390 6 : if (blob_us.data == NULL) {
391 0 : return WERR_INVALID_DATA;
392 : }
393 :
394 6 : rc = gnutls_cipher_init(&cipher_handle,
395 : cipher_algo,
396 : &key,
397 : &iv);
398 6 : if (rc < 0) {
399 0 : DBG_ERR("gnutls_cipher_init failed: %s\n",
400 : gnutls_strerror(rc));
401 0 : return WERR_INVALID_DATA;
402 : }
403 :
404 12 : rc = gnutls_cipher_decrypt2(cipher_handle,
405 : access_check,
406 : access_check_len,
407 6 : blob_us.data,
408 : blob_us.length);
409 6 : gnutls_cipher_deinit(cipher_handle);
410 6 : if (rc < 0) {
411 0 : DBG_ERR("gnutls_cipher_decrypt2 failed: %s\n",
412 : gnutls_strerror(rc));
413 0 : return WERR_INVALID_DATA;
414 : }
415 :
416 6 : switch (version) {
417 5 : case 2:
418 5 : {
419 5 : uint32_t hash_size = 20;
420 5 : uint8_t hash[hash_size];
421 : gnutls_hash_hd_t dig_ctx;
422 :
423 5 : ndr_err = ndr_pull_struct_blob(&blob_us, sub_ctx, &uncrypted_accesscheckv2,
424 : (ndr_pull_flags_fn_t)ndr_pull_bkrp_access_check_v2);
425 5 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
426 : /* Unable to unmarshall */
427 2 : return WERR_INVALID_DATA;
428 : }
429 5 : if (uncrypted_accesscheckv2.magic != 0x1) {
430 : /* wrong magic */
431 1 : return WERR_INVALID_DATA;
432 : }
433 :
434 4 : gnutls_hash_init(&dig_ctx, GNUTLS_DIG_SHA1);
435 8 : gnutls_hash(dig_ctx,
436 4 : blob_us.data,
437 4 : blob_us.length - hash_size);
438 4 : gnutls_hash_deinit(dig_ctx, hash);
439 : /*
440 : * We free it after the sha1 calculation because blob.data
441 : * point to the same area
442 : */
443 :
444 4 : if (!mem_equal_const_time(hash, uncrypted_accesscheckv2.hash, hash_size)) {
445 1 : DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
446 1 : return WERR_INVALID_DATA;
447 : }
448 3 : access_sid = &(uncrypted_accesscheckv2.sid);
449 6 : break;
450 : }
451 1 : case 3:
452 1 : {
453 1 : uint32_t hash_size = 64;
454 1 : uint8_t hash[hash_size];
455 : gnutls_hash_hd_t dig_ctx;
456 :
457 1 : ndr_err = ndr_pull_struct_blob(&blob_us, sub_ctx, &uncrypted_accesscheckv3,
458 : (ndr_pull_flags_fn_t)ndr_pull_bkrp_access_check_v3);
459 1 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
460 : /* Unable to unmarshall */
461 0 : return WERR_INVALID_DATA;
462 : }
463 1 : if (uncrypted_accesscheckv3.magic != 0x1) {
464 : /* wrong magic */
465 0 : return WERR_INVALID_DATA;
466 : }
467 :
468 1 : gnutls_hash_init(&dig_ctx, GNUTLS_DIG_SHA512);
469 2 : gnutls_hash(dig_ctx,
470 1 : blob_us.data,
471 1 : blob_us.length - hash_size);
472 1 : gnutls_hash_deinit(dig_ctx, hash);
473 :
474 : /*
475 : * We free it after the sha1 calculation because blob.data
476 : * point to the same area
477 : */
478 :
479 1 : if (!mem_equal_const_time(hash, uncrypted_accesscheckv3.hash, hash_size)) {
480 0 : DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
481 0 : return WERR_INVALID_DATA;
482 : }
483 1 : access_sid = &(uncrypted_accesscheckv3.sid);
484 2 : break;
485 : }
486 0 : default:
487 : /* Never reached normally as we filtered at the switch / case level */
488 0 : return WERR_INVALID_DATA;
489 : }
490 :
491 4 : caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
492 :
493 4 : if (!dom_sid_equal(caller_sid, access_sid)) {
494 1 : return WERR_INVALID_ACCESS;
495 : }
496 3 : return WERR_OK;
497 : }
498 :
499 : /*
500 : * We have some data, such as saved website or IMAP passwords that the
501 : * client has in profile on-disk. This needs to be decrypted. This
502 : * version gives the server the data over the network (protected by
503 : * the X.509 certificate and public key encryption, and asks that it
504 : * be decrypted returned for short-term use, protected only by the
505 : * negotiated transport encryption.
506 : *
507 : * The data is NOT stored in the LSA, but a X.509 certificate, public
508 : * and private keys used to encrypt the data will be stored. There is
509 : * only one active encryption key pair and certificate per domain, it
510 : * is pointed at with G$BCKUPKEY_PREFERRED in the LSA secrets store.
511 : *
512 : * The potentially multiple valid decrypting key pairs are in turn
513 : * stored in the LSA secrets store as G$BCKUPKEY_keyGuidString.
514 : *
515 : */
516 10 : static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
517 : TALLOC_CTX *mem_ctx,
518 : struct bkrp_BackupKey *r,
519 : struct ldb_context *ldb_ctx)
520 : {
521 10 : struct auth_session_info *session_info =
522 0 : dcesrv_call_session_info(dce_call);
523 : struct bkrp_client_side_wrapped uncrypt_request;
524 : DATA_BLOB blob;
525 : enum ndr_err_code ndr_err;
526 : char *guid_string;
527 : char *cert_secret_name;
528 : DATA_BLOB lsa_secret;
529 10 : DATA_BLOB *uncrypted_data = NULL;
530 : NTSTATUS status;
531 : uint32_t requested_version;
532 :
533 10 : blob.data = r->in.data_in;
534 10 : blob.length = r->in.data_in_len;
535 :
536 10 : if (r->in.data_in_len < 4 || r->in.data_in == NULL) {
537 0 : return WERR_INVALID_PARAMETER;
538 : }
539 :
540 : /*
541 : * We check for the version here, so we can actually print the
542 : * message as we are unlikely to parse it with NDR.
543 : */
544 10 : requested_version = IVAL(r->in.data_in, 0);
545 10 : if ((requested_version != BACKUPKEY_CLIENT_WRAP_VERSION2)
546 4 : && (requested_version != BACKUPKEY_CLIENT_WRAP_VERSION3)) {
547 1 : DEBUG(1, ("Request for unknown BackupKey sub-protocol %d\n", requested_version));
548 1 : return WERR_INVALID_PARAMETER;
549 : }
550 :
551 9 : ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &uncrypt_request,
552 : (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_wrapped);
553 9 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
554 0 : return WERR_INVALID_PARAMETER;
555 : }
556 :
557 9 : if ((uncrypt_request.version != BACKUPKEY_CLIENT_WRAP_VERSION2)
558 3 : && (uncrypt_request.version != BACKUPKEY_CLIENT_WRAP_VERSION3)) {
559 0 : DEBUG(1, ("Request for unknown BackupKey sub-protocol %d\n", uncrypt_request.version));
560 0 : return WERR_INVALID_PARAMETER;
561 : }
562 :
563 9 : guid_string = GUID_string(mem_ctx, &uncrypt_request.guid);
564 9 : if (guid_string == NULL) {
565 0 : return WERR_NOT_ENOUGH_MEMORY;
566 : }
567 :
568 9 : cert_secret_name = talloc_asprintf(mem_ctx,
569 : "BCKUPKEY_%s",
570 : guid_string);
571 9 : if (cert_secret_name == NULL) {
572 0 : return WERR_NOT_ENOUGH_MEMORY;
573 : }
574 :
575 9 : status = get_lsa_secret(mem_ctx,
576 : ldb_ctx,
577 : cert_secret_name,
578 : &lsa_secret);
579 9 : if (!NT_STATUS_IS_OK(status)) {
580 1 : DEBUG(10, ("Error while fetching secret %s\n", cert_secret_name));
581 1 : return WERR_INVALID_DATA;
582 8 : } else if (lsa_secret.length == 0) {
583 : /* we do not have the real secret attribute, like if we are an RODC */
584 0 : return WERR_INVALID_PARAMETER;
585 : } else {
586 : struct bkrp_exported_RSA_key_pair keypair;
587 8 : gnutls_privkey_t privkey = NULL;
588 : gnutls_datum_t reversed_secret;
589 : gnutls_datum_t uncrypted_secret;
590 : uint32_t i;
591 : DATA_BLOB blob_us;
592 : WERROR werr;
593 : int rc;
594 :
595 8 : ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, &keypair, (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair);
596 8 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
597 0 : DEBUG(2, ("Unable to parse the ndr encoded cert in key %s\n", cert_secret_name));
598 5 : return WERR_FILE_NOT_FOUND;
599 : }
600 :
601 8 : status = get_pk_from_raw_keypair_params(mem_ctx,
602 : &keypair,
603 : &privkey);
604 8 : if (!NT_STATUS_IS_OK(status)) {
605 0 : return WERR_INTERNAL_ERROR;
606 : }
607 :
608 8 : reversed_secret.data = talloc_array(mem_ctx, uint8_t,
609 : uncrypt_request.encrypted_secret_len);
610 8 : if (reversed_secret.data == NULL) {
611 0 : gnutls_privkey_deinit(privkey);
612 0 : return WERR_NOT_ENOUGH_MEMORY;
613 : }
614 :
615 : /* The secret has to be reversed ... */
616 2056 : for(i=0; i< uncrypt_request.encrypted_secret_len; i++) {
617 2048 : uint8_t *reversed = (uint8_t *)reversed_secret.data;
618 2048 : uint8_t *uncrypt = uncrypt_request.encrypted_secret;
619 2048 : reversed[i] = uncrypt[uncrypt_request.encrypted_secret_len - 1 - i];
620 : }
621 8 : reversed_secret.size = uncrypt_request.encrypted_secret_len;
622 :
623 : /*
624 : * Let's try to decrypt the secret now that
625 : * we have the private key ...
626 : */
627 8 : rc = gnutls_privkey_decrypt_data(privkey,
628 : 0,
629 : &reversed_secret,
630 : &uncrypted_secret);
631 8 : gnutls_privkey_deinit(privkey);
632 8 : if (rc != GNUTLS_E_SUCCESS) {
633 : /* We are not able to decrypt the secret, looks like something is wrong */
634 1 : return WERR_INVALID_PARAMETER;
635 : }
636 7 : blob_us.data = uncrypted_secret.data;
637 7 : blob_us.length = uncrypted_secret.size;
638 :
639 7 : if (uncrypt_request.version == 2) {
640 : struct bkrp_encrypted_secret_v2 uncrypted_secretv2;
641 :
642 5 : ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv2,
643 : (ndr_pull_flags_fn_t)ndr_pull_bkrp_encrypted_secret_v2);
644 5 : gnutls_free(uncrypted_secret.data);
645 5 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
646 : /* Unable to unmarshall */
647 3 : return WERR_INVALID_DATA;
648 : }
649 5 : if (uncrypted_secretv2.magic != 0x20) {
650 : /* wrong magic */
651 0 : return WERR_INVALID_DATA;
652 : }
653 :
654 5 : werr = get_and_verify_access_check(mem_ctx, 2,
655 : uncrypted_secretv2.payload_key,
656 : uncrypt_request.access_check,
657 : uncrypt_request.access_check_len,
658 : session_info);
659 5 : if (!W_ERROR_IS_OK(werr)) {
660 3 : return werr;
661 : }
662 2 : uncrypted_data = talloc(mem_ctx, DATA_BLOB);
663 2 : if (uncrypted_data == NULL) {
664 0 : return WERR_INVALID_DATA;
665 : }
666 :
667 2 : uncrypted_data->data = uncrypted_secretv2.secret;
668 2 : uncrypted_data->length = uncrypted_secretv2.secret_len;
669 : }
670 4 : if (uncrypt_request.version == 3) {
671 : struct bkrp_encrypted_secret_v3 uncrypted_secretv3;
672 :
673 2 : ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv3,
674 : (ndr_pull_flags_fn_t)ndr_pull_bkrp_encrypted_secret_v3);
675 2 : gnutls_free(uncrypted_secret.data);
676 2 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
677 : /* Unable to unmarshall */
678 1 : return WERR_INVALID_DATA;
679 : }
680 :
681 3 : if (uncrypted_secretv3.magic1 != 0x30 ||
682 2 : uncrypted_secretv3.magic2 != 0x6610 ||
683 1 : uncrypted_secretv3.magic3 != 0x800e) {
684 : /* wrong magic */
685 1 : return WERR_INVALID_DATA;
686 : }
687 :
688 : /*
689 : * Confirm that the caller is permitted to
690 : * read this particular data. Because one key
691 : * pair is used per domain, the caller could
692 : * have stolen the profile data on-disk and
693 : * would otherwise be able to read the
694 : * passwords.
695 : */
696 :
697 1 : werr = get_and_verify_access_check(mem_ctx, 3,
698 : uncrypted_secretv3.payload_key,
699 : uncrypt_request.access_check,
700 : uncrypt_request.access_check_len,
701 : session_info);
702 1 : if (!W_ERROR_IS_OK(werr)) {
703 0 : return werr;
704 : }
705 :
706 1 : uncrypted_data = talloc(mem_ctx, DATA_BLOB);
707 1 : if (uncrypted_data == NULL) {
708 0 : return WERR_INVALID_DATA;
709 : }
710 :
711 1 : uncrypted_data->data = uncrypted_secretv3.secret;
712 1 : uncrypted_data->length = uncrypted_secretv3.secret_len;
713 : }
714 :
715 : /*
716 : * Yeah if we are here all looks pretty good:
717 : * - hash is ok
718 : * - user sid is the same as the one in access check
719 : * - we were able to decrypt the whole stuff
720 : */
721 : }
722 :
723 3 : if (uncrypted_data->data == NULL) {
724 0 : return WERR_INVALID_DATA;
725 : }
726 :
727 : /* There is a magic value a the beginning of the data
728 : * we can use an adhoc structure but as the
729 : * parent structure is just an array of bytes it a lot of work
730 : * work just prepending 4 bytes
731 : */
732 3 : *(r->out.data_out) = talloc_zero_array(mem_ctx, uint8_t, uncrypted_data->length + 4);
733 3 : W_ERROR_HAVE_NO_MEMORY(*(r->out.data_out));
734 3 : memcpy(4+*(r->out.data_out), uncrypted_data->data, uncrypted_data->length);
735 3 : *(r->out.data_out_len) = uncrypted_data->length + 4;
736 :
737 3 : return WERR_OK;
738 : }
739 :
740 8 : static DATA_BLOB *reverse_and_get_blob(TALLOC_CTX *mem_ctx,
741 : gnutls_datum_t *datum)
742 : {
743 : DATA_BLOB *blob;
744 : size_t i;
745 :
746 8 : blob = talloc(mem_ctx, DATA_BLOB);
747 8 : if (blob == NULL) {
748 0 : return NULL;
749 : }
750 :
751 8 : blob->length = datum->size;
752 8 : if (datum->data[0] == '\0') {
753 : /* The datum has a leading byte zero, skip it */
754 4 : blob->length = datum->size - 1;
755 : }
756 8 : blob->data = talloc_zero_array(mem_ctx, uint8_t, blob->length);
757 8 : if (blob->data == NULL) {
758 0 : talloc_free(blob);
759 0 : return NULL;
760 : }
761 :
762 1163 : for (i = 0; i < blob->length; i++) {
763 1155 : blob->data[i] = datum->data[datum->size - i - 1];
764 : }
765 :
766 8 : return blob;
767 : }
768 :
769 1 : static WERROR create_privkey_rsa(gnutls_privkey_t *pk)
770 : {
771 1 : int bits = 2048;
772 1 : gnutls_x509_privkey_t x509_privkey = NULL;
773 1 : gnutls_privkey_t privkey = NULL;
774 : int rc;
775 :
776 1 : rc = gnutls_x509_privkey_init(&x509_privkey);
777 1 : if (rc != GNUTLS_E_SUCCESS) {
778 0 : DBG_ERR("gnutls_x509_privkey_init failed - %s\n",
779 : gnutls_strerror(rc));
780 0 : return WERR_INTERNAL_ERROR;
781 : }
782 :
783 1 : rc = gnutls_x509_privkey_generate(x509_privkey,
784 : GNUTLS_PK_RSA,
785 : bits,
786 : 0);
787 1 : if (rc != GNUTLS_E_SUCCESS) {
788 0 : DBG_ERR("gnutls_x509_privkey_generate failed - %s\n",
789 : gnutls_strerror(rc));
790 0 : gnutls_x509_privkey_deinit(x509_privkey);
791 0 : return WERR_INTERNAL_ERROR;
792 : }
793 :
794 1 : rc = gnutls_privkey_init(&privkey);
795 1 : if (rc != GNUTLS_E_SUCCESS) {
796 0 : DBG_ERR("gnutls_privkey_init failed - %s\n",
797 : gnutls_strerror(rc));
798 0 : gnutls_x509_privkey_deinit(x509_privkey);
799 0 : return WERR_INTERNAL_ERROR;
800 : }
801 :
802 1 : rc = gnutls_privkey_import_x509(privkey,
803 : x509_privkey,
804 : GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
805 1 : if (rc != GNUTLS_E_SUCCESS) {
806 0 : DBG_ERR("gnutls_privkey_import_x509 failed - %s\n",
807 : gnutls_strerror(rc));
808 0 : gnutls_x509_privkey_deinit(x509_privkey);
809 0 : return WERR_INTERNAL_ERROR;
810 : }
811 :
812 1 : *pk = privkey;
813 :
814 1 : return WERR_OK;
815 : }
816 :
817 1 : static WERROR self_sign_cert(TALLOC_CTX *mem_ctx,
818 : time_t lifetime,
819 : const char *dn,
820 : gnutls_privkey_t issuer_privkey,
821 : gnutls_x509_crt_t *certificate,
822 : DATA_BLOB *guidblob)
823 : {
824 : gnutls_datum_t unique_id;
825 : gnutls_datum_t serial_number;
826 : gnutls_x509_crt_t issuer_cert;
827 : gnutls_x509_privkey_t x509_issuer_privkey;
828 1 : time_t activation = time(NULL);
829 1 : time_t expiry = activation + lifetime;
830 : const char *error_string;
831 : uint8_t *reversed;
832 : size_t i;
833 : int rc;
834 :
835 1 : unique_id.size = guidblob->length;
836 1 : unique_id.data = talloc_memdup(mem_ctx,
837 : guidblob->data,
838 : guidblob->length);
839 1 : if (unique_id.data == NULL) {
840 0 : return WERR_NOT_ENOUGH_MEMORY;
841 : }
842 :
843 1 : reversed = talloc_array(mem_ctx, uint8_t, guidblob->length);
844 1 : if (reversed == NULL) {
845 0 : talloc_free(unique_id.data);
846 0 : return WERR_NOT_ENOUGH_MEMORY;
847 : }
848 :
849 : /* Native AD generates certificates with serialnumber in reversed notation */
850 17 : for (i = 0; i < guidblob->length; i++) {
851 16 : uint8_t *uncrypt = guidblob->data;
852 16 : reversed[i] = uncrypt[guidblob->length - i - 1];
853 : }
854 1 : serial_number.size = guidblob->length;
855 1 : serial_number.data = reversed;
856 :
857 : /* Create certificate to sign */
858 1 : rc = gnutls_x509_crt_init(&issuer_cert);
859 1 : if (rc != GNUTLS_E_SUCCESS) {
860 0 : DBG_ERR("gnutls_x509_crt_init failed - %s\n",
861 : gnutls_strerror(rc));
862 0 : return WERR_NOT_ENOUGH_MEMORY;
863 : }
864 :
865 1 : rc = gnutls_x509_crt_set_dn(issuer_cert, dn, &error_string);
866 1 : if (rc != GNUTLS_E_SUCCESS) {
867 0 : DBG_ERR("gnutls_x509_crt_set_dn failed - %s (%s)\n",
868 : gnutls_strerror(rc),
869 : error_string);
870 0 : gnutls_x509_crt_deinit(issuer_cert);
871 0 : return WERR_INVALID_PARAMETER;
872 : }
873 :
874 1 : rc = gnutls_x509_crt_set_issuer_dn(issuer_cert, dn, &error_string);
875 1 : if (rc != GNUTLS_E_SUCCESS) {
876 0 : DBG_ERR("gnutls_x509_crt_set_issuer_dn failed - %s (%s)\n",
877 : gnutls_strerror(rc),
878 : error_string);
879 0 : gnutls_x509_crt_deinit(issuer_cert);
880 0 : return WERR_INVALID_PARAMETER;
881 : }
882 :
883 : /* Get x509 privkey for subjectPublicKeyInfo */
884 1 : rc = gnutls_x509_privkey_init(&x509_issuer_privkey);
885 1 : if (rc != GNUTLS_E_SUCCESS) {
886 0 : DBG_ERR("gnutls_x509_privkey_init failed - %s\n",
887 : gnutls_strerror(rc));
888 0 : gnutls_x509_crt_deinit(issuer_cert);
889 0 : return WERR_INVALID_PARAMETER;
890 : }
891 :
892 1 : rc = gnutls_privkey_export_x509(issuer_privkey,
893 : &x509_issuer_privkey);
894 1 : if (rc != GNUTLS_E_SUCCESS) {
895 0 : DBG_ERR("gnutls_x509_privkey_init failed - %s\n",
896 : gnutls_strerror(rc));
897 0 : gnutls_x509_privkey_deinit(x509_issuer_privkey);
898 0 : gnutls_x509_crt_deinit(issuer_cert);
899 0 : return WERR_INVALID_PARAMETER;
900 : }
901 :
902 : /* Set subjectPublicKeyInfo */
903 1 : rc = gnutls_x509_crt_set_key(issuer_cert, x509_issuer_privkey);
904 1 : gnutls_x509_privkey_deinit(x509_issuer_privkey);
905 1 : if (rc != GNUTLS_E_SUCCESS) {
906 0 : DBG_ERR("gnutls_x509_crt_set_pubkey failed - %s\n",
907 : gnutls_strerror(rc));
908 0 : gnutls_x509_crt_deinit(issuer_cert);
909 0 : return WERR_INVALID_PARAMETER;
910 : }
911 :
912 1 : rc = gnutls_x509_crt_set_activation_time(issuer_cert, activation);
913 1 : if (rc != GNUTLS_E_SUCCESS) {
914 0 : DBG_ERR("gnutls_x509_crt_set_activation_time failed - %s\n",
915 : gnutls_strerror(rc));
916 0 : gnutls_x509_crt_deinit(issuer_cert);
917 0 : return WERR_INVALID_PARAMETER;
918 : }
919 :
920 1 : rc = gnutls_x509_crt_set_expiration_time(issuer_cert, expiry);
921 1 : if (rc != GNUTLS_E_SUCCESS) {
922 0 : DBG_ERR("gnutls_x509_crt_set_expiration_time failed - %s\n",
923 : gnutls_strerror(rc));
924 0 : gnutls_x509_crt_deinit(issuer_cert);
925 0 : return WERR_INVALID_PARAMETER;
926 : }
927 :
928 1 : rc = gnutls_x509_crt_set_version(issuer_cert, 3);
929 1 : if (rc != GNUTLS_E_SUCCESS) {
930 0 : DBG_ERR("gnutls_x509_crt_set_version failed - %s\n",
931 : gnutls_strerror(rc));
932 0 : gnutls_x509_crt_deinit(issuer_cert);
933 0 : return WERR_INVALID_PARAMETER;
934 : }
935 :
936 2 : rc = gnutls_x509_crt_set_subject_unique_id(issuer_cert,
937 1 : unique_id.data,
938 1 : unique_id.size);
939 1 : if (rc != GNUTLS_E_SUCCESS) {
940 0 : DBG_ERR("gnutls_x509_crt_set_subject_key_id failed - %s\n",
941 : gnutls_strerror(rc));
942 0 : gnutls_x509_crt_deinit(issuer_cert);
943 0 : return WERR_INVALID_PARAMETER;
944 : }
945 :
946 2 : rc = gnutls_x509_crt_set_issuer_unique_id(issuer_cert,
947 1 : unique_id.data,
948 1 : unique_id.size);
949 1 : if (rc != GNUTLS_E_SUCCESS) {
950 0 : DBG_ERR("gnutls_x509_crt_set_issuer_unique_id failed - %s\n",
951 : gnutls_strerror(rc));
952 0 : gnutls_x509_crt_deinit(issuer_cert);
953 0 : return WERR_INVALID_PARAMETER;
954 : }
955 :
956 2 : rc = gnutls_x509_crt_set_serial(issuer_cert,
957 1 : serial_number.data,
958 1 : serial_number.size);
959 1 : if (rc != GNUTLS_E_SUCCESS) {
960 0 : DBG_ERR("gnutls_x509_crt_set_serial failed - %s\n",
961 : gnutls_strerror(rc));
962 0 : gnutls_x509_crt_deinit(issuer_cert);
963 0 : return WERR_INVALID_PARAMETER;
964 : }
965 :
966 1 : rc = gnutls_x509_crt_privkey_sign(issuer_cert,
967 : issuer_cert,
968 : issuer_privkey,
969 : GNUTLS_DIG_SHA1,
970 : 0);
971 1 : if (rc != GNUTLS_E_SUCCESS) {
972 0 : DBG_ERR("gnutls_x509_crt_privkey_sign failed - %s\n",
973 : gnutls_strerror(rc));
974 0 : return WERR_INVALID_PARAMETER;
975 : }
976 :
977 1 : *certificate = issuer_cert;
978 :
979 1 : return WERR_OK;
980 : }
981 :
982 : /* Return an error when we fail to generate a certificate */
983 1 : static WERROR generate_bkrp_cert(TALLOC_CTX *mem_ctx,
984 : struct dcesrv_call_state *dce_call,
985 : struct ldb_context *ldb_ctx,
986 : const char *dn)
987 : {
988 : WERROR werr;
989 1 : gnutls_privkey_t issuer_privkey = NULL;
990 1 : gnutls_x509_crt_t cert = NULL;
991 : gnutls_datum_t cert_blob;
992 : gnutls_datum_t m, e, d, p, q, u, e1, e2;
993 : DATA_BLOB blob;
994 : DATA_BLOB blobkeypair;
995 : DATA_BLOB *tmp;
996 1 : bool ok = true;
997 1 : struct GUID guid = GUID_random();
998 : NTSTATUS status;
999 : char *secret_name;
1000 : struct bkrp_exported_RSA_key_pair keypair;
1001 : enum ndr_err_code ndr_err;
1002 1 : time_t nb_seconds_validity = 3600 * 24 * 365;
1003 : int rc;
1004 :
1005 1 : DEBUG(6, ("Trying to generate a certificate\n"));
1006 1 : werr = create_privkey_rsa(&issuer_privkey);
1007 1 : if (!W_ERROR_IS_OK(werr)) {
1008 0 : return werr;
1009 : }
1010 :
1011 1 : status = GUID_to_ndr_blob(&guid, mem_ctx, &blob);
1012 1 : if (!NT_STATUS_IS_OK(status)) {
1013 0 : gnutls_privkey_deinit(issuer_privkey);
1014 0 : return WERR_INVALID_DATA;
1015 : }
1016 :
1017 1 : werr = self_sign_cert(mem_ctx,
1018 : nb_seconds_validity,
1019 : dn,
1020 : issuer_privkey,
1021 : &cert,
1022 : &blob);
1023 1 : if (!W_ERROR_IS_OK(werr)) {
1024 0 : gnutls_privkey_deinit(issuer_privkey);
1025 0 : return WERR_INVALID_DATA;
1026 : }
1027 :
1028 1 : rc = gnutls_x509_crt_export2(cert, GNUTLS_X509_FMT_DER, &cert_blob);
1029 1 : if (rc != GNUTLS_E_SUCCESS) {
1030 0 : DBG_ERR("gnutls_x509_crt_export2 failed - %s\n",
1031 : gnutls_strerror(rc));
1032 0 : gnutls_privkey_deinit(issuer_privkey);
1033 0 : gnutls_x509_crt_deinit(cert);
1034 0 : return WERR_INVALID_DATA;
1035 : }
1036 :
1037 1 : keypair.cert.length = cert_blob.size;
1038 1 : keypair.cert.data = talloc_memdup(mem_ctx, cert_blob.data, cert_blob.size);
1039 1 : gnutls_x509_crt_deinit(cert);
1040 1 : gnutls_free(cert_blob.data);
1041 1 : if (keypair.cert.data == NULL) {
1042 0 : gnutls_privkey_deinit(issuer_privkey);
1043 0 : return WERR_NOT_ENOUGH_MEMORY;
1044 : }
1045 :
1046 1 : rc = gnutls_privkey_export_rsa_raw(issuer_privkey,
1047 : &m,
1048 : &e,
1049 : &d,
1050 : &p,
1051 : &q,
1052 : &u,
1053 : &e1,
1054 : &e2);
1055 1 : if (rc != GNUTLS_E_SUCCESS) {
1056 0 : gnutls_privkey_deinit(issuer_privkey);
1057 0 : return WERR_INVALID_DATA;
1058 : }
1059 :
1060 : /*
1061 : * Heimdal's bignum are big endian and the
1062 : * structure expect it to be in little endian
1063 : * so we reverse the buffer to make it work
1064 : */
1065 1 : tmp = reverse_and_get_blob(mem_ctx, &e);
1066 1 : if (tmp == NULL) {
1067 0 : ok = false;
1068 : } else {
1069 1 : SMB_ASSERT(tmp->length <= 4);
1070 1 : keypair.public_exponent = *tmp;
1071 : }
1072 :
1073 1 : tmp = reverse_and_get_blob(mem_ctx, &d);
1074 1 : if (tmp == NULL) {
1075 0 : ok = false;
1076 : } else {
1077 1 : keypair.private_exponent = *tmp;
1078 : }
1079 :
1080 1 : tmp = reverse_and_get_blob(mem_ctx, &m);
1081 1 : if (tmp == NULL) {
1082 0 : ok = false;
1083 : } else {
1084 1 : keypair.modulus = *tmp;
1085 : }
1086 :
1087 1 : tmp = reverse_and_get_blob(mem_ctx, &p);
1088 1 : if (tmp == NULL) {
1089 0 : ok = false;
1090 : } else {
1091 1 : keypair.prime1 = *tmp;
1092 : }
1093 :
1094 1 : tmp = reverse_and_get_blob(mem_ctx, &q);
1095 1 : if (tmp == NULL) {
1096 0 : ok = false;
1097 : } else {
1098 1 : keypair.prime2 = *tmp;
1099 : }
1100 :
1101 1 : tmp = reverse_and_get_blob(mem_ctx, &e1);
1102 1 : if (tmp == NULL) {
1103 0 : ok = false;
1104 : } else {
1105 1 : keypair.exponent1 = *tmp;
1106 : }
1107 :
1108 1 : tmp = reverse_and_get_blob(mem_ctx, &e2);
1109 1 : if (tmp == NULL) {
1110 0 : ok = false;
1111 : } else {
1112 1 : keypair.exponent2 = *tmp;
1113 : }
1114 :
1115 1 : tmp = reverse_and_get_blob(mem_ctx, &u);
1116 1 : if (tmp == NULL) {
1117 0 : ok = false;
1118 : } else {
1119 1 : keypair.coefficient = *tmp;
1120 : }
1121 :
1122 : /* One of the keypair allocation was wrong */
1123 1 : if (ok == false) {
1124 0 : gnutls_privkey_deinit(issuer_privkey);
1125 0 : return WERR_INVALID_DATA;
1126 : }
1127 :
1128 1 : keypair.certificate_len = keypair.cert.length;
1129 1 : ndr_err = ndr_push_struct_blob(&blobkeypair,
1130 : mem_ctx,
1131 : &keypair,
1132 : (ndr_push_flags_fn_t)ndr_push_bkrp_exported_RSA_key_pair);
1133 1 : gnutls_privkey_deinit(issuer_privkey);
1134 1 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1135 0 : return WERR_INVALID_DATA;
1136 : }
1137 :
1138 1 : secret_name = talloc_asprintf(mem_ctx, "BCKUPKEY_%s", GUID_string(mem_ctx, &guid));
1139 1 : if (secret_name == NULL) {
1140 0 : return WERR_OUTOFMEMORY;
1141 : }
1142 :
1143 1 : status = set_lsa_secret(mem_ctx, ldb_ctx, secret_name, &blobkeypair);
1144 1 : if (!NT_STATUS_IS_OK(status)) {
1145 0 : DEBUG(2, ("Failed to save the secret %s\n", secret_name));
1146 : }
1147 1 : talloc_free(secret_name);
1148 :
1149 1 : GUID_to_ndr_blob(&guid, mem_ctx, &blob);
1150 1 : status = set_lsa_secret(mem_ctx, ldb_ctx, "BCKUPKEY_PREFERRED", &blob);
1151 1 : if (!NT_STATUS_IS_OK(status)) {
1152 0 : DEBUG(2, ("Failed to save the secret BCKUPKEY_PREFERRED\n"));
1153 : }
1154 :
1155 1 : return WERR_OK;
1156 : }
1157 :
1158 13 : static WERROR bkrp_retrieve_client_wrap_key(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1159 : struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx)
1160 : {
1161 : struct GUID guid;
1162 : char *guid_string;
1163 : DATA_BLOB lsa_secret;
1164 : enum ndr_err_code ndr_err;
1165 : NTSTATUS status;
1166 :
1167 : /*
1168 : * here we basicaly need to return our certificate
1169 : * search for lsa secret BCKUPKEY_PREFERRED first
1170 : */
1171 :
1172 13 : status = get_lsa_secret(mem_ctx,
1173 : ldb_ctx,
1174 : "BCKUPKEY_PREFERRED",
1175 : &lsa_secret);
1176 13 : if (NT_STATUS_EQUAL(status, NT_STATUS_RESOURCE_NAME_NOT_FOUND)) {
1177 : /* Ok we can be in this case if there was no certs */
1178 1 : struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
1179 1 : char *dn = talloc_asprintf(mem_ctx, "CN=%s",
1180 : lpcfg_realm(lp_ctx));
1181 :
1182 1 : WERROR werr = generate_bkrp_cert(mem_ctx, dce_call, ldb_ctx, dn);
1183 1 : if (!W_ERROR_IS_OK(werr)) {
1184 0 : return WERR_INVALID_PARAMETER;
1185 : }
1186 1 : status = get_lsa_secret(mem_ctx,
1187 : ldb_ctx,
1188 : "BCKUPKEY_PREFERRED",
1189 : &lsa_secret);
1190 :
1191 1 : if (!NT_STATUS_IS_OK(status)) {
1192 : /* Ok we really don't manage to get this certs ...*/
1193 0 : DEBUG(2, ("Unable to locate BCKUPKEY_PREFERRED after cert generation\n"));
1194 0 : return WERR_FILE_NOT_FOUND;
1195 : }
1196 12 : } else if (!NT_STATUS_IS_OK(status)) {
1197 0 : return WERR_INTERNAL_ERROR;
1198 : }
1199 :
1200 13 : if (lsa_secret.length == 0) {
1201 0 : DEBUG(1, ("No secret in BCKUPKEY_PREFERRED, are we an undetected RODC?\n"));
1202 0 : return WERR_INTERNAL_ERROR;
1203 : } else {
1204 : char *cert_secret_name;
1205 :
1206 13 : status = GUID_from_ndr_blob(&lsa_secret, &guid);
1207 13 : if (!NT_STATUS_IS_OK(status)) {
1208 0 : return WERR_FILE_NOT_FOUND;
1209 : }
1210 :
1211 13 : guid_string = GUID_string(mem_ctx, &guid);
1212 13 : if (guid_string == NULL) {
1213 : /* We return file not found because the client
1214 : * expect this error
1215 : */
1216 0 : return WERR_FILE_NOT_FOUND;
1217 : }
1218 :
1219 13 : cert_secret_name = talloc_asprintf(mem_ctx,
1220 : "BCKUPKEY_%s",
1221 : guid_string);
1222 13 : status = get_lsa_secret(mem_ctx,
1223 : ldb_ctx,
1224 : cert_secret_name,
1225 : &lsa_secret);
1226 13 : if (!NT_STATUS_IS_OK(status)) {
1227 0 : return WERR_FILE_NOT_FOUND;
1228 : }
1229 :
1230 13 : if (lsa_secret.length != 0) {
1231 : struct bkrp_exported_RSA_key_pair keypair;
1232 13 : ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, &keypair,
1233 : (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair);
1234 13 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1235 0 : return WERR_FILE_NOT_FOUND;
1236 : }
1237 13 : *(r->out.data_out_len) = keypair.cert.length;
1238 13 : *(r->out.data_out) = talloc_memdup(mem_ctx, keypair.cert.data, keypair.cert.length);
1239 13 : W_ERROR_HAVE_NO_MEMORY(*(r->out.data_out));
1240 13 : return WERR_OK;
1241 : } else {
1242 0 : DEBUG(1, ("No or broken secret called %s\n", cert_secret_name));
1243 0 : return WERR_INTERNAL_ERROR;
1244 : }
1245 : }
1246 :
1247 : return WERR_NOT_SUPPORTED;
1248 : }
1249 :
1250 1 : static WERROR generate_bkrp_server_wrap_key(TALLOC_CTX *ctx, struct ldb_context *ldb_ctx)
1251 : {
1252 1 : struct GUID guid = GUID_random();
1253 : enum ndr_err_code ndr_err;
1254 : DATA_BLOB blob_wrap_key, guid_blob;
1255 : struct bkrp_dc_serverwrap_key wrap_key;
1256 : NTSTATUS status;
1257 : char *secret_name;
1258 1 : TALLOC_CTX *frame = talloc_stackframe();
1259 :
1260 1 : generate_random_buffer(wrap_key.key, sizeof(wrap_key.key));
1261 :
1262 1 : ndr_err = ndr_push_struct_blob(&blob_wrap_key, ctx, &wrap_key, (ndr_push_flags_fn_t)ndr_push_bkrp_dc_serverwrap_key);
1263 1 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1264 0 : TALLOC_FREE(frame);
1265 0 : return WERR_INVALID_DATA;
1266 : }
1267 :
1268 1 : secret_name = talloc_asprintf(frame, "BCKUPKEY_%s", GUID_string(ctx, &guid));
1269 1 : if (secret_name == NULL) {
1270 0 : TALLOC_FREE(frame);
1271 0 : return WERR_NOT_ENOUGH_MEMORY;
1272 : }
1273 :
1274 1 : status = set_lsa_secret(frame, ldb_ctx, secret_name, &blob_wrap_key);
1275 1 : if (!NT_STATUS_IS_OK(status)) {
1276 0 : DEBUG(2, ("Failed to save the secret %s\n", secret_name));
1277 0 : TALLOC_FREE(frame);
1278 0 : return WERR_INTERNAL_ERROR;
1279 : }
1280 :
1281 1 : status = GUID_to_ndr_blob(&guid, frame, &guid_blob);
1282 1 : if (!NT_STATUS_IS_OK(status)) {
1283 0 : DEBUG(2, ("Failed to save the secret %s\n", secret_name));
1284 0 : TALLOC_FREE(frame);
1285 : }
1286 :
1287 1 : status = set_lsa_secret(frame, ldb_ctx, "BCKUPKEY_P", &guid_blob);
1288 1 : if (!NT_STATUS_IS_OK(status)) {
1289 0 : DEBUG(2, ("Failed to save the secret %s\n", secret_name));
1290 0 : TALLOC_FREE(frame);
1291 0 : return WERR_INTERNAL_ERROR;
1292 : }
1293 :
1294 1 : TALLOC_FREE(frame);
1295 :
1296 1 : return WERR_OK;
1297 : }
1298 :
1299 : /*
1300 : * Find the specified decryption keys from the LSA secrets store as
1301 : * G$BCKUPKEY_keyGuidString.
1302 : */
1303 :
1304 31 : static WERROR bkrp_do_retrieve_server_wrap_key(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx,
1305 : struct bkrp_dc_serverwrap_key *server_key,
1306 : struct GUID *guid)
1307 : {
1308 : NTSTATUS status;
1309 : DATA_BLOB lsa_secret;
1310 : char *secret_name;
1311 : char *guid_string;
1312 : enum ndr_err_code ndr_err;
1313 :
1314 31 : guid_string = GUID_string(mem_ctx, guid);
1315 31 : if (guid_string == NULL) {
1316 : /* We return file not found because the client
1317 : * expect this error
1318 : */
1319 0 : return WERR_FILE_NOT_FOUND;
1320 : }
1321 :
1322 31 : secret_name = talloc_asprintf(mem_ctx, "BCKUPKEY_%s", guid_string);
1323 31 : if (secret_name == NULL) {
1324 0 : return WERR_NOT_ENOUGH_MEMORY;
1325 : }
1326 :
1327 31 : status = get_lsa_secret(mem_ctx, ldb_ctx, secret_name, &lsa_secret);
1328 31 : if (!NT_STATUS_IS_OK(status)) {
1329 2 : DEBUG(10, ("Error while fetching secret %s\n", secret_name));
1330 2 : return WERR_INVALID_DATA;
1331 : }
1332 29 : if (lsa_secret.length == 0) {
1333 : /* RODC case, we do not have secrets locally */
1334 0 : DEBUG(1, ("Unable to fetch value for secret %s, are we an undetected RODC?\n",
1335 : secret_name));
1336 0 : return WERR_INTERNAL_ERROR;
1337 : }
1338 29 : ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, server_key,
1339 : (ndr_pull_flags_fn_t)ndr_pull_bkrp_dc_serverwrap_key);
1340 29 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1341 0 : DEBUG(2, ("Unable to parse the ndr encoded server wrap key %s\n", secret_name));
1342 0 : return WERR_INVALID_DATA;
1343 : }
1344 :
1345 29 : return WERR_OK;
1346 : }
1347 :
1348 : /*
1349 : * Find the current, preferred ServerWrap Key by looking at
1350 : * G$BCKUPKEY_P in the LSA secrets store.
1351 : *
1352 : * Then find the current decryption keys from the LSA secrets store as
1353 : * G$BCKUPKEY_keyGuidString.
1354 : */
1355 :
1356 14 : static WERROR bkrp_do_retrieve_default_server_wrap_key(TALLOC_CTX *mem_ctx,
1357 : struct ldb_context *ldb_ctx,
1358 : struct bkrp_dc_serverwrap_key *server_key,
1359 : struct GUID *returned_guid)
1360 : {
1361 : NTSTATUS status;
1362 : DATA_BLOB guid_binary;
1363 :
1364 14 : status = get_lsa_secret(mem_ctx, ldb_ctx, "BCKUPKEY_P", &guid_binary);
1365 14 : if (!NT_STATUS_IS_OK(status)) {
1366 1 : DEBUG(10, ("Error while fetching secret BCKUPKEY_P to find current GUID\n"));
1367 1 : return WERR_FILE_NOT_FOUND;
1368 13 : } else if (guid_binary.length == 0) {
1369 : /* RODC case, we do not have secrets locally */
1370 0 : DEBUG(1, ("Unable to fetch value for secret BCKUPKEY_P, are we an undetected RODC?\n"));
1371 0 : return WERR_INTERNAL_ERROR;
1372 : }
1373 :
1374 13 : status = GUID_from_ndr_blob(&guid_binary, returned_guid);
1375 13 : if (!NT_STATUS_IS_OK(status)) {
1376 0 : return WERR_FILE_NOT_FOUND;
1377 : }
1378 :
1379 13 : return bkrp_do_retrieve_server_wrap_key(mem_ctx, ldb_ctx,
1380 : server_key, returned_guid);
1381 : }
1382 :
1383 30 : static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1384 : struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx)
1385 : {
1386 30 : struct auth_session_info *session_info =
1387 0 : dcesrv_call_session_info(dce_call);
1388 : WERROR werr;
1389 : struct bkrp_server_side_wrapped decrypt_request;
1390 : DATA_BLOB sid_blob, encrypted_blob;
1391 : DATA_BLOB blob;
1392 : enum ndr_err_code ndr_err;
1393 : struct bkrp_dc_serverwrap_key server_key;
1394 : struct bkrp_rc4encryptedpayload rc4payload;
1395 : struct dom_sid *caller_sid;
1396 : uint8_t symkey[20]; /* SHA-1 hash len */
1397 : uint8_t mackey[20]; /* SHA-1 hash len */
1398 : uint8_t mac[20]; /* SHA-1 hash len */
1399 : gnutls_hmac_hd_t hmac_hnd;
1400 : gnutls_cipher_hd_t cipher_hnd;
1401 : gnutls_datum_t cipher_key;
1402 : int rc;
1403 :
1404 30 : blob.data = r->in.data_in;
1405 30 : blob.length = r->in.data_in_len;
1406 :
1407 30 : if (r->in.data_in_len == 0 || r->in.data_in == NULL) {
1408 1 : return WERR_INVALID_PARAMETER;
1409 : }
1410 :
1411 29 : ndr_err = ndr_pull_struct_blob_all(&blob, mem_ctx, &decrypt_request,
1412 : (ndr_pull_flags_fn_t)ndr_pull_bkrp_server_side_wrapped);
1413 29 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1414 10 : return WERR_INVALID_PARAMETER;
1415 : }
1416 :
1417 19 : if (decrypt_request.magic != BACKUPKEY_SERVER_WRAP_VERSION) {
1418 1 : return WERR_INVALID_PARAMETER;
1419 : }
1420 :
1421 18 : werr = bkrp_do_retrieve_server_wrap_key(mem_ctx, ldb_ctx, &server_key,
1422 : &decrypt_request.guid);
1423 18 : if (!W_ERROR_IS_OK(werr)) {
1424 2 : return werr;
1425 : }
1426 :
1427 16 : dump_data_pw("server_key: \n", server_key.key, sizeof(server_key.key));
1428 :
1429 16 : dump_data_pw("r2: \n", decrypt_request.r2, sizeof(decrypt_request.r2));
1430 :
1431 : /*
1432 : * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1433 : * BACKUPKEY_BACKUP_GUID, it really is the whole key
1434 : */
1435 :
1436 16 : rc = gnutls_hmac_init(&hmac_hnd,
1437 : GNUTLS_MAC_SHA1,
1438 : server_key.key,
1439 : sizeof(server_key.key));
1440 16 : if (rc != GNUTLS_E_SUCCESS) {
1441 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1442 : }
1443 :
1444 16 : rc = gnutls_hmac(hmac_hnd,
1445 : decrypt_request.r2,
1446 : sizeof(decrypt_request.r2));
1447 :
1448 16 : if (rc != GNUTLS_E_SUCCESS) {
1449 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1450 : }
1451 :
1452 16 : gnutls_hmac_output(hmac_hnd, symkey);
1453 16 : dump_data_pw("symkey: \n", symkey, sizeof(symkey));
1454 :
1455 : /* rc4 decrypt sid and secret using sym key */
1456 16 : cipher_key.data = symkey;
1457 16 : cipher_key.size = sizeof(symkey);
1458 :
1459 16 : encrypted_blob = data_blob_const(decrypt_request.rc4encryptedpayload,
1460 16 : decrypt_request.ciphertext_length);
1461 :
1462 16 : rc = gnutls_cipher_init(&cipher_hnd,
1463 : GNUTLS_CIPHER_ARCFOUR_128,
1464 : &cipher_key,
1465 : NULL);
1466 16 : if (rc != GNUTLS_E_SUCCESS) {
1467 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1468 : }
1469 48 : rc = gnutls_cipher_encrypt2(cipher_hnd,
1470 16 : encrypted_blob.data,
1471 : encrypted_blob.length,
1472 16 : encrypted_blob.data,
1473 : encrypted_blob.length);
1474 16 : gnutls_cipher_deinit(cipher_hnd);
1475 16 : if (rc != GNUTLS_E_SUCCESS) {
1476 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1477 : }
1478 :
1479 16 : ndr_err = ndr_pull_struct_blob_all(&encrypted_blob, mem_ctx, &rc4payload,
1480 : (ndr_pull_flags_fn_t)ndr_pull_bkrp_rc4encryptedpayload);
1481 16 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1482 4 : return WERR_INVALID_PARAMETER;
1483 : }
1484 :
1485 12 : if (decrypt_request.payload_length != rc4payload.secret_data.length) {
1486 6 : return WERR_INVALID_PARAMETER;
1487 : }
1488 :
1489 6 : dump_data_pw("r3: \n", rc4payload.r3, sizeof(rc4payload.r3));
1490 :
1491 : /*
1492 : * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1493 : * BACKUPKEY_BACKUP_GUID, it really is the whole key
1494 : */
1495 6 : rc = gnutls_hmac(hmac_hnd,
1496 : rc4payload.r3,
1497 : sizeof(rc4payload.r3));
1498 6 : if (rc != GNUTLS_E_SUCCESS) {
1499 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1500 : }
1501 :
1502 6 : gnutls_hmac_deinit(hmac_hnd, mackey);
1503 :
1504 6 : dump_data_pw("mackey: \n", mackey, sizeof(mackey));
1505 :
1506 6 : ndr_err = ndr_push_struct_blob(&sid_blob, mem_ctx, &rc4payload.sid,
1507 : (ndr_push_flags_fn_t)ndr_push_dom_sid);
1508 6 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1509 0 : return WERR_INTERNAL_ERROR;
1510 : }
1511 :
1512 6 : rc = gnutls_hmac_init(&hmac_hnd,
1513 : GNUTLS_MAC_SHA1,
1514 : mackey,
1515 : sizeof(mackey));
1516 6 : if (rc != GNUTLS_E_SUCCESS) {
1517 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1518 : }
1519 :
1520 : /* SID field */
1521 12 : rc = gnutls_hmac(hmac_hnd,
1522 6 : sid_blob.data,
1523 : sid_blob.length);
1524 6 : if (rc != GNUTLS_E_SUCCESS) {
1525 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1526 : }
1527 :
1528 : /* Secret field */
1529 12 : rc = gnutls_hmac(hmac_hnd,
1530 6 : rc4payload.secret_data.data,
1531 : rc4payload.secret_data.length);
1532 6 : if (rc != GNUTLS_E_SUCCESS) {
1533 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1534 : }
1535 :
1536 6 : gnutls_hmac_deinit(hmac_hnd, mac);
1537 6 : dump_data_pw("mac: \n", mac, sizeof(mac));
1538 6 : dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac));
1539 :
1540 6 : if (!mem_equal_const_time(mac, rc4payload.mac, sizeof(mac))) {
1541 0 : return WERR_INVALID_ACCESS;
1542 : }
1543 :
1544 6 : caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
1545 :
1546 6 : if (!dom_sid_equal(&rc4payload.sid, caller_sid)) {
1547 2 : return WERR_INVALID_ACCESS;
1548 : }
1549 :
1550 4 : *(r->out.data_out) = rc4payload.secret_data.data;
1551 4 : *(r->out.data_out_len) = rc4payload.secret_data.length;
1552 :
1553 4 : return WERR_OK;
1554 : }
1555 :
1556 : /*
1557 : * For BACKUPKEY_RESTORE_GUID we need to check the first 4 bytes to
1558 : * determine what type of restore is wanted.
1559 : *
1560 : * See MS-BKRP 3.1.4.1.4 BACKUPKEY_RESTORE_GUID point 1.
1561 : */
1562 :
1563 27 : static WERROR bkrp_generic_decrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1564 : struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx)
1565 : {
1566 27 : if (r->in.data_in_len < 4 || r->in.data_in == NULL) {
1567 3 : return WERR_INVALID_PARAMETER;
1568 : }
1569 :
1570 24 : if (IVAL(r->in.data_in, 0) == BACKUPKEY_SERVER_WRAP_VERSION) {
1571 14 : return bkrp_server_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1572 : }
1573 :
1574 10 : return bkrp_client_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1575 : }
1576 :
1577 : /*
1578 : * We have some data, such as saved website or IMAP passwords that the
1579 : * client would like to put into the profile on-disk. This needs to
1580 : * be encrypted. This version gives the server the data over the
1581 : * network (protected only by the negotiated transport encryption),
1582 : * and asks that it be encrypted and returned for long-term storage.
1583 : *
1584 : * The data is NOT stored in the LSA, but a key to encrypt the data
1585 : * will be stored. There is only one active encryption key per domain,
1586 : * it is pointed at with G$BCKUPKEY_P in the LSA secrets store.
1587 : *
1588 : * The potentially multiple valid decryptiong keys (and the encryption
1589 : * key) are in turn stored in the LSA secrets store as
1590 : * G$BCKUPKEY_keyGuidString.
1591 : *
1592 : */
1593 :
1594 13 : static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1595 : struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx)
1596 : {
1597 13 : struct auth_session_info *session_info =
1598 0 : dcesrv_call_session_info(dce_call);
1599 : DATA_BLOB sid_blob, encrypted_blob, server_wrapped_blob;
1600 : WERROR werr;
1601 : struct dom_sid *caller_sid;
1602 : uint8_t symkey[20]; /* SHA-1 hash len */
1603 : uint8_t mackey[20]; /* SHA-1 hash len */
1604 : struct bkrp_rc4encryptedpayload rc4payload;
1605 : gnutls_hmac_hd_t hmac_hnd;
1606 : struct bkrp_dc_serverwrap_key server_key;
1607 : enum ndr_err_code ndr_err;
1608 : struct bkrp_server_side_wrapped server_side_wrapped;
1609 : struct GUID guid;
1610 : gnutls_cipher_hd_t cipher_hnd;
1611 : gnutls_datum_t cipher_key;
1612 : int rc;
1613 :
1614 13 : if (r->in.data_in_len == 0 || r->in.data_in == NULL) {
1615 0 : return WERR_INVALID_PARAMETER;
1616 : }
1617 :
1618 13 : werr = bkrp_do_retrieve_default_server_wrap_key(mem_ctx,
1619 : ldb_ctx, &server_key,
1620 : &guid);
1621 :
1622 13 : if (!W_ERROR_IS_OK(werr)) {
1623 1 : if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
1624 : /* Generate the server wrap key since one wasn't found */
1625 1 : werr = generate_bkrp_server_wrap_key(mem_ctx,
1626 : ldb_ctx);
1627 1 : if (!W_ERROR_IS_OK(werr)) {
1628 0 : return WERR_INVALID_PARAMETER;
1629 : }
1630 1 : werr = bkrp_do_retrieve_default_server_wrap_key(mem_ctx,
1631 : ldb_ctx,
1632 : &server_key,
1633 : &guid);
1634 :
1635 1 : if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
1636 : /* Ok we really don't manage to get this secret ...*/
1637 0 : return WERR_FILE_NOT_FOUND;
1638 : }
1639 : } else {
1640 : /* In theory we should NEVER reach this point as it
1641 : should only appear in a rodc server */
1642 : /* we do not have the real secret attribute */
1643 0 : return WERR_INVALID_PARAMETER;
1644 : }
1645 : }
1646 :
1647 13 : caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
1648 :
1649 13 : dump_data_pw("server_key: \n", server_key.key, sizeof(server_key.key));
1650 :
1651 : /*
1652 : * This is the key derivation step, so that the HMAC and RC4
1653 : * operations over the user-supplied data are not able to
1654 : * disclose the master key. By using random data, the symkey
1655 : * and mackey values are unique for this operation, and
1656 : * discovering these (by reversing the RC4 over the
1657 : * attacker-controlled data) does not return something able to
1658 : * be used to decyrpt the encrypted data of other users
1659 : */
1660 13 : generate_random_buffer(server_side_wrapped.r2, sizeof(server_side_wrapped.r2));
1661 :
1662 13 : dump_data_pw("r2: \n", server_side_wrapped.r2, sizeof(server_side_wrapped.r2));
1663 :
1664 13 : generate_random_buffer(rc4payload.r3, sizeof(rc4payload.r3));
1665 :
1666 13 : dump_data_pw("r3: \n", rc4payload.r3, sizeof(rc4payload.r3));
1667 :
1668 :
1669 : /*
1670 : * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1671 : * BACKUPKEY_BACKUP_GUID, it really is the whole key
1672 : */
1673 13 : rc = gnutls_hmac_init(&hmac_hnd,
1674 : GNUTLS_MAC_SHA1,
1675 : server_key.key,
1676 : sizeof(server_key.key));
1677 13 : if (rc != GNUTLS_E_SUCCESS) {
1678 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1679 : }
1680 :
1681 13 : rc = gnutls_hmac(hmac_hnd,
1682 : server_side_wrapped.r2,
1683 : sizeof(server_side_wrapped.r2));
1684 13 : if (rc != GNUTLS_E_SUCCESS) {
1685 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1686 : }
1687 13 : gnutls_hmac_output(hmac_hnd, symkey);
1688 13 : dump_data_pw("symkey: \n", symkey, sizeof(symkey));
1689 :
1690 : /*
1691 : * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1692 : * BACKUPKEY_BACKUP_GUID, it really is the whole key
1693 : */
1694 13 : rc = gnutls_hmac(hmac_hnd,
1695 : rc4payload.r3,
1696 : sizeof(rc4payload.r3));
1697 13 : if (rc != GNUTLS_E_SUCCESS) {
1698 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1699 : }
1700 13 : gnutls_hmac_deinit(hmac_hnd, mackey);
1701 13 : dump_data_pw("mackey: \n", mackey, sizeof(mackey));
1702 :
1703 13 : ndr_err = ndr_push_struct_blob(&sid_blob, mem_ctx, caller_sid,
1704 : (ndr_push_flags_fn_t)ndr_push_dom_sid);
1705 13 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1706 0 : return WERR_INTERNAL_ERROR;
1707 : }
1708 :
1709 13 : rc4payload.secret_data.data = r->in.data_in;
1710 13 : rc4payload.secret_data.length = r->in.data_in_len;
1711 :
1712 13 : rc = gnutls_hmac_init(&hmac_hnd,
1713 : GNUTLS_MAC_SHA1,
1714 : mackey,
1715 : sizeof(mackey));
1716 13 : if (rc != GNUTLS_E_SUCCESS) {
1717 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1718 : }
1719 :
1720 : /* SID field */
1721 26 : rc = gnutls_hmac(hmac_hnd,
1722 13 : sid_blob.data,
1723 : sid_blob.length);
1724 13 : if (rc != GNUTLS_E_SUCCESS) {
1725 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1726 : }
1727 :
1728 : /* Secret field */
1729 26 : rc = gnutls_hmac(hmac_hnd,
1730 13 : rc4payload.secret_data.data,
1731 : rc4payload.secret_data.length);
1732 13 : if (rc != GNUTLS_E_SUCCESS) {
1733 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1734 : }
1735 :
1736 13 : gnutls_hmac_deinit(hmac_hnd, rc4payload.mac);
1737 13 : dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac));
1738 :
1739 13 : rc4payload.sid = *caller_sid;
1740 :
1741 13 : ndr_err = ndr_push_struct_blob(&encrypted_blob, mem_ctx, &rc4payload,
1742 : (ndr_push_flags_fn_t)ndr_push_bkrp_rc4encryptedpayload);
1743 13 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1744 0 : return WERR_INTERNAL_ERROR;
1745 : }
1746 :
1747 : /* rc4 encrypt sid and secret using sym key */
1748 13 : cipher_key.data = symkey;
1749 13 : cipher_key.size = sizeof(symkey);
1750 :
1751 13 : rc = gnutls_cipher_init(&cipher_hnd,
1752 : GNUTLS_CIPHER_ARCFOUR_128,
1753 : &cipher_key,
1754 : NULL);
1755 13 : if (rc != GNUTLS_E_SUCCESS) {
1756 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1757 : }
1758 39 : rc = gnutls_cipher_encrypt2(cipher_hnd,
1759 13 : encrypted_blob.data,
1760 : encrypted_blob.length,
1761 13 : encrypted_blob.data,
1762 : encrypted_blob.length);
1763 13 : gnutls_cipher_deinit(cipher_hnd);
1764 13 : if (rc != GNUTLS_E_SUCCESS) {
1765 0 : return gnutls_error_to_werror(rc, WERR_INTERNAL_ERROR);
1766 : }
1767 :
1768 : /* create server wrap structure */
1769 :
1770 13 : server_side_wrapped.payload_length = rc4payload.secret_data.length;
1771 13 : server_side_wrapped.ciphertext_length = encrypted_blob.length;
1772 13 : server_side_wrapped.guid = guid;
1773 13 : server_side_wrapped.rc4encryptedpayload = encrypted_blob.data;
1774 :
1775 13 : ndr_err = ndr_push_struct_blob(&server_wrapped_blob, mem_ctx, &server_side_wrapped,
1776 : (ndr_push_flags_fn_t)ndr_push_bkrp_server_side_wrapped);
1777 13 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1778 0 : return WERR_INTERNAL_ERROR;
1779 : }
1780 :
1781 13 : *(r->out.data_out) = server_wrapped_blob.data;
1782 13 : *(r->out.data_out_len) = server_wrapped_blob.length;
1783 :
1784 13 : return WERR_OK;
1785 : }
1786 :
1787 69 : static WERROR dcesrv_bkrp_BackupKey(struct dcesrv_call_state *dce_call,
1788 : TALLOC_CTX *mem_ctx, struct bkrp_BackupKey *r)
1789 : {
1790 69 : WERROR error = WERR_INVALID_PARAMETER;
1791 : struct ldb_context *ldb_ctx;
1792 : bool is_rodc;
1793 69 : const char *addr = "unknown";
1794 : /* At which level we start to add more debug of what is done in the protocol */
1795 69 : const int debuglevel = 4;
1796 :
1797 69 : if (DEBUGLVL(debuglevel)) {
1798 : const struct tsocket_address *remote_address;
1799 0 : remote_address = dcesrv_connection_get_remote_address(dce_call->conn);
1800 0 : if (tsocket_address_is_inet(remote_address, "ip")) {
1801 0 : addr = tsocket_address_inet_addr_string(remote_address, mem_ctx);
1802 0 : W_ERROR_HAVE_NO_MEMORY(addr);
1803 : }
1804 : }
1805 :
1806 69 : if (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC) {
1807 0 : return WERR_NOT_SUPPORTED;
1808 : }
1809 :
1810 : /*
1811 : * Save the current remote session details so they can used by the
1812 : * audit logging module. This allows the audit logging to report the
1813 : * remote users details, rather than the system users details.
1814 : */
1815 69 : ldb_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
1816 :
1817 69 : if (samdb_rodc(ldb_ctx, &is_rodc) != LDB_SUCCESS) {
1818 0 : talloc_unlink(mem_ctx, ldb_ctx);
1819 0 : return WERR_INVALID_PARAMETER;
1820 : }
1821 :
1822 69 : if (!is_rodc) {
1823 69 : if(strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1824 : BACKUPKEY_RESTORE_GUID, strlen(BACKUPKEY_RESTORE_GUID)) == 0) {
1825 27 : DEBUG(debuglevel, ("Client %s requested to decrypt a wrapped secret\n", addr));
1826 27 : error = bkrp_generic_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1827 : }
1828 :
1829 69 : if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1830 : BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID, strlen(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID)) == 0) {
1831 13 : DEBUG(debuglevel, ("Client %s requested certificate for client wrapped secret\n", addr));
1832 13 : error = bkrp_retrieve_client_wrap_key(dce_call, mem_ctx, r, ldb_ctx);
1833 : }
1834 :
1835 69 : if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1836 : BACKUPKEY_RESTORE_GUID_WIN2K, strlen(BACKUPKEY_RESTORE_GUID_WIN2K)) == 0) {
1837 16 : DEBUG(debuglevel, ("Client %s requested to decrypt a server side wrapped secret\n", addr));
1838 16 : error = bkrp_server_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1839 : }
1840 :
1841 69 : if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1842 : BACKUPKEY_BACKUP_GUID, strlen(BACKUPKEY_BACKUP_GUID)) == 0) {
1843 13 : DEBUG(debuglevel, ("Client %s requested a server wrapped secret\n", addr));
1844 13 : error = bkrp_server_wrap_encrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1845 : }
1846 : }
1847 : /*else: I am a RODC so I don't handle backup key protocol */
1848 :
1849 69 : talloc_unlink(mem_ctx, ldb_ctx);
1850 69 : return error;
1851 : }
1852 :
1853 : /* include the generated boilerplate */
1854 : #include "librpc/gen_ndr/ndr_backupkey_s.c"
|