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"
33 #include <hcrypto/rsa.h>
34 #include <hcrypto/bn.h>
35 #include <hcrypto/sha.h>
37 #include "../lib/tsocket/tsocket.h"
38 #include "../libcli/security/security.h"
40 #define BACKUPKEY_MIN_VERSION 2
41 #define BACKUPKEY_MAX_VERSION 3
43 static const unsigned rsa_with_var_num
[] = { 1, 2, 840, 113549, 1, 1, 1 };
44 /* Equivalent to asn1_oid_id_pkcs1_rsaEncryption*/
45 static const AlgorithmIdentifier _hx509_signature_rsa_with_var_num
= {
46 { 7, discard_const_p(unsigned, rsa_with_var_num
) }, NULL
49 static NTSTATUS
set_lsa_secret(TALLOC_CTX
*mem_ctx
,
50 struct ldb_context
*ldb
,
52 const DATA_BLOB
*secret
)
54 struct ldb_message
*msg
;
55 struct ldb_result
*res
;
56 struct ldb_dn
*domain_dn
;
57 struct ldb_dn
*system_dn
;
61 struct timeval now
= timeval_current();
62 NTTIME nt_now
= timeval_to_nttime(&now
);
63 const char *attrs
[] = {
67 domain_dn
= ldb_get_default_basedn(ldb
);
69 return NT_STATUS_INTERNAL_ERROR
;
72 msg
= ldb_msg_new(mem_ctx
);
74 return NT_STATUS_NO_MEMORY
;
78 * This function is a lot like dcesrv_lsa_CreateSecret
79 * in the rpc_server/lsa directory
80 * The reason why we duplicate the effort here is that:
81 * * we want to keep the former function static
82 * * we want to avoid the burden of doing LSA calls
83 * when we can just manipulate the secrets directly
84 * * taillor the function to the particular needs of backup protocol
87 system_dn
= samdb_search_dn(ldb
, msg
, domain_dn
, "(&(objectClass=container)(cn=System))");
88 if (system_dn
== NULL
) {
90 return NT_STATUS_NO_MEMORY
;
93 name2
= talloc_asprintf(msg
, "%s Secret", name
);
96 return NT_STATUS_NO_MEMORY
;
99 ret
= ldb_search(ldb
, mem_ctx
, &res
, system_dn
, LDB_SCOPE_SUBTREE
, attrs
,
100 "(&(cn=%s)(objectclass=secret))",
101 ldb_binary_encode_string(mem_ctx
, name2
));
103 if (ret
!= LDB_SUCCESS
|| res
->count
!= 0 ) {
104 DEBUG(2, ("Secret %s already exists !\n", name2
));
106 return NT_STATUS_OBJECT_NAME_COLLISION
;
110 * We don't care about previous value as we are
111 * here only if the key didn't exists before
114 msg
->dn
= ldb_dn_copy(mem_ctx
, system_dn
);
115 if (msg
->dn
== NULL
) {
117 return NT_STATUS_NO_MEMORY
;
119 if (!ldb_dn_add_child_fmt(msg
->dn
, "cn=%s", name2
)) {
121 return NT_STATUS_NO_MEMORY
;
124 ret
= ldb_msg_add_string(msg
, "cn", name2
);
125 if (ret
!= LDB_SUCCESS
) {
127 return NT_STATUS_NO_MEMORY
;
129 ret
= ldb_msg_add_string(msg
, "objectClass", "secret");
130 if (ret
!= LDB_SUCCESS
) {
132 return NT_STATUS_NO_MEMORY
;
134 ret
= samdb_msg_add_uint64(ldb
, mem_ctx
, msg
, "priorSetTime", nt_now
);
135 if (ret
!= LDB_SUCCESS
) {
137 return NT_STATUS_NO_MEMORY
;
139 val
.data
= secret
->data
;
140 val
.length
= secret
->length
;
141 ret
= ldb_msg_add_value(msg
, "currentValue", &val
, NULL
);
142 if (ret
!= LDB_SUCCESS
) {
144 return NT_STATUS_NO_MEMORY
;
146 ret
= samdb_msg_add_uint64(ldb
, mem_ctx
, msg
, "lastSetTime", nt_now
);
147 if (ret
!= LDB_SUCCESS
) {
149 return NT_STATUS_NO_MEMORY
;
153 * create the secret with DSDB_MODIFY_RELAX
154 * otherwise dsdb/samdb/ldb_modules/objectclass.c forbid
155 * the create of LSA secret object
157 ret
= dsdb_add(ldb
, msg
, DSDB_MODIFY_RELAX
);
158 if (ret
!= LDB_SUCCESS
) {
159 DEBUG(2,("Failed to create secret record %s: %s\n",
160 ldb_dn_get_linearized(msg
->dn
),
161 ldb_errstring(ldb
)));
163 return NT_STATUS_ACCESS_DENIED
;
170 /* This function is pretty much like dcesrv_lsa_QuerySecret */
171 static NTSTATUS
get_lsa_secret(TALLOC_CTX
*mem_ctx
,
172 struct ldb_context
*ldb
,
177 struct ldb_result
*res
;
178 struct ldb_dn
*domain_dn
;
179 struct ldb_dn
*system_dn
;
180 const struct ldb_val
*val
;
182 const char *attrs
[] = {
191 domain_dn
= ldb_get_default_basedn(ldb
);
193 return NT_STATUS_INTERNAL_ERROR
;
196 tmp_mem
= talloc_new(mem_ctx
);
197 if (tmp_mem
== NULL
) {
198 return NT_STATUS_NO_MEMORY
;
201 system_dn
= samdb_search_dn(ldb
, tmp_mem
, domain_dn
, "(&(objectClass=container)(cn=System))");
202 if (system_dn
== NULL
) {
203 talloc_free(tmp_mem
);
204 return NT_STATUS_NO_MEMORY
;
207 ret
= ldb_search(ldb
, mem_ctx
, &res
, system_dn
, LDB_SCOPE_SUBTREE
, attrs
,
208 "(&(cn=%s Secret)(objectclass=secret))",
209 ldb_binary_encode_string(tmp_mem
, name
));
211 if (ret
!= LDB_SUCCESS
|| res
->count
== 0) {
212 talloc_free(tmp_mem
);
214 * Important NOT to use NT_STATUS_OBJECT_NAME_NOT_FOUND
215 * as this return value is used to detect the case
216 * when we have the secret but without the currentValue
219 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 talloc_free(tmp_mem
);
235 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
239 secret
->data
= talloc_move(mem_ctx
, &data
);
240 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 dom_sid
**access_sid
)
384 heim_octet_string iv
;
385 heim_octet_string access_check_os
;
392 enum ndr_err_code ndr_err
;
395 /* This one should not be freed */
396 const AlgorithmIdentifier
*alg
;
403 alg
= hx509_crypto_des_rsdi_ede3_cbc();
409 alg
=hx509_crypto_aes256_cbc();
413 return WERR_INVALID_DATA
;
416 hx509_context_init(&hctx
);
417 res
= hx509_crypto_init(hctx
, NULL
,
420 hx509_context_free(&hctx
);
423 return WERR_INVALID_DATA
;
426 res
= hx509_crypto_set_key_data(crypto
, key_and_iv
, key_len
);
428 iv
.data
= talloc_memdup(sub_ctx
, key_len
+ key_and_iv
, iv_len
);
432 hx509_crypto_destroy(crypto
);
433 return WERR_INVALID_DATA
;
436 hx509_crypto_set_padding(crypto
, HX509_CRYPTO_PADDING_NONE
);
437 res
= hx509_crypto_decrypt(crypto
,
444 hx509_crypto_destroy(crypto
);
445 return WERR_INVALID_DATA
;
448 blob_us
.data
= access_check_os
.data
;
449 blob_us
.length
= access_check_os
.length
;
451 hx509_crypto_destroy(crypto
);
454 uint32_t hash_size
= 20;
455 uint8_t hash
[hash_size
];
457 struct bkrp_access_check_v2 uncrypted_accesscheckv2
;
459 ndr_err
= ndr_pull_struct_blob(&blob_us
, sub_ctx
, &uncrypted_accesscheckv2
,
460 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_access_check_v2
);
461 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
462 /* Unable to unmarshall */
463 der_free_octet_string(&access_check_os
);
464 return WERR_INVALID_DATA
;
466 if (uncrypted_accesscheckv2
.magic
!= 0x1) {
468 der_free_octet_string(&access_check_os
);
469 return WERR_INVALID_DATA
;
473 SHA1_Update(&sctx
, blob_us
.data
, blob_us
.length
- hash_size
);
474 SHA1_Final(hash
, &sctx
);
475 der_free_octet_string(&access_check_os
);
477 * We free it after the sha1 calculation because blob.data
478 * point to the same area
481 if (memcmp(hash
, uncrypted_accesscheckv2
.hash
, hash_size
) != 0) {
482 DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
483 return WERR_INVALID_DATA
;
485 *access_sid
= dom_sid_dup(sub_ctx
, &(uncrypted_accesscheckv2
.sid
));
486 if (*access_sid
== NULL
) {
493 uint32_t hash_size
= 64;
494 uint8_t hash
[hash_size
];
495 struct hc_sha512state sctx
;
496 struct bkrp_access_check_v3 uncrypted_accesscheckv3
;
498 ndr_err
= ndr_pull_struct_blob(&blob_us
, sub_ctx
, &uncrypted_accesscheckv3
,
499 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_access_check_v3
);
500 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
501 /* Unable to unmarshall */
502 der_free_octet_string(&access_check_os
);
503 return WERR_INVALID_DATA
;
505 if (uncrypted_accesscheckv3
.magic
!= 0x1) {
507 der_free_octet_string(&access_check_os
);
508 return WERR_INVALID_DATA
;
512 SHA512_Update(&sctx
, blob_us
.data
, blob_us
.length
- hash_size
);
513 SHA512_Final(hash
, &sctx
);
514 der_free_octet_string(&access_check_os
);
516 * We free it after the sha1 calculation because blob.data
517 * point to the same area
520 if (memcmp(hash
, uncrypted_accesscheckv3
.hash
, hash_size
) != 0) {
521 DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
522 return WERR_INVALID_DATA
;
524 *access_sid
= dom_sid_dup(sub_ctx
, &(uncrypted_accesscheckv3
.sid
));
525 if (*access_sid
== NULL
) {
531 /* Never reached normally as we filtered at the switch / case level */
532 return WERR_INVALID_DATA
;
535 static WERROR
bkrp_do_uncrypt_client_wrap_key(struct dcesrv_call_state
*dce_call
,
537 struct bkrp_BackupKey
*r
,
538 struct ldb_context
*ldb_ctx
)
540 struct bkrp_client_side_wrapped uncrypt_request
;
542 enum ndr_err_code ndr_err
;
544 char *cert_secret_name
;
546 DATA_BLOB
*uncrypted
;
549 blob
.data
= r
->in
.data_in
;
550 blob
.length
= r
->in
.data_in_len
;
552 if (r
->in
.data_in_len
== 0 || r
->in
.data_in
== NULL
) {
553 return WERR_INVALID_PARAM
;
556 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &uncrypt_request
,
557 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_wrapped
);
558 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
559 return WERR_INVALID_PARAM
;
562 if (uncrypt_request
.version
< BACKUPKEY_MIN_VERSION
) {
563 return WERR_INVALID_PARAMETER
;
566 if (uncrypt_request
.version
> BACKUPKEY_MAX_VERSION
) {
567 return WERR_INVALID_PARAMETER
;
570 guid_string
= GUID_string(mem_ctx
, &uncrypt_request
.guid
);
571 if (guid_string
== NULL
) {
575 cert_secret_name
= talloc_asprintf(mem_ctx
,
578 if (cert_secret_name
== NULL
) {
582 status
= get_lsa_secret(mem_ctx
,
586 if (!NT_STATUS_IS_OK(status
)) {
587 DEBUG(10, ("Error while fetching secret %s\n", cert_secret_name
));
588 if (NT_STATUS_EQUAL(status
,NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
589 /* we do not have the real secret attribute */
590 return WERR_INVALID_PARAMETER
;
592 return WERR_FILE_NOT_FOUND
;
596 if (secret
.length
!= 0) {
598 struct bkrp_exported_RSA_key_pair keypair
;
599 hx509_private_key pk
;
601 struct dom_sid
*access_sid
= NULL
;
602 heim_octet_string reversed_secret
;
603 heim_octet_string uncrypted_secret
;
604 AlgorithmIdentifier alg
;
605 struct dom_sid
*caller_sid
;
609 ndr_err
= ndr_pull_struct_blob(&secret
, mem_ctx
, &keypair
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_exported_RSA_key_pair
);
610 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
611 DEBUG(2, ("Unable to parse the ndr encoded cert in key %s\n", cert_secret_name
));
612 return WERR_FILE_NOT_FOUND
;
615 status
= get_pk_from_raw_keypair_params(mem_ctx
, &keypair
, &pk
);
616 if (!NT_STATUS_IS_OK(status
)) {
617 return WERR_INTERNAL_ERROR
;
620 reversed_secret
.data
= talloc_array(mem_ctx
, uint8_t,
621 uncrypt_request
.encrypted_secret_len
);
622 if (reversed_secret
.data
== NULL
) {
623 hx509_private_key_free(&pk
);
627 /* The secret has to be reversed ... */
628 for(i
=0; i
< uncrypt_request
.encrypted_secret_len
; i
++) {
629 uint8_t *reversed
= (uint8_t *)reversed_secret
.data
;
630 uint8_t *uncrypt
= uncrypt_request
.encrypted_secret
;
631 reversed
[i
] = uncrypt
[uncrypt_request
.encrypted_secret_len
- 1 - i
];
633 reversed_secret
.length
= uncrypt_request
.encrypted_secret_len
;
636 * Let's try to decrypt the secret now that
637 * we have the private key ...
639 hx509_context_init(&hctx
);
640 res
= hx509_private_key_private_decrypt(hctx
, &reversed_secret
,
643 hx509_context_free(&hctx
);
644 hx509_private_key_free(&pk
);
646 /* We are not able to decrypt the secret, looks like something is wrong */
647 return WERR_INVALID_DATA
;
649 blob_us
.data
= uncrypted_secret
.data
;
650 blob_us
.length
= uncrypted_secret
.length
;
652 if (uncrypt_request
.version
== 2) {
653 struct bkrp_encrypted_secret_v2 uncrypted_secretv2
;
655 ndr_err
= ndr_pull_struct_blob(&blob_us
, mem_ctx
, &uncrypted_secretv2
,
656 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_encrypted_secret_v2
);
657 der_free_octet_string(&uncrypted_secret
);
658 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
659 /* Unable to unmarshall */
660 return WERR_INVALID_DATA
;
662 if (uncrypted_secretv2
.magic
!= 0x20) {
664 return WERR_INVALID_DATA
;
667 werr
= get_and_verify_access_check(mem_ctx
, 2,
668 uncrypted_secretv2
.payload_key
,
669 uncrypt_request
.access_check
,
670 uncrypt_request
.access_check_len
,
672 if (!W_ERROR_IS_OK(werr
)) {
675 uncrypted
= talloc(mem_ctx
, DATA_BLOB
);
676 if (uncrypted
== NULL
) {
677 return WERR_INVALID_DATA
;
680 uncrypted
->data
= uncrypted_secretv2
.secret
;
681 uncrypted
->length
= uncrypted_secretv2
.secret_len
;
683 if (uncrypt_request
.version
== 3) {
684 struct bkrp_encrypted_secret_v3 uncrypted_secretv3
;
686 ndr_err
= ndr_pull_struct_blob(&blob_us
, mem_ctx
, &uncrypted_secretv3
,
687 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_encrypted_secret_v3
);
689 der_free_octet_string(&uncrypted_secret
);
690 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
691 /* Unable to unmarshall */
692 return WERR_INVALID_DATA
;
695 if (uncrypted_secretv3
.magic1
!= 0x30 ||
696 uncrypted_secretv3
.magic2
!= 0x6610 ||
697 uncrypted_secretv3
.magic3
!= 0x800e) {
699 return WERR_INVALID_DATA
;
702 werr
= get_and_verify_access_check(mem_ctx
, 3,
703 uncrypted_secretv3
.payload_key
,
704 uncrypt_request
.access_check
,
705 uncrypt_request
.access_check_len
,
707 if (!W_ERROR_IS_OK(werr
)) {
711 uncrypted
= talloc(mem_ctx
, DATA_BLOB
);
712 if (uncrypted
== NULL
) {
713 return WERR_INVALID_DATA
;
716 uncrypted
->data
= uncrypted_secretv3
.secret
;
717 uncrypted
->length
= uncrypted_secretv3
.secret_len
;
720 caller_sid
= &dce_call
->conn
->auth_state
.session_info
->security_token
->sids
[PRIMARY_USER_SID_INDEX
];
722 if (!dom_sid_equal(caller_sid
, access_sid
)) {
723 talloc_free(uncrypted
);
724 return WERR_INVALID_ACCESS
;
728 * Yeah if we are here all looks pretty good:
730 * - user sid is the same as the one in access check
731 * - we were able to decrypt the whole stuff
735 if (uncrypted
->data
== NULL
) {
736 return WERR_INVALID_DATA
;
739 /* There is a magic value a the beginning of the data
740 * we can use an adhoc structure but as the
741 * parent structure is just an array of bytes it a lot of work
742 * work just prepending 4 bytes
744 *(r
->out
.data_out
) = talloc_zero_array(mem_ctx
, uint8_t, uncrypted
->length
+ 4);
745 W_ERROR_HAVE_NO_MEMORY(*(r
->out
.data_out
));
746 memcpy(4+*(r
->out
.data_out
), uncrypted
->data
, uncrypted
->length
);
747 *(r
->out
.data_out_len
) = uncrypted
->length
+ 4;
752 static WERROR
create_heimdal_rsa_key(TALLOC_CTX
*ctx
, hx509_context
*hctx
,
753 hx509_private_key
*pk
, RSA
**_rsa
)
765 if(pub_expo
== NULL
) {
766 return WERR_INTERNAL_ERROR
;
769 /* set the public expo to 65537 like everyone */
770 BN_set_word(pub_expo
, 0x10001);
775 return WERR_INTERNAL_ERROR
;
778 ret
= RSA_generate_key_ex(rsa
, bits
, pub_expo
, NULL
);
782 return WERR_INTERNAL_ERROR
;
786 len
= i2d_RSAPrivateKey(rsa
, NULL
);
789 return WERR_INTERNAL_ERROR
;
792 p0
= p
= talloc_array(ctx
, uint8_t, len
);
795 return WERR_INTERNAL_ERROR
;
798 len
= i2d_RSAPrivateKey(rsa
, &p
);
802 return WERR_INTERNAL_ERROR
;
806 * To dump the key we can use :
807 * rk_dumpdata("h5lkey", p0, len);
809 ret
= hx509_parse_private_key(*hctx
, &_hx509_signature_rsa_with_var_num
,
810 p0
, len
, HX509_KEY_FORMAT_DER
, pk
);
815 return WERR_INTERNAL_ERROR
;
822 static WERROR
self_sign_cert(TALLOC_CTX
*ctx
, hx509_context
*hctx
, hx509_request
*req
,
823 time_t lifetime
, hx509_private_key
*private_key
,
824 hx509_cert
*cert
, DATA_BLOB
*guidblob
)
826 SubjectPublicKeyInfo spki
;
827 hx509_name subject
= NULL
;
829 struct heim_bit_string uniqueid
;
832 uniqueid
.data
= talloc_memdup(ctx
, guidblob
->data
, guidblob
->length
);
833 /* uniqueid is a bit string in which each byte represent 1 bit (1 or 0)
834 * so as 1 byte is 8 bits we need to provision 8 times more space as in the
837 uniqueid
.length
= 8 * guidblob
->length
;
839 memset(&spki
, 0, sizeof(spki
));
841 ret
= hx509_request_get_name(*hctx
, *req
, &subject
);
843 talloc_free(uniqueid
.data
);
844 return WERR_INTERNAL_ERROR
;
846 ret
= hx509_request_get_SubjectPublicKeyInfo(*hctx
, *req
, &spki
);
848 talloc_free(uniqueid
.data
);
849 hx509_name_free(&subject
);
850 return WERR_INTERNAL_ERROR
;
853 ret
= hx509_ca_tbs_init(*hctx
, &tbs
);
855 talloc_free(uniqueid
.data
);
856 hx509_name_free(&subject
);
857 free_SubjectPublicKeyInfo(&spki
);
858 return WERR_INTERNAL_ERROR
;
861 ret
= hx509_ca_tbs_set_spki(*hctx
, tbs
, &spki
);
863 talloc_free(uniqueid
.data
);
864 hx509_name_free(&subject
);
865 free_SubjectPublicKeyInfo(&spki
);
866 return WERR_INTERNAL_ERROR
;
868 ret
= hx509_ca_tbs_set_subject(*hctx
, tbs
, subject
);
870 talloc_free(uniqueid
.data
);
871 hx509_name_free(&subject
);
872 free_SubjectPublicKeyInfo(&spki
);
873 hx509_ca_tbs_free(&tbs
);
874 return WERR_INTERNAL_ERROR
;
876 ret
= hx509_ca_tbs_set_ca(*hctx
, tbs
, 1);
878 talloc_free(uniqueid
.data
);
879 hx509_name_free(&subject
);
880 free_SubjectPublicKeyInfo(&spki
);
881 hx509_ca_tbs_free(&tbs
);
882 return WERR_INTERNAL_ERROR
;
884 ret
= hx509_ca_tbs_set_notAfter_lifetime(*hctx
, tbs
, lifetime
);
886 talloc_free(uniqueid
.data
);
887 hx509_name_free(&subject
);
888 free_SubjectPublicKeyInfo(&spki
);
889 hx509_ca_tbs_free(&tbs
);
890 return WERR_INTERNAL_ERROR
;
892 ret
= hx509_ca_tbs_set_unique(*hctx
, tbs
, &uniqueid
, &uniqueid
);
894 talloc_free(uniqueid
.data
);
895 hx509_name_free(&subject
);
896 free_SubjectPublicKeyInfo(&spki
);
897 hx509_ca_tbs_free(&tbs
);
898 return WERR_INTERNAL_ERROR
;
900 ret
= hx509_ca_sign_self(*hctx
, tbs
, *private_key
, cert
);
902 talloc_free(uniqueid
.data
);
903 hx509_name_free(&subject
);
904 free_SubjectPublicKeyInfo(&spki
);
905 hx509_ca_tbs_free(&tbs
);
906 return WERR_INTERNAL_ERROR
;
908 hx509_name_free(&subject
);
909 free_SubjectPublicKeyInfo(&spki
);
910 hx509_ca_tbs_free(&tbs
);
915 static WERROR
create_req(TALLOC_CTX
*ctx
, hx509_context
*hctx
, hx509_request
*req
,
916 hx509_private_key
*signer
,RSA
**rsa
, const char *dn
)
919 SubjectPublicKeyInfo key
;
924 w_err
= create_heimdal_rsa_key(ctx
, hctx
, signer
, rsa
);
925 if (!W_ERROR_IS_OK(w_err
)) {
929 hx509_request_init(*hctx
, req
);
930 ret
= hx509_parse_name(*hctx
, dn
, &name
);
933 hx509_private_key_free(signer
);
934 hx509_request_free(req
);
935 hx509_name_free(&name
);
936 return WERR_INTERNAL_ERROR
;
939 ret
= hx509_request_set_name(*hctx
, *req
, name
);
942 hx509_private_key_free(signer
);
943 hx509_request_free(req
);
944 hx509_name_free(&name
);
945 return WERR_INTERNAL_ERROR
;
947 hx509_name_free(&name
);
949 ret
= hx509_private_key2SPKI(*hctx
, *signer
, &key
);
952 hx509_private_key_free(signer
);
953 hx509_request_free(req
);
954 return WERR_INTERNAL_ERROR
;
956 ret
= hx509_request_set_SubjectPublicKeyInfo(*hctx
, *req
, &key
);
959 hx509_private_key_free(signer
);
960 free_SubjectPublicKeyInfo(&key
);
961 hx509_request_free(req
);
962 return WERR_INTERNAL_ERROR
;
965 free_SubjectPublicKeyInfo(&key
);
970 /* Return an error when we fail to generate a certificate */
971 static WERROR
generate_bkrp_cert(TALLOC_CTX
*ctx
, struct dcesrv_call_state
*dce_call
, struct ldb_context
*ldb_ctx
, const char *dn
)
974 struct heim_octet_string data
;
978 hx509_private_key pk
;
982 DATA_BLOB blobkeypair
;
986 struct GUID guid
= GUID_random();
989 struct bkrp_exported_RSA_key_pair keypair
;
990 enum ndr_err_code ndr_err
;
991 uint32_t nb_days_validity
= 365;
993 DEBUG(6, ("Trying to generate a certificate\n"));
994 hx509_context_init(&hctx
);
995 w_err
= create_req(ctx
, &hctx
, &req
, &pk
, &rsa
, dn
);
996 if (!W_ERROR_IS_OK(w_err
)) {
997 hx509_context_free(&hctx
);
1001 status
= GUID_to_ndr_blob(&guid
, ctx
, &blob
);
1002 if (!NT_STATUS_IS_OK(status
)) {
1003 hx509_context_free(&hctx
);
1004 hx509_private_key_free(&pk
);
1006 return WERR_INVALID_DATA
;
1009 w_err
= self_sign_cert(ctx
, &hctx
, &req
, nb_days_validity
, &pk
, &cert
, &blob
);
1010 if (!W_ERROR_IS_OK(w_err
)) {
1011 hx509_private_key_free(&pk
);
1012 hx509_context_free(&hctx
);
1013 return WERR_INVALID_DATA
;
1016 ret
= hx509_cert_binary(hctx
, cert
, &data
);
1018 hx509_cert_free(cert
);
1019 hx509_private_key_free(&pk
);
1020 hx509_context_free(&hctx
);
1021 return WERR_INVALID_DATA
;
1024 keypair
.cert
.data
= talloc_memdup(ctx
, data
.data
, data
.length
);
1025 keypair
.cert
.length
= data
.length
;
1028 * Heimdal's bignum are big endian and the
1029 * structure expect it to be in little endian
1030 * so we reverse the buffer to make it work
1032 tmp
= reverse_and_get_blob(ctx
, rsa
->e
);
1036 keypair
.public_exponent
= *tmp
;
1037 SMB_ASSERT(tmp
->length
<= 4);
1039 * The value is now in little endian but if can happen that the length is
1040 * less than 4 bytes.
1041 * So if we have less than 4 bytes we pad with zeros so that it correctly
1042 * fit into the structure.
1044 if (tmp
->length
< 4) {
1046 * We need the expo to fit 4 bytes
1048 keypair
.public_exponent
.data
= talloc_zero_array(ctx
, uint8_t, 4);
1049 memcpy(keypair
.public_exponent
.data
, tmp
->data
, tmp
->length
);
1050 keypair
.public_exponent
.length
= 4;
1054 tmp
= reverse_and_get_blob(ctx
,rsa
->d
);
1058 keypair
.private_exponent
= *tmp
;
1061 tmp
= reverse_and_get_blob(ctx
,rsa
->n
);
1065 keypair
.modulus
= *tmp
;
1068 tmp
= reverse_and_get_blob(ctx
,rsa
->p
);
1072 keypair
.prime1
= *tmp
;
1075 tmp
= reverse_and_get_blob(ctx
,rsa
->q
);
1079 keypair
.prime2
= *tmp
;
1082 tmp
= reverse_and_get_blob(ctx
,rsa
->dmp1
);
1086 keypair
.exponent1
= *tmp
;
1089 tmp
= reverse_and_get_blob(ctx
,rsa
->dmq1
);
1093 keypair
.exponent2
= *tmp
;
1096 tmp
= reverse_and_get_blob(ctx
,rsa
->iqmp
);
1100 keypair
.coefficient
= *tmp
;
1103 /* One of the keypair allocation was wrong */
1105 der_free_octet_string(&data
);
1106 hx509_cert_free(cert
);
1107 hx509_private_key_free(&pk
);
1108 hx509_context_free(&hctx
);
1110 return WERR_INVALID_DATA
;
1112 keypair
.certificate_len
= keypair
.cert
.length
;
1113 ndr_err
= ndr_push_struct_blob(&blobkeypair
, ctx
, &keypair
, (ndr_push_flags_fn_t
)ndr_push_bkrp_exported_RSA_key_pair
);
1114 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1115 der_free_octet_string(&data
);
1116 hx509_cert_free(cert
);
1117 hx509_private_key_free(&pk
);
1118 hx509_context_free(&hctx
);
1120 return WERR_INVALID_DATA
;
1123 secret_name
= talloc_asprintf(ctx
, "BCKUPKEY_%s", GUID_string(ctx
, &guid
));
1124 if (secret_name
== NULL
) {
1125 der_free_octet_string(&data
);
1126 hx509_cert_free(cert
);
1127 hx509_private_key_free(&pk
);
1128 hx509_context_free(&hctx
);
1130 return WERR_OUTOFMEMORY
;
1133 status
= set_lsa_secret(ctx
, ldb_ctx
, secret_name
, &blobkeypair
);
1134 if (!NT_STATUS_IS_OK(status
)) {
1135 DEBUG(2, ("Failed to save the secret %s\n", secret_name
));
1137 talloc_free(secret_name
);
1139 GUID_to_ndr_blob(&guid
, ctx
, &blob
);
1140 status
= set_lsa_secret(ctx
, ldb_ctx
, "BCKUPKEY_PREFERRED", &blob
);
1141 if (!NT_STATUS_IS_OK(status
)) {
1142 DEBUG(2, ("Failed to save the secret BCKUPKEY_PREFERRED\n"));
1145 der_free_octet_string(&data
);
1146 hx509_cert_free(cert
);
1147 hx509_private_key_free(&pk
);
1148 hx509_context_free(&hctx
);
1153 static WERROR
bkrp_do_retreive_client_wrap_key(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
1154 struct bkrp_BackupKey
*r
,struct ldb_context
*ldb_ctx
)
1159 enum ndr_err_code ndr_err
;
1163 * here we basicaly need to return our certificate
1164 * search for lsa secret BCKUPKEY_PREFERRED first
1167 status
= get_lsa_secret(mem_ctx
,
1169 "BCKUPKEY_PREFERRED",
1171 if (!NT_STATUS_IS_OK(status
)) {
1172 DEBUG(10, ("Error while fetching secret BCKUPKEY_PREFERRED\n"));
1173 if (!NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
1174 /* Ok we can be in this case if there was no certs */
1175 struct loadparm_context
*lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
1176 char *dn
= talloc_asprintf(mem_ctx
, "CN=%s.%s",
1177 lpcfg_netbios_name(lp_ctx
),
1178 lpcfg_realm(lp_ctx
));
1180 WERROR werr
= generate_bkrp_cert(mem_ctx
, dce_call
, ldb_ctx
, dn
);
1181 if (!W_ERROR_IS_OK(werr
)) {
1182 return WERR_INVALID_PARAMETER
;
1184 status
= get_lsa_secret(mem_ctx
,
1186 "BCKUPKEY_PREFERRED",
1189 if (!NT_STATUS_IS_OK(status
)) {
1190 /* Ok we really don't manage to get this certs ...*/
1191 DEBUG(2, ("Unable to locate BCKUPKEY_PREFERRED after cert generation\n"));
1192 return WERR_FILE_NOT_FOUND
;
1195 /* In theory we should NEVER reach this point as it
1196 should only appear in a rodc server */
1197 /* we do not have the real secret attribute */
1198 return WERR_INVALID_PARAMETER
;
1202 if (secret
.length
!= 0) {
1203 char *cert_secret_name
;
1205 status
= GUID_from_ndr_blob(&secret
, &guid
);
1206 if (!NT_STATUS_IS_OK(status
)) {
1207 return WERR_FILE_NOT_FOUND
;
1210 guid_string
= GUID_string(mem_ctx
, &guid
);
1211 if (guid_string
== NULL
) {
1212 /* We return file not found because the client
1215 return WERR_FILE_NOT_FOUND
;
1218 cert_secret_name
= talloc_asprintf(mem_ctx
,
1221 status
= get_lsa_secret(mem_ctx
,
1225 if (!NT_STATUS_IS_OK(status
)) {
1226 return WERR_FILE_NOT_FOUND
;
1229 if (secret
.length
!= 0) {
1230 struct bkrp_exported_RSA_key_pair keypair
;
1231 ndr_err
= ndr_pull_struct_blob(&secret
, mem_ctx
, &keypair
,
1232 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_exported_RSA_key_pair
);
1233 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1234 return WERR_FILE_NOT_FOUND
;
1236 *(r
->out
.data_out_len
) = keypair
.cert
.length
;
1237 *(r
->out
.data_out
) = talloc_memdup(mem_ctx
, keypair
.cert
.data
, keypair
.cert
.length
);
1238 W_ERROR_HAVE_NO_MEMORY(*(r
->out
.data_out
));
1241 DEBUG(10, ("No or broken secret called %s\n", cert_secret_name
));
1242 return WERR_FILE_NOT_FOUND
;
1245 DEBUG(10, ("No secret BCKUPKEY_PREFERRED\n"));
1246 return WERR_FILE_NOT_FOUND
;
1249 return WERR_NOT_SUPPORTED
;
1252 static WERROR
dcesrv_bkrp_BackupKey(struct dcesrv_call_state
*dce_call
,
1253 TALLOC_CTX
*mem_ctx
, struct bkrp_BackupKey
*r
)
1255 WERROR error
= WERR_INVALID_PARAM
;
1256 struct ldb_context
*ldb_ctx
;
1258 const char *addr
= "unknown";
1259 /* At which level we start to add more debug of what is done in the protocol */
1260 const int debuglevel
= 4;
1262 if (DEBUGLVL(debuglevel
)) {
1263 const struct tsocket_address
*remote_address
;
1264 remote_address
= dcesrv_connection_get_remote_address(dce_call
->conn
);
1265 if (tsocket_address_is_inet(remote_address
, "ip")) {
1266 addr
= tsocket_address_inet_addr_string(remote_address
, mem_ctx
);
1267 W_ERROR_HAVE_NO_MEMORY(addr
);
1271 if (lpcfg_server_role(dce_call
->conn
->dce_ctx
->lp_ctx
) != ROLE_DOMAIN_CONTROLLER
) {
1272 return WERR_NOT_SUPPORTED
;
1275 if (!dce_call
->conn
->auth_state
.auth_info
||
1276 dce_call
->conn
->auth_state
.auth_info
->auth_level
!= DCERPC_AUTH_LEVEL_PRIVACY
) {
1277 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED
);
1280 ldb_ctx
= samdb_connect(mem_ctx
, dce_call
->event_ctx
,
1281 dce_call
->conn
->dce_ctx
->lp_ctx
,
1282 system_session(dce_call
->conn
->dce_ctx
->lp_ctx
), 0);
1284 if (samdb_rodc(ldb_ctx
, &is_rodc
) != LDB_SUCCESS
) {
1285 talloc_unlink(mem_ctx
, ldb_ctx
);
1286 return WERR_INVALID_PARAM
;
1290 if(strncasecmp(GUID_string(mem_ctx
, r
->in
.guidActionAgent
),
1291 BACKUPKEY_RESTORE_GUID
, strlen(BACKUPKEY_RESTORE_GUID
)) == 0) {
1292 DEBUG(debuglevel
, ("Client %s requested to decrypt a client side wrapped secret\n", addr
));
1293 error
= bkrp_do_uncrypt_client_wrap_key(dce_call
, mem_ctx
, r
, ldb_ctx
);
1296 if (strncasecmp(GUID_string(mem_ctx
, r
->in
.guidActionAgent
),
1297 BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID
, strlen(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID
)) == 0) {
1298 DEBUG(debuglevel
, ("Client %s requested certificate for client wrapped secret\n", addr
));
1299 error
= bkrp_do_retreive_client_wrap_key(dce_call
, mem_ctx
, r
, ldb_ctx
);
1302 /*else: I am a RODC so I don't handle backup key protocol */
1304 talloc_unlink(mem_ctx
, ldb_ctx
);
1308 /* include the generated boilerplate */
1309 #include "librpc/gen_ndr/ndr_backupkey_s.c"