2 Unix SMB/CIFS implementation.
4 endpoint server for the backupkey interface
6 Copyright (C) Matthieu Patou <mat@samba.org> 2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "rpc_server/dcerpc_server.h"
24 #include "librpc/gen_ndr/ndr_backupkey.h"
25 #include "dsdb/common/util.h"
26 #include "dsdb/samdb/samdb.h"
27 #include "lib/ldb/include/ldb_errors.h"
28 #include "../lib/util/util_ldb.h"
29 #include "param/param.h"
30 #include "auth/session.h"
31 #include "system/network.h"
34 #include <hcrypto/rsa.h>
35 #include <hcrypto/bn.h>
36 #include <hcrypto/sha.h>
37 #include <hcrypto/evp.h>
38 #include <hcrypto/hmac.h>
40 #include "../lib/tsocket/tsocket.h"
41 #include "../libcli/security/security.h"
42 #include "librpc/gen_ndr/ndr_security.h"
43 #include "lib/crypto/arcfour.h"
45 #define BACKUPKEY_MIN_VERSION 2
46 #define BACKUPKEY_MAX_VERSION 3
48 static const unsigned rsa_with_var_num
[] = { 1, 2, 840, 113549, 1, 1, 1 };
49 /* Equivalent to asn1_oid_id_pkcs1_rsaEncryption*/
50 static const AlgorithmIdentifier _hx509_signature_rsa_with_var_num
= {
51 { 7, discard_const_p(unsigned, rsa_with_var_num
) }, NULL
54 static NTSTATUS
set_lsa_secret(TALLOC_CTX
*mem_ctx
,
55 struct ldb_context
*ldb
,
57 const DATA_BLOB
*lsa_secret
)
59 struct ldb_message
*msg
;
60 struct ldb_result
*res
;
61 struct ldb_dn
*domain_dn
;
62 struct ldb_dn
*system_dn
;
66 struct timeval now
= timeval_current();
67 NTTIME nt_now
= timeval_to_nttime(&now
);
68 const char *attrs
[] = {
72 domain_dn
= ldb_get_default_basedn(ldb
);
74 return NT_STATUS_INTERNAL_ERROR
;
77 msg
= ldb_msg_new(mem_ctx
);
79 return NT_STATUS_NO_MEMORY
;
83 * This function is a lot like dcesrv_lsa_CreateSecret
84 * in the rpc_server/lsa directory
85 * The reason why we duplicate the effort here is that:
86 * * we want to keep the former function static
87 * * we want to avoid the burden of doing LSA calls
88 * when we can just manipulate the secrets directly
89 * * taillor the function to the particular needs of backup protocol
92 system_dn
= samdb_search_dn(ldb
, msg
, domain_dn
, "(&(objectClass=container)(cn=System))");
93 if (system_dn
== NULL
) {
95 return NT_STATUS_NO_MEMORY
;
98 name2
= talloc_asprintf(msg
, "%s Secret", name
);
101 return NT_STATUS_NO_MEMORY
;
104 ret
= ldb_search(ldb
, mem_ctx
, &res
, system_dn
, LDB_SCOPE_SUBTREE
, attrs
,
105 "(&(cn=%s)(objectclass=secret))",
106 ldb_binary_encode_string(mem_ctx
, name2
));
108 if (ret
!= LDB_SUCCESS
|| res
->count
!= 0 ) {
109 DEBUG(2, ("Secret %s already exists !\n", name2
));
111 return NT_STATUS_OBJECT_NAME_COLLISION
;
115 * We don't care about previous value as we are
116 * here only if the key didn't exists before
119 msg
->dn
= ldb_dn_copy(mem_ctx
, system_dn
);
120 if (msg
->dn
== NULL
) {
122 return NT_STATUS_NO_MEMORY
;
124 if (!ldb_dn_add_child_fmt(msg
->dn
, "cn=%s", name2
)) {
126 return NT_STATUS_NO_MEMORY
;
129 ret
= ldb_msg_add_string(msg
, "cn", name2
);
130 if (ret
!= LDB_SUCCESS
) {
132 return NT_STATUS_NO_MEMORY
;
134 ret
= ldb_msg_add_string(msg
, "objectClass", "secret");
135 if (ret
!= LDB_SUCCESS
) {
137 return NT_STATUS_NO_MEMORY
;
139 ret
= samdb_msg_add_uint64(ldb
, mem_ctx
, msg
, "priorSetTime", nt_now
);
140 if (ret
!= LDB_SUCCESS
) {
142 return NT_STATUS_NO_MEMORY
;
144 val
.data
= lsa_secret
->data
;
145 val
.length
= lsa_secret
->length
;
146 ret
= ldb_msg_add_value(msg
, "currentValue", &val
, NULL
);
147 if (ret
!= LDB_SUCCESS
) {
149 return NT_STATUS_NO_MEMORY
;
151 ret
= samdb_msg_add_uint64(ldb
, mem_ctx
, msg
, "lastSetTime", nt_now
);
152 if (ret
!= LDB_SUCCESS
) {
154 return NT_STATUS_NO_MEMORY
;
158 * create the secret with DSDB_MODIFY_RELAX
159 * otherwise dsdb/samdb/ldb_modules/objectclass.c forbid
160 * the create of LSA secret object
162 ret
= dsdb_add(ldb
, msg
, DSDB_MODIFY_RELAX
);
163 if (ret
!= LDB_SUCCESS
) {
164 DEBUG(2,("Failed to create secret record %s: %s\n",
165 ldb_dn_get_linearized(msg
->dn
),
166 ldb_errstring(ldb
)));
168 return NT_STATUS_ACCESS_DENIED
;
175 /* This function is pretty much like dcesrv_lsa_QuerySecret */
176 static NTSTATUS
get_lsa_secret(TALLOC_CTX
*mem_ctx
,
177 struct ldb_context
*ldb
,
179 DATA_BLOB
*lsa_secret
)
182 struct ldb_result
*res
;
183 struct ldb_dn
*domain_dn
;
184 struct ldb_dn
*system_dn
;
185 const struct ldb_val
*val
;
187 const char *attrs
[] = {
193 lsa_secret
->data
= NULL
;
194 lsa_secret
->length
= 0;
196 domain_dn
= ldb_get_default_basedn(ldb
);
198 return NT_STATUS_INTERNAL_ERROR
;
201 tmp_mem
= talloc_new(mem_ctx
);
202 if (tmp_mem
== NULL
) {
203 return NT_STATUS_NO_MEMORY
;
206 system_dn
= samdb_search_dn(ldb
, tmp_mem
, domain_dn
, "(&(objectClass=container)(cn=System))");
207 if (system_dn
== NULL
) {
208 talloc_free(tmp_mem
);
209 return NT_STATUS_NO_MEMORY
;
212 ret
= ldb_search(ldb
, mem_ctx
, &res
, system_dn
, LDB_SCOPE_SUBTREE
, attrs
,
213 "(&(cn=%s Secret)(objectclass=secret))",
214 ldb_binary_encode_string(tmp_mem
, name
));
216 if (ret
!= LDB_SUCCESS
) {
217 talloc_free(tmp_mem
);
218 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
219 } else if (res
->count
== 0) {
220 return NT_STATUS_RESOURCE_NAME_NOT_FOUND
;
221 } else if (res
->count
> 1) {
222 DEBUG(2, ("Secret %s collision\n", name
));
223 talloc_free(tmp_mem
);
224 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
227 val
= ldb_msg_find_ldb_val(res
->msgs
[0], "currentValue");
230 * The secret object is here but we don't have the secret value
231 * The most common case is a RODC
233 *lsa_secret
= data_blob_null
;
234 talloc_free(tmp_mem
);
239 lsa_secret
->data
= talloc_move(mem_ctx
, &data
);
240 lsa_secret
->length
= val
->length
;
242 talloc_free(tmp_mem
);
246 static DATA_BLOB
*reverse_and_get_blob(TALLOC_CTX
*mem_ctx
, BIGNUM
*bn
)
249 DATA_BLOB
*rev
= talloc(mem_ctx
, DATA_BLOB
);
252 blob
.length
= BN_num_bytes(bn
);
253 blob
.data
= talloc_array(mem_ctx
, uint8_t, blob
.length
);
255 if (blob
.data
== NULL
) {
259 BN_bn2bin(bn
, blob
.data
);
261 rev
->data
= talloc_array(mem_ctx
, uint8_t, blob
.length
);
262 if (rev
->data
== NULL
) {
266 for(i
=0; i
< blob
.length
; i
++) {
267 rev
->data
[i
] = blob
.data
[blob
.length
- i
-1];
269 rev
->length
= blob
.length
;
270 talloc_free(blob
.data
);
274 static BIGNUM
*reverse_and_get_bignum(TALLOC_CTX
*mem_ctx
, DATA_BLOB
*blob
)
280 rev
.data
= talloc_array(mem_ctx
, uint8_t, blob
->length
);
281 if (rev
.data
== NULL
) {
285 for(i
=0; i
< blob
->length
; i
++) {
286 rev
.data
[i
] = blob
->data
[blob
->length
- i
-1];
288 rev
.length
= blob
->length
;
290 ret
= BN_bin2bn(rev
.data
, rev
.length
, NULL
);
291 talloc_free(rev
.data
);
296 static NTSTATUS
get_pk_from_raw_keypair_params(TALLOC_CTX
*ctx
,
297 struct bkrp_exported_RSA_key_pair
*keypair
,
298 hx509_private_key
*pk
)
302 struct hx509_private_key_ops
*ops
;
304 hx509_context_init(&hctx
);
305 ops
= hx509_find_private_alg(&_hx509_signature_rsa_with_var_num
.algorithm
);
307 DEBUG(2, ("Not supported algorithm\n"));
308 return NT_STATUS_INTERNAL_ERROR
;
311 if (hx509_private_key_init(pk
, ops
, NULL
) != 0) {
312 hx509_context_free(&hctx
);
313 return NT_STATUS_NO_MEMORY
;
318 hx509_context_free(&hctx
);
319 return NT_STATUS_INVALID_PARAMETER
;
322 rsa
->n
= reverse_and_get_bignum(ctx
, &(keypair
->modulus
));
323 if (rsa
->n
== NULL
) {
325 hx509_context_free(&hctx
);
326 return NT_STATUS_INVALID_PARAMETER
;
328 rsa
->d
= reverse_and_get_bignum(ctx
, &(keypair
->private_exponent
));
329 if (rsa
->d
== NULL
) {
331 hx509_context_free(&hctx
);
332 return NT_STATUS_INVALID_PARAMETER
;
334 rsa
->p
= reverse_and_get_bignum(ctx
, &(keypair
->prime1
));
335 if (rsa
->p
== NULL
) {
337 hx509_context_free(&hctx
);
338 return NT_STATUS_INVALID_PARAMETER
;
340 rsa
->q
= reverse_and_get_bignum(ctx
, &(keypair
->prime2
));
341 if (rsa
->q
== NULL
) {
343 hx509_context_free(&hctx
);
344 return NT_STATUS_INVALID_PARAMETER
;
346 rsa
->dmp1
= reverse_and_get_bignum(ctx
, &(keypair
->exponent1
));
347 if (rsa
->dmp1
== NULL
) {
349 hx509_context_free(&hctx
);
350 return NT_STATUS_INVALID_PARAMETER
;
352 rsa
->dmq1
= reverse_and_get_bignum(ctx
, &(keypair
->exponent2
));
353 if (rsa
->dmq1
== NULL
) {
355 hx509_context_free(&hctx
);
356 return NT_STATUS_INVALID_PARAMETER
;
358 rsa
->iqmp
= reverse_and_get_bignum(ctx
, &(keypair
->coefficient
));
359 if (rsa
->iqmp
== NULL
) {
361 hx509_context_free(&hctx
);
362 return NT_STATUS_INVALID_PARAMETER
;
364 rsa
->e
= reverse_and_get_bignum(ctx
, &(keypair
->public_exponent
));
365 if (rsa
->e
== NULL
) {
367 hx509_context_free(&hctx
);
368 return NT_STATUS_INVALID_PARAMETER
;
371 hx509_private_key_assign_rsa(*pk
, rsa
);
373 hx509_context_free(&hctx
);
377 static WERROR
get_and_verify_access_check(TALLOC_CTX
*sub_ctx
,
380 uint8_t *access_check
,
381 uint32_t access_check_len
,
382 struct auth_session_info
*session_info
)
384 heim_octet_string iv
;
385 heim_octet_string access_check_os
;
392 enum ndr_err_code ndr_err
;
395 struct dom_sid
*access_sid
= NULL
;
396 struct dom_sid
*caller_sid
= NULL
;
398 /* This one should not be freed */
399 const AlgorithmIdentifier
*alg
;
405 alg
= hx509_crypto_des_rsdi_ede3_cbc();
411 alg
=hx509_crypto_aes256_cbc();
415 return WERR_INVALID_DATA
;
418 hx509_context_init(&hctx
);
419 res
= hx509_crypto_init(hctx
, NULL
,
422 hx509_context_free(&hctx
);
425 return WERR_INVALID_DATA
;
428 res
= hx509_crypto_set_key_data(crypto
, key_and_iv
, key_len
);
430 iv
.data
= talloc_memdup(sub_ctx
, key_len
+ key_and_iv
, iv_len
);
434 hx509_crypto_destroy(crypto
);
435 return WERR_INVALID_DATA
;
438 hx509_crypto_set_padding(crypto
, HX509_CRYPTO_PADDING_NONE
);
439 res
= hx509_crypto_decrypt(crypto
,
446 hx509_crypto_destroy(crypto
);
447 return WERR_INVALID_DATA
;
450 blob_us
.data
= access_check_os
.data
;
451 blob_us
.length
= access_check_os
.length
;
453 hx509_crypto_destroy(crypto
);
458 uint32_t hash_size
= 20;
459 uint8_t hash
[hash_size
];
461 struct bkrp_access_check_v2 uncrypted_accesscheckv2
;
463 ndr_err
= ndr_pull_struct_blob(&blob_us
, sub_ctx
, &uncrypted_accesscheckv2
,
464 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_access_check_v2
);
465 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
466 /* Unable to unmarshall */
467 der_free_octet_string(&access_check_os
);
468 return WERR_INVALID_DATA
;
470 if (uncrypted_accesscheckv2
.magic
!= 0x1) {
472 der_free_octet_string(&access_check_os
);
473 return WERR_INVALID_DATA
;
477 SHA1_Update(&sctx
, blob_us
.data
, blob_us
.length
- hash_size
);
478 SHA1_Final(hash
, &sctx
);
479 der_free_octet_string(&access_check_os
);
481 * We free it after the sha1 calculation because blob.data
482 * point to the same area
485 if (memcmp(hash
, uncrypted_accesscheckv2
.hash
, hash_size
) != 0) {
486 DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
487 return WERR_INVALID_DATA
;
489 access_sid
= &(uncrypted_accesscheckv2
.sid
);
494 uint32_t hash_size
= 64;
495 uint8_t hash
[hash_size
];
496 struct hc_sha512state sctx
;
497 struct bkrp_access_check_v3 uncrypted_accesscheckv3
;
499 ndr_err
= ndr_pull_struct_blob(&blob_us
, sub_ctx
, &uncrypted_accesscheckv3
,
500 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_access_check_v3
);
501 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
502 /* Unable to unmarshall */
503 der_free_octet_string(&access_check_os
);
504 return WERR_INVALID_DATA
;
506 if (uncrypted_accesscheckv3
.magic
!= 0x1) {
508 der_free_octet_string(&access_check_os
);
509 return WERR_INVALID_DATA
;
513 SHA512_Update(&sctx
, blob_us
.data
, blob_us
.length
- hash_size
);
514 SHA512_Final(hash
, &sctx
);
515 der_free_octet_string(&access_check_os
);
517 * We free it after the sha1 calculation because blob.data
518 * point to the same area
521 if (memcmp(hash
, uncrypted_accesscheckv3
.hash
, hash_size
) != 0) {
522 DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
523 return WERR_INVALID_DATA
;
525 access_sid
= &(uncrypted_accesscheckv3
.sid
);
529 /* Never reached normally as we filtered at the switch / case level */
530 return WERR_INVALID_DATA
;
533 caller_sid
= &session_info
->security_token
->sids
[PRIMARY_USER_SID_INDEX
];
535 if (!dom_sid_equal(caller_sid
, access_sid
)) {
536 return WERR_INVALID_ACCESS
;
542 * We have some data, such as saved website or IMAP passwords that the
543 * client has in profile on-disk. This needs to be decrypted. This
544 * version gives the server the data over the network (protected by
545 * the X.509 certificate and public key encryption, and asks that it
546 * be decrypted returned for short-term use, protected only by the
547 * negotiated transport encryption.
549 * The data is NOT stored in the LSA, but a X.509 certificate, public
550 * and private keys used to encrypt the data will be stored. There is
551 * only one active encryption key pair and certificate per domain, it
552 * is pointed at with G$BCKUPKEY_PREFERRED in the LSA secrets store.
554 * The potentially multiple valid decrypting key pairs are in turn
555 * stored in the LSA secrets store as G$BCKUPKEY_keyGuidString.
558 static WERROR
bkrp_client_wrap_decrypt_data(struct dcesrv_call_state
*dce_call
,
560 struct bkrp_BackupKey
*r
,
561 struct ldb_context
*ldb_ctx
)
563 struct bkrp_client_side_wrapped uncrypt_request
;
565 enum ndr_err_code ndr_err
;
567 char *cert_secret_name
;
568 DATA_BLOB lsa_secret
;
569 DATA_BLOB
*uncrypted_data
;
572 blob
.data
= r
->in
.data_in
;
573 blob
.length
= r
->in
.data_in_len
;
575 if (r
->in
.data_in_len
== 0 || r
->in
.data_in
== NULL
) {
576 return WERR_INVALID_PARAM
;
579 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &uncrypt_request
,
580 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_wrapped
);
581 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
582 return WERR_INVALID_PARAM
;
585 if (uncrypt_request
.version
< BACKUPKEY_MIN_VERSION
) {
586 return WERR_INVALID_PARAMETER
;
589 if (uncrypt_request
.version
> BACKUPKEY_MAX_VERSION
) {
590 return WERR_INVALID_PARAMETER
;
593 guid_string
= GUID_string(mem_ctx
, &uncrypt_request
.guid
);
594 if (guid_string
== NULL
) {
598 cert_secret_name
= talloc_asprintf(mem_ctx
,
601 if (cert_secret_name
== NULL
) {
605 status
= get_lsa_secret(mem_ctx
,
609 if (!NT_STATUS_IS_OK(status
)) {
610 DEBUG(10, ("Error while fetching secret %s\n", cert_secret_name
));
611 return WERR_FILE_NOT_FOUND
;
612 } else if (lsa_secret
.length
== 0) {
613 /* we do not have the real secret attribute, like if we are an RODC */
614 return WERR_INVALID_PARAMETER
;
617 struct bkrp_exported_RSA_key_pair keypair
;
618 hx509_private_key pk
;
620 heim_octet_string reversed_secret
;
621 heim_octet_string uncrypted_secret
;
622 AlgorithmIdentifier alg
;
626 ndr_err
= ndr_pull_struct_blob(&lsa_secret
, mem_ctx
, &keypair
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_exported_RSA_key_pair
);
627 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
628 DEBUG(2, ("Unable to parse the ndr encoded cert in key %s\n", cert_secret_name
));
629 return WERR_FILE_NOT_FOUND
;
632 status
= get_pk_from_raw_keypair_params(mem_ctx
, &keypair
, &pk
);
633 if (!NT_STATUS_IS_OK(status
)) {
634 return WERR_INTERNAL_ERROR
;
637 reversed_secret
.data
= talloc_array(mem_ctx
, uint8_t,
638 uncrypt_request
.encrypted_secret_len
);
639 if (reversed_secret
.data
== NULL
) {
640 hx509_private_key_free(&pk
);
644 /* The secret has to be reversed ... */
645 for(i
=0; i
< uncrypt_request
.encrypted_secret_len
; i
++) {
646 uint8_t *reversed
= (uint8_t *)reversed_secret
.data
;
647 uint8_t *uncrypt
= uncrypt_request
.encrypted_secret
;
648 reversed
[i
] = uncrypt
[uncrypt_request
.encrypted_secret_len
- 1 - i
];
650 reversed_secret
.length
= uncrypt_request
.encrypted_secret_len
;
653 * Let's try to decrypt the secret now that
654 * we have the private key ...
656 hx509_context_init(&hctx
);
657 res
= hx509_private_key_private_decrypt(hctx
, &reversed_secret
,
660 hx509_context_free(&hctx
);
661 hx509_private_key_free(&pk
);
663 /* We are not able to decrypt the secret, looks like something is wrong */
664 return WERR_INVALID_DATA
;
666 blob_us
.data
= uncrypted_secret
.data
;
667 blob_us
.length
= uncrypted_secret
.length
;
669 if (uncrypt_request
.version
== 2) {
670 struct bkrp_encrypted_secret_v2 uncrypted_secretv2
;
672 ndr_err
= ndr_pull_struct_blob(&blob_us
, mem_ctx
, &uncrypted_secretv2
,
673 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_encrypted_secret_v2
);
674 der_free_octet_string(&uncrypted_secret
);
675 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
676 /* Unable to unmarshall */
677 return WERR_INVALID_DATA
;
679 if (uncrypted_secretv2
.magic
!= 0x20) {
681 return WERR_INVALID_DATA
;
684 werr
= get_and_verify_access_check(mem_ctx
, 2,
685 uncrypted_secretv2
.payload_key
,
686 uncrypt_request
.access_check
,
687 uncrypt_request
.access_check_len
,
688 dce_call
->conn
->auth_state
.session_info
);
689 if (!W_ERROR_IS_OK(werr
)) {
692 uncrypted_data
= talloc(mem_ctx
, DATA_BLOB
);
693 if (uncrypted_data
== NULL
) {
694 return WERR_INVALID_DATA
;
697 uncrypted_data
->data
= uncrypted_secretv2
.secret
;
698 uncrypted_data
->length
= uncrypted_secretv2
.secret_len
;
700 if (uncrypt_request
.version
== 3) {
701 struct bkrp_encrypted_secret_v3 uncrypted_secretv3
;
703 ndr_err
= ndr_pull_struct_blob(&blob_us
, mem_ctx
, &uncrypted_secretv3
,
704 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_encrypted_secret_v3
);
706 der_free_octet_string(&uncrypted_secret
);
707 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
708 /* Unable to unmarshall */
709 return WERR_INVALID_DATA
;
712 if (uncrypted_secretv3
.magic1
!= 0x30 ||
713 uncrypted_secretv3
.magic2
!= 0x6610 ||
714 uncrypted_secretv3
.magic3
!= 0x800e) {
716 return WERR_INVALID_DATA
;
720 * Confirm that the caller is permitted to
721 * read this particular data. Because one key
722 * pair is used per domain, the caller could
723 * have stolen the profile data on-disk and
724 * would otherwise be able to read the
728 werr
= get_and_verify_access_check(mem_ctx
, 3,
729 uncrypted_secretv3
.payload_key
,
730 uncrypt_request
.access_check
,
731 uncrypt_request
.access_check_len
,
732 dce_call
->conn
->auth_state
.session_info
);
733 if (!W_ERROR_IS_OK(werr
)) {
737 uncrypted_data
= talloc(mem_ctx
, DATA_BLOB
);
738 if (uncrypted_data
== NULL
) {
739 return WERR_INVALID_DATA
;
742 uncrypted_data
->data
= uncrypted_secretv3
.secret
;
743 uncrypted_data
->length
= uncrypted_secretv3
.secret_len
;
747 * Yeah if we are here all looks pretty good:
749 * - user sid is the same as the one in access check
750 * - we were able to decrypt the whole stuff
754 if (uncrypted_data
->data
== NULL
) {
755 return WERR_INVALID_DATA
;
758 /* There is a magic value a the beginning of the data
759 * we can use an adhoc structure but as the
760 * parent structure is just an array of bytes it a lot of work
761 * work just prepending 4 bytes
763 *(r
->out
.data_out
) = talloc_zero_array(mem_ctx
, uint8_t, uncrypted_data
->length
+ 4);
764 W_ERROR_HAVE_NO_MEMORY(*(r
->out
.data_out
));
765 memcpy(4+*(r
->out
.data_out
), uncrypted_data
->data
, uncrypted_data
->length
);
766 *(r
->out
.data_out_len
) = uncrypted_data
->length
+ 4;
771 static WERROR
create_heimdal_rsa_key(TALLOC_CTX
*ctx
, hx509_context
*hctx
,
772 hx509_private_key
*pk
, RSA
**_rsa
)
780 int RSA_returned_bits
;
785 if(pub_expo
== NULL
) {
786 return WERR_INTERNAL_ERROR
;
789 /* set the public expo to 65537 like everyone */
790 BN_set_word(pub_expo
, 0x10001);
795 return WERR_INTERNAL_ERROR
;
798 while (RSA_returned_bits
!= bits
) {
799 ret
= RSA_generate_key_ex(rsa
, bits
, pub_expo
, NULL
);
803 return WERR_INTERNAL_ERROR
;
805 RSA_returned_bits
= BN_num_bits(rsa
->n
);
806 DEBUG(6, ("RSA_generate_key_ex returned %d Bits\n", RSA_returned_bits
));
810 len
= i2d_RSAPrivateKey(rsa
, NULL
);
813 return WERR_INTERNAL_ERROR
;
816 p0
= p
= talloc_array(ctx
, uint8_t, len
);
819 return WERR_INTERNAL_ERROR
;
822 len
= i2d_RSAPrivateKey(rsa
, &p
);
826 return WERR_INTERNAL_ERROR
;
830 * To dump the key we can use :
831 * rk_dumpdata("h5lkey", p0, len);
833 ret
= hx509_parse_private_key(*hctx
, &_hx509_signature_rsa_with_var_num
,
834 p0
, len
, HX509_KEY_FORMAT_DER
, pk
);
839 return WERR_INTERNAL_ERROR
;
846 static WERROR
self_sign_cert(TALLOC_CTX
*ctx
, hx509_context
*hctx
, hx509_request
*req
,
847 time_t lifetime
, hx509_private_key
*private_key
,
848 hx509_cert
*cert
, DATA_BLOB
*guidblob
)
850 SubjectPublicKeyInfo spki
;
851 hx509_name subject
= NULL
;
853 struct heim_bit_string uniqueid
;
854 struct heim_integer serialnumber
;
857 uniqueid
.data
= talloc_memdup(ctx
, guidblob
->data
, guidblob
->length
);
858 if (uniqueid
.data
== NULL
) {
861 /* uniqueid is a bit string in which each byte represent 1 bit (1 or 0)
862 * so as 1 byte is 8 bits we need to provision 8 times more space as in the
865 uniqueid
.length
= 8 * guidblob
->length
;
867 serialnumber
.data
= talloc_array(ctx
, uint8_t,
869 if (serialnumber
.data
== NULL
) {
870 talloc_free(uniqueid
.data
);
874 /* Native AD generates certificates with serialnumber in reversed notation */
875 for (i
= 0; i
< guidblob
->length
; i
++) {
876 uint8_t *reversed
= (uint8_t *)serialnumber
.data
;
877 uint8_t *uncrypt
= guidblob
->data
;
878 reversed
[i
] = uncrypt
[guidblob
->length
- 1 - i
];
880 serialnumber
.length
= guidblob
->length
;
881 serialnumber
.negative
= 0;
883 memset(&spki
, 0, sizeof(spki
));
885 ret
= hx509_request_get_name(*hctx
, *req
, &subject
);
889 ret
= hx509_request_get_SubjectPublicKeyInfo(*hctx
, *req
, &spki
);
894 ret
= hx509_ca_tbs_init(*hctx
, &tbs
);
899 ret
= hx509_ca_tbs_set_spki(*hctx
, tbs
, &spki
);
903 ret
= hx509_ca_tbs_set_subject(*hctx
, tbs
, subject
);
907 ret
= hx509_ca_tbs_set_ca(*hctx
, tbs
, 1);
911 ret
= hx509_ca_tbs_set_notAfter_lifetime(*hctx
, tbs
, lifetime
);
915 ret
= hx509_ca_tbs_set_unique(*hctx
, tbs
, &uniqueid
, &uniqueid
);
919 ret
= hx509_ca_tbs_set_serialnumber(*hctx
, tbs
, &serialnumber
);
923 ret
= hx509_ca_sign_self(*hctx
, tbs
, *private_key
, cert
);
927 hx509_name_free(&subject
);
928 free_SubjectPublicKeyInfo(&spki
);
929 hx509_ca_tbs_free(&tbs
);
934 hx509_ca_tbs_free(&tbs
);
936 free_SubjectPublicKeyInfo(&spki
);
938 hx509_name_free(&subject
);
940 talloc_free(uniqueid
.data
);
941 talloc_free(serialnumber
.data
);
942 return WERR_INTERNAL_ERROR
;
945 static WERROR
create_req(TALLOC_CTX
*ctx
, hx509_context
*hctx
, hx509_request
*req
,
946 hx509_private_key
*signer
,RSA
**rsa
, const char *dn
)
949 SubjectPublicKeyInfo key
;
954 werr
= create_heimdal_rsa_key(ctx
, hctx
, signer
, rsa
);
955 if (!W_ERROR_IS_OK(werr
)) {
959 hx509_request_init(*hctx
, req
);
960 ret
= hx509_parse_name(*hctx
, dn
, &name
);
963 hx509_private_key_free(signer
);
964 hx509_request_free(req
);
965 hx509_name_free(&name
);
966 return WERR_INTERNAL_ERROR
;
969 ret
= hx509_request_set_name(*hctx
, *req
, name
);
972 hx509_private_key_free(signer
);
973 hx509_request_free(req
);
974 hx509_name_free(&name
);
975 return WERR_INTERNAL_ERROR
;
977 hx509_name_free(&name
);
979 ret
= hx509_private_key2SPKI(*hctx
, *signer
, &key
);
982 hx509_private_key_free(signer
);
983 hx509_request_free(req
);
984 return WERR_INTERNAL_ERROR
;
986 ret
= hx509_request_set_SubjectPublicKeyInfo(*hctx
, *req
, &key
);
989 hx509_private_key_free(signer
);
990 free_SubjectPublicKeyInfo(&key
);
991 hx509_request_free(req
);
992 return WERR_INTERNAL_ERROR
;
995 free_SubjectPublicKeyInfo(&key
);
1000 /* Return an error when we fail to generate a certificate */
1001 static WERROR
generate_bkrp_cert(TALLOC_CTX
*ctx
, struct dcesrv_call_state
*dce_call
, struct ldb_context
*ldb_ctx
, const char *dn
)
1003 heim_octet_string data
;
1007 hx509_private_key pk
;
1011 DATA_BLOB blobkeypair
;
1015 struct GUID guid
= GUID_random();
1018 struct bkrp_exported_RSA_key_pair keypair
;
1019 enum ndr_err_code ndr_err
;
1020 uint32_t nb_seconds_validity
= 3600 * 24 * 365;
1022 DEBUG(6, ("Trying to generate a certificate\n"));
1023 hx509_context_init(&hctx
);
1024 werr
= create_req(ctx
, &hctx
, &req
, &pk
, &rsa
, dn
);
1025 if (!W_ERROR_IS_OK(werr
)) {
1026 hx509_context_free(&hctx
);
1030 status
= GUID_to_ndr_blob(&guid
, ctx
, &blob
);
1031 if (!NT_STATUS_IS_OK(status
)) {
1032 hx509_context_free(&hctx
);
1033 hx509_private_key_free(&pk
);
1035 return WERR_INVALID_DATA
;
1038 werr
= self_sign_cert(ctx
, &hctx
, &req
, nb_seconds_validity
, &pk
, &cert
, &blob
);
1039 if (!W_ERROR_IS_OK(werr
)) {
1040 hx509_private_key_free(&pk
);
1041 hx509_context_free(&hctx
);
1042 return WERR_INVALID_DATA
;
1045 ret
= hx509_cert_binary(hctx
, cert
, &data
);
1047 hx509_cert_free(cert
);
1048 hx509_private_key_free(&pk
);
1049 hx509_context_free(&hctx
);
1050 return WERR_INVALID_DATA
;
1053 keypair
.cert
.data
= talloc_memdup(ctx
, data
.data
, data
.length
);
1054 keypair
.cert
.length
= data
.length
;
1057 * Heimdal's bignum are big endian and the
1058 * structure expect it to be in little endian
1059 * so we reverse the buffer to make it work
1061 tmp
= reverse_and_get_blob(ctx
, rsa
->e
);
1065 keypair
.public_exponent
= *tmp
;
1066 SMB_ASSERT(tmp
->length
<= 4);
1068 * The value is now in little endian but if can happen that the length is
1069 * less than 4 bytes.
1070 * So if we have less than 4 bytes we pad with zeros so that it correctly
1071 * fit into the structure.
1073 if (tmp
->length
< 4) {
1075 * We need the expo to fit 4 bytes
1077 keypair
.public_exponent
.data
= talloc_zero_array(ctx
, uint8_t, 4);
1078 memcpy(keypair
.public_exponent
.data
, tmp
->data
, tmp
->length
);
1079 keypair
.public_exponent
.length
= 4;
1083 tmp
= reverse_and_get_blob(ctx
,rsa
->d
);
1087 keypair
.private_exponent
= *tmp
;
1090 tmp
= reverse_and_get_blob(ctx
,rsa
->n
);
1094 keypair
.modulus
= *tmp
;
1097 tmp
= reverse_and_get_blob(ctx
,rsa
->p
);
1101 keypair
.prime1
= *tmp
;
1104 tmp
= reverse_and_get_blob(ctx
,rsa
->q
);
1108 keypair
.prime2
= *tmp
;
1111 tmp
= reverse_and_get_blob(ctx
,rsa
->dmp1
);
1115 keypair
.exponent1
= *tmp
;
1118 tmp
= reverse_and_get_blob(ctx
,rsa
->dmq1
);
1122 keypair
.exponent2
= *tmp
;
1125 tmp
= reverse_and_get_blob(ctx
,rsa
->iqmp
);
1129 keypair
.coefficient
= *tmp
;
1132 /* One of the keypair allocation was wrong */
1134 der_free_octet_string(&data
);
1135 hx509_cert_free(cert
);
1136 hx509_private_key_free(&pk
);
1137 hx509_context_free(&hctx
);
1139 return WERR_INVALID_DATA
;
1141 keypair
.certificate_len
= keypair
.cert
.length
;
1142 ndr_err
= ndr_push_struct_blob(&blobkeypair
, ctx
, &keypair
, (ndr_push_flags_fn_t
)ndr_push_bkrp_exported_RSA_key_pair
);
1143 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1144 der_free_octet_string(&data
);
1145 hx509_cert_free(cert
);
1146 hx509_private_key_free(&pk
);
1147 hx509_context_free(&hctx
);
1149 return WERR_INVALID_DATA
;
1152 secret_name
= talloc_asprintf(ctx
, "BCKUPKEY_%s", GUID_string(ctx
, &guid
));
1153 if (secret_name
== NULL
) {
1154 der_free_octet_string(&data
);
1155 hx509_cert_free(cert
);
1156 hx509_private_key_free(&pk
);
1157 hx509_context_free(&hctx
);
1159 return WERR_OUTOFMEMORY
;
1162 status
= set_lsa_secret(ctx
, ldb_ctx
, secret_name
, &blobkeypair
);
1163 if (!NT_STATUS_IS_OK(status
)) {
1164 DEBUG(2, ("Failed to save the secret %s\n", secret_name
));
1166 talloc_free(secret_name
);
1168 GUID_to_ndr_blob(&guid
, ctx
, &blob
);
1169 status
= set_lsa_secret(ctx
, ldb_ctx
, "BCKUPKEY_PREFERRED", &blob
);
1170 if (!NT_STATUS_IS_OK(status
)) {
1171 DEBUG(2, ("Failed to save the secret BCKUPKEY_PREFERRED\n"));
1174 der_free_octet_string(&data
);
1175 hx509_cert_free(cert
);
1176 hx509_private_key_free(&pk
);
1177 hx509_context_free(&hctx
);
1182 static WERROR
bkrp_retrieve_client_wrap_key(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1183 struct bkrp_BackupKey
*r
, struct ldb_context
*ldb_ctx
)
1187 DATA_BLOB lsa_secret
;
1188 enum ndr_err_code ndr_err
;
1192 * here we basicaly need to return our certificate
1193 * search for lsa secret BCKUPKEY_PREFERRED first
1196 status
= get_lsa_secret(mem_ctx
,
1198 "BCKUPKEY_PREFERRED",
1200 if (NT_STATUS_EQUAL(status
, NT_STATUS_RESOURCE_NAME_NOT_FOUND
)) {
1201 /* Ok we can be in this case if there was no certs */
1202 struct loadparm_context
*lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
1203 char *dn
= talloc_asprintf(mem_ctx
, "CN=%s",
1204 lpcfg_realm(lp_ctx
));
1206 WERROR werr
= generate_bkrp_cert(mem_ctx
, dce_call
, ldb_ctx
, dn
);
1207 if (!W_ERROR_IS_OK(werr
)) {
1208 return WERR_INVALID_PARAMETER
;
1210 status
= get_lsa_secret(mem_ctx
,
1212 "BCKUPKEY_PREFERRED",
1215 if (!NT_STATUS_IS_OK(status
)) {
1216 /* Ok we really don't manage to get this certs ...*/
1217 DEBUG(2, ("Unable to locate BCKUPKEY_PREFERRED after cert generation\n"));
1218 return WERR_FILE_NOT_FOUND
;
1220 } else if (!NT_STATUS_IS_OK(status
)) {
1221 return WERR_INTERNAL_ERROR
;
1224 if (lsa_secret
.length
== 0) {
1225 DEBUG(1, ("No secret in BCKUPKEY_PREFERRED, are we an undetected RODC?\n"));
1226 return WERR_INTERNAL_ERROR
;
1228 char *cert_secret_name
;
1230 status
= GUID_from_ndr_blob(&lsa_secret
, &guid
);
1231 if (!NT_STATUS_IS_OK(status
)) {
1232 return WERR_FILE_NOT_FOUND
;
1235 guid_string
= GUID_string(mem_ctx
, &guid
);
1236 if (guid_string
== NULL
) {
1237 /* We return file not found because the client
1240 return WERR_FILE_NOT_FOUND
;
1243 cert_secret_name
= talloc_asprintf(mem_ctx
,
1246 status
= get_lsa_secret(mem_ctx
,
1250 if (!NT_STATUS_IS_OK(status
)) {
1251 return WERR_FILE_NOT_FOUND
;
1254 if (lsa_secret
.length
!= 0) {
1255 struct bkrp_exported_RSA_key_pair keypair
;
1256 ndr_err
= ndr_pull_struct_blob(&lsa_secret
, mem_ctx
, &keypair
,
1257 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_exported_RSA_key_pair
);
1258 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1259 return WERR_FILE_NOT_FOUND
;
1261 *(r
->out
.data_out_len
) = keypair
.cert
.length
;
1262 *(r
->out
.data_out
) = talloc_memdup(mem_ctx
, keypair
.cert
.data
, keypair
.cert
.length
);
1263 W_ERROR_HAVE_NO_MEMORY(*(r
->out
.data_out
));
1266 DEBUG(1, ("No or broken secret called %s\n", cert_secret_name
));
1267 return WERR_INTERNAL_ERROR
;
1271 return WERR_NOT_SUPPORTED
;
1274 static WERROR
generate_bkrp_server_wrap_key(TALLOC_CTX
*ctx
, struct ldb_context
*ldb_ctx
)
1276 struct GUID guid
= GUID_random();
1277 enum ndr_err_code ndr_err
;
1278 DATA_BLOB blob_wrap_key
, guid_blob
;
1279 struct bkrp_dc_serverwrap_key wrap_key
;
1282 TALLOC_CTX
*frame
= talloc_stackframe();
1284 generate_random_buffer(wrap_key
.key
, sizeof(wrap_key
.key
));
1286 ndr_err
= ndr_push_struct_blob(&blob_wrap_key
, ctx
, &wrap_key
, (ndr_push_flags_fn_t
)ndr_push_bkrp_dc_serverwrap_key
);
1287 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1289 return WERR_INVALID_DATA
;
1292 secret_name
= talloc_asprintf(frame
, "BCKUPKEY_%s", GUID_string(ctx
, &guid
));
1293 if (secret_name
== NULL
) {
1298 status
= set_lsa_secret(frame
, ldb_ctx
, secret_name
, &blob_wrap_key
);
1299 if (!NT_STATUS_IS_OK(status
)) {
1300 DEBUG(2, ("Failed to save the secret %s\n", secret_name
));
1302 return WERR_INTERNAL_ERROR
;
1305 status
= GUID_to_ndr_blob(&guid
, frame
, &guid_blob
);
1306 if (!NT_STATUS_IS_OK(status
)) {
1307 DEBUG(2, ("Failed to save the secret %s\n", secret_name
));
1311 status
= set_lsa_secret(frame
, ldb_ctx
, "BCKUPKEY_P", &guid_blob
);
1312 if (!NT_STATUS_IS_OK(status
)) {
1313 DEBUG(2, ("Failed to save the secret %s\n", secret_name
));
1315 return WERR_INTERNAL_ERROR
;
1324 * Find the specified decryption keys from the LSA secrets store as
1325 * G$BCKUPKEY_keyGuidString.
1328 static WERROR
bkrp_do_retrieve_server_wrap_key(TALLOC_CTX
*mem_ctx
, struct ldb_context
*ldb_ctx
,
1329 struct bkrp_dc_serverwrap_key
*server_key
,
1333 DATA_BLOB guid_binary
, lsa_secret
;
1336 enum ndr_err_code ndr_err
;
1338 guid_string
= GUID_string(mem_ctx
, guid
);
1339 if (guid_string
== NULL
) {
1340 /* We return file not found because the client
1343 return WERR_FILE_NOT_FOUND
;
1346 secret_name
= talloc_asprintf(mem_ctx
, "BCKUPKEY_%s", guid_string
);
1347 if (secret_name
== NULL
) {
1351 status
= get_lsa_secret(mem_ctx
, ldb_ctx
, secret_name
, &lsa_secret
);
1352 if (!NT_STATUS_IS_OK(status
)) {
1353 DEBUG(10, ("Error while fetching secret %s\n", secret_name
));
1354 return WERR_INVALID_DATA
;
1355 } else if (guid_binary
.length
== 0) {
1356 /* RODC case, we do not have secrets locally */
1357 DEBUG(1, ("Unable to fetch value for secret %s, are we an undetected RODC?\n",
1359 return WERR_INTERNAL_ERROR
;
1361 ndr_err
= ndr_pull_struct_blob(&lsa_secret
, mem_ctx
, server_key
,
1362 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_dc_serverwrap_key
);
1363 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1364 DEBUG(2, ("Unable to parse the ndr encoded server wrap key %s\n", secret_name
));
1365 return WERR_INVALID_DATA
;
1372 * Find the current, preferred ServerWrap Key by looking at
1373 * G$BCKUPKEY_P in the LSA secrets store.
1375 * Then find the current decryption keys from the LSA secrets store as
1376 * G$BCKUPKEY_keyGuidString.
1379 static WERROR
bkrp_do_retrieve_default_server_wrap_key(TALLOC_CTX
*mem_ctx
,
1380 struct ldb_context
*ldb_ctx
,
1381 struct bkrp_dc_serverwrap_key
*server_key
,
1382 struct GUID
*returned_guid
)
1385 DATA_BLOB guid_binary
;
1387 status
= get_lsa_secret(mem_ctx
, ldb_ctx
, "BCKUPKEY_P", &guid_binary
);
1388 if (!NT_STATUS_IS_OK(status
)) {
1389 DEBUG(10, ("Error while fetching secret BCKUPKEY_P to find current GUID\n"));
1390 return WERR_FILE_NOT_FOUND
;
1391 } else if (guid_binary
.length
== 0) {
1392 /* RODC case, we do not have secrets locally */
1393 DEBUG(1, ("Unable to fetch value for secret BCKUPKEY_P, are we an undetected RODC?\n"));
1394 return WERR_INTERNAL_ERROR
;
1397 status
= GUID_from_ndr_blob(&guid_binary
, returned_guid
);
1398 if (!NT_STATUS_IS_OK(status
)) {
1399 return WERR_FILE_NOT_FOUND
;
1402 return bkrp_do_retrieve_server_wrap_key(mem_ctx
, ldb_ctx
,
1403 server_key
, returned_guid
);
1406 static WERROR
bkrp_server_wrap_decrypt_data(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1407 struct bkrp_BackupKey
*r
,struct ldb_context
*ldb_ctx
)
1410 struct bkrp_server_side_wrapped decrypt_request
;
1411 DATA_BLOB sid_blob
, encrypted_blob
, symkey_blob
;
1413 enum ndr_err_code ndr_err
;
1414 struct bkrp_dc_serverwrap_key server_key
;
1415 struct bkrp_rc4encryptedpayload rc4payload
;
1416 struct dom_sid
*caller_sid
;
1417 uint8_t symkey
[20]; /* SHA-1 hash len */
1418 uint8_t mackey
[20]; /* SHA-1 hash len */
1419 uint8_t mac
[20]; /* SHA-1 hash len */
1420 unsigned int hash_len
;
1423 blob
.data
= r
->in
.data_in
;
1424 blob
.length
= r
->in
.data_in_len
;
1426 if (r
->in
.data_in_len
== 0 || r
->in
.data_in
== NULL
) {
1427 return WERR_INVALID_PARAM
;
1430 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &decrypt_request
,
1431 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_server_side_wrapped
);
1432 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1433 return WERR_INVALID_PARAM
;
1436 if (decrypt_request
.magic
!= 1) {
1437 return WERR_INVALID_PARAM
;
1440 werr
= bkrp_do_retrieve_server_wrap_key(mem_ctx
, ldb_ctx
, &server_key
,
1441 &decrypt_request
.guid
);
1442 if (!W_ERROR_IS_OK(werr
)) {
1446 dump_data_pw("server_key: \n", server_key
.key
, sizeof(server_key
.key
));
1448 dump_data_pw("r2: \n", decrypt_request
.r2
, sizeof(decrypt_request
.r2
));
1451 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1452 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1454 HMAC(EVP_sha1(), server_key
.key
, sizeof(server_key
.key
),
1455 decrypt_request
.r2
, sizeof(decrypt_request
.r2
),
1458 dump_data_pw("symkey: \n", symkey
, hash_len
);
1460 /* rc4 decrypt sid and secret using sym key */
1461 symkey_blob
= data_blob_const(symkey
, sizeof(symkey
));
1463 encrypted_blob
= data_blob_const(decrypt_request
.rc4encryptedpayload
,
1464 decrypt_request
.ciphertext_length
);
1466 arcfour_crypt_blob(encrypted_blob
.data
, encrypted_blob
.length
, &symkey_blob
);
1468 ndr_err
= ndr_pull_struct_blob(&encrypted_blob
, mem_ctx
, &rc4payload
,
1469 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_rc4encryptedpayload
);
1470 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1471 return WERR_INVALID_PARAM
;
1474 if (decrypt_request
.payload_length
!= rc4payload
.secret_data
.length
) {
1475 return WERR_INVALID_PARAM
;
1478 dump_data_pw("r3: \n", rc4payload
.r3
, sizeof(rc4payload
.r3
));
1481 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1482 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1484 HMAC(EVP_sha1(), server_key
.key
, sizeof(server_key
.key
),
1485 rc4payload
.r3
, sizeof(rc4payload
.r3
),
1488 dump_data_pw("mackey: \n", mackey
, sizeof(mackey
));
1490 ndr_err
= ndr_push_struct_blob(&sid_blob
, mem_ctx
, &rc4payload
.sid
,
1491 (ndr_push_flags_fn_t
)ndr_push_dom_sid
);
1492 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1493 return WERR_INTERNAL_ERROR
;
1496 HMAC_CTX_init(&ctx
);
1497 HMAC_Init_ex(&ctx
, mackey
, hash_len
, EVP_sha1(), NULL
);
1499 HMAC_Update(&ctx
, sid_blob
.data
, sid_blob
.length
);
1501 HMAC_Update(&ctx
, rc4payload
.secret_data
.data
, rc4payload
.secret_data
.length
);
1502 HMAC_Final(&ctx
, mac
, &hash_len
);
1503 HMAC_CTX_cleanup(&ctx
);
1505 dump_data_pw("mac: \n", mac
, sizeof(mac
));
1506 dump_data_pw("rc4payload.mac: \n", rc4payload
.mac
, sizeof(rc4payload
.mac
));
1508 if (memcmp(mac
, rc4payload
.mac
, sizeof(mac
)) != 0) {
1509 return WERR_INVALID_ACCESS
;
1512 caller_sid
= &dce_call
->conn
->auth_state
.session_info
->security_token
->sids
[PRIMARY_USER_SID_INDEX
];
1514 if (!dom_sid_equal(&rc4payload
.sid
, caller_sid
)) {
1515 return WERR_INVALID_ACCESS
;
1518 *(r
->out
.data_out
) = rc4payload
.secret_data
.data
;
1519 *(r
->out
.data_out_len
) = rc4payload
.secret_data
.length
;
1525 * For BACKUPKEY_RESTORE_GUID we need to check the first 4 bytes to
1526 * determine what type of restore is wanted.
1528 * See MS-BKRP 3.1.4.1.4 BACKUPKEY_RESTORE_GUID point 1.
1531 static WERROR
bkrp_generic_decrypt_data(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1532 struct bkrp_BackupKey
*r
, struct ldb_context
*ldb_ctx
)
1534 if (r
->in
.data_in_len
< 4 || r
->in
.data_in
== NULL
) {
1535 return WERR_INVALID_PARAM
;
1538 if (IVAL(r
->in
.data_in
, 0) == 1) {
1539 return bkrp_server_wrap_decrypt_data(dce_call
, mem_ctx
, r
, ldb_ctx
);
1542 return bkrp_client_wrap_decrypt_data(dce_call
, mem_ctx
, r
, ldb_ctx
);
1546 * We have some data, such as saved website or IMAP passwords that the
1547 * client would like to put into the profile on-disk. This needs to
1548 * be encrypted. This version gives the server the data over the
1549 * network (protected only by the negotiated transport encryption),
1550 * and asks that it be encrypted and returned for long-term storage.
1552 * The data is NOT stored in the LSA, but a key to encrypt the data
1553 * will be stored. There is only one active encryption key per domain,
1554 * it is pointed at with G$BCKUPKEY_P in the LSA secrets store.
1556 * The potentially multiple valid decryptiong keys (and the encryption
1557 * key) are in turn stored in the LSA secrets store as
1558 * G$BCKUPKEY_keyGuidString.
1562 static WERROR
bkrp_server_wrap_encrypt_data(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1563 struct bkrp_BackupKey
*r
,struct ldb_context
*ldb_ctx
)
1565 DATA_BLOB sid_blob
, encrypted_blob
, symkey_blob
, server_wrapped_blob
;
1567 struct dom_sid
*caller_sid
;
1568 uint8_t symkey
[20]; /* SHA-1 hash len */
1569 uint8_t mackey
[20]; /* SHA-1 hash len */
1570 unsigned int hash_len
;
1571 struct bkrp_rc4encryptedpayload rc4payload
;
1573 struct bkrp_dc_serverwrap_key server_key
;
1574 enum ndr_err_code ndr_err
;
1575 struct bkrp_server_side_wrapped server_side_wrapped
;
1578 if (r
->in
.data_in_len
== 0 || r
->in
.data_in
== NULL
) {
1579 return WERR_INVALID_PARAM
;
1582 werr
= bkrp_do_retrieve_default_server_wrap_key(mem_ctx
,
1583 ldb_ctx
, &server_key
,
1586 if (!W_ERROR_IS_OK(werr
)) {
1587 if (W_ERROR_EQUAL(werr
, WERR_FILE_NOT_FOUND
)) {
1588 /* Generate the server wrap key since one wasn't found */
1589 werr
= generate_bkrp_server_wrap_key(mem_ctx
,
1591 if (!W_ERROR_IS_OK(werr
)) {
1592 return WERR_INVALID_PARAMETER
;
1594 werr
= bkrp_do_retrieve_default_server_wrap_key(mem_ctx
,
1599 if (W_ERROR_EQUAL(werr
, WERR_FILE_NOT_FOUND
)) {
1600 /* Ok we really don't manage to get this secret ...*/
1601 return WERR_FILE_NOT_FOUND
;
1604 /* In theory we should NEVER reach this point as it
1605 should only appear in a rodc server */
1606 /* we do not have the real secret attribute */
1607 return WERR_INVALID_PARAMETER
;
1611 caller_sid
= &dce_call
->conn
->auth_state
.session_info
->security_token
->sids
[PRIMARY_USER_SID_INDEX
];
1613 dump_data_pw("server_key: \n", server_key
.key
, sizeof(server_key
.key
));
1616 * This is the key derivation step, so that the HMAC and RC4
1617 * operations over the user-supplied data are not able to
1618 * disclose the master key. By using random data, the symkey
1619 * and mackey values are unique for this operation, and
1620 * discovering these (by reversing the RC4 over the
1621 * attacker-controlled data) does not return something able to
1622 * be used to decyrpt the encrypted data of other users
1624 generate_random_buffer(server_side_wrapped
.r2
, sizeof(server_side_wrapped
.r2
));
1626 dump_data_pw("r2: \n", server_side_wrapped
.r2
, sizeof(server_side_wrapped
.r2
));
1628 generate_random_buffer(rc4payload
.r3
, sizeof(rc4payload
.r3
));
1630 dump_data_pw("r3: \n", rc4payload
.r3
, sizeof(rc4payload
.r3
));
1634 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1635 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1637 HMAC(EVP_sha1(), server_key
.key
, sizeof(server_key
.key
),
1638 server_side_wrapped
.r2
, sizeof(server_side_wrapped
.r2
),
1641 dump_data_pw("symkey: \n", symkey
, hash_len
);
1644 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1645 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1647 HMAC(EVP_sha1(), server_key
.key
, sizeof(server_key
.key
),
1648 rc4payload
.r3
, sizeof(rc4payload
.r3
),
1651 dump_data_pw("mackey: \n", mackey
, sizeof(mackey
));
1653 ndr_err
= ndr_push_struct_blob(&sid_blob
, mem_ctx
, caller_sid
,
1654 (ndr_push_flags_fn_t
)ndr_push_dom_sid
);
1655 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1656 return WERR_INTERNAL_ERROR
;
1659 rc4payload
.secret_data
.data
= r
->in
.data_in
;
1660 rc4payload
.secret_data
.length
= r
->in
.data_in_len
;
1663 HMAC_CTX_init(&ctx
);
1664 HMAC_Init_ex(&ctx
, mackey
, 20, EVP_sha1(), NULL
);
1666 HMAC_Update(&ctx
, sid_blob
.data
, sid_blob
.length
);
1668 HMAC_Update(&ctx
, rc4payload
.secret_data
.data
, rc4payload
.secret_data
.length
);
1669 HMAC_Final(&ctx
, rc4payload
.mac
, &hash_len
);
1670 HMAC_CTX_cleanup(&ctx
);
1672 dump_data_pw("rc4payload.mac: \n", rc4payload
.mac
, sizeof(rc4payload
.mac
));
1674 rc4payload
.sid
= *caller_sid
;
1676 ndr_err
= ndr_push_struct_blob(&encrypted_blob
, mem_ctx
, &rc4payload
,
1677 (ndr_push_flags_fn_t
)ndr_push_bkrp_rc4encryptedpayload
);
1678 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1679 return WERR_INTERNAL_ERROR
;
1682 /* rc4 encrypt sid and secret using sym key */
1683 symkey_blob
= data_blob_const(symkey
, sizeof(symkey
));
1684 arcfour_crypt_blob(encrypted_blob
.data
, encrypted_blob
.length
, &symkey_blob
);
1686 /* create server wrap structure */
1688 server_side_wrapped
.payload_length
= rc4payload
.secret_data
.length
;
1689 server_side_wrapped
.ciphertext_length
= encrypted_blob
.length
;
1690 server_side_wrapped
.guid
= guid
;
1691 server_side_wrapped
.rc4encryptedpayload
= encrypted_blob
.data
;
1693 ndr_err
= ndr_push_struct_blob(&server_wrapped_blob
, mem_ctx
, &server_side_wrapped
,
1694 (ndr_push_flags_fn_t
)ndr_push_bkrp_server_side_wrapped
);
1695 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1696 return WERR_INTERNAL_ERROR
;
1700 *(r
->out
.data_out
) = server_wrapped_blob
.data
;
1701 *(r
->out
.data_out_len
) = server_wrapped_blob
.length
;
1706 static WERROR
dcesrv_bkrp_BackupKey(struct dcesrv_call_state
*dce_call
,
1707 TALLOC_CTX
*mem_ctx
, struct bkrp_BackupKey
*r
)
1709 WERROR error
= WERR_INVALID_PARAM
;
1710 struct ldb_context
*ldb_ctx
;
1712 const char *addr
= "unknown";
1713 /* At which level we start to add more debug of what is done in the protocol */
1714 const int debuglevel
= 4;
1716 if (DEBUGLVL(debuglevel
)) {
1717 const struct tsocket_address
*remote_address
;
1718 remote_address
= dcesrv_connection_get_remote_address(dce_call
->conn
);
1719 if (tsocket_address_is_inet(remote_address
, "ip")) {
1720 addr
= tsocket_address_inet_addr_string(remote_address
, mem_ctx
);
1721 W_ERROR_HAVE_NO_MEMORY(addr
);
1725 if (lpcfg_server_role(dce_call
->conn
->dce_ctx
->lp_ctx
) != ROLE_ACTIVE_DIRECTORY_DC
) {
1726 return WERR_NOT_SUPPORTED
;
1729 if (!dce_call
->conn
->auth_state
.auth_info
||
1730 dce_call
->conn
->auth_state
.auth_info
->auth_level
!= DCERPC_AUTH_LEVEL_PRIVACY
) {
1731 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
1734 ldb_ctx
= samdb_connect(mem_ctx
, dce_call
->event_ctx
,
1735 dce_call
->conn
->dce_ctx
->lp_ctx
,
1736 system_session(dce_call
->conn
->dce_ctx
->lp_ctx
), 0);
1738 if (samdb_rodc(ldb_ctx
, &is_rodc
) != LDB_SUCCESS
) {
1739 talloc_unlink(mem_ctx
, ldb_ctx
);
1740 return WERR_INVALID_PARAM
;
1744 if(strncasecmp(GUID_string(mem_ctx
, r
->in
.guidActionAgent
),
1745 BACKUPKEY_RESTORE_GUID
, strlen(BACKUPKEY_RESTORE_GUID
)) == 0) {
1746 DEBUG(debuglevel
, ("Client %s requested to decrypt a wrapped secret\n", addr
));
1747 error
= bkrp_generic_decrypt_data(dce_call
, mem_ctx
, r
, ldb_ctx
);
1750 if (strncasecmp(GUID_string(mem_ctx
, r
->in
.guidActionAgent
),
1751 BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID
, strlen(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID
)) == 0) {
1752 DEBUG(debuglevel
, ("Client %s requested certificate for client wrapped secret\n", addr
));
1753 error
= bkrp_retrieve_client_wrap_key(dce_call
, mem_ctx
, r
, ldb_ctx
);
1756 if (strncasecmp(GUID_string(mem_ctx
, r
->in
.guidActionAgent
),
1757 BACKUPKEY_RESTORE_GUID_WIN2K
, strlen(BACKUPKEY_RESTORE_GUID_WIN2K
)) == 0) {
1758 DEBUG(debuglevel
, ("Client %s requested to decrypt a server side wrapped secret\n", addr
));
1759 error
= bkrp_server_wrap_decrypt_data(dce_call
, mem_ctx
, r
, ldb_ctx
);
1762 if (strncasecmp(GUID_string(mem_ctx
, r
->in
.guidActionAgent
),
1763 BACKUPKEY_BACKUP_GUID
, strlen(BACKUPKEY_BACKUP_GUID
)) == 0) {
1764 DEBUG(debuglevel
, ("Client %s requested a server wrapped secret\n", addr
));
1765 error
= bkrp_server_wrap_encrypt_data(dce_call
, mem_ctx
, r
, ldb_ctx
);
1768 /*else: I am a RODC so I don't handle backup key protocol */
1770 talloc_unlink(mem_ctx
, ldb_ctx
);
1774 /* include the generated boilerplate */
1775 #include "librpc/gen_ndr/ndr_backupkey_s.c"