2 Unix SMB/CIFS implementation.
3 test suite for backupkey remote protocol rpc operations
5 Copyright (C) Matthieu Patou 2010-2011
6 Copyright (C) Andreas Schneider <asn@samba.org> 2015
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 "../libcli/security/security.h"
25 #include "torture/rpc/torture_rpc.h"
26 #include "torture/ndr/ndr.h"
28 #include "librpc/gen_ndr/ndr_backupkey_c.h"
29 #include "librpc/gen_ndr/ndr_backupkey.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "librpc/gen_ndr/ndr_security.h"
32 #include "lib/cmdline/popt_common.h"
33 #include "libcli/auth/proto.h"
34 #include <system/network.h>
36 #include <gnutls/gnutls.h>
37 #include <gnutls/crypto.h>
38 #include <gnutls/x509.h>
39 #include <gnutls/abstract.h>
45 WRONG_CIPHERTEXT_LENGTH
,
47 SHORT_CIPHERTEXT_LENGTH
,
49 ZERO_CIPHERTEXT_LENGTH
,
55 /* Our very special and valued secret */
56 /* No need to put const as we cast the array in uint8_t
57 * we will get a warning about the discared const
59 static const char secret
[] = "tata yoyo mais qu'est ce qu'il y a sous ton grand chapeau ?";
61 /* Get the SID from a user */
62 static struct dom_sid
*get_user_sid(struct torture_context
*tctx
,
66 struct lsa_ObjectAttribute attr
;
67 struct lsa_QosInfo qos
;
68 struct lsa_OpenPolicy2 r
;
71 struct policy_handle handle
;
72 struct lsa_LookupNames l
;
73 struct lsa_TransSidArray sids
;
74 struct lsa_RefDomainList
*domains
= NULL
;
75 struct lsa_String lsa_name
;
77 struct dom_sid
*result
;
79 struct dcerpc_pipe
*p2
;
80 struct dcerpc_binding_handle
*b
;
82 const char *domain
= cli_credentials_get_domain(
83 popt_get_cmdline_credentials());
85 torture_assert_ntstatus_ok(tctx
,
86 torture_rpc_connection(tctx
, &p2
, &ndr_table_lsarpc
),
87 "could not open lsarpc pipe");
88 b
= p2
->binding_handle
;
90 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
94 qos
.impersonation_level
= 2;
96 qos
.effective_only
= 0;
100 attr
.object_name
= NULL
;
102 attr
.sec_desc
= NULL
;
105 r
.in
.system_name
= "\\";
107 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
108 r
.out
.handle
= &handle
;
110 status
= dcerpc_lsa_OpenPolicy2_r(b
, tmp_ctx
, &r
);
111 if (!NT_STATUS_IS_OK(status
)) {
112 torture_comment(tctx
,
113 "OpenPolicy2 failed - %s\n",
115 talloc_free(tmp_ctx
);
118 if (!NT_STATUS_IS_OK(r
.out
.result
)) {
119 torture_comment(tctx
,
120 "OpenPolicy2_ failed - %s\n",
121 nt_errstr(r
.out
.result
));
122 talloc_free(tmp_ctx
);
129 lsa_name
.string
= talloc_asprintf(tmp_ctx
, "%s\\%s", domain
, user
);
131 l
.in
.handle
= &handle
;
133 l
.in
.names
= &lsa_name
;
137 l
.out
.count
= &count
;
139 l
.out
.domains
= &domains
;
141 status
= dcerpc_lsa_LookupNames_r(b
, tmp_ctx
, &l
);
142 if (!NT_STATUS_IS_OK(status
)) {
143 torture_comment(tctx
,
144 "LookupNames of %s failed - %s\n",
147 talloc_free(tmp_ctx
);
151 if (domains
->count
== 0) {
155 result
= dom_sid_add_rid(mem_ctx
,
156 domains
->domains
[0].sid
,
157 l
.out
.sids
->sids
[0].rid
);
158 c
.in
.handle
= &handle
;
159 c
.out
.handle
= &handle
;
161 status
= dcerpc_lsa_Close_r(b
, tmp_ctx
, &c
);
163 if (!NT_STATUS_IS_OK(status
)) {
164 torture_comment(tctx
,
165 "dcerpc_lsa_Close failed - %s\n",
167 talloc_free(tmp_ctx
);
171 if (!NT_STATUS_IS_OK(c
.out
.result
)) {
172 torture_comment(tctx
,
173 "dcerpc_lsa_Close failed - %s\n",
174 nt_errstr(c
.out
.result
));
175 talloc_free(tmp_ctx
);
179 talloc_free(tmp_ctx
);
182 torture_comment(tctx
, "Get_user_sid finished\n");
187 * Create a bkrp_encrypted_secret_vX structure
188 * the version depends on the version parameter
189 * the structure is returned as a blob.
190 * The broken flag is to indicate if we want
191 * to create a non conform to specification structre
193 static DATA_BLOB
*create_unencryptedsecret(TALLOC_CTX
*mem_ctx
,
197 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
198 DATA_BLOB
*blob
= talloc_zero(mem_ctx
, DATA_BLOB
);
199 enum ndr_err_code ndr_err
;
202 struct bkrp_encrypted_secret_v2 unenc_sec
;
204 ZERO_STRUCT(unenc_sec
);
205 unenc_sec
.secret_len
= sizeof(secret
);
206 unenc_sec
.secret
= discard_const_p(uint8_t, secret
);
207 generate_random_buffer(unenc_sec
.payload_key
,
208 sizeof(unenc_sec
.payload_key
));
210 ndr_err
= ndr_push_struct_blob(blob
, blob
, &unenc_sec
,
211 (ndr_push_flags_fn_t
)ndr_push_bkrp_encrypted_secret_v2
);
212 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
217 /* The magic value is correctly set by the NDR push
218 * but we want to test the behavior of the server
219 * if a differrent value is provided
221 ((uint8_t*)blob
->data
)[4] = 79; /* A great year !!! */
226 struct bkrp_encrypted_secret_v3 unenc_sec
;
228 ZERO_STRUCT(unenc_sec
);
229 unenc_sec
.secret_len
= sizeof(secret
);
230 unenc_sec
.secret
= discard_const_p(uint8_t, secret
);
231 generate_random_buffer(unenc_sec
.payload_key
,
232 sizeof(unenc_sec
.payload_key
));
234 ndr_err
= ndr_push_struct_blob(blob
, blob
, &unenc_sec
,
235 (ndr_push_flags_fn_t
)ndr_push_bkrp_encrypted_secret_v3
);
236 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
242 * The magic value is correctly set by the NDR push
243 * but we want to test the behavior of the server
244 * if a differrent value is provided
246 ((uint8_t*)blob
->data
)[4] = 79; /* A great year !!! */
249 talloc_free(tmp_ctx
);
254 * Create an access check structure, the format depends on the version parameter.
255 * If broken is specified then we create a stucture that isn't conform to the
258 * If the structure can't be created then NULL is returned.
260 static DATA_BLOB
*create_access_check(struct torture_context
*tctx
,
261 struct dcerpc_pipe
*p
,
267 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
268 DATA_BLOB
*blob
= talloc_zero(mem_ctx
, DATA_BLOB
);
269 enum ndr_err_code ndr_err
;
270 const struct dom_sid
*sid
= get_user_sid(tctx
, tmp_ctx
, user
);
277 struct bkrp_access_check_v2 access_struct
;
278 gnutls_hash_hd_t dig_ctx
;
281 ZERO_STRUCT(access_struct
);
282 generate_random_buffer(nonce
, sizeof(nonce
));
283 access_struct
.nonce_len
= sizeof(nonce
);
284 access_struct
.nonce
= nonce
;
285 access_struct
.sid
= *sid
;
287 ndr_err
= ndr_push_struct_blob(blob
, blob
, &access_struct
,
288 (ndr_push_flags_fn_t
)ndr_push_bkrp_access_check_v2
);
289 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
294 * We pushed the whole structure including a null hash
295 * but the hash need to be calculated only up to the hash field
296 * so we reduce the size of what has to be calculated
299 gnutls_hash_init(&dig_ctx
, GNUTLS_DIG_SHA1
);
302 blob
->length
- sizeof(access_struct
.hash
));
303 gnutls_hash_deinit(dig_ctx
,
304 blob
->data
+ blob
->length
- sizeof(access_struct
.hash
));
306 /* Altering the SHA */
308 blob
->data
[blob
->length
- 1]++;
313 struct bkrp_access_check_v3 access_struct
;
314 gnutls_hash_hd_t dig_ctx
;
317 ZERO_STRUCT(access_struct
);
318 generate_random_buffer(nonce
, sizeof(nonce
));
319 access_struct
.nonce_len
= sizeof(nonce
);
320 access_struct
.nonce
= nonce
;
321 access_struct
.sid
= *sid
;
323 ndr_err
= ndr_push_struct_blob(blob
, blob
, &access_struct
,
324 (ndr_push_flags_fn_t
)ndr_push_bkrp_access_check_v3
);
325 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
329 /*We pushed the whole structure including a null hash
330 * but the hash need to be calculated only up to the hash field
331 * so we reduce the size of what has to be calculated
334 gnutls_hash_init(&dig_ctx
, GNUTLS_DIG_SHA512
);
337 blob
->length
- sizeof(access_struct
.hash
));
338 gnutls_hash_deinit(dig_ctx
,
339 blob
->data
+ blob
->length
- sizeof(access_struct
.hash
));
341 /* Altering the SHA */
343 blob
->data
[blob
->length
-1]++;
346 talloc_free(tmp_ctx
);
351 static DATA_BLOB
*encrypt_blob(struct torture_context
*tctx
,
355 DATA_BLOB
*to_encrypt
,
356 gnutls_cipher_algorithm_t cipher_algo
)
358 gnutls_cipher_hd_t cipher_handle
= { 0 };
359 gnutls_datum_t gkey
= {
363 gnutls_datum_t giv
= {
370 blob
= talloc(mem_ctx
, DATA_BLOB
);
375 *blob
= data_blob_talloc_zero(mem_ctx
, to_encrypt
->length
);
376 if (blob
->data
== NULL
) {
381 rc
= gnutls_cipher_init(&cipher_handle
,
385 if (rc
!= GNUTLS_E_SUCCESS
) {
386 torture_comment(tctx
,
387 "gnutls_cipher_init failed: %s\n",
388 gnutls_strerror(rc
));
393 rc
= gnutls_cipher_encrypt2(cipher_handle
,
398 gnutls_cipher_deinit(cipher_handle
);
399 if (rc
!= GNUTLS_E_SUCCESS
) {
400 torture_comment(tctx
,
401 "gnutls_cipher_decrypt2 failed: %s\n",
402 gnutls_strerror(rc
));
410 * Certs used for this protocol have a GUID in the issuer_uniq_id field.
411 * This function fetch it.
413 static struct GUID
*get_cert_guid(struct torture_context
*tctx
,
418 gnutls_x509_crt_t x509_cert
= NULL
;
419 gnutls_datum_t x509_crt_data
= {
423 uint8_t dummy
[1] = {0};
424 DATA_BLOB issuer_unique_id
= {
428 struct GUID
*guid
= talloc_zero(mem_ctx
, struct GUID
);
432 rc
= gnutls_x509_crt_init(&x509_cert
);
433 if (rc
!= GNUTLS_E_SUCCESS
) {
434 torture_comment(tctx
,
435 "gnutls_x509_crt_init failed - %s",
436 gnutls_strerror(rc
));
440 rc
= gnutls_x509_crt_import(x509_cert
,
442 GNUTLS_X509_FMT_DER
);
443 if (rc
!= GNUTLS_E_SUCCESS
) {
444 torture_comment(tctx
,
445 "gnutls_x509_crt_import failed - %s",
446 gnutls_strerror(rc
));
447 gnutls_x509_crt_deinit(x509_cert
);
451 /* Get the buffer size */
452 rc
= gnutls_x509_crt_get_issuer_unique_id(x509_cert
,
453 (char *)issuer_unique_id
.data
,
454 &issuer_unique_id
.length
);
455 if (rc
!= GNUTLS_E_SHORT_MEMORY_BUFFER
||
456 issuer_unique_id
.length
== 0) {
457 gnutls_x509_crt_deinit(x509_cert
);
461 issuer_unique_id
= data_blob_talloc_zero(mem_ctx
,
462 issuer_unique_id
.length
);
463 if (issuer_unique_id
.data
== NULL
) {
464 gnutls_x509_crt_deinit(x509_cert
);
468 rc
= gnutls_x509_crt_get_issuer_unique_id(x509_cert
,
469 (char *)issuer_unique_id
.data
,
470 &issuer_unique_id
.length
);
471 gnutls_x509_crt_deinit(x509_cert
);
472 if (rc
!= GNUTLS_E_SUCCESS
) {
473 torture_comment(tctx
,
474 "gnutls_x509_crt_get_issuer_unique_id failed - %s",
475 gnutls_strerror(rc
));
479 status
= GUID_from_data_blob(&issuer_unique_id
, guid
);
480 if (!NT_STATUS_IS_OK(status
)) {
488 * Encrypt a blob with the private key of the certificate
489 * passed as a parameter.
491 static DATA_BLOB
*encrypt_blob_pk(struct torture_context
*tctx
,
495 DATA_BLOB
*to_encrypt
)
497 gnutls_x509_crt_t x509_cert
;
498 gnutls_datum_t x509_crt_data
= {
502 gnutls_pubkey_t pubkey
;
503 gnutls_datum_t plaintext
= {
504 .data
= to_encrypt
->data
,
505 .size
= to_encrypt
->length
,
507 gnutls_datum_t ciphertext
= {
513 rc
= gnutls_x509_crt_init(&x509_cert
);
514 if (rc
!= GNUTLS_E_SUCCESS
) {
518 rc
= gnutls_x509_crt_import(x509_cert
,
520 GNUTLS_X509_FMT_DER
);
521 if (rc
!= GNUTLS_E_SUCCESS
) {
522 gnutls_x509_crt_deinit(x509_cert
);
526 rc
= gnutls_pubkey_init(&pubkey
);
527 if (rc
!= GNUTLS_E_SUCCESS
) {
528 gnutls_x509_crt_deinit(x509_cert
);
532 rc
= gnutls_pubkey_import_x509(pubkey
,
535 gnutls_x509_crt_deinit(x509_cert
);
536 if (rc
!= GNUTLS_E_SUCCESS
) {
537 gnutls_pubkey_deinit(pubkey
);
541 rc
= gnutls_pubkey_encrypt_data(pubkey
,
545 gnutls_pubkey_deinit(pubkey
);
546 if (rc
!= GNUTLS_E_SUCCESS
) {
550 blob
= talloc_zero(mem_ctx
, DATA_BLOB
);
552 gnutls_pubkey_deinit(pubkey
);
556 *blob
= data_blob_talloc(blob
, ciphertext
.data
, ciphertext
.size
);
557 gnutls_free(ciphertext
.data
);
558 if (blob
->data
== NULL
) {
559 gnutls_pubkey_deinit(pubkey
);
566 static struct bkrp_BackupKey
*createRetrieveBackupKeyGUIDStruct(struct torture_context
*tctx
,
567 struct dcerpc_pipe
*p
, int version
, DATA_BLOB
*out
)
569 struct dcerpc_binding
*binding
;
570 struct bkrp_client_side_wrapped data
;
571 struct GUID
*g
= talloc(tctx
, struct GUID
);
572 struct bkrp_BackupKey
*r
= talloc_zero(tctx
, struct bkrp_BackupKey
);
573 enum ndr_err_code ndr_err
;
581 binding
= dcerpc_binding_dup(tctx
, p
->binding
);
582 if (binding
== NULL
) {
586 status
= dcerpc_binding_set_flags(binding
, DCERPC_SEAL
|DCERPC_AUTH_SPNEGO
, 0);
587 if (!NT_STATUS_IS_OK(status
)) {
592 status
= GUID_from_string(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID
, g
);
593 if (!NT_STATUS_IS_OK(status
)) {
597 r
->in
.guidActionAgent
= g
;
598 data
.version
= version
;
599 ndr_err
= ndr_push_struct_blob(&blob
, tctx
, &data
,
600 (ndr_push_flags_fn_t
)ndr_push_bkrp_client_side_wrapped
);
601 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
604 r
->in
.data_in
= blob
.data
;
605 r
->in
.data_in_len
= blob
.length
;
606 r
->out
.data_out
= &out
->data
;
607 r
->out
.data_out_len
= talloc(r
, uint32_t);
611 static struct bkrp_BackupKey
*createRestoreGUIDStruct(struct torture_context
*tctx
,
612 struct dcerpc_pipe
*p
, int version
, DATA_BLOB
*out
,
616 bool broken_magic_secret
,
617 bool broken_magic_access
,
618 bool broken_hash_access
,
619 bool broken_cert_guid
)
621 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
622 struct bkrp_client_side_wrapped data
;
625 DATA_BLOB
*enc_sec
= NULL
;
626 DATA_BLOB
*enc_xs
= NULL
;
628 DATA_BLOB enc_sec_reverted
;
632 struct GUID
*guid
, *g
;
635 enum ndr_err_code ndr_err
;
638 gnutls_cipher_algorithm_t cipher_algo
;
639 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, version
, &out_blob
);
645 /* we take a fake user*/
648 user
= cli_credentials_get_username(
649 popt_get_cmdline_credentials());
653 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
655 torture_assert_werr_ok(tctx
, r
->out
.result
,
659 * We have to set it outside of the function createRetrieveBackupKeyGUIDStruct
660 * the len of the blob, this is due to the fact that they don't have the
661 * same size (one is 32bits the other 64bits)
663 out_blob
.length
= *r
->out
.data_out_len
;
665 sec
= create_unencryptedsecret(tctx
, broken_magic_secret
, version
);
670 xs
= create_access_check(tctx
, p
, tctx
, user
, broken_hash_access
, version
);
675 if (broken_magic_access
){
676 /* The start of the access_check structure contains the
677 * GUID of the certificate
682 enc_sec
= encrypt_blob_pk(tctx
, tctx
, out_blob
.data
, out_blob
.length
, sec
);
686 enc_sec_reverted
.data
= talloc_array(tctx
, uint8_t, enc_sec
->length
);
687 if (enc_sec_reverted
.data
== NULL
) {
690 enc_sec_reverted
.length
= enc_sec
->length
;
693 * We DO NOT revert the array on purpose it's in order to check that
694 * when the server is not able to decrypt then it answer the correct error
697 for(t
=0; t
< enc_sec
->length
; t
++) {
698 enc_sec_reverted
.data
[t
] = ((uint8_t*)enc_sec
->data
)[t
];
701 for(t
=0; t
< enc_sec
->length
; t
++) {
702 enc_sec_reverted
.data
[t
] = ((uint8_t*)enc_sec
->data
)[enc_sec
->length
- t
-1];
709 cipher_algo
= GNUTLS_CIPHER_3DES_CBC
;
712 cipher_algo
= GNUTLS_CIPHER_AES_256_CBC
;
717 iv
.length
= gnutls_cipher_get_iv_size(cipher_algo
);
718 iv
.data
= sec
->data
+ (size
- iv
.length
);
720 key
.length
= gnutls_cipher_get_key_size(cipher_algo
);
721 key
.data
= sec
->data
+ (size
- (key
.length
+ iv
.length
));
723 enc_xs
= encrypt_blob(tctx
, tctx
, &key
, &iv
, xs
, cipher_algo
);
728 /* To cope with the fact that heimdal do padding at the end for the moment */
729 enc_xs
->length
= xs
->length
;
731 guid
= get_cert_guid(tctx
, tctx
, out_blob
.data
, out_blob
.length
);
736 if (broken_version
) {
739 data
.version
= version
;
743 data
.encrypted_secret
= enc_sec_reverted
.data
;
744 data
.access_check
= enc_xs
->data
;
745 data
.encrypted_secret_len
= enc_sec
->length
;
746 data
.access_check_len
= enc_xs
->length
;
748 /* We want the blob to persist after this function so we don't
749 * allocate it in the stack
751 blob2
= talloc(tctx
, DATA_BLOB
);
756 ndr_err
= ndr_push_struct_blob(blob2
, tctx
, &data
,
757 (ndr_push_flags_fn_t
)ndr_push_bkrp_client_side_wrapped
);
758 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
762 if (broken_cert_guid
) {
768 g
= talloc(tctx
, struct GUID
);
773 status
= GUID_from_string(BACKUPKEY_RESTORE_GUID
, g
);
774 if (!NT_STATUS_IS_OK(status
)) {
778 r
->in
.guidActionAgent
= g
;
779 r
->in
.data_in
= blob2
->data
;
780 r
->in
.data_in_len
= blob2
->length
;
782 r
->out
.data_out
= &(out
->data
);
783 r
->out
.data_out_len
= talloc(r
, uint32_t);
787 /* Check that we are able to receive the certificate of the DCs
788 * used for client wrap version of the backup key protocol
790 static bool test_RetrieveBackupKeyGUID(struct torture_context
*tctx
,
791 struct dcerpc_pipe
*p
)
793 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
795 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
796 enum dcerpc_AuthType auth_type
;
797 enum dcerpc_AuthLevel auth_level
;
803 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
805 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
806 torture_assert_ntstatus_ok(tctx
,
807 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
810 out_blob
.length
= *r
->out
.data_out_len
;
811 torture_assert_werr_equal(tctx
,
814 "Wrong dce/rpc error code");
816 torture_assert_ntstatus_equal(tctx
,
817 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
818 NT_STATUS_ACCESS_DENIED
,
824 /* Test to check the failure to recover a secret because the
825 * secret blob is not reversed
827 static bool test_RestoreGUID_ko(struct torture_context
*tctx
,
828 struct dcerpc_pipe
*p
)
830 enum ndr_err_code ndr_err
;
831 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
833 struct bkrp_client_side_unwrapped resp
;
834 enum dcerpc_AuthType auth_type
;
835 enum dcerpc_AuthLevel auth_level
;
837 gnutls_global_init();
839 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
841 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
842 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
843 true, false, false, false, false, false, false);
844 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
845 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
846 out_blob
.length
= *r
->out
.data_out_len
;
847 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
848 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
849 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_PARAMETER
, "Wrong error code");
851 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
852 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
853 NT_STATUS_ACCESS_DENIED
, "Get GUID");
856 gnutls_global_deinit();
861 static bool test_RestoreGUID_wrongversion(struct torture_context
*tctx
,
862 struct dcerpc_pipe
*p
)
864 enum ndr_err_code ndr_err
;
865 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
867 struct bkrp_client_side_unwrapped resp
;
868 enum dcerpc_AuthType auth_type
;
869 enum dcerpc_AuthLevel auth_level
;
871 gnutls_global_init();
873 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
875 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
876 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
877 false, true, false, false, false, false, false);
878 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
879 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
880 out_blob
.length
= *r
->out
.data_out_len
;
881 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
882 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
883 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_PARAMETER
, "Wrong error code on wrong version");
885 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
886 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
887 NT_STATUS_ACCESS_DENIED
, "Get GUID");
890 gnutls_global_deinit();
895 static bool test_RestoreGUID_wronguser(struct torture_context
*tctx
,
896 struct dcerpc_pipe
*p
)
898 enum ndr_err_code ndr_err
;
899 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
901 struct bkrp_client_side_unwrapped resp
;
902 enum dcerpc_AuthType auth_type
;
903 enum dcerpc_AuthLevel auth_level
;
905 gnutls_global_init();
907 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
909 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
910 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
911 false, false, true, false, false, false, false);
912 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
913 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
914 out_blob
.length
= *r
->out
.data_out_len
;
915 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
916 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
917 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_ACCESS
, "Restore GUID");
919 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
920 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
921 NT_STATUS_ACCESS_DENIED
, "Get GUID");
924 gnutls_global_deinit();
929 static bool test_RestoreGUID_v3(struct torture_context
*tctx
,
930 struct dcerpc_pipe
*p
)
932 enum ndr_err_code ndr_err
;
933 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
935 struct bkrp_client_side_unwrapped resp
;
936 enum dcerpc_AuthType auth_type
;
937 enum dcerpc_AuthLevel auth_level
;
939 gnutls_global_init();
941 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
943 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
944 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
945 false, false, false, false, false, false, false);
946 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
947 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
948 out_blob
.length
= *r
->out
.data_out_len
;
949 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
950 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 1, "Unable to unmarshall bkrp_client_side_unwrapped");
951 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_OK
, "Restore GUID");
952 torture_assert_str_equal(tctx
, (char*)resp
.secret
.data
, secret
, "Wrong secret");
954 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
955 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
956 NT_STATUS_ACCESS_DENIED
, "Get GUID");
959 gnutls_global_deinit();
964 static bool test_RestoreGUID(struct torture_context
*tctx
,
965 struct dcerpc_pipe
*p
)
967 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
969 struct bkrp_client_side_unwrapped resp
;
970 enum dcerpc_AuthType auth_type
;
971 enum dcerpc_AuthLevel auth_level
;
973 gnutls_global_init();
975 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
977 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
978 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
979 false, false, false, false, false, false, false);
980 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
981 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
982 out_blob
.length
= *r
->out
.data_out_len
;
983 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_OK
, "Restore GUID");
984 torture_assert_ndr_err_equal(tctx
,
985 ndr_pull_struct_blob(&out_blob
, tctx
, &resp
,
986 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
),
988 "Unable to unmarshall bkrp_client_side_unwrapped");
989 torture_assert_str_equal(tctx
, (char*)resp
.secret
.data
, secret
, "Wrong secret");
991 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
992 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
993 NT_STATUS_ACCESS_DENIED
, "Get GUID");
996 gnutls_global_deinit();
1001 static bool test_RestoreGUID_badmagiconsecret(struct torture_context
*tctx
,
1002 struct dcerpc_pipe
*p
)
1004 enum ndr_err_code ndr_err
;
1005 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1007 struct bkrp_client_side_unwrapped resp
;
1008 enum dcerpc_AuthType auth_type
;
1009 enum dcerpc_AuthLevel auth_level
;
1011 gnutls_global_init();
1013 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1015 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1016 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
1017 false, false, false, true, false, false, false);
1018 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
1019 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1020 out_blob
.length
= *r
->out
.data_out_len
;
1021 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
1022 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1023 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Wrong error code while providing bad magic in secret");
1025 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1026 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1027 NT_STATUS_ACCESS_DENIED
, "Get GUID");
1030 gnutls_global_deinit();
1035 static bool test_RestoreGUID_emptyrequest(struct torture_context
*tctx
,
1036 struct dcerpc_pipe
*p
)
1038 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1040 enum dcerpc_AuthType auth_type
;
1041 enum dcerpc_AuthLevel auth_level
;
1043 gnutls_global_init();
1045 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1047 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1048 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
1049 false, false, false, true, false, false, true);
1051 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
1052 r
->in
.data_in
= talloc(tctx
, uint8_t);
1053 r
->in
.data_in_len
= 0;
1055 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1056 out_blob
.length
= *r
->out
.data_out_len
;
1057 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_PARAMETER
, "Bad error code on wrong has in access check");
1059 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1060 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1061 NT_STATUS_ACCESS_DENIED
, "Get GUID");
1064 gnutls_global_deinit();
1069 static bool test_RestoreGUID_badcertguid(struct torture_context
*tctx
,
1070 struct dcerpc_pipe
*p
)
1072 enum ndr_err_code ndr_err
;
1073 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1075 struct bkrp_client_side_unwrapped resp
;
1076 enum dcerpc_AuthType auth_type
;
1077 enum dcerpc_AuthLevel auth_level
;
1079 gnutls_global_init();
1081 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1083 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1084 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
1085 false, false, false, false, false, false, true);
1086 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct() failed");
1087 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1088 out_blob
.length
= *r
->out
.data_out_len
;
1089 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
1090 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1093 * Windows 2012R2 has, presumably, a programming error
1094 * returning an NTSTATUS code on this interface
1096 if (W_ERROR_V(r
->out
.result
) != NT_STATUS_V(NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
1097 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Bad error code on wrong has in access check");
1100 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1101 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1102 NT_STATUS_ACCESS_DENIED
, "Get GUID");
1105 gnutls_global_deinit();
1110 static bool test_RestoreGUID_badmagicaccesscheck(struct torture_context
*tctx
,
1111 struct dcerpc_pipe
*p
)
1113 enum ndr_err_code ndr_err
;
1114 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1116 struct bkrp_client_side_unwrapped resp
;
1117 enum dcerpc_AuthType auth_type
;
1118 enum dcerpc_AuthLevel auth_level
;
1120 gnutls_global_init();
1122 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1124 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1125 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
1126 false, false, false, false, true, false, false);
1127 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
1128 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1129 out_blob
.length
= *r
->out
.data_out_len
;
1130 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
1131 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1132 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Bad error code on wrong has in access check");
1134 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1135 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1136 NT_STATUS_ACCESS_DENIED
, "Get GUID");
1139 gnutls_global_deinit();
1144 static bool test_RestoreGUID_badhashaccesscheck(struct torture_context
*tctx
,
1145 struct dcerpc_pipe
*p
)
1147 enum ndr_err_code ndr_err
;
1148 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1150 struct bkrp_client_side_unwrapped resp
;
1151 enum dcerpc_AuthType auth_type
;
1152 enum dcerpc_AuthLevel auth_level
;
1154 gnutls_global_init();
1156 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1158 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1159 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
1160 false, false, false, false, false, true, false);
1161 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
1162 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1163 out_blob
.length
= *r
->out
.data_out_len
;
1164 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
1165 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1166 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Bad error code on wrong has in access check");
1168 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1169 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1170 NT_STATUS_ACCESS_DENIED
, "Get GUID");
1173 gnutls_global_init();
1179 * Check that the RSA modulus in the certificate of the DCs has 2048 bits.
1181 static bool test_RetrieveBackupKeyGUID_validate(struct torture_context
*tctx
,
1182 struct dcerpc_pipe
*p
)
1184 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1186 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1187 enum dcerpc_AuthType auth_type
;
1188 enum dcerpc_AuthLevel auth_level
;
1190 gnutls_global_init();
1192 torture_assert(tctx
, r
!= NULL
, "test_RetrieveBackupKeyGUID_validate failed");
1198 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1200 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1201 gnutls_x509_crt_t x509_cert
= NULL
;
1202 gnutls_pubkey_t pubkey
= NULL
;
1203 gnutls_datum_t x509_crt_data
;
1204 gnutls_pk_algorithm_t pubkey_algo
;
1205 uint8_t dummy
[1] = {0};
1206 DATA_BLOB subject_unique_id
= {
1210 DATA_BLOB issuer_unique_id
= {
1214 DATA_BLOB reversed
= {
1218 DATA_BLOB serial_number
;
1219 unsigned int RSA_returned_bits
= 0;
1225 torture_assert_ntstatus_ok(tctx
,
1226 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1229 torture_assert_werr_ok(tctx
, r
->out
.result
,
1232 out_blob
.length
= *r
->out
.data_out_len
;
1234 x509_crt_data
.data
= out_blob
.data
;
1235 x509_crt_data
.size
= out_blob
.length
;
1237 rc
= gnutls_x509_crt_init(&x509_cert
);
1238 if (rc
!= GNUTLS_E_SUCCESS
) {
1242 rc
= gnutls_x509_crt_import(x509_cert
,
1244 GNUTLS_X509_FMT_DER
);
1245 torture_assert_int_equal(tctx
,
1248 "gnutls_x509_crt_import failed");
1250 /* Compare unique ids */
1252 /* Get buffer size */
1253 rc
= gnutls_x509_crt_get_subject_unique_id(x509_cert
,
1254 (char *)subject_unique_id
.data
,
1255 &subject_unique_id
.length
);
1256 torture_assert_int_equal(tctx
,
1258 GNUTLS_E_SHORT_MEMORY_BUFFER
,
1259 "gnutls_x509_crt_get_subject_unique_id "
1260 "get buffer size failed");
1262 subject_unique_id
= data_blob_talloc_zero(tctx
,
1263 subject_unique_id
.length
);
1265 rc
= gnutls_x509_crt_get_subject_unique_id(x509_cert
,
1266 (char *)subject_unique_id
.data
,
1267 &subject_unique_id
.length
);
1268 torture_assert_int_equal(tctx
,
1271 "gnutls_x509_crt_get_subject_unique_id failed");
1273 rc
= gnutls_x509_crt_get_issuer_unique_id(x509_cert
,
1274 (char *)issuer_unique_id
.data
,
1275 &issuer_unique_id
.length
);
1276 torture_assert_int_equal(tctx
,
1278 GNUTLS_E_SHORT_MEMORY_BUFFER
,
1279 "gnutls_x509_crt_get_issuer_unique_id "
1280 "get buffer size failed");
1282 issuer_unique_id
= data_blob_talloc_zero(tctx
,
1283 issuer_unique_id
.length
);
1285 rc
= gnutls_x509_crt_get_issuer_unique_id(x509_cert
,
1286 (char *)issuer_unique_id
.data
,
1287 &issuer_unique_id
.length
);
1288 torture_assert_int_equal(tctx
,
1291 "gnutls_x509_crt_get_issuer_unique_id failed");
1293 cmp
= data_blob_cmp(&subject_unique_id
, &issuer_unique_id
);
1294 torture_assert(tctx
,
1296 "The GUID to identify the public key is not "
1299 rc
= gnutls_x509_crt_get_serial(x509_cert
,
1302 torture_assert_int_equal(tctx
,
1304 GNUTLS_E_SHORT_MEMORY_BUFFER
,
1305 "gnutls_x509_crt_get_serial "
1306 "get buffer size failed");
1308 reversed
= data_blob_talloc_zero(tctx
,
1311 rc
= gnutls_x509_crt_get_serial(x509_cert
,
1314 torture_assert_int_equal(tctx
,
1317 "gnutls_x509_crt_get_serial failed");
1320 * Heimdal sometimes adds a leading byte to the data buffer of
1321 * the serial number. So lets uses the subject_unique_id size
1322 * and ignore the leading byte.
1324 serial_number
= data_blob_talloc_zero(tctx
,
1325 subject_unique_id
.length
);
1327 for (i
= 0; i
< serial_number
.length
; i
++) {
1328 serial_number
.data
[i
] = reversed
.data
[reversed
.length
- i
- 1];
1331 cmp
= data_blob_cmp(&subject_unique_id
, &serial_number
);
1332 torture_assert(tctx
,
1334 "The GUID to identify the public key is not "
1337 /* Check certificate version */
1338 version
= gnutls_x509_crt_get_version(x509_cert
);
1339 torture_assert_int_equal(tctx
,
1342 "Invalid certificate version");
1344 /* Get the public key */
1345 rc
= gnutls_pubkey_init(&pubkey
);
1346 torture_assert_int_equal(tctx
,
1349 "gnutls_pubkey_init failed");
1351 rc
= gnutls_pubkey_import_x509(pubkey
,
1354 gnutls_x509_crt_deinit(x509_cert
);
1355 torture_assert_int_equal(tctx
,
1358 "gnutls_pubkey_import_x509 failed");
1360 pubkey_algo
= gnutls_pubkey_get_pk_algorithm(pubkey
,
1361 &RSA_returned_bits
);
1362 gnutls_pubkey_deinit(pubkey
);
1363 torture_assert_int_equal(tctx
,
1366 "gnutls_pubkey_get_pk_algorithm did "
1367 "not return a RSA key");
1368 torture_assert_int_equal(tctx
,
1371 "RSA Key doesn't have 2048 bits");
1373 torture_assert_ntstatus_equal(tctx
,
1374 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1375 NT_STATUS_ACCESS_DENIED
,
1379 gnutls_global_deinit();
1384 static bool test_ServerWrap_encrypt_decrypt(struct torture_context
*tctx
,
1385 struct dcerpc_pipe
*p
)
1387 struct bkrp_BackupKey r
;
1389 DATA_BLOB plaintext
= data_blob_const(secret
, sizeof(secret
));
1390 DATA_BLOB encrypted
;
1392 DATA_BLOB decrypted
;
1394 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1395 enum dcerpc_AuthType auth_type
;
1396 enum dcerpc_AuthLevel auth_level
;
1399 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1402 torture_assert_ntstatus_ok(tctx
,
1403 GUID_from_string(BACKUPKEY_BACKUP_GUID
, &guid
),
1406 r
.in
.guidActionAgent
= &guid
;
1407 r
.in
.data_in
= plaintext
.data
;
1408 r
.in
.data_in_len
= plaintext
.length
;
1410 r
.out
.data_out
= &encrypted
.data
;
1411 r
.out
.data_out_len
= &enclen
;
1412 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1413 torture_assert_ntstatus_ok(tctx
,
1414 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1417 torture_assert_ntstatus_equal(tctx
,
1418 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1419 NT_STATUS_ACCESS_DENIED
,
1423 torture_assert_werr_ok(tctx
,
1426 encrypted
.length
= *r
.out
.data_out_len
;
1429 torture_assert_ntstatus_ok(tctx
,
1430 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1433 r
.in
.guidActionAgent
= &guid
;
1434 r
.in
.data_in
= encrypted
.data
;
1435 r
.in
.data_in_len
= encrypted
.length
;
1437 r
.out
.data_out
= &(decrypted
.data
);
1438 r
.out
.data_out_len
= &declen
;
1439 torture_assert_ntstatus_ok(tctx
,
1440 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1442 torture_assert_werr_ok(tctx
,
1445 decrypted
.length
= *r
.out
.data_out_len
;
1448 torture_assert_data_blob_equal(tctx
, plaintext
, decrypted
, "Decrypt failed");
1451 torture_assert_ntstatus_ok(tctx
,
1452 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1455 r
.in
.guidActionAgent
= &guid
;
1456 r
.in
.data_in
= encrypted
.data
;
1457 r
.in
.data_in_len
= encrypted
.length
;
1459 r
.out
.data_out
= &(decrypted
.data
);
1460 r
.out
.data_out_len
= &declen
;
1461 torture_assert_ntstatus_ok(tctx
,
1462 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1464 torture_assert_werr_ok(tctx
,
1467 decrypted
.length
= *r
.out
.data_out_len
;
1470 torture_assert_data_blob_equal(tctx
, plaintext
, decrypted
, "Decrypt failed");
1474 static bool test_ServerWrap_decrypt_wrong_keyGUID(struct torture_context
*tctx
,
1475 struct dcerpc_pipe
*p
)
1477 struct bkrp_BackupKey r
;
1479 DATA_BLOB plaintext
= data_blob_const(secret
, sizeof(secret
));
1480 DATA_BLOB encrypted
;
1482 DATA_BLOB decrypted
;
1484 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1485 enum ndr_err_code ndr_err
;
1486 struct bkrp_server_side_wrapped server_side_wrapped
;
1487 enum dcerpc_AuthType auth_type
;
1488 enum dcerpc_AuthLevel auth_level
;
1491 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1494 torture_assert_ntstatus_ok(tctx
,
1495 GUID_from_string(BACKUPKEY_BACKUP_GUID
, &guid
),
1498 r
.in
.guidActionAgent
= &guid
;
1499 r
.in
.data_in
= plaintext
.data
;
1500 r
.in
.data_in_len
= plaintext
.length
;
1502 r
.out
.data_out
= &encrypted
.data
;
1503 r
.out
.data_out_len
= &enclen
;
1504 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1505 torture_assert_ntstatus_ok(tctx
,
1506 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1509 torture_assert_ntstatus_equal(tctx
,
1510 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1511 NT_STATUS_ACCESS_DENIED
,
1515 torture_assert_werr_ok(tctx
,
1518 encrypted
.length
= *r
.out
.data_out_len
;
1520 ndr_err
= ndr_pull_struct_blob(&encrypted
, tctx
, &server_side_wrapped
,
1521 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_server_side_wrapped
);
1522 torture_assert_ndr_err_equal(tctx
, ndr_err
, NDR_ERR_SUCCESS
, "pull of server_side_wrapped");
1524 /* Change the GUID */
1525 server_side_wrapped
.guid
= GUID_random();
1527 ndr_err
= ndr_push_struct_blob(&encrypted
, tctx
, &server_side_wrapped
,
1528 (ndr_push_flags_fn_t
)ndr_push_bkrp_server_side_wrapped
);
1529 torture_assert_ndr_err_equal(tctx
, ndr_err
, NDR_ERR_SUCCESS
, "push of server_side_wrapped");
1532 torture_assert_ntstatus_ok(tctx
,
1533 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1536 r
.in
.guidActionAgent
= &guid
;
1537 r
.in
.data_in
= encrypted
.data
;
1538 r
.in
.data_in_len
= encrypted
.length
;
1540 r
.out
.data_out
= &(decrypted
.data
);
1541 r
.out
.data_out_len
= &declen
;
1542 torture_assert_ntstatus_ok(tctx
,
1543 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1545 torture_assert_werr_equal(tctx
,
1548 "decrypt should fail with WERR_INVALID_DATA");
1551 torture_assert_ntstatus_ok(tctx
,
1552 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1555 r
.in
.guidActionAgent
= &guid
;
1556 r
.in
.data_in
= encrypted
.data
;
1557 r
.in
.data_in_len
= encrypted
.length
;
1559 r
.out
.data_out
= &(decrypted
.data
);
1560 r
.out
.data_out_len
= &declen
;
1561 torture_assert_ntstatus_ok(tctx
,
1562 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1564 torture_assert_werr_equal(tctx
,
1567 "decrypt should fail with WERR_INVALID_DATA");
1572 static bool test_ServerWrap_decrypt_empty_request(struct torture_context
*tctx
,
1573 struct dcerpc_pipe
*p
)
1575 struct bkrp_BackupKey r
;
1577 DATA_BLOB decrypted
;
1579 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1580 uint8_t short_request
[4] = { 1, 0, 0, 0 };
1581 enum dcerpc_AuthType auth_type
;
1582 enum dcerpc_AuthLevel auth_level
;
1585 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1588 torture_assert_ntstatus_ok(tctx
,
1589 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1592 r
.in
.guidActionAgent
= &guid
;
1593 r
.in
.data_in
= short_request
;
1594 r
.in
.data_in_len
= 0;
1596 r
.out
.data_out
= &(decrypted
.data
);
1597 r
.out
.data_out_len
= &declen
;
1598 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1599 torture_assert_ntstatus_ok(tctx
,
1600 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1603 torture_assert_ntstatus_equal(tctx
,
1604 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1605 NT_STATUS_ACCESS_DENIED
,
1609 torture_assert_werr_equal(tctx
,
1611 WERR_INVALID_PARAMETER
,
1612 "decrypt should fail with WERR_INVALID_PARAMETER");
1615 torture_assert_ntstatus_ok(tctx
,
1616 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1619 r
.in
.guidActionAgent
= &guid
;
1620 r
.in
.data_in
= short_request
;
1621 r
.in
.data_in_len
= 0;
1623 r
.out
.data_out
= &(decrypted
.data
);
1624 r
.out
.data_out_len
= &declen
;
1625 torture_assert_ntstatus_ok(tctx
,
1626 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1628 torture_assert_werr_equal(tctx
,
1630 WERR_INVALID_PARAMETER
,
1631 "decrypt should fail with WERR_INVALID_PARAMETER");
1634 torture_assert_ntstatus_ok(tctx
,
1635 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1638 r
.in
.guidActionAgent
= &guid
;
1639 r
.in
.data_in
= NULL
;
1640 r
.in
.data_in_len
= 0;
1642 r
.out
.data_out
= &(decrypted
.data
);
1643 r
.out
.data_out_len
= &declen
;
1644 torture_assert_ntstatus_equal(tctx
,
1645 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1646 NT_STATUS_INVALID_PARAMETER_MIX
,
1650 torture_assert_ntstatus_ok(tctx
,
1651 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1654 r
.in
.guidActionAgent
= &guid
;
1655 r
.in
.data_in
= NULL
;
1656 r
.in
.data_in_len
= 0;
1658 r
.out
.data_out
= &(decrypted
.data
);
1659 r
.out
.data_out_len
= &declen
;
1660 torture_assert_ntstatus_equal(tctx
,
1661 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1662 NT_STATUS_INVALID_PARAMETER_MIX
,
1669 static bool test_ServerWrap_decrypt_short_request(struct torture_context
*tctx
,
1670 struct dcerpc_pipe
*p
)
1672 struct bkrp_BackupKey r
;
1674 DATA_BLOB decrypted
;
1676 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1677 uint8_t short_request
[4] = { 1, 0, 0, 0 };
1678 enum dcerpc_AuthType auth_type
;
1679 enum dcerpc_AuthLevel auth_level
;
1682 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1685 torture_assert_ntstatus_ok(tctx
,
1686 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1689 r
.in
.guidActionAgent
= &guid
;
1690 r
.in
.data_in
= short_request
;
1691 r
.in
.data_in_len
= 4;
1693 r
.out
.data_out
= &(decrypted
.data
);
1694 r
.out
.data_out_len
= &declen
;
1695 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1696 torture_assert_ntstatus_ok(tctx
,
1697 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1700 torture_assert_ntstatus_equal(tctx
,
1701 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1702 NT_STATUS_ACCESS_DENIED
,
1706 torture_assert_werr_equal(tctx
,
1708 WERR_INVALID_PARAMETER
,
1709 "decrypt should fail with WERR_INVALID_PARM");
1712 torture_assert_ntstatus_ok(tctx
,
1713 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1716 r
.in
.guidActionAgent
= &guid
;
1717 r
.in
.data_in
= short_request
;
1718 r
.in
.data_in_len
= 4;
1720 r
.out
.data_out
= &(decrypted
.data
);
1721 r
.out
.data_out_len
= &declen
;
1722 torture_assert_ntstatus_ok(tctx
,
1723 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1725 torture_assert_werr_equal(tctx
,
1727 WERR_INVALID_PARAMETER
,
1728 "decrypt should fail with WERR_INVALID_PARAMETER");
1731 torture_assert_ntstatus_ok(tctx
,
1732 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1735 r
.in
.guidActionAgent
= &guid
;
1736 r
.in
.data_in
= short_request
;
1737 r
.in
.data_in_len
= 1;
1739 r
.out
.data_out
= &(decrypted
.data
);
1740 r
.out
.data_out_len
= &declen
;
1741 torture_assert_ntstatus_ok(tctx
,
1742 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1744 torture_assert_werr_equal(tctx
,
1746 WERR_INVALID_PARAMETER
,
1747 "decrypt should fail with WERR_INVALID_PARAMETER");
1750 torture_assert_ntstatus_ok(tctx
,
1751 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1754 r
.in
.guidActionAgent
= &guid
;
1755 r
.in
.data_in
= short_request
;
1756 r
.in
.data_in_len
= 1;
1758 r
.out
.data_out
= &(decrypted
.data
);
1759 r
.out
.data_out_len
= &declen
;
1760 torture_assert_ntstatus_ok(tctx
,
1761 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1763 torture_assert_werr_equal(tctx
,
1765 WERR_INVALID_PARAMETER
,
1766 "decrypt should fail with WERR_INVALID_PARAMETER");
1771 static bool test_ServerWrap_encrypt_decrypt_manual(struct torture_context
*tctx
,
1772 struct bkrp_server_side_wrapped
*server_side_wrapped
,
1773 enum test_wrong wrong
)
1775 char *lsa_binding_string
= NULL
;
1776 struct dcerpc_binding
*lsa_binding
= NULL
;
1777 struct dcerpc_pipe
*lsa_p
= NULL
;
1778 struct dcerpc_binding_handle
*lsa_b
= NULL
;
1779 struct lsa_OpenSecret r_secret
;
1780 struct lsa_QuerySecret r_query_secret
;
1781 struct policy_handle
*handle
, sec_handle
;
1782 struct bkrp_BackupKey r
;
1783 struct GUID preferred_key_guid
;
1784 DATA_BLOB plaintext
= data_blob_const(secret
, sizeof(secret
));
1785 DATA_BLOB preferred_key
, preferred_key_clear
, session_key
,
1786 decrypt_key
, decrypt_key_clear
, encrypted_blob
,
1788 struct bkrp_dc_serverwrap_key server_key
;
1789 struct lsa_DATA_BUF_PTR bufp1
;
1790 char *key_guid_string
;
1791 struct bkrp_rc4encryptedpayload rc4payload
;
1792 struct dom_sid
*caller_sid
;
1793 uint8_t symkey
[20]; /* SHA-1 hash len */
1794 uint8_t mackey
[20]; /* SHA-1 hash len */
1795 uint8_t mac
[20]; /* SHA-1 hash len */
1796 gnutls_hmac_hd_t hmac_hnd
;
1797 gnutls_cipher_hd_t cipher_hnd
;
1798 gnutls_datum_t cipher_key
;
1802 ZERO_STRUCT(r_secret
);
1803 ZERO_STRUCT(r_query_secret
);
1805 /* Now read BCKUPKEY_P and prove we can do a matching decrypt and encrypt */
1807 /* lsa_OpenSecret only works with ncacn_np and AUTH_LEVEL_NONE */
1808 lsa_binding_string
= talloc_asprintf(tctx
, "ncacn_np:%s",
1809 torture_setting_string(tctx
, "host", NULL
));
1810 torture_assert(tctx
, lsa_binding_string
!= NULL
, "lsa_binding_string");
1812 torture_assert_ntstatus_ok(tctx
,
1813 dcerpc_parse_binding(tctx
, lsa_binding_string
, &lsa_binding
),
1814 "Failed to parse dcerpc binding");
1816 torture_assert_ntstatus_ok(tctx
,
1817 dcerpc_pipe_connect_b(tctx
, &lsa_p
,
1818 lsa_binding
, &ndr_table_lsarpc
,
1819 popt_get_cmdline_credentials(),
1820 tctx
->ev
, tctx
->lp_ctx
),
1821 "Opening LSA pipe");
1822 lsa_b
= lsa_p
->binding_handle
;
1824 torture_assert(tctx
, test_lsa_OpenPolicy2(lsa_b
, tctx
, &handle
), "OpenPolicy failed");
1825 r_secret
.in
.name
.string
= "G$BCKUPKEY_P";
1827 r_secret
.in
.handle
= handle
;
1828 r_secret
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1829 r_secret
.out
.sec_handle
= &sec_handle
;
1831 torture_comment(tctx
, "Testing OpenSecret\n");
1833 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenSecret_r(lsa_b
, tctx
, &r_secret
),
1834 "OpenSecret failed");
1835 torture_assert_ntstatus_ok(tctx
, r_secret
.out
.result
,
1836 "OpenSecret failed");
1838 r_query_secret
.in
.sec_handle
= &sec_handle
;
1839 r_query_secret
.in
.new_val
= &bufp1
;
1842 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QuerySecret_r(lsa_b
, tctx
, &r_query_secret
),
1843 "QuerySecret failed");
1844 torture_assert_ntstatus_ok(tctx
, r_query_secret
.out
.result
,
1845 "QuerySecret failed");
1848 preferred_key
.data
= r_query_secret
.out
.new_val
->buf
->data
;
1849 preferred_key
.length
= r_query_secret
.out
.new_val
->buf
->size
;
1850 torture_assert_ntstatus_ok(tctx
, dcerpc_fetch_session_key(lsa_p
, &session_key
),
1851 "dcerpc_fetch_session_key failed");
1853 torture_assert_ntstatus_ok(tctx
,
1854 sess_decrypt_blob(tctx
,
1855 &preferred_key
, &session_key
, &preferred_key_clear
),
1856 "sess_decrypt_blob failed");
1858 torture_assert_ntstatus_ok(tctx
, GUID_from_ndr_blob(&preferred_key_clear
, &preferred_key_guid
),
1859 "GUID parse failed");
1861 torture_assert_guid_equal(tctx
, server_side_wrapped
->guid
,
1863 "GUID didn't match value pointed at by G$BCKUPKEY_P");
1865 /* And read BCKUPKEY_<guid> and get the actual key */
1867 key_guid_string
= GUID_string(tctx
, &server_side_wrapped
->guid
);
1868 r_secret
.in
.name
.string
= talloc_asprintf(tctx
, "G$BCKUPKEY_%s", key_guid_string
);
1870 r_secret
.in
.handle
= handle
;
1871 r_secret
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1872 r_secret
.out
.sec_handle
= &sec_handle
;
1874 torture_comment(tctx
, "Testing OpenSecret\n");
1876 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenSecret_r(lsa_b
, tctx
, &r_secret
),
1877 "OpenSecret failed");
1878 torture_assert_ntstatus_ok(tctx
, r_secret
.out
.result
,
1879 "OpenSecret failed");
1881 r_query_secret
.in
.sec_handle
= &sec_handle
;
1882 r_query_secret
.in
.new_val
= &bufp1
;
1884 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QuerySecret_r(lsa_b
, tctx
, &r_query_secret
),
1885 "QuerySecret failed");
1886 torture_assert_ntstatus_ok(tctx
, r_query_secret
.out
.result
,
1887 "QuerySecret failed");
1890 decrypt_key
.data
= r_query_secret
.out
.new_val
->buf
->data
;
1891 decrypt_key
.length
= r_query_secret
.out
.new_val
->buf
->size
;
1893 torture_assert_ntstatus_ok(tctx
,
1894 sess_decrypt_blob(tctx
,
1895 &decrypt_key
, &session_key
, &decrypt_key_clear
),
1896 "sess_decrypt_blob failed");
1898 torture_assert_ndr_err_equal(tctx
, ndr_pull_struct_blob(&decrypt_key_clear
, tctx
, &server_key
,
1899 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_dc_serverwrap_key
),
1900 NDR_ERR_SUCCESS
, "Failed to parse server_key");
1902 torture_assert_int_equal(tctx
, server_key
.magic
, 1, "Failed to correctly decrypt server key");
1905 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1906 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1908 gnutls_hmac_init(&hmac_hnd
,
1911 sizeof(server_key
.key
));
1912 gnutls_hmac(hmac_hnd
,
1913 server_side_wrapped
->r2
,
1914 sizeof(server_side_wrapped
->r2
));
1915 gnutls_hmac_output(hmac_hnd
, symkey
);
1917 /* rc4 decrypt sid and secret using sym key */
1918 cipher_key
.data
= symkey
;
1919 cipher_key
.size
= sizeof(symkey
);
1921 encrypted_blob
= data_blob_talloc(tctx
, server_side_wrapped
->rc4encryptedpayload
,
1922 server_side_wrapped
->ciphertext_length
);
1924 rc
= gnutls_cipher_init(&cipher_hnd
,
1925 GNUTLS_CIPHER_ARCFOUR_128
,
1928 torture_assert_int_equal(tctx
,
1931 "gnutls_cipher_init failed");
1932 rc
= gnutls_cipher_encrypt2(cipher_hnd
,
1933 encrypted_blob
.data
,
1934 encrypted_blob
.length
,
1935 encrypted_blob
.data
,
1936 encrypted_blob
.length
);
1937 torture_assert_int_equal(tctx
,
1940 "gnutls_cipher_encrypt failed");
1941 gnutls_cipher_deinit(cipher_hnd
);
1943 torture_assert_ndr_err_equal(tctx
, ndr_pull_struct_blob(&encrypted_blob
, tctx
, &rc4payload
,
1944 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_rc4encryptedpayload
),
1945 NDR_ERR_SUCCESS
, "Failed to parse rc4encryptedpayload");
1947 torture_assert_int_equal(tctx
, rc4payload
.secret_data
.length
,
1948 server_side_wrapped
->payload_length
,
1949 "length of decrypted payload not the length declared in surrounding structure");
1952 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1953 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1955 gnutls_hmac(hmac_hnd
,
1957 sizeof(rc4payload
.r3
));
1958 gnutls_hmac_deinit(hmac_hnd
, mackey
);
1960 torture_assert_ndr_err_equal(tctx
, ndr_push_struct_blob(&sid_blob
, tctx
, &rc4payload
.sid
,
1961 (ndr_push_flags_fn_t
)ndr_push_dom_sid
),
1962 NDR_ERR_SUCCESS
, "unable to push SID");
1964 gnutls_hmac_init(&hmac_hnd
,
1969 gnutls_hmac(hmac_hnd
,
1973 gnutls_hmac(hmac_hnd
,
1974 rc4payload
.secret_data
.data
,
1975 rc4payload
.secret_data
.length
);
1976 gnutls_hmac_output(hmac_hnd
, mac
);
1978 torture_assert_mem_equal(tctx
, mac
, rc4payload
.mac
, sizeof(mac
), "mac not correct");
1979 torture_assert_int_equal(tctx
, rc4payload
.secret_data
.length
,
1980 plaintext
.length
, "decrypted data is not correct length");
1981 torture_assert_mem_equal(tctx
, rc4payload
.secret_data
.data
,
1982 plaintext
.data
, plaintext
.length
,
1983 "decrypted data is not correct");
1985 /* Not strictly correct all the time, but good enough for this test */
1986 caller_sid
= get_user_sid(tctx
, tctx
,
1987 cli_credentials_get_username(
1988 popt_get_cmdline_credentials()));
1990 torture_assert_sid_equal(tctx
, &rc4payload
.sid
, caller_sid
, "Secret saved with wrong SID");
1995 if (wrong
== WRONG_SID
) {
1996 rc4payload
.sid
.sub_auths
[rc4payload
.sid
.num_auths
- 1] = DOMAIN_RID_KRBTGT
;
1999 dump_data_pw("mackey: \n", mackey
, sizeof(mackey
));
2001 torture_assert_ndr_err_equal(tctx
,
2002 ndr_push_struct_blob(&sid_blob
, tctx
, &rc4payload
.sid
,
2003 (ndr_push_flags_fn_t
)ndr_push_dom_sid
),
2005 "push of sid failed");
2008 gnutls_hmac(hmac_hnd
,
2012 gnutls_hmac(hmac_hnd
,
2013 rc4payload
.secret_data
.data
,
2014 rc4payload
.secret_data
.length
);
2015 gnutls_hmac_deinit(hmac_hnd
, rc4payload
.mac
);
2017 dump_data_pw("rc4payload.mac: \n", rc4payload
.mac
, sizeof(rc4payload
.mac
));
2019 torture_assert_ndr_err_equal(tctx
,
2020 ndr_push_struct_blob(&encrypted_blob
, tctx
, &rc4payload
,
2021 (ndr_push_flags_fn_t
)ndr_push_bkrp_rc4encryptedpayload
),
2023 "push of rc4payload failed");
2025 if (wrong
== WRONG_KEY
) {
2031 /* rc4 encrypt sid and secret using sym key */
2032 cipher_key
.data
= symkey
;
2033 cipher_key
.size
= sizeof(symkey
);
2035 rc
= gnutls_cipher_init(&cipher_hnd
,
2036 GNUTLS_CIPHER_ARCFOUR_128
,
2039 torture_assert_int_equal(tctx
,
2042 "gnutls_cipher_init failed");
2043 rc
= gnutls_cipher_encrypt2(cipher_hnd
,
2044 encrypted_blob
.data
,
2045 encrypted_blob
.length
,
2046 encrypted_blob
.data
,
2047 encrypted_blob
.length
);
2048 torture_assert_int_equal(tctx
,
2051 "gnutls_cipher_encrypt failed");
2052 gnutls_cipher_deinit(cipher_hnd
);
2055 /* re-create server wrap structure */
2057 torture_assert_int_equal(tctx
, encrypted_blob
.length
,
2058 server_side_wrapped
->ciphertext_length
,
2059 "expected encrypted length not to change");
2060 if (wrong
== RIGHT_KEY
) {
2061 torture_assert_mem_equal(tctx
, server_side_wrapped
->rc4encryptedpayload
,
2062 encrypted_blob
.data
,
2063 encrypted_blob
.length
,
2064 "expected encrypted data not to change");
2067 server_side_wrapped
->payload_length
= rc4payload
.secret_data
.length
;
2068 server_side_wrapped
->ciphertext_length
= encrypted_blob
.length
;
2069 server_side_wrapped
->rc4encryptedpayload
= encrypted_blob
.data
;
2075 static bool test_ServerWrap_decrypt_wrong_stuff(struct torture_context
*tctx
,
2076 struct dcerpc_pipe
*p
,
2077 enum test_wrong wrong
)
2079 struct bkrp_BackupKey r
;
2081 DATA_BLOB plaintext
= data_blob_const(secret
, sizeof(secret
));
2082 DATA_BLOB encrypted
;
2084 DATA_BLOB decrypted
;
2086 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2087 enum ndr_err_code ndr_err
;
2088 struct bkrp_server_side_wrapped server_side_wrapped
;
2089 bool repush
= false;
2090 enum dcerpc_AuthType auth_type
;
2091 enum dcerpc_AuthLevel auth_level
;
2094 gnutls_global_init();
2096 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
2099 torture_assert_ntstatus_ok(tctx
,
2100 GUID_from_string(BACKUPKEY_BACKUP_GUID
, &guid
),
2103 r
.in
.guidActionAgent
= &guid
;
2104 r
.in
.data_in
= plaintext
.data
;
2105 r
.in
.data_in_len
= plaintext
.length
;
2107 r
.out
.data_out
= &encrypted
.data
;
2108 r
.out
.data_out_len
= &enclen
;
2109 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
2110 torture_assert_ntstatus_ok(tctx
,
2111 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
2114 torture_assert_ntstatus_equal(tctx
,
2115 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
2116 NT_STATUS_ACCESS_DENIED
,
2120 torture_assert_werr_ok(tctx
,
2123 encrypted
.length
= *r
.out
.data_out_len
;
2125 ndr_err
= ndr_pull_struct_blob(&encrypted
, tctx
, &server_side_wrapped
,
2126 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_server_side_wrapped
);
2127 torture_assert_ndr_err_equal(tctx
, ndr_err
, NDR_ERR_SUCCESS
, "pull of server_side_wrapped");
2129 torture_assert_int_equal(tctx
, server_side_wrapped
.payload_length
, plaintext
.length
,
2130 "wrong payload length");
2134 /* Change the magic. Forced by our NDR layer, so do it raw */
2135 SIVAL(encrypted
.data
, 0, 78); /* valid values are 1-3 */
2138 server_side_wrapped
.r2
[0] = 78;
2139 server_side_wrapped
.r2
[1] = 78;
2140 server_side_wrapped
.r2
[3] = 78;
2143 case WRONG_PAYLOAD_LENGTH
:
2144 server_side_wrapped
.payload_length
= UINT32_MAX
- 8;
2147 case WRONG_CIPHERTEXT_LENGTH
:
2149 * Change the ciphertext len. We can't push this if
2150 * we have it wrong, so do it raw
2152 SIVAL(encrypted
.data
, 8, UINT32_MAX
- 8); /* valid values are 1-3 */
2154 case SHORT_PAYLOAD_LENGTH
:
2155 server_side_wrapped
.payload_length
= server_side_wrapped
.payload_length
- 8;
2158 case SHORT_CIPHERTEXT_LENGTH
:
2160 * Change the ciphertext len. We can't push this if
2161 * we have it wrong, so do it raw
2163 SIVAL(encrypted
.data
, 8, server_side_wrapped
.ciphertext_length
- 8); /* valid values are 1-3 */
2165 case ZERO_PAYLOAD_LENGTH
:
2166 server_side_wrapped
.payload_length
= 0;
2169 case ZERO_CIPHERTEXT_LENGTH
:
2171 * Change the ciphertext len. We can't push this if
2172 * we have it wrong, so do it raw
2174 SIVAL(encrypted
.data
, 8, 0); /* valid values are 1-3 */
2180 torture_assert(tctx
,
2181 test_ServerWrap_encrypt_decrypt_manual(tctx
, &server_side_wrapped
, wrong
),
2182 "test_ServerWrap_encrypt_decrypt_manual failed");
2188 ndr_err
= ndr_push_struct_blob(&encrypted
, tctx
, &server_side_wrapped
,
2189 (ndr_push_flags_fn_t
)ndr_push_bkrp_server_side_wrapped
);
2190 torture_assert_ndr_err_equal(tctx
, ndr_err
, NDR_ERR_SUCCESS
, "push of server_side_wrapped");
2194 torture_assert_ntstatus_ok(tctx
,
2195 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
2198 r
.in
.guidActionAgent
= &guid
;
2199 r
.in
.data_in
= encrypted
.data
;
2200 r
.in
.data_in_len
= encrypted
.length
;
2202 r
.out
.data_out
= &(decrypted
.data
);
2203 r
.out
.data_out_len
= &declen
;
2204 torture_assert_ntstatus_ok(tctx
,
2205 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
2208 if ((wrong
== WRONG_R2
|| wrong
== WRONG_KEY
)
2209 && W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_SID
)) {
2210 torture_assert_werr_equal(tctx
,
2213 "decrypt should fail with WERR_INVALID_SID or WERR_INVALID_PARAMETER");
2214 } else if (wrong
== RIGHT_KEY
) {
2215 torture_assert_werr_equal(tctx
,
2218 "decrypt should succeed!");
2219 } else if (wrong
== WRONG_SID
) {
2220 torture_assert_werr_equal(tctx
,
2222 WERR_INVALID_ACCESS
,
2223 "decrypt should fail with WERR_INVALID_ACCESS");
2225 if (!W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_ACCESS
)
2226 && !W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_PARAMETER
)) {
2227 torture_assert_werr_equal(tctx
, r
.out
.result
,
2229 "decrypt should fail with WERR_INVALID_ACCESS, WERR_INVALID_PARAMETER or WERR_INVALID_DATA");
2234 torture_assert_ntstatus_ok(tctx
,
2235 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
2238 r
.in
.guidActionAgent
= &guid
;
2239 r
.in
.data_in
= encrypted
.data
;
2240 r
.in
.data_in_len
= encrypted
.length
;
2242 r
.out
.data_out
= &(decrypted
.data
);
2243 r
.out
.data_out_len
= &declen
;
2244 torture_assert_ntstatus_ok(tctx
,
2245 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
2248 if ((wrong
== WRONG_R2
|| wrong
== WRONG_KEY
)
2249 && W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_SID
)) {
2250 torture_assert_werr_equal(tctx
,
2253 "decrypt should fail with WERR_INVALID_SID or WERR_INVALID_PARAMETER");
2254 } else if (wrong
== RIGHT_KEY
) {
2255 torture_assert_werr_equal(tctx
,
2258 "decrypt should succeed!");
2259 } else if (wrong
== WRONG_SID
) {
2260 torture_assert_werr_equal(tctx
,
2262 WERR_INVALID_ACCESS
,
2263 "decrypt should fail with WERR_INVALID_ACCESS");
2265 torture_assert_werr_equal(tctx
,
2267 WERR_INVALID_PARAMETER
,
2268 "decrypt should fail with WERR_INVALID_PARAMETER");
2271 gnutls_global_deinit();
2276 static bool test_ServerWrap_decrypt_wrong_magic(struct torture_context
*tctx
,
2277 struct dcerpc_pipe
*p
)
2279 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_MAGIC
);
2282 static bool test_ServerWrap_decrypt_wrong_r2(struct torture_context
*tctx
,
2283 struct dcerpc_pipe
*p
)
2285 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_R2
);
2288 static bool test_ServerWrap_decrypt_wrong_payload_length(struct torture_context
*tctx
,
2289 struct dcerpc_pipe
*p
)
2291 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_PAYLOAD_LENGTH
);
2294 static bool test_ServerWrap_decrypt_short_payload_length(struct torture_context
*tctx
,
2295 struct dcerpc_pipe
*p
)
2297 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, SHORT_PAYLOAD_LENGTH
);
2300 static bool test_ServerWrap_decrypt_zero_payload_length(struct torture_context
*tctx
,
2301 struct dcerpc_pipe
*p
)
2303 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, ZERO_PAYLOAD_LENGTH
);
2306 static bool test_ServerWrap_decrypt_wrong_ciphertext_length(struct torture_context
*tctx
,
2307 struct dcerpc_pipe
*p
)
2309 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_CIPHERTEXT_LENGTH
);
2312 static bool test_ServerWrap_decrypt_short_ciphertext_length(struct torture_context
*tctx
,
2313 struct dcerpc_pipe
*p
)
2315 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, SHORT_CIPHERTEXT_LENGTH
);
2318 static bool test_ServerWrap_decrypt_zero_ciphertext_length(struct torture_context
*tctx
,
2319 struct dcerpc_pipe
*p
)
2321 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, ZERO_CIPHERTEXT_LENGTH
);
2324 static bool test_ServerWrap_encrypt_decrypt_remote_key(struct torture_context
*tctx
,
2325 struct dcerpc_pipe
*p
)
2327 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, RIGHT_KEY
);
2330 static bool test_ServerWrap_encrypt_decrypt_wrong_key(struct torture_context
*tctx
,
2331 struct dcerpc_pipe
*p
)
2333 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_KEY
);
2336 static bool test_ServerWrap_encrypt_decrypt_wrong_sid(struct torture_context
*tctx
,
2337 struct dcerpc_pipe
*p
)
2339 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_SID
);
2342 struct torture_suite
*torture_rpc_backupkey(TALLOC_CTX
*mem_ctx
)
2344 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "backupkey");
2346 struct torture_rpc_tcase
*tcase
;
2348 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "backupkey",
2349 &ndr_table_backupkey
);
2351 torture_rpc_tcase_add_test(tcase
, "retreive_backup_key_guid",
2352 test_RetrieveBackupKeyGUID
);
2354 torture_rpc_tcase_add_test(tcase
, "restore_guid",
2357 torture_rpc_tcase_add_test(tcase
, "restore_guid version 3",
2358 test_RestoreGUID_v3
);
2360 /* We double the test in order to be sure that we don't mess stuff (ie. freeing static stuff) */
2362 torture_rpc_tcase_add_test(tcase
, "restore_guid_2nd",
2365 torture_rpc_tcase_add_test(tcase
, "unable_to_decrypt_secret",
2366 test_RestoreGUID_ko
);
2368 torture_rpc_tcase_add_test(tcase
, "wrong_user_restore_guid",
2369 test_RestoreGUID_wronguser
);
2371 torture_rpc_tcase_add_test(tcase
, "wrong_version_restore_guid",
2372 test_RestoreGUID_wrongversion
);
2374 torture_rpc_tcase_add_test(tcase
, "bad_magic_on_secret_restore_guid",
2375 test_RestoreGUID_badmagiconsecret
);
2377 torture_rpc_tcase_add_test(tcase
, "bad_hash_on_secret_restore_guid",
2378 test_RestoreGUID_badhashaccesscheck
);
2380 torture_rpc_tcase_add_test(tcase
, "bad_magic_on_accesscheck_restore_guid",
2381 test_RestoreGUID_badmagicaccesscheck
);
2383 torture_rpc_tcase_add_test(tcase
, "bad_cert_guid_restore_guid",
2384 test_RestoreGUID_badcertguid
);
2386 torture_rpc_tcase_add_test(tcase
, "empty_request_restore_guid",
2387 test_RestoreGUID_emptyrequest
);
2389 torture_rpc_tcase_add_test(tcase
, "retreive_backup_key_guid_validate",
2390 test_RetrieveBackupKeyGUID_validate
);
2392 torture_rpc_tcase_add_test(tcase
, "server_wrap_encrypt_decrypt",
2393 test_ServerWrap_encrypt_decrypt
);
2395 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_wrong_keyGUID",
2396 test_ServerWrap_decrypt_wrong_keyGUID
);
2398 torture_rpc_tcase_add_test(tcase
, "server_wrap_empty_request",
2399 test_ServerWrap_decrypt_empty_request
);
2401 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_short_request",
2402 test_ServerWrap_decrypt_short_request
);
2404 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_wrong_magic",
2405 test_ServerWrap_decrypt_wrong_magic
);
2407 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_wrong_r2",
2408 test_ServerWrap_decrypt_wrong_r2
);
2410 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_wrong_payload_length",
2411 test_ServerWrap_decrypt_wrong_payload_length
);
2413 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_short_payload_length",
2414 test_ServerWrap_decrypt_short_payload_length
);
2416 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_zero_payload_length",
2417 test_ServerWrap_decrypt_zero_payload_length
);
2419 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_wrong_ciphertext_length",
2420 test_ServerWrap_decrypt_wrong_ciphertext_length
);
2422 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_short_ciphertext_length",
2423 test_ServerWrap_decrypt_short_ciphertext_length
);
2425 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_zero_ciphertext_length",
2426 test_ServerWrap_decrypt_zero_ciphertext_length
);
2428 torture_rpc_tcase_add_test(tcase
, "server_wrap_encrypt_decrypt_remote_key",
2429 test_ServerWrap_encrypt_decrypt_remote_key
);
2431 torture_rpc_tcase_add_test(tcase
, "server_wrap_encrypt_decrypt_wrong_key",
2432 test_ServerWrap_encrypt_decrypt_wrong_key
);
2434 torture_rpc_tcase_add_test(tcase
, "server_wrap_encrypt_decrypt_wrong_sid",
2435 test_ServerWrap_encrypt_decrypt_wrong_sid
);