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>
38 #include "../lib/tsocket/tsocket.h"
39 #include "../libcli/security/security.h"
41 #define BACKUPKEY_MIN_VERSION 2
42 #define BACKUPKEY_MAX_VERSION 3
44 static const unsigned rsa_with_var_num
[] = { 1, 2, 840, 113549, 1, 1, 1 };
45 /* Equivalent to asn1_oid_id_pkcs1_rsaEncryption*/
46 static const AlgorithmIdentifier _hx509_signature_rsa_with_var_num
= {
47 { 7, discard_const_p(unsigned, rsa_with_var_num
) }, NULL
50 static NTSTATUS
set_lsa_secret(TALLOC_CTX
*mem_ctx
,
51 struct ldb_context
*ldb
,
53 const DATA_BLOB
*secret
)
55 struct ldb_message
*msg
;
56 struct ldb_result
*res
;
57 struct ldb_dn
*domain_dn
;
58 struct ldb_dn
*system_dn
;
62 struct timeval now
= timeval_current();
63 NTTIME nt_now
= timeval_to_nttime(&now
);
64 const char *attrs
[] = {
68 domain_dn
= ldb_get_default_basedn(ldb
);
70 return NT_STATUS_INTERNAL_ERROR
;
73 msg
= ldb_msg_new(mem_ctx
);
75 return NT_STATUS_NO_MEMORY
;
79 * This function is a lot like dcesrv_lsa_CreateSecret
80 * in the rpc_server/lsa directory
81 * The reason why we duplicate the effort here is that:
82 * * we want to keep the former function static
83 * * we want to avoid the burden of doing LSA calls
84 * when we can just manipulate the secrets directly
85 * * taillor the function to the particular needs of backup protocol
88 system_dn
= samdb_search_dn(ldb
, msg
, domain_dn
, "(&(objectClass=container)(cn=System))");
89 if (system_dn
== NULL
) {
91 return NT_STATUS_NO_MEMORY
;
94 name2
= talloc_asprintf(msg
, "%s Secret", name
);
97 return NT_STATUS_NO_MEMORY
;
100 ret
= ldb_search(ldb
, mem_ctx
, &res
, system_dn
, LDB_SCOPE_SUBTREE
, attrs
,
101 "(&(cn=%s)(objectclass=secret))",
102 ldb_binary_encode_string(mem_ctx
, name2
));
104 if (ret
!= LDB_SUCCESS
|| res
->count
!= 0 ) {
105 DEBUG(2, ("Secret %s already exists !\n", name2
));
107 return NT_STATUS_OBJECT_NAME_COLLISION
;
111 * We don't care about previous value as we are
112 * here only if the key didn't exists before
115 msg
->dn
= ldb_dn_copy(mem_ctx
, system_dn
);
116 if (msg
->dn
== NULL
) {
118 return NT_STATUS_NO_MEMORY
;
120 if (!ldb_dn_add_child_fmt(msg
->dn
, "cn=%s", name2
)) {
122 return NT_STATUS_NO_MEMORY
;
125 ret
= ldb_msg_add_string(msg
, "cn", name2
);
126 if (ret
!= LDB_SUCCESS
) {
128 return NT_STATUS_NO_MEMORY
;
130 ret
= ldb_msg_add_string(msg
, "objectClass", "secret");
131 if (ret
!= LDB_SUCCESS
) {
133 return NT_STATUS_NO_MEMORY
;
135 ret
= samdb_msg_add_uint64(ldb
, mem_ctx
, msg
, "priorSetTime", nt_now
);
136 if (ret
!= LDB_SUCCESS
) {
138 return NT_STATUS_NO_MEMORY
;
140 val
.data
= secret
->data
;
141 val
.length
= secret
->length
;
142 ret
= ldb_msg_add_value(msg
, "currentValue", &val
, NULL
);
143 if (ret
!= LDB_SUCCESS
) {
145 return NT_STATUS_NO_MEMORY
;
147 ret
= samdb_msg_add_uint64(ldb
, mem_ctx
, msg
, "lastSetTime", nt_now
);
148 if (ret
!= LDB_SUCCESS
) {
150 return NT_STATUS_NO_MEMORY
;
154 * create the secret with DSDB_MODIFY_RELAX
155 * otherwise dsdb/samdb/ldb_modules/objectclass.c forbid
156 * the create of LSA secret object
158 ret
= dsdb_add(ldb
, msg
, DSDB_MODIFY_RELAX
);
159 if (ret
!= LDB_SUCCESS
) {
160 DEBUG(2,("Failed to create secret record %s: %s\n",
161 ldb_dn_get_linearized(msg
->dn
),
162 ldb_errstring(ldb
)));
164 return NT_STATUS_ACCESS_DENIED
;
171 /* This function is pretty much like dcesrv_lsa_QuerySecret */
172 static NTSTATUS
get_lsa_secret(TALLOC_CTX
*mem_ctx
,
173 struct ldb_context
*ldb
,
178 struct ldb_result
*res
;
179 struct ldb_dn
*domain_dn
;
180 struct ldb_dn
*system_dn
;
181 const struct ldb_val
*val
;
183 const char *attrs
[] = {
192 domain_dn
= ldb_get_default_basedn(ldb
);
194 return NT_STATUS_INTERNAL_ERROR
;
197 tmp_mem
= talloc_new(mem_ctx
);
198 if (tmp_mem
== NULL
) {
199 return NT_STATUS_NO_MEMORY
;
202 system_dn
= samdb_search_dn(ldb
, tmp_mem
, domain_dn
, "(&(objectClass=container)(cn=System))");
203 if (system_dn
== NULL
) {
204 talloc_free(tmp_mem
);
205 return NT_STATUS_NO_MEMORY
;
208 ret
= ldb_search(ldb
, mem_ctx
, &res
, system_dn
, LDB_SCOPE_SUBTREE
, attrs
,
209 "(&(cn=%s Secret)(objectclass=secret))",
210 ldb_binary_encode_string(tmp_mem
, name
));
212 if (ret
!= LDB_SUCCESS
|| res
->count
== 0) {
213 talloc_free(tmp_mem
);
215 * Important NOT to use NT_STATUS_OBJECT_NAME_NOT_FOUND
216 * as this return value is used to detect the case
217 * when we have the secret but without the currentValue
220 return NT_STATUS_RESOURCE_NAME_NOT_FOUND
;
223 if (res
->count
> 1) {
224 DEBUG(2, ("Secret %s collision\n", name
));
225 talloc_free(tmp_mem
);
226 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
229 val
= ldb_msg_find_ldb_val(res
->msgs
[0], "currentValue");
232 * The secret object is here but we don't have the secret value
233 * The most common case is a RODC
235 talloc_free(tmp_mem
);
236 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
240 secret
->data
= talloc_move(mem_ctx
, &data
);
241 secret
->length
= val
->length
;
243 talloc_free(tmp_mem
);
247 static DATA_BLOB
*reverse_and_get_blob(TALLOC_CTX
*mem_ctx
, BIGNUM
*bn
)
250 DATA_BLOB
*rev
= talloc(mem_ctx
, DATA_BLOB
);
253 blob
.length
= BN_num_bytes(bn
);
254 blob
.data
= talloc_array(mem_ctx
, uint8_t, blob
.length
);
256 if (blob
.data
== NULL
) {
260 BN_bn2bin(bn
, blob
.data
);
262 rev
->data
= talloc_array(mem_ctx
, uint8_t, blob
.length
);
263 if (rev
->data
== NULL
) {
267 for(i
=0; i
< blob
.length
; i
++) {
268 rev
->data
[i
] = blob
.data
[blob
.length
- i
-1];
270 rev
->length
= blob
.length
;
271 talloc_free(blob
.data
);
275 static BIGNUM
*reverse_and_get_bignum(TALLOC_CTX
*mem_ctx
, DATA_BLOB
*blob
)
281 rev
.data
= talloc_array(mem_ctx
, uint8_t, blob
->length
);
282 if (rev
.data
== NULL
) {
286 for(i
=0; i
< blob
->length
; i
++) {
287 rev
.data
[i
] = blob
->data
[blob
->length
- i
-1];
289 rev
.length
= blob
->length
;
291 ret
= BN_bin2bn(rev
.data
, rev
.length
, NULL
);
292 talloc_free(rev
.data
);
297 static NTSTATUS
get_pk_from_raw_keypair_params(TALLOC_CTX
*ctx
,
298 struct bkrp_exported_RSA_key_pair
*keypair
,
299 hx509_private_key
*pk
)
303 struct hx509_private_key_ops
*ops
;
305 hx509_context_init(&hctx
);
306 ops
= hx509_find_private_alg(&_hx509_signature_rsa_with_var_num
.algorithm
);
308 DEBUG(2, ("Not supported algorithm\n"));
309 return NT_STATUS_INTERNAL_ERROR
;
312 if (hx509_private_key_init(pk
, ops
, NULL
) != 0) {
313 hx509_context_free(&hctx
);
314 return NT_STATUS_NO_MEMORY
;
319 hx509_context_free(&hctx
);
320 return NT_STATUS_INVALID_PARAMETER
;
323 rsa
->n
= reverse_and_get_bignum(ctx
, &(keypair
->modulus
));
324 if (rsa
->n
== NULL
) {
326 hx509_context_free(&hctx
);
327 return NT_STATUS_INVALID_PARAMETER
;
329 rsa
->d
= reverse_and_get_bignum(ctx
, &(keypair
->private_exponent
));
330 if (rsa
->d
== NULL
) {
332 hx509_context_free(&hctx
);
333 return NT_STATUS_INVALID_PARAMETER
;
335 rsa
->p
= reverse_and_get_bignum(ctx
, &(keypair
->prime1
));
336 if (rsa
->p
== NULL
) {
338 hx509_context_free(&hctx
);
339 return NT_STATUS_INVALID_PARAMETER
;
341 rsa
->q
= reverse_and_get_bignum(ctx
, &(keypair
->prime2
));
342 if (rsa
->q
== NULL
) {
344 hx509_context_free(&hctx
);
345 return NT_STATUS_INVALID_PARAMETER
;
347 rsa
->dmp1
= reverse_and_get_bignum(ctx
, &(keypair
->exponent1
));
348 if (rsa
->dmp1
== NULL
) {
350 hx509_context_free(&hctx
);
351 return NT_STATUS_INVALID_PARAMETER
;
353 rsa
->dmq1
= reverse_and_get_bignum(ctx
, &(keypair
->exponent2
));
354 if (rsa
->dmq1
== NULL
) {
356 hx509_context_free(&hctx
);
357 return NT_STATUS_INVALID_PARAMETER
;
359 rsa
->iqmp
= reverse_and_get_bignum(ctx
, &(keypair
->coefficient
));
360 if (rsa
->iqmp
== NULL
) {
362 hx509_context_free(&hctx
);
363 return NT_STATUS_INVALID_PARAMETER
;
365 rsa
->e
= reverse_and_get_bignum(ctx
, &(keypair
->public_exponent
));
366 if (rsa
->e
== NULL
) {
368 hx509_context_free(&hctx
);
369 return NT_STATUS_INVALID_PARAMETER
;
372 hx509_private_key_assign_rsa(*pk
, rsa
);
374 hx509_context_free(&hctx
);
378 static WERROR
get_and_verify_access_check(TALLOC_CTX
*sub_ctx
,
381 uint8_t *access_check
,
382 uint32_t access_check_len
,
383 struct auth_session_info
*session_info
)
385 heim_octet_string iv
;
386 heim_octet_string access_check_os
;
393 enum ndr_err_code ndr_err
;
396 struct dom_sid
*access_sid
= NULL
;
397 struct dom_sid
*caller_sid
= NULL
;
399 /* This one should not be freed */
400 const AlgorithmIdentifier
*alg
;
406 alg
= hx509_crypto_des_rsdi_ede3_cbc();
412 alg
=hx509_crypto_aes256_cbc();
416 return WERR_INVALID_DATA
;
419 hx509_context_init(&hctx
);
420 res
= hx509_crypto_init(hctx
, NULL
,
423 hx509_context_free(&hctx
);
426 return WERR_INVALID_DATA
;
429 res
= hx509_crypto_set_key_data(crypto
, key_and_iv
, key_len
);
431 iv
.data
= talloc_memdup(sub_ctx
, key_len
+ key_and_iv
, iv_len
);
435 hx509_crypto_destroy(crypto
);
436 return WERR_INVALID_DATA
;
439 hx509_crypto_set_padding(crypto
, HX509_CRYPTO_PADDING_NONE
);
440 res
= hx509_crypto_decrypt(crypto
,
447 hx509_crypto_destroy(crypto
);
448 return WERR_INVALID_DATA
;
451 blob_us
.data
= access_check_os
.data
;
452 blob_us
.length
= access_check_os
.length
;
454 hx509_crypto_destroy(crypto
);
459 uint32_t hash_size
= 20;
460 uint8_t hash
[hash_size
];
462 struct bkrp_access_check_v2 uncrypted_accesscheckv2
;
464 ndr_err
= ndr_pull_struct_blob(&blob_us
, sub_ctx
, &uncrypted_accesscheckv2
,
465 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_access_check_v2
);
466 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
467 /* Unable to unmarshall */
468 der_free_octet_string(&access_check_os
);
469 return WERR_INVALID_DATA
;
471 if (uncrypted_accesscheckv2
.magic
!= 0x1) {
473 der_free_octet_string(&access_check_os
);
474 return WERR_INVALID_DATA
;
478 SHA1_Update(&sctx
, blob_us
.data
, blob_us
.length
- hash_size
);
479 SHA1_Final(hash
, &sctx
);
480 der_free_octet_string(&access_check_os
);
482 * We free it after the sha1 calculation because blob.data
483 * point to the same area
486 if (memcmp(hash
, uncrypted_accesscheckv2
.hash
, hash_size
) != 0) {
487 DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
488 return WERR_INVALID_DATA
;
490 access_sid
= &(uncrypted_accesscheckv2
.sid
);
495 uint32_t hash_size
= 64;
496 uint8_t hash
[hash_size
];
497 struct hc_sha512state sctx
;
498 struct bkrp_access_check_v3 uncrypted_accesscheckv3
;
500 ndr_err
= ndr_pull_struct_blob(&blob_us
, sub_ctx
, &uncrypted_accesscheckv3
,
501 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_access_check_v3
);
502 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
503 /* Unable to unmarshall */
504 der_free_octet_string(&access_check_os
);
505 return WERR_INVALID_DATA
;
507 if (uncrypted_accesscheckv3
.magic
!= 0x1) {
509 der_free_octet_string(&access_check_os
);
510 return WERR_INVALID_DATA
;
514 SHA512_Update(&sctx
, blob_us
.data
, blob_us
.length
- hash_size
);
515 SHA512_Final(hash
, &sctx
);
516 der_free_octet_string(&access_check_os
);
518 * We free it after the sha1 calculation because blob.data
519 * point to the same area
522 if (memcmp(hash
, uncrypted_accesscheckv3
.hash
, hash_size
) != 0) {
523 DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
524 return WERR_INVALID_DATA
;
526 access_sid
= &(uncrypted_accesscheckv3
.sid
);
530 /* Never reached normally as we filtered at the switch / case level */
531 return WERR_INVALID_DATA
;
534 caller_sid
= &session_info
->security_token
->sids
[PRIMARY_USER_SID_INDEX
];
536 if (!dom_sid_equal(caller_sid
, access_sid
)) {
537 return WERR_INVALID_ACCESS
;
543 * We have some data, such as saved website or IMAP passwords that the
544 * client has in profile on-disk. This needs to be decrypted. This
545 * version gives the server the data over the network (protected by
546 * the X.509 certificate and public key encryption, and asks that it
547 * be decrypted returned for short-term use, protected only by the
548 * negotiated transport encryption.
550 * The data is NOT stored in the LSA, but a X.509 certificate, public
551 * and private keys used to encrypt the data will be stored. There is
552 * only one active encryption key pair and certificate per domain, it
553 * is pointed at with G$BCKUPKEY_PREFERRED in the LSA secrets store.
555 * The potentially multiple valid decrypting key pairs are in turn
556 * stored in the LSA secrets store as G$BCKUPKEY_keyGuidString.
559 static WERROR
bkrp_client_wrap_decrypt_data(struct dcesrv_call_state
*dce_call
,
561 struct bkrp_BackupKey
*r
,
562 struct ldb_context
*ldb_ctx
)
564 struct bkrp_client_side_wrapped uncrypt_request
;
566 enum ndr_err_code ndr_err
;
568 char *cert_secret_name
;
570 DATA_BLOB
*uncrypted
;
573 blob
.data
= r
->in
.data_in
;
574 blob
.length
= r
->in
.data_in_len
;
576 if (r
->in
.data_in_len
== 0 || r
->in
.data_in
== NULL
) {
577 return WERR_INVALID_PARAM
;
580 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &uncrypt_request
,
581 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_wrapped
);
582 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
583 return WERR_INVALID_PARAM
;
586 if (uncrypt_request
.version
< BACKUPKEY_MIN_VERSION
) {
587 return WERR_INVALID_PARAMETER
;
590 if (uncrypt_request
.version
> BACKUPKEY_MAX_VERSION
) {
591 return WERR_INVALID_PARAMETER
;
594 guid_string
= GUID_string(mem_ctx
, &uncrypt_request
.guid
);
595 if (guid_string
== NULL
) {
599 cert_secret_name
= talloc_asprintf(mem_ctx
,
602 if (cert_secret_name
== NULL
) {
606 status
= get_lsa_secret(mem_ctx
,
610 if (!NT_STATUS_IS_OK(status
)) {
611 DEBUG(10, ("Error while fetching secret %s\n", cert_secret_name
));
612 if (NT_STATUS_EQUAL(status
,NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
613 /* we do not have the real secret attribute */
614 return WERR_INVALID_PARAMETER
;
616 return WERR_FILE_NOT_FOUND
;
620 if (secret
.length
!= 0) {
622 struct bkrp_exported_RSA_key_pair keypair
;
623 hx509_private_key pk
;
625 heim_octet_string reversed_secret
;
626 heim_octet_string uncrypted_secret
;
627 AlgorithmIdentifier alg
;
631 ndr_err
= ndr_pull_struct_blob(&secret
, mem_ctx
, &keypair
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_exported_RSA_key_pair
);
632 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
633 DEBUG(2, ("Unable to parse the ndr encoded cert in key %s\n", cert_secret_name
));
634 return WERR_FILE_NOT_FOUND
;
637 status
= get_pk_from_raw_keypair_params(mem_ctx
, &keypair
, &pk
);
638 if (!NT_STATUS_IS_OK(status
)) {
639 return WERR_INTERNAL_ERROR
;
642 reversed_secret
.data
= talloc_array(mem_ctx
, uint8_t,
643 uncrypt_request
.encrypted_secret_len
);
644 if (reversed_secret
.data
== NULL
) {
645 hx509_private_key_free(&pk
);
649 /* The secret has to be reversed ... */
650 for(i
=0; i
< uncrypt_request
.encrypted_secret_len
; i
++) {
651 uint8_t *reversed
= (uint8_t *)reversed_secret
.data
;
652 uint8_t *uncrypt
= uncrypt_request
.encrypted_secret
;
653 reversed
[i
] = uncrypt
[uncrypt_request
.encrypted_secret_len
- 1 - i
];
655 reversed_secret
.length
= uncrypt_request
.encrypted_secret_len
;
658 * Let's try to decrypt the secret now that
659 * we have the private key ...
661 hx509_context_init(&hctx
);
662 res
= hx509_private_key_private_decrypt(hctx
, &reversed_secret
,
665 hx509_context_free(&hctx
);
666 hx509_private_key_free(&pk
);
668 /* We are not able to decrypt the secret, looks like something is wrong */
669 return WERR_INVALID_DATA
;
671 blob_us
.data
= uncrypted_secret
.data
;
672 blob_us
.length
= uncrypted_secret
.length
;
674 if (uncrypt_request
.version
== 2) {
675 struct bkrp_encrypted_secret_v2 uncrypted_secretv2
;
677 ndr_err
= ndr_pull_struct_blob(&blob_us
, mem_ctx
, &uncrypted_secretv2
,
678 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_encrypted_secret_v2
);
679 der_free_octet_string(&uncrypted_secret
);
680 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
681 /* Unable to unmarshall */
682 return WERR_INVALID_DATA
;
684 if (uncrypted_secretv2
.magic
!= 0x20) {
686 return WERR_INVALID_DATA
;
689 werr
= get_and_verify_access_check(mem_ctx
, 2,
690 uncrypted_secretv2
.payload_key
,
691 uncrypt_request
.access_check
,
692 uncrypt_request
.access_check_len
,
693 dce_call
->conn
->auth_state
.session_info
);
694 if (!W_ERROR_IS_OK(werr
)) {
697 uncrypted
= talloc(mem_ctx
, DATA_BLOB
);
698 if (uncrypted
== NULL
) {
699 return WERR_INVALID_DATA
;
702 uncrypted
->data
= uncrypted_secretv2
.secret
;
703 uncrypted
->length
= uncrypted_secretv2
.secret_len
;
705 if (uncrypt_request
.version
== 3) {
706 struct bkrp_encrypted_secret_v3 uncrypted_secretv3
;
708 ndr_err
= ndr_pull_struct_blob(&blob_us
, mem_ctx
, &uncrypted_secretv3
,
709 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_encrypted_secret_v3
);
711 der_free_octet_string(&uncrypted_secret
);
712 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
713 /* Unable to unmarshall */
714 return WERR_INVALID_DATA
;
717 if (uncrypted_secretv3
.magic1
!= 0x30 ||
718 uncrypted_secretv3
.magic2
!= 0x6610 ||
719 uncrypted_secretv3
.magic3
!= 0x800e) {
721 return WERR_INVALID_DATA
;
725 * Confirm that the caller is permitted to
726 * read this particular data. Because one key
727 * pair is used per domain, the caller could
728 * have stolen the profile data on-disk and
729 * would otherwise be able to read the
733 werr
= get_and_verify_access_check(mem_ctx
, 3,
734 uncrypted_secretv3
.payload_key
,
735 uncrypt_request
.access_check
,
736 uncrypt_request
.access_check_len
,
737 dce_call
->conn
->auth_state
.session_info
);
738 if (!W_ERROR_IS_OK(werr
)) {
742 uncrypted
= talloc(mem_ctx
, DATA_BLOB
);
743 if (uncrypted
== NULL
) {
744 return WERR_INVALID_DATA
;
747 uncrypted
->data
= uncrypted_secretv3
.secret
;
748 uncrypted
->length
= uncrypted_secretv3
.secret_len
;
752 * Yeah if we are here all looks pretty good:
754 * - user sid is the same as the one in access check
755 * - we were able to decrypt the whole stuff
759 if (uncrypted
->data
== NULL
) {
760 return WERR_INVALID_DATA
;
763 /* There is a magic value a the beginning of the data
764 * we can use an adhoc structure but as the
765 * parent structure is just an array of bytes it a lot of work
766 * work just prepending 4 bytes
768 *(r
->out
.data_out
) = talloc_zero_array(mem_ctx
, uint8_t, uncrypted
->length
+ 4);
769 W_ERROR_HAVE_NO_MEMORY(*(r
->out
.data_out
));
770 memcpy(4+*(r
->out
.data_out
), uncrypted
->data
, uncrypted
->length
);
771 *(r
->out
.data_out_len
) = uncrypted
->length
+ 4;
776 static WERROR
create_heimdal_rsa_key(TALLOC_CTX
*ctx
, hx509_context
*hctx
,
777 hx509_private_key
*pk
, RSA
**_rsa
)
785 int RSA_returned_bits
;
790 if(pub_expo
== NULL
) {
791 return WERR_INTERNAL_ERROR
;
794 /* set the public expo to 65537 like everyone */
795 BN_set_word(pub_expo
, 0x10001);
800 return WERR_INTERNAL_ERROR
;
803 while (RSA_returned_bits
!= bits
) {
804 ret
= RSA_generate_key_ex(rsa
, bits
, pub_expo
, NULL
);
808 return WERR_INTERNAL_ERROR
;
810 RSA_returned_bits
= BN_num_bits(rsa
->n
);
811 DEBUG(6, ("RSA_generate_key_ex returned %d Bits\n", RSA_returned_bits
));
815 len
= i2d_RSAPrivateKey(rsa
, NULL
);
818 return WERR_INTERNAL_ERROR
;
821 p0
= p
= talloc_array(ctx
, uint8_t, len
);
824 return WERR_INTERNAL_ERROR
;
827 len
= i2d_RSAPrivateKey(rsa
, &p
);
831 return WERR_INTERNAL_ERROR
;
835 * To dump the key we can use :
836 * rk_dumpdata("h5lkey", p0, len);
838 ret
= hx509_parse_private_key(*hctx
, &_hx509_signature_rsa_with_var_num
,
839 p0
, len
, HX509_KEY_FORMAT_DER
, pk
);
844 return WERR_INTERNAL_ERROR
;
851 static WERROR
self_sign_cert(TALLOC_CTX
*ctx
, hx509_context
*hctx
, hx509_request
*req
,
852 time_t lifetime
, hx509_private_key
*private_key
,
853 hx509_cert
*cert
, DATA_BLOB
*guidblob
)
855 SubjectPublicKeyInfo spki
;
856 hx509_name subject
= NULL
;
858 struct heim_bit_string uniqueid
;
859 struct heim_integer serialnumber
;
862 uniqueid
.data
= talloc_memdup(ctx
, guidblob
->data
, guidblob
->length
);
863 if (uniqueid
.data
== NULL
) {
866 /* uniqueid is a bit string in which each byte represent 1 bit (1 or 0)
867 * so as 1 byte is 8 bits we need to provision 8 times more space as in the
870 uniqueid
.length
= 8 * guidblob
->length
;
872 serialnumber
.data
= talloc_array(ctx
, uint8_t,
874 if (serialnumber
.data
== NULL
) {
875 talloc_free(uniqueid
.data
);
879 /* Native AD generates certificates with serialnumber in reversed notation */
880 for (i
= 0; i
< guidblob
->length
; i
++) {
881 uint8_t *reversed
= (uint8_t *)serialnumber
.data
;
882 uint8_t *uncrypt
= guidblob
->data
;
883 reversed
[i
] = uncrypt
[guidblob
->length
- 1 - i
];
885 serialnumber
.length
= guidblob
->length
;
886 serialnumber
.negative
= 0;
888 memset(&spki
, 0, sizeof(spki
));
890 ret
= hx509_request_get_name(*hctx
, *req
, &subject
);
894 ret
= hx509_request_get_SubjectPublicKeyInfo(*hctx
, *req
, &spki
);
899 ret
= hx509_ca_tbs_init(*hctx
, &tbs
);
904 ret
= hx509_ca_tbs_set_spki(*hctx
, tbs
, &spki
);
908 ret
= hx509_ca_tbs_set_subject(*hctx
, tbs
, subject
);
912 ret
= hx509_ca_tbs_set_ca(*hctx
, tbs
, 1);
916 ret
= hx509_ca_tbs_set_notAfter_lifetime(*hctx
, tbs
, lifetime
);
920 ret
= hx509_ca_tbs_set_unique(*hctx
, tbs
, &uniqueid
, &uniqueid
);
924 ret
= hx509_ca_tbs_set_serialnumber(*hctx
, tbs
, &serialnumber
);
928 ret
= hx509_ca_sign_self(*hctx
, tbs
, *private_key
, cert
);
932 hx509_name_free(&subject
);
933 free_SubjectPublicKeyInfo(&spki
);
934 hx509_ca_tbs_free(&tbs
);
939 hx509_ca_tbs_free(&tbs
);
941 free_SubjectPublicKeyInfo(&spki
);
943 hx509_name_free(&subject
);
945 talloc_free(uniqueid
.data
);
946 talloc_free(serialnumber
.data
);
947 return WERR_INTERNAL_ERROR
;
950 static WERROR
create_req(TALLOC_CTX
*ctx
, hx509_context
*hctx
, hx509_request
*req
,
951 hx509_private_key
*signer
,RSA
**rsa
, const char *dn
)
954 SubjectPublicKeyInfo key
;
959 werr
= create_heimdal_rsa_key(ctx
, hctx
, signer
, rsa
);
960 if (!W_ERROR_IS_OK(werr
)) {
964 hx509_request_init(*hctx
, req
);
965 ret
= hx509_parse_name(*hctx
, dn
, &name
);
968 hx509_private_key_free(signer
);
969 hx509_request_free(req
);
970 hx509_name_free(&name
);
971 return WERR_INTERNAL_ERROR
;
974 ret
= hx509_request_set_name(*hctx
, *req
, name
);
977 hx509_private_key_free(signer
);
978 hx509_request_free(req
);
979 hx509_name_free(&name
);
980 return WERR_INTERNAL_ERROR
;
982 hx509_name_free(&name
);
984 ret
= hx509_private_key2SPKI(*hctx
, *signer
, &key
);
987 hx509_private_key_free(signer
);
988 hx509_request_free(req
);
989 return WERR_INTERNAL_ERROR
;
991 ret
= hx509_request_set_SubjectPublicKeyInfo(*hctx
, *req
, &key
);
994 hx509_private_key_free(signer
);
995 free_SubjectPublicKeyInfo(&key
);
996 hx509_request_free(req
);
997 return WERR_INTERNAL_ERROR
;
1000 free_SubjectPublicKeyInfo(&key
);
1005 /* Return an error when we fail to generate a certificate */
1006 static WERROR
generate_bkrp_cert(TALLOC_CTX
*ctx
, struct dcesrv_call_state
*dce_call
, struct ldb_context
*ldb_ctx
, const char *dn
)
1008 heim_octet_string data
;
1012 hx509_private_key pk
;
1016 DATA_BLOB blobkeypair
;
1020 struct GUID guid
= GUID_random();
1023 struct bkrp_exported_RSA_key_pair keypair
;
1024 enum ndr_err_code ndr_err
;
1025 uint32_t nb_seconds_validity
= 3600 * 24 * 365;
1027 DEBUG(6, ("Trying to generate a certificate\n"));
1028 hx509_context_init(&hctx
);
1029 werr
= create_req(ctx
, &hctx
, &req
, &pk
, &rsa
, dn
);
1030 if (!W_ERROR_IS_OK(werr
)) {
1031 hx509_context_free(&hctx
);
1035 status
= GUID_to_ndr_blob(&guid
, ctx
, &blob
);
1036 if (!NT_STATUS_IS_OK(status
)) {
1037 hx509_context_free(&hctx
);
1038 hx509_private_key_free(&pk
);
1040 return WERR_INVALID_DATA
;
1043 werr
= self_sign_cert(ctx
, &hctx
, &req
, nb_seconds_validity
, &pk
, &cert
, &blob
);
1044 if (!W_ERROR_IS_OK(werr
)) {
1045 hx509_private_key_free(&pk
);
1046 hx509_context_free(&hctx
);
1047 return WERR_INVALID_DATA
;
1050 ret
= hx509_cert_binary(hctx
, cert
, &data
);
1052 hx509_cert_free(cert
);
1053 hx509_private_key_free(&pk
);
1054 hx509_context_free(&hctx
);
1055 return WERR_INVALID_DATA
;
1058 keypair
.cert
.data
= talloc_memdup(ctx
, data
.data
, data
.length
);
1059 keypair
.cert
.length
= data
.length
;
1062 * Heimdal's bignum are big endian and the
1063 * structure expect it to be in little endian
1064 * so we reverse the buffer to make it work
1066 tmp
= reverse_and_get_blob(ctx
, rsa
->e
);
1070 keypair
.public_exponent
= *tmp
;
1071 SMB_ASSERT(tmp
->length
<= 4);
1073 * The value is now in little endian but if can happen that the length is
1074 * less than 4 bytes.
1075 * So if we have less than 4 bytes we pad with zeros so that it correctly
1076 * fit into the structure.
1078 if (tmp
->length
< 4) {
1080 * We need the expo to fit 4 bytes
1082 keypair
.public_exponent
.data
= talloc_zero_array(ctx
, uint8_t, 4);
1083 memcpy(keypair
.public_exponent
.data
, tmp
->data
, tmp
->length
);
1084 keypair
.public_exponent
.length
= 4;
1088 tmp
= reverse_and_get_blob(ctx
,rsa
->d
);
1092 keypair
.private_exponent
= *tmp
;
1095 tmp
= reverse_and_get_blob(ctx
,rsa
->n
);
1099 keypair
.modulus
= *tmp
;
1102 tmp
= reverse_and_get_blob(ctx
,rsa
->p
);
1106 keypair
.prime1
= *tmp
;
1109 tmp
= reverse_and_get_blob(ctx
,rsa
->q
);
1113 keypair
.prime2
= *tmp
;
1116 tmp
= reverse_and_get_blob(ctx
,rsa
->dmp1
);
1120 keypair
.exponent1
= *tmp
;
1123 tmp
= reverse_and_get_blob(ctx
,rsa
->dmq1
);
1127 keypair
.exponent2
= *tmp
;
1130 tmp
= reverse_and_get_blob(ctx
,rsa
->iqmp
);
1134 keypair
.coefficient
= *tmp
;
1137 /* One of the keypair allocation was wrong */
1139 der_free_octet_string(&data
);
1140 hx509_cert_free(cert
);
1141 hx509_private_key_free(&pk
);
1142 hx509_context_free(&hctx
);
1144 return WERR_INVALID_DATA
;
1146 keypair
.certificate_len
= keypair
.cert
.length
;
1147 ndr_err
= ndr_push_struct_blob(&blobkeypair
, ctx
, &keypair
, (ndr_push_flags_fn_t
)ndr_push_bkrp_exported_RSA_key_pair
);
1148 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1149 der_free_octet_string(&data
);
1150 hx509_cert_free(cert
);
1151 hx509_private_key_free(&pk
);
1152 hx509_context_free(&hctx
);
1154 return WERR_INVALID_DATA
;
1157 secret_name
= talloc_asprintf(ctx
, "BCKUPKEY_%s", GUID_string(ctx
, &guid
));
1158 if (secret_name
== NULL
) {
1159 der_free_octet_string(&data
);
1160 hx509_cert_free(cert
);
1161 hx509_private_key_free(&pk
);
1162 hx509_context_free(&hctx
);
1164 return WERR_OUTOFMEMORY
;
1167 status
= set_lsa_secret(ctx
, ldb_ctx
, secret_name
, &blobkeypair
);
1168 if (!NT_STATUS_IS_OK(status
)) {
1169 DEBUG(2, ("Failed to save the secret %s\n", secret_name
));
1171 talloc_free(secret_name
);
1173 GUID_to_ndr_blob(&guid
, ctx
, &blob
);
1174 status
= set_lsa_secret(ctx
, ldb_ctx
, "BCKUPKEY_PREFERRED", &blob
);
1175 if (!NT_STATUS_IS_OK(status
)) {
1176 DEBUG(2, ("Failed to save the secret BCKUPKEY_PREFERRED\n"));
1179 der_free_octet_string(&data
);
1180 hx509_cert_free(cert
);
1181 hx509_private_key_free(&pk
);
1182 hx509_context_free(&hctx
);
1187 static WERROR
bkrp_retrieve_client_wrap_key(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1188 struct bkrp_BackupKey
*r
, struct ldb_context
*ldb_ctx
)
1193 enum ndr_err_code ndr_err
;
1197 * here we basicaly need to return our certificate
1198 * search for lsa secret BCKUPKEY_PREFERRED first
1201 status
= get_lsa_secret(mem_ctx
,
1203 "BCKUPKEY_PREFERRED",
1205 if (!NT_STATUS_IS_OK(status
)) {
1206 DEBUG(10, ("Error while fetching secret BCKUPKEY_PREFERRED\n"));
1207 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
1208 /* Ok we can be in this case if there was no certs */
1209 struct loadparm_context
*lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
1210 char *dn
= talloc_asprintf(mem_ctx
, "CN=%s",
1211 lpcfg_realm(lp_ctx
));
1213 WERROR werr
= generate_bkrp_cert(mem_ctx
, dce_call
, ldb_ctx
, dn
);
1214 if (!W_ERROR_IS_OK(werr
)) {
1215 return WERR_INVALID_PARAMETER
;
1217 status
= get_lsa_secret(mem_ctx
,
1219 "BCKUPKEY_PREFERRED",
1222 if (!NT_STATUS_IS_OK(status
)) {
1223 /* Ok we really don't manage to get this certs ...*/
1224 DEBUG(2, ("Unable to locate BCKUPKEY_PREFERRED after cert generation\n"));
1225 return WERR_FILE_NOT_FOUND
;
1228 /* In theory we should NEVER reach this point as it
1229 should only appear in a rodc server */
1230 /* we do not have the real secret attribute */
1231 return WERR_INVALID_PARAMETER
;
1235 if (secret
.length
!= 0) {
1236 char *cert_secret_name
;
1238 status
= GUID_from_ndr_blob(&secret
, &guid
);
1239 if (!NT_STATUS_IS_OK(status
)) {
1240 return WERR_FILE_NOT_FOUND
;
1243 guid_string
= GUID_string(mem_ctx
, &guid
);
1244 if (guid_string
== NULL
) {
1245 /* We return file not found because the client
1248 return WERR_FILE_NOT_FOUND
;
1251 cert_secret_name
= talloc_asprintf(mem_ctx
,
1254 status
= get_lsa_secret(mem_ctx
,
1258 if (!NT_STATUS_IS_OK(status
)) {
1259 return WERR_FILE_NOT_FOUND
;
1262 if (secret
.length
!= 0) {
1263 struct bkrp_exported_RSA_key_pair keypair
;
1264 ndr_err
= ndr_pull_struct_blob(&secret
, mem_ctx
, &keypair
,
1265 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_exported_RSA_key_pair
);
1266 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1267 return WERR_FILE_NOT_FOUND
;
1269 *(r
->out
.data_out_len
) = keypair
.cert
.length
;
1270 *(r
->out
.data_out
) = talloc_memdup(mem_ctx
, keypair
.cert
.data
, keypair
.cert
.length
);
1271 W_ERROR_HAVE_NO_MEMORY(*(r
->out
.data_out
));
1274 DEBUG(10, ("No or broken secret called %s\n", cert_secret_name
));
1275 return WERR_FILE_NOT_FOUND
;
1278 DEBUG(10, ("No secret BCKUPKEY_PREFERRED\n"));
1279 return WERR_FILE_NOT_FOUND
;
1282 return WERR_NOT_SUPPORTED
;
1285 static WERROR
bkrp_do_uncrypt_server_wrap_key(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1286 struct bkrp_BackupKey
*r
,struct ldb_context
*ldb_ctx
)
1288 return WERR_NOT_SUPPORTED
;
1291 static WERROR
bkrp_do_retrieve_server_wrap_key(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1292 struct bkrp_BackupKey
*r
,struct ldb_context
*ldb_ctx
)
1294 return WERR_NOT_SUPPORTED
;
1297 static WERROR
dcesrv_bkrp_BackupKey(struct dcesrv_call_state
*dce_call
,
1298 TALLOC_CTX
*mem_ctx
, struct bkrp_BackupKey
*r
)
1300 WERROR error
= WERR_INVALID_PARAM
;
1301 struct ldb_context
*ldb_ctx
;
1303 const char *addr
= "unknown";
1304 /* At which level we start to add more debug of what is done in the protocol */
1305 const int debuglevel
= 4;
1307 if (DEBUGLVL(debuglevel
)) {
1308 const struct tsocket_address
*remote_address
;
1309 remote_address
= dcesrv_connection_get_remote_address(dce_call
->conn
);
1310 if (tsocket_address_is_inet(remote_address
, "ip")) {
1311 addr
= tsocket_address_inet_addr_string(remote_address
, mem_ctx
);
1312 W_ERROR_HAVE_NO_MEMORY(addr
);
1316 if (lpcfg_server_role(dce_call
->conn
->dce_ctx
->lp_ctx
) != ROLE_ACTIVE_DIRECTORY_DC
) {
1317 return WERR_NOT_SUPPORTED
;
1320 if (!dce_call
->conn
->auth_state
.auth_info
||
1321 dce_call
->conn
->auth_state
.auth_info
->auth_level
!= DCERPC_AUTH_LEVEL_PRIVACY
) {
1322 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
1325 ldb_ctx
= samdb_connect(mem_ctx
, dce_call
->event_ctx
,
1326 dce_call
->conn
->dce_ctx
->lp_ctx
,
1327 system_session(dce_call
->conn
->dce_ctx
->lp_ctx
), 0);
1329 if (samdb_rodc(ldb_ctx
, &is_rodc
) != LDB_SUCCESS
) {
1330 talloc_unlink(mem_ctx
, ldb_ctx
);
1331 return WERR_INVALID_PARAM
;
1335 if(strncasecmp(GUID_string(mem_ctx
, r
->in
.guidActionAgent
),
1336 BACKUPKEY_RESTORE_GUID
, strlen(BACKUPKEY_RESTORE_GUID
)) == 0) {
1337 DEBUG(debuglevel
, ("Client %s requested to decrypt a client side wrapped secret\n", addr
));
1338 error
= bkrp_client_wrap_decrypt_data(dce_call
, mem_ctx
, r
, ldb_ctx
);
1341 if (strncasecmp(GUID_string(mem_ctx
, r
->in
.guidActionAgent
),
1342 BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID
, strlen(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID
)) == 0) {
1343 DEBUG(debuglevel
, ("Client %s requested certificate for client wrapped secret\n", addr
));
1344 error
= bkrp_retrieve_client_wrap_key(dce_call
, mem_ctx
, r
, ldb_ctx
);
1347 if (strncasecmp(GUID_string(mem_ctx
, r
->in
.guidActionAgent
),
1348 BACKUPKEY_RESTORE_GUID_WIN2K
, strlen(BACKUPKEY_RESTORE_GUID_WIN2K
)) == 0) {
1349 DEBUG(debuglevel
, ("Client %s requested to decrypt a server side wrapped secret, not implemented yet\n", addr
));
1350 error
= bkrp_do_uncrypt_server_wrap_key(dce_call
, mem_ctx
, r
, ldb_ctx
);
1353 if (strncasecmp(GUID_string(mem_ctx
, r
->in
.guidActionAgent
),
1354 BACKUPKEY_BACKUP_GUID
, strlen(BACKUPKEY_BACKUP_GUID
)) == 0) {
1355 DEBUG(debuglevel
, ("Client %s requested a server wrapped secret, not implemented yet\n", addr
));
1356 error
= bkrp_do_retrieve_server_wrap_key(dce_call
, mem_ctx
, r
, ldb_ctx
);
1359 /*else: I am a RODC so I don't handle backup key protocol */
1361 talloc_unlink(mem_ctx
, ldb_ctx
);
1365 /* include the generated boilerplate */
1366 #include "librpc/gen_ndr/ndr_backupkey_s.c"