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/cmdline.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 discarded 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 samba_cmdline_get_creds());
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 structure
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 different 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 different 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 structure 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
= NULL
;
268 DATA_BLOB
*blob
= NULL
;
269 enum ndr_err_code ndr_err
;
270 const struct dom_sid
*sid
= NULL
;
272 tmp_ctx
= talloc_new(mem_ctx
);
273 if (tmp_ctx
== NULL
) {
277 sid
= get_user_sid(tctx
, tmp_ctx
, user
);
279 talloc_free(tmp_ctx
);
283 blob
= talloc_zero(mem_ctx
, DATA_BLOB
);
285 talloc_free(tmp_ctx
);
290 struct bkrp_access_check_v2 access_struct
;
291 gnutls_hash_hd_t dig_ctx
;
295 ZERO_STRUCT(access_struct
);
296 generate_random_buffer(nonce
, sizeof(nonce
));
297 access_struct
.nonce_len
= sizeof(nonce
);
298 access_struct
.nonce
= nonce
;
299 access_struct
.sid
= *sid
;
301 ndr_err
= ndr_push_struct_blob(blob
, blob
, &access_struct
,
302 (ndr_push_flags_fn_t
)ndr_push_bkrp_access_check_v2
);
303 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
305 talloc_free(tmp_ctx
);
310 * We pushed the whole structure including a null hash
311 * but the hash need to be calculated only up to the hash field
312 * so we reduce the size of what has to be calculated
315 rc
= gnutls_hash_init(&dig_ctx
, GNUTLS_DIG_SHA1
);
316 if (rc
!= GNUTLS_E_SUCCESS
) {
318 talloc_free(tmp_ctx
);
321 rc
= gnutls_hash(dig_ctx
,
323 blob
->length
- sizeof(access_struct
.hash
));
324 gnutls_hash_deinit(dig_ctx
,
325 blob
->data
+ blob
->length
- sizeof(access_struct
.hash
));
326 if (rc
!= GNUTLS_E_SUCCESS
) {
328 talloc_free(tmp_ctx
);
332 /* Altering the SHA */
334 blob
->data
[blob
->length
- 1]++;
339 struct bkrp_access_check_v3 access_struct
;
340 gnutls_hash_hd_t dig_ctx
;
344 ZERO_STRUCT(access_struct
);
345 generate_random_buffer(nonce
, sizeof(nonce
));
346 access_struct
.nonce_len
= sizeof(nonce
);
347 access_struct
.nonce
= nonce
;
348 access_struct
.sid
= *sid
;
350 ndr_err
= ndr_push_struct_blob(blob
, blob
, &access_struct
,
351 (ndr_push_flags_fn_t
)ndr_push_bkrp_access_check_v3
);
352 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
354 talloc_free(tmp_ctx
);
358 /*We pushed the whole structure including a null hash
359 * but the hash need to be calculated only up to the hash field
360 * so we reduce the size of what has to be calculated
363 rc
= gnutls_hash_init(&dig_ctx
, GNUTLS_DIG_SHA512
);
364 if (rc
!= GNUTLS_E_SUCCESS
) {
366 talloc_free(tmp_ctx
);
369 rc
= gnutls_hash(dig_ctx
,
371 blob
->length
- sizeof(access_struct
.hash
));
372 gnutls_hash_deinit(dig_ctx
,
373 blob
->data
+ blob
->length
- sizeof(access_struct
.hash
));
374 if (rc
!= GNUTLS_E_SUCCESS
) {
376 talloc_free(tmp_ctx
);
380 /* Altering the SHA */
382 blob
->data
[blob
->length
-1]++;
385 talloc_free(tmp_ctx
);
390 static DATA_BLOB
*encrypt_blob(struct torture_context
*tctx
,
394 DATA_BLOB
*to_encrypt
,
395 gnutls_cipher_algorithm_t cipher_algo
)
397 gnutls_cipher_hd_t cipher_handle
= { 0 };
398 gnutls_datum_t gkey
= {
402 gnutls_datum_t giv
= {
409 blob
= talloc(mem_ctx
, DATA_BLOB
);
414 *blob
= data_blob_talloc_zero(mem_ctx
, to_encrypt
->length
);
415 if (blob
->data
== NULL
) {
420 rc
= gnutls_cipher_init(&cipher_handle
,
424 if (rc
!= GNUTLS_E_SUCCESS
) {
425 torture_comment(tctx
,
426 "gnutls_cipher_init failed: %s\n",
427 gnutls_strerror(rc
));
432 rc
= gnutls_cipher_encrypt2(cipher_handle
,
437 gnutls_cipher_deinit(cipher_handle
);
438 if (rc
!= GNUTLS_E_SUCCESS
) {
439 torture_comment(tctx
,
440 "gnutls_cipher_decrypt2 failed: %s\n",
441 gnutls_strerror(rc
));
449 * Certs used for this protocol have a GUID in the issuer_uniq_id field.
450 * This function fetch it.
452 static struct GUID
*get_cert_guid(struct torture_context
*tctx
,
457 gnutls_x509_crt_t x509_cert
= NULL
;
458 gnutls_datum_t x509_crt_data
= {
462 uint8_t dummy
[1] = {0};
463 DATA_BLOB issuer_unique_id
= {
467 struct GUID
*guid
= talloc_zero(mem_ctx
, struct GUID
);
471 rc
= gnutls_x509_crt_init(&x509_cert
);
472 if (rc
!= GNUTLS_E_SUCCESS
) {
473 torture_comment(tctx
,
474 "gnutls_x509_crt_init failed - %s",
475 gnutls_strerror(rc
));
479 rc
= gnutls_x509_crt_import(x509_cert
,
481 GNUTLS_X509_FMT_DER
);
482 if (rc
!= GNUTLS_E_SUCCESS
) {
483 torture_comment(tctx
,
484 "gnutls_x509_crt_import failed - %s",
485 gnutls_strerror(rc
));
486 gnutls_x509_crt_deinit(x509_cert
);
490 /* Get the buffer size */
491 rc
= gnutls_x509_crt_get_issuer_unique_id(x509_cert
,
492 (char *)issuer_unique_id
.data
,
493 &issuer_unique_id
.length
);
494 if (rc
!= GNUTLS_E_SHORT_MEMORY_BUFFER
||
495 issuer_unique_id
.length
== 0) {
496 gnutls_x509_crt_deinit(x509_cert
);
500 issuer_unique_id
= data_blob_talloc_zero(mem_ctx
,
501 issuer_unique_id
.length
);
502 if (issuer_unique_id
.data
== NULL
) {
503 gnutls_x509_crt_deinit(x509_cert
);
507 rc
= gnutls_x509_crt_get_issuer_unique_id(x509_cert
,
508 (char *)issuer_unique_id
.data
,
509 &issuer_unique_id
.length
);
510 gnutls_x509_crt_deinit(x509_cert
);
511 if (rc
!= GNUTLS_E_SUCCESS
) {
512 torture_comment(tctx
,
513 "gnutls_x509_crt_get_issuer_unique_id failed - %s",
514 gnutls_strerror(rc
));
518 status
= GUID_from_data_blob(&issuer_unique_id
, guid
);
519 if (!NT_STATUS_IS_OK(status
)) {
527 * Encrypt a blob with the private key of the certificate
528 * passed as a parameter.
530 static DATA_BLOB
*encrypt_blob_pk(struct torture_context
*tctx
,
534 DATA_BLOB
*to_encrypt
)
536 gnutls_x509_crt_t x509_cert
;
537 gnutls_datum_t x509_crt_data
= {
541 gnutls_pubkey_t pubkey
;
542 gnutls_datum_t plaintext
= {
543 .data
= to_encrypt
->data
,
544 .size
= to_encrypt
->length
,
546 gnutls_datum_t ciphertext
= {
552 rc
= gnutls_x509_crt_init(&x509_cert
);
553 if (rc
!= GNUTLS_E_SUCCESS
) {
557 rc
= gnutls_x509_crt_import(x509_cert
,
559 GNUTLS_X509_FMT_DER
);
560 if (rc
!= GNUTLS_E_SUCCESS
) {
561 gnutls_x509_crt_deinit(x509_cert
);
565 rc
= gnutls_pubkey_init(&pubkey
);
566 if (rc
!= GNUTLS_E_SUCCESS
) {
567 gnutls_x509_crt_deinit(x509_cert
);
571 rc
= gnutls_pubkey_import_x509(pubkey
,
574 gnutls_x509_crt_deinit(x509_cert
);
575 if (rc
!= GNUTLS_E_SUCCESS
) {
576 gnutls_pubkey_deinit(pubkey
);
580 rc
= gnutls_pubkey_encrypt_data(pubkey
,
584 gnutls_pubkey_deinit(pubkey
);
585 if (rc
!= GNUTLS_E_SUCCESS
) {
589 blob
= talloc_zero(mem_ctx
, DATA_BLOB
);
591 gnutls_pubkey_deinit(pubkey
);
595 *blob
= data_blob_talloc(blob
, ciphertext
.data
, ciphertext
.size
);
596 gnutls_free(ciphertext
.data
);
597 if (blob
->data
== NULL
) {
598 gnutls_pubkey_deinit(pubkey
);
605 static struct bkrp_BackupKey
*createRetrieveBackupKeyGUIDStruct(struct torture_context
*tctx
,
606 struct dcerpc_pipe
*p
, int version
, DATA_BLOB
*out
)
608 struct dcerpc_binding
*binding
;
609 struct bkrp_client_side_wrapped data
;
610 struct GUID
*g
= talloc(tctx
, struct GUID
);
611 struct bkrp_BackupKey
*r
= talloc_zero(tctx
, struct bkrp_BackupKey
);
612 enum ndr_err_code ndr_err
;
620 binding
= dcerpc_binding_dup(tctx
, p
->binding
);
621 if (binding
== NULL
) {
625 status
= dcerpc_binding_set_flags(binding
, DCERPC_SEAL
|DCERPC_AUTH_SPNEGO
, 0);
626 if (!NT_STATUS_IS_OK(status
)) {
631 status
= GUID_from_string(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID
, g
);
632 if (!NT_STATUS_IS_OK(status
)) {
636 r
->in
.guidActionAgent
= g
;
637 data
.version
= version
;
638 ndr_err
= ndr_push_struct_blob(&blob
, tctx
, &data
,
639 (ndr_push_flags_fn_t
)ndr_push_bkrp_client_side_wrapped
);
640 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
643 r
->in
.data_in
= blob
.data
;
644 r
->in
.data_in_len
= blob
.length
;
645 r
->out
.data_out
= &out
->data
;
646 r
->out
.data_out_len
= talloc(r
, uint32_t);
650 static struct bkrp_BackupKey
*createRestoreGUIDStruct(struct torture_context
*tctx
,
651 struct dcerpc_pipe
*p
, int version
, DATA_BLOB
*out
,
655 bool broken_magic_secret
,
656 bool broken_magic_access
,
657 bool broken_hash_access
,
658 bool broken_cert_guid
)
660 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
661 struct bkrp_client_side_wrapped data
;
664 DATA_BLOB
*enc_sec
= NULL
;
665 DATA_BLOB
*enc_xs
= NULL
;
667 DATA_BLOB enc_sec_reverted
;
671 struct GUID
*guid
, *g
;
674 enum ndr_err_code ndr_err
;
677 gnutls_cipher_algorithm_t cipher_algo
;
678 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, version
, &out_blob
);
684 /* we take a fake user*/
687 user
= cli_credentials_get_username(
688 samba_cmdline_get_creds());
692 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
694 torture_assert_werr_ok(tctx
, r
->out
.result
,
698 * We have to set it outside of the function createRetrieveBackupKeyGUIDStruct
699 * the len of the blob, this is due to the fact that they don't have the
700 * same size (one is 32bits the other 64bits)
702 out_blob
.length
= *r
->out
.data_out_len
;
704 sec
= create_unencryptedsecret(tctx
, broken_magic_secret
, version
);
709 xs
= create_access_check(tctx
, p
, tctx
, user
, broken_hash_access
, version
);
714 if (broken_magic_access
){
715 /* The start of the access_check structure contains the
716 * GUID of the certificate
721 enc_sec
= encrypt_blob_pk(tctx
, tctx
, out_blob
.data
, out_blob
.length
, sec
);
725 enc_sec_reverted
.data
= talloc_array(tctx
, uint8_t, enc_sec
->length
);
726 if (enc_sec_reverted
.data
== NULL
) {
729 enc_sec_reverted
.length
= enc_sec
->length
;
732 * We DO NOT revert the array on purpose it's in order to check that
733 * when the server is not able to decrypt then it answer the correct error
736 for(t
=0; t
< enc_sec
->length
; t
++) {
737 enc_sec_reverted
.data
[t
] = ((uint8_t*)enc_sec
->data
)[t
];
740 for(t
=0; t
< enc_sec
->length
; t
++) {
741 enc_sec_reverted
.data
[t
] = ((uint8_t*)enc_sec
->data
)[enc_sec
->length
- t
-1];
748 cipher_algo
= GNUTLS_CIPHER_3DES_CBC
;
751 cipher_algo
= GNUTLS_CIPHER_AES_256_CBC
;
756 iv
.length
= gnutls_cipher_get_iv_size(cipher_algo
);
757 iv
.data
= sec
->data
+ (size
- iv
.length
);
759 key
.length
= gnutls_cipher_get_key_size(cipher_algo
);
760 key
.data
= sec
->data
+ (size
- (key
.length
+ iv
.length
));
762 enc_xs
= encrypt_blob(tctx
, tctx
, &key
, &iv
, xs
, cipher_algo
);
767 /* To cope with the fact that heimdal do padding at the end for the moment */
768 enc_xs
->length
= xs
->length
;
770 guid
= get_cert_guid(tctx
, tctx
, out_blob
.data
, out_blob
.length
);
775 if (broken_version
) {
778 data
.version
= version
;
782 data
.encrypted_secret
= enc_sec_reverted
.data
;
783 data
.access_check
= enc_xs
->data
;
784 data
.encrypted_secret_len
= enc_sec
->length
;
785 data
.access_check_len
= enc_xs
->length
;
787 /* We want the blob to persist after this function so we don't
788 * allocate it in the stack
790 blob2
= talloc(tctx
, DATA_BLOB
);
795 ndr_err
= ndr_push_struct_blob(blob2
, tctx
, &data
,
796 (ndr_push_flags_fn_t
)ndr_push_bkrp_client_side_wrapped
);
797 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
801 if (broken_cert_guid
) {
807 g
= talloc(tctx
, struct GUID
);
812 status
= GUID_from_string(BACKUPKEY_RESTORE_GUID
, g
);
813 if (!NT_STATUS_IS_OK(status
)) {
817 r
->in
.guidActionAgent
= g
;
818 r
->in
.data_in
= blob2
->data
;
819 r
->in
.data_in_len
= blob2
->length
;
821 r
->out
.data_out
= &(out
->data
);
822 r
->out
.data_out_len
= talloc(r
, uint32_t);
826 /* Check that we are able to receive the certificate of the DCs
827 * used for client wrap version of the backup key protocol
829 static bool test_RetrieveBackupKeyGUID(struct torture_context
*tctx
,
830 struct dcerpc_pipe
*p
)
832 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
834 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
835 enum dcerpc_AuthType auth_type
;
836 enum dcerpc_AuthLevel auth_level
;
842 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
844 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
845 torture_assert_ntstatus_ok(tctx
,
846 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
849 out_blob
.length
= *r
->out
.data_out_len
;
850 torture_assert_werr_equal(tctx
,
853 "Wrong dce/rpc error code");
855 torture_assert_ntstatus_equal(tctx
,
856 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
857 NT_STATUS_ACCESS_DENIED
,
863 /* Test to check the failure to recover a secret because the
864 * secret blob is not reversed
866 static bool test_RestoreGUID_ko(struct torture_context
*tctx
,
867 struct dcerpc_pipe
*p
)
869 enum ndr_err_code ndr_err
;
870 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
872 struct bkrp_client_side_unwrapped resp
;
873 enum dcerpc_AuthType auth_type
;
874 enum dcerpc_AuthLevel auth_level
;
876 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
878 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
879 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
880 true, false, false, false, false, false, false);
881 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
882 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
883 out_blob
.length
= *r
->out
.data_out_len
;
884 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
885 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
886 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_PARAMETER
, "Wrong error code");
888 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
889 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
890 NT_STATUS_ACCESS_DENIED
, "Get GUID");
896 static bool test_RestoreGUID_wrongversion(struct torture_context
*tctx
,
897 struct dcerpc_pipe
*p
)
899 enum ndr_err_code ndr_err
;
900 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
902 struct bkrp_client_side_unwrapped resp
;
903 enum dcerpc_AuthType auth_type
;
904 enum dcerpc_AuthLevel auth_level
;
906 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
908 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
909 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
910 false, true, false, false, false, false, false);
911 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
912 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
913 out_blob
.length
= *r
->out
.data_out_len
;
914 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
915 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
916 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_PARAMETER
, "Wrong error code on wrong version");
918 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
919 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
920 NT_STATUS_ACCESS_DENIED
, "Get GUID");
926 static bool test_RestoreGUID_wronguser(struct torture_context
*tctx
,
927 struct dcerpc_pipe
*p
)
929 enum ndr_err_code ndr_err
;
930 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
932 struct bkrp_client_side_unwrapped resp
;
933 enum dcerpc_AuthType auth_type
;
934 enum dcerpc_AuthLevel auth_level
;
936 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
938 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
939 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
940 false, false, true, false, false, false, false);
941 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
942 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
943 out_blob
.length
= *r
->out
.data_out_len
;
944 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
945 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
946 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_ACCESS
, "Restore GUID");
948 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
949 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
950 NT_STATUS_ACCESS_DENIED
, "Get GUID");
956 static bool test_RestoreGUID_v3(struct torture_context
*tctx
,
957 struct dcerpc_pipe
*p
)
959 enum ndr_err_code ndr_err
;
960 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
962 struct bkrp_client_side_unwrapped resp
;
963 enum dcerpc_AuthType auth_type
;
964 enum dcerpc_AuthLevel auth_level
;
966 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
968 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
969 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
970 false, false, false, false, false, false, false);
971 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
972 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
973 out_blob
.length
= *r
->out
.data_out_len
;
974 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
975 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 1, "Unable to unmarshall bkrp_client_side_unwrapped");
976 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_OK
, "Restore GUID");
977 torture_assert_str_equal(tctx
, (char*)resp
.secret
.data
, secret
, "Wrong secret");
979 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
980 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
981 NT_STATUS_ACCESS_DENIED
, "Get GUID");
987 static bool test_RestoreGUID(struct torture_context
*tctx
,
988 struct dcerpc_pipe
*p
)
990 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
992 struct bkrp_client_side_unwrapped resp
;
993 enum dcerpc_AuthType auth_type
;
994 enum dcerpc_AuthLevel auth_level
;
996 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
998 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
999 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
1000 false, false, false, false, false, false, false);
1001 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
1002 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1003 out_blob
.length
= *r
->out
.data_out_len
;
1004 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_OK
, "Restore GUID");
1005 torture_assert_ndr_err_equal(tctx
,
1006 ndr_pull_struct_blob(&out_blob
, tctx
, &resp
,
1007 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
),
1009 "Unable to unmarshall bkrp_client_side_unwrapped");
1010 torture_assert_str_equal(tctx
, (char*)resp
.secret
.data
, secret
, "Wrong secret");
1012 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1013 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1014 NT_STATUS_ACCESS_DENIED
, "Get GUID");
1020 static bool test_RestoreGUID_badmagiconsecret(struct torture_context
*tctx
,
1021 struct dcerpc_pipe
*p
)
1023 enum ndr_err_code ndr_err
;
1024 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1026 struct bkrp_client_side_unwrapped resp
;
1027 enum dcerpc_AuthType auth_type
;
1028 enum dcerpc_AuthLevel auth_level
;
1030 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1032 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1033 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
1034 false, false, false, true, false, false, false);
1035 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
1036 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1037 out_blob
.length
= *r
->out
.data_out_len
;
1038 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
1039 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1040 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Wrong error code while providing bad magic in secret");
1042 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1043 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1044 NT_STATUS_ACCESS_DENIED
, "Get GUID");
1050 static bool test_RestoreGUID_emptyrequest(struct torture_context
*tctx
,
1051 struct dcerpc_pipe
*p
)
1053 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1055 enum dcerpc_AuthType auth_type
;
1056 enum dcerpc_AuthLevel auth_level
;
1058 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1060 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1061 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
1062 false, false, false, true, false, false, true);
1064 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
1065 r
->in
.data_in
= talloc(tctx
, uint8_t);
1066 r
->in
.data_in_len
= 0;
1068 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1069 out_blob
.length
= *r
->out
.data_out_len
;
1070 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_PARAMETER
, "Bad error code on wrong has in access check");
1072 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1073 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1074 NT_STATUS_ACCESS_DENIED
, "Get GUID");
1080 static bool test_RestoreGUID_badcertguid(struct torture_context
*tctx
,
1081 struct dcerpc_pipe
*p
)
1083 enum ndr_err_code ndr_err
;
1084 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1086 struct bkrp_client_side_unwrapped resp
;
1087 enum dcerpc_AuthType auth_type
;
1088 enum dcerpc_AuthLevel auth_level
;
1090 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1092 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1093 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
1094 false, false, false, false, false, false, true);
1095 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct() failed");
1096 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1097 out_blob
.length
= *r
->out
.data_out_len
;
1098 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
1099 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1102 * Windows 2012R2 has, presumably, a programming error
1103 * returning an NTSTATUS code on this interface
1105 if (W_ERROR_V(r
->out
.result
) != NT_STATUS_V(NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
1106 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Bad error code on wrong has in access check");
1109 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1110 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1111 NT_STATUS_ACCESS_DENIED
, "Get GUID");
1117 static bool test_RestoreGUID_badmagicaccesscheck(struct torture_context
*tctx
,
1118 struct dcerpc_pipe
*p
)
1120 enum ndr_err_code ndr_err
;
1121 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1123 struct bkrp_client_side_unwrapped resp
;
1124 enum dcerpc_AuthType auth_type
;
1125 enum dcerpc_AuthLevel auth_level
;
1127 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1129 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1130 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
1131 false, false, false, false, true, false, false);
1132 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
1133 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1134 out_blob
.length
= *r
->out
.data_out_len
;
1135 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
1136 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1137 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Bad error code on wrong has in access check");
1139 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1140 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1141 NT_STATUS_ACCESS_DENIED
, "Get GUID");
1147 static bool test_RestoreGUID_badhashaccesscheck(struct torture_context
*tctx
,
1148 struct dcerpc_pipe
*p
)
1150 enum ndr_err_code ndr_err
;
1151 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1153 struct bkrp_client_side_unwrapped resp
;
1154 enum dcerpc_AuthType auth_type
;
1155 enum dcerpc_AuthLevel auth_level
;
1157 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1159 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1160 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
1161 false, false, false, false, false, true, false);
1162 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
1163 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1164 out_blob
.length
= *r
->out
.data_out_len
;
1165 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
1166 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1167 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Bad error code on wrong has in access check");
1169 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1170 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1171 NT_STATUS_ACCESS_DENIED
, "Get GUID");
1178 * Check that the RSA modulus in the certificate of the DCs has 2048 bits.
1180 static bool test_RetrieveBackupKeyGUID_validate(struct torture_context
*tctx
,
1181 struct dcerpc_pipe
*p
)
1183 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1185 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1186 enum dcerpc_AuthType auth_type
;
1187 enum dcerpc_AuthLevel auth_level
;
1189 torture_assert(tctx
, r
!= NULL
, "test_RetrieveBackupKeyGUID_validate failed");
1195 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1197 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1198 gnutls_x509_crt_t x509_cert
= NULL
;
1199 gnutls_pubkey_t pubkey
= NULL
;
1200 gnutls_datum_t x509_crt_data
;
1201 gnutls_pk_algorithm_t pubkey_algo
;
1202 uint8_t dummy
[1] = {0};
1203 DATA_BLOB subject_unique_id
= {
1207 DATA_BLOB issuer_unique_id
= {
1211 DATA_BLOB reversed
= {
1215 DATA_BLOB serial_number
;
1216 unsigned int RSA_returned_bits
= 0;
1222 torture_assert_ntstatus_ok(tctx
,
1223 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1226 torture_assert_werr_ok(tctx
, r
->out
.result
,
1229 out_blob
.length
= *r
->out
.data_out_len
;
1231 x509_crt_data
.data
= out_blob
.data
;
1232 x509_crt_data
.size
= out_blob
.length
;
1234 rc
= gnutls_x509_crt_init(&x509_cert
);
1235 if (rc
!= GNUTLS_E_SUCCESS
) {
1239 rc
= gnutls_x509_crt_import(x509_cert
,
1241 GNUTLS_X509_FMT_DER
);
1242 torture_assert_int_equal(tctx
,
1245 "gnutls_x509_crt_import failed");
1247 /* Compare unique ids */
1249 /* Get buffer size */
1250 rc
= gnutls_x509_crt_get_subject_unique_id(x509_cert
,
1251 (char *)subject_unique_id
.data
,
1252 &subject_unique_id
.length
);
1253 torture_assert_int_equal(tctx
,
1255 GNUTLS_E_SHORT_MEMORY_BUFFER
,
1256 "gnutls_x509_crt_get_subject_unique_id "
1257 "get buffer size failed");
1259 subject_unique_id
= data_blob_talloc_zero(tctx
,
1260 subject_unique_id
.length
);
1262 rc
= gnutls_x509_crt_get_subject_unique_id(x509_cert
,
1263 (char *)subject_unique_id
.data
,
1264 &subject_unique_id
.length
);
1265 torture_assert_int_equal(tctx
,
1268 "gnutls_x509_crt_get_subject_unique_id failed");
1270 rc
= gnutls_x509_crt_get_issuer_unique_id(x509_cert
,
1271 (char *)issuer_unique_id
.data
,
1272 &issuer_unique_id
.length
);
1273 torture_assert_int_equal(tctx
,
1275 GNUTLS_E_SHORT_MEMORY_BUFFER
,
1276 "gnutls_x509_crt_get_issuer_unique_id "
1277 "get buffer size failed");
1279 issuer_unique_id
= data_blob_talloc_zero(tctx
,
1280 issuer_unique_id
.length
);
1282 rc
= gnutls_x509_crt_get_issuer_unique_id(x509_cert
,
1283 (char *)issuer_unique_id
.data
,
1284 &issuer_unique_id
.length
);
1285 torture_assert_int_equal(tctx
,
1288 "gnutls_x509_crt_get_issuer_unique_id failed");
1290 cmp
= data_blob_cmp(&subject_unique_id
, &issuer_unique_id
);
1291 torture_assert(tctx
,
1293 "The GUID to identify the public key is not "
1296 rc
= gnutls_x509_crt_get_serial(x509_cert
,
1299 torture_assert_int_equal(tctx
,
1301 GNUTLS_E_SHORT_MEMORY_BUFFER
,
1302 "gnutls_x509_crt_get_serial "
1303 "get buffer size failed");
1305 reversed
= data_blob_talloc_zero(tctx
,
1308 rc
= gnutls_x509_crt_get_serial(x509_cert
,
1311 torture_assert_int_equal(tctx
,
1314 "gnutls_x509_crt_get_serial failed");
1317 * Heimdal sometimes adds a leading byte to the data buffer of
1318 * the serial number. So lets uses the subject_unique_id size
1319 * and ignore the leading byte.
1321 serial_number
= data_blob_talloc_zero(tctx
,
1322 subject_unique_id
.length
);
1324 for (i
= 0; i
< serial_number
.length
; i
++) {
1325 serial_number
.data
[i
] = reversed
.data
[reversed
.length
- i
- 1];
1328 cmp
= data_blob_cmp(&subject_unique_id
, &serial_number
);
1329 torture_assert(tctx
,
1331 "The GUID to identify the public key is not "
1334 /* Check certificate version */
1335 version
= gnutls_x509_crt_get_version(x509_cert
);
1336 torture_assert_int_equal(tctx
,
1339 "Invalid certificate version");
1341 /* Get the public key */
1342 rc
= gnutls_pubkey_init(&pubkey
);
1343 torture_assert_int_equal(tctx
,
1346 "gnutls_pubkey_init failed");
1348 rc
= gnutls_pubkey_import_x509(pubkey
,
1351 gnutls_x509_crt_deinit(x509_cert
);
1352 torture_assert_int_equal(tctx
,
1355 "gnutls_pubkey_import_x509 failed");
1357 pubkey_algo
= gnutls_pubkey_get_pk_algorithm(pubkey
,
1358 &RSA_returned_bits
);
1359 gnutls_pubkey_deinit(pubkey
);
1360 torture_assert_int_equal(tctx
,
1363 "gnutls_pubkey_get_pk_algorithm did "
1364 "not return a RSA key");
1365 torture_assert_int_equal(tctx
,
1368 "RSA Key doesn't have 2048 bits");
1370 torture_assert_ntstatus_equal(tctx
,
1371 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1372 NT_STATUS_ACCESS_DENIED
,
1379 static bool test_ServerWrap_encrypt_decrypt(struct torture_context
*tctx
,
1380 struct dcerpc_pipe
*p
)
1382 struct bkrp_BackupKey r
;
1384 DATA_BLOB plaintext
= data_blob_const(secret
, sizeof(secret
));
1385 DATA_BLOB encrypted
;
1387 DATA_BLOB decrypted
;
1389 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1390 enum dcerpc_AuthType auth_type
;
1391 enum dcerpc_AuthLevel auth_level
;
1394 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1397 torture_assert_ntstatus_ok(tctx
,
1398 GUID_from_string(BACKUPKEY_BACKUP_GUID
, &guid
),
1401 r
.in
.guidActionAgent
= &guid
;
1402 r
.in
.data_in
= plaintext
.data
;
1403 r
.in
.data_in_len
= plaintext
.length
;
1405 r
.out
.data_out
= &encrypted
.data
;
1406 r
.out
.data_out_len
= &enclen
;
1407 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1408 torture_assert_ntstatus_ok(tctx
,
1409 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1412 torture_assert_ntstatus_equal(tctx
,
1413 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1414 NT_STATUS_ACCESS_DENIED
,
1418 torture_assert_werr_ok(tctx
,
1421 encrypted
.length
= *r
.out
.data_out_len
;
1424 torture_assert_ntstatus_ok(tctx
,
1425 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1428 r
.in
.guidActionAgent
= &guid
;
1429 r
.in
.data_in
= encrypted
.data
;
1430 r
.in
.data_in_len
= encrypted
.length
;
1432 r
.out
.data_out
= &(decrypted
.data
);
1433 r
.out
.data_out_len
= &declen
;
1434 torture_assert_ntstatus_ok(tctx
,
1435 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1437 torture_assert_werr_ok(tctx
,
1440 decrypted
.length
= *r
.out
.data_out_len
;
1443 torture_assert_data_blob_equal(tctx
, plaintext
, decrypted
, "Decrypt failed");
1446 torture_assert_ntstatus_ok(tctx
,
1447 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1450 r
.in
.guidActionAgent
= &guid
;
1451 r
.in
.data_in
= encrypted
.data
;
1452 r
.in
.data_in_len
= encrypted
.length
;
1454 r
.out
.data_out
= &(decrypted
.data
);
1455 r
.out
.data_out_len
= &declen
;
1456 torture_assert_ntstatus_ok(tctx
,
1457 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1459 torture_assert_werr_ok(tctx
,
1462 decrypted
.length
= *r
.out
.data_out_len
;
1465 torture_assert_data_blob_equal(tctx
, plaintext
, decrypted
, "Decrypt failed");
1469 static bool test_ServerWrap_decrypt_wrong_keyGUID(struct torture_context
*tctx
,
1470 struct dcerpc_pipe
*p
)
1472 struct bkrp_BackupKey r
;
1474 DATA_BLOB plaintext
= data_blob_const(secret
, sizeof(secret
));
1475 DATA_BLOB encrypted
;
1477 DATA_BLOB decrypted
;
1479 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1480 enum ndr_err_code ndr_err
;
1481 struct bkrp_server_side_wrapped server_side_wrapped
;
1482 enum dcerpc_AuthType auth_type
;
1483 enum dcerpc_AuthLevel auth_level
;
1486 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1489 torture_assert_ntstatus_ok(tctx
,
1490 GUID_from_string(BACKUPKEY_BACKUP_GUID
, &guid
),
1493 r
.in
.guidActionAgent
= &guid
;
1494 r
.in
.data_in
= plaintext
.data
;
1495 r
.in
.data_in_len
= plaintext
.length
;
1497 r
.out
.data_out
= &encrypted
.data
;
1498 r
.out
.data_out_len
= &enclen
;
1499 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1500 torture_assert_ntstatus_ok(tctx
,
1501 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1504 torture_assert_ntstatus_equal(tctx
,
1505 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1506 NT_STATUS_ACCESS_DENIED
,
1510 torture_assert_werr_ok(tctx
,
1513 encrypted
.length
= *r
.out
.data_out_len
;
1515 ndr_err
= ndr_pull_struct_blob(&encrypted
, tctx
, &server_side_wrapped
,
1516 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_server_side_wrapped
);
1517 torture_assert_ndr_err_equal(tctx
, ndr_err
, NDR_ERR_SUCCESS
, "pull of server_side_wrapped");
1519 /* Change the GUID */
1520 server_side_wrapped
.guid
= GUID_random();
1522 ndr_err
= ndr_push_struct_blob(&encrypted
, tctx
, &server_side_wrapped
,
1523 (ndr_push_flags_fn_t
)ndr_push_bkrp_server_side_wrapped
);
1524 torture_assert_ndr_err_equal(tctx
, ndr_err
, NDR_ERR_SUCCESS
, "push of server_side_wrapped");
1527 torture_assert_ntstatus_ok(tctx
,
1528 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1531 r
.in
.guidActionAgent
= &guid
;
1532 r
.in
.data_in
= encrypted
.data
;
1533 r
.in
.data_in_len
= encrypted
.length
;
1535 r
.out
.data_out
= &(decrypted
.data
);
1536 r
.out
.data_out_len
= &declen
;
1537 torture_assert_ntstatus_ok(tctx
,
1538 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1540 torture_assert_werr_equal(tctx
,
1543 "decrypt should fail with WERR_INVALID_DATA");
1546 torture_assert_ntstatus_ok(tctx
,
1547 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1550 r
.in
.guidActionAgent
= &guid
;
1551 r
.in
.data_in
= encrypted
.data
;
1552 r
.in
.data_in_len
= encrypted
.length
;
1554 r
.out
.data_out
= &(decrypted
.data
);
1555 r
.out
.data_out_len
= &declen
;
1556 torture_assert_ntstatus_ok(tctx
,
1557 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1559 torture_assert_werr_equal(tctx
,
1562 "decrypt should fail with WERR_INVALID_DATA");
1567 static bool test_ServerWrap_decrypt_empty_request(struct torture_context
*tctx
,
1568 struct dcerpc_pipe
*p
)
1570 struct bkrp_BackupKey r
;
1572 DATA_BLOB decrypted
;
1574 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1575 uint8_t short_request
[4] = { 1, 0, 0, 0 };
1576 enum dcerpc_AuthType auth_type
;
1577 enum dcerpc_AuthLevel auth_level
;
1580 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1583 torture_assert_ntstatus_ok(tctx
,
1584 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1587 r
.in
.guidActionAgent
= &guid
;
1588 r
.in
.data_in
= short_request
;
1589 r
.in
.data_in_len
= 0;
1591 r
.out
.data_out
= &(decrypted
.data
);
1592 r
.out
.data_out_len
= &declen
;
1593 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1594 torture_assert_ntstatus_ok(tctx
,
1595 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1598 torture_assert_ntstatus_equal(tctx
,
1599 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1600 NT_STATUS_ACCESS_DENIED
,
1604 torture_assert_werr_equal(tctx
,
1606 WERR_INVALID_PARAMETER
,
1607 "decrypt should fail with WERR_INVALID_PARAMETER");
1610 torture_assert_ntstatus_ok(tctx
,
1611 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1614 r
.in
.guidActionAgent
= &guid
;
1615 r
.in
.data_in
= short_request
;
1616 r
.in
.data_in_len
= 0;
1618 r
.out
.data_out
= &(decrypted
.data
);
1619 r
.out
.data_out_len
= &declen
;
1620 torture_assert_ntstatus_ok(tctx
,
1621 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1623 torture_assert_werr_equal(tctx
,
1625 WERR_INVALID_PARAMETER
,
1626 "decrypt should fail with WERR_INVALID_PARAMETER");
1629 torture_assert_ntstatus_ok(tctx
,
1630 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1633 r
.in
.guidActionAgent
= &guid
;
1634 r
.in
.data_in
= NULL
;
1635 r
.in
.data_in_len
= 0;
1637 r
.out
.data_out
= &(decrypted
.data
);
1638 r
.out
.data_out_len
= &declen
;
1639 torture_assert_ntstatus_equal(tctx
,
1640 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1641 NT_STATUS_INVALID_PARAMETER_MIX
,
1645 torture_assert_ntstatus_ok(tctx
,
1646 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1649 r
.in
.guidActionAgent
= &guid
;
1650 r
.in
.data_in
= NULL
;
1651 r
.in
.data_in_len
= 0;
1653 r
.out
.data_out
= &(decrypted
.data
);
1654 r
.out
.data_out_len
= &declen
;
1655 torture_assert_ntstatus_equal(tctx
,
1656 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1657 NT_STATUS_INVALID_PARAMETER_MIX
,
1664 static bool test_ServerWrap_decrypt_short_request(struct torture_context
*tctx
,
1665 struct dcerpc_pipe
*p
)
1667 struct bkrp_BackupKey r
;
1669 DATA_BLOB decrypted
;
1671 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1672 uint8_t short_request
[4] = { 1, 0, 0, 0 };
1673 enum dcerpc_AuthType auth_type
;
1674 enum dcerpc_AuthLevel auth_level
;
1677 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1680 torture_assert_ntstatus_ok(tctx
,
1681 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1684 r
.in
.guidActionAgent
= &guid
;
1685 r
.in
.data_in
= short_request
;
1686 r
.in
.data_in_len
= 4;
1688 r
.out
.data_out
= &(decrypted
.data
);
1689 r
.out
.data_out_len
= &declen
;
1690 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1691 torture_assert_ntstatus_ok(tctx
,
1692 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1695 torture_assert_ntstatus_equal(tctx
,
1696 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1697 NT_STATUS_ACCESS_DENIED
,
1701 torture_assert_werr_equal(tctx
,
1703 WERR_INVALID_PARAMETER
,
1704 "decrypt should fail with WERR_INVALID_PARM");
1707 torture_assert_ntstatus_ok(tctx
,
1708 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1711 r
.in
.guidActionAgent
= &guid
;
1712 r
.in
.data_in
= short_request
;
1713 r
.in
.data_in_len
= 4;
1715 r
.out
.data_out
= &(decrypted
.data
);
1716 r
.out
.data_out_len
= &declen
;
1717 torture_assert_ntstatus_ok(tctx
,
1718 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1720 torture_assert_werr_equal(tctx
,
1722 WERR_INVALID_PARAMETER
,
1723 "decrypt should fail with WERR_INVALID_PARAMETER");
1726 torture_assert_ntstatus_ok(tctx
,
1727 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1730 r
.in
.guidActionAgent
= &guid
;
1731 r
.in
.data_in
= short_request
;
1732 r
.in
.data_in_len
= 1;
1734 r
.out
.data_out
= &(decrypted
.data
);
1735 r
.out
.data_out_len
= &declen
;
1736 torture_assert_ntstatus_ok(tctx
,
1737 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1739 torture_assert_werr_equal(tctx
,
1741 WERR_INVALID_PARAMETER
,
1742 "decrypt should fail with WERR_INVALID_PARAMETER");
1745 torture_assert_ntstatus_ok(tctx
,
1746 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1749 r
.in
.guidActionAgent
= &guid
;
1750 r
.in
.data_in
= short_request
;
1751 r
.in
.data_in_len
= 1;
1753 r
.out
.data_out
= &(decrypted
.data
);
1754 r
.out
.data_out_len
= &declen
;
1755 torture_assert_ntstatus_ok(tctx
,
1756 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1758 torture_assert_werr_equal(tctx
,
1760 WERR_INVALID_PARAMETER
,
1761 "decrypt should fail with WERR_INVALID_PARAMETER");
1766 static bool test_ServerWrap_encrypt_decrypt_manual(struct torture_context
*tctx
,
1767 struct bkrp_server_side_wrapped
*server_side_wrapped
,
1768 enum test_wrong wrong
)
1770 char *lsa_binding_string
= NULL
;
1771 struct dcerpc_binding
*lsa_binding
= NULL
;
1772 struct dcerpc_pipe
*lsa_p
= NULL
;
1773 struct dcerpc_binding_handle
*lsa_b
= NULL
;
1774 struct lsa_OpenSecret r_secret
;
1775 struct lsa_QuerySecret r_query_secret
;
1776 struct policy_handle
*handle
, sec_handle
;
1777 struct bkrp_BackupKey r
;
1778 struct GUID preferred_key_guid
;
1779 DATA_BLOB plaintext
= data_blob_const(secret
, sizeof(secret
));
1780 DATA_BLOB preferred_key
, preferred_key_clear
, session_key
,
1781 decrypt_key
, decrypt_key_clear
, encrypted_blob
,
1783 struct bkrp_dc_serverwrap_key server_key
;
1784 struct lsa_DATA_BUF_PTR bufp1
;
1785 char *key_guid_string
;
1786 struct bkrp_rc4encryptedpayload rc4payload
;
1787 struct dom_sid
*caller_sid
;
1788 uint8_t symkey
[20]; /* SHA-1 hash len */
1789 uint8_t mackey
[20]; /* SHA-1 hash len */
1790 uint8_t mac
[20]; /* SHA-1 hash len */
1791 gnutls_hmac_hd_t hmac_hnd
;
1792 gnutls_cipher_hd_t cipher_hnd
;
1793 gnutls_datum_t cipher_key
;
1797 ZERO_STRUCT(r_secret
);
1798 ZERO_STRUCT(r_query_secret
);
1800 /* Now read BCKUPKEY_P and prove we can do a matching decrypt and encrypt */
1802 /* lsa_OpenSecret only works with ncacn_np and AUTH_LEVEL_NONE */
1803 lsa_binding_string
= talloc_asprintf(tctx
, "ncacn_np:%s",
1804 torture_setting_string(tctx
, "host", NULL
));
1805 torture_assert(tctx
, lsa_binding_string
!= NULL
, "lsa_binding_string");
1807 torture_assert_ntstatus_ok(tctx
,
1808 dcerpc_parse_binding(tctx
, lsa_binding_string
, &lsa_binding
),
1809 "Failed to parse dcerpc binding");
1811 torture_assert_ntstatus_ok(tctx
,
1812 dcerpc_pipe_connect_b(tctx
, &lsa_p
,
1813 lsa_binding
, &ndr_table_lsarpc
,
1814 samba_cmdline_get_creds(),
1815 tctx
->ev
, tctx
->lp_ctx
),
1816 "Opening LSA pipe");
1817 lsa_b
= lsa_p
->binding_handle
;
1819 torture_assert(tctx
, test_lsa_OpenPolicy2(lsa_b
, tctx
, &handle
), "OpenPolicy failed");
1820 r_secret
.in
.name
.string
= "G$BCKUPKEY_P";
1822 r_secret
.in
.handle
= handle
;
1823 r_secret
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1824 r_secret
.out
.sec_handle
= &sec_handle
;
1826 torture_comment(tctx
, "Testing OpenSecret\n");
1828 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenSecret_r(lsa_b
, tctx
, &r_secret
),
1829 "OpenSecret failed");
1830 torture_assert_ntstatus_ok(tctx
, r_secret
.out
.result
,
1831 "OpenSecret failed");
1833 r_query_secret
.in
.sec_handle
= &sec_handle
;
1834 r_query_secret
.in
.new_val
= &bufp1
;
1837 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QuerySecret_r(lsa_b
, tctx
, &r_query_secret
),
1838 "QuerySecret failed");
1839 torture_assert_ntstatus_ok(tctx
, r_query_secret
.out
.result
,
1840 "QuerySecret failed");
1843 preferred_key
.data
= r_query_secret
.out
.new_val
->buf
->data
;
1844 preferred_key
.length
= r_query_secret
.out
.new_val
->buf
->size
;
1845 torture_assert_ntstatus_ok(tctx
, dcerpc_fetch_session_key(lsa_p
, &session_key
),
1846 "dcerpc_fetch_session_key failed");
1848 torture_assert_ntstatus_ok(tctx
,
1849 sess_decrypt_blob(tctx
,
1850 &preferred_key
, &session_key
, &preferred_key_clear
),
1851 "sess_decrypt_blob failed");
1853 torture_assert_ntstatus_ok(tctx
, GUID_from_ndr_blob(&preferred_key_clear
, &preferred_key_guid
),
1854 "GUID parse failed");
1856 torture_assert_guid_equal(tctx
, server_side_wrapped
->guid
,
1858 "GUID didn't match value pointed at by G$BCKUPKEY_P");
1860 /* And read BCKUPKEY_<guid> and get the actual key */
1862 key_guid_string
= GUID_string(tctx
, &server_side_wrapped
->guid
);
1863 r_secret
.in
.name
.string
= talloc_asprintf(tctx
, "G$BCKUPKEY_%s", key_guid_string
);
1865 r_secret
.in
.handle
= handle
;
1866 r_secret
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1867 r_secret
.out
.sec_handle
= &sec_handle
;
1869 torture_comment(tctx
, "Testing OpenSecret\n");
1871 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenSecret_r(lsa_b
, tctx
, &r_secret
),
1872 "OpenSecret failed");
1873 torture_assert_ntstatus_ok(tctx
, r_secret
.out
.result
,
1874 "OpenSecret failed");
1876 r_query_secret
.in
.sec_handle
= &sec_handle
;
1877 r_query_secret
.in
.new_val
= &bufp1
;
1879 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QuerySecret_r(lsa_b
, tctx
, &r_query_secret
),
1880 "QuerySecret failed");
1881 torture_assert_ntstatus_ok(tctx
, r_query_secret
.out
.result
,
1882 "QuerySecret failed");
1885 decrypt_key
.data
= r_query_secret
.out
.new_val
->buf
->data
;
1886 decrypt_key
.length
= r_query_secret
.out
.new_val
->buf
->size
;
1888 torture_assert_ntstatus_ok(tctx
,
1889 sess_decrypt_blob(tctx
,
1890 &decrypt_key
, &session_key
, &decrypt_key_clear
),
1891 "sess_decrypt_blob failed");
1893 torture_assert_ndr_err_equal(tctx
, ndr_pull_struct_blob(&decrypt_key_clear
, tctx
, &server_key
,
1894 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_dc_serverwrap_key
),
1895 NDR_ERR_SUCCESS
, "Failed to parse server_key");
1897 torture_assert_int_equal(tctx
, server_key
.magic
, 1, "Failed to correctly decrypt server key");
1900 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1901 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1903 gnutls_hmac_init(&hmac_hnd
,
1906 sizeof(server_key
.key
));
1907 gnutls_hmac(hmac_hnd
,
1908 server_side_wrapped
->r2
,
1909 sizeof(server_side_wrapped
->r2
));
1910 gnutls_hmac_output(hmac_hnd
, symkey
);
1912 /* rc4 decrypt sid and secret using sym key */
1913 cipher_key
.data
= symkey
;
1914 cipher_key
.size
= sizeof(symkey
);
1916 encrypted_blob
= data_blob_talloc(tctx
, server_side_wrapped
->rc4encryptedpayload
,
1917 server_side_wrapped
->ciphertext_length
);
1919 rc
= gnutls_cipher_init(&cipher_hnd
,
1920 GNUTLS_CIPHER_ARCFOUR_128
,
1923 torture_assert_int_equal(tctx
,
1926 "gnutls_cipher_init failed");
1927 rc
= gnutls_cipher_encrypt2(cipher_hnd
,
1928 encrypted_blob
.data
,
1929 encrypted_blob
.length
,
1930 encrypted_blob
.data
,
1931 encrypted_blob
.length
);
1932 torture_assert_int_equal(tctx
,
1935 "gnutls_cipher_encrypt failed");
1936 gnutls_cipher_deinit(cipher_hnd
);
1938 torture_assert_ndr_err_equal(tctx
, ndr_pull_struct_blob(&encrypted_blob
, tctx
, &rc4payload
,
1939 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_rc4encryptedpayload
),
1940 NDR_ERR_SUCCESS
, "Failed to parse rc4encryptedpayload");
1942 torture_assert_int_equal(tctx
, rc4payload
.secret_data
.length
,
1943 server_side_wrapped
->payload_length
,
1944 "length of decrypted payload not the length declared in surrounding structure");
1947 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1948 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1950 gnutls_hmac(hmac_hnd
,
1952 sizeof(rc4payload
.r3
));
1953 gnutls_hmac_deinit(hmac_hnd
, mackey
);
1955 torture_assert_ndr_err_equal(tctx
, ndr_push_struct_blob(&sid_blob
, tctx
, &rc4payload
.sid
,
1956 (ndr_push_flags_fn_t
)ndr_push_dom_sid
),
1957 NDR_ERR_SUCCESS
, "unable to push SID");
1959 gnutls_hmac_init(&hmac_hnd
,
1964 gnutls_hmac(hmac_hnd
,
1968 gnutls_hmac(hmac_hnd
,
1969 rc4payload
.secret_data
.data
,
1970 rc4payload
.secret_data
.length
);
1971 gnutls_hmac_output(hmac_hnd
, mac
);
1973 torture_assert_mem_equal(tctx
, mac
, rc4payload
.mac
, sizeof(mac
), "mac not correct");
1974 torture_assert_int_equal(tctx
, rc4payload
.secret_data
.length
,
1975 plaintext
.length
, "decrypted data is not correct length");
1976 torture_assert_mem_equal(tctx
, rc4payload
.secret_data
.data
,
1977 plaintext
.data
, plaintext
.length
,
1978 "decrypted data is not correct");
1980 /* Not strictly correct all the time, but good enough for this test */
1981 caller_sid
= get_user_sid(tctx
, tctx
,
1982 cli_credentials_get_username(
1983 samba_cmdline_get_creds()));
1985 torture_assert_sid_equal(tctx
, &rc4payload
.sid
, caller_sid
, "Secret saved with wrong SID");
1990 if (wrong
== WRONG_SID
) {
1991 rc4payload
.sid
.sub_auths
[rc4payload
.sid
.num_auths
- 1] = DOMAIN_RID_KRBTGT
;
1994 dump_data_pw("mackey: \n", mackey
, sizeof(mackey
));
1996 torture_assert_ndr_err_equal(tctx
,
1997 ndr_push_struct_blob(&sid_blob
, tctx
, &rc4payload
.sid
,
1998 (ndr_push_flags_fn_t
)ndr_push_dom_sid
),
2000 "push of sid failed");
2003 gnutls_hmac(hmac_hnd
,
2007 gnutls_hmac(hmac_hnd
,
2008 rc4payload
.secret_data
.data
,
2009 rc4payload
.secret_data
.length
);
2010 gnutls_hmac_deinit(hmac_hnd
, rc4payload
.mac
);
2012 dump_data_pw("rc4payload.mac: \n", rc4payload
.mac
, sizeof(rc4payload
.mac
));
2014 torture_assert_ndr_err_equal(tctx
,
2015 ndr_push_struct_blob(&encrypted_blob
, tctx
, &rc4payload
,
2016 (ndr_push_flags_fn_t
)ndr_push_bkrp_rc4encryptedpayload
),
2018 "push of rc4payload failed");
2020 if (wrong
== WRONG_KEY
) {
2026 /* rc4 encrypt sid and secret using sym key */
2027 cipher_key
.data
= symkey
;
2028 cipher_key
.size
= sizeof(symkey
);
2030 rc
= gnutls_cipher_init(&cipher_hnd
,
2031 GNUTLS_CIPHER_ARCFOUR_128
,
2034 torture_assert_int_equal(tctx
,
2037 "gnutls_cipher_init failed");
2038 rc
= gnutls_cipher_encrypt2(cipher_hnd
,
2039 encrypted_blob
.data
,
2040 encrypted_blob
.length
,
2041 encrypted_blob
.data
,
2042 encrypted_blob
.length
);
2043 torture_assert_int_equal(tctx
,
2046 "gnutls_cipher_encrypt failed");
2047 gnutls_cipher_deinit(cipher_hnd
);
2050 /* re-create server wrap structure */
2052 torture_assert_int_equal(tctx
, encrypted_blob
.length
,
2053 server_side_wrapped
->ciphertext_length
,
2054 "expected encrypted length not to change");
2055 if (wrong
== RIGHT_KEY
) {
2056 torture_assert_mem_equal(tctx
, server_side_wrapped
->rc4encryptedpayload
,
2057 encrypted_blob
.data
,
2058 encrypted_blob
.length
,
2059 "expected encrypted data not to change");
2062 server_side_wrapped
->payload_length
= rc4payload
.secret_data
.length
;
2063 server_side_wrapped
->ciphertext_length
= encrypted_blob
.length
;
2064 server_side_wrapped
->rc4encryptedpayload
= encrypted_blob
.data
;
2070 static bool test_ServerWrap_decrypt_wrong_stuff(struct torture_context
*tctx
,
2071 struct dcerpc_pipe
*p
,
2072 enum test_wrong wrong
)
2074 struct bkrp_BackupKey r
;
2076 DATA_BLOB plaintext
= data_blob_const(secret
, sizeof(secret
));
2077 DATA_BLOB encrypted
;
2079 DATA_BLOB decrypted
;
2081 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2082 enum ndr_err_code ndr_err
;
2083 struct bkrp_server_side_wrapped server_side_wrapped
;
2084 bool repush
= false;
2085 enum dcerpc_AuthType auth_type
;
2086 enum dcerpc_AuthLevel auth_level
;
2089 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
2092 torture_assert_ntstatus_ok(tctx
,
2093 GUID_from_string(BACKUPKEY_BACKUP_GUID
, &guid
),
2096 r
.in
.guidActionAgent
= &guid
;
2097 r
.in
.data_in
= plaintext
.data
;
2098 r
.in
.data_in_len
= plaintext
.length
;
2100 r
.out
.data_out
= &encrypted
.data
;
2101 r
.out
.data_out_len
= &enclen
;
2102 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
2103 torture_assert_ntstatus_ok(tctx
,
2104 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
2107 torture_assert_ntstatus_equal(tctx
,
2108 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
2109 NT_STATUS_ACCESS_DENIED
,
2113 torture_assert_werr_ok(tctx
,
2116 encrypted
.length
= *r
.out
.data_out_len
;
2118 ndr_err
= ndr_pull_struct_blob(&encrypted
, tctx
, &server_side_wrapped
,
2119 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_server_side_wrapped
);
2120 torture_assert_ndr_err_equal(tctx
, ndr_err
, NDR_ERR_SUCCESS
, "pull of server_side_wrapped");
2122 torture_assert_int_equal(tctx
, server_side_wrapped
.payload_length
, plaintext
.length
,
2123 "wrong payload length");
2127 /* Change the magic. Forced by our NDR layer, so do it raw */
2128 SIVAL(encrypted
.data
, 0, 78); /* valid values are 1-3 */
2131 server_side_wrapped
.r2
[0] = 78;
2132 server_side_wrapped
.r2
[1] = 78;
2133 server_side_wrapped
.r2
[2] = 78;
2136 case WRONG_PAYLOAD_LENGTH
:
2137 server_side_wrapped
.payload_length
= UINT32_MAX
- 8;
2140 case WRONG_CIPHERTEXT_LENGTH
:
2142 * Change the ciphertext len. We can't push this if
2143 * we have it wrong, so do it raw
2145 SIVAL(encrypted
.data
, 8, UINT32_MAX
- 8); /* valid values are 1-3 */
2147 case SHORT_PAYLOAD_LENGTH
:
2148 server_side_wrapped
.payload_length
= server_side_wrapped
.payload_length
- 8;
2151 case SHORT_CIPHERTEXT_LENGTH
:
2153 * Change the ciphertext len. We can't push this if
2154 * we have it wrong, so do it raw
2156 SIVAL(encrypted
.data
, 8, server_side_wrapped
.ciphertext_length
- 8); /* valid values are 1-3 */
2158 case ZERO_PAYLOAD_LENGTH
:
2159 server_side_wrapped
.payload_length
= 0;
2162 case ZERO_CIPHERTEXT_LENGTH
:
2164 * Change the ciphertext len. We can't push this if
2165 * we have it wrong, so do it raw
2167 SIVAL(encrypted
.data
, 8, 0); /* valid values are 1-3 */
2173 torture_assert(tctx
,
2174 test_ServerWrap_encrypt_decrypt_manual(tctx
, &server_side_wrapped
, wrong
),
2175 "test_ServerWrap_encrypt_decrypt_manual failed");
2181 ndr_err
= ndr_push_struct_blob(&encrypted
, tctx
, &server_side_wrapped
,
2182 (ndr_push_flags_fn_t
)ndr_push_bkrp_server_side_wrapped
);
2183 torture_assert_ndr_err_equal(tctx
, ndr_err
, NDR_ERR_SUCCESS
, "push of server_side_wrapped");
2187 torture_assert_ntstatus_ok(tctx
,
2188 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
2191 r
.in
.guidActionAgent
= &guid
;
2192 r
.in
.data_in
= encrypted
.data
;
2193 r
.in
.data_in_len
= encrypted
.length
;
2195 r
.out
.data_out
= &(decrypted
.data
);
2196 r
.out
.data_out_len
= &declen
;
2197 torture_assert_ntstatus_ok(tctx
,
2198 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
2201 if ((wrong
== WRONG_R2
|| wrong
== WRONG_KEY
)
2202 && W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_SID
)) {
2203 torture_assert_werr_equal(tctx
,
2206 "decrypt should fail with WERR_INVALID_SID or WERR_INVALID_PARAMETER");
2207 } else if (wrong
== RIGHT_KEY
) {
2208 torture_assert_werr_equal(tctx
,
2211 "decrypt should succeed!");
2212 } else if (wrong
== WRONG_SID
) {
2213 torture_assert_werr_equal(tctx
,
2215 WERR_INVALID_ACCESS
,
2216 "decrypt should fail with WERR_INVALID_ACCESS");
2218 if (!W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_ACCESS
)
2219 && !W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_PARAMETER
)) {
2220 torture_assert_werr_equal(tctx
, r
.out
.result
,
2222 "decrypt should fail with WERR_INVALID_ACCESS, WERR_INVALID_PARAMETER or WERR_INVALID_DATA");
2227 torture_assert_ntstatus_ok(tctx
,
2228 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
2231 r
.in
.guidActionAgent
= &guid
;
2232 r
.in
.data_in
= encrypted
.data
;
2233 r
.in
.data_in_len
= encrypted
.length
;
2235 r
.out
.data_out
= &(decrypted
.data
);
2236 r
.out
.data_out_len
= &declen
;
2237 torture_assert_ntstatus_ok(tctx
,
2238 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
2241 if ((wrong
== WRONG_R2
|| wrong
== WRONG_KEY
)
2242 && W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_SID
)) {
2243 torture_assert_werr_equal(tctx
,
2246 "decrypt should fail with WERR_INVALID_SID or WERR_INVALID_PARAMETER");
2247 } else if (wrong
== RIGHT_KEY
) {
2248 torture_assert_werr_equal(tctx
,
2251 "decrypt should succeed!");
2252 } else if (wrong
== WRONG_SID
) {
2253 torture_assert_werr_equal(tctx
,
2255 WERR_INVALID_ACCESS
,
2256 "decrypt should fail with WERR_INVALID_ACCESS");
2258 if (!W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_ACCESS
)
2259 && !W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_PARAMETER
)) {
2260 torture_assert_werr_equal(tctx
, r
.out
.result
,
2262 "decrypt should fail with WERR_INVALID_ACCESS, WERR_INVALID_PARAMETER or WERR_INVALID_DATA");
2269 static bool test_ServerWrap_decrypt_wrong_magic(struct torture_context
*tctx
,
2270 struct dcerpc_pipe
*p
)
2272 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_MAGIC
);
2275 static bool test_ServerWrap_decrypt_wrong_r2(struct torture_context
*tctx
,
2276 struct dcerpc_pipe
*p
)
2278 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_R2
);
2281 static bool test_ServerWrap_decrypt_wrong_payload_length(struct torture_context
*tctx
,
2282 struct dcerpc_pipe
*p
)
2284 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_PAYLOAD_LENGTH
);
2287 static bool test_ServerWrap_decrypt_short_payload_length(struct torture_context
*tctx
,
2288 struct dcerpc_pipe
*p
)
2290 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, SHORT_PAYLOAD_LENGTH
);
2293 static bool test_ServerWrap_decrypt_zero_payload_length(struct torture_context
*tctx
,
2294 struct dcerpc_pipe
*p
)
2296 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, ZERO_PAYLOAD_LENGTH
);
2299 static bool test_ServerWrap_decrypt_wrong_ciphertext_length(struct torture_context
*tctx
,
2300 struct dcerpc_pipe
*p
)
2302 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_CIPHERTEXT_LENGTH
);
2305 static bool test_ServerWrap_decrypt_short_ciphertext_length(struct torture_context
*tctx
,
2306 struct dcerpc_pipe
*p
)
2308 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, SHORT_CIPHERTEXT_LENGTH
);
2311 static bool test_ServerWrap_decrypt_zero_ciphertext_length(struct torture_context
*tctx
,
2312 struct dcerpc_pipe
*p
)
2314 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, ZERO_CIPHERTEXT_LENGTH
);
2317 static bool test_ServerWrap_encrypt_decrypt_remote_key(struct torture_context
*tctx
,
2318 struct dcerpc_pipe
*p
)
2320 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, RIGHT_KEY
);
2323 static bool test_ServerWrap_encrypt_decrypt_wrong_key(struct torture_context
*tctx
,
2324 struct dcerpc_pipe
*p
)
2326 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_KEY
);
2329 static bool test_ServerWrap_encrypt_decrypt_wrong_sid(struct torture_context
*tctx
,
2330 struct dcerpc_pipe
*p
)
2332 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_SID
);
2335 struct torture_suite
*torture_rpc_backupkey(TALLOC_CTX
*mem_ctx
)
2337 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "backupkey");
2339 struct torture_rpc_tcase
*tcase
;
2341 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "backupkey",
2342 &ndr_table_backupkey
);
2344 torture_rpc_tcase_add_test(tcase
, "retreive_backup_key_guid",
2345 test_RetrieveBackupKeyGUID
);
2347 torture_rpc_tcase_add_test(tcase
, "restore_guid",
2350 torture_rpc_tcase_add_test(tcase
, "restore_guid version 3",
2351 test_RestoreGUID_v3
);
2353 /* We double the test in order to be sure that we don't mess stuff (ie. freeing static stuff) */
2355 torture_rpc_tcase_add_test(tcase
, "restore_guid_2nd",
2358 torture_rpc_tcase_add_test(tcase
, "unable_to_decrypt_secret",
2359 test_RestoreGUID_ko
);
2361 torture_rpc_tcase_add_test(tcase
, "wrong_user_restore_guid",
2362 test_RestoreGUID_wronguser
);
2364 torture_rpc_tcase_add_test(tcase
, "wrong_version_restore_guid",
2365 test_RestoreGUID_wrongversion
);
2367 torture_rpc_tcase_add_test(tcase
, "bad_magic_on_secret_restore_guid",
2368 test_RestoreGUID_badmagiconsecret
);
2370 torture_rpc_tcase_add_test(tcase
, "bad_hash_on_secret_restore_guid",
2371 test_RestoreGUID_badhashaccesscheck
);
2373 torture_rpc_tcase_add_test(tcase
, "bad_magic_on_accesscheck_restore_guid",
2374 test_RestoreGUID_badmagicaccesscheck
);
2376 torture_rpc_tcase_add_test(tcase
, "bad_cert_guid_restore_guid",
2377 test_RestoreGUID_badcertguid
);
2379 torture_rpc_tcase_add_test(tcase
, "empty_request_restore_guid",
2380 test_RestoreGUID_emptyrequest
);
2382 torture_rpc_tcase_add_test(tcase
, "retreive_backup_key_guid_validate",
2383 test_RetrieveBackupKeyGUID_validate
);
2385 torture_rpc_tcase_add_test(tcase
, "server_wrap_encrypt_decrypt",
2386 test_ServerWrap_encrypt_decrypt
);
2388 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_wrong_keyGUID",
2389 test_ServerWrap_decrypt_wrong_keyGUID
);
2391 torture_rpc_tcase_add_test(tcase
, "server_wrap_empty_request",
2392 test_ServerWrap_decrypt_empty_request
);
2394 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_short_request",
2395 test_ServerWrap_decrypt_short_request
);
2397 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_wrong_magic",
2398 test_ServerWrap_decrypt_wrong_magic
);
2400 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_wrong_r2",
2401 test_ServerWrap_decrypt_wrong_r2
);
2403 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_wrong_payload_length",
2404 test_ServerWrap_decrypt_wrong_payload_length
);
2406 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_short_payload_length",
2407 test_ServerWrap_decrypt_short_payload_length
);
2409 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_zero_payload_length",
2410 test_ServerWrap_decrypt_zero_payload_length
);
2412 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_wrong_ciphertext_length",
2413 test_ServerWrap_decrypt_wrong_ciphertext_length
);
2415 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_short_ciphertext_length",
2416 test_ServerWrap_decrypt_short_ciphertext_length
);
2418 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_zero_ciphertext_length",
2419 test_ServerWrap_decrypt_zero_ciphertext_length
);
2421 torture_rpc_tcase_add_test(tcase
, "server_wrap_encrypt_decrypt_remote_key",
2422 test_ServerWrap_encrypt_decrypt_remote_key
);
2424 torture_rpc_tcase_add_test(tcase
, "server_wrap_encrypt_decrypt_wrong_key",
2425 test_ServerWrap_encrypt_decrypt_wrong_key
);
2427 torture_rpc_tcase_add_test(tcase
, "server_wrap_encrypt_decrypt_wrong_sid",
2428 test_ServerWrap_encrypt_decrypt_wrong_sid
);