1 /*
2    Unix SMB/CIFS implementation.
3    test suite for backupkey remote protocol rpc operations
4 
5    Copyright (C) Matthieu Patou 2010-2011
6    Copyright (C) Andreas Schneider <asn@samba.org> 2015
7 
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.
12 
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.
17 
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/>.
20 */
21 
22 #include "includes.h"
23 #include "../libcli/security/security.h"
24 
25 #include "torture/rpc/torture_rpc.h"
26 #include "torture/ndr/ndr.h"
27 
28 #include "librpc/gen_ndr/ndr_backupkey_c.h"
29 #include "librpc/gen_ndr/ndr_backupkey.h"
30 #include "librpc/gen_ndr/ndr_lsa_c.h"
31 #include "librpc/gen_ndr/ndr_security.h"
32 #include "lib/cmdline/popt_common.h"
33 #include "libcli/auth/proto.h"
34 #include <system/network.h>
35 
36 #include <gnutls/gnutls.h>
37 #include <gnutls/crypto.h>
38 #include <gnutls/x509.h>
39 #include <gnutls/abstract.h>
40 
41 enum test_wrong {
42 	WRONG_MAGIC,
43 	WRONG_R2,
44 	WRONG_PAYLOAD_LENGTH,
45 	WRONG_CIPHERTEXT_LENGTH,
46 	SHORT_PAYLOAD_LENGTH,
47 	SHORT_CIPHERTEXT_LENGTH,
48 	ZERO_PAYLOAD_LENGTH,
49 	ZERO_CIPHERTEXT_LENGTH,
50 	RIGHT_KEY,
51 	WRONG_KEY,
52 	WRONG_SID,
53 };
54 
55 /* Our very special and valued secret */
56 /* No need to put const as we cast the array in uint8_t
57  * we will get a warning about the discared const
58  */
59 static const char secret[] = "tata yoyo mais qu'est ce qu'il y a sous ton grand chapeau ?";
60 
61 /* Get the SID from a user */
get_user_sid(struct torture_context * tctx,TALLOC_CTX * mem_ctx,const char * user)62 static struct dom_sid *get_user_sid(struct torture_context *tctx,
63 				    TALLOC_CTX *mem_ctx,
64 				    const char *user)
65 {
66 	struct lsa_ObjectAttribute attr;
67 	struct lsa_QosInfo qos;
68 	struct lsa_OpenPolicy2 r;
69 	struct lsa_Close c;
70 	NTSTATUS status;
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;
76 	uint32_t count = 0;
77 	struct dom_sid *result;
78 	TALLOC_CTX *tmp_ctx;
79 	struct dcerpc_pipe *p2;
80 	struct dcerpc_binding_handle *b;
81 
82 	const char *domain = cli_credentials_get_domain(
83 			popt_get_cmdline_credentials());
84 
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;
89 
90 	if (!(tmp_ctx = talloc_new(mem_ctx))) {
91 		return NULL;
92 	}
93 	qos.len = 0;
94 	qos.impersonation_level = 2;
95 	qos.context_mode = 1;
96 	qos.effective_only = 0;
97 
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;
104 
105 	r.in.system_name = "\\";
106 	r.in.attr = &attr;
107 	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
108 	r.out.handle = &handle;
109 
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;
117 	}
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;
124 	}
125 
126 	sids.count = 0;
127 	sids.sids = NULL;
128 
129 	lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, user);
130 
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;
140 
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;
149 	}
150 
151 	if (domains->count == 0) {
152 		return NULL;
153 	}
154 
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;
160 
161 	status = dcerpc_lsa_Close_r(b, tmp_ctx, &c);
162 
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;
169 	}
170 
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;
177 	}
178 
179 	talloc_free(tmp_ctx);
180 	talloc_free(p2);
181 
182 	torture_comment(tctx, "Get_user_sid finished\n");
183 	return result;
184 }
185 
186 /*
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
192  */
create_unencryptedsecret(TALLOC_CTX * mem_ctx,bool broken,int version)193 static DATA_BLOB *create_unencryptedsecret(TALLOC_CTX *mem_ctx,
194 					   bool broken,
195 					   int version)
196 {
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;
200 
201 	if (version == 2) {
202 		struct bkrp_encrypted_secret_v2 unenc_sec;
203 
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));
209 
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;
214 		}
215 
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
220 			 */
221 			((uint8_t*)blob->data)[4] = 79; /* A great year !!! */
222 		}
223 	}
224 
225 	if (version == 3) {
226 		struct bkrp_encrypted_secret_v3 unenc_sec;
227 
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));
233 
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;
238 		}
239 
240 		if (broken) {
241 			/*
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
245 			 */
246 			((uint8_t*)blob->data)[4] = 79; /* A great year !!! */
247 		}
248 	}
249 	talloc_free(tmp_ctx);
250 	return blob;
251 }
252 
253 /*
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.
257  *
258  * If the structure can't be created then NULL is returned.
259  */
create_access_check(struct torture_context * tctx,struct dcerpc_pipe * p,TALLOC_CTX * mem_ctx,const char * user,bool broken,uint32_t version)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)
266 {
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);
271 
272 	if (sid == NULL) {
273 		return NULL;
274 	}
275 
276 	if (version == 2) {
277 		struct bkrp_access_check_v2 access_struct;
278 		gnutls_hash_hd_t dig_ctx;
279 		uint8_t nonce[32];
280 
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;
286 
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;
291 		}
292 
293 		/*
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
297 		 */
298 
299 		gnutls_hash_init(&dig_ctx, GNUTLS_DIG_SHA1);
300 		gnutls_hash(dig_ctx,
301 			    blob->data,
302 			    blob->length - sizeof(access_struct.hash));
303 		gnutls_hash_deinit(dig_ctx,
304 				   blob->data + blob->length - sizeof(access_struct.hash));
305 
306 		/* Altering the SHA */
307 		if (broken) {
308 			blob->data[blob->length - 1]++;
309 		}
310 	}
311 
312 	if (version == 3) {
313 		struct bkrp_access_check_v3 access_struct;
314 		gnutls_hash_hd_t dig_ctx;
315 		uint8_t nonce[32];
316 
317 		ZERO_STRUCT(access_struct);
318 		generate_random_buffer(nonce, sizeof(nonce));
319 		access_struct.nonce_len = sizeof(nonce);
320 		access_struct.nonce = nonce;
321 		access_struct.sid = *sid;
322 
323 		ndr_err = ndr_push_struct_blob(blob, blob, &access_struct,
324 				(ndr_push_flags_fn_t)ndr_push_bkrp_access_check_v3);
325 		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
326 			return NULL;
327 		}
328 
329 		/*We pushed the whole structure including a null hash
330 		* but the hash need to be calculated only up to the hash field
331 		* so we reduce the size of what has to be calculated
332 		*/
333 
334 		gnutls_hash_init(&dig_ctx, GNUTLS_DIG_SHA512);
335 		gnutls_hash(dig_ctx,
336 			    blob->data,
337 			    blob->length - sizeof(access_struct.hash));
338 		gnutls_hash_deinit(dig_ctx,
339 				   blob->data + blob->length - sizeof(access_struct.hash));
340 
341 		/* Altering the SHA */
342 		if (broken) {
343 			blob->data[blob->length -1]++;
344 		}
345 	}
346 	talloc_free(tmp_ctx);
347 	return blob;
348 }
349 
350 
encrypt_blob(struct torture_context * tctx,TALLOC_CTX * mem_ctx,DATA_BLOB * key,DATA_BLOB * iv,DATA_BLOB * to_encrypt,gnutls_cipher_algorithm_t cipher_algo)351 static DATA_BLOB *encrypt_blob(struct torture_context *tctx,
352 				    TALLOC_CTX *mem_ctx,
353 				    DATA_BLOB *key,
354 				    DATA_BLOB *iv,
355 				    DATA_BLOB *to_encrypt,
356 				    gnutls_cipher_algorithm_t cipher_algo)
357 {
358 	gnutls_cipher_hd_t cipher_handle = { 0 };
359 	gnutls_datum_t gkey = {
360 		.data = key->data,
361 		.size = key->length,
362 	};
363 	gnutls_datum_t giv = {
364 		.data = iv->data,
365 		.size = iv->length,
366 	};
367 	DATA_BLOB *blob;
368 	int rc;
369 
370 	blob = talloc(mem_ctx, DATA_BLOB);
371 	if (blob == NULL) {
372 		return NULL;
373 	}
374 
375 	*blob = data_blob_talloc_zero(mem_ctx, to_encrypt->length);
376 	if (blob->data == NULL) {
377 		talloc_free(blob);
378 		return NULL;
379 	}
380 
381 	rc = gnutls_cipher_init(&cipher_handle,
382 				cipher_algo,
383 				&gkey,
384 				&giv);
385 	if (rc != GNUTLS_E_SUCCESS) {
386 		torture_comment(tctx,
387 				"gnutls_cipher_init failed: %s\n",
388 				gnutls_strerror(rc));
389 		talloc_free(blob);
390 		return NULL;
391 	}
392 
393 	rc = gnutls_cipher_encrypt2(cipher_handle,
394 				    to_encrypt->data,
395 				    to_encrypt->length,
396 				    blob->data,
397 				    blob->length);
398 	gnutls_cipher_deinit(cipher_handle);
399 	if (rc != GNUTLS_E_SUCCESS) {
400 		torture_comment(tctx,
401 				"gnutls_cipher_decrypt2 failed: %s\n",
402 				gnutls_strerror(rc));
403 		return NULL;
404 	}
405 
406 	return blob;
407 }
408 
409 /*
410  * Certs used for this protocol have a GUID in the issuer_uniq_id field.
411  * This function fetch it.
412  */
get_cert_guid(struct torture_context * tctx,TALLOC_CTX * mem_ctx,uint8_t * cert_data,uint32_t cert_len)413 static struct GUID *get_cert_guid(struct torture_context *tctx,
414 				  TALLOC_CTX *mem_ctx,
415 				  uint8_t *cert_data,
416 				  uint32_t cert_len)
417 {
418 	gnutls_x509_crt_t x509_cert = NULL;
419 	gnutls_datum_t x509_crt_data = {
420 		.data = cert_data,
421 		.size = cert_len,
422 	};
423 	uint8_t dummy[1] = {0};
424 	DATA_BLOB issuer_unique_id = {
425 		.data = dummy,
426 		.length = 0,
427 	};
428 	struct GUID *guid = talloc_zero(mem_ctx, struct GUID);
429 	NTSTATUS status;
430 	int rc;
431 
432 	rc = gnutls_x509_crt_init(&x509_cert);
433 	if (rc != GNUTLS_E_SUCCESS) {
434 		torture_comment(tctx,
435 				"gnutls_x509_crt_init failed - %s",
436 				gnutls_strerror(rc));
437 		return NULL;
438 	}
439 
440 	rc = gnutls_x509_crt_import(x509_cert,
441 				    &x509_crt_data,
442 				    GNUTLS_X509_FMT_DER);
443 	if (rc != GNUTLS_E_SUCCESS) {
444 		torture_comment(tctx,
445 				"gnutls_x509_crt_import failed - %s",
446 				gnutls_strerror(rc));
447 		gnutls_x509_crt_deinit(x509_cert);
448 		return NULL;
449 	}
450 
451 	/* Get the buffer size */
452 	rc = gnutls_x509_crt_get_issuer_unique_id(x509_cert,
453 						  (char *)issuer_unique_id.data,
454 						  &issuer_unique_id.length);
455 	if (rc != GNUTLS_E_SHORT_MEMORY_BUFFER ||
456 	    issuer_unique_id.length == 0) {
457 		gnutls_x509_crt_deinit(x509_cert);
458 		return NULL;
459 	}
460 
461 	issuer_unique_id = data_blob_talloc_zero(mem_ctx,
462 						 issuer_unique_id.length);
463 	if (issuer_unique_id.data == NULL) {
464 		gnutls_x509_crt_deinit(x509_cert);
465 		return NULL;
466 	}
467 
468 	rc = gnutls_x509_crt_get_issuer_unique_id(x509_cert,
469 						  (char *)issuer_unique_id.data,
470 						  &issuer_unique_id.length);
471 	gnutls_x509_crt_deinit(x509_cert);
472 	if (rc != GNUTLS_E_SUCCESS) {
473 		torture_comment(tctx,
474 				"gnutls_x509_crt_get_issuer_unique_id failed - %s",
475 				gnutls_strerror(rc));
476 		return NULL;
477 	}
478 
479 	status = GUID_from_data_blob(&issuer_unique_id, guid);
480 	if (!NT_STATUS_IS_OK(status)) {
481 		return NULL;
482 	}
483 
484 	return guid;
485 }
486 
487 /*
488  * Encrypt a blob with the private key of the certificate
489  * passed as a parameter.
490  */
encrypt_blob_pk(struct torture_context * tctx,TALLOC_CTX * mem_ctx,uint8_t * cert_data,uint32_t cert_len,DATA_BLOB * to_encrypt)491 static DATA_BLOB *encrypt_blob_pk(struct torture_context *tctx,
492 				  TALLOC_CTX *mem_ctx,
493 				  uint8_t *cert_data,
494 				  uint32_t cert_len,
495 				  DATA_BLOB *to_encrypt)
496 {
497 	gnutls_x509_crt_t x509_cert;
498 	gnutls_datum_t x509_crt_data = {
499 		.data = cert_data,
500 		.size = cert_len,
501 	};
502 	gnutls_pubkey_t pubkey;
503 	gnutls_datum_t plaintext = {
504 		.data = to_encrypt->data,
505 		.size = to_encrypt->length,
506 	};
507 	gnutls_datum_t ciphertext = {
508 		.data = NULL,
509 	};
510 	DATA_BLOB *blob;
511 	int rc;
512 
513 	rc = gnutls_x509_crt_init(&x509_cert);
514 	if (rc != GNUTLS_E_SUCCESS) {
515 		return NULL;
516 	}
517 
518 	rc = gnutls_x509_crt_import(x509_cert,
519 				    &x509_crt_data,
520 				    GNUTLS_X509_FMT_DER);
521 	if (rc != GNUTLS_E_SUCCESS) {
522 		gnutls_x509_crt_deinit(x509_cert);
523 		return NULL;
524 	}
525 
526 	rc = gnutls_pubkey_init(&pubkey);
527 	if (rc != GNUTLS_E_SUCCESS) {
528 		gnutls_x509_crt_deinit(x509_cert);
529 		return NULL;
530 	}
531 
532 	rc = gnutls_pubkey_import_x509(pubkey,
533 				       x509_cert,
534 				       0);
535 	gnutls_x509_crt_deinit(x509_cert);
536 	if (rc != GNUTLS_E_SUCCESS) {
537 		gnutls_pubkey_deinit(pubkey);
538 		return NULL;
539 	}
540 
541 	rc = gnutls_pubkey_encrypt_data(pubkey,
542 					0,
543 					&plaintext,
544 					&ciphertext);
545 	gnutls_pubkey_deinit(pubkey);
546 	if (rc != GNUTLS_E_SUCCESS) {
547 		return NULL;
548 	}
549 
550 	blob = talloc_zero(mem_ctx, DATA_BLOB);
551 	if (blob == NULL) {
552 		gnutls_pubkey_deinit(pubkey);
553 		return NULL;
554 	}
555 
556 	*blob = data_blob_talloc(blob, ciphertext.data, ciphertext.size);
557 	gnutls_free(ciphertext.data);
558 	if (blob->data == NULL) {
559 		gnutls_pubkey_deinit(pubkey);
560 		return NULL;
561 	}
562 
563 	return blob;
564 }
565 
createRetrieveBackupKeyGUIDStruct(struct torture_context * tctx,struct dcerpc_pipe * p,int version,DATA_BLOB * out)566 static struct bkrp_BackupKey *createRetrieveBackupKeyGUIDStruct(struct torture_context *tctx,
567 				struct dcerpc_pipe *p, int version, DATA_BLOB *out)
568 {
569 	struct dcerpc_binding *binding;
570 	struct bkrp_client_side_wrapped data;
571 	struct GUID *g = talloc(tctx, struct GUID);
572 	struct bkrp_BackupKey *r = talloc_zero(tctx, struct bkrp_BackupKey);
573 	enum ndr_err_code ndr_err;
574 	DATA_BLOB blob;
575 	NTSTATUS status;
576 
577 	if (r == NULL) {
578 		return NULL;
579 	}
580 
581 	binding = dcerpc_binding_dup(tctx, p->binding);
582 	if (binding == NULL) {
583 		return NULL;
584 	}
585 
586 	status = dcerpc_binding_set_flags(binding, DCERPC_SEAL|DCERPC_AUTH_SPNEGO, 0);
587 	if (!NT_STATUS_IS_OK(status)) {
588 		return NULL;
589 	}
590 
591 	ZERO_STRUCT(data);
592 	status = GUID_from_string(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID, g);
593 	if (!NT_STATUS_IS_OK(status)) {
594 		return NULL;
595 	}
596 
597 	r->in.guidActionAgent = g;
598 	data.version = version;
599 	ndr_err = ndr_push_struct_blob(&blob, tctx, &data,
600 			(ndr_push_flags_fn_t)ndr_push_bkrp_client_side_wrapped);
601 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
602 		return NULL;
603 	}
604 	r->in.data_in = blob.data;
605 	r->in.data_in_len = blob.length;
606 	r->out.data_out = &out->data;
607 	r->out.data_out_len = talloc(r, uint32_t);
608 	return r;
609 }
610 
createRestoreGUIDStruct(struct torture_context * tctx,struct dcerpc_pipe * p,int version,DATA_BLOB * out,bool norevert,bool broken_version,bool broken_user,bool broken_magic_secret,bool broken_magic_access,bool broken_hash_access,bool broken_cert_guid)611 static struct bkrp_BackupKey *createRestoreGUIDStruct(struct torture_context *tctx,
612 				struct dcerpc_pipe *p, int version, DATA_BLOB *out,
613 				bool norevert,
614 				bool broken_version,
615 				bool broken_user,
616 				bool broken_magic_secret,
617 				bool broken_magic_access,
618 				bool broken_hash_access,
619 				bool broken_cert_guid)
620 {
621 	struct dcerpc_binding_handle *b = p->binding_handle;
622 	struct bkrp_client_side_wrapped data;
623 	DATA_BLOB *xs;
624 	DATA_BLOB *sec;
625 	DATA_BLOB *enc_sec = NULL;
626 	DATA_BLOB *enc_xs = NULL;
627 	DATA_BLOB *blob2;
628 	DATA_BLOB enc_sec_reverted;
629 	DATA_BLOB key;
630 	DATA_BLOB iv;
631 	DATA_BLOB out_blob;
632 	struct GUID *guid, *g;
633 	int t;
634 	uint32_t size;
635 	enum ndr_err_code ndr_err;
636 	NTSTATUS status;
637 	const char *user;
638 	gnutls_cipher_algorithm_t cipher_algo;
639 	struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, version, &out_blob);
640 	if (r == NULL) {
641 		return NULL;
642 	}
643 
644 	if (broken_user) {
645 		/* we take a fake user*/
646 		user = "guest";
647 	} else {
648 		user = cli_credentials_get_username(
649 				popt_get_cmdline_credentials());
650 	}
651 
652 
653 	torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
654 					"Get GUID");
655 	torture_assert_werr_ok(tctx, r->out.result,
656 			       "Get GUID");
657 
658 	/*
659 	 * We have to set it outside of the function createRetrieveBackupKeyGUIDStruct
660 	 * the len of the blob, this is due to the fact that they don't have the
661 	 * same size (one is 32bits the other 64bits)
662 	 */
663 	out_blob.length = *r->out.data_out_len;
664 
665 	sec = create_unencryptedsecret(tctx, broken_magic_secret, version);
666 	if (sec == NULL) {
667 		return NULL;
668 	}
669 
670 	xs = create_access_check(tctx, p, tctx, user, broken_hash_access, version);
671 	if (xs == NULL) {
672 		return NULL;
673 	}
674 
675 	if (broken_magic_access){
676 		/* The start of the access_check structure contains the
677 		 * GUID of the certificate
678 		 */
679 		xs->data[0]++;
680 	}
681 
682 	enc_sec = encrypt_blob_pk(tctx, tctx, out_blob.data, out_blob.length, sec);
683 	if (!enc_sec) {
684 		return NULL;
685 	}
686 	enc_sec_reverted.data = talloc_array(tctx, uint8_t, enc_sec->length);
687 	if (enc_sec_reverted.data == NULL) {
688 		return NULL;
689 	}
690 	enc_sec_reverted.length = enc_sec->length;
691 
692 	/*
693 	* We DO NOT revert the array on purpose it's in order to check that
694 	* when the server is not able to decrypt then it answer the correct error
695 	*/
696 	if (norevert) {
697 		for(t=0; t< enc_sec->length; t++) {
698 			enc_sec_reverted.data[t] = ((uint8_t*)enc_sec->data)[t];
699 		}
700 	} else {
701 		for(t=0; t< enc_sec->length; t++) {
702 			enc_sec_reverted.data[t] = ((uint8_t*)enc_sec->data)[enc_sec->length - t -1];
703 		}
704 	}
705 
706 	size = sec->length;
707 	switch (version) {
708 	case 2:
709 		cipher_algo = GNUTLS_CIPHER_3DES_CBC;
710 		break;
711 	case 3:
712 		cipher_algo = GNUTLS_CIPHER_AES_256_CBC;
713 		break;
714 	default:
715 		return NULL;
716 	}
717 	iv.length = gnutls_cipher_get_iv_size(cipher_algo);
718 	iv.data = sec->data + (size - iv.length);
719 
720 	key.length = gnutls_cipher_get_key_size(cipher_algo);
721 	key.data = sec->data + (size - (key.length + iv.length));
722 
723 	enc_xs = encrypt_blob(tctx, tctx, &key, &iv, xs, cipher_algo);
724 	if (!enc_xs) {
725 		return NULL;
726 	}
727 
728 	/* To cope with the fact that heimdal do padding at the end for the moment */
729 	enc_xs->length = xs->length;
730 
731 	guid = get_cert_guid(tctx, tctx, out_blob.data, out_blob.length);
732 	if (guid == NULL) {
733 		return NULL;
734 	}
735 
736 	if (broken_version) {
737 		data.version = 1;
738 	} else {
739 		data.version = version;
740 	}
741 
742 	data.guid = *guid;
743 	data.encrypted_secret = enc_sec_reverted.data;
744 	data.access_check = enc_xs->data;
745 	data.encrypted_secret_len = enc_sec->length;
746 	data.access_check_len = enc_xs->length;
747 
748 	/* We want the blob to persist after this function so we don't
749 	 * allocate it in the stack
750 	 */
751 	blob2 = talloc(tctx, DATA_BLOB);
752 	if (blob2 == NULL) {
753 		return NULL;
754 	}
755 
756 	ndr_err = ndr_push_struct_blob(blob2, tctx, &data,
757 			(ndr_push_flags_fn_t)ndr_push_bkrp_client_side_wrapped);
758 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
759 		return NULL;
760 	}
761 
762 	if (broken_cert_guid) {
763 		blob2->data[12]++;
764 	}
765 
766 	ZERO_STRUCT(*r);
767 
768 	g = talloc(tctx, struct GUID);
769 	if (g == NULL) {
770 		return NULL;
771 	}
772 
773 	status = GUID_from_string(BACKUPKEY_RESTORE_GUID, g);
774 	if (!NT_STATUS_IS_OK(status)) {
775 		return NULL;
776 	}
777 
778 	r->in.guidActionAgent = g;
779 	r->in.data_in = blob2->data;
780 	r->in.data_in_len = blob2->length;
781 	r->in.param = 0;
782 	r->out.data_out = &(out->data);
783 	r->out.data_out_len = talloc(r, uint32_t);
784 	return r;
785 }
786 
787 /* Check that we are able to receive the certificate of the DCs
788  * used for client wrap version of the backup key protocol
789  */
test_RetrieveBackupKeyGUID(struct torture_context * tctx,struct dcerpc_pipe * p)790 static bool test_RetrieveBackupKeyGUID(struct torture_context *tctx,
791 					struct dcerpc_pipe *p)
792 {
793 	struct dcerpc_binding_handle *b = p->binding_handle;
794 	DATA_BLOB out_blob;
795 	struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
796 	enum dcerpc_AuthType auth_type;
797 	enum dcerpc_AuthLevel auth_level;
798 
799 	if (r == NULL) {
800 		return false;
801 	}
802 
803 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
804 
805 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
806 		torture_assert_ntstatus_ok(tctx,
807 				dcerpc_bkrp_BackupKey_r(b, tctx, r),
808 				"Get GUID");
809 
810 		out_blob.length = *r->out.data_out_len;
811 		torture_assert_werr_equal(tctx,
812 						r->out.result,
813 						WERR_OK,
814 						"Wrong dce/rpc error code");
815 	} else {
816 		torture_assert_ntstatus_equal(tctx,
817 						dcerpc_bkrp_BackupKey_r(b, tctx, r),
818 						NT_STATUS_ACCESS_DENIED,
819 						"Get GUID");
820 	}
821 	return true;
822 }
823 
824 /* Test to check the failure to recover a secret because the
825  * secret blob is not reversed
826  */
test_RestoreGUID_ko(struct torture_context * tctx,struct dcerpc_pipe * p)827 static bool test_RestoreGUID_ko(struct torture_context *tctx,
828 				struct dcerpc_pipe *p)
829 {
830 	enum ndr_err_code ndr_err;
831 	struct dcerpc_binding_handle *b = p->binding_handle;
832 	DATA_BLOB out_blob;
833 	struct bkrp_client_side_unwrapped resp;
834 	enum dcerpc_AuthType auth_type;
835 	enum dcerpc_AuthLevel auth_level;
836 
837 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
838 
839 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
840 		struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
841 					true, false, false, false, false, false, false);
842 		torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
843 		torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
844 		out_blob.length = *r->out.data_out_len;
845 		ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
846 		torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
847 		torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAMETER, "Wrong error code");
848 	} else {
849 		struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
850 		torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
851 			NT_STATUS_ACCESS_DENIED, "Get GUID");
852 	}
853 
854 	return true;
855 }
856 
test_RestoreGUID_wrongversion(struct torture_context * tctx,struct dcerpc_pipe * p)857 static bool test_RestoreGUID_wrongversion(struct torture_context *tctx,
858 					  struct dcerpc_pipe *p)
859 {
860 	enum ndr_err_code ndr_err;
861 	struct dcerpc_binding_handle *b = p->binding_handle;
862 	DATA_BLOB out_blob;
863 	struct bkrp_client_side_unwrapped resp;
864 	enum dcerpc_AuthType auth_type;
865 	enum dcerpc_AuthLevel auth_level;
866 
867 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
868 
869 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
870 		struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
871 					false, true, false, false, false, false, false);
872 		torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
873 		torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
874 		out_blob.length = *r->out.data_out_len;
875 		ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
876 		torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
877 		torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAMETER, "Wrong error code on wrong version");
878 	} else {
879 		struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
880 		torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
881 			NT_STATUS_ACCESS_DENIED, "Get GUID");
882 	}
883 
884 	return true;
885 }
886 
test_RestoreGUID_wronguser(struct torture_context * tctx,struct dcerpc_pipe * p)887 static bool test_RestoreGUID_wronguser(struct torture_context *tctx,
888 				       struct dcerpc_pipe *p)
889 {
890 	enum ndr_err_code ndr_err;
891 	struct dcerpc_binding_handle *b = p->binding_handle;
892 	DATA_BLOB out_blob;
893 	struct bkrp_client_side_unwrapped resp;
894 	enum dcerpc_AuthType auth_type;
895 	enum dcerpc_AuthLevel auth_level;
896 
897 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
898 
899 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
900 		struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
901 					false, false, true, false, false, false, false);
902 		torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
903 		torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
904 		out_blob.length = *r->out.data_out_len;
905 		ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
906 		torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
907 		torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_ACCESS, "Restore GUID");
908 	} else {
909 		struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
910 		torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
911 			NT_STATUS_ACCESS_DENIED, "Get GUID");
912 	}
913 
914 	return true;
915 }
916 
test_RestoreGUID_v3(struct torture_context * tctx,struct dcerpc_pipe * p)917 static bool test_RestoreGUID_v3(struct torture_context *tctx,
918 				struct dcerpc_pipe *p)
919 {
920 	enum ndr_err_code ndr_err;
921 	struct dcerpc_binding_handle *b = p->binding_handle;
922 	DATA_BLOB out_blob;
923 	struct bkrp_client_side_unwrapped resp;
924 	enum dcerpc_AuthType auth_type;
925 	enum dcerpc_AuthLevel auth_level;
926 
927 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
928 
929 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
930 		struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob,
931 					false, false, false, false, false, false, false);
932 		torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
933 		torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
934 		out_blob.length = *r->out.data_out_len;
935 		ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
936 		torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 1, "Unable to unmarshall bkrp_client_side_unwrapped");
937 		torture_assert_werr_equal(tctx, r->out.result, WERR_OK, "Restore GUID");
938 		torture_assert_str_equal(tctx, (char*)resp.secret.data, secret, "Wrong secret");
939 	} else {
940 		struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
941 		torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
942 			NT_STATUS_ACCESS_DENIED, "Get GUID");
943 	}
944 
945 	return true;
946 }
947 
test_RestoreGUID(struct torture_context * tctx,struct dcerpc_pipe * p)948 static bool test_RestoreGUID(struct torture_context *tctx,
949 			     struct dcerpc_pipe *p)
950 {
951 	struct dcerpc_binding_handle *b = p->binding_handle;
952 	DATA_BLOB out_blob;
953 	struct bkrp_client_side_unwrapped resp;
954 	enum dcerpc_AuthType auth_type;
955 	enum dcerpc_AuthLevel auth_level;
956 
957 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
958 
959 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
960 		struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
961 					false, false, false, false, false, false, false);
962 		torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
963 		torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
964 		out_blob.length = *r->out.data_out_len;
965 		torture_assert_werr_equal(tctx, r->out.result, WERR_OK, "Restore GUID");
966 		torture_assert_ndr_err_equal(tctx,
967 					     ndr_pull_struct_blob(&out_blob, tctx, &resp,
968 								(ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped),
969 					     NDR_ERR_SUCCESS,
970 					     "Unable to unmarshall bkrp_client_side_unwrapped");
971 		torture_assert_str_equal(tctx, (char*)resp.secret.data, secret, "Wrong secret");
972 	} else {
973 		struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
974 		torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
975 			NT_STATUS_ACCESS_DENIED, "Get GUID");
976 	}
977 
978 	return true;
979 }
980 
test_RestoreGUID_badmagiconsecret(struct torture_context * tctx,struct dcerpc_pipe * p)981 static bool test_RestoreGUID_badmagiconsecret(struct torture_context *tctx,
982 					      struct dcerpc_pipe *p)
983 {
984 	enum ndr_err_code ndr_err;
985 	struct dcerpc_binding_handle *b = p->binding_handle;
986 	DATA_BLOB out_blob;
987 	struct bkrp_client_side_unwrapped resp;
988 	enum dcerpc_AuthType auth_type;
989 	enum dcerpc_AuthLevel auth_level;
990 
991 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
992 
993 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
994 		struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob,
995 					false, false, false, true, false, false, false);
996 		torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
997 		torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
998 		out_blob.length = *r->out.data_out_len;
999 		ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
1000 		torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1001 		torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Wrong error code while providing bad magic in secret");
1002 	} else {
1003 		struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
1004 		torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
1005 			NT_STATUS_ACCESS_DENIED, "Get GUID");
1006 	}
1007 
1008 	return true;
1009 }
1010 
test_RestoreGUID_emptyrequest(struct torture_context * tctx,struct dcerpc_pipe * p)1011 static bool test_RestoreGUID_emptyrequest(struct torture_context *tctx,
1012 					  struct dcerpc_pipe *p)
1013 {
1014 	struct dcerpc_binding_handle *b = p->binding_handle;
1015 	DATA_BLOB out_blob;
1016 	enum dcerpc_AuthType auth_type;
1017 	enum dcerpc_AuthLevel auth_level;
1018 
1019 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1020 
1021 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1022 		struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob,
1023 					false, false, false, true, false, false, true);
1024 
1025 		torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
1026 		r->in.data_in = talloc(tctx, uint8_t);
1027 		r->in.data_in_len = 0;
1028 		r->in.param = 0;
1029 		torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
1030 		out_blob.length = *r->out.data_out_len;
1031 		torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAMETER, "Bad error code on wrong has in access check");
1032 	} else {
1033 		struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
1034 		torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
1035 			NT_STATUS_ACCESS_DENIED, "Get GUID");
1036 	}
1037 
1038 	return true;
1039 }
1040 
test_RestoreGUID_badcertguid(struct torture_context * tctx,struct dcerpc_pipe * p)1041 static bool test_RestoreGUID_badcertguid(struct torture_context *tctx,
1042 					 struct dcerpc_pipe *p)
1043 {
1044 	enum ndr_err_code ndr_err;
1045 	struct dcerpc_binding_handle *b = p->binding_handle;
1046 	DATA_BLOB out_blob;
1047 	struct bkrp_client_side_unwrapped resp;
1048 	enum dcerpc_AuthType auth_type;
1049 	enum dcerpc_AuthLevel auth_level;
1050 
1051 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1052 
1053 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1054 		struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob,
1055 					false, false, false, false, false, false, true);
1056 		torture_assert(tctx, r != NULL, "createRestoreGUIDStruct() failed");
1057 		torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
1058 		out_blob.length = *r->out.data_out_len;
1059 		ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
1060 		torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1061 
1062 		/*
1063 		 * Windows 2012R2 has, presumably, a programming error
1064 		 * returning an NTSTATUS code on this interface
1065 		 */
1066 		if (W_ERROR_V(r->out.result) != NT_STATUS_V(NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1067 			torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Bad error code on wrong has in access check");
1068 		}
1069 	} else {
1070 		struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
1071 		torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
1072 			NT_STATUS_ACCESS_DENIED, "Get GUID");
1073 	}
1074 
1075 	return true;
1076 }
1077 
test_RestoreGUID_badmagicaccesscheck(struct torture_context * tctx,struct dcerpc_pipe * p)1078 static bool test_RestoreGUID_badmagicaccesscheck(struct torture_context *tctx,
1079 						 struct dcerpc_pipe *p)
1080 {
1081 	enum ndr_err_code ndr_err;
1082 	struct dcerpc_binding_handle *b = p->binding_handle;
1083 	DATA_BLOB out_blob;
1084 	struct bkrp_client_side_unwrapped resp;
1085 	enum dcerpc_AuthType auth_type;
1086 	enum dcerpc_AuthLevel auth_level;
1087 
1088 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1089 
1090 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1091 		struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
1092 					false, false, false, false, true, false, false);
1093 		torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
1094 		torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
1095 		out_blob.length = *r->out.data_out_len;
1096 		ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
1097 		torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1098 		torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Bad error code on wrong has in access check");
1099 	} else {
1100 		struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
1101 		torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
1102 			NT_STATUS_ACCESS_DENIED, "Get GUID");
1103 	}
1104 
1105 	return true;
1106 }
1107 
test_RestoreGUID_badhashaccesscheck(struct torture_context * tctx,struct dcerpc_pipe * p)1108 static bool test_RestoreGUID_badhashaccesscheck(struct torture_context *tctx,
1109 						struct dcerpc_pipe *p)
1110 {
1111 	enum ndr_err_code ndr_err;
1112 	struct dcerpc_binding_handle *b = p->binding_handle;
1113 	DATA_BLOB out_blob;
1114 	struct bkrp_client_side_unwrapped resp;
1115 	enum dcerpc_AuthType auth_type;
1116 	enum dcerpc_AuthLevel auth_level;
1117 
1118 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1119 
1120 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1121 		struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
1122 					false, false, false, false, false, true, false);
1123 		torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
1124 		torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
1125 		out_blob.length = *r->out.data_out_len;
1126 		ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
1127 		torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1128 		torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Bad error code on wrong has in access check");
1129 	} else {
1130 		struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
1131 		torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
1132 			NT_STATUS_ACCESS_DENIED, "Get GUID");
1133 	}
1134 
1135 	return true;
1136 }
1137 
1138 /*
1139  * Check that the RSA modulus in the certificate of the DCs has 2048 bits.
1140  */
test_RetrieveBackupKeyGUID_validate(struct torture_context * tctx,struct dcerpc_pipe * p)1141 static bool test_RetrieveBackupKeyGUID_validate(struct torture_context *tctx,
1142 						struct dcerpc_pipe *p)
1143 {
1144 	struct dcerpc_binding_handle *b = p->binding_handle;
1145 	DATA_BLOB out_blob;
1146 	struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
1147 	enum dcerpc_AuthType auth_type;
1148 	enum dcerpc_AuthLevel auth_level;
1149 
1150 	torture_assert(tctx, r != NULL, "test_RetrieveBackupKeyGUID_validate failed");
1151 
1152 	if (r == NULL) {
1153 		return false;
1154 	}
1155 
1156 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1157 
1158 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1159 		gnutls_x509_crt_t x509_cert = NULL;
1160 		gnutls_pubkey_t pubkey = NULL;
1161 		gnutls_datum_t x509_crt_data;
1162 		gnutls_pk_algorithm_t pubkey_algo;
1163 		uint8_t dummy[1] = {0};
1164 		DATA_BLOB subject_unique_id = {
1165 			.data = dummy,
1166 			.length = 0,
1167 		};
1168 		DATA_BLOB issuer_unique_id = {
1169 			.data = dummy,
1170 			.length = 0,
1171 		};
1172 		DATA_BLOB reversed = {
1173 			.data = dummy,
1174 			.length = 0,
1175 		};
1176 		DATA_BLOB serial_number;
1177 		unsigned int RSA_returned_bits = 0;
1178 		int version;
1179 		size_t i;
1180 		int cmp;
1181 		int rc;
1182 
1183 		torture_assert_ntstatus_ok(tctx,
1184 				dcerpc_bkrp_BackupKey_r(b, tctx, r),
1185 				"Get GUID");
1186 
1187 		torture_assert_werr_ok(tctx, r->out.result,
1188 				       "Get GUID");
1189 
1190 		out_blob.length = *r->out.data_out_len;
1191 
1192 		x509_crt_data.data = out_blob.data;
1193 		x509_crt_data.size = out_blob.length;
1194 
1195 		rc = gnutls_x509_crt_init(&x509_cert);
1196 		if (rc != GNUTLS_E_SUCCESS) {
1197 			return NULL;
1198 		}
1199 
1200 		rc = gnutls_x509_crt_import(x509_cert,
1201 					    &x509_crt_data,
1202 					    GNUTLS_X509_FMT_DER);
1203 		torture_assert_int_equal(tctx,
1204 					 rc,
1205 					 GNUTLS_E_SUCCESS,
1206 					 "gnutls_x509_crt_import failed");
1207 
1208 		/* Compare unique ids */
1209 
1210 		/* Get buffer size */
1211 		rc = gnutls_x509_crt_get_subject_unique_id(x509_cert,
1212 							   (char *)subject_unique_id.data,
1213 							   &subject_unique_id.length);
1214 		torture_assert_int_equal(tctx,
1215 					 rc,
1216 					 GNUTLS_E_SHORT_MEMORY_BUFFER,
1217 					 "gnutls_x509_crt_get_subject_unique_id "
1218 					 "get buffer size failed");
1219 
1220 		subject_unique_id = data_blob_talloc_zero(tctx,
1221 							  subject_unique_id.length);
1222 
1223 		rc = gnutls_x509_crt_get_subject_unique_id(x509_cert,
1224 							   (char *)subject_unique_id.data,
1225 							   &subject_unique_id.length);
1226 		torture_assert_int_equal(tctx,
1227 					 rc,
1228 					 GNUTLS_E_SUCCESS,
1229 					 "gnutls_x509_crt_get_subject_unique_id failed");
1230 
1231 		rc = gnutls_x509_crt_get_issuer_unique_id(x509_cert,
1232 							  (char *)issuer_unique_id.data,
1233 							  &issuer_unique_id.length);
1234 		torture_assert_int_equal(tctx,
1235 					 rc,
1236 					 GNUTLS_E_SHORT_MEMORY_BUFFER,
1237 					 "gnutls_x509_crt_get_issuer_unique_id "
1238 					 "get buffer size failed");
1239 
1240 		issuer_unique_id = data_blob_talloc_zero(tctx,
1241 							 issuer_unique_id.length);
1242 
1243 		rc = gnutls_x509_crt_get_issuer_unique_id(x509_cert,
1244 							  (char *)issuer_unique_id.data,
1245 							  &issuer_unique_id.length);
1246 		torture_assert_int_equal(tctx,
1247 					 rc,
1248 					 GNUTLS_E_SUCCESS,
1249 					 "gnutls_x509_crt_get_issuer_unique_id failed");
1250 
1251 		cmp = data_blob_cmp(&subject_unique_id, &issuer_unique_id);
1252 		torture_assert(tctx,
1253 			       cmp == 0,
1254 			       "The GUID to identify the public key is not "
1255 			       "identical");
1256 
1257 		rc = gnutls_x509_crt_get_serial(x509_cert,
1258 						reversed.data,
1259 						&reversed.length);
1260 		torture_assert_int_equal(tctx,
1261 					 rc,
1262 					 GNUTLS_E_SHORT_MEMORY_BUFFER,
1263 					 "gnutls_x509_crt_get_serial "
1264 					 "get buffer size failed");
1265 
1266 		reversed = data_blob_talloc_zero(tctx,
1267 						 reversed.length);
1268 
1269 		rc = gnutls_x509_crt_get_serial(x509_cert,
1270 						reversed.data,
1271 						&reversed.length);
1272 		torture_assert_int_equal(tctx,
1273 					 rc,
1274 					 GNUTLS_E_SUCCESS,
1275 					 "gnutls_x509_crt_get_serial failed");
1276 
1277 		/*
1278 		 * Heimdal sometimes adds a leading byte to the data buffer of
1279 		 * the serial number. So lets uses the subject_unique_id size
1280 		 * and ignore the leading byte.
1281 		 */
1282 		serial_number = data_blob_talloc_zero(tctx,
1283 						      subject_unique_id.length);
1284 
1285 		for (i = 0; i < serial_number.length; i++) {
1286 			serial_number.data[i] = reversed.data[reversed.length - i - 1];
1287 		}
1288 
1289 		cmp = data_blob_cmp(&subject_unique_id, &serial_number);
1290 		torture_assert(tctx,
1291 			       cmp == 0,
1292 			       "The GUID to identify the public key is not "
1293 			       "identical");
1294 
1295 		/* Check certificate version */
1296 		version = gnutls_x509_crt_get_version(x509_cert);
1297 		torture_assert_int_equal(tctx,
1298 					 version,
1299 					 3,
1300 					 "Invalid certificate version");
1301 
1302 		/* Get the public key */
1303 		rc = gnutls_pubkey_init(&pubkey);
1304 		torture_assert_int_equal(tctx,
1305 					 rc,
1306 					 GNUTLS_E_SUCCESS,
1307 					 "gnutls_pubkey_init failed");
1308 
1309 		rc = gnutls_pubkey_import_x509(pubkey,
1310 					       x509_cert,
1311 					       0);
1312 		gnutls_x509_crt_deinit(x509_cert);
1313 		torture_assert_int_equal(tctx,
1314 					 rc,
1315 					 GNUTLS_E_SUCCESS,
1316 					 "gnutls_pubkey_import_x509 failed");
1317 
1318 		pubkey_algo = gnutls_pubkey_get_pk_algorithm(pubkey,
1319 							     &RSA_returned_bits);
1320 		gnutls_pubkey_deinit(pubkey);
1321 		torture_assert_int_equal(tctx,
1322 					 pubkey_algo,
1323 					 GNUTLS_PK_RSA,
1324 					 "gnutls_pubkey_get_pk_algorithm did "
1325 					 "not return a RSA key");
1326 		torture_assert_int_equal(tctx,
1327 						RSA_returned_bits,
1328 						2048,
1329 						"RSA Key doesn't have 2048 bits");
1330 	} else {
1331 		torture_assert_ntstatus_equal(tctx,
1332 						dcerpc_bkrp_BackupKey_r(b, tctx, r),
1333 						NT_STATUS_ACCESS_DENIED,
1334 						"Get GUID");
1335 	}
1336 
1337 	return true;
1338 }
1339 
test_ServerWrap_encrypt_decrypt(struct torture_context * tctx,struct dcerpc_pipe * p)1340 static bool test_ServerWrap_encrypt_decrypt(struct torture_context *tctx,
1341 					    struct dcerpc_pipe *p)
1342 {
1343 	struct bkrp_BackupKey r;
1344 	struct GUID guid;
1345 	DATA_BLOB plaintext = data_blob_const(secret, sizeof(secret));
1346 	DATA_BLOB encrypted;
1347 	uint32_t enclen;
1348 	DATA_BLOB decrypted;
1349 	uint32_t declen;
1350 	struct dcerpc_binding_handle *b = p->binding_handle;
1351 	enum dcerpc_AuthType auth_type;
1352 	enum dcerpc_AuthLevel auth_level;
1353 	ZERO_STRUCT(r);
1354 
1355 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1356 
1357 	/* Encrypt */
1358 	torture_assert_ntstatus_ok(tctx,
1359 				   GUID_from_string(BACKUPKEY_BACKUP_GUID, &guid),
1360 				   "obtain GUID");
1361 
1362 	r.in.guidActionAgent = &guid;
1363 	r.in.data_in = plaintext.data;
1364 	r.in.data_in_len = plaintext.length;
1365 	r.in.param = 0;
1366 	r.out.data_out = &encrypted.data;
1367 	r.out.data_out_len = &enclen;
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;
1378 	}
1379 	torture_assert_werr_ok(tctx,
1380 			       r.out.result,
1381 			       "encrypt");
1382 	encrypted.length = *r.out.data_out_len;
1383 
1384 	/* Decrypt */
1385 	torture_assert_ntstatus_ok(tctx,
1386 				   GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1387 				   "obtain GUID");
1388 
1389 	r.in.guidActionAgent = &guid;
1390 	r.in.data_in = encrypted.data;
1391 	r.in.data_in_len = encrypted.length;
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_ok(tctx,
1399 			       r.out.result,
1400 			       "decrypt");
1401 	decrypted.length = *r.out.data_out_len;
1402 
1403 	/* Compare */
1404 	torture_assert_data_blob_equal(tctx, plaintext, decrypted, "Decrypt failed");
1405 
1406 	/* Decrypt */
1407 	torture_assert_ntstatus_ok(tctx,
1408 				   GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1409 				   "obtain GUID");
1410 
1411 	r.in.guidActionAgent = &guid;
1412 	r.in.data_in = encrypted.data;
1413 	r.in.data_in_len = encrypted.length;
1414 	r.in.param = 0;
1415 	r.out.data_out = &(decrypted.data);
1416 	r.out.data_out_len = &declen;
1417 	torture_assert_ntstatus_ok(tctx,
1418 				   dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1419 				   "decrypt");
1420 	torture_assert_werr_ok(tctx,
1421 			       r.out.result,
1422 			       "decrypt");
1423 	decrypted.length = *r.out.data_out_len;
1424 
1425 	/* Compare */
1426 	torture_assert_data_blob_equal(tctx, plaintext, decrypted, "Decrypt failed");
1427 	return true;
1428 }
1429 
test_ServerWrap_decrypt_wrong_keyGUID(struct torture_context * tctx,struct dcerpc_pipe * p)1430 static bool test_ServerWrap_decrypt_wrong_keyGUID(struct torture_context *tctx,
1431 						  struct dcerpc_pipe *p)
1432 {
1433 	struct bkrp_BackupKey r;
1434 	struct GUID guid;
1435 	DATA_BLOB plaintext = data_blob_const(secret, sizeof(secret));
1436 	DATA_BLOB encrypted;
1437 	uint32_t enclen;
1438 	DATA_BLOB decrypted;
1439 	uint32_t declen;
1440 	struct dcerpc_binding_handle *b = p->binding_handle;
1441 	enum ndr_err_code ndr_err;
1442 	struct bkrp_server_side_wrapped server_side_wrapped;
1443 	enum dcerpc_AuthType auth_type;
1444 	enum dcerpc_AuthLevel auth_level;
1445 	ZERO_STRUCT(r);
1446 
1447 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1448 
1449 	/* Encrypt */
1450 	torture_assert_ntstatus_ok(tctx,
1451 				   GUID_from_string(BACKUPKEY_BACKUP_GUID, &guid),
1452 				   "obtain GUID");
1453 
1454 	r.in.guidActionAgent = &guid;
1455 	r.in.data_in = plaintext.data;
1456 	r.in.data_in_len = plaintext.length;
1457 	r.in.param = 0;
1458 	r.out.data_out = &encrypted.data;
1459 	r.out.data_out_len = &enclen;
1460 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1461 		torture_assert_ntstatus_ok(tctx,
1462 					   dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1463 					   "encrypt");
1464 	} else {
1465 		torture_assert_ntstatus_equal(tctx,
1466 					      dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1467 					      NT_STATUS_ACCESS_DENIED,
1468 					      "encrypt");
1469 		return true;
1470 	}
1471 	torture_assert_werr_ok(tctx,
1472 			       r.out.result,
1473 			       "encrypt");
1474 	encrypted.length = *r.out.data_out_len;
1475 
1476 	ndr_err = ndr_pull_struct_blob(&encrypted, tctx, &server_side_wrapped,
1477 				       (ndr_pull_flags_fn_t)ndr_pull_bkrp_server_side_wrapped);
1478 	torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "pull of server_side_wrapped");
1479 
1480 	/* Change the GUID */
1481 	server_side_wrapped.guid = GUID_random();
1482 
1483 	ndr_err = ndr_push_struct_blob(&encrypted, tctx, &server_side_wrapped,
1484 				       (ndr_push_flags_fn_t)ndr_push_bkrp_server_side_wrapped);
1485 	torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "push of server_side_wrapped");
1486 
1487 	/* Decrypt */
1488 	torture_assert_ntstatus_ok(tctx,
1489 				   GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1490 				   "obtain GUID");
1491 
1492 	r.in.guidActionAgent = &guid;
1493 	r.in.data_in = encrypted.data;
1494 	r.in.data_in_len = encrypted.length;
1495 	r.in.param = 0;
1496 	r.out.data_out = &(decrypted.data);
1497 	r.out.data_out_len = &declen;
1498 	torture_assert_ntstatus_ok(tctx,
1499 				   dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1500 				   "decrypt");
1501 	torture_assert_werr_equal(tctx,
1502 				  r.out.result,
1503 				  WERR_INVALID_DATA,
1504 				  "decrypt should fail with WERR_INVALID_DATA");
1505 
1506 	/* Decrypt */
1507 	torture_assert_ntstatus_ok(tctx,
1508 				   GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1509 				   "obtain GUID");
1510 
1511 	r.in.guidActionAgent = &guid;
1512 	r.in.data_in = encrypted.data;
1513 	r.in.data_in_len = encrypted.length;
1514 	r.in.param = 0;
1515 	r.out.data_out = &(decrypted.data);
1516 	r.out.data_out_len = &declen;
1517 	torture_assert_ntstatus_ok(tctx,
1518 				   dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1519 				   "decrypt");
1520 	torture_assert_werr_equal(tctx,
1521 				  r.out.result,
1522 				  WERR_INVALID_DATA,
1523 				  "decrypt should fail with WERR_INVALID_DATA");
1524 
1525 	return true;
1526 }
1527 
test_ServerWrap_decrypt_empty_request(struct torture_context * tctx,struct dcerpc_pipe * p)1528 static bool test_ServerWrap_decrypt_empty_request(struct torture_context *tctx,
1529 						 struct dcerpc_pipe *p)
1530 {
1531 	struct bkrp_BackupKey r;
1532 	struct GUID guid;
1533 	DATA_BLOB decrypted;
1534 	uint32_t declen;
1535 	struct dcerpc_binding_handle *b = p->binding_handle;
1536 	uint8_t short_request[4] = { 1, 0, 0, 0 };
1537 	enum dcerpc_AuthType auth_type;
1538 	enum dcerpc_AuthLevel auth_level;
1539 	ZERO_STRUCT(r);
1540 
1541 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1542 
1543 	/* Decrypt */
1544 	torture_assert_ntstatus_ok(tctx,
1545 				   GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1546 				   "obtain GUID");
1547 
1548 	r.in.guidActionAgent = &guid;
1549 	r.in.data_in = short_request;
1550 	r.in.data_in_len = 0;
1551 	r.in.param = 0;
1552 	r.out.data_out = &(decrypted.data);
1553 	r.out.data_out_len = &declen;
1554 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1555 		torture_assert_ntstatus_ok(tctx,
1556 					   dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1557 					   "encrypt");
1558 	} else {
1559 		torture_assert_ntstatus_equal(tctx,
1560 					      dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1561 					      NT_STATUS_ACCESS_DENIED,
1562 					      "encrypt");
1563 		return true;
1564 	}
1565 	torture_assert_werr_equal(tctx,
1566 				  r.out.result,
1567 				  WERR_INVALID_PARAMETER,
1568 				  "decrypt should fail with WERR_INVALID_PARAMETER");
1569 
1570 	/* Decrypt */
1571 	torture_assert_ntstatus_ok(tctx,
1572 				   GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1573 				   "obtain GUID");
1574 
1575 	r.in.guidActionAgent = &guid;
1576 	r.in.data_in = short_request;
1577 	r.in.data_in_len = 0;
1578 	r.in.param = 0;
1579 	r.out.data_out = &(decrypted.data);
1580 	r.out.data_out_len = &declen;
1581 	torture_assert_ntstatus_ok(tctx,
1582 				   dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1583 				   "decrypt");
1584 	torture_assert_werr_equal(tctx,
1585 				  r.out.result,
1586 				  WERR_INVALID_PARAMETER,
1587 				  "decrypt should fail with WERR_INVALID_PARAMETER");
1588 
1589 	/* Decrypt */
1590 	torture_assert_ntstatus_ok(tctx,
1591 				   GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1592 				   "obtain GUID");
1593 
1594 	r.in.guidActionAgent = &guid;
1595 	r.in.data_in = NULL;
1596 	r.in.data_in_len = 0;
1597 	r.in.param = 0;
1598 	r.out.data_out = &(decrypted.data);
1599 	r.out.data_out_len = &declen;
1600 	torture_assert_ntstatus_equal(tctx,
1601 				      dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1602 				      NT_STATUS_INVALID_PARAMETER_MIX,
1603 				      "decrypt");
1604 
1605 	/* Decrypt */
1606 	torture_assert_ntstatus_ok(tctx,
1607 				   GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1608 				   "obtain GUID");
1609 
1610 	r.in.guidActionAgent = &guid;
1611 	r.in.data_in = NULL;
1612 	r.in.data_in_len = 0;
1613 	r.in.param = 0;
1614 	r.out.data_out = &(decrypted.data);
1615 	r.out.data_out_len = &declen;
1616 	torture_assert_ntstatus_equal(tctx,
1617 				      dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1618 				      NT_STATUS_INVALID_PARAMETER_MIX,
1619 				      "decrypt");
1620 
1621 	return true;
1622 }
1623 
1624 
test_ServerWrap_decrypt_short_request(struct torture_context * tctx,struct dcerpc_pipe * p)1625 static bool test_ServerWrap_decrypt_short_request(struct torture_context *tctx,
1626 						 struct dcerpc_pipe *p)
1627 {
1628 	struct bkrp_BackupKey r;
1629 	struct GUID guid;
1630 	DATA_BLOB decrypted;
1631 	uint32_t declen;
1632 	struct dcerpc_binding_handle *b = p->binding_handle;
1633 	uint8_t short_request[4] = { 1, 0, 0, 0 };
1634 	enum dcerpc_AuthType auth_type;
1635 	enum dcerpc_AuthLevel auth_level;
1636 	ZERO_STRUCT(r);
1637 
1638 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1639 
1640 	/* Decrypt */
1641 	torture_assert_ntstatus_ok(tctx,
1642 				   GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1643 				   "obtain GUID");
1644 
1645 	r.in.guidActionAgent = &guid;
1646 	r.in.data_in = short_request;
1647 	r.in.data_in_len = 4;
1648 	r.in.param = 0;
1649 	r.out.data_out = &(decrypted.data);
1650 	r.out.data_out_len = &declen;
1651 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1652 		torture_assert_ntstatus_ok(tctx,
1653 					   dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1654 					   "encrypt");
1655 	} else {
1656 		torture_assert_ntstatus_equal(tctx,
1657 					      dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1658 					      NT_STATUS_ACCESS_DENIED,
1659 					      "encrypt");
1660 		return true;
1661 	}
1662 	torture_assert_werr_equal(tctx,
1663 				  r.out.result,
1664 				  WERR_INVALID_PARAMETER,
1665 				  "decrypt should fail with WERR_INVALID_PARM");
1666 
1667 	/* Decrypt */
1668 	torture_assert_ntstatus_ok(tctx,
1669 				   GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1670 				   "obtain GUID");
1671 
1672 	r.in.guidActionAgent = &guid;
1673 	r.in.data_in = short_request;
1674 	r.in.data_in_len = 4;
1675 	r.in.param = 0;
1676 	r.out.data_out = &(decrypted.data);
1677 	r.out.data_out_len = &declen;
1678 	torture_assert_ntstatus_ok(tctx,
1679 				   dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1680 				   "decrypt");
1681 	torture_assert_werr_equal(tctx,
1682 				  r.out.result,
1683 				  WERR_INVALID_PARAMETER,
1684 				  "decrypt should fail with WERR_INVALID_PARAMETER");
1685 
1686 	/* Decrypt */
1687 	torture_assert_ntstatus_ok(tctx,
1688 				   GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1689 				   "obtain GUID");
1690 
1691 	r.in.guidActionAgent = &guid;
1692 	r.in.data_in = short_request;
1693 	r.in.data_in_len = 1;
1694 	r.in.param = 0;
1695 	r.out.data_out = &(decrypted.data);
1696 	r.out.data_out_len = &declen;
1697 	torture_assert_ntstatus_ok(tctx,
1698 				   dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1699 				   "decrypt");
1700 	torture_assert_werr_equal(tctx,
1701 				  r.out.result,
1702 				  WERR_INVALID_PARAMETER,
1703 				  "decrypt should fail with WERR_INVALID_PARAMETER");
1704 
1705 	/* Decrypt */
1706 	torture_assert_ntstatus_ok(tctx,
1707 				   GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1708 				   "obtain GUID");
1709 
1710 	r.in.guidActionAgent = &guid;
1711 	r.in.data_in = short_request;
1712 	r.in.data_in_len = 1;
1713 	r.in.param = 0;
1714 	r.out.data_out = &(decrypted.data);
1715 	r.out.data_out_len = &declen;
1716 	torture_assert_ntstatus_ok(tctx,
1717 				   dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1718 				   "decrypt");
1719 	torture_assert_werr_equal(tctx,
1720 				  r.out.result,
1721 				  WERR_INVALID_PARAMETER,
1722 				  "decrypt should fail with WERR_INVALID_PARAMETER");
1723 
1724 	return true;
1725 }
1726 
test_ServerWrap_encrypt_decrypt_manual(struct torture_context * tctx,struct bkrp_server_side_wrapped * server_side_wrapped,enum test_wrong wrong)1727 static bool test_ServerWrap_encrypt_decrypt_manual(struct torture_context *tctx,
1728 						   struct bkrp_server_side_wrapped *server_side_wrapped,
1729 						   enum test_wrong wrong)
1730 {
1731 	char *lsa_binding_string = NULL;
1732 	struct dcerpc_binding *lsa_binding = NULL;
1733 	struct dcerpc_pipe *lsa_p = NULL;
1734 	struct dcerpc_binding_handle *lsa_b = NULL;
1735 	struct lsa_OpenSecret r_secret;
1736 	struct lsa_QuerySecret r_query_secret;
1737 	struct policy_handle *handle, sec_handle;
1738 	struct bkrp_BackupKey r;
1739 	struct GUID preferred_key_guid;
1740 	DATA_BLOB plaintext = data_blob_const(secret, sizeof(secret));
1741 	DATA_BLOB preferred_key, preferred_key_clear, session_key,
1742 		decrypt_key, decrypt_key_clear, encrypted_blob,
1743 		sid_blob;
1744 	struct bkrp_dc_serverwrap_key server_key;
1745 	struct lsa_DATA_BUF_PTR bufp1;
1746 	char *key_guid_string;
1747 	struct bkrp_rc4encryptedpayload rc4payload;
1748 	struct dom_sid *caller_sid;
1749 	uint8_t symkey[20]; /* SHA-1 hash len */
1750 	uint8_t mackey[20]; /* SHA-1 hash len */
1751 	uint8_t mac[20]; /* SHA-1 hash len */
1752 	gnutls_hmac_hd_t hmac_hnd;
1753 	gnutls_cipher_hd_t cipher_hnd;
1754 	gnutls_datum_t cipher_key;
1755 	int rc;
1756 
1757 	ZERO_STRUCT(r);
1758 	ZERO_STRUCT(r_secret);
1759 	ZERO_STRUCT(r_query_secret);
1760 
1761 	/* Now read BCKUPKEY_P and prove we can do a matching decrypt and encrypt */
1762 
1763 	/* lsa_OpenSecret only works with ncacn_np and AUTH_LEVEL_NONE */
1764 	lsa_binding_string = talloc_asprintf(tctx, "ncacn_np:%s",
1765 				torture_setting_string(tctx, "host", NULL));
1766 	torture_assert(tctx, lsa_binding_string != NULL, "lsa_binding_string");
1767 
1768 	torture_assert_ntstatus_ok(tctx,
1769 		dcerpc_parse_binding(tctx, lsa_binding_string, &lsa_binding),
1770 		"Failed to parse dcerpc binding");
1771 
1772 	torture_assert_ntstatus_ok(tctx,
1773 				   dcerpc_pipe_connect_b(tctx, &lsa_p,
1774 					lsa_binding, &ndr_table_lsarpc,
1775 					popt_get_cmdline_credentials(),
1776 					tctx->ev, tctx->lp_ctx),
1777 				   "Opening LSA pipe");
1778 	lsa_b = lsa_p->binding_handle;
1779 
1780 	torture_assert(tctx, test_lsa_OpenPolicy2(lsa_b, tctx, &handle), "OpenPolicy failed");
1781 	r_secret.in.name.string = "G$BCKUPKEY_P";
1782 
1783 	r_secret.in.handle = handle;
1784 	r_secret.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1785 	r_secret.out.sec_handle = &sec_handle;
1786 
1787 	torture_comment(tctx, "Testing OpenSecret\n");
1788 
1789 	torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(lsa_b, tctx, &r_secret),
1790 				   "OpenSecret failed");
1791 	torture_assert_ntstatus_ok(tctx, r_secret.out.result,
1792 				   "OpenSecret failed");
1793 
1794 	r_query_secret.in.sec_handle = &sec_handle;
1795 	r_query_secret.in.new_val = &bufp1;
1796 	bufp1.buf = NULL;
1797 
1798 	torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(lsa_b, tctx, &r_query_secret),
1799 		"QuerySecret failed");
1800 	torture_assert_ntstatus_ok(tctx, r_query_secret.out.result,
1801 				   "QuerySecret failed");
1802 
1803 
1804 	preferred_key.data = r_query_secret.out.new_val->buf->data;
1805 	preferred_key.length = r_query_secret.out.new_val->buf->size;
1806 	torture_assert_ntstatus_ok(tctx, dcerpc_fetch_session_key(lsa_p, &session_key),
1807 				   "dcerpc_fetch_session_key failed");
1808 
1809 	torture_assert_ntstatus_ok(tctx,
1810 				   sess_decrypt_blob(tctx,
1811 						     &preferred_key, &session_key, &preferred_key_clear),
1812 				   "sess_decrypt_blob failed");
1813 
1814 	torture_assert_ntstatus_ok(tctx, GUID_from_ndr_blob(&preferred_key_clear, &preferred_key_guid),
1815 				   "GUID parse failed");
1816 
1817 	torture_assert_guid_equal(tctx, server_side_wrapped->guid,
1818 				  preferred_key_guid,
1819 				  "GUID didn't match value pointed at by G$BCKUPKEY_P");
1820 
1821 	/* And read BCKUPKEY_<guid> and get the actual key */
1822 
1823 	key_guid_string = GUID_string(tctx, &server_side_wrapped->guid);
1824 	r_secret.in.name.string = talloc_asprintf(tctx, "G$BCKUPKEY_%s", key_guid_string);
1825 
1826 	r_secret.in.handle = handle;
1827 	r_secret.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1828 	r_secret.out.sec_handle = &sec_handle;
1829 
1830 	torture_comment(tctx, "Testing OpenSecret\n");
1831 
1832 	torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(lsa_b, tctx, &r_secret),
1833 				   "OpenSecret failed");
1834 	torture_assert_ntstatus_ok(tctx, r_secret.out.result,
1835 				   "OpenSecret failed");
1836 
1837 	r_query_secret.in.sec_handle = &sec_handle;
1838 	r_query_secret.in.new_val = &bufp1;
1839 
1840 	torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(lsa_b, tctx, &r_query_secret),
1841 				   "QuerySecret failed");
1842 	torture_assert_ntstatus_ok(tctx, r_query_secret.out.result,
1843 				   "QuerySecret failed");
1844 
1845 
1846 	decrypt_key.data = r_query_secret.out.new_val->buf->data;
1847 	decrypt_key.length = r_query_secret.out.new_val->buf->size;
1848 
1849 	torture_assert_ntstatus_ok(tctx,
1850 				   sess_decrypt_blob(tctx,
1851 						     &decrypt_key, &session_key, &decrypt_key_clear),
1852 				   "sess_decrypt_blob failed");
1853 
1854 	torture_assert_ndr_err_equal(tctx, ndr_pull_struct_blob(&decrypt_key_clear, tctx, &server_key,
1855 								(ndr_pull_flags_fn_t)ndr_pull_bkrp_dc_serverwrap_key),
1856 				     NDR_ERR_SUCCESS, "Failed to parse server_key");
1857 
1858 	torture_assert_int_equal(tctx, server_key.magic, 1, "Failed to correctly decrypt server key");
1859 
1860 	/*
1861 	 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1862 	 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1863 	 */
1864 	gnutls_hmac_init(&hmac_hnd,
1865 			 GNUTLS_MAC_SHA1,
1866 			 server_key.key,
1867 			 sizeof(server_key.key));
1868 	gnutls_hmac(hmac_hnd,
1869 		    server_side_wrapped->r2,
1870 		    sizeof(server_side_wrapped->r2));
1871 	gnutls_hmac_output(hmac_hnd, symkey);
1872 
1873 	/* rc4 decrypt sid and secret using sym key */
1874 	cipher_key.data = symkey;
1875 	cipher_key.size = sizeof(symkey);
1876 
1877 	encrypted_blob = data_blob_talloc(tctx, server_side_wrapped->rc4encryptedpayload,
1878 					  server_side_wrapped->ciphertext_length);
1879 
1880 	rc = gnutls_cipher_init(&cipher_hnd,
1881 				GNUTLS_CIPHER_ARCFOUR_128,
1882 				&cipher_key,
1883 				NULL);
1884 	torture_assert_int_equal(tctx,
1885 				 rc,
1886 				 GNUTLS_E_SUCCESS,
1887 				 "gnutls_cipher_init failed");
1888 	rc = gnutls_cipher_encrypt2(cipher_hnd,
1889 				    encrypted_blob.data,
1890 				    encrypted_blob.length,
1891 				    encrypted_blob.data,
1892 				    encrypted_blob.length);
1893 	torture_assert_int_equal(tctx,
1894 				 rc,
1895 				 GNUTLS_E_SUCCESS,
1896 				 "gnutls_cipher_encrypt failed");
1897 	gnutls_cipher_deinit(cipher_hnd);
1898 
1899 	torture_assert_ndr_err_equal(tctx, ndr_pull_struct_blob(&encrypted_blob, tctx, &rc4payload,
1900 				       (ndr_pull_flags_fn_t)ndr_pull_bkrp_rc4encryptedpayload),
1901 				     NDR_ERR_SUCCESS, "Failed to parse rc4encryptedpayload");
1902 
1903 	torture_assert_int_equal(tctx, rc4payload.secret_data.length,
1904 				 server_side_wrapped->payload_length,
1905 				 "length of decrypted payload not the length declared in surrounding structure");
1906 
1907 	/*
1908 	 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1
1909 	 * BACKUPKEY_BACKUP_GUID, it really is the whole key
1910 	 */
1911 	gnutls_hmac(hmac_hnd,
1912 		    rc4payload.r3,
1913 		    sizeof(rc4payload.r3));
1914 	gnutls_hmac_deinit(hmac_hnd, mackey);
1915 
1916 	torture_assert_ndr_err_equal(tctx, ndr_push_struct_blob(&sid_blob, tctx, &rc4payload.sid,
1917 								(ndr_push_flags_fn_t)ndr_push_dom_sid),
1918 				     NDR_ERR_SUCCESS, "unable to push SID");
1919 
1920 	gnutls_hmac_init(&hmac_hnd,
1921 			 GNUTLS_MAC_SHA1,
1922 			 mackey,
1923 			 sizeof(mackey));
1924 	/* SID field */
1925 	gnutls_hmac(hmac_hnd,
1926 		    sid_blob.data,
1927 		    sid_blob.length);
1928 	/* Secret field */
1929 	gnutls_hmac(hmac_hnd,
1930 		    rc4payload.secret_data.data,
1931 		    rc4payload.secret_data.length);
1932 	gnutls_hmac_output(hmac_hnd, mac);
1933 
1934 	torture_assert_mem_equal(tctx, mac, rc4payload.mac, sizeof(mac), "mac not correct");
1935 	torture_assert_int_equal(tctx, rc4payload.secret_data.length,
1936 				 plaintext.length, "decrypted data is not correct length");
1937 	torture_assert_mem_equal(tctx, rc4payload.secret_data.data,
1938 				 plaintext.data, plaintext.length,
1939 				 "decrypted data is not correct");
1940 
1941 	/* Not strictly correct all the time, but good enough for this test */
1942 	caller_sid = get_user_sid(tctx, tctx,
1943 			cli_credentials_get_username(
1944 				popt_get_cmdline_credentials()));
1945 
1946 	torture_assert_sid_equal(tctx, &rc4payload.sid, caller_sid, "Secret saved with wrong SID");
1947 
1948 
1949 	/* RE-encrypt */
1950 
1951 	if (wrong == WRONG_SID) {
1952 		rc4payload.sid.sub_auths[rc4payload.sid.num_auths - 1] = DOMAIN_RID_KRBTGT;
1953 	}
1954 
1955 	dump_data_pw("mackey: \n", mackey, sizeof(mackey));
1956 
1957 	torture_assert_ndr_err_equal(tctx,
1958 				     ndr_push_struct_blob(&sid_blob, tctx, &rc4payload.sid,
1959 							  (ndr_push_flags_fn_t)ndr_push_dom_sid),
1960 				     NDR_ERR_SUCCESS,
1961 				     "push of sid failed");
1962 
1963 	/* SID field */
1964 	gnutls_hmac(hmac_hnd,
1965 		    sid_blob.data,
1966 		    sid_blob.length);
1967 	/* Secret field */
1968 	gnutls_hmac(hmac_hnd,
1969 		    rc4payload.secret_data.data,
1970 		    rc4payload.secret_data.length);
1971 	gnutls_hmac_deinit(hmac_hnd, rc4payload.mac);
1972 
1973 	dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac));
1974 
1975 	torture_assert_ndr_err_equal(tctx,
1976 				     ndr_push_struct_blob(&encrypted_blob, tctx, &rc4payload,
1977 							  (ndr_push_flags_fn_t)ndr_push_bkrp_rc4encryptedpayload),
1978 				     NDR_ERR_SUCCESS,
1979 				     "push of rc4payload failed");
1980 
1981 	if (wrong == WRONG_KEY) {
1982 		symkey[0] = 78;
1983 		symkey[1] = 78;
1984 		symkey[2] = 78;
1985 	}
1986 
1987 	/* rc4 encrypt sid and secret using sym key */
1988 	cipher_key.data = symkey;
1989 	cipher_key.size = sizeof(symkey);
1990 
1991 	rc = gnutls_cipher_init(&cipher_hnd,
1992 				GNUTLS_CIPHER_ARCFOUR_128,
1993 				&cipher_key,
1994 				NULL);
1995 	torture_assert_int_equal(tctx,
1996 				 rc,
1997 				 GNUTLS_E_SUCCESS,
1998 				 "gnutls_cipher_init failed");
1999 	rc = gnutls_cipher_encrypt2(cipher_hnd,
2000 				    encrypted_blob.data,
2001 				    encrypted_blob.length,
2002 				    encrypted_blob.data,
2003 				    encrypted_blob.length);
2004 	torture_assert_int_equal(tctx,
2005 				 rc,
2006 				 GNUTLS_E_SUCCESS,
2007 				 "gnutls_cipher_encrypt failed");
2008 	gnutls_cipher_deinit(cipher_hnd);
2009 
2010 
2011 	/* re-create server wrap structure */
2012 
2013 	torture_assert_int_equal(tctx, encrypted_blob.length,
2014 				 server_side_wrapped->ciphertext_length,
2015 				 "expected encrypted length not to change");
2016 	if (wrong == RIGHT_KEY) {
2017 		torture_assert_mem_equal(tctx, server_side_wrapped->rc4encryptedpayload,
2018 					 encrypted_blob.data,
2019 					 encrypted_blob.length,
2020 					 "expected encrypted data not to change");
2021 	}
2022 
2023 	server_side_wrapped->payload_length = rc4payload.secret_data.length;
2024 	server_side_wrapped->ciphertext_length = encrypted_blob.length;
2025 	server_side_wrapped->rc4encryptedpayload = encrypted_blob.data;
2026 
2027 	return true;
2028 }
2029 
2030 
test_ServerWrap_decrypt_wrong_stuff(struct torture_context * tctx,struct dcerpc_pipe * p,enum test_wrong wrong)2031 static bool test_ServerWrap_decrypt_wrong_stuff(struct torture_context *tctx,
2032 						struct dcerpc_pipe *p,
2033 						enum test_wrong wrong)
2034 {
2035 	struct bkrp_BackupKey r;
2036 	struct GUID guid;
2037 	DATA_BLOB plaintext = data_blob_const(secret, sizeof(secret));
2038 	DATA_BLOB encrypted;
2039 	uint32_t enclen;
2040 	DATA_BLOB decrypted;
2041 	uint32_t declen;
2042 	struct dcerpc_binding_handle *b = p->binding_handle;
2043 	enum ndr_err_code ndr_err;
2044 	struct bkrp_server_side_wrapped server_side_wrapped;
2045 	bool repush = false;
2046 	enum dcerpc_AuthType auth_type;
2047 	enum dcerpc_AuthLevel auth_level;
2048 	ZERO_STRUCT(r);
2049 
2050 	dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
2051 
2052 	/* Encrypt */
2053 	torture_assert_ntstatus_ok(tctx,
2054 				   GUID_from_string(BACKUPKEY_BACKUP_GUID, &guid),
2055 				   "obtain GUID");
2056 
2057 	r.in.guidActionAgent = &guid;
2058 	r.in.data_in = plaintext.data;
2059 	r.in.data_in_len = plaintext.length;
2060 	r.in.param = 0;
2061 	r.out.data_out = &encrypted.data;
2062 	r.out.data_out_len = &enclen;
2063 	if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2064 		torture_assert_ntstatus_ok(tctx,
2065 					   dcerpc_bkrp_BackupKey_r(b, tctx, &r),
2066 					   "encrypt");
2067 	} else {
2068 		torture_assert_ntstatus_equal(tctx,
2069 					      dcerpc_bkrp_BackupKey_r(b, tctx, &r),
2070 					      NT_STATUS_ACCESS_DENIED,
2071 					      "encrypt");
2072 		return true;
2073 	}
2074 	torture_assert_werr_ok(tctx,
2075 			       r.out.result,
2076 			       "encrypt");
2077 	encrypted.length = *r.out.data_out_len;
2078 
2079 	ndr_err = ndr_pull_struct_blob(&encrypted, tctx, &server_side_wrapped,
2080 				       (ndr_pull_flags_fn_t)ndr_pull_bkrp_server_side_wrapped);
2081 	torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "pull of server_side_wrapped");
2082 
2083 	torture_assert_int_equal(tctx, server_side_wrapped.payload_length, plaintext.length,
2084 				 "wrong payload length");
2085 
2086 	switch (wrong) {
2087 	case WRONG_MAGIC:
2088 		/* Change the magic.  Forced by our NDR layer, so do it raw */
2089 		SIVAL(encrypted.data, 0, 78);  /* valid values are 1-3 */
2090 		break;
2091 	case WRONG_R2:
2092 		server_side_wrapped.r2[0] = 78;
2093 		server_side_wrapped.r2[1] = 78;
2094 		server_side_wrapped.r2[3] = 78;
2095 		repush = true;
2096 		break;
2097 	case WRONG_PAYLOAD_LENGTH:
2098 		server_side_wrapped.payload_length = UINT32_MAX - 8;
2099 		repush = true;
2100 		break;
2101 	case WRONG_CIPHERTEXT_LENGTH:
2102 		/*
2103 		 * Change the ciphertext len.  We can't push this if
2104 		 * we have it wrong, so do it raw
2105 		 */
2106 		SIVAL(encrypted.data, 8, UINT32_MAX - 8);  /* valid values are 1-3 */
2107 		break;
2108 	case SHORT_PAYLOAD_LENGTH:
2109 		server_side_wrapped.payload_length = server_side_wrapped.payload_length - 8;
2110 		repush = true;
2111 		break;
2112 	case SHORT_CIPHERTEXT_LENGTH:
2113 		/*
2114 		 * Change the ciphertext len.  We can't push this if
2115 		 * we have it wrong, so do it raw
2116 		 */
2117 		SIVAL(encrypted.data, 8, server_side_wrapped.ciphertext_length - 8);  /* valid values are 1-3 */
2118 		break;
2119 	case ZERO_PAYLOAD_LENGTH:
2120 		server_side_wrapped.payload_length = 0;
2121 		repush = true;
2122 		break;
2123 	case ZERO_CIPHERTEXT_LENGTH:
2124 		/*
2125 		 * Change the ciphertext len.  We can't push this if
2126 		 * we have it wrong, so do it raw
2127 		 */
2128 		SIVAL(encrypted.data, 8, 0);  /* valid values are 1-3 */
2129 		break;
2130 
2131 	case RIGHT_KEY:
2132 	case WRONG_KEY:
2133 	case WRONG_SID:
2134 		torture_assert(tctx,
2135 			       test_ServerWrap_encrypt_decrypt_manual(tctx, &server_side_wrapped, wrong),
2136 			       "test_ServerWrap_encrypt_decrypt_manual failed");
2137 		repush = true;
2138 		break;
2139 	}
2140 
2141 	if (repush) {
2142 		ndr_err = ndr_push_struct_blob(&encrypted, tctx, &server_side_wrapped,
2143 					       (ndr_push_flags_fn_t)ndr_push_bkrp_server_side_wrapped);
2144 		torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "push of server_side_wrapped");
2145 	}
2146 
2147 	/* Decrypt */
2148 	torture_assert_ntstatus_ok(tctx,
2149 				   GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
2150 				   "obtain GUID");
2151 
2152 	r.in.guidActionAgent = &guid;
2153 	r.in.data_in = encrypted.data;
2154 	r.in.data_in_len = encrypted.length;
2155 	r.in.param = 0;
2156 	r.out.data_out = &(decrypted.data);
2157 	r.out.data_out_len = &declen;
2158 	torture_assert_ntstatus_ok(tctx,
2159 				   dcerpc_bkrp_BackupKey_r(b, tctx, &r),
2160 				   "decrypt");
2161 
2162 	if ((wrong == WRONG_R2 || wrong == WRONG_KEY)
2163 	    && W_ERROR_EQUAL(r.out.result, WERR_INVALID_SID)) {
2164 		torture_assert_werr_equal(tctx,
2165 					  r.out.result,
2166 					  WERR_INVALID_SID,
2167 					  "decrypt should fail with WERR_INVALID_SID or WERR_INVALID_PARAMETER");
2168 	} else if (wrong == RIGHT_KEY) {
2169 		torture_assert_werr_equal(tctx,
2170 					  r.out.result,
2171 					  WERR_OK,
2172 					  "decrypt should succeed!");
2173 	} else if (wrong == WRONG_SID) {
2174 		torture_assert_werr_equal(tctx,
2175 					  r.out.result,
2176 					  WERR_INVALID_ACCESS,
2177 					  "decrypt should fail with WERR_INVALID_ACCESS");
2178 	} else {
2179 		if (!W_ERROR_EQUAL(r.out.result, WERR_INVALID_ACCESS)
2180 		    && !W_ERROR_EQUAL(r.out.result, WERR_INVALID_PARAMETER)) {
2181 			torture_assert_werr_equal(tctx, r.out.result,
2182 						  WERR_INVALID_DATA,
2183 						  "decrypt should fail with WERR_INVALID_ACCESS, WERR_INVALID_PARAMETER or WERR_INVALID_DATA");
2184 		}
2185 	}
2186 
2187 	/* Decrypt */
2188 	torture_assert_ntstatus_ok(tctx,
2189 				   GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
2190 				   "obtain GUID");
2191 
2192 	r.in.guidActionAgent = &guid;
2193 	r.in.data_in = encrypted.data;
2194 	r.in.data_in_len = encrypted.length;
2195 	r.in.param = 0;
2196 	r.out.data_out = &(decrypted.data);
2197 	r.out.data_out_len = &declen;
2198 	torture_assert_ntstatus_ok(tctx,
2199 				   dcerpc_bkrp_BackupKey_r(b, tctx, &r),
2200 				   "decrypt");
2201 
2202 	if ((wrong == WRONG_R2 || wrong == WRONG_KEY)
2203 	    && W_ERROR_EQUAL(r.out.result, WERR_INVALID_SID)) {
2204 		torture_assert_werr_equal(tctx,
2205 					  r.out.result,
2206 					  WERR_INVALID_SID,
2207 					  "decrypt should fail with WERR_INVALID_SID or WERR_INVALID_PARAMETER");
2208 	} else if (wrong == RIGHT_KEY) {
2209 		torture_assert_werr_equal(tctx,
2210 					  r.out.result,
2211 					  WERR_OK,
2212 					  "decrypt should succeed!");
2213 	} else if (wrong == WRONG_SID) {
2214 		torture_assert_werr_equal(tctx,
2215 					  r.out.result,
2216 					  WERR_INVALID_ACCESS,
2217 					  "decrypt should fail with WERR_INVALID_ACCESS");
2218 	} else {
2219 		torture_assert_werr_equal(tctx,
2220 					  r.out.result,
2221 					  WERR_INVALID_PARAMETER,
2222 					  "decrypt should fail with WERR_INVALID_PARAMETER");
2223 	}
2224 
2225 	return true;
2226 }
2227 
test_ServerWrap_decrypt_wrong_magic(struct torture_context * tctx,struct dcerpc_pipe * p)2228 static bool test_ServerWrap_decrypt_wrong_magic(struct torture_context *tctx,
2229 						struct dcerpc_pipe *p)
2230 {
2231 	return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_MAGIC);
2232 }
2233 
test_ServerWrap_decrypt_wrong_r2(struct torture_context * tctx,struct dcerpc_pipe * p)2234 static bool test_ServerWrap_decrypt_wrong_r2(struct torture_context *tctx,
2235 						struct dcerpc_pipe *p)
2236 {
2237 	return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_R2);
2238 }
2239 
test_ServerWrap_decrypt_wrong_payload_length(struct torture_context * tctx,struct dcerpc_pipe * p)2240 static bool test_ServerWrap_decrypt_wrong_payload_length(struct torture_context *tctx,
2241 							 struct dcerpc_pipe *p)
2242 {
2243 	return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_PAYLOAD_LENGTH);
2244 }
2245 
test_ServerWrap_decrypt_short_payload_length(struct torture_context * tctx,struct dcerpc_pipe * p)2246 static bool test_ServerWrap_decrypt_short_payload_length(struct torture_context *tctx,
2247 							 struct dcerpc_pipe *p)
2248 {
2249 	return test_ServerWrap_decrypt_wrong_stuff(tctx, p, SHORT_PAYLOAD_LENGTH);
2250 }
2251 
test_ServerWrap_decrypt_zero_payload_length(struct torture_context * tctx,struct dcerpc_pipe * p)2252 static bool test_ServerWrap_decrypt_zero_payload_length(struct torture_context *tctx,
2253 							 struct dcerpc_pipe *p)
2254 {
2255 	return test_ServerWrap_decrypt_wrong_stuff(tctx, p, ZERO_PAYLOAD_LENGTH);
2256 }
2257 
test_ServerWrap_decrypt_wrong_ciphertext_length(struct torture_context * tctx,struct dcerpc_pipe * p)2258 static bool test_ServerWrap_decrypt_wrong_ciphertext_length(struct torture_context *tctx,
2259 							 struct dcerpc_pipe *p)
2260 {
2261 	return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_CIPHERTEXT_LENGTH);
2262 }
2263 
test_ServerWrap_decrypt_short_ciphertext_length(struct torture_context * tctx,struct dcerpc_pipe * p)2264 static bool test_ServerWrap_decrypt_short_ciphertext_length(struct torture_context *tctx,
2265 							 struct dcerpc_pipe *p)
2266 {
2267 	return test_ServerWrap_decrypt_wrong_stuff(tctx, p, SHORT_CIPHERTEXT_LENGTH);
2268 }
2269 
test_ServerWrap_decrypt_zero_ciphertext_length(struct torture_context * tctx,struct dcerpc_pipe * p)2270 static bool test_ServerWrap_decrypt_zero_ciphertext_length(struct torture_context *tctx,
2271 							   struct dcerpc_pipe *p)
2272 {
2273 	return test_ServerWrap_decrypt_wrong_stuff(tctx, p, ZERO_CIPHERTEXT_LENGTH);
2274 }
2275 
test_ServerWrap_encrypt_decrypt_remote_key(struct torture_context * tctx,struct dcerpc_pipe * p)2276 static bool test_ServerWrap_encrypt_decrypt_remote_key(struct torture_context *tctx,
2277 						       struct dcerpc_pipe *p)
2278 {
2279 	return test_ServerWrap_decrypt_wrong_stuff(tctx, p, RIGHT_KEY);
2280 }
2281 
test_ServerWrap_encrypt_decrypt_wrong_key(struct torture_context * tctx,struct dcerpc_pipe * p)2282 static bool test_ServerWrap_encrypt_decrypt_wrong_key(struct torture_context *tctx,
2283 						       struct dcerpc_pipe *p)
2284 {
2285 	return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_KEY);
2286 }
2287 
test_ServerWrap_encrypt_decrypt_wrong_sid(struct torture_context * tctx,struct dcerpc_pipe * p)2288 static bool test_ServerWrap_encrypt_decrypt_wrong_sid(struct torture_context *tctx,
2289 						      struct dcerpc_pipe *p)
2290 {
2291 	return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_SID);
2292 }
2293 
torture_rpc_backupkey(TALLOC_CTX * mem_ctx)2294 struct torture_suite *torture_rpc_backupkey(TALLOC_CTX *mem_ctx)
2295 {
2296 	struct torture_suite *suite = torture_suite_create(mem_ctx, "backupkey");
2297 
2298 	struct torture_rpc_tcase *tcase;
2299 
2300 	tcase = torture_suite_add_rpc_iface_tcase(suite, "backupkey",
2301 						  &ndr_table_backupkey);
2302 
2303 	torture_rpc_tcase_add_test(tcase, "retreive_backup_key_guid",
2304 				   test_RetrieveBackupKeyGUID);
2305 
2306 	torture_rpc_tcase_add_test(tcase, "restore_guid",
2307 				   test_RestoreGUID);
2308 
2309 	torture_rpc_tcase_add_test(tcase, "restore_guid version 3",
2310 				   test_RestoreGUID_v3);
2311 
2312 /* We double the test in order to be sure that we don't mess stuff (ie. freeing static stuff) */
2313 
2314 	torture_rpc_tcase_add_test(tcase, "restore_guid_2nd",
2315 				   test_RestoreGUID);
2316 
2317 	torture_rpc_tcase_add_test(tcase, "unable_to_decrypt_secret",
2318 				   test_RestoreGUID_ko);
2319 
2320 	torture_rpc_tcase_add_test(tcase, "wrong_user_restore_guid",
2321 				   test_RestoreGUID_wronguser);
2322 
2323 	torture_rpc_tcase_add_test(tcase, "wrong_version_restore_guid",
2324 				   test_RestoreGUID_wrongversion);
2325 
2326 	torture_rpc_tcase_add_test(tcase, "bad_magic_on_secret_restore_guid",
2327 				   test_RestoreGUID_badmagiconsecret);
2328 
2329 	torture_rpc_tcase_add_test(tcase, "bad_hash_on_secret_restore_guid",
2330 				   test_RestoreGUID_badhashaccesscheck);
2331 
2332 	torture_rpc_tcase_add_test(tcase, "bad_magic_on_accesscheck_restore_guid",
2333 				   test_RestoreGUID_badmagicaccesscheck);
2334 
2335 	torture_rpc_tcase_add_test(tcase, "bad_cert_guid_restore_guid",
2336 				   test_RestoreGUID_badcertguid);
2337 
2338 	torture_rpc_tcase_add_test(tcase, "empty_request_restore_guid",
2339 				   test_RestoreGUID_emptyrequest);
2340 
2341 	torture_rpc_tcase_add_test(tcase, "retreive_backup_key_guid_validate",
2342 				   test_RetrieveBackupKeyGUID_validate);
2343 
2344 	torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt",
2345 				   test_ServerWrap_encrypt_decrypt);
2346 
2347 	torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_keyGUID",
2348 				   test_ServerWrap_decrypt_wrong_keyGUID);
2349 
2350 	torture_rpc_tcase_add_test(tcase, "server_wrap_empty_request",
2351 				   test_ServerWrap_decrypt_empty_request);
2352 
2353 	torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_short_request",
2354 				   test_ServerWrap_decrypt_short_request);
2355 
2356 	torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_magic",
2357 				   test_ServerWrap_decrypt_wrong_magic);
2358 
2359 	torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_r2",
2360 				   test_ServerWrap_decrypt_wrong_r2);
2361 
2362 	torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_payload_length",
2363 				   test_ServerWrap_decrypt_wrong_payload_length);
2364 
2365 	torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_short_payload_length",
2366 				   test_ServerWrap_decrypt_short_payload_length);
2367 
2368 	torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_zero_payload_length",
2369 				   test_ServerWrap_decrypt_zero_payload_length);
2370 
2371 	torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_ciphertext_length",
2372 				   test_ServerWrap_decrypt_wrong_ciphertext_length);
2373 
2374 	torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_short_ciphertext_length",
2375 				   test_ServerWrap_decrypt_short_ciphertext_length);
2376 
2377 	torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_zero_ciphertext_length",
2378 				   test_ServerWrap_decrypt_zero_ciphertext_length);
2379 
2380 	torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt_remote_key",
2381 				   test_ServerWrap_encrypt_decrypt_remote_key);
2382 
2383 	torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt_wrong_key",
2384 				   test_ServerWrap_encrypt_decrypt_wrong_key);
2385 
2386 	torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt_wrong_sid",
2387 				   test_ServerWrap_encrypt_decrypt_wrong_sid);
2388 
2389 	return suite;
2390 }
2391