2 Unix SMB/CIFS implementation.
4 endpoint server for the backupkey interface
6 Copyright (C) Matthieu Patou <mat@samba.org> 2010
7 Copyright (C) Andreas Schneider <asn@samba.org> 2015
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.
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.
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/>.
24 #include "rpc_server/dcerpc_server.h"
25 #include "librpc/gen_ndr/ndr_backupkey.h"
26 #include "dsdb/common/util.h"
27 #include "dsdb/samdb/samdb.h"
28 #include "lib/ldb/include/ldb_errors.h"
29 #include "../lib/util/util_ldb.h"
30 #include "param/param.h"
31 #include "auth/session.h"
32 #include "system/network.h"
34 #include "../lib/tsocket/tsocket.h"
35 #include "../libcli/security/security.h"
36 #include "librpc/gen_ndr/ndr_security.h"
37 #include "libds/common/roles.h"
39 #include <gnutls/gnutls.h>
40 #include <gnutls/x509.h>
41 #include <gnutls/crypto.h>
42 #include <gnutls/abstract.h>
44 #define DCESRV_INTERFACE_BACKUPKEY_BIND(call, iface) \
45 dcesrv_interface_backupkey_bind(call, iface)
46 static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_call_state *dce_call,
47 const struct dcesrv_interface *iface)
49 return dcesrv_interface_bind_require_privacy(dce_call, iface);
52 static NTSTATUS set_lsa_secret(TALLOC_CTX *mem_ctx,
53 struct ldb_context *ldb,
55 const DATA_BLOB *lsa_secret)
57 struct ldb_message *msg;
58 struct ldb_result *res;
59 struct ldb_dn *domain_dn;
60 struct ldb_dn *system_dn;
64 struct timeval now = timeval_current();
65 NTTIME nt_now = timeval_to_nttime(&now);
66 const char *attrs[] = {
70 domain_dn = ldb_get_default_basedn(ldb);
72 return NT_STATUS_INTERNAL_ERROR;
75 msg = ldb_msg_new(mem_ctx);
77 return NT_STATUS_NO_MEMORY;
81 * This function is a lot like dcesrv_lsa_CreateSecret
82 * in the rpc_server/lsa directory
83 * The reason why we duplicate the effort here is that:
84 * * we want to keep the former function static
85 * * we want to avoid the burden of doing LSA calls
86 * when we can just manipulate the secrets directly
87 * * taillor the function to the particular needs of backup protocol
90 system_dn = samdb_search_dn(ldb, msg, domain_dn, "(&(objectClass=container)(cn=System))");
91 if (system_dn == NULL) {
93 return NT_STATUS_NO_MEMORY;
96 name2 = talloc_asprintf(msg, "%s Secret", name);
99 return NT_STATUS_NO_MEMORY;
102 ret = ldb_search(ldb, mem_ctx, &res, system_dn, LDB_SCOPE_SUBTREE, attrs,
103 "(&(cn=%s)(objectclass=secret))",
104 ldb_binary_encode_string(mem_ctx, name2));
106 if (ret != LDB_SUCCESS || res->count != 0 ) {
107 DEBUG(2, ("Secret %s already exists !\n", name2));
109 return NT_STATUS_OBJECT_NAME_COLLISION;
113 * We don't care about previous value as we are
114 * here only if the key didn't exists before
117 msg->dn = ldb_dn_copy(mem_ctx, system_dn);
118 if (msg->dn == NULL) {
120 return NT_STATUS_NO_MEMORY;
122 if (!ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
124 return NT_STATUS_NO_MEMORY;
127 ret = ldb_msg_add_string(msg, "cn", name2);
128 if (ret != LDB_SUCCESS) {
130 return NT_STATUS_NO_MEMORY;
132 ret = ldb_msg_add_string(msg, "objectClass", "secret");
133 if (ret != LDB_SUCCESS) {
135 return NT_STATUS_NO_MEMORY;
137 ret = samdb_msg_add_uint64(ldb, mem_ctx, msg, "priorSetTime", nt_now);
138 if (ret != LDB_SUCCESS) {
140 return NT_STATUS_NO_MEMORY;
142 val.data = lsa_secret->data;
143 val.length = lsa_secret->length;
144 ret = ldb_msg_add_value(msg, "currentValue", &val, NULL);
145 if (ret != LDB_SUCCESS) {
147 return NT_STATUS_NO_MEMORY;
149 ret = samdb_msg_add_uint64(ldb, mem_ctx, msg, "lastSetTime", nt_now);
150 if (ret != LDB_SUCCESS) {
152 return NT_STATUS_NO_MEMORY;
156 * create the secret with DSDB_MODIFY_RELAX
157 * otherwise dsdb/samdb/ldb_modules/objectclass.c forbid
158 * the create of LSA secret object
160 ret = dsdb_add(ldb, msg, DSDB_MODIFY_RELAX);
161 if (ret != LDB_SUCCESS) {
162 DEBUG(2,("Failed to create secret record %s: %s\n",
163 ldb_dn_get_linearized(msg->dn),
164 ldb_errstring(ldb)));
166 return NT_STATUS_ACCESS_DENIED;
173 /* This function is pretty much like dcesrv_lsa_QuerySecret */
174 static NTSTATUS get_lsa_secret(TALLOC_CTX *mem_ctx,
175 struct ldb_context *ldb,
177 DATA_BLOB *lsa_secret)
180 struct ldb_result *res;
181 struct ldb_dn *domain_dn;
182 struct ldb_dn *system_dn;
183 const struct ldb_val *val;
185 const char *attrs[] = {
191 lsa_secret->data = NULL;
192 lsa_secret->length = 0;
194 domain_dn = ldb_get_default_basedn(ldb);
196 return NT_STATUS_INTERNAL_ERROR;
199 tmp_mem = talloc_new(mem_ctx);
200 if (tmp_mem == NULL) {
201 return NT_STATUS_NO_MEMORY;
204 system_dn = samdb_search_dn(ldb, tmp_mem, domain_dn, "(&(objectClass=container)(cn=System))");
205 if (system_dn == NULL) {
206 talloc_free(tmp_mem);
207 return NT_STATUS_NO_MEMORY;
210 ret = ldb_search(ldb, mem_ctx, &res, system_dn, LDB_SCOPE_SUBTREE, attrs,
211 "(&(cn=%s Secret)(objectclass=secret))",
212 ldb_binary_encode_string(tmp_mem, name));
214 if (ret != LDB_SUCCESS) {
215 talloc_free(tmp_mem);
216 return NT_STATUS_INTERNAL_DB_CORRUPTION;
218 if (res->count == 0) {
219 talloc_free(tmp_mem);
220 return NT_STATUS_RESOURCE_NAME_NOT_FOUND;
222 if (res->count > 1) {
223 DEBUG(2, ("Secret %s collision\n", name));
224 talloc_free(tmp_mem);
225 return NT_STATUS_INTERNAL_DB_CORRUPTION;
228 val = ldb_msg_find_ldb_val(res->msgs[0], "currentValue");
231 * The secret object is here but we don't have the secret value
232 * The most common case is a RODC
234 *lsa_secret = data_blob_null;
235 talloc_free(tmp_mem);
240 lsa_secret->data = talloc_move(mem_ctx, &data);
241 lsa_secret->length = val->length;
243 talloc_free(tmp_mem);
247 static int reverse_and_get_bignum(TALLOC_CTX *mem_ctx,
249 gnutls_datum_t *datum)
253 datum->data = talloc_array(mem_ctx, uint8_t, blob.length);
254 if (datum->data == NULL) {
258 for(i = 0; i < blob.length; i++) {
259 datum->data[i] = blob.data[blob.length - i - 1];
261 datum->size = blob.length;
266 static NTSTATUS get_pk_from_raw_keypair_params(TALLOC_CTX *ctx,
267 struct bkrp_exported_RSA_key_pair *keypair,
268 gnutls_privkey_t *pk)
270 gnutls_x509_privkey_t x509_privkey = NULL;
271 gnutls_privkey_t privkey = NULL;
272 gnutls_datum_t m, e, d, p, q, u, e1, e2;
275 rc = reverse_and_get_bignum(ctx, keypair->modulus, &m);
277 return NT_STATUS_INVALID_PARAMETER;
279 rc = reverse_and_get_bignum(ctx, keypair->public_exponent, &e);
281 return NT_STATUS_INVALID_PARAMETER;
283 rc = reverse_and_get_bignum(ctx, keypair->private_exponent, &d);
285 return NT_STATUS_INVALID_PARAMETER;
288 rc = reverse_and_get_bignum(ctx, keypair->prime1, &p);
290 return NT_STATUS_INVALID_PARAMETER;
292 rc = reverse_and_get_bignum(ctx, keypair->prime2, &q);
294 return NT_STATUS_INVALID_PARAMETER;
297 rc = reverse_and_get_bignum(ctx, keypair->coefficient, &u);
299 return NT_STATUS_INVALID_PARAMETER;
302 rc = reverse_and_get_bignum(ctx, keypair->exponent1, &e1);
304 return NT_STATUS_INVALID_PARAMETER;
306 rc = reverse_and_get_bignum(ctx, keypair->exponent2, &e2);
308 return NT_STATUS_INVALID_PARAMETER;
311 rc = gnutls_x509_privkey_init(&x509_privkey);
312 if (rc != GNUTLS_E_SUCCESS) {
313 DBG_ERR("gnutls_x509_privkey_init failed - %s\n",
314 gnutls_strerror(rc));
315 return NT_STATUS_INTERNAL_ERROR;
318 rc = gnutls_x509_privkey_import_rsa_raw2(x509_privkey,
327 if (rc != GNUTLS_E_SUCCESS) {
328 DBG_ERR("gnutls_x509_privkey_import_rsa_raw2 failed - %s\n",
329 gnutls_strerror(rc));
330 return NT_STATUS_INTERNAL_ERROR;
333 rc = gnutls_privkey_init(&privkey);
334 if (rc != GNUTLS_E_SUCCESS) {
335 DBG_ERR("gnutls_privkey_init failed - %s\n",
336 gnutls_strerror(rc));
337 gnutls_x509_privkey_deinit(x509_privkey);
338 return NT_STATUS_INTERNAL_ERROR;
341 rc = gnutls_privkey_import_x509(privkey,
343 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
344 if (rc != GNUTLS_E_SUCCESS) {
345 DBG_ERR("gnutls_privkey_import_x509 failed - %s\n",
346 gnutls_strerror(rc));
347 gnutls_x509_privkey_deinit(x509_privkey);
348 return NT_STATUS_INTERNAL_ERROR;
356 static WERROR get_and_verify_access_check(TALLOC_CTX *sub_ctx,
359 uint8_t *access_check,
360 uint32_t access_check_len,
361 struct auth_session_info *session_info)
363 gnutls_cipher_hd_t cipher_handle = { 0 };
364 gnutls_cipher_algorithm_t cipher_algo;
366 enum ndr_err_code ndr_err;
370 struct dom_sid *access_sid = NULL;
371 struct dom_sid *caller_sid = NULL;
376 cipher_algo = GNUTLS_CIPHER_3DES_CBC;
379 cipher_algo = GNUTLS_CIPHER_AES_256_CBC;
382 return WERR_INVALID_DATA;
385 key.data = key_and_iv;
386 key.size = gnutls_cipher_get_key_size(cipher_algo);
388 iv.data = key_and_iv + key.size;
389 iv.size = gnutls_cipher_get_iv_size(cipher_algo);
391 /* Allocate data structure for the plaintext */
392 blob_us = data_blob_talloc_zero(sub_ctx, access_check_len);
393 if (blob_us.data == NULL) {
394 return WERR_INVALID_DATA;
397 rc = gnutls_cipher_init(&cipher_handle,
402 DBG_ERR("gnutls_cipher_init failed: %s\n",
403 gnutls_strerror(rc));
404 return WERR_INVALID_DATA;
407 rc = gnutls_cipher_decrypt2(cipher_handle,
412 gnutls_cipher_deinit(cipher_handle);
414 DBG_ERR("gnutls_cipher_decrypt2 failed: %s\n",
415 gnutls_strerror(rc));
416 return WERR_INVALID_DATA;
422 uint32_t hash_size = 20;
423 uint8_t hash[hash_size];
424 gnutls_hash_hd_t dig_ctx;
425 struct bkrp_access_check_v2 uncrypted_accesscheckv2;
427 ndr_err = ndr_pull_struct_blob(&blob_us, sub_ctx, &uncrypted_accesscheckv2,
428 (ndr_pull_flags_fn_t)ndr_pull_bkrp_access_check_v2);
429 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
430 /* Unable to unmarshall */
431 return WERR_INVALID_DATA;
433 if (uncrypted_accesscheckv2.magic != 0x1) {
435 return WERR_INVALID_DATA;
438 gnutls_hash_init(&dig_ctx, GNUTLS_DIG_SHA1);
441 blob_us.length - hash_size);
442 gnutls_hash_deinit(dig_ctx, hash);
444 * We free it after the sha1 calculation because blob.data
445 * point to the same area
448 if (memcmp(hash, uncrypted_accesscheckv2.hash, hash_size) != 0) {
449 DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
450 return WERR_INVALID_DATA;
452 access_sid = &(uncrypted_accesscheckv2.sid);
457 uint32_t hash_size = 64;
458 uint8_t hash[hash_size];
459 gnutls_hash_hd_t dig_ctx;
460 struct bkrp_access_check_v3 uncrypted_accesscheckv3;
462 ndr_err = ndr_pull_struct_blob(&blob_us, sub_ctx, &uncrypted_accesscheckv3,
463 (ndr_pull_flags_fn_t)ndr_pull_bkrp_access_check_v3);
464 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
465 /* Unable to unmarshall */
466 return WERR_INVALID_DATA;
468 if (uncrypted_accesscheckv3.magic != 0x1) {
470 return WERR_INVALID_DATA;
473 gnutls_hash_init(&dig_ctx, GNUTLS_DIG_SHA512);
476 blob_us.length - hash_size);
477 gnutls_hash_deinit(dig_ctx, hash);
480 * We free it after the sha1 calculation because blob.data
481 * point to the same area
484 if (memcmp(hash, uncrypted_accesscheckv3.hash, hash_size) != 0) {
485 DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
486 return WERR_INVALID_DATA;
488 access_sid = &(uncrypted_accesscheckv3.sid);
492 /* Never reached normally as we filtered at the switch / case level */
493 return WERR_INVALID_DATA;
496 caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
498 if (!dom_sid_equal(caller_sid, access_sid)) {
499 return WERR_INVALID_ACCESS;
505 * We have some data, such as saved website or IMAP passwords that the
506 * client has in profile on-disk. This needs to be decrypted. This
507 * version gives the server the data over the network (protected by
508 * the X.509 certificate and public key encryption, and asks that it
509 * be decrypted returned for short-term use, protected only by the
510 * negotiated transport encryption.
512 * The data is NOT stored in the LSA, but a X.509 certificate, public
513 * and private keys used to encrypt the data will be stored. There is
514 * only one active encryption key pair and certificate per domain, it
515 * is pointed at with G$BCKUPKEY_PREFERRED in the LSA secrets store.
517 * The potentially multiple valid decrypting key pairs are in turn
518 * stored in the LSA secrets store as G$BCKUPKEY_keyGuidString.
521 static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
523 struct bkrp_BackupKey *r,
524 struct ldb_context *ldb_ctx)
526 struct bkrp_client_side_wrapped uncrypt_request;
528 enum ndr_err_code ndr_err;
530 char *cert_secret_name;
531 DATA_BLOB lsa_secret;
532 DATA_BLOB *uncrypted_data = NULL;
534 uint32_t requested_version;
536 blob.data = r->in.data_in;
537 blob.length = r->in.data_in_len;
539 if (r->in.data_in_len < 4 || r->in.data_in == NULL) {
540 return WERR_INVALID_PARAMETER;
544 * We check for the version here, so we can actually print the
545 * message as we are unlikely to parse it with NDR.
547 requested_version = IVAL(r->in.data_in, 0);
548 if ((requested_version != BACKUPKEY_CLIENT_WRAP_VERSION2)
549 && (requested_version != BACKUPKEY_CLIENT_WRAP_VERSION3)) {
550 DEBUG(1, ("Request for unknown BackupKey sub-protocol %d\n", requested_version));
551 return WERR_INVALID_PARAMETER;
554 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &uncrypt_request,
555 (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_wrapped);
556 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
557 return WERR_INVALID_PARAMETER;
560 if ((uncrypt_request.version != BACKUPKEY_CLIENT_WRAP_VERSION2)
561 && (uncrypt_request.version != BACKUPKEY_CLIENT_WRAP_VERSION3)) {
562 DEBUG(1, ("Request for unknown BackupKey sub-protocol %d\n", uncrypt_request.version));
563 return WERR_INVALID_PARAMETER;
566 guid_string = GUID_string(mem_ctx, &uncrypt_request.guid);
567 if (guid_string == NULL) {
568 return WERR_NOT_ENOUGH_MEMORY;
571 cert_secret_name = talloc_asprintf(mem_ctx,
574 if (cert_secret_name == NULL) {
575 return WERR_NOT_ENOUGH_MEMORY;
578 status = get_lsa_secret(mem_ctx,
582 if (!NT_STATUS_IS_OK(status)) {
583 DEBUG(10, ("Error while fetching secret %s\n", cert_secret_name));
584 return WERR_INVALID_DATA;
585 } else if (lsa_secret.length == 0) {
586 /* we do not have the real secret attribute, like if we are an RODC */
587 return WERR_INVALID_PARAMETER;
589 struct bkrp_exported_RSA_key_pair keypair;
590 gnutls_privkey_t privkey = NULL;
591 gnutls_datum_t reversed_secret;
592 gnutls_datum_t uncrypted_secret;
598 ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, &keypair, (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair);
599 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
600 DEBUG(2, ("Unable to parse the ndr encoded cert in key %s\n", cert_secret_name));
601 return WERR_FILE_NOT_FOUND;
604 status = get_pk_from_raw_keypair_params(mem_ctx,
607 if (!NT_STATUS_IS_OK(status)) {
608 return WERR_INTERNAL_ERROR;
611 reversed_secret.data = talloc_array(mem_ctx, uint8_t,
612 uncrypt_request.encrypted_secret_len);
613 if (reversed_secret.data == NULL) {
614 gnutls_privkey_deinit(privkey);
615 return WERR_NOT_ENOUGH_MEMORY;
618 /* The secret has to be reversed ... */
619 for(i=0; i< uncrypt_request.encrypted_secret_len; i++) {
620 uint8_t *reversed = (uint8_t *)reversed_secret.data;
621 uint8_t *uncrypt = uncrypt_request.encrypted_secret;
622 reversed[i] = uncrypt[uncrypt_request.encrypted_secret_len - 1 - i];
624 reversed_secret.size = uncrypt_request.encrypted_secret_len;
627 * Let's try to decrypt the secret now that
628 * we have the private key ...
630 rc = gnutls_privkey_decrypt_data(privkey,
634 gnutls_privkey_deinit(privkey);
635 if (rc != GNUTLS_E_SUCCESS) {
636 /* We are not able to decrypt the secret, looks like something is wrong */
637 return WERR_INVALID_PARAMETER;
639 blob_us.data = uncrypted_secret.data;
640 blob_us.length = uncrypted_secret.size;
642 if (uncrypt_request.version == 2) {
643 struct bkrp_encrypted_secret_v2 uncrypted_secretv2;
645 ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv2,
646 (ndr_pull_flags_fn_t)ndr_pull_bkrp_encrypted_secret_v2);
647 gnutls_free(uncrypted_secret.data);
648 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
649 /* Unable to unmarshall */
650 return WERR_INVALID_DATA;
652 if (uncrypted_secretv2.magic != 0x20) {
654 return WERR_INVALID_DATA;
657 werr = get_and_verify_access_check(mem_ctx, 2,
658 uncrypted_secretv2.payload_key,
659 uncrypt_request.access_check,
660 uncrypt_request.access_check_len,
661 dce_call->conn->auth_state.session_info);
662 if (!W_ERROR_IS_OK(werr)) {
665 uncrypted_data = talloc(mem_ctx, DATA_BLOB);
666 if (uncrypted_data == NULL) {
667 return WERR_INVALID_DATA;
670 uncrypted_data->data = uncrypted_secretv2.secret;
671 uncrypted_data->length = uncrypted_secretv2.secret_len;
673 if (uncrypt_request.version == 3) {
674 struct bkrp_encrypted_secret_v3 uncrypted_secretv3;
676 ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv3,
677 (ndr_pull_flags_fn_t)ndr_pull_bkrp_encrypted_secret_v3);
678 gnutls_free(uncrypted_secret.data);
679 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
680 /* Unable to unmarshall */
681 return WERR_INVALID_DATA;
684 if (uncrypted_secretv3.magic1 != 0x30 ||
685 uncrypted_secretv3.magic2 != 0x6610 ||
686 uncrypted_secretv3.magic3 != 0x800e) {
688 return WERR_INVALID_DATA;
692 * Confirm that the caller is permitted to
693 * read this particular data. Because one key
694 * pair is used per domain, the caller could
695 * have stolen the profile data on-disk and
696 * would otherwise be able to read the
700 werr = get_and_verify_access_check(mem_ctx, 3,
701 uncrypted_secretv3.payload_key,
702 uncrypt_request.access_check,
703 uncrypt_request.access_check_len,
704 dce_call->conn->auth_state.session_info);
705 if (!W_ERROR_IS_OK(werr)) {
709 uncrypted_data = talloc(mem_ctx, DATA_BLOB);
710 if (uncrypted_data == NULL) {
711 return WERR_INVALID_DATA;
714 uncrypted_data->data = uncrypted_secretv3.secret;
715 uncrypted_data->length = uncrypted_secretv3.secret_len;
719 * Yeah if we are here all looks pretty good:
721 * - user sid is the same as the one in access check
722 * - we were able to decrypt the whole stuff
726 if (uncrypted_data->data == NULL) {
727 return WERR_INVALID_DATA;
730 /* There is a magic value a the beginning of the data
731 * we can use an adhoc structure but as the
732 * parent structure is just an array of bytes it a lot of work
733 * work just prepending 4 bytes
735 *(r->out.data_out) = talloc_zero_array(mem_ctx, uint8_t, uncrypted_data->length + 4);
736 W_ERROR_HAVE_NO_MEMORY(*(r->out.data_out));
737 memcpy(4+*(r->out.data_out), uncrypted_data->data, uncrypted_data->length);
738 *(r->out.data_out_len) = uncrypted_data->length + 4;
743 static DATA_BLOB *reverse_and_get_blob(TALLOC_CTX *mem_ctx,
744 gnutls_datum_t *datum)
749 blob = talloc(mem_ctx, DATA_BLOB);
754 blob->length = datum->size;
755 if (datum->data[0] == '\0') {
756 /* The datum has a leading byte zero, skip it */
757 blob->length = datum->size - 1;
759 blob->data = talloc_zero_array(mem_ctx, uint8_t, blob->length);
760 if (blob->data == NULL) {
765 for (i = 0; i < blob->length; i++) {
766 blob->data[i] = datum->data[datum->size - i - 1];
772 static WERROR create_privkey_rsa(gnutls_privkey_t *pk)
775 gnutls_x509_privkey_t x509_privkey = NULL;
776 gnutls_privkey_t privkey = NULL;
779 rc = gnutls_x509_privkey_init(&x509_privkey);
780 if (rc != GNUTLS_E_SUCCESS) {
781 DBG_ERR("gnutls_x509_privkey_init failed - %s\n",
782 gnutls_strerror(rc));
783 return WERR_INTERNAL_ERROR;
786 rc = gnutls_x509_privkey_generate(x509_privkey,
790 if (rc != GNUTLS_E_SUCCESS) {
791 DBG_ERR("gnutls_x509_privkey_generate failed - %s\n",
792 gnutls_strerror(rc));
793 gnutls_x509_privkey_deinit(x509_privkey);
794 return WERR_INTERNAL_ERROR;
797 rc = gnutls_privkey_init(&privkey);
798 if (rc != GNUTLS_E_SUCCESS) {
799 DBG_ERR("gnutls_privkey_init failed - %s\n",
800 gnutls_strerror(rc));
801 gnutls_x509_privkey_deinit(x509_privkey);
802 return WERR_INTERNAL_ERROR;
805 rc = gnutls_privkey_import_x509(privkey,
807 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
808 if (rc != GNUTLS_E_SUCCESS) {
809 DBG_ERR("gnutls_privkey_import_x509 failed - %s\n",
810 gnutls_strerror(rc));
811 gnutls_x509_privkey_deinit(x509_privkey);
812 return WERR_INTERNAL_ERROR;
820 static WERROR self_sign_cert(TALLOC_CTX *mem_ctx,
823 gnutls_privkey_t issuer_privkey,
824 gnutls_x509_crt_t *certificate,
827 gnutls_datum_t unique_id;
828 gnutls_datum_t serial_number;
829 gnutls_x509_crt_t issuer_cert;
830 gnutls_x509_privkey_t x509_issuer_privkey;
831 time_t activation = time(NULL);
832 time_t expiry = activation + lifetime;
833 const char *error_string;
838 unique_id.size = guidblob->length;
839 unique_id.data = talloc_memdup(mem_ctx,
842 if (unique_id.data == NULL) {
843 return WERR_NOT_ENOUGH_MEMORY;
846 reversed = talloc_array(mem_ctx, uint8_t, guidblob->length);
847 if (reversed == NULL) {
848 talloc_free(unique_id.data);
849 return WERR_NOT_ENOUGH_MEMORY;
852 /* Native AD generates certificates with serialnumber in reversed notation */
853 for (i = 0; i < guidblob->length; i++) {
854 uint8_t *uncrypt = guidblob->data;
855 reversed[i] = uncrypt[guidblob->length - i - 1];
857 serial_number.size = guidblob->length;
858 serial_number.data = reversed;
860 /* Create certificate to sign */
861 rc = gnutls_x509_crt_init(&issuer_cert);
862 if (rc != GNUTLS_E_SUCCESS) {
863 DBG_ERR("gnutls_x509_crt_init failed - %s\n",
864 gnutls_strerror(rc));
865 return WERR_NOT_ENOUGH_MEMORY;
868 rc = gnutls_x509_crt_set_dn(issuer_cert, dn, &error_string);
869 if (rc != GNUTLS_E_SUCCESS) {
870 DBG_ERR("gnutls_x509_crt_set_dn failed - %s (%s)\n",
873 gnutls_x509_crt_deinit(issuer_cert);
874 return WERR_INVALID_PARAMETER;
877 rc = gnutls_x509_crt_set_issuer_dn(issuer_cert, dn, &error_string);
878 if (rc != GNUTLS_E_SUCCESS) {
879 DBG_ERR("gnutls_x509_crt_set_issuer_dn failed - %s (%s)\n",
882 gnutls_x509_crt_deinit(issuer_cert);
883 return WERR_INVALID_PARAMETER;
886 /* Get x509 privkey for subjectPublicKeyInfo */
887 rc = gnutls_x509_privkey_init(&x509_issuer_privkey);
888 if (rc != GNUTLS_E_SUCCESS) {
889 DBG_ERR("gnutls_x509_privkey_init failed - %s\n",
890 gnutls_strerror(rc));
891 gnutls_x509_crt_deinit(issuer_cert);
892 return WERR_INVALID_PARAMETER;
895 rc = gnutls_privkey_export_x509(issuer_privkey,
896 &x509_issuer_privkey);
897 if (rc != GNUTLS_E_SUCCESS) {
898 DBG_ERR("gnutls_x509_privkey_init failed - %s\n",
899 gnutls_strerror(rc));
900 gnutls_x509_privkey_deinit(x509_issuer_privkey);
901 gnutls_x509_crt_deinit(issuer_cert);
902 return WERR_INVALID_PARAMETER;
905 /* Set subjectPublicKeyInfo */
906 rc = gnutls_x509_crt_set_key(issuer_cert, x509_issuer_privkey);
907 gnutls_x509_privkey_deinit(x509_issuer_privkey);
908 if (rc != GNUTLS_E_SUCCESS) {
909 DBG_ERR("gnutls_x509_crt_set_pubkey failed - %s\n",
910 gnutls_strerror(rc));
911 gnutls_x509_crt_deinit(issuer_cert);
912 return WERR_INVALID_PARAMETER;
915 rc = gnutls_x509_crt_set_activation_time(issuer_cert, activation);
916 if (rc != GNUTLS_E_SUCCESS) {
917 DBG_ERR("gnutls_x509_crt_set_activation_time failed - %s\n",
918 gnutls_strerror(rc));
919 gnutls_x509_crt_deinit(issuer_cert);
920 return WERR_INVALID_PARAMETER;
923 rc = gnutls_x509_crt_set_expiration_time(issuer_cert, expiry);
924 if (rc != GNUTLS_E_SUCCESS) {
925 DBG_ERR("gnutls_x509_crt_set_expiration_time failed - %s\n",
926 gnutls_strerror(rc));
927 gnutls_x509_crt_deinit(issuer_cert);
928 return WERR_INVALID_PARAMETER;
931 rc = gnutls_x509_crt_set_version(issuer_cert, 3);
932 if (rc != GNUTLS_E_SUCCESS) {
933 DBG_ERR("gnutls_x509_crt_set_version failed - %s\n",
934 gnutls_strerror(rc));
935 gnutls_x509_crt_deinit(issuer_cert);
936 return WERR_INVALID_PARAMETER;
939 rc = gnutls_x509_crt_set_subject_unique_id(issuer_cert,
942 if (rc != GNUTLS_E_SUCCESS) {
943 DBG_ERR("gnutls_x509_crt_set_subject_key_id failed - %s\n",
944 gnutls_strerror(rc));
945 gnutls_x509_crt_deinit(issuer_cert);
946 return WERR_INVALID_PARAMETER;
949 rc = gnutls_x509_crt_set_issuer_unique_id(issuer_cert,
952 if (rc != GNUTLS_E_SUCCESS) {
953 DBG_ERR("gnutls_x509_crt_set_issuer_unique_id failed - %s\n",
954 gnutls_strerror(rc));
955 gnutls_x509_crt_deinit(issuer_cert);
956 return WERR_INVALID_PARAMETER;
959 rc = gnutls_x509_crt_set_serial(issuer_cert,
962 if (rc != GNUTLS_E_SUCCESS) {
963 DBG_ERR("gnutls_x509_crt_set_serial failed - %s\n",
964 gnutls_strerror(rc));
965 gnutls_x509_crt_deinit(issuer_cert);
966 return WERR_INVALID_PARAMETER;
969 rc = gnutls_x509_crt_privkey_sign(issuer_cert,
974 if (rc != GNUTLS_E_SUCCESS) {
975 DBG_ERR("gnutls_x509_crt_privkey_sign failed - %s\n",
976 gnutls_strerror(rc));
977 return WERR_INVALID_PARAMETER;
980 *certificate = issuer_cert;
985 /* Return an error when we fail to generate a certificate */
986 static WERROR generate_bkrp_cert(TALLOC_CTX *mem_ctx,
987 struct dcesrv_call_state *dce_call,
988 struct ldb_context *ldb_ctx,
992 gnutls_privkey_t issuer_privkey = NULL;
993 gnutls_x509_crt_t cert = NULL;
994 gnutls_datum_t cert_blob;
995 gnutls_datum_t m, e, d, p, q, u, e1, e2;
997 DATA_BLOB blobkeypair;
1000 struct GUID guid = GUID_random();
1003 struct bkrp_exported_RSA_key_pair keypair;
1004 enum ndr_err_code ndr_err;
1005 time_t nb_seconds_validity = 3600 * 24 * 365;
1008 DEBUG(6, ("Trying to generate a certificate\n"));
1009 werr = create_privkey_rsa(&issuer_privkey);
1010 if (!W_ERROR_IS_OK(werr)) {
1014 status = GUID_to_ndr_blob(&guid, mem_ctx, &blob);
1015 if (!NT_STATUS_IS_OK(status)) {
1016 gnutls_privkey_deinit(issuer_privkey);
1017 return WERR_INVALID_DATA;
1020 werr = self_sign_cert(mem_ctx,
1021 nb_seconds_validity,
1026 if (!W_ERROR_IS_OK(werr)) {
1027 gnutls_privkey_deinit(issuer_privkey);
1028 return WERR_INVALID_DATA;
1031 rc = gnutls_x509_crt_export2(cert, GNUTLS_X509_FMT_DER, &cert_blob);
1032 if (rc != GNUTLS_E_SUCCESS) {
1033 DBG_ERR("gnutls_x509_crt_export2 failed - %s\n",
1034 gnutls_strerror(rc));
1035 gnutls_privkey_deinit(issuer_privkey);
1036 gnutls_x509_crt_deinit(cert);
1037 return WERR_INVALID_DATA;
1040 keypair.cert.length = cert_blob.size;
1041 keypair.cert.data = talloc_memdup(mem_ctx, cert_blob.data, cert_blob.size);
1042 gnutls_x509_crt_deinit(cert);
1043 gnutls_free(cert_blob.data);
1044 if (keypair.cert.data == NULL) {
1045 gnutls_privkey_deinit(issuer_privkey);
1046 return WERR_NOT_ENOUGH_MEMORY;
1049 rc = gnutls_privkey_export_rsa_raw(issuer_privkey,
1058 if (rc != GNUTLS_E_SUCCESS) {
1059 gnutls_privkey_deinit(issuer_privkey);
1060 return WERR_INVALID_DATA;
1064 * Heimdal's bignum are big endian and the
1065 * structure expect it to be in little endian
1066 * so we reverse the buffer to make it work
1068 tmp = reverse_and_get_blob(mem_ctx, &e);
1072 SMB_ASSERT(tmp->length <= 4);
1073 keypair.public_exponent = *tmp;
1076 tmp = reverse_and_get_blob(mem_ctx, &d);
1080 keypair.private_exponent = *tmp;
1083 tmp = reverse_and_get_blob(mem_ctx, &m);
1087 keypair.modulus = *tmp;
1090 tmp = reverse_and_get_blob(mem_ctx, &p);
1094 keypair.prime1 = *tmp;
1097 tmp = reverse_and_get_blob(mem_ctx, &q);
1101 keypair.prime2 = *tmp;
1104 tmp = reverse_and_get_blob(mem_ctx, &e1);
1108 keypair.exponent1 = *tmp;
1111 tmp = reverse_and_get_blob(mem_ctx, &e2);
1115 keypair.exponent2 = *tmp;
1118 tmp = reverse_and_get_blob(mem_ctx, &u);
1122 keypair.coefficient = *tmp;
1125 /* One of the keypair allocation was wrong */
1127 gnutls_privkey_deinit(issuer_privkey);
1128 return WERR_INVALID_DATA;
1131 keypair.certificate_len = keypair.cert.length;
1132 ndr_err = ndr_push_struct_blob(&blobkeypair,
1135 (ndr_push_flags_fn_t)ndr_push_bkrp_exported_RSA_key_pair);
1136 gnutls_privkey_deinit(issuer_privkey);
1137 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1138 return WERR_INVALID_DATA;
1141 secret_name = talloc_asprintf(mem_ctx, "BCKUPKEY_%s", GUID_string(mem_ctx, &guid));
1142 if (secret_name == NULL) {
1143 return WERR_OUTOFMEMORY;
1146 status = set_lsa_secret(mem_ctx, ldb_ctx, secret_name, &blobkeypair);
1147 if (!NT_STATUS_IS_OK(status)) {
1148 DEBUG(2, ("Failed to save the secret %s\n", secret_name));
1150 talloc_free(secret_name);
1152 GUID_to_ndr_blob(&guid, mem_ctx, &blob);
1153 status = set_lsa_secret(mem_ctx, ldb_ctx, "BCKUPKEY_PREFERRED", &blob);
1154 if (!NT_STATUS_IS_OK(status)) {
1155 DEBUG(2, ("Failed to save the secret BCKUPKEY_PREFERRED\n"));
1161 static WERROR bkrp_retrieve_client_wrap_key(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1162 struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx)
1166 DATA_BLOB lsa_secret;
1167 enum ndr_err_code ndr_err;
1171 * here we basicaly need to return our certificate
1172 * search for lsa secret BCKUPKEY_PREFERRED first
1175 status = get_lsa_secret(mem_ctx,
1177 "BCKUPKEY_PREFERRED",
1179 if (NT_STATUS_EQUAL(status, NT_STATUS_RESOURCE_NAME_NOT_FOUND)) {
1180 /* Ok we can be in this case if there was no certs */
1181 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
1182 char *dn = talloc_asprintf(mem_ctx, "CN=%s",
1183 lpcfg_realm(lp_ctx));
1185 WERROR werr = generate_bkrp_cert(mem_ctx, dce_call, ldb_ctx, dn);
1186 if (!W_ERROR_IS_OK(werr)) {
1187 return WERR_INVALID_PARAMETER;
1189 status = get_lsa_secret(mem_ctx,
1191 "BCKUPKEY_PREFERRED",
1194 if (!NT_STATUS_IS_OK(status)) {
1195 /* Ok we really don't manage to get this certs ...*/
1196 DEBUG(2, ("Unable to locate BCKUPKEY_PREFERRED after cert generation\n"));
1197 return WERR_FILE_NOT_FOUND;
1199 } else if (!NT_STATUS_IS_OK(status)) {
1200 return WERR_INTERNAL_ERROR;
1203 if (lsa_secret.length == 0) {
1204 DEBUG(1, ("No secret in BCKUPKEY_PREFERRED, are we an undetected RODC?\n"));
1205 return WERR_INTERNAL_ERROR;
1207 char *cert_secret_name;
1209 status = GUID_from_ndr_blob(&lsa_secret, &guid);
1210 if (!NT_STATUS_IS_OK(status)) {
1211 return WERR_FILE_NOT_FOUND;
1214 guid_string = GUID_string(mem_ctx, &guid);
1215 if (guid_string == NULL) {
1216 /* We return file not found because the client
1219 return WERR_FILE_NOT_FOUND;
1222 cert_secret_name = talloc_asprintf(mem_ctx,
1225 status = get_lsa_secret(mem_ctx,
1229 if (!NT_STATUS_IS_OK(status)) {
1230 return WERR_FILE_NOT_FOUND;
1233 if (lsa_secret.length != 0) {
1234 struct bkrp_exported_RSA_key_pair keypair;
1235 ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, &keypair,
1236 (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair);
1237 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1238 return WERR_FILE_NOT_FOUND;
1240 *(r->out.data_out_len) = keypair.cert.length;
1241 *(r->out.data_out) = talloc_memdup(mem_ctx, keypair.cert.data, keypair.cert.length);
1242 W_ERROR_HAVE_NO_MEMORY(*(r->out.data_out));
1245 DEBUG(1, ("No or broken secret called %s\n", cert_secret_name));
1246 return WERR_INTERNAL_ERROR;
1250 return WERR_NOT_SUPPORTED;
1253 static WERROR generate_bkrp_server_wrap_key(TALLOC_CTX *ctx, struct ldb_context *ldb_ctx)
1255 struct GUID guid = GUID_random();
1256 enum ndr_err_code ndr_err;
1257 DATA_BLOB blob_wrap_key, guid_blob;
1258 struct bkrp_dc_serverwrap_key wrap_key;
1261 TALLOC_CTX *frame = talloc_stackframe();
1263 generate_random_buffer(wrap_key.key, sizeof(wrap_key.key));
1265 ndr_err = ndr_push_struct_blob(&blob_wrap_key, ctx, &wrap_key, (ndr_push_flags_fn_t)ndr_push_bkrp_dc_serverwrap_key);
1266 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1268 return WERR_INVALID_DATA;
1271 secret_name = talloc_asprintf(frame, "BCKUPKEY_%s", GUID_string(ctx, &guid));
1272 if (secret_name == NULL) {
1274 return WERR_NOT_ENOUGH_MEMORY;
1277 status = set_lsa_secret(frame, ldb_ctx, secret_name, &blob_wrap_key);
1278 if (!NT_STATUS_IS_OK(status)) {
1279 DEBUG(2, ("Failed to save the secret %s\n", secret_name));
1281 return WERR_INTERNAL_ERROR;
1284 status = GUID_to_ndr_blob(&guid, frame, &guid_blob);
1285 if (!NT_STATUS_IS_OK(status)) {
1286 DEBUG(2, ("Failed to save the secret %s\n", secret_name));
1290 status = set_lsa_secret(frame, ldb_ctx, "BCKUPKEY_P", &guid_blob);
1291 if (!NT_STATUS_IS_OK(status)) {
1292 DEBUG(2, ("Failed to save the secret %s\n", secret_name));
1294 return WERR_INTERNAL_ERROR;
1303 * Find the specified decryption keys from the LSA secrets store as
1304 * G$BCKUPKEY_keyGuidString.
1307 static WERROR bkrp_do_retrieve_server_wrap_key(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx,
1308 struct bkrp_dc_serverwrap_key *server_key,
1312 DATA_BLOB lsa_secret;
1315 enum ndr_err_code ndr_err;
1317 guid_string = GUID_string(mem_ctx, guid);
1318 if (guid_string == NULL) {
1319 /* We return file not found because the client
1322 return WERR_FILE_NOT_FOUND;
1325 secret_name = talloc_asprintf(mem_ctx, "BCKUPKEY_%s", guid_string);
1326 if (secret_name == NULL) {
1327 return WERR_NOT_ENOUGH_MEMORY;
1330 status = get_lsa_secret(mem_ctx, ldb_ctx, secret_name, &lsa_secret);
1331 if (!NT_STATUS_IS_OK(status)) {
1332 DEBUG(10, ("Error while fetching secret %s\n", secret_name));
1333 return WERR_INVALID_DATA;
1335 if (lsa_secret.length == 0) {
1336 /* RODC case, we do not have secrets locally */
1337 DEBUG(1, ("Unable to fetch value for secret %s, are we an undetected RODC?\n",
1339 return WERR_INTERNAL_ERROR;
1341 ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, server_key,
1342 (ndr_pull_flags_fn_t)ndr_pull_bkrp_dc_serverwrap_key);
1343 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1344 DEBUG(2, ("Unable to parse the ndr encoded server wrap key %s\n", secret_name));
1345 return WERR_INVALID_DATA;
1352 * Find the current, preferred ServerWrap Key by looking at
1353 * G$BCKUPKEY_P in the LSA secrets store.
1355 * Then find the current decryption keys from the LSA secrets store as
1356 * G$BCKUPKEY_keyGuidString.
1359 static WERROR bkrp_do_retrieve_default_server_wrap_key(TALLOC_CTX *mem_ctx,
1360 struct ldb_context *ldb_ctx,
1361 struct bkrp_dc_serverwrap_key *server_key,
1362 struct GUID *returned_guid)
1365 DATA_BLOB guid_binary;
1367 status = get_lsa_secret(mem_ctx, ldb_ctx, "BCKUPKEY_P", &guid_binary);
1368 if (!NT_STATUS_IS_OK(status)) {
1369 DEBUG(10, ("Error while fetching secret BCKUPKEY_P to find current GUID\n"));
1370 return WERR_FILE_NOT_FOUND;
1371 } else if (guid_binary.length == 0) {
1372 /* RODC case, we do not have secrets locally */
1373 DEBUG(1, ("Unable to fetch value for secret BCKUPKEY_P, are we an undetected RODC?\n"));
1374 return WERR_INTERNAL_ERROR;
1377 status = GUID_from_ndr_blob(&guid_binary, returned_guid);
1378 if (!NT_STATUS_IS_OK(status)) {
1379 return WERR_FILE_NOT_FOUND;
1382 return bkrp_do_retrieve_server_wrap_key(mem_ctx, ldb_ctx,
1383 server_key, returned_guid);
1386 static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1387 struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx)
1390 struct bkrp_server_side_wrapped decrypt_request;
1391 DATA_BLOB sid_blob, encrypted_blob;
1393 enum ndr_err_code ndr_err;
1394 struct bkrp_dc_serverwrap_key server_key;
1395 struct bkrp_rc4encryptedpayload rc4payload;
1396 struct dom_sid *caller_sid;
1397 uint8_t symkey[20]; /* SHA-1 hash len */
1398 uint8_t mackey[20]; /* SHA-1 hash len */
1399 uint8_t mac[20]; /* SHA-1 hash len */
1400 gnutls_hmac_hd_t hmac_hnd;
1401 gnutls_cipher_hd_t cipher_hnd;
1402 gnutls_datum_t cipher_key;
1405 blob.data = r->in.data_in;
1406 blob.length = r->in.data_in_len;
1408 if (r->in.data_in_len == 0 || r->in.data_in == NULL) {
1409 return WERR_INVALID_PARAMETER;
1412 ndr_err = ndr_pull_struct_blob_all(&blob, mem_ctx, &decrypt_request,
1413 (ndr_pull_flags_fn_t)ndr_pull_bkrp_server_side_wrapped);
1414 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1415 return WERR_INVALID_PARAMETER;
1418 if (decrypt_request.magic != BACKUPKEY_SERVER_WRAP_VERSION) {
1419 return WERR_INVALID_PARAMETER;
1422 werr = bkrp_do_retrieve_server_wrap_key(mem_ctx, ldb_ctx, &server_key,
1423 &decrypt_request.guid);
1424 if (!W_ERROR_IS_OK(werr)) {
1428 dump_data_pw("server_key: \n", server_key.key, sizeof(server_key.key));
1430 dump_data_pw("r2: \n", decrypt_request.r2, sizeof(decrypt_request.r2));
1433 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1434 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1437 gnutls_hmac_init(&hmac_hnd,
1440 sizeof(server_key.key));
1441 gnutls_hmac(hmac_hnd,
1443 sizeof(decrypt_request.r2));
1444 gnutls_hmac_output(hmac_hnd, symkey);
1446 dump_data_pw("symkey: \n", symkey, sizeof(symkey));
1448 /* rc4 decrypt sid and secret using sym key */
1449 cipher_key.data = symkey;
1450 cipher_key.size = sizeof(symkey);
1452 encrypted_blob = data_blob_const(decrypt_request.rc4encryptedpayload,
1453 decrypt_request.ciphertext_length);
1455 rc = gnutls_cipher_init(&cipher_hnd,
1456 GNUTLS_CIPHER_ARCFOUR_128,
1459 if (rc != GNUTLS_E_SUCCESS) {
1460 DBG_ERR("gnutls_cipher_init failed - %s\n",
1461 gnutls_strerror(rc));
1462 return WERR_INVALID_PARAMETER;
1464 rc = gnutls_cipher_encrypt2(cipher_hnd,
1465 encrypted_blob.data,
1466 encrypted_blob.length,
1467 encrypted_blob.data,
1468 encrypted_blob.length);
1469 gnutls_cipher_deinit(cipher_hnd);
1470 if (rc != GNUTLS_E_SUCCESS) {
1471 DBG_ERR("gnutls_cipher_encrypt2 failed - %s\n",
1472 gnutls_strerror(rc));
1473 return WERR_INVALID_PARAMETER;
1476 ndr_err = ndr_pull_struct_blob_all(&encrypted_blob, mem_ctx, &rc4payload,
1477 (ndr_pull_flags_fn_t)ndr_pull_bkrp_rc4encryptedpayload);
1478 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1479 return WERR_INVALID_PARAMETER;
1482 if (decrypt_request.payload_length != rc4payload.secret_data.length) {
1483 return WERR_INVALID_PARAMETER;
1486 dump_data_pw("r3: \n", rc4payload.r3, sizeof(rc4payload.r3));
1489 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1490 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1492 gnutls_hmac(hmac_hnd,
1494 sizeof(rc4payload.r3));
1495 gnutls_hmac_deinit(hmac_hnd, mackey);
1497 dump_data_pw("mackey: \n", mackey, sizeof(mackey));
1499 ndr_err = ndr_push_struct_blob(&sid_blob, mem_ctx, &rc4payload.sid,
1500 (ndr_push_flags_fn_t)ndr_push_dom_sid);
1501 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1502 return WERR_INTERNAL_ERROR;
1505 gnutls_hmac_init(&hmac_hnd,
1510 gnutls_hmac(hmac_hnd,
1514 gnutls_hmac(hmac_hnd,
1515 rc4payload.secret_data.data,
1516 rc4payload.secret_data.length);
1517 gnutls_hmac_deinit(hmac_hnd, mac);
1519 dump_data_pw("mac: \n", mac, sizeof(mac));
1520 dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac));
1522 if (memcmp(mac, rc4payload.mac, sizeof(mac)) != 0) {
1523 return WERR_INVALID_ACCESS;
1526 caller_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
1528 if (!dom_sid_equal(&rc4payload.sid, caller_sid)) {
1529 return WERR_INVALID_ACCESS;
1532 *(r->out.data_out) = rc4payload.secret_data.data;
1533 *(r->out.data_out_len) = rc4payload.secret_data.length;
1539 * For BACKUPKEY_RESTORE_GUID we need to check the first 4 bytes to
1540 * determine what type of restore is wanted.
1542 * See MS-BKRP 3.1.4.1.4 BACKUPKEY_RESTORE_GUID point 1.
1545 static WERROR bkrp_generic_decrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1546 struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx)
1548 if (r->in.data_in_len < 4 || r->in.data_in == NULL) {
1549 return WERR_INVALID_PARAMETER;
1552 if (IVAL(r->in.data_in, 0) == BACKUPKEY_SERVER_WRAP_VERSION) {
1553 return bkrp_server_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1556 return bkrp_client_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1560 * We have some data, such as saved website or IMAP passwords that the
1561 * client would like to put into the profile on-disk. This needs to
1562 * be encrypted. This version gives the server the data over the
1563 * network (protected only by the negotiated transport encryption),
1564 * and asks that it be encrypted and returned for long-term storage.
1566 * The data is NOT stored in the LSA, but a key to encrypt the data
1567 * will be stored. There is only one active encryption key per domain,
1568 * it is pointed at with G$BCKUPKEY_P in the LSA secrets store.
1570 * The potentially multiple valid decryptiong keys (and the encryption
1571 * key) are in turn stored in the LSA secrets store as
1572 * G$BCKUPKEY_keyGuidString.
1576 static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1577 struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx)
1579 DATA_BLOB sid_blob, encrypted_blob, server_wrapped_blob;
1581 struct dom_sid *caller_sid;
1582 uint8_t symkey[20]; /* SHA-1 hash len */
1583 uint8_t mackey[20]; /* SHA-1 hash len */
1584 struct bkrp_rc4encryptedpayload rc4payload;
1585 gnutls_hmac_hd_t hmac_hnd;
1586 struct bkrp_dc_serverwrap_key server_key;
1587 enum ndr_err_code ndr_err;
1588 struct bkrp_server_side_wrapped server_side_wrapped;
1590 gnutls_cipher_hd_t cipher_hnd;
1591 gnutls_datum_t cipher_key;
1594 if (r->in.data_in_len == 0 || r->in.data_in == NULL) {
1595 return WERR_INVALID_PARAMETER;
1598 werr = bkrp_do_retrieve_default_server_wrap_key(mem_ctx,
1599 ldb_ctx, &server_key,
1602 if (!W_ERROR_IS_OK(werr)) {
1603 if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
1604 /* Generate the server wrap key since one wasn't found */
1605 werr = generate_bkrp_server_wrap_key(mem_ctx,
1607 if (!W_ERROR_IS_OK(werr)) {
1608 return WERR_INVALID_PARAMETER;
1610 werr = bkrp_do_retrieve_default_server_wrap_key(mem_ctx,
1615 if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
1616 /* Ok we really don't manage to get this secret ...*/
1617 return WERR_FILE_NOT_FOUND;
1620 /* In theory we should NEVER reach this point as it
1621 should only appear in a rodc server */
1622 /* we do not have the real secret attribute */
1623 return WERR_INVALID_PARAMETER;
1627 caller_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
1629 dump_data_pw("server_key: \n", server_key.key, sizeof(server_key.key));
1632 * This is the key derivation step, so that the HMAC and RC4
1633 * operations over the user-supplied data are not able to
1634 * disclose the master key. By using random data, the symkey
1635 * and mackey values are unique for this operation, and
1636 * discovering these (by reversing the RC4 over the
1637 * attacker-controlled data) does not return something able to
1638 * be used to decyrpt the encrypted data of other users
1640 generate_random_buffer(server_side_wrapped.r2, sizeof(server_side_wrapped.r2));
1642 dump_data_pw("r2: \n", server_side_wrapped.r2, sizeof(server_side_wrapped.r2));
1644 generate_random_buffer(rc4payload.r3, sizeof(rc4payload.r3));
1646 dump_data_pw("r3: \n", rc4payload.r3, sizeof(rc4payload.r3));
1650 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1651 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1653 gnutls_hmac_init(&hmac_hnd,
1656 sizeof(server_key.key));
1657 gnutls_hmac(hmac_hnd,
1658 server_side_wrapped.r2,
1659 sizeof(server_side_wrapped.r2));
1660 gnutls_hmac_output(hmac_hnd, symkey);
1662 dump_data_pw("symkey: \n", symkey, sizeof(symkey));
1665 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1666 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1668 gnutls_hmac(hmac_hnd,
1670 sizeof(rc4payload.r3));
1671 gnutls_hmac_deinit(hmac_hnd, mackey);
1673 dump_data_pw("mackey: \n", mackey, sizeof(mackey));
1675 ndr_err = ndr_push_struct_blob(&sid_blob, mem_ctx, caller_sid,
1676 (ndr_push_flags_fn_t)ndr_push_dom_sid);
1677 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1678 return WERR_INTERNAL_ERROR;
1681 rc4payload.secret_data.data = r->in.data_in;
1682 rc4payload.secret_data.length = r->in.data_in_len;
1684 gnutls_hmac_init(&hmac_hnd,
1689 gnutls_hmac(hmac_hnd,
1693 gnutls_hmac(hmac_hnd,
1694 rc4payload.secret_data.data,
1695 rc4payload.secret_data.length);
1696 gnutls_hmac_deinit(hmac_hnd, rc4payload.mac);
1698 dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac));
1700 rc4payload.sid = *caller_sid;
1702 ndr_err = ndr_push_struct_blob(&encrypted_blob, mem_ctx, &rc4payload,
1703 (ndr_push_flags_fn_t)ndr_push_bkrp_rc4encryptedpayload);
1704 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1705 return WERR_INTERNAL_ERROR;
1708 /* rc4 encrypt sid and secret using sym key */
1709 cipher_key.data = symkey;
1710 cipher_key.size = sizeof(symkey);
1712 rc = gnutls_cipher_init(&cipher_hnd,
1713 GNUTLS_CIPHER_ARCFOUR_128,
1716 if (rc != GNUTLS_E_SUCCESS) {
1717 DBG_ERR("gnutls_cipher_init failed - %s\n",
1718 gnutls_strerror(rc));
1719 return WERR_INVALID_PARAMETER;
1721 rc = gnutls_cipher_encrypt2(cipher_hnd,
1722 encrypted_blob.data,
1723 encrypted_blob.length,
1724 encrypted_blob.data,
1725 encrypted_blob.length);
1726 gnutls_cipher_deinit(cipher_hnd);
1727 if (rc != GNUTLS_E_SUCCESS) {
1728 DBG_ERR("gnutls_cipher_encrypt2 failed - %s\n",
1729 gnutls_strerror(rc));
1730 return WERR_INVALID_PARAMETER;
1733 /* create server wrap structure */
1735 server_side_wrapped.payload_length = rc4payload.secret_data.length;
1736 server_side_wrapped.ciphertext_length = encrypted_blob.length;
1737 server_side_wrapped.guid = guid;
1738 server_side_wrapped.rc4encryptedpayload = encrypted_blob.data;
1740 ndr_err = ndr_push_struct_blob(&server_wrapped_blob, mem_ctx, &server_side_wrapped,
1741 (ndr_push_flags_fn_t)ndr_push_bkrp_server_side_wrapped);
1742 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1743 return WERR_INTERNAL_ERROR;
1746 *(r->out.data_out) = server_wrapped_blob.data;
1747 *(r->out.data_out_len) = server_wrapped_blob.length;
1752 static WERROR dcesrv_bkrp_BackupKey(struct dcesrv_call_state *dce_call,
1753 TALLOC_CTX *mem_ctx, struct bkrp_BackupKey *r)
1755 WERROR error = WERR_INVALID_PARAMETER;
1756 struct ldb_context *ldb_ctx;
1758 const char *addr = "unknown";
1759 /* At which level we start to add more debug of what is done in the protocol */
1760 const int debuglevel = 4;
1762 gnutls_global_init();
1764 if (DEBUGLVL(debuglevel)) {
1765 const struct tsocket_address *remote_address;
1766 remote_address = dcesrv_connection_get_remote_address(dce_call->conn);
1767 if (tsocket_address_is_inet(remote_address, "ip")) {
1768 addr = tsocket_address_inet_addr_string(remote_address, mem_ctx);
1769 W_ERROR_HAVE_NO_MEMORY(addr);
1773 if (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC) {
1774 return WERR_NOT_SUPPORTED;
1777 ldb_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
1778 dce_call->conn->dce_ctx->lp_ctx,
1779 system_session(dce_call->conn->dce_ctx->lp_ctx), 0);
1781 if (samdb_rodc(ldb_ctx, &is_rodc) != LDB_SUCCESS) {
1782 talloc_unlink(mem_ctx, ldb_ctx);
1783 return WERR_INVALID_PARAMETER;
1787 if(strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1788 BACKUPKEY_RESTORE_GUID, strlen(BACKUPKEY_RESTORE_GUID)) == 0) {
1789 DEBUG(debuglevel, ("Client %s requested to decrypt a wrapped secret\n", addr));
1790 error = bkrp_generic_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1793 if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1794 BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID, strlen(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID)) == 0) {
1795 DEBUG(debuglevel, ("Client %s requested certificate for client wrapped secret\n", addr));
1796 error = bkrp_retrieve_client_wrap_key(dce_call, mem_ctx, r, ldb_ctx);
1799 if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1800 BACKUPKEY_RESTORE_GUID_WIN2K, strlen(BACKUPKEY_RESTORE_GUID_WIN2K)) == 0) {
1801 DEBUG(debuglevel, ("Client %s requested to decrypt a server side wrapped secret\n", addr));
1802 error = bkrp_server_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1805 if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
1806 BACKUPKEY_BACKUP_GUID, strlen(BACKUPKEY_BACKUP_GUID)) == 0) {
1807 DEBUG(debuglevel, ("Client %s requested a server wrapped secret\n", addr));
1808 error = bkrp_server_wrap_encrypt_data(dce_call, mem_ctx, r, ldb_ctx);
1811 /*else: I am a RODC so I don't handle backup key protocol */
1813 gnutls_global_deinit();
1814 talloc_unlink(mem_ctx, ldb_ctx);
1818 /* include the generated boilerplate */
1819 #include "librpc/gen_ndr/ndr_backupkey_s.c"