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 const struct dcerpc_binding
*bd
=
609 dcerpc_binding_handle_get_binding(p
->binding_handle
);
610 struct dcerpc_binding
*binding
;
611 struct bkrp_client_side_wrapped data
;
612 struct GUID
*g
= talloc(tctx
, struct GUID
);
613 struct bkrp_BackupKey
*r
= talloc_zero(tctx
, struct bkrp_BackupKey
);
614 enum ndr_err_code ndr_err
;
622 binding
= dcerpc_binding_dup(tctx
, bd
);
623 if (binding
== NULL
) {
627 status
= dcerpc_binding_set_flags(binding
, DCERPC_SEAL
|DCERPC_AUTH_SPNEGO
, 0);
628 if (!NT_STATUS_IS_OK(status
)) {
633 status
= GUID_from_string(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID
, g
);
634 if (!NT_STATUS_IS_OK(status
)) {
638 r
->in
.guidActionAgent
= g
;
639 data
.version
= version
;
640 ndr_err
= ndr_push_struct_blob(&blob
, tctx
, &data
,
641 (ndr_push_flags_fn_t
)ndr_push_bkrp_client_side_wrapped
);
642 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
645 r
->in
.data_in
= blob
.data
;
646 r
->in
.data_in_len
= blob
.length
;
647 r
->out
.data_out
= &out
->data
;
648 r
->out
.data_out_len
= talloc(r
, uint32_t);
652 static struct bkrp_BackupKey
*createRestoreGUIDStruct(struct torture_context
*tctx
,
653 struct dcerpc_pipe
*p
, int version
, DATA_BLOB
*out
,
657 bool broken_magic_secret
,
658 bool broken_magic_access
,
659 bool broken_hash_access
,
660 bool broken_cert_guid
)
662 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
663 struct bkrp_client_side_wrapped data
;
666 DATA_BLOB
*enc_sec
= NULL
;
667 DATA_BLOB
*enc_xs
= NULL
;
669 DATA_BLOB enc_sec_reverted
;
673 struct GUID
*guid
, *g
;
676 enum ndr_err_code ndr_err
;
679 gnutls_cipher_algorithm_t cipher_algo
;
680 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, version
, &out_blob
);
686 /* we take a fake user*/
689 user
= cli_credentials_get_username(
690 samba_cmdline_get_creds());
694 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
696 torture_assert_werr_ok(tctx
, r
->out
.result
,
700 * We have to set it outside of the function createRetrieveBackupKeyGUIDStruct
701 * the len of the blob, this is due to the fact that they don't have the
702 * same size (one is 32bits the other 64bits)
704 out_blob
.length
= *r
->out
.data_out_len
;
706 sec
= create_unencryptedsecret(tctx
, broken_magic_secret
, version
);
711 xs
= create_access_check(tctx
, p
, tctx
, user
, broken_hash_access
, version
);
716 if (broken_magic_access
){
717 /* The start of the access_check structure contains the
718 * GUID of the certificate
723 enc_sec
= encrypt_blob_pk(tctx
, tctx
, out_blob
.data
, out_blob
.length
, sec
);
727 enc_sec_reverted
.data
= talloc_array(tctx
, uint8_t, enc_sec
->length
);
728 if (enc_sec_reverted
.data
== NULL
) {
731 enc_sec_reverted
.length
= enc_sec
->length
;
734 * We DO NOT revert the array on purpose it's in order to check that
735 * when the server is not able to decrypt then it answer the correct error
738 for(t
=0; t
< enc_sec
->length
; t
++) {
739 enc_sec_reverted
.data
[t
] = ((uint8_t*)enc_sec
->data
)[t
];
742 for(t
=0; t
< enc_sec
->length
; t
++) {
743 enc_sec_reverted
.data
[t
] = ((uint8_t*)enc_sec
->data
)[enc_sec
->length
- t
-1];
750 cipher_algo
= GNUTLS_CIPHER_3DES_CBC
;
753 cipher_algo
= GNUTLS_CIPHER_AES_256_CBC
;
758 iv
.length
= gnutls_cipher_get_iv_size(cipher_algo
);
759 iv
.data
= sec
->data
+ (size
- iv
.length
);
761 key
.length
= gnutls_cipher_get_key_size(cipher_algo
);
762 key
.data
= sec
->data
+ (size
- (key
.length
+ iv
.length
));
764 enc_xs
= encrypt_blob(tctx
, tctx
, &key
, &iv
, xs
, cipher_algo
);
769 /* To cope with the fact that heimdal do padding at the end for the moment */
770 enc_xs
->length
= xs
->length
;
772 guid
= get_cert_guid(tctx
, tctx
, out_blob
.data
, out_blob
.length
);
777 if (broken_version
) {
780 data
.version
= version
;
784 data
.encrypted_secret
= enc_sec_reverted
.data
;
785 data
.access_check
= enc_xs
->data
;
786 data
.encrypted_secret_len
= enc_sec
->length
;
787 data
.access_check_len
= enc_xs
->length
;
789 /* We want the blob to persist after this function so we don't
790 * allocate it in the stack
792 blob2
= talloc(tctx
, DATA_BLOB
);
797 ndr_err
= ndr_push_struct_blob(blob2
, tctx
, &data
,
798 (ndr_push_flags_fn_t
)ndr_push_bkrp_client_side_wrapped
);
799 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
803 if (broken_cert_guid
) {
809 g
= talloc(tctx
, struct GUID
);
814 status
= GUID_from_string(BACKUPKEY_RESTORE_GUID
, g
);
815 if (!NT_STATUS_IS_OK(status
)) {
819 r
->in
.guidActionAgent
= g
;
820 r
->in
.data_in
= blob2
->data
;
821 r
->in
.data_in_len
= blob2
->length
;
823 r
->out
.data_out
= &(out
->data
);
824 r
->out
.data_out_len
= talloc(r
, uint32_t);
828 /* Check that we are able to receive the certificate of the DCs
829 * used for client wrap version of the backup key protocol
831 static bool test_RetrieveBackupKeyGUID(struct torture_context
*tctx
,
832 struct dcerpc_pipe
*p
)
834 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
836 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
837 enum dcerpc_AuthType auth_type
;
838 enum dcerpc_AuthLevel auth_level
;
844 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
846 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
847 torture_assert_ntstatus_ok(tctx
,
848 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
851 out_blob
.length
= *r
->out
.data_out_len
;
852 torture_assert_werr_equal(tctx
,
855 "Wrong dce/rpc error code");
857 torture_assert_ntstatus_equal(tctx
,
858 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
859 NT_STATUS_ACCESS_DENIED
,
865 /* Test to check the failure to recover a secret because the
866 * secret blob is not reversed
868 static bool test_RestoreGUID_ko(struct torture_context
*tctx
,
869 struct dcerpc_pipe
*p
)
871 enum ndr_err_code ndr_err
;
872 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
874 struct bkrp_client_side_unwrapped resp
;
875 enum dcerpc_AuthType auth_type
;
876 enum dcerpc_AuthLevel auth_level
;
878 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
880 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
881 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
882 true, false, false, false, false, false, false);
883 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
884 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
885 out_blob
.length
= *r
->out
.data_out_len
;
886 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
887 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
888 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_PARAMETER
, "Wrong error code");
890 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
891 if (!dcerpc_binding_handle_is_connected(b
)) {
892 torture_skip(tctx
, "already disconnected");
894 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
895 NT_STATUS_CONNECTION_DISCONNECTED
, "Get GUID");
901 static bool test_RestoreGUID_wrongversion(struct torture_context
*tctx
,
902 struct dcerpc_pipe
*p
)
904 enum ndr_err_code ndr_err
;
905 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
907 struct bkrp_client_side_unwrapped resp
;
908 enum dcerpc_AuthType auth_type
;
909 enum dcerpc_AuthLevel auth_level
;
911 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
913 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
914 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
915 false, true, false, false, false, false, false);
916 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
917 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
918 out_blob
.length
= *r
->out
.data_out_len
;
919 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
920 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
921 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_PARAMETER
, "Wrong error code on wrong version");
923 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
924 if (!dcerpc_binding_handle_is_connected(b
)) {
925 torture_skip(tctx
, "already disconnected");
927 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
928 NT_STATUS_CONNECTION_DISCONNECTED
, "Get GUID");
934 static bool test_RestoreGUID_wronguser(struct torture_context
*tctx
,
935 struct dcerpc_pipe
*p
)
937 enum ndr_err_code ndr_err
;
938 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
940 struct bkrp_client_side_unwrapped resp
;
941 enum dcerpc_AuthType auth_type
;
942 enum dcerpc_AuthLevel auth_level
;
944 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
946 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
947 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
948 false, false, true, false, false, false, false);
949 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
950 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
951 out_blob
.length
= *r
->out
.data_out_len
;
952 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
953 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
954 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_ACCESS
, "Restore GUID");
956 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
957 if (!dcerpc_binding_handle_is_connected(b
)) {
958 torture_skip(tctx
, "already disconnected");
960 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
961 NT_STATUS_CONNECTION_DISCONNECTED
, "Get GUID");
967 static bool test_RestoreGUID_v3(struct torture_context
*tctx
,
968 struct dcerpc_pipe
*p
)
970 enum ndr_err_code ndr_err
;
971 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
973 struct bkrp_client_side_unwrapped resp
;
974 enum dcerpc_AuthType auth_type
;
975 enum dcerpc_AuthLevel auth_level
;
977 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
979 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
980 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
981 false, false, false, false, false, false, false);
982 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
983 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
984 out_blob
.length
= *r
->out
.data_out_len
;
985 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
986 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 1, "Unable to unmarshall bkrp_client_side_unwrapped");
987 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_OK
, "Restore GUID");
988 torture_assert_str_equal(tctx
, (char*)resp
.secret
.data
, secret
, "Wrong secret");
990 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
991 if (!dcerpc_binding_handle_is_connected(b
)) {
992 torture_skip(tctx
, "already disconnected");
994 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
995 NT_STATUS_CONNECTION_DISCONNECTED
, "Get GUID");
1001 static bool test_RestoreGUID(struct torture_context
*tctx
,
1002 struct dcerpc_pipe
*p
)
1004 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1006 struct bkrp_client_side_unwrapped resp
;
1007 enum dcerpc_AuthType auth_type
;
1008 enum dcerpc_AuthLevel auth_level
;
1010 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1012 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1013 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
1014 false, false, false, false, false, false, false);
1015 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
1016 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1017 out_blob
.length
= *r
->out
.data_out_len
;
1018 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_OK
, "Restore GUID");
1019 torture_assert_ndr_err_equal(tctx
,
1020 ndr_pull_struct_blob(&out_blob
, tctx
, &resp
,
1021 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
),
1023 "Unable to unmarshall bkrp_client_side_unwrapped");
1024 torture_assert_str_equal(tctx
, (char*)resp
.secret
.data
, secret
, "Wrong secret");
1026 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1027 if (!dcerpc_binding_handle_is_connected(b
)) {
1028 torture_skip(tctx
, "already disconnected");
1030 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1031 NT_STATUS_CONNECTION_DISCONNECTED
, "Get GUID");
1037 static bool test_RestoreGUID_badmagiconsecret(struct torture_context
*tctx
,
1038 struct dcerpc_pipe
*p
)
1040 enum ndr_err_code ndr_err
;
1041 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1043 struct bkrp_client_side_unwrapped resp
;
1044 enum dcerpc_AuthType auth_type
;
1045 enum dcerpc_AuthLevel auth_level
;
1047 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1049 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1050 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
1051 false, false, false, true, false, false, false);
1052 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
1053 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1054 out_blob
.length
= *r
->out
.data_out_len
;
1055 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
1056 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1057 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Wrong error code while providing bad magic in secret");
1059 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1060 if (!dcerpc_binding_handle_is_connected(b
)) {
1061 torture_skip(tctx
, "already disconnected");
1063 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1064 NT_STATUS_CONNECTION_DISCONNECTED
, "Get GUID");
1070 static bool test_RestoreGUID_emptyrequest(struct torture_context
*tctx
,
1071 struct dcerpc_pipe
*p
)
1073 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1075 enum dcerpc_AuthType auth_type
;
1076 enum dcerpc_AuthLevel auth_level
;
1078 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1080 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1081 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
1082 false, false, false, true, false, false, true);
1084 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
1085 r
->in
.data_in
= talloc(tctx
, uint8_t);
1086 r
->in
.data_in_len
= 0;
1088 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1089 out_blob
.length
= *r
->out
.data_out_len
;
1090 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_PARAMETER
, "Bad error code on wrong has in access check");
1092 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1093 if (!dcerpc_binding_handle_is_connected(b
)) {
1094 torture_skip(tctx
, "already disconnected");
1096 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1097 NT_STATUS_CONNECTION_DISCONNECTED
, "Get GUID");
1103 static bool test_RestoreGUID_badcertguid(struct torture_context
*tctx
,
1104 struct dcerpc_pipe
*p
)
1106 enum ndr_err_code ndr_err
;
1107 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1109 struct bkrp_client_side_unwrapped resp
;
1110 enum dcerpc_AuthType auth_type
;
1111 enum dcerpc_AuthLevel auth_level
;
1113 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1115 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1116 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 3, &out_blob
,
1117 false, false, false, false, false, false, true);
1118 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct() failed");
1119 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1120 out_blob
.length
= *r
->out
.data_out_len
;
1121 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
1122 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1125 * Windows 2012R2 has, presumably, a programming error
1126 * returning an NTSTATUS code on this interface
1128 if (W_ERROR_V(r
->out
.result
) != NT_STATUS_V(NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
1129 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Bad error code on wrong has in access check");
1132 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1133 if (!dcerpc_binding_handle_is_connected(b
)) {
1134 torture_skip(tctx
, "already disconnected");
1136 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1137 NT_STATUS_CONNECTION_DISCONNECTED
, "Get GUID");
1143 static bool test_RestoreGUID_badmagicaccesscheck(struct torture_context
*tctx
,
1144 struct dcerpc_pipe
*p
)
1146 enum ndr_err_code ndr_err
;
1147 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1149 struct bkrp_client_side_unwrapped resp
;
1150 enum dcerpc_AuthType auth_type
;
1151 enum dcerpc_AuthLevel auth_level
;
1153 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1155 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1156 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
1157 false, false, false, false, true, false, false);
1158 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
1159 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1160 out_blob
.length
= *r
->out
.data_out_len
;
1161 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
1162 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1163 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Bad error code on wrong has in access check");
1165 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1166 if (!dcerpc_binding_handle_is_connected(b
)) {
1167 torture_skip(tctx
, "already disconnected");
1169 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1170 NT_STATUS_CONNECTION_DISCONNECTED
, "Get GUID");
1176 static bool test_RestoreGUID_badhashaccesscheck(struct torture_context
*tctx
,
1177 struct dcerpc_pipe
*p
)
1179 enum ndr_err_code ndr_err
;
1180 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1182 struct bkrp_client_side_unwrapped resp
;
1183 enum dcerpc_AuthType auth_type
;
1184 enum dcerpc_AuthLevel auth_level
;
1186 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1188 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1189 struct bkrp_BackupKey
*r
= createRestoreGUIDStruct(tctx
, p
, 2, &out_blob
,
1190 false, false, false, false, false, true, false);
1191 torture_assert(tctx
, r
!= NULL
, "createRestoreGUIDStruct failed");
1192 torture_assert_ntstatus_ok(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
), "Restore GUID");
1193 out_blob
.length
= *r
->out
.data_out_len
;
1194 ndr_err
= ndr_pull_struct_blob(&out_blob
, tctx
, &resp
, (ndr_pull_flags_fn_t
)ndr_pull_bkrp_client_side_unwrapped
);
1195 torture_assert_int_equal(tctx
, NDR_ERR_CODE_IS_SUCCESS(ndr_err
), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1196 torture_assert_werr_equal(tctx
, r
->out
.result
, WERR_INVALID_DATA
, "Bad error code on wrong has in access check");
1198 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1199 if (!dcerpc_binding_handle_is_connected(b
)) {
1200 torture_skip(tctx
, "already disconnected");
1202 torture_assert_ntstatus_equal(tctx
, dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1203 NT_STATUS_CONNECTION_DISCONNECTED
, "Get GUID");
1210 * Check that the RSA modulus in the certificate of the DCs has 2048 bits.
1212 static bool test_RetrieveBackupKeyGUID_validate(struct torture_context
*tctx
,
1213 struct dcerpc_pipe
*p
)
1215 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1217 struct bkrp_BackupKey
*r
= createRetrieveBackupKeyGUIDStruct(tctx
, p
, 2, &out_blob
);
1218 enum dcerpc_AuthType auth_type
;
1219 enum dcerpc_AuthLevel auth_level
;
1221 torture_assert(tctx
, r
!= NULL
, "test_RetrieveBackupKeyGUID_validate failed");
1227 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1229 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1230 gnutls_x509_crt_t x509_cert
= NULL
;
1231 gnutls_pubkey_t pubkey
= NULL
;
1232 gnutls_datum_t x509_crt_data
;
1233 gnutls_pk_algorithm_t pubkey_algo
;
1234 uint8_t dummy
[1] = {0};
1235 DATA_BLOB subject_unique_id
= {
1239 DATA_BLOB issuer_unique_id
= {
1243 DATA_BLOB reversed
= {
1247 DATA_BLOB serial_number
;
1248 unsigned int RSA_returned_bits
= 0;
1254 torture_assert_ntstatus_ok(tctx
,
1255 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1258 torture_assert_werr_ok(tctx
, r
->out
.result
,
1261 out_blob
.length
= *r
->out
.data_out_len
;
1263 x509_crt_data
.data
= out_blob
.data
;
1264 x509_crt_data
.size
= out_blob
.length
;
1266 rc
= gnutls_x509_crt_init(&x509_cert
);
1267 if (rc
!= GNUTLS_E_SUCCESS
) {
1271 rc
= gnutls_x509_crt_import(x509_cert
,
1273 GNUTLS_X509_FMT_DER
);
1274 torture_assert_int_equal(tctx
,
1277 "gnutls_x509_crt_import failed");
1279 /* Compare unique ids */
1281 /* Get buffer size */
1282 rc
= gnutls_x509_crt_get_subject_unique_id(x509_cert
,
1283 (char *)subject_unique_id
.data
,
1284 &subject_unique_id
.length
);
1285 torture_assert_int_equal(tctx
,
1287 GNUTLS_E_SHORT_MEMORY_BUFFER
,
1288 "gnutls_x509_crt_get_subject_unique_id "
1289 "get buffer size failed");
1291 subject_unique_id
= data_blob_talloc_zero(tctx
,
1292 subject_unique_id
.length
);
1294 rc
= gnutls_x509_crt_get_subject_unique_id(x509_cert
,
1295 (char *)subject_unique_id
.data
,
1296 &subject_unique_id
.length
);
1297 torture_assert_int_equal(tctx
,
1300 "gnutls_x509_crt_get_subject_unique_id failed");
1302 rc
= gnutls_x509_crt_get_issuer_unique_id(x509_cert
,
1303 (char *)issuer_unique_id
.data
,
1304 &issuer_unique_id
.length
);
1305 torture_assert_int_equal(tctx
,
1307 GNUTLS_E_SHORT_MEMORY_BUFFER
,
1308 "gnutls_x509_crt_get_issuer_unique_id "
1309 "get buffer size failed");
1311 issuer_unique_id
= data_blob_talloc_zero(tctx
,
1312 issuer_unique_id
.length
);
1314 rc
= gnutls_x509_crt_get_issuer_unique_id(x509_cert
,
1315 (char *)issuer_unique_id
.data
,
1316 &issuer_unique_id
.length
);
1317 torture_assert_int_equal(tctx
,
1320 "gnutls_x509_crt_get_issuer_unique_id failed");
1322 cmp
= data_blob_cmp(&subject_unique_id
, &issuer_unique_id
);
1323 torture_assert(tctx
,
1325 "The GUID to identify the public key is not "
1328 rc
= gnutls_x509_crt_get_serial(x509_cert
,
1331 torture_assert_int_equal(tctx
,
1333 GNUTLS_E_SHORT_MEMORY_BUFFER
,
1334 "gnutls_x509_crt_get_serial "
1335 "get buffer size failed");
1337 reversed
= data_blob_talloc_zero(tctx
,
1340 rc
= gnutls_x509_crt_get_serial(x509_cert
,
1343 torture_assert_int_equal(tctx
,
1346 "gnutls_x509_crt_get_serial failed");
1349 * Heimdal sometimes adds a leading byte to the data buffer of
1350 * the serial number. So lets uses the subject_unique_id size
1351 * and ignore the leading byte.
1353 serial_number
= data_blob_talloc_zero(tctx
,
1354 subject_unique_id
.length
);
1356 for (i
= 0; i
< serial_number
.length
; i
++) {
1357 serial_number
.data
[i
] = reversed
.data
[reversed
.length
- i
- 1];
1360 cmp
= data_blob_cmp(&subject_unique_id
, &serial_number
);
1361 torture_assert(tctx
,
1363 "The GUID to identify the public key is not "
1366 /* Check certificate version */
1367 version
= gnutls_x509_crt_get_version(x509_cert
);
1368 torture_assert_int_equal(tctx
,
1371 "Invalid certificate version");
1373 /* Get the public key */
1374 rc
= gnutls_pubkey_init(&pubkey
);
1375 torture_assert_int_equal(tctx
,
1378 "gnutls_pubkey_init failed");
1380 rc
= gnutls_pubkey_import_x509(pubkey
,
1383 gnutls_x509_crt_deinit(x509_cert
);
1384 torture_assert_int_equal(tctx
,
1387 "gnutls_pubkey_import_x509 failed");
1389 pubkey_algo
= gnutls_pubkey_get_pk_algorithm(pubkey
,
1390 &RSA_returned_bits
);
1391 gnutls_pubkey_deinit(pubkey
);
1392 torture_assert_int_equal(tctx
,
1395 "gnutls_pubkey_get_pk_algorithm did "
1396 "not return a RSA key");
1397 torture_assert_int_equal(tctx
,
1400 "RSA Key doesn't have 2048 bits");
1402 if (!dcerpc_binding_handle_is_connected(b
)) {
1403 torture_skip(tctx
, "already disconnected");
1405 torture_assert_ntstatus_equal(tctx
,
1406 dcerpc_bkrp_BackupKey_r(b
, tctx
, r
),
1407 NT_STATUS_CONNECTION_DISCONNECTED
,
1414 static bool test_ServerWrap_encrypt_decrypt(struct torture_context
*tctx
,
1415 struct dcerpc_pipe
*p
)
1417 struct bkrp_BackupKey r
;
1419 DATA_BLOB plaintext
= data_blob_const(secret
, sizeof(secret
));
1420 DATA_BLOB encrypted
;
1422 DATA_BLOB decrypted
;
1424 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1425 enum dcerpc_AuthType auth_type
;
1426 enum dcerpc_AuthLevel auth_level
;
1429 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1432 torture_assert_ntstatus_ok(tctx
,
1433 GUID_from_string(BACKUPKEY_BACKUP_GUID
, &guid
),
1436 r
.in
.guidActionAgent
= &guid
;
1437 r
.in
.data_in
= plaintext
.data
;
1438 r
.in
.data_in_len
= plaintext
.length
;
1440 r
.out
.data_out
= &encrypted
.data
;
1441 r
.out
.data_out_len
= &enclen
;
1442 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1443 torture_assert_ntstatus_ok(tctx
,
1444 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1447 if (!dcerpc_binding_handle_is_connected(b
)) {
1448 torture_skip(tctx
, "already disconnected");
1450 torture_assert_ntstatus_equal(tctx
,
1451 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1452 NT_STATUS_CONNECTION_DISCONNECTED
,
1456 torture_assert_werr_ok(tctx
,
1459 encrypted
.length
= *r
.out
.data_out_len
;
1462 torture_assert_ntstatus_ok(tctx
,
1463 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1466 r
.in
.guidActionAgent
= &guid
;
1467 r
.in
.data_in
= encrypted
.data
;
1468 r
.in
.data_in_len
= encrypted
.length
;
1470 r
.out
.data_out
= &(decrypted
.data
);
1471 r
.out
.data_out_len
= &declen
;
1472 torture_assert_ntstatus_ok(tctx
,
1473 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1475 torture_assert_werr_ok(tctx
,
1478 decrypted
.length
= *r
.out
.data_out_len
;
1481 torture_assert_data_blob_equal(tctx
, plaintext
, decrypted
, "Decrypt failed");
1484 torture_assert_ntstatus_ok(tctx
,
1485 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1488 r
.in
.guidActionAgent
= &guid
;
1489 r
.in
.data_in
= encrypted
.data
;
1490 r
.in
.data_in_len
= encrypted
.length
;
1492 r
.out
.data_out
= &(decrypted
.data
);
1493 r
.out
.data_out_len
= &declen
;
1494 torture_assert_ntstatus_ok(tctx
,
1495 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1497 torture_assert_werr_ok(tctx
,
1500 decrypted
.length
= *r
.out
.data_out_len
;
1503 torture_assert_data_blob_equal(tctx
, plaintext
, decrypted
, "Decrypt failed");
1507 static bool test_ServerWrap_decrypt_wrong_keyGUID(struct torture_context
*tctx
,
1508 struct dcerpc_pipe
*p
)
1510 struct bkrp_BackupKey r
;
1512 DATA_BLOB plaintext
= data_blob_const(secret
, sizeof(secret
));
1513 DATA_BLOB encrypted
;
1515 DATA_BLOB decrypted
;
1517 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1518 enum ndr_err_code ndr_err
;
1519 struct bkrp_server_side_wrapped server_side_wrapped
;
1520 enum dcerpc_AuthType auth_type
;
1521 enum dcerpc_AuthLevel auth_level
;
1524 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1527 torture_assert_ntstatus_ok(tctx
,
1528 GUID_from_string(BACKUPKEY_BACKUP_GUID
, &guid
),
1531 r
.in
.guidActionAgent
= &guid
;
1532 r
.in
.data_in
= plaintext
.data
;
1533 r
.in
.data_in_len
= plaintext
.length
;
1535 r
.out
.data_out
= &encrypted
.data
;
1536 r
.out
.data_out_len
= &enclen
;
1537 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1538 torture_assert_ntstatus_ok(tctx
,
1539 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1542 if (!dcerpc_binding_handle_is_connected(b
)) {
1543 torture_skip(tctx
, "already disconnected");
1545 torture_assert_ntstatus_equal(tctx
,
1546 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1547 NT_STATUS_CONNECTION_DISCONNECTED
,
1551 torture_assert_werr_ok(tctx
,
1554 encrypted
.length
= *r
.out
.data_out_len
;
1556 ndr_err
= ndr_pull_struct_blob(&encrypted
, tctx
, &server_side_wrapped
,
1557 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_server_side_wrapped
);
1558 torture_assert_ndr_err_equal(tctx
, ndr_err
, NDR_ERR_SUCCESS
, "pull of server_side_wrapped");
1560 /* Change the GUID */
1561 server_side_wrapped
.guid
= GUID_random();
1563 ndr_err
= ndr_push_struct_blob(&encrypted
, tctx
, &server_side_wrapped
,
1564 (ndr_push_flags_fn_t
)ndr_push_bkrp_server_side_wrapped
);
1565 torture_assert_ndr_err_equal(tctx
, ndr_err
, NDR_ERR_SUCCESS
, "push of server_side_wrapped");
1568 torture_assert_ntstatus_ok(tctx
,
1569 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1572 r
.in
.guidActionAgent
= &guid
;
1573 r
.in
.data_in
= encrypted
.data
;
1574 r
.in
.data_in_len
= encrypted
.length
;
1576 r
.out
.data_out
= &(decrypted
.data
);
1577 r
.out
.data_out_len
= &declen
;
1578 torture_assert_ntstatus_ok(tctx
,
1579 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1581 torture_assert_werr_equal(tctx
,
1584 "decrypt should fail with WERR_INVALID_DATA");
1587 torture_assert_ntstatus_ok(tctx
,
1588 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1591 r
.in
.guidActionAgent
= &guid
;
1592 r
.in
.data_in
= encrypted
.data
;
1593 r
.in
.data_in_len
= encrypted
.length
;
1595 r
.out
.data_out
= &(decrypted
.data
);
1596 r
.out
.data_out_len
= &declen
;
1597 torture_assert_ntstatus_ok(tctx
,
1598 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1600 torture_assert_werr_equal(tctx
,
1603 "decrypt should fail with WERR_INVALID_DATA");
1608 static bool test_ServerWrap_decrypt_empty_request(struct torture_context
*tctx
,
1609 struct dcerpc_pipe
*p
)
1611 struct bkrp_BackupKey r
;
1613 DATA_BLOB decrypted
;
1615 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1616 uint8_t short_request
[4] = { 1, 0, 0, 0 };
1617 enum dcerpc_AuthType auth_type
;
1618 enum dcerpc_AuthLevel auth_level
;
1621 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1624 torture_assert_ntstatus_ok(tctx
,
1625 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1628 r
.in
.guidActionAgent
= &guid
;
1629 r
.in
.data_in
= short_request
;
1630 r
.in
.data_in_len
= 0;
1632 r
.out
.data_out
= &(decrypted
.data
);
1633 r
.out
.data_out_len
= &declen
;
1634 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1635 torture_assert_ntstatus_ok(tctx
,
1636 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1639 if (!dcerpc_binding_handle_is_connected(b
)) {
1640 torture_skip(tctx
, "already disconnected");
1642 torture_assert_ntstatus_equal(tctx
,
1643 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1644 NT_STATUS_CONNECTION_DISCONNECTED
,
1648 torture_assert_werr_equal(tctx
,
1650 WERR_INVALID_PARAMETER
,
1651 "decrypt should fail with WERR_INVALID_PARAMETER");
1654 torture_assert_ntstatus_ok(tctx
,
1655 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1658 r
.in
.guidActionAgent
= &guid
;
1659 r
.in
.data_in
= short_request
;
1660 r
.in
.data_in_len
= 0;
1662 r
.out
.data_out
= &(decrypted
.data
);
1663 r
.out
.data_out_len
= &declen
;
1664 torture_assert_ntstatus_ok(tctx
,
1665 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1667 torture_assert_werr_equal(tctx
,
1669 WERR_INVALID_PARAMETER
,
1670 "decrypt should fail with WERR_INVALID_PARAMETER");
1673 torture_assert_ntstatus_ok(tctx
,
1674 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1677 r
.in
.guidActionAgent
= &guid
;
1678 r
.in
.data_in
= NULL
;
1679 r
.in
.data_in_len
= 0;
1681 r
.out
.data_out
= &(decrypted
.data
);
1682 r
.out
.data_out_len
= &declen
;
1683 torture_assert_ntstatus_equal(tctx
,
1684 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1685 NT_STATUS_INVALID_PARAMETER_MIX
,
1689 torture_assert_ntstatus_ok(tctx
,
1690 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1693 r
.in
.guidActionAgent
= &guid
;
1694 r
.in
.data_in
= NULL
;
1695 r
.in
.data_in_len
= 0;
1697 r
.out
.data_out
= &(decrypted
.data
);
1698 r
.out
.data_out_len
= &declen
;
1699 torture_assert_ntstatus_equal(tctx
,
1700 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1701 NT_STATUS_INVALID_PARAMETER_MIX
,
1708 static bool test_ServerWrap_decrypt_short_request(struct torture_context
*tctx
,
1709 struct dcerpc_pipe
*p
)
1711 struct bkrp_BackupKey r
;
1713 DATA_BLOB decrypted
;
1715 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1716 uint8_t short_request
[4] = { 1, 0, 0, 0 };
1717 enum dcerpc_AuthType auth_type
;
1718 enum dcerpc_AuthLevel auth_level
;
1721 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
1724 torture_assert_ntstatus_ok(tctx
,
1725 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1728 r
.in
.guidActionAgent
= &guid
;
1729 r
.in
.data_in
= short_request
;
1730 r
.in
.data_in_len
= 4;
1732 r
.out
.data_out
= &(decrypted
.data
);
1733 r
.out
.data_out_len
= &declen
;
1734 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
1735 torture_assert_ntstatus_ok(tctx
,
1736 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1739 if (!dcerpc_binding_handle_is_connected(b
)) {
1740 torture_skip(tctx
, "already disconnected");
1742 torture_assert_ntstatus_equal(tctx
,
1743 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1744 NT_STATUS_CONNECTION_DISCONNECTED
,
1748 torture_assert_werr_equal(tctx
,
1750 WERR_INVALID_PARAMETER
,
1751 "decrypt should fail with WERR_INVALID_PARM");
1754 torture_assert_ntstatus_ok(tctx
,
1755 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1758 r
.in
.guidActionAgent
= &guid
;
1759 r
.in
.data_in
= short_request
;
1760 r
.in
.data_in_len
= 4;
1762 r
.out
.data_out
= &(decrypted
.data
);
1763 r
.out
.data_out_len
= &declen
;
1764 torture_assert_ntstatus_ok(tctx
,
1765 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1767 torture_assert_werr_equal(tctx
,
1769 WERR_INVALID_PARAMETER
,
1770 "decrypt should fail with WERR_INVALID_PARAMETER");
1773 torture_assert_ntstatus_ok(tctx
,
1774 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
1777 r
.in
.guidActionAgent
= &guid
;
1778 r
.in
.data_in
= short_request
;
1779 r
.in
.data_in_len
= 1;
1781 r
.out
.data_out
= &(decrypted
.data
);
1782 r
.out
.data_out_len
= &declen
;
1783 torture_assert_ntstatus_ok(tctx
,
1784 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1786 torture_assert_werr_equal(tctx
,
1788 WERR_INVALID_PARAMETER
,
1789 "decrypt should fail with WERR_INVALID_PARAMETER");
1792 torture_assert_ntstatus_ok(tctx
,
1793 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
1796 r
.in
.guidActionAgent
= &guid
;
1797 r
.in
.data_in
= short_request
;
1798 r
.in
.data_in_len
= 1;
1800 r
.out
.data_out
= &(decrypted
.data
);
1801 r
.out
.data_out_len
= &declen
;
1802 torture_assert_ntstatus_ok(tctx
,
1803 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
1805 torture_assert_werr_equal(tctx
,
1807 WERR_INVALID_PARAMETER
,
1808 "decrypt should fail with WERR_INVALID_PARAMETER");
1813 static bool test_ServerWrap_encrypt_decrypt_manual(struct torture_context
*tctx
,
1814 struct bkrp_server_side_wrapped
*server_side_wrapped
,
1815 enum test_wrong wrong
)
1817 char *lsa_binding_string
= NULL
;
1818 struct dcerpc_binding
*lsa_binding
= NULL
;
1819 struct dcerpc_pipe
*lsa_p
= NULL
;
1820 struct dcerpc_binding_handle
*lsa_b
= NULL
;
1821 struct lsa_OpenSecret r_secret
;
1822 struct lsa_QuerySecret r_query_secret
;
1823 struct policy_handle
*handle
, sec_handle
;
1824 struct bkrp_BackupKey r
;
1825 struct GUID preferred_key_guid
;
1826 DATA_BLOB plaintext
= data_blob_const(secret
, sizeof(secret
));
1827 DATA_BLOB preferred_key
, preferred_key_clear
, session_key
,
1828 decrypt_key
, decrypt_key_clear
, encrypted_blob
,
1830 struct bkrp_dc_serverwrap_key server_key
;
1831 struct lsa_DATA_BUF_PTR bufp1
;
1832 char *key_guid_string
;
1833 struct bkrp_rc4encryptedpayload rc4payload
;
1834 struct dom_sid
*caller_sid
;
1835 uint8_t symkey
[20]; /* SHA-1 hash len */
1836 uint8_t mackey
[20]; /* SHA-1 hash len */
1837 uint8_t mac
[20]; /* SHA-1 hash len */
1838 gnutls_hmac_hd_t hmac_hnd
;
1839 gnutls_cipher_hd_t cipher_hnd
;
1840 gnutls_datum_t cipher_key
;
1844 ZERO_STRUCT(r_secret
);
1845 ZERO_STRUCT(r_query_secret
);
1847 /* Now read BCKUPKEY_P and prove we can do a matching decrypt and encrypt */
1849 /* lsa_OpenSecret only works with ncacn_np and AUTH_LEVEL_NONE */
1850 lsa_binding_string
= talloc_asprintf(tctx
, "ncacn_np:%s",
1851 torture_setting_string(tctx
, "host", NULL
));
1852 torture_assert(tctx
, lsa_binding_string
!= NULL
, "lsa_binding_string");
1854 torture_assert_ntstatus_ok(tctx
,
1855 dcerpc_parse_binding(tctx
, lsa_binding_string
, &lsa_binding
),
1856 "Failed to parse dcerpc binding");
1858 torture_assert_ntstatus_ok(tctx
,
1859 dcerpc_pipe_connect_b(tctx
, &lsa_p
,
1860 lsa_binding
, &ndr_table_lsarpc
,
1861 samba_cmdline_get_creds(),
1862 tctx
->ev
, tctx
->lp_ctx
),
1863 "Opening LSA pipe");
1864 lsa_b
= lsa_p
->binding_handle
;
1866 torture_assert(tctx
, test_lsa_OpenPolicy2(lsa_b
, tctx
, &handle
), "OpenPolicy failed");
1867 r_secret
.in
.name
.string
= "G$BCKUPKEY_P";
1869 r_secret
.in
.handle
= handle
;
1870 r_secret
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1871 r_secret
.out
.sec_handle
= &sec_handle
;
1873 torture_comment(tctx
, "Testing OpenSecret\n");
1875 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenSecret_r(lsa_b
, tctx
, &r_secret
),
1876 "OpenSecret failed");
1877 torture_assert_ntstatus_ok(tctx
, r_secret
.out
.result
,
1878 "OpenSecret failed");
1880 r_query_secret
.in
.sec_handle
= &sec_handle
;
1881 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 preferred_key
.data
= r_query_secret
.out
.new_val
->buf
->data
;
1891 preferred_key
.length
= r_query_secret
.out
.new_val
->buf
->size
;
1892 torture_assert_ntstatus_ok(tctx
,
1893 dcerpc_binding_handle_transport_session_key(lsa_b
, tctx
, &session_key
),
1894 "transport_session_key failed");
1896 torture_assert_ntstatus_ok(tctx
,
1897 sess_decrypt_blob(tctx
,
1898 &preferred_key
, &session_key
, &preferred_key_clear
),
1899 "sess_decrypt_blob failed");
1901 torture_assert_ntstatus_ok(tctx
, GUID_from_ndr_blob(&preferred_key_clear
, &preferred_key_guid
),
1902 "GUID parse failed");
1904 torture_assert_guid_equal(tctx
, server_side_wrapped
->guid
,
1906 "GUID didn't match value pointed at by G$BCKUPKEY_P");
1908 /* And read BCKUPKEY_<guid> and get the actual key */
1910 key_guid_string
= GUID_string(tctx
, &server_side_wrapped
->guid
);
1911 r_secret
.in
.name
.string
= talloc_asprintf(tctx
, "G$BCKUPKEY_%s", key_guid_string
);
1913 r_secret
.in
.handle
= handle
;
1914 r_secret
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1915 r_secret
.out
.sec_handle
= &sec_handle
;
1917 torture_comment(tctx
, "Testing OpenSecret\n");
1919 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_OpenSecret_r(lsa_b
, tctx
, &r_secret
),
1920 "OpenSecret failed");
1921 torture_assert_ntstatus_ok(tctx
, r_secret
.out
.result
,
1922 "OpenSecret failed");
1924 r_query_secret
.in
.sec_handle
= &sec_handle
;
1925 r_query_secret
.in
.new_val
= &bufp1
;
1927 torture_assert_ntstatus_ok(tctx
, dcerpc_lsa_QuerySecret_r(lsa_b
, tctx
, &r_query_secret
),
1928 "QuerySecret failed");
1929 torture_assert_ntstatus_ok(tctx
, r_query_secret
.out
.result
,
1930 "QuerySecret failed");
1933 decrypt_key
.data
= r_query_secret
.out
.new_val
->buf
->data
;
1934 decrypt_key
.length
= r_query_secret
.out
.new_val
->buf
->size
;
1936 torture_assert_ntstatus_ok(tctx
,
1937 sess_decrypt_blob(tctx
,
1938 &decrypt_key
, &session_key
, &decrypt_key_clear
),
1939 "sess_decrypt_blob failed");
1941 torture_assert_ndr_err_equal(tctx
, ndr_pull_struct_blob(&decrypt_key_clear
, tctx
, &server_key
,
1942 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_dc_serverwrap_key
),
1943 NDR_ERR_SUCCESS
, "Failed to parse server_key");
1945 torture_assert_int_equal(tctx
, server_key
.magic
, 1, "Failed to correctly decrypt server key");
1948 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1949 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1951 gnutls_hmac_init(&hmac_hnd
,
1954 sizeof(server_key
.key
));
1955 gnutls_hmac(hmac_hnd
,
1956 server_side_wrapped
->r2
,
1957 sizeof(server_side_wrapped
->r2
));
1958 gnutls_hmac_output(hmac_hnd
, symkey
);
1960 /* rc4 decrypt sid and secret using sym key */
1961 cipher_key
.data
= symkey
;
1962 cipher_key
.size
= sizeof(symkey
);
1964 encrypted_blob
= data_blob_talloc(tctx
, server_side_wrapped
->rc4encryptedpayload
,
1965 server_side_wrapped
->ciphertext_length
);
1967 rc
= gnutls_cipher_init(&cipher_hnd
,
1968 GNUTLS_CIPHER_ARCFOUR_128
,
1971 torture_assert_int_equal(tctx
,
1974 "gnutls_cipher_init failed");
1975 rc
= gnutls_cipher_encrypt2(cipher_hnd
,
1976 encrypted_blob
.data
,
1977 encrypted_blob
.length
,
1978 encrypted_blob
.data
,
1979 encrypted_blob
.length
);
1980 torture_assert_int_equal(tctx
,
1983 "gnutls_cipher_encrypt failed");
1984 gnutls_cipher_deinit(cipher_hnd
);
1986 torture_assert_ndr_err_equal(tctx
, ndr_pull_struct_blob(&encrypted_blob
, tctx
, &rc4payload
,
1987 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_rc4encryptedpayload
),
1988 NDR_ERR_SUCCESS
, "Failed to parse rc4encryptedpayload");
1990 torture_assert_int_equal(tctx
, rc4payload
.secret_data
.length
,
1991 server_side_wrapped
->payload_length
,
1992 "length of decrypted payload not the length declared in surrounding structure");
1995 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1996 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1998 gnutls_hmac(hmac_hnd
,
2000 sizeof(rc4payload
.r3
));
2001 gnutls_hmac_deinit(hmac_hnd
, mackey
);
2003 torture_assert_ndr_err_equal(tctx
, ndr_push_struct_blob(&sid_blob
, tctx
, &rc4payload
.sid
,
2004 (ndr_push_flags_fn_t
)ndr_push_dom_sid
),
2005 NDR_ERR_SUCCESS
, "unable to push SID");
2007 gnutls_hmac_init(&hmac_hnd
,
2012 gnutls_hmac(hmac_hnd
,
2016 gnutls_hmac(hmac_hnd
,
2017 rc4payload
.secret_data
.data
,
2018 rc4payload
.secret_data
.length
);
2019 gnutls_hmac_output(hmac_hnd
, mac
);
2021 torture_assert_mem_equal(tctx
, mac
, rc4payload
.mac
, sizeof(mac
), "mac not correct");
2022 torture_assert_int_equal(tctx
, rc4payload
.secret_data
.length
,
2023 plaintext
.length
, "decrypted data is not correct length");
2024 torture_assert_mem_equal(tctx
, rc4payload
.secret_data
.data
,
2025 plaintext
.data
, plaintext
.length
,
2026 "decrypted data is not correct");
2028 /* Not strictly correct all the time, but good enough for this test */
2029 caller_sid
= get_user_sid(tctx
, tctx
,
2030 cli_credentials_get_username(
2031 samba_cmdline_get_creds()));
2033 torture_assert_sid_equal(tctx
, &rc4payload
.sid
, caller_sid
, "Secret saved with wrong SID");
2038 if (wrong
== WRONG_SID
) {
2039 rc4payload
.sid
.sub_auths
[rc4payload
.sid
.num_auths
- 1] = DOMAIN_RID_KRBTGT
;
2042 dump_data_pw("mackey: \n", mackey
, sizeof(mackey
));
2044 torture_assert_ndr_err_equal(tctx
,
2045 ndr_push_struct_blob(&sid_blob
, tctx
, &rc4payload
.sid
,
2046 (ndr_push_flags_fn_t
)ndr_push_dom_sid
),
2048 "push of sid failed");
2051 gnutls_hmac(hmac_hnd
,
2055 gnutls_hmac(hmac_hnd
,
2056 rc4payload
.secret_data
.data
,
2057 rc4payload
.secret_data
.length
);
2058 gnutls_hmac_deinit(hmac_hnd
, rc4payload
.mac
);
2060 dump_data_pw("rc4payload.mac: \n", rc4payload
.mac
, sizeof(rc4payload
.mac
));
2062 torture_assert_ndr_err_equal(tctx
,
2063 ndr_push_struct_blob(&encrypted_blob
, tctx
, &rc4payload
,
2064 (ndr_push_flags_fn_t
)ndr_push_bkrp_rc4encryptedpayload
),
2066 "push of rc4payload failed");
2068 if (wrong
== WRONG_KEY
) {
2074 /* rc4 encrypt sid and secret using sym key */
2075 cipher_key
.data
= symkey
;
2076 cipher_key
.size
= sizeof(symkey
);
2078 rc
= gnutls_cipher_init(&cipher_hnd
,
2079 GNUTLS_CIPHER_ARCFOUR_128
,
2082 torture_assert_int_equal(tctx
,
2085 "gnutls_cipher_init failed");
2086 rc
= gnutls_cipher_encrypt2(cipher_hnd
,
2087 encrypted_blob
.data
,
2088 encrypted_blob
.length
,
2089 encrypted_blob
.data
,
2090 encrypted_blob
.length
);
2091 torture_assert_int_equal(tctx
,
2094 "gnutls_cipher_encrypt failed");
2095 gnutls_cipher_deinit(cipher_hnd
);
2098 /* re-create server wrap structure */
2100 torture_assert_int_equal(tctx
, encrypted_blob
.length
,
2101 server_side_wrapped
->ciphertext_length
,
2102 "expected encrypted length not to change");
2103 if (wrong
== RIGHT_KEY
) {
2104 torture_assert_mem_equal(tctx
, server_side_wrapped
->rc4encryptedpayload
,
2105 encrypted_blob
.data
,
2106 encrypted_blob
.length
,
2107 "expected encrypted data not to change");
2110 server_side_wrapped
->payload_length
= rc4payload
.secret_data
.length
;
2111 server_side_wrapped
->ciphertext_length
= encrypted_blob
.length
;
2112 server_side_wrapped
->rc4encryptedpayload
= encrypted_blob
.data
;
2118 static bool test_ServerWrap_decrypt_wrong_stuff(struct torture_context
*tctx
,
2119 struct dcerpc_pipe
*p
,
2120 enum test_wrong wrong
)
2122 struct bkrp_BackupKey r
;
2124 DATA_BLOB plaintext
= data_blob_const(secret
, sizeof(secret
));
2125 DATA_BLOB encrypted
;
2127 DATA_BLOB decrypted
;
2129 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2130 enum ndr_err_code ndr_err
;
2131 struct bkrp_server_side_wrapped server_side_wrapped
;
2132 bool repush
= false;
2133 enum dcerpc_AuthType auth_type
;
2134 enum dcerpc_AuthLevel auth_level
;
2137 dcerpc_binding_handle_auth_info(b
, &auth_type
, &auth_level
);
2140 torture_assert_ntstatus_ok(tctx
,
2141 GUID_from_string(BACKUPKEY_BACKUP_GUID
, &guid
),
2144 r
.in
.guidActionAgent
= &guid
;
2145 r
.in
.data_in
= plaintext
.data
;
2146 r
.in
.data_in_len
= plaintext
.length
;
2148 r
.out
.data_out
= &encrypted
.data
;
2149 r
.out
.data_out_len
= &enclen
;
2150 if (auth_level
== DCERPC_AUTH_LEVEL_PRIVACY
) {
2151 torture_assert_ntstatus_ok(tctx
,
2152 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
2155 if (!dcerpc_binding_handle_is_connected(b
)) {
2156 torture_skip(tctx
, "already disconnected");
2158 torture_assert_ntstatus_equal(tctx
,
2159 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
2160 NT_STATUS_CONNECTION_DISCONNECTED
,
2164 torture_assert_werr_ok(tctx
,
2167 encrypted
.length
= *r
.out
.data_out_len
;
2169 ndr_err
= ndr_pull_struct_blob(&encrypted
, tctx
, &server_side_wrapped
,
2170 (ndr_pull_flags_fn_t
)ndr_pull_bkrp_server_side_wrapped
);
2171 torture_assert_ndr_err_equal(tctx
, ndr_err
, NDR_ERR_SUCCESS
, "pull of server_side_wrapped");
2173 torture_assert_int_equal(tctx
, server_side_wrapped
.payload_length
, plaintext
.length
,
2174 "wrong payload length");
2178 /* Change the magic. Forced by our NDR layer, so do it raw */
2179 SIVAL(encrypted
.data
, 0, 78); /* valid values are 1-3 */
2182 server_side_wrapped
.r2
[0] = 78;
2183 server_side_wrapped
.r2
[1] = 78;
2184 server_side_wrapped
.r2
[2] = 78;
2187 case WRONG_PAYLOAD_LENGTH
:
2188 server_side_wrapped
.payload_length
= UINT32_MAX
- 8;
2191 case WRONG_CIPHERTEXT_LENGTH
:
2193 * Change the ciphertext len. We can't push this if
2194 * we have it wrong, so do it raw
2196 SIVAL(encrypted
.data
, 8, UINT32_MAX
- 8); /* valid values are 1-3 */
2198 case SHORT_PAYLOAD_LENGTH
:
2199 server_side_wrapped
.payload_length
= server_side_wrapped
.payload_length
- 8;
2202 case SHORT_CIPHERTEXT_LENGTH
:
2204 * Change the ciphertext len. We can't push this if
2205 * we have it wrong, so do it raw
2207 SIVAL(encrypted
.data
, 8, server_side_wrapped
.ciphertext_length
- 8); /* valid values are 1-3 */
2209 case ZERO_PAYLOAD_LENGTH
:
2210 server_side_wrapped
.payload_length
= 0;
2213 case ZERO_CIPHERTEXT_LENGTH
:
2215 * Change the ciphertext len. We can't push this if
2216 * we have it wrong, so do it raw
2218 SIVAL(encrypted
.data
, 8, 0); /* valid values are 1-3 */
2224 torture_assert(tctx
,
2225 test_ServerWrap_encrypt_decrypt_manual(tctx
, &server_side_wrapped
, wrong
),
2226 "test_ServerWrap_encrypt_decrypt_manual failed");
2232 ndr_err
= ndr_push_struct_blob(&encrypted
, tctx
, &server_side_wrapped
,
2233 (ndr_push_flags_fn_t
)ndr_push_bkrp_server_side_wrapped
);
2234 torture_assert_ndr_err_equal(tctx
, ndr_err
, NDR_ERR_SUCCESS
, "push of server_side_wrapped");
2238 torture_assert_ntstatus_ok(tctx
,
2239 GUID_from_string(BACKUPKEY_RESTORE_GUID
, &guid
),
2242 r
.in
.guidActionAgent
= &guid
;
2243 r
.in
.data_in
= encrypted
.data
;
2244 r
.in
.data_in_len
= encrypted
.length
;
2246 r
.out
.data_out
= &(decrypted
.data
);
2247 r
.out
.data_out_len
= &declen
;
2248 torture_assert_ntstatus_ok(tctx
,
2249 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
2252 if ((wrong
== WRONG_R2
|| wrong
== WRONG_KEY
)
2253 && W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_SID
)) {
2254 torture_assert_werr_equal(tctx
,
2257 "decrypt should fail with WERR_INVALID_SID or WERR_INVALID_PARAMETER");
2258 } else if (wrong
== RIGHT_KEY
) {
2259 torture_assert_werr_equal(tctx
,
2262 "decrypt should succeed!");
2263 } else if (wrong
== WRONG_SID
) {
2264 torture_assert_werr_equal(tctx
,
2266 WERR_INVALID_ACCESS
,
2267 "decrypt should fail with WERR_INVALID_ACCESS");
2269 if (!W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_ACCESS
)
2270 && !W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_PARAMETER
)) {
2271 torture_assert_werr_equal(tctx
, r
.out
.result
,
2273 "decrypt should fail with WERR_INVALID_ACCESS, WERR_INVALID_PARAMETER or WERR_INVALID_DATA");
2278 torture_assert_ntstatus_ok(tctx
,
2279 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K
, &guid
),
2282 r
.in
.guidActionAgent
= &guid
;
2283 r
.in
.data_in
= encrypted
.data
;
2284 r
.in
.data_in_len
= encrypted
.length
;
2286 r
.out
.data_out
= &(decrypted
.data
);
2287 r
.out
.data_out_len
= &declen
;
2288 torture_assert_ntstatus_ok(tctx
,
2289 dcerpc_bkrp_BackupKey_r(b
, tctx
, &r
),
2292 if ((wrong
== WRONG_R2
|| wrong
== WRONG_KEY
)
2293 && W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_SID
)) {
2294 torture_assert_werr_equal(tctx
,
2297 "decrypt should fail with WERR_INVALID_SID or WERR_INVALID_PARAMETER");
2298 } else if (wrong
== RIGHT_KEY
) {
2299 torture_assert_werr_equal(tctx
,
2302 "decrypt should succeed!");
2303 } else if (wrong
== WRONG_SID
) {
2304 torture_assert_werr_equal(tctx
,
2306 WERR_INVALID_ACCESS
,
2307 "decrypt should fail with WERR_INVALID_ACCESS");
2309 if (!W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_ACCESS
)
2310 && !W_ERROR_EQUAL(r
.out
.result
, WERR_INVALID_PARAMETER
)) {
2311 torture_assert_werr_equal(tctx
, r
.out
.result
,
2313 "decrypt should fail with WERR_INVALID_ACCESS, WERR_INVALID_PARAMETER or WERR_INVALID_DATA");
2320 static bool test_ServerWrap_decrypt_wrong_magic(struct torture_context
*tctx
,
2321 struct dcerpc_pipe
*p
)
2323 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_MAGIC
);
2326 static bool test_ServerWrap_decrypt_wrong_r2(struct torture_context
*tctx
,
2327 struct dcerpc_pipe
*p
)
2329 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_R2
);
2332 static bool test_ServerWrap_decrypt_wrong_payload_length(struct torture_context
*tctx
,
2333 struct dcerpc_pipe
*p
)
2335 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_PAYLOAD_LENGTH
);
2338 static bool test_ServerWrap_decrypt_short_payload_length(struct torture_context
*tctx
,
2339 struct dcerpc_pipe
*p
)
2341 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, SHORT_PAYLOAD_LENGTH
);
2344 static bool test_ServerWrap_decrypt_zero_payload_length(struct torture_context
*tctx
,
2345 struct dcerpc_pipe
*p
)
2347 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, ZERO_PAYLOAD_LENGTH
);
2350 static bool test_ServerWrap_decrypt_wrong_ciphertext_length(struct torture_context
*tctx
,
2351 struct dcerpc_pipe
*p
)
2353 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_CIPHERTEXT_LENGTH
);
2356 static bool test_ServerWrap_decrypt_short_ciphertext_length(struct torture_context
*tctx
,
2357 struct dcerpc_pipe
*p
)
2359 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, SHORT_CIPHERTEXT_LENGTH
);
2362 static bool test_ServerWrap_decrypt_zero_ciphertext_length(struct torture_context
*tctx
,
2363 struct dcerpc_pipe
*p
)
2365 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, ZERO_CIPHERTEXT_LENGTH
);
2368 static bool test_ServerWrap_encrypt_decrypt_remote_key(struct torture_context
*tctx
,
2369 struct dcerpc_pipe
*p
)
2371 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, RIGHT_KEY
);
2374 static bool test_ServerWrap_encrypt_decrypt_wrong_key(struct torture_context
*tctx
,
2375 struct dcerpc_pipe
*p
)
2377 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_KEY
);
2380 static bool test_ServerWrap_encrypt_decrypt_wrong_sid(struct torture_context
*tctx
,
2381 struct dcerpc_pipe
*p
)
2383 return test_ServerWrap_decrypt_wrong_stuff(tctx
, p
, WRONG_SID
);
2386 struct torture_suite
*torture_rpc_backupkey(TALLOC_CTX
*mem_ctx
)
2388 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "backupkey");
2390 struct torture_rpc_tcase
*tcase
;
2392 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "backupkey",
2393 &ndr_table_backupkey
);
2395 torture_rpc_tcase_add_test(tcase
, "retreive_backup_key_guid",
2396 test_RetrieveBackupKeyGUID
);
2398 torture_rpc_tcase_add_test(tcase
, "restore_guid",
2401 torture_rpc_tcase_add_test(tcase
, "restore_guid version 3",
2402 test_RestoreGUID_v3
);
2404 /* We double the test in order to be sure that we don't mess stuff (ie. freeing static stuff) */
2406 torture_rpc_tcase_add_test(tcase
, "restore_guid_2nd",
2409 torture_rpc_tcase_add_test(tcase
, "unable_to_decrypt_secret",
2410 test_RestoreGUID_ko
);
2412 torture_rpc_tcase_add_test(tcase
, "wrong_user_restore_guid",
2413 test_RestoreGUID_wronguser
);
2415 torture_rpc_tcase_add_test(tcase
, "wrong_version_restore_guid",
2416 test_RestoreGUID_wrongversion
);
2418 torture_rpc_tcase_add_test(tcase
, "bad_magic_on_secret_restore_guid",
2419 test_RestoreGUID_badmagiconsecret
);
2421 torture_rpc_tcase_add_test(tcase
, "bad_hash_on_secret_restore_guid",
2422 test_RestoreGUID_badhashaccesscheck
);
2424 torture_rpc_tcase_add_test(tcase
, "bad_magic_on_accesscheck_restore_guid",
2425 test_RestoreGUID_badmagicaccesscheck
);
2427 torture_rpc_tcase_add_test(tcase
, "bad_cert_guid_restore_guid",
2428 test_RestoreGUID_badcertguid
);
2430 torture_rpc_tcase_add_test(tcase
, "empty_request_restore_guid",
2431 test_RestoreGUID_emptyrequest
);
2433 torture_rpc_tcase_add_test(tcase
, "retreive_backup_key_guid_validate",
2434 test_RetrieveBackupKeyGUID_validate
);
2436 torture_rpc_tcase_add_test(tcase
, "server_wrap_encrypt_decrypt",
2437 test_ServerWrap_encrypt_decrypt
);
2439 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_wrong_keyGUID",
2440 test_ServerWrap_decrypt_wrong_keyGUID
);
2442 torture_rpc_tcase_add_test(tcase
, "server_wrap_empty_request",
2443 test_ServerWrap_decrypt_empty_request
);
2445 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_short_request",
2446 test_ServerWrap_decrypt_short_request
);
2448 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_wrong_magic",
2449 test_ServerWrap_decrypt_wrong_magic
);
2451 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_wrong_r2",
2452 test_ServerWrap_decrypt_wrong_r2
);
2454 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_wrong_payload_length",
2455 test_ServerWrap_decrypt_wrong_payload_length
);
2457 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_short_payload_length",
2458 test_ServerWrap_decrypt_short_payload_length
);
2460 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_zero_payload_length",
2461 test_ServerWrap_decrypt_zero_payload_length
);
2463 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_wrong_ciphertext_length",
2464 test_ServerWrap_decrypt_wrong_ciphertext_length
);
2466 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_short_ciphertext_length",
2467 test_ServerWrap_decrypt_short_ciphertext_length
);
2469 torture_rpc_tcase_add_test(tcase
, "server_wrap_decrypt_zero_ciphertext_length",
2470 test_ServerWrap_decrypt_zero_ciphertext_length
);
2472 torture_rpc_tcase_add_test(tcase
, "server_wrap_encrypt_decrypt_remote_key",
2473 test_ServerWrap_encrypt_decrypt_remote_key
);
2475 torture_rpc_tcase_add_test(tcase
, "server_wrap_encrypt_decrypt_wrong_key",
2476 test_ServerWrap_encrypt_decrypt_wrong_key
);
2478 torture_rpc_tcase_add_test(tcase
, "server_wrap_encrypt_decrypt_wrong_sid",
2479 test_ServerWrap_encrypt_decrypt_wrong_sid
);