Fix the developer O3 build
[Samba.git] / source4 / torture / rpc / backupkey.c
blobc3e990819ec101b2a2316e841d9d7c07d9ecb70e
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for backupkey remote protocol rpc operations
5 Copyright (C) Matthieu Patou 2010-2011
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "../libcli/security/security.h"
23 #include "librpc/gen_ndr/ndr_backupkey_c.h"
24 #include "librpc/gen_ndr/ndr_backupkey.h"
25 #include "librpc/gen_ndr/ndr_lsa_c.h"
26 #include "librpc/gen_ndr/ndr_security.h"
27 #include "torture/rpc/torture_rpc.h"
28 #include "torture/ndr/ndr.h"
29 #include "lib/cmdline/popt_common.h"
30 #include "libcli/auth/proto.h"
31 #include "lib/crypto/arcfour.h"
32 #include <com_err.h>
33 #include <hcrypto/sha.h>
34 #include <system/network.h>
35 #include <hx509.h>
36 #include <der.h>
37 #include <hcrypto/rsa.h>
38 #include <hcrypto/hmac.h>
39 #include <hcrypto/sha.h>
40 #include <hcrypto/evp.h>
42 enum test_wrong {
43 WRONG_MAGIC,
44 WRONG_R2,
45 WRONG_PAYLOAD_LENGTH,
46 WRONG_CIPHERTEXT_LENGTH,
47 SHORT_PAYLOAD_LENGTH,
48 SHORT_CIPHERTEXT_LENGTH,
49 ZERO_PAYLOAD_LENGTH,
50 ZERO_CIPHERTEXT_LENGTH,
51 RIGHT_KEY,
52 WRONG_KEY,
53 WRONG_SID,
56 /* Our very special and valued secret */
57 /* No need to put const as we cast the array in uint8_t
58 * we will get a warning about the discared const
60 static const char secret[] = "tata yoyo mais qu'est ce qu'il y a sous ton grand chapeau ?";
62 /* Get the SID from a user */
63 static struct dom_sid *get_user_sid(struct torture_context *tctx,
64 TALLOC_CTX *mem_ctx,
65 const char *user)
67 struct lsa_ObjectAttribute attr;
68 struct lsa_QosInfo qos;
69 struct lsa_OpenPolicy2 r;
70 struct lsa_Close c;
71 NTSTATUS status;
72 struct policy_handle handle;
73 struct lsa_LookupNames l;
74 struct lsa_TransSidArray sids;
75 struct lsa_RefDomainList *domains = NULL;
76 struct lsa_String lsa_name;
77 uint32_t count = 0;
78 struct dom_sid *result;
79 TALLOC_CTX *tmp_ctx;
80 struct dcerpc_pipe *p2;
81 struct dcerpc_binding_handle *b;
83 const char *domain = cli_credentials_get_domain(cmdline_credentials);
85 torture_assert_ntstatus_ok(tctx,
86 torture_rpc_connection(tctx, &p2, &ndr_table_lsarpc),
87 "could not open lsarpc pipe");
88 b = p2->binding_handle;
90 if (!(tmp_ctx = talloc_new(mem_ctx))) {
91 return NULL;
93 qos.len = 0;
94 qos.impersonation_level = 2;
95 qos.context_mode = 1;
96 qos.effective_only = 0;
98 attr.len = 0;
99 attr.root_dir = NULL;
100 attr.object_name = NULL;
101 attr.attributes = 0;
102 attr.sec_desc = NULL;
103 attr.sec_qos = &qos;
105 r.in.system_name = "\\";
106 r.in.attr = &attr;
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",
114 nt_errstr(status));
115 talloc_free(tmp_ctx);
116 return NULL;
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);
123 return NULL;
126 sids.count = 0;
127 sids.sids = NULL;
129 lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, user);
131 l.in.handle = &handle;
132 l.in.num_names = 1;
133 l.in.names = &lsa_name;
134 l.in.sids = &sids;
135 l.in.level = 1;
136 l.in.count = &count;
137 l.out.count = &count;
138 l.out.sids = &sids;
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",
145 lsa_name.string,
146 nt_errstr(status));
147 talloc_free(tmp_ctx);
148 return NULL;
151 if (domains->count == 0) {
152 return NULL;
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",
166 nt_errstr(status));
167 talloc_free(tmp_ctx);
168 return NULL;
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);
176 return NULL;
179 talloc_free(tmp_ctx);
180 talloc_free(p2);
182 torture_comment(tctx, "Get_user_sid finished\n");
183 return result;
187 * Create a bkrp_encrypted_secret_vX structure
188 * the version depends on the version parameter
189 * the structure is returned as a blob.
190 * The broken flag is to indicate if we want
191 * to create a non conform to specification structre
193 static DATA_BLOB *create_unencryptedsecret(TALLOC_CTX *mem_ctx,
194 bool broken,
195 int version)
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;
201 if (version == 2) {
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)) {
213 return NULL;
216 if (broken) {
217 /* The magic value is correctly set by the NDR push
218 * but we want to test the behavior of the server
219 * if a differrent value is provided
221 ((uint8_t*)blob->data)[4] = 79; /* A great year !!! */
225 if (version == 3) {
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)) {
237 return NULL;
240 if (broken) {
242 * The magic value is correctly set by the NDR push
243 * but we want to test the behavior of the server
244 * if a differrent value is provided
246 ((uint8_t*)blob->data)[4] = 79; /* A great year !!! */
249 talloc_free(tmp_ctx);
250 return blob;
254 * Create an access check structure, the format depends on the version parameter.
255 * If broken is specified then we create a stucture that isn't conform to the
256 * specification.
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,
262 TALLOC_CTX *mem_ctx,
263 const char *user,
264 bool broken,
265 uint32_t version)
267 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
268 DATA_BLOB *blob = talloc_zero(mem_ctx, DATA_BLOB);
269 enum ndr_err_code ndr_err;
270 const struct dom_sid *sid = get_user_sid(tctx, tmp_ctx, user);
272 if (sid == NULL) {
273 return NULL;
276 if (version == 2) {
277 struct bkrp_access_check_v2 access_struct;
278 struct sha sctx;
279 uint8_t nonce[32];
281 ZERO_STRUCT(access_struct);
282 generate_random_buffer(nonce, sizeof(nonce));
283 access_struct.nonce_len = sizeof(nonce);
284 access_struct.nonce = nonce;
285 access_struct.sid = *sid;
287 ndr_err = ndr_push_struct_blob(blob, blob, &access_struct,
288 (ndr_push_flags_fn_t)ndr_push_bkrp_access_check_v2);
289 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
290 return NULL;
294 * We pushed the whole structure including a null hash
295 * but the hash need to be calculated only up to the hash field
296 * so we reduce the size of what has to be calculated
299 SHA1_Init(&sctx);
300 SHA1_Update(&sctx, blob->data,
301 blob->length - sizeof(access_struct.hash));
302 SHA1_Final(blob->data + blob->length - sizeof(access_struct.hash),
303 &sctx);
305 /* Altering the SHA */
306 if (broken) {
307 blob->data[blob->length - 1]++;
311 if (version == 3) {
312 struct bkrp_access_check_v3 access_struct;
313 struct hc_sha512state sctx;
314 uint8_t nonce[32];
316 ZERO_STRUCT(access_struct);
317 generate_random_buffer(nonce, sizeof(nonce));
318 access_struct.nonce_len = sizeof(nonce);
319 access_struct.nonce = nonce;
320 access_struct.sid = *sid;
322 ndr_err = ndr_push_struct_blob(blob, blob, &access_struct,
323 (ndr_push_flags_fn_t)ndr_push_bkrp_access_check_v3);
324 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
325 return NULL;
328 /*We pushed the whole structure including a null hash
329 * but the hash need to be calculated only up to the hash field
330 * so we reduce the size of what has to be calculated
333 SHA512_Init(&sctx);
334 SHA512_Update(&sctx, blob->data,
335 blob->length - sizeof(access_struct.hash));
336 SHA512_Final(blob->data + blob->length - sizeof(access_struct.hash),
337 &sctx);
339 /* Altering the SHA */
340 if (broken) {
341 blob->data[blob->length -1]++;
344 talloc_free(tmp_ctx);
345 return blob;
349 static DATA_BLOB *encrypt_blob(struct torture_context *tctx,
350 TALLOC_CTX *mem_ctx,
351 DATA_BLOB *key,
352 DATA_BLOB *iv,
353 DATA_BLOB *to_encrypt,
354 const AlgorithmIdentifier *alg)
356 hx509_crypto crypto;
357 hx509_context hctx;
358 heim_octet_string ivos;
359 heim_octet_string *encrypted;
360 DATA_BLOB *blob = talloc_zero(mem_ctx, DATA_BLOB);
361 int res;
363 ivos.data = talloc_array(mem_ctx, uint8_t, iv->length);
364 ivos.length = iv->length;
365 memcpy(ivos.data, iv->data, iv->length);
367 hx509_context_init(&hctx);
368 res = hx509_crypto_init(hctx, NULL, &alg->algorithm, &crypto);
369 if (res) {
370 torture_comment(tctx,
371 "error while doing the init of the crypto object\n");
372 hx509_context_free(&hctx);
373 return NULL;
375 res = hx509_crypto_set_key_data(crypto, key->data, key->length);
376 if (res) {
377 torture_comment(tctx,
378 "error while setting the key of the crypto object\n");
379 hx509_context_free(&hctx);
380 return NULL;
383 hx509_crypto_set_padding(crypto, HX509_CRYPTO_PADDING_NONE);
384 res = hx509_crypto_encrypt(crypto,
385 to_encrypt->data,
386 to_encrypt->length,
387 &ivos,
388 &encrypted);
389 if (res) {
390 torture_comment(tctx, "error while encrypting\n");
391 hx509_crypto_destroy(crypto);
392 hx509_context_free(&hctx);
393 return NULL;
396 *blob = data_blob_talloc(blob, encrypted->data, encrypted->length);
397 der_free_octet_string(encrypted);
398 free(encrypted);
399 hx509_crypto_destroy(crypto);
400 hx509_context_free(&hctx);
401 return blob;
405 * Certs used for this protocol have a GUID in the issuer_uniq_id field.
406 * This function fetch it.
408 static struct GUID *get_cert_guid(struct torture_context *tctx,
409 TALLOC_CTX *mem_ctx,
410 uint8_t *cert_data,
411 uint32_t cert_len)
413 hx509_context hctx;
414 hx509_cert cert;
415 heim_bit_string subjectuniqid;
416 DATA_BLOB data;
417 int hret;
418 uint32_t size;
419 struct GUID *guid = talloc_zero(mem_ctx, struct GUID);
420 NTSTATUS status;
422 hx509_context_init(&hctx);
424 hret = hx509_cert_init_data(hctx, cert_data, cert_len, &cert);
425 if (hret) {
426 torture_comment(tctx, "error while loading the cert\n");
427 hx509_context_free(&hctx);
428 return NULL;
430 hret = hx509_cert_get_issuer_unique_id(hctx, cert, &subjectuniqid);
431 if (hret) {
432 torture_comment(tctx, "error while getting the issuer_uniq_id\n");
433 hx509_cert_free(cert);
434 hx509_context_free(&hctx);
435 return NULL;
438 /* The subjectuniqid is a bit string,
439 * which means that the real size has to be divided by 8
440 * to have the number of bytes
442 hx509_cert_free(cert);
443 hx509_context_free(&hctx);
444 size = subjectuniqid.length / 8;
445 data = data_blob_const(subjectuniqid.data, size);
447 status = GUID_from_data_blob(&data, guid);
448 der_free_bit_string(&subjectuniqid);
449 if (!NT_STATUS_IS_OK(status)) {
450 return NULL;
453 return guid;
457 * Encrypt a blob with the private key of the certificate
458 * passed as a parameter.
460 static DATA_BLOB *encrypt_blob_pk(struct torture_context *tctx,
461 TALLOC_CTX *mem_ctx,
462 uint8_t *cert_data,
463 uint32_t cert_len,
464 DATA_BLOB *to_encrypt)
466 hx509_context hctx;
467 hx509_cert cert;
468 heim_octet_string secretdata;
469 heim_octet_string encrypted;
470 heim_oid encryption_oid;
471 DATA_BLOB *blob;
472 int hret;
474 hx509_context_init(&hctx);
476 hret = hx509_cert_init_data(hctx, cert_data, cert_len, &cert);
477 if (hret) {
478 torture_comment(tctx, "error while loading the cert\n");
479 hx509_context_free(&hctx);
480 return NULL;
483 secretdata.data = to_encrypt->data;
484 secretdata.length = to_encrypt->length;
485 hret = hx509_cert_public_encrypt(hctx, &secretdata,
486 cert, &encryption_oid,
487 &encrypted);
488 hx509_cert_free(cert);
489 hx509_context_free(&hctx);
490 if (hret) {
491 torture_comment(tctx, "error while encrypting\n");
492 return NULL;
495 blob = talloc_zero(mem_ctx, DATA_BLOB);
496 if (blob == NULL) {
497 der_free_oid(&encryption_oid);
498 der_free_octet_string(&encrypted);
499 return NULL;
502 *blob = data_blob_talloc(blob, encrypted.data, encrypted.length);
503 der_free_octet_string(&encrypted);
504 der_free_oid(&encryption_oid);
505 if (blob->data == NULL) {
506 return NULL;
509 return blob;
513 static struct bkrp_BackupKey *createRetreiveBackupKeyGUIDStruct(struct torture_context *tctx,
514 struct dcerpc_pipe *p, int version, DATA_BLOB *out)
516 struct dcerpc_binding *binding;
517 struct bkrp_client_side_wrapped data;
518 struct GUID *g = talloc(tctx, struct GUID);
519 struct bkrp_BackupKey *r = talloc_zero(tctx, struct bkrp_BackupKey);
520 enum ndr_err_code ndr_err;
521 DATA_BLOB blob;
522 NTSTATUS status;
524 if (r == NULL) {
525 return NULL;
528 binding = dcerpc_binding_dup(tctx, p->binding);
529 if (binding == NULL) {
530 return NULL;
533 status = dcerpc_binding_set_flags(binding, DCERPC_SEAL|DCERPC_AUTH_SPNEGO, 0);
534 if (!NT_STATUS_IS_OK(status)) {
535 return NULL;
538 ZERO_STRUCT(data);
539 status = GUID_from_string(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID, g);
540 if (!NT_STATUS_IS_OK(status)) {
541 return NULL;
544 r->in.guidActionAgent = g;
545 data.version = version;
546 ndr_err = ndr_push_struct_blob(&blob, tctx, &data,
547 (ndr_push_flags_fn_t)ndr_push_bkrp_client_side_wrapped);
548 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
549 return NULL;
551 r->in.data_in = blob.data;
552 r->in.data_in_len = blob.length;
553 r->out.data_out = &out->data;
554 r->out.data_out_len = talloc(r, uint32_t);
555 return r;
558 static struct bkrp_BackupKey *createRestoreGUIDStruct(struct torture_context *tctx,
559 struct dcerpc_pipe *p, int version, DATA_BLOB *out,
560 bool norevert,
561 bool broken_version,
562 bool broken_user,
563 bool broken_magic_secret,
564 bool broken_magic_access,
565 bool broken_hash_access,
566 bool broken_cert_guid)
568 struct dcerpc_binding_handle *b = p->binding_handle;
569 struct bkrp_client_side_wrapped data;
570 DATA_BLOB *xs;
571 DATA_BLOB *sec;
572 DATA_BLOB *enc_sec = NULL;
573 DATA_BLOB *enc_xs = NULL;
574 DATA_BLOB *blob2;
575 DATA_BLOB enc_sec_reverted;
576 DATA_BLOB des3_key;
577 DATA_BLOB aes_key;
578 DATA_BLOB iv;
579 DATA_BLOB out_blob;
580 struct GUID *guid, *g;
581 int t;
582 uint32_t size;
583 enum ndr_err_code ndr_err;
584 NTSTATUS status;
585 const char *user;
586 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, version, &out_blob);
587 if (r == NULL) {
588 return NULL;
591 if (broken_user) {
592 /* we take a fake user*/
593 user = "guest";
594 } else {
595 user = cli_credentials_get_username(cmdline_credentials);
599 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
600 "Get GUID");
601 torture_assert_werr_ok(tctx, r->out.result,
602 "Get GUID");
605 * We have to set it outside of the function createRetreiveBackupKeyGUIDStruct
606 * the len of the blob, this is due to the fact that they don't have the
607 * same size (one is 32bits the other 64bits)
609 out_blob.length = *r->out.data_out_len;
611 sec = create_unencryptedsecret(tctx, broken_magic_secret, version);
612 if (sec == NULL) {
613 return NULL;
616 xs = create_access_check(tctx, p, tctx, user, broken_hash_access, version);
617 if (xs == NULL) {
618 return NULL;
621 if (broken_magic_access){
622 /* The start of the access_check structure contains the
623 * GUID of the certificate
625 xs->data[0]++;
628 enc_sec = encrypt_blob_pk(tctx, tctx, out_blob.data, out_blob.length, sec);
629 if (!enc_sec) {
630 return NULL;
632 enc_sec_reverted.data = talloc_array(tctx, uint8_t, enc_sec->length);
633 if (enc_sec_reverted.data == NULL) {
634 return NULL;
636 enc_sec_reverted.length = enc_sec->length;
639 * We DO NOT revert the array on purpose it's in order to check that
640 * when the server is not able to decrypt then it answer the correct error
642 if (norevert) {
643 for(t=0; t< enc_sec->length; t++) {
644 enc_sec_reverted.data[t] = ((uint8_t*)enc_sec->data)[t];
646 } else {
647 for(t=0; t< enc_sec->length; t++) {
648 enc_sec_reverted.data[t] = ((uint8_t*)enc_sec->data)[enc_sec->length - t -1];
652 size = sec->length;
653 if (version ==2) {
654 const AlgorithmIdentifier *alg = hx509_crypto_des_rsdi_ede3_cbc();
655 iv.data = sec->data+(size - 8);
656 iv.length = 8;
658 des3_key.data = sec->data+(size - 32);
659 des3_key.length = 24;
661 enc_xs = encrypt_blob(tctx, tctx, &des3_key, &iv, xs, alg);
663 if (version == 3) {
664 const AlgorithmIdentifier *alg = hx509_crypto_aes256_cbc();
665 iv.data = sec->data+(size-16);
666 iv.length = 16;
668 aes_key.data = sec->data+(size-48);
669 aes_key.length = 32;
671 enc_xs = encrypt_blob(tctx, tctx, &aes_key, &iv, xs, alg);
674 if (!enc_xs) {
675 return NULL;
678 /* To cope with the fact that heimdal do padding at the end for the moment */
679 enc_xs->length = xs->length;
681 guid = get_cert_guid(tctx, tctx, out_blob.data, out_blob.length);
682 if (guid == NULL) {
683 return NULL;
686 if (broken_version) {
687 data.version = 1;
688 } else {
689 data.version = version;
692 data.guid = *guid;
693 data.encrypted_secret = enc_sec_reverted.data;
694 data.access_check = enc_xs->data;
695 data.encrypted_secret_len = enc_sec->length;
696 data.access_check_len = enc_xs->length;
698 /* We want the blob to persist after this function so we don't
699 * allocate it in the stack
701 blob2 = talloc(tctx, DATA_BLOB);
702 if (blob2 == NULL) {
703 return NULL;
706 ndr_err = ndr_push_struct_blob(blob2, tctx, &data,
707 (ndr_push_flags_fn_t)ndr_push_bkrp_client_side_wrapped);
708 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
709 return NULL;
712 if (broken_cert_guid) {
713 blob2->data[12]++;
716 ZERO_STRUCT(*r);
718 g = talloc(tctx, struct GUID);
719 if (g == NULL) {
720 return NULL;
723 status = GUID_from_string(BACKUPKEY_RESTORE_GUID, g);
724 if (!NT_STATUS_IS_OK(status)) {
725 return NULL;
728 r->in.guidActionAgent = g;
729 r->in.data_in = blob2->data;
730 r->in.data_in_len = blob2->length;
731 r->in.param = 0;
732 r->out.data_out = &(out->data);
733 r->out.data_out_len = talloc(r, uint32_t);
734 return r;
737 /* Check that we are able to receive the certificate of the DCs
738 * used for client wrap version of the backup key protocol
740 static bool test_RetreiveBackupKeyGUID(struct torture_context *tctx,
741 struct dcerpc_pipe *p)
743 struct dcerpc_binding_handle *b = p->binding_handle;
744 DATA_BLOB out_blob;
745 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
746 enum dcerpc_AuthType auth_type;
747 enum dcerpc_AuthLevel auth_level;
749 if (r == NULL) {
750 return false;
753 dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
755 if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
756 torture_assert_ntstatus_ok(tctx,
757 dcerpc_bkrp_BackupKey_r(b, tctx, r),
758 "Get GUID");
760 out_blob.length = *r->out.data_out_len;
761 torture_assert_werr_equal(tctx,
762 r->out.result,
763 WERR_OK,
764 "Wrong dce/rpc error code");
765 } else {
766 torture_assert_ntstatus_equal(tctx,
767 dcerpc_bkrp_BackupKey_r(b, tctx, r),
768 NT_STATUS_ACCESS_DENIED,
769 "Get GUID");
771 return true;
774 /* Test to check the failure to recover a secret because the
775 * secret blob is not reversed
777 static bool test_RestoreGUID_ko(struct torture_context *tctx,
778 struct dcerpc_pipe *p)
780 enum ndr_err_code ndr_err;
781 struct dcerpc_binding_handle *b = p->binding_handle;
782 DATA_BLOB out_blob;
783 struct bkrp_client_side_unwrapped resp;
784 enum dcerpc_AuthType auth_type;
785 enum dcerpc_AuthLevel auth_level;
787 dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
789 if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
790 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
791 true, false, false, false, false, false, false);
792 torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
793 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
794 out_blob.length = *r->out.data_out_len;
795 ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
796 torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
797 torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAM, "Wrong error code");
798 } else {
799 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
800 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
801 NT_STATUS_ACCESS_DENIED, "Get GUID");
803 return true;
806 static bool test_RestoreGUID_wrongversion(struct torture_context *tctx,
807 struct dcerpc_pipe *p)
809 enum ndr_err_code ndr_err;
810 struct dcerpc_binding_handle *b = p->binding_handle;
811 DATA_BLOB out_blob;
812 struct bkrp_client_side_unwrapped resp;
813 enum dcerpc_AuthType auth_type;
814 enum dcerpc_AuthLevel auth_level;
816 dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
818 if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
819 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
820 false, true, false, false, false, false, false);
821 torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
822 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
823 out_blob.length = *r->out.data_out_len;
824 ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
825 torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
826 torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAM, "Wrong error code on wrong version");
827 } else {
828 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
829 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
830 NT_STATUS_ACCESS_DENIED, "Get GUID");
832 return true;
835 static bool test_RestoreGUID_wronguser(struct torture_context *tctx,
836 struct dcerpc_pipe *p)
838 enum ndr_err_code ndr_err;
839 struct dcerpc_binding_handle *b = p->binding_handle;
840 DATA_BLOB out_blob;
841 struct bkrp_client_side_unwrapped resp;
842 enum dcerpc_AuthType auth_type;
843 enum dcerpc_AuthLevel auth_level;
845 dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
847 if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
848 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
849 false, false, true, false, false, false, false);
850 torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
851 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
852 out_blob.length = *r->out.data_out_len;
853 ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
854 torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
855 torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_ACCESS, "Restore GUID");
856 } else {
857 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
858 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
859 NT_STATUS_ACCESS_DENIED, "Get GUID");
861 return true;
864 static bool test_RestoreGUID_v3(struct torture_context *tctx,
865 struct dcerpc_pipe *p)
867 enum ndr_err_code ndr_err;
868 struct dcerpc_binding_handle *b = p->binding_handle;
869 DATA_BLOB out_blob;
870 struct bkrp_client_side_unwrapped resp;
871 enum dcerpc_AuthType auth_type;
872 enum dcerpc_AuthLevel auth_level;
874 dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
876 if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
877 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob,
878 false, false, false, false, false, false, false);
879 torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
880 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
881 out_blob.length = *r->out.data_out_len;
882 ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
883 torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 1, "Unable to unmarshall bkrp_client_side_unwrapped");
884 torture_assert_werr_equal(tctx, r->out.result, WERR_OK, "Restore GUID");
885 torture_assert_str_equal(tctx, (char*)resp.secret.data, secret, "Wrong secret");
886 } else {
887 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
888 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
889 NT_STATUS_ACCESS_DENIED, "Get GUID");
891 return true;
894 static bool test_RestoreGUID(struct torture_context *tctx,
895 struct dcerpc_pipe *p)
897 struct dcerpc_binding_handle *b = p->binding_handle;
898 DATA_BLOB out_blob;
899 struct bkrp_client_side_unwrapped resp;
900 enum dcerpc_AuthType auth_type;
901 enum dcerpc_AuthLevel auth_level;
903 dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
905 if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
906 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
907 false, false, false, false, false, false, false);
908 torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
909 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
910 out_blob.length = *r->out.data_out_len;
911 torture_assert_werr_equal(tctx, r->out.result, WERR_OK, "Restore GUID");
912 torture_assert_ndr_err_equal(tctx,
913 ndr_pull_struct_blob(&out_blob, tctx, &resp,
914 (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped),
915 NDR_ERR_SUCCESS,
916 "Unable to unmarshall bkrp_client_side_unwrapped");
917 torture_assert_str_equal(tctx, (char*)resp.secret.data, secret, "Wrong secret");
918 } else {
919 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
920 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
921 NT_STATUS_ACCESS_DENIED, "Get GUID");
923 return true;
926 static bool test_RestoreGUID_badmagiconsecret(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;
931 DATA_BLOB out_blob;
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, 3, &out_blob,
940 false, false, false, true, 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_DATA, "Wrong error code while providing bad magic in secret");
947 } else {
948 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(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");
952 return true;
955 static bool test_RestoreGUID_emptyrequest(struct torture_context *tctx,
956 struct dcerpc_pipe *p)
958 struct dcerpc_binding_handle *b = p->binding_handle;
959 DATA_BLOB out_blob;
960 enum dcerpc_AuthType auth_type;
961 enum dcerpc_AuthLevel auth_level;
963 dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
965 if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
966 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob,
967 false, false, false, true, false, false, true);
969 torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
970 r->in.data_in = talloc(tctx, uint8_t);
971 r->in.data_in_len = 0;
972 r->in.param = 0;
973 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
974 out_blob.length = *r->out.data_out_len;
975 torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAM, "Bad error code on wrong has in access check");
976 } else {
977 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
978 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
979 NT_STATUS_ACCESS_DENIED, "Get GUID");
981 return true;
984 static bool test_RestoreGUID_badcertguid(struct torture_context *tctx,
985 struct dcerpc_pipe *p)
987 enum ndr_err_code ndr_err;
988 struct dcerpc_binding_handle *b = p->binding_handle;
989 DATA_BLOB out_blob;
990 struct bkrp_client_side_unwrapped resp;
991 enum dcerpc_AuthType auth_type;
992 enum dcerpc_AuthLevel auth_level;
994 dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
996 if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
997 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob,
998 false, false, false, false, false, false, true);
999 torture_assert(tctx, r != NULL, "createRestoreGUIDStruct() failed");
1000 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
1001 out_blob.length = *r->out.data_out_len;
1002 ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
1003 torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1006 * Windows 2012R2 has, presumably, a programming error
1007 * returning an NTSTATUS code on this interface
1009 if (W_ERROR_V(r->out.result) != NT_STATUS_V(NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1010 torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Bad error code on wrong has in access check");
1012 } else {
1013 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
1014 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
1015 NT_STATUS_ACCESS_DENIED, "Get GUID");
1017 return true;
1020 static bool test_RestoreGUID_badmagicaccesscheck(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;
1025 DATA_BLOB out_blob;
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, 2, &out_blob,
1034 false, false, false, false, true, 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, "Bad error code on wrong has in access check");
1041 } else {
1042 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(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");
1046 return true;
1049 static bool test_RestoreGUID_badhashaccesscheck(struct torture_context *tctx,
1050 struct dcerpc_pipe *p)
1052 enum ndr_err_code ndr_err;
1053 struct dcerpc_binding_handle *b = p->binding_handle;
1054 DATA_BLOB out_blob;
1055 struct bkrp_client_side_unwrapped resp;
1056 enum dcerpc_AuthType auth_type;
1057 enum dcerpc_AuthLevel auth_level;
1059 dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1061 if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1062 struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
1063 false, false, false, false, false, true, false);
1064 torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
1065 torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
1066 out_blob.length = *r->out.data_out_len;
1067 ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
1068 torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1069 torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Bad error code on wrong has in access check");
1070 } else {
1071 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
1072 torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
1073 NT_STATUS_ACCESS_DENIED, "Get GUID");
1075 return true;
1079 * Check that the RSA modulus in the certificate of the DCs has 2048 bits.
1081 static bool test_RetreiveBackupKeyGUID_2048bits(struct torture_context *tctx,
1082 struct dcerpc_pipe *p)
1084 struct dcerpc_binding_handle *b = p->binding_handle;
1085 DATA_BLOB out_blob;
1086 struct bkrp_BackupKey *r = createRetreiveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
1087 enum dcerpc_AuthType auth_type;
1088 enum dcerpc_AuthLevel auth_level;
1090 hx509_context hctx;
1091 int hret;
1092 hx509_cert cert;
1093 SubjectPublicKeyInfo spki;
1094 RSA *rsa;
1095 int RSA_returned_bits;
1097 torture_assert(tctx, r != NULL, "createRetreiveBackupKeyGUIDStruct failed");
1099 hx509_context_init(&hctx);
1101 if (r == NULL) {
1102 return false;
1105 dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1107 if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1108 const unsigned char *spki_spk_data;
1109 torture_assert_ntstatus_ok(tctx,
1110 dcerpc_bkrp_BackupKey_r(b, tctx, r),
1111 "Get GUID");
1113 torture_assert_werr_ok(tctx, r->out.result,
1114 "Get GUID");
1116 out_blob.length = *r->out.data_out_len;
1118 hret = hx509_cert_init_data(hctx, out_blob.data, out_blob.length, &cert);
1119 torture_assert_int_equal(tctx, hret, 0, "hx509_cert_init_data failed");
1121 hret = hx509_cert_get_SPKI(hctx, cert , &spki);
1122 torture_assert_int_equal(tctx, hret, 0, "hx509_cert_get_SPKI failed");
1124 /* We must take a copy, as d2i_RSAPublicKey *changes* the input parameter */
1125 spki_spk_data = spki.subjectPublicKey.data;
1126 rsa = d2i_RSAPublicKey(NULL, &spki_spk_data, spki.subjectPublicKey.length / 8);
1127 torture_assert_int_equal(tctx, rsa != NULL, 1, "d2i_RSAPublicKey failed");
1129 RSA_returned_bits = BN_num_bits(rsa->n);
1130 torture_assert_int_equal(tctx,
1131 RSA_returned_bits,
1132 2048,
1133 "RSA Key doesn't have 2048 bits");
1135 RSA_free(rsa);
1138 * Because we prevented spki from being changed above,
1139 * we can now safely call this to free it
1141 free_SubjectPublicKeyInfo(&spki);
1142 hx509_cert_free(cert);
1143 hx509_context_free(&hctx);
1145 } else {
1146 torture_assert_ntstatus_equal(tctx,
1147 dcerpc_bkrp_BackupKey_r(b, tctx, r),
1148 NT_STATUS_ACCESS_DENIED,
1149 "Get GUID");
1151 return true;
1154 static bool test_ServerWrap_encrypt_decrypt(struct torture_context *tctx,
1155 struct dcerpc_pipe *p)
1157 struct bkrp_BackupKey r;
1158 struct GUID guid;
1159 DATA_BLOB plaintext = data_blob_const(secret, sizeof(secret));
1160 DATA_BLOB encrypted;
1161 uint32_t enclen;
1162 DATA_BLOB decrypted;
1163 uint32_t declen;
1164 struct dcerpc_binding_handle *b = p->binding_handle;
1165 enum dcerpc_AuthType auth_type;
1166 enum dcerpc_AuthLevel auth_level;
1167 ZERO_STRUCT(r);
1169 dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1171 /* Encrypt */
1172 torture_assert_ntstatus_ok(tctx,
1173 GUID_from_string(BACKUPKEY_BACKUP_GUID, &guid),
1174 "obtain GUID");
1176 r.in.guidActionAgent = &guid;
1177 r.in.data_in = plaintext.data;
1178 r.in.data_in_len = plaintext.length;
1179 r.in.param = 0;
1180 r.out.data_out = &encrypted.data;
1181 r.out.data_out_len = &enclen;
1182 if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1183 torture_assert_ntstatus_ok(tctx,
1184 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1185 "encrypt");
1186 } else {
1187 torture_assert_ntstatus_equal(tctx,
1188 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1189 NT_STATUS_ACCESS_DENIED,
1190 "encrypt");
1191 return true;
1193 torture_assert_werr_ok(tctx,
1194 r.out.result,
1195 "encrypt");
1196 encrypted.length = *r.out.data_out_len;
1198 /* Decrypt */
1199 torture_assert_ntstatus_ok(tctx,
1200 GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1201 "obtain GUID");
1203 r.in.guidActionAgent = &guid;
1204 r.in.data_in = encrypted.data;
1205 r.in.data_in_len = encrypted.length;
1206 r.in.param = 0;
1207 r.out.data_out = &(decrypted.data);
1208 r.out.data_out_len = &declen;
1209 torture_assert_ntstatus_ok(tctx,
1210 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1211 "decrypt");
1212 torture_assert_werr_ok(tctx,
1213 r.out.result,
1214 "decrypt");
1215 decrypted.length = *r.out.data_out_len;
1217 /* Compare */
1218 torture_assert_data_blob_equal(tctx, plaintext, decrypted, "Decrypt failed");
1220 /* Decrypt */
1221 torture_assert_ntstatus_ok(tctx,
1222 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1223 "obtain GUID");
1225 r.in.guidActionAgent = &guid;
1226 r.in.data_in = encrypted.data;
1227 r.in.data_in_len = encrypted.length;
1228 r.in.param = 0;
1229 r.out.data_out = &(decrypted.data);
1230 r.out.data_out_len = &declen;
1231 torture_assert_ntstatus_ok(tctx,
1232 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1233 "decrypt");
1234 torture_assert_werr_ok(tctx,
1235 r.out.result,
1236 "decrypt");
1237 decrypted.length = *r.out.data_out_len;
1239 /* Compare */
1240 torture_assert_data_blob_equal(tctx, plaintext, decrypted, "Decrypt failed");
1241 return true;
1244 static bool test_ServerWrap_decrypt_wrong_keyGUID(struct torture_context *tctx,
1245 struct dcerpc_pipe *p)
1247 struct bkrp_BackupKey r;
1248 struct GUID guid;
1249 DATA_BLOB plaintext = data_blob_const(secret, sizeof(secret));
1250 DATA_BLOB encrypted;
1251 uint32_t enclen;
1252 DATA_BLOB decrypted;
1253 uint32_t declen;
1254 struct dcerpc_binding_handle *b = p->binding_handle;
1255 enum ndr_err_code ndr_err;
1256 struct bkrp_server_side_wrapped server_side_wrapped;
1257 enum dcerpc_AuthType auth_type;
1258 enum dcerpc_AuthLevel auth_level;
1259 ZERO_STRUCT(r);
1261 dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1263 /* Encrypt */
1264 torture_assert_ntstatus_ok(tctx,
1265 GUID_from_string(BACKUPKEY_BACKUP_GUID, &guid),
1266 "obtain GUID");
1268 r.in.guidActionAgent = &guid;
1269 r.in.data_in = plaintext.data;
1270 r.in.data_in_len = plaintext.length;
1271 r.in.param = 0;
1272 r.out.data_out = &encrypted.data;
1273 r.out.data_out_len = &enclen;
1274 if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1275 torture_assert_ntstatus_ok(tctx,
1276 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1277 "encrypt");
1278 } else {
1279 torture_assert_ntstatus_equal(tctx,
1280 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1281 NT_STATUS_ACCESS_DENIED,
1282 "encrypt");
1283 return true;
1285 torture_assert_werr_ok(tctx,
1286 r.out.result,
1287 "encrypt");
1288 encrypted.length = *r.out.data_out_len;
1290 ndr_err = ndr_pull_struct_blob(&encrypted, tctx, &server_side_wrapped,
1291 (ndr_pull_flags_fn_t)ndr_pull_bkrp_server_side_wrapped);
1292 torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "pull of server_side_wrapped");
1294 /* Change the GUID */
1295 server_side_wrapped.guid = GUID_random();
1297 ndr_err = ndr_push_struct_blob(&encrypted, tctx, &server_side_wrapped,
1298 (ndr_push_flags_fn_t)ndr_push_bkrp_server_side_wrapped);
1299 torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "push of server_side_wrapped");
1301 /* Decrypt */
1302 torture_assert_ntstatus_ok(tctx,
1303 GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1304 "obtain GUID");
1306 r.in.guidActionAgent = &guid;
1307 r.in.data_in = encrypted.data;
1308 r.in.data_in_len = encrypted.length;
1309 r.in.param = 0;
1310 r.out.data_out = &(decrypted.data);
1311 r.out.data_out_len = &declen;
1312 torture_assert_ntstatus_ok(tctx,
1313 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1314 "decrypt");
1315 torture_assert_werr_equal(tctx,
1316 r.out.result,
1317 WERR_INVALID_DATA,
1318 "decrypt should fail with WERR_INVALID_DATA");
1320 /* Decrypt */
1321 torture_assert_ntstatus_ok(tctx,
1322 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1323 "obtain GUID");
1325 r.in.guidActionAgent = &guid;
1326 r.in.data_in = encrypted.data;
1327 r.in.data_in_len = encrypted.length;
1328 r.in.param = 0;
1329 r.out.data_out = &(decrypted.data);
1330 r.out.data_out_len = &declen;
1331 torture_assert_ntstatus_ok(tctx,
1332 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1333 "decrypt");
1334 torture_assert_werr_equal(tctx,
1335 r.out.result,
1336 WERR_INVALID_DATA,
1337 "decrypt should fail with WERR_INVALID_DATA");
1339 return true;
1342 static bool test_ServerWrap_decrypt_empty_request(struct torture_context *tctx,
1343 struct dcerpc_pipe *p)
1345 struct bkrp_BackupKey r;
1346 struct GUID guid;
1347 DATA_BLOB decrypted;
1348 uint32_t declen;
1349 struct dcerpc_binding_handle *b = p->binding_handle;
1350 uint8_t short_request[4] = { 1, 0, 0, 0 };
1351 enum dcerpc_AuthType auth_type;
1352 enum dcerpc_AuthLevel auth_level;
1353 ZERO_STRUCT(r);
1355 dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1357 /* Decrypt */
1358 torture_assert_ntstatus_ok(tctx,
1359 GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1360 "obtain GUID");
1362 r.in.guidActionAgent = &guid;
1363 r.in.data_in = short_request;
1364 r.in.data_in_len = 0;
1365 r.in.param = 0;
1366 r.out.data_out = &(decrypted.data);
1367 r.out.data_out_len = &declen;
1368 if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1369 torture_assert_ntstatus_ok(tctx,
1370 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1371 "encrypt");
1372 } else {
1373 torture_assert_ntstatus_equal(tctx,
1374 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1375 NT_STATUS_ACCESS_DENIED,
1376 "encrypt");
1377 return true;
1379 torture_assert_werr_equal(tctx,
1380 r.out.result,
1381 WERR_INVALID_PARAM,
1382 "decrypt should fail with WERR_INVALID_PARAM");
1384 /* Decrypt */
1385 torture_assert_ntstatus_ok(tctx,
1386 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1387 "obtain GUID");
1389 r.in.guidActionAgent = &guid;
1390 r.in.data_in = short_request;
1391 r.in.data_in_len = 0;
1392 r.in.param = 0;
1393 r.out.data_out = &(decrypted.data);
1394 r.out.data_out_len = &declen;
1395 torture_assert_ntstatus_ok(tctx,
1396 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1397 "decrypt");
1398 torture_assert_werr_equal(tctx,
1399 r.out.result,
1400 WERR_INVALID_PARAM,
1401 "decrypt should fail with WERR_INVALID_PARAM");
1403 /* Decrypt */
1404 torture_assert_ntstatus_ok(tctx,
1405 GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1406 "obtain GUID");
1408 r.in.guidActionAgent = &guid;
1409 r.in.data_in = NULL;
1410 r.in.data_in_len = 0;
1411 r.in.param = 0;
1412 r.out.data_out = &(decrypted.data);
1413 r.out.data_out_len = &declen;
1414 torture_assert_ntstatus_equal(tctx,
1415 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1416 NT_STATUS_INVALID_PARAMETER_MIX,
1417 "decrypt");
1419 /* Decrypt */
1420 torture_assert_ntstatus_ok(tctx,
1421 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1422 "obtain GUID");
1424 r.in.guidActionAgent = &guid;
1425 r.in.data_in = NULL;
1426 r.in.data_in_len = 0;
1427 r.in.param = 0;
1428 r.out.data_out = &(decrypted.data);
1429 r.out.data_out_len = &declen;
1430 torture_assert_ntstatus_equal(tctx,
1431 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1432 NT_STATUS_INVALID_PARAMETER_MIX,
1433 "decrypt");
1435 return true;
1439 static bool test_ServerWrap_decrypt_short_request(struct torture_context *tctx,
1440 struct dcerpc_pipe *p)
1442 struct bkrp_BackupKey r;
1443 struct GUID guid;
1444 DATA_BLOB decrypted;
1445 uint32_t declen;
1446 struct dcerpc_binding_handle *b = p->binding_handle;
1447 uint8_t short_request[4] = { 1, 0, 0, 0 };
1448 enum dcerpc_AuthType auth_type;
1449 enum dcerpc_AuthLevel auth_level;
1450 ZERO_STRUCT(r);
1452 dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1454 /* Decrypt */
1455 torture_assert_ntstatus_ok(tctx,
1456 GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1457 "obtain GUID");
1459 r.in.guidActionAgent = &guid;
1460 r.in.data_in = short_request;
1461 r.in.data_in_len = 4;
1462 r.in.param = 0;
1463 r.out.data_out = &(decrypted.data);
1464 r.out.data_out_len = &declen;
1465 if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1466 torture_assert_ntstatus_ok(tctx,
1467 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1468 "encrypt");
1469 } else {
1470 torture_assert_ntstatus_equal(tctx,
1471 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1472 NT_STATUS_ACCESS_DENIED,
1473 "encrypt");
1474 return true;
1476 torture_assert_werr_equal(tctx,
1477 r.out.result,
1478 WERR_INVALID_PARAM,
1479 "decrypt should fail with WERR_INVALID_PARM");
1481 /* Decrypt */
1482 torture_assert_ntstatus_ok(tctx,
1483 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1484 "obtain GUID");
1486 r.in.guidActionAgent = &guid;
1487 r.in.data_in = short_request;
1488 r.in.data_in_len = 4;
1489 r.in.param = 0;
1490 r.out.data_out = &(decrypted.data);
1491 r.out.data_out_len = &declen;
1492 torture_assert_ntstatus_ok(tctx,
1493 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1494 "decrypt");
1495 torture_assert_werr_equal(tctx,
1496 r.out.result,
1497 WERR_INVALID_PARAM,
1498 "decrypt should fail with WERR_INVALID_PARAM");
1500 /* Decrypt */
1501 torture_assert_ntstatus_ok(tctx,
1502 GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1503 "obtain GUID");
1505 r.in.guidActionAgent = &guid;
1506 r.in.data_in = short_request;
1507 r.in.data_in_len = 1;
1508 r.in.param = 0;
1509 r.out.data_out = &(decrypted.data);
1510 r.out.data_out_len = &declen;
1511 torture_assert_ntstatus_ok(tctx,
1512 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1513 "decrypt");
1514 torture_assert_werr_equal(tctx,
1515 r.out.result,
1516 WERR_INVALID_PARAM,
1517 "decrypt should fail with WERR_INVALID_PARAM");
1519 /* Decrypt */
1520 torture_assert_ntstatus_ok(tctx,
1521 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1522 "obtain GUID");
1524 r.in.guidActionAgent = &guid;
1525 r.in.data_in = short_request;
1526 r.in.data_in_len = 1;
1527 r.in.param = 0;
1528 r.out.data_out = &(decrypted.data);
1529 r.out.data_out_len = &declen;
1530 torture_assert_ntstatus_ok(tctx,
1531 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1532 "decrypt");
1533 torture_assert_werr_equal(tctx,
1534 r.out.result,
1535 WERR_INVALID_PARAM,
1536 "decrypt should fail with WERR_INVALID_PARAM");
1538 return true;
1541 static bool test_ServerWrap_encrypt_decrypt_manual(struct torture_context *tctx,
1542 struct bkrp_server_side_wrapped *server_side_wrapped,
1543 enum test_wrong wrong)
1545 struct dcerpc_pipe *lsa_p;
1546 struct dcerpc_binding_handle *lsa_b;
1547 struct lsa_OpenSecret r_secret;
1548 struct lsa_QuerySecret r_query_secret;
1549 struct policy_handle *handle, sec_handle;
1550 struct bkrp_BackupKey r;
1551 struct GUID preferred_key_guid;
1552 DATA_BLOB plaintext = data_blob_const(secret, sizeof(secret));
1553 DATA_BLOB preferred_key, preferred_key_clear, session_key,
1554 decrypt_key, decrypt_key_clear, encrypted_blob, symkey_blob,
1555 sid_blob;
1556 struct bkrp_dc_serverwrap_key server_key;
1557 struct lsa_DATA_BUF_PTR bufp1;
1558 char *key_guid_string;
1559 struct bkrp_rc4encryptedpayload rc4payload;
1560 struct dom_sid *caller_sid;
1561 uint8_t symkey[20]; /* SHA-1 hash len */
1562 uint8_t mackey[20]; /* SHA-1 hash len */
1563 uint8_t mac[20]; /* SHA-1 hash len */
1564 unsigned int hash_len;
1565 HMAC_CTX ctx;
1566 ZERO_STRUCT(r);
1567 ZERO_STRUCT(r_secret);
1568 ZERO_STRUCT(r_query_secret);
1570 /* Now read BCKUPKEY_P and prove we can do a matching decrypt and encrypt */
1572 torture_assert_ntstatus_ok(tctx,
1573 torture_rpc_connection(tctx, &lsa_p, &ndr_table_lsarpc),
1574 "Opening LSA pipe");
1575 lsa_b = lsa_p->binding_handle;
1577 torture_assert(tctx, test_lsa_OpenPolicy2(lsa_b, tctx, &handle), "OpenPolicy failed");
1578 r_secret.in.name.string = "G$BCKUPKEY_P";
1580 r_secret.in.handle = handle;
1581 r_secret.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1582 r_secret.out.sec_handle = &sec_handle;
1584 torture_comment(tctx, "Testing OpenSecret\n");
1586 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(lsa_b, tctx, &r_secret),
1587 "OpenSecret failed");
1588 torture_assert_ntstatus_ok(tctx, r_secret.out.result,
1589 "OpenSecret failed");
1591 r_query_secret.in.sec_handle = &sec_handle;
1592 r_query_secret.in.new_val = &bufp1;
1593 bufp1.buf = NULL;
1595 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(lsa_b, tctx, &r_query_secret),
1596 "QuerySecret failed");
1597 torture_assert_ntstatus_ok(tctx, r_query_secret.out.result,
1598 "QuerySecret failed");
1601 preferred_key.data = r_query_secret.out.new_val->buf->data;
1602 preferred_key.length = r_query_secret.out.new_val->buf->size;
1603 torture_assert_ntstatus_ok(tctx, dcerpc_fetch_session_key(lsa_p, &session_key),
1604 "dcerpc_fetch_session_key failed");
1606 torture_assert_ntstatus_ok(tctx,
1607 sess_decrypt_blob(tctx,
1608 &preferred_key, &session_key, &preferred_key_clear),
1609 "sess_decrypt_blob failed");
1611 torture_assert_ntstatus_ok(tctx, GUID_from_ndr_blob(&preferred_key_clear, &preferred_key_guid),
1612 "GUID parse failed");
1614 torture_assert_guid_equal(tctx, server_side_wrapped->guid,
1615 preferred_key_guid,
1616 "GUID didn't match value pointed at by G$BCKUPKEY_P");
1618 /* And read BCKUPKEY_<guid> and get the actual key */
1620 key_guid_string = GUID_string(tctx, &server_side_wrapped->guid);
1621 r_secret.in.name.string = talloc_asprintf(tctx, "G$BCKUPKEY_%s", key_guid_string);
1623 r_secret.in.handle = handle;
1624 r_secret.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1625 r_secret.out.sec_handle = &sec_handle;
1627 torture_comment(tctx, "Testing OpenSecret\n");
1629 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(lsa_b, tctx, &r_secret),
1630 "OpenSecret failed");
1631 torture_assert_ntstatus_ok(tctx, r_secret.out.result,
1632 "OpenSecret failed");
1634 r_query_secret.in.sec_handle = &sec_handle;
1635 r_query_secret.in.new_val = &bufp1;
1637 torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(lsa_b, tctx, &r_query_secret),
1638 "QuerySecret failed");
1639 torture_assert_ntstatus_ok(tctx, r_query_secret.out.result,
1640 "QuerySecret failed");
1643 decrypt_key.data = r_query_secret.out.new_val->buf->data;
1644 decrypt_key.length = r_query_secret.out.new_val->buf->size;
1646 torture_assert_ntstatus_ok(tctx,
1647 sess_decrypt_blob(tctx,
1648 &decrypt_key, &session_key, &decrypt_key_clear),
1649 "sess_decrypt_blob failed");
1651 torture_assert_ndr_err_equal(tctx, ndr_pull_struct_blob(&decrypt_key_clear, tctx, &server_key,
1652 (ndr_pull_flags_fn_t)ndr_pull_bkrp_dc_serverwrap_key),
1653 NDR_ERR_SUCCESS, "Failed to parse server_key");
1655 torture_assert_int_equal(tctx, server_key.magic, 1, "Failed to correctly decrypt server key");
1658 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1659 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1661 HMAC(EVP_sha1(), server_key.key, sizeof(server_key.key),
1662 server_side_wrapped->r2, sizeof(server_side_wrapped->r2),
1663 symkey, &hash_len);
1665 /* rc4 decrypt sid and secret using sym key */
1666 symkey_blob = data_blob_const(symkey, sizeof(symkey));
1668 encrypted_blob = data_blob_talloc(tctx, server_side_wrapped->rc4encryptedpayload,
1669 server_side_wrapped->ciphertext_length);
1671 arcfour_crypt_blob(encrypted_blob.data, encrypted_blob.length, &symkey_blob);
1673 torture_assert_ndr_err_equal(tctx, ndr_pull_struct_blob(&encrypted_blob, tctx, &rc4payload,
1674 (ndr_pull_flags_fn_t)ndr_pull_bkrp_rc4encryptedpayload),
1675 NDR_ERR_SUCCESS, "Failed to parse rc4encryptedpayload");
1677 torture_assert_int_equal(tctx, rc4payload.secret_data.length,
1678 server_side_wrapped->payload_length,
1679 "length of decrypted payload not the length declared in surrounding structure");
1682 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1683 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1685 HMAC(EVP_sha1(), server_key.key, sizeof(server_key.key),
1686 rc4payload.r3, sizeof(rc4payload.r3),
1687 mackey, &hash_len);
1689 torture_assert_ndr_err_equal(tctx, ndr_push_struct_blob(&sid_blob, tctx, &rc4payload.sid,
1690 (ndr_push_flags_fn_t)ndr_push_dom_sid),
1691 NDR_ERR_SUCCESS, "unable to push SID");
1693 HMAC_CTX_init(&ctx);
1694 HMAC_Init_ex(&ctx, mackey, hash_len, EVP_sha1(), NULL);
1695 /* SID field */
1696 HMAC_Update(&ctx, sid_blob.data, sid_blob.length);
1697 /* Secret field */
1698 HMAC_Update(&ctx, rc4payload.secret_data.data, rc4payload.secret_data.length);
1699 HMAC_Final(&ctx, mac, &hash_len);
1700 HMAC_CTX_cleanup(&ctx);
1702 torture_assert_mem_equal(tctx, mac, rc4payload.mac, sizeof(mac), "mac not correct");
1703 torture_assert_int_equal(tctx, rc4payload.secret_data.length,
1704 plaintext.length, "decrypted data is not correct length");
1705 torture_assert_mem_equal(tctx, rc4payload.secret_data.data,
1706 plaintext.data, plaintext.length,
1707 "decrypted data is not correct");
1709 /* Not strictly correct all the time, but good enough for this test */
1710 caller_sid = get_user_sid(tctx, tctx, cli_credentials_get_username(cmdline_credentials));
1712 torture_assert_sid_equal(tctx, &rc4payload.sid, caller_sid, "Secret saved with wrong SID");
1715 /* RE-encrypt */
1717 if (wrong == WRONG_SID) {
1718 rc4payload.sid.sub_auths[rc4payload.sid.num_auths - 1] = DOMAIN_RID_KRBTGT;
1721 dump_data_pw("mackey: \n", mackey, sizeof(mackey));
1723 torture_assert_ndr_err_equal(tctx,
1724 ndr_push_struct_blob(&sid_blob, tctx, &rc4payload.sid,
1725 (ndr_push_flags_fn_t)ndr_push_dom_sid),
1726 NDR_ERR_SUCCESS,
1727 "push of sid failed");
1729 HMAC_CTX_init(&ctx);
1730 HMAC_Init_ex(&ctx, mackey, 20, EVP_sha1(), NULL);
1731 /* SID field */
1732 HMAC_Update(&ctx, sid_blob.data, sid_blob.length);
1733 /* Secret field */
1734 HMAC_Update(&ctx, rc4payload.secret_data.data, rc4payload.secret_data.length);
1735 HMAC_Final(&ctx, rc4payload.mac, &hash_len);
1736 HMAC_CTX_cleanup(&ctx);
1738 dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac));
1740 torture_assert_ndr_err_equal(tctx,
1741 ndr_push_struct_blob(&encrypted_blob, tctx, &rc4payload,
1742 (ndr_push_flags_fn_t)ndr_push_bkrp_rc4encryptedpayload),
1743 NDR_ERR_SUCCESS,
1744 "push of rc4payload failed");
1746 if (wrong == WRONG_KEY) {
1747 symkey_blob.data[0] = 78;
1748 symkey_blob.data[1] = 78;
1749 symkey_blob.data[2] = 78;
1752 /* rc4 encrypt sid and secret using sym key */
1753 arcfour_crypt_blob(encrypted_blob.data, encrypted_blob.length, &symkey_blob);
1755 /* re-create server wrap structure */
1757 torture_assert_int_equal(tctx, encrypted_blob.length,
1758 server_side_wrapped->ciphertext_length,
1759 "expected encrypted length not to change");
1760 if (wrong == RIGHT_KEY) {
1761 torture_assert_mem_equal(tctx, server_side_wrapped->rc4encryptedpayload,
1762 encrypted_blob.data,
1763 encrypted_blob.length,
1764 "expected encrypted data not to change");
1767 server_side_wrapped->payload_length = rc4payload.secret_data.length;
1768 server_side_wrapped->ciphertext_length = encrypted_blob.length;
1769 server_side_wrapped->rc4encryptedpayload = encrypted_blob.data;
1771 return true;
1775 static bool test_ServerWrap_decrypt_wrong_stuff(struct torture_context *tctx,
1776 struct dcerpc_pipe *p,
1777 enum test_wrong wrong)
1779 struct bkrp_BackupKey r;
1780 struct GUID guid;
1781 DATA_BLOB plaintext = data_blob_const(secret, sizeof(secret));
1782 DATA_BLOB encrypted;
1783 uint32_t enclen;
1784 DATA_BLOB decrypted;
1785 uint32_t declen;
1786 struct dcerpc_binding_handle *b = p->binding_handle;
1787 enum ndr_err_code ndr_err;
1788 struct bkrp_server_side_wrapped server_side_wrapped;
1789 bool repush = false;
1790 enum dcerpc_AuthType auth_type;
1791 enum dcerpc_AuthLevel auth_level;
1792 ZERO_STRUCT(r);
1794 dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1796 /* Encrypt */
1797 torture_assert_ntstatus_ok(tctx,
1798 GUID_from_string(BACKUPKEY_BACKUP_GUID, &guid),
1799 "obtain GUID");
1801 r.in.guidActionAgent = &guid;
1802 r.in.data_in = plaintext.data;
1803 r.in.data_in_len = plaintext.length;
1804 r.in.param = 0;
1805 r.out.data_out = &encrypted.data;
1806 r.out.data_out_len = &enclen;
1807 if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1808 torture_assert_ntstatus_ok(tctx,
1809 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1810 "encrypt");
1811 } else {
1812 torture_assert_ntstatus_equal(tctx,
1813 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1814 NT_STATUS_ACCESS_DENIED,
1815 "encrypt");
1816 return true;
1818 torture_assert_werr_ok(tctx,
1819 r.out.result,
1820 "encrypt");
1821 encrypted.length = *r.out.data_out_len;
1823 ndr_err = ndr_pull_struct_blob(&encrypted, tctx, &server_side_wrapped,
1824 (ndr_pull_flags_fn_t)ndr_pull_bkrp_server_side_wrapped);
1825 torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "pull of server_side_wrapped");
1827 torture_assert_int_equal(tctx, server_side_wrapped.payload_length, plaintext.length,
1828 "wrong payload length");
1830 switch (wrong) {
1831 case WRONG_MAGIC:
1832 /* Change the magic. Forced by our NDR layer, so do it raw */
1833 SIVAL(encrypted.data, 0, 78); /* valid values are 1-3 */
1834 break;
1835 case WRONG_R2:
1836 server_side_wrapped.r2[0] = 78;
1837 server_side_wrapped.r2[1] = 78;
1838 server_side_wrapped.r2[3] = 78;
1839 repush = true;
1840 break;
1841 case WRONG_PAYLOAD_LENGTH:
1842 server_side_wrapped.payload_length = UINT32_MAX - 8;
1843 repush = true;
1844 break;
1845 case WRONG_CIPHERTEXT_LENGTH:
1847 * Change the ciphertext len. We can't push this if
1848 * we have it wrong, so do it raw
1850 SIVAL(encrypted.data, 8, UINT32_MAX - 8); /* valid values are 1-3 */
1851 break;
1852 case SHORT_PAYLOAD_LENGTH:
1853 server_side_wrapped.payload_length = server_side_wrapped.payload_length - 8;
1854 repush = true;
1855 break;
1856 case SHORT_CIPHERTEXT_LENGTH:
1858 * Change the ciphertext len. We can't push this if
1859 * we have it wrong, so do it raw
1861 SIVAL(encrypted.data, 8, server_side_wrapped.ciphertext_length - 8); /* valid values are 1-3 */
1862 break;
1863 case ZERO_PAYLOAD_LENGTH:
1864 server_side_wrapped.payload_length = 0;
1865 repush = true;
1866 break;
1867 case ZERO_CIPHERTEXT_LENGTH:
1869 * Change the ciphertext len. We can't push this if
1870 * we have it wrong, so do it raw
1872 SIVAL(encrypted.data, 8, 0); /* valid values are 1-3 */
1873 break;
1875 case RIGHT_KEY:
1876 case WRONG_KEY:
1877 case WRONG_SID:
1878 torture_assert(tctx,
1879 test_ServerWrap_encrypt_decrypt_manual(tctx, &server_side_wrapped, wrong),
1880 "test_ServerWrap_encrypt_decrypt_manual failed");
1881 repush = true;
1882 break;
1885 if (repush) {
1886 ndr_err = ndr_push_struct_blob(&encrypted, tctx, &server_side_wrapped,
1887 (ndr_push_flags_fn_t)ndr_push_bkrp_server_side_wrapped);
1888 torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "push of server_side_wrapped");
1891 /* Decrypt */
1892 torture_assert_ntstatus_ok(tctx,
1893 GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1894 "obtain GUID");
1896 r.in.guidActionAgent = &guid;
1897 r.in.data_in = encrypted.data;
1898 r.in.data_in_len = encrypted.length;
1899 r.in.param = 0;
1900 r.out.data_out = &(decrypted.data);
1901 r.out.data_out_len = &declen;
1902 torture_assert_ntstatus_ok(tctx,
1903 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1904 "decrypt");
1906 if ((wrong == WRONG_R2 || wrong == WRONG_KEY)
1907 && W_ERROR_EQUAL(r.out.result, WERR_INVALID_SID)) {
1908 torture_assert_werr_equal(tctx,
1909 r.out.result,
1910 WERR_INVALID_SID,
1911 "decrypt should fail with WERR_INVALID_SID or WERR_INVALID_PARAM");
1912 } else if (wrong == RIGHT_KEY) {
1913 torture_assert_werr_equal(tctx,
1914 r.out.result,
1915 WERR_OK,
1916 "decrypt should succeed!");
1917 } else if (wrong == WRONG_SID) {
1918 torture_assert_werr_equal(tctx,
1919 r.out.result,
1920 WERR_INVALID_ACCESS,
1921 "decrypt should fail with WERR_INVALID_ACCESS");
1922 } else {
1923 torture_assert_werr_equal(tctx,
1924 r.out.result,
1925 WERR_INVALID_PARAM,
1926 "decrypt should fail with WERR_INVALID_PARAM");
1929 /* Decrypt */
1930 torture_assert_ntstatus_ok(tctx,
1931 GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1932 "obtain GUID");
1934 r.in.guidActionAgent = &guid;
1935 r.in.data_in = encrypted.data;
1936 r.in.data_in_len = encrypted.length;
1937 r.in.param = 0;
1938 r.out.data_out = &(decrypted.data);
1939 r.out.data_out_len = &declen;
1940 torture_assert_ntstatus_ok(tctx,
1941 dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1942 "decrypt");
1944 if ((wrong == WRONG_R2 || wrong == WRONG_KEY)
1945 && W_ERROR_EQUAL(r.out.result, WERR_INVALID_SID)) {
1946 torture_assert_werr_equal(tctx,
1947 r.out.result,
1948 WERR_INVALID_SID,
1949 "decrypt should fail with WERR_INVALID_SID or WERR_INVALID_PARAM");
1950 } else if (wrong == RIGHT_KEY) {
1951 torture_assert_werr_equal(tctx,
1952 r.out.result,
1953 WERR_OK,
1954 "decrypt should succeed!");
1955 } else if (wrong == WRONG_SID) {
1956 torture_assert_werr_equal(tctx,
1957 r.out.result,
1958 WERR_INVALID_ACCESS,
1959 "decrypt should fail with WERR_INVALID_ACCESS");
1960 } else {
1961 torture_assert_werr_equal(tctx,
1962 r.out.result,
1963 WERR_INVALID_PARAM,
1964 "decrypt should fail with WERR_INVALID_PARAM");
1967 return true;
1970 static bool test_ServerWrap_decrypt_wrong_magic(struct torture_context *tctx,
1971 struct dcerpc_pipe *p)
1973 return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_MAGIC);
1976 static bool test_ServerWrap_decrypt_wrong_r2(struct torture_context *tctx,
1977 struct dcerpc_pipe *p)
1979 return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_R2);
1982 static bool test_ServerWrap_decrypt_wrong_payload_length(struct torture_context *tctx,
1983 struct dcerpc_pipe *p)
1985 return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_PAYLOAD_LENGTH);
1988 static bool test_ServerWrap_decrypt_short_payload_length(struct torture_context *tctx,
1989 struct dcerpc_pipe *p)
1991 return test_ServerWrap_decrypt_wrong_stuff(tctx, p, SHORT_PAYLOAD_LENGTH);
1994 static bool test_ServerWrap_decrypt_zero_payload_length(struct torture_context *tctx,
1995 struct dcerpc_pipe *p)
1997 return test_ServerWrap_decrypt_wrong_stuff(tctx, p, ZERO_PAYLOAD_LENGTH);
2000 static bool test_ServerWrap_decrypt_wrong_ciphertext_length(struct torture_context *tctx,
2001 struct dcerpc_pipe *p)
2003 return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_CIPHERTEXT_LENGTH);
2006 static bool test_ServerWrap_decrypt_short_ciphertext_length(struct torture_context *tctx,
2007 struct dcerpc_pipe *p)
2009 return test_ServerWrap_decrypt_wrong_stuff(tctx, p, SHORT_CIPHERTEXT_LENGTH);
2012 static bool test_ServerWrap_decrypt_zero_ciphertext_length(struct torture_context *tctx,
2013 struct dcerpc_pipe *p)
2015 return test_ServerWrap_decrypt_wrong_stuff(tctx, p, ZERO_CIPHERTEXT_LENGTH);
2018 static bool test_ServerWrap_encrypt_decrypt_remote_key(struct torture_context *tctx,
2019 struct dcerpc_pipe *p)
2021 return test_ServerWrap_decrypt_wrong_stuff(tctx, p, RIGHT_KEY);
2024 static bool test_ServerWrap_encrypt_decrypt_wrong_key(struct torture_context *tctx,
2025 struct dcerpc_pipe *p)
2027 return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_KEY);
2030 static bool test_ServerWrap_encrypt_decrypt_wrong_sid(struct torture_context *tctx,
2031 struct dcerpc_pipe *p)
2033 return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_SID);
2036 struct torture_suite *torture_rpc_backupkey(TALLOC_CTX *mem_ctx)
2038 struct torture_rpc_tcase *tcase;
2039 struct torture_suite *suite = torture_suite_create(mem_ctx, "backupkey");
2041 tcase = torture_suite_add_rpc_iface_tcase(suite, "backupkey",
2042 &ndr_table_backupkey);
2044 torture_rpc_tcase_add_test(tcase, "retreive_backup_key_guid",
2045 test_RetreiveBackupKeyGUID);
2047 torture_rpc_tcase_add_test(tcase, "restore_guid",
2048 test_RestoreGUID);
2050 torture_rpc_tcase_add_test(tcase, "restore_guid version 3",
2051 test_RestoreGUID_v3);
2053 /* We double the test in order to be sure that we don't mess stuff (ie. freeing static stuff) */
2055 torture_rpc_tcase_add_test(tcase, "restore_guid_2nd",
2056 test_RestoreGUID);
2058 torture_rpc_tcase_add_test(tcase, "unable_to_decrypt_secret",
2059 test_RestoreGUID_ko);
2061 torture_rpc_tcase_add_test(tcase, "wrong_user_restore_guid",
2062 test_RestoreGUID_wronguser);
2064 torture_rpc_tcase_add_test(tcase, "wrong_version_restore_guid",
2065 test_RestoreGUID_wrongversion);
2067 torture_rpc_tcase_add_test(tcase, "bad_magic_on_secret_restore_guid",
2068 test_RestoreGUID_badmagiconsecret);
2070 torture_rpc_tcase_add_test(tcase, "bad_hash_on_secret_restore_guid",
2071 test_RestoreGUID_badhashaccesscheck);
2073 torture_rpc_tcase_add_test(tcase, "bad_magic_on_accesscheck_restore_guid",
2074 test_RestoreGUID_badmagicaccesscheck);
2076 torture_rpc_tcase_add_test(tcase, "bad_cert_guid_restore_guid",
2077 test_RestoreGUID_badcertguid);
2079 torture_rpc_tcase_add_test(tcase, "empty_request_restore_guid",
2080 test_RestoreGUID_emptyrequest);
2082 torture_rpc_tcase_add_test(tcase, "retreive_backup_key_guid_2048_bits",
2083 test_RetreiveBackupKeyGUID_2048bits);
2085 torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt",
2086 test_ServerWrap_encrypt_decrypt);
2088 torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_keyGUID",
2089 test_ServerWrap_decrypt_wrong_keyGUID);
2091 torture_rpc_tcase_add_test(tcase, "server_wrap_empty_request",
2092 test_ServerWrap_decrypt_empty_request);
2094 torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_short_request",
2095 test_ServerWrap_decrypt_short_request);
2097 torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_magic",
2098 test_ServerWrap_decrypt_wrong_magic);
2100 torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_r2",
2101 test_ServerWrap_decrypt_wrong_r2);
2103 torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_payload_length",
2104 test_ServerWrap_decrypt_wrong_payload_length);
2106 torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_short_payload_length",
2107 test_ServerWrap_decrypt_short_payload_length);
2109 torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_zero_payload_length",
2110 test_ServerWrap_decrypt_zero_payload_length);
2112 torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_ciphertext_length",
2113 test_ServerWrap_decrypt_wrong_ciphertext_length);
2115 torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_short_ciphertext_length",
2116 test_ServerWrap_decrypt_short_ciphertext_length);
2118 torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_zero_ciphertext_length",
2119 test_ServerWrap_decrypt_zero_ciphertext_length);
2121 torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt_remote_key",
2122 test_ServerWrap_encrypt_decrypt_remote_key);
2124 torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt_wrong_key",
2125 test_ServerWrap_encrypt_decrypt_wrong_key);
2127 torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt_wrong_sid",
2128 test_ServerWrap_encrypt_decrypt_wrong_sid);
2130 return suite;