Line data Source code
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/cmdline.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 */
62 14 : 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 14 : struct lsa_RefDomainList *domains = NULL;
75 : struct lsa_String lsa_name;
76 14 : 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 14 : const char *domain = cli_credentials_get_domain(
83 : samba_cmdline_get_creds());
84 :
85 14 : torture_assert_ntstatus_ok(tctx,
86 : torture_rpc_connection(tctx, &p2, &ndr_table_lsarpc),
87 : "could not open lsarpc pipe");
88 14 : b = p2->binding_handle;
89 :
90 14 : if (!(tmp_ctx = talloc_new(mem_ctx))) {
91 0 : return NULL;
92 : }
93 14 : qos.len = 0;
94 14 : qos.impersonation_level = 2;
95 14 : qos.context_mode = 1;
96 14 : qos.effective_only = 0;
97 :
98 14 : attr.len = 0;
99 14 : attr.root_dir = NULL;
100 14 : attr.object_name = NULL;
101 14 : attr.attributes = 0;
102 14 : attr.sec_desc = NULL;
103 14 : attr.sec_qos = &qos;
104 :
105 14 : r.in.system_name = "\\";
106 14 : r.in.attr = &attr;
107 14 : r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
108 14 : r.out.handle = &handle;
109 :
110 14 : status = dcerpc_lsa_OpenPolicy2_r(b, tmp_ctx, &r);
111 14 : if (!NT_STATUS_IS_OK(status)) {
112 0 : torture_comment(tctx,
113 : "OpenPolicy2 failed - %s\n",
114 : nt_errstr(status));
115 0 : talloc_free(tmp_ctx);
116 0 : return NULL;
117 : }
118 14 : if (!NT_STATUS_IS_OK(r.out.result)) {
119 0 : torture_comment(tctx,
120 : "OpenPolicy2_ failed - %s\n",
121 : nt_errstr(r.out.result));
122 0 : talloc_free(tmp_ctx);
123 0 : return NULL;
124 : }
125 :
126 14 : sids.count = 0;
127 14 : sids.sids = NULL;
128 :
129 14 : lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, user);
130 :
131 14 : l.in.handle = &handle;
132 14 : l.in.num_names = 1;
133 14 : l.in.names = &lsa_name;
134 14 : l.in.sids = &sids;
135 14 : l.in.level = 1;
136 14 : l.in.count = &count;
137 14 : l.out.count = &count;
138 14 : l.out.sids = &sids;
139 14 : l.out.domains = &domains;
140 :
141 14 : status = dcerpc_lsa_LookupNames_r(b, tmp_ctx, &l);
142 14 : if (!NT_STATUS_IS_OK(status)) {
143 0 : torture_comment(tctx,
144 : "LookupNames of %s failed - %s\n",
145 : lsa_name.string,
146 : nt_errstr(status));
147 0 : talloc_free(tmp_ctx);
148 0 : return NULL;
149 : }
150 :
151 14 : if (domains->count == 0) {
152 0 : return NULL;
153 : }
154 :
155 28 : result = dom_sid_add_rid(mem_ctx,
156 14 : domains->domains[0].sid,
157 14 : l.out.sids->sids[0].rid);
158 14 : c.in.handle = &handle;
159 14 : c.out.handle = &handle;
160 :
161 14 : status = dcerpc_lsa_Close_r(b, tmp_ctx, &c);
162 :
163 14 : if (!NT_STATUS_IS_OK(status)) {
164 0 : torture_comment(tctx,
165 : "dcerpc_lsa_Close failed - %s\n",
166 : nt_errstr(status));
167 0 : talloc_free(tmp_ctx);
168 0 : return NULL;
169 : }
170 :
171 14 : if (!NT_STATUS_IS_OK(c.out.result)) {
172 0 : torture_comment(tctx,
173 : "dcerpc_lsa_Close failed - %s\n",
174 : nt_errstr(c.out.result));
175 0 : talloc_free(tmp_ctx);
176 0 : return NULL;
177 : }
178 :
179 14 : talloc_free(tmp_ctx);
180 14 : talloc_free(p2);
181 :
182 14 : torture_comment(tctx, "Get_user_sid finished\n");
183 14 : 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 : */
193 11 : static DATA_BLOB *create_unencryptedsecret(TALLOC_CTX *mem_ctx,
194 : bool broken,
195 : int version)
196 : {
197 11 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
198 11 : DATA_BLOB *blob = talloc_zero(mem_ctx, DATA_BLOB);
199 : enum ndr_err_code ndr_err;
200 :
201 11 : if (version == 2) {
202 : struct bkrp_encrypted_secret_v2 unenc_sec;
203 :
204 7 : ZERO_STRUCT(unenc_sec);
205 7 : unenc_sec.secret_len = sizeof(secret);
206 7 : unenc_sec.secret = discard_const_p(uint8_t, secret);
207 7 : generate_random_buffer(unenc_sec.payload_key,
208 : sizeof(unenc_sec.payload_key));
209 :
210 7 : ndr_err = ndr_push_struct_blob(blob, blob, &unenc_sec,
211 : (ndr_push_flags_fn_t)ndr_push_bkrp_encrypted_secret_v2);
212 7 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
213 0 : return NULL;
214 : }
215 :
216 7 : 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 0 : ((uint8_t*)blob->data)[4] = 79; /* A great year !!! */
222 : }
223 : }
224 :
225 11 : if (version == 3) {
226 : struct bkrp_encrypted_secret_v3 unenc_sec;
227 :
228 4 : ZERO_STRUCT(unenc_sec);
229 4 : unenc_sec.secret_len = sizeof(secret);
230 4 : unenc_sec.secret = discard_const_p(uint8_t, secret);
231 4 : generate_random_buffer(unenc_sec.payload_key,
232 : sizeof(unenc_sec.payload_key));
233 :
234 4 : ndr_err = ndr_push_struct_blob(blob, blob, &unenc_sec,
235 : (ndr_push_flags_fn_t)ndr_push_bkrp_encrypted_secret_v3);
236 4 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
237 0 : return NULL;
238 : }
239 :
240 4 : 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 2 : ((uint8_t*)blob->data)[4] = 79; /* A great year !!! */
247 : }
248 : }
249 11 : talloc_free(tmp_ctx);
250 11 : 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 : */
260 11 : 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 11 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
268 11 : DATA_BLOB *blob = talloc_zero(mem_ctx, DATA_BLOB);
269 : enum ndr_err_code ndr_err;
270 11 : const struct dom_sid *sid = get_user_sid(tctx, tmp_ctx, user);
271 :
272 11 : if (sid == NULL) {
273 0 : return NULL;
274 : }
275 :
276 11 : 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 7 : ZERO_STRUCT(access_struct);
282 7 : generate_random_buffer(nonce, sizeof(nonce));
283 7 : access_struct.nonce_len = sizeof(nonce);
284 7 : access_struct.nonce = nonce;
285 7 : access_struct.sid = *sid;
286 :
287 7 : ndr_err = ndr_push_struct_blob(blob, blob, &access_struct,
288 : (ndr_push_flags_fn_t)ndr_push_bkrp_access_check_v2);
289 7 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
290 0 : 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 7 : gnutls_hash_init(&dig_ctx, GNUTLS_DIG_SHA1);
300 14 : gnutls_hash(dig_ctx,
301 7 : blob->data,
302 7 : blob->length - sizeof(access_struct.hash));
303 7 : gnutls_hash_deinit(dig_ctx,
304 7 : blob->data + blob->length - sizeof(access_struct.hash));
305 :
306 : /* Altering the SHA */
307 7 : if (broken) {
308 1 : blob->data[blob->length - 1]++;
309 : }
310 : }
311 :
312 11 : 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 4 : ZERO_STRUCT(access_struct);
318 4 : generate_random_buffer(nonce, sizeof(nonce));
319 4 : access_struct.nonce_len = sizeof(nonce);
320 4 : access_struct.nonce = nonce;
321 4 : access_struct.sid = *sid;
322 :
323 4 : ndr_err = ndr_push_struct_blob(blob, blob, &access_struct,
324 : (ndr_push_flags_fn_t)ndr_push_bkrp_access_check_v3);
325 4 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
326 0 : 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 4 : gnutls_hash_init(&dig_ctx, GNUTLS_DIG_SHA512);
335 8 : gnutls_hash(dig_ctx,
336 4 : blob->data,
337 4 : blob->length - sizeof(access_struct.hash));
338 4 : gnutls_hash_deinit(dig_ctx,
339 4 : blob->data + blob->length - sizeof(access_struct.hash));
340 :
341 : /* Altering the SHA */
342 4 : if (broken) {
343 0 : blob->data[blob->length -1]++;
344 : }
345 : }
346 11 : talloc_free(tmp_ctx);
347 11 : return blob;
348 : }
349 :
350 :
351 11 : 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 11 : gnutls_cipher_hd_t cipher_handle = { 0 };
359 22 : gnutls_datum_t gkey = {
360 11 : .data = key->data,
361 11 : .size = key->length,
362 : };
363 22 : gnutls_datum_t giv = {
364 11 : .data = iv->data,
365 11 : .size = iv->length,
366 : };
367 : DATA_BLOB *blob;
368 : int rc;
369 :
370 11 : blob = talloc(mem_ctx, DATA_BLOB);
371 11 : if (blob == NULL) {
372 0 : return NULL;
373 : }
374 :
375 11 : *blob = data_blob_talloc_zero(mem_ctx, to_encrypt->length);
376 11 : if (blob->data == NULL) {
377 0 : talloc_free(blob);
378 0 : return NULL;
379 : }
380 :
381 11 : rc = gnutls_cipher_init(&cipher_handle,
382 : cipher_algo,
383 : &gkey,
384 : &giv);
385 11 : if (rc != GNUTLS_E_SUCCESS) {
386 0 : torture_comment(tctx,
387 : "gnutls_cipher_init failed: %s\n",
388 : gnutls_strerror(rc));
389 0 : talloc_free(blob);
390 0 : return NULL;
391 : }
392 :
393 33 : rc = gnutls_cipher_encrypt2(cipher_handle,
394 11 : to_encrypt->data,
395 : to_encrypt->length,
396 11 : blob->data,
397 : blob->length);
398 11 : gnutls_cipher_deinit(cipher_handle);
399 11 : if (rc != GNUTLS_E_SUCCESS) {
400 0 : torture_comment(tctx,
401 : "gnutls_cipher_decrypt2 failed: %s\n",
402 : gnutls_strerror(rc));
403 0 : return NULL;
404 : }
405 :
406 11 : 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 : */
413 11 : 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 11 : gnutls_x509_crt_t x509_cert = NULL;
419 11 : gnutls_datum_t x509_crt_data = {
420 : .data = cert_data,
421 : .size = cert_len,
422 : };
423 11 : uint8_t dummy[1] = {0};
424 11 : DATA_BLOB issuer_unique_id = {
425 : .data = dummy,
426 : .length = 0,
427 : };
428 11 : struct GUID *guid = talloc_zero(mem_ctx, struct GUID);
429 : NTSTATUS status;
430 : int rc;
431 :
432 11 : rc = gnutls_x509_crt_init(&x509_cert);
433 11 : if (rc != GNUTLS_E_SUCCESS) {
434 0 : torture_comment(tctx,
435 : "gnutls_x509_crt_init failed - %s",
436 : gnutls_strerror(rc));
437 0 : return NULL;
438 : }
439 :
440 11 : rc = gnutls_x509_crt_import(x509_cert,
441 : &x509_crt_data,
442 : GNUTLS_X509_FMT_DER);
443 11 : if (rc != GNUTLS_E_SUCCESS) {
444 0 : torture_comment(tctx,
445 : "gnutls_x509_crt_import failed - %s",
446 : gnutls_strerror(rc));
447 0 : gnutls_x509_crt_deinit(x509_cert);
448 0 : return NULL;
449 : }
450 :
451 : /* Get the buffer size */
452 11 : rc = gnutls_x509_crt_get_issuer_unique_id(x509_cert,
453 11 : (char *)issuer_unique_id.data,
454 : &issuer_unique_id.length);
455 22 : if (rc != GNUTLS_E_SHORT_MEMORY_BUFFER ||
456 11 : issuer_unique_id.length == 0) {
457 0 : gnutls_x509_crt_deinit(x509_cert);
458 0 : return NULL;
459 : }
460 :
461 11 : issuer_unique_id = data_blob_talloc_zero(mem_ctx,
462 : issuer_unique_id.length);
463 11 : if (issuer_unique_id.data == NULL) {
464 0 : gnutls_x509_crt_deinit(x509_cert);
465 0 : return NULL;
466 : }
467 :
468 11 : rc = gnutls_x509_crt_get_issuer_unique_id(x509_cert,
469 11 : (char *)issuer_unique_id.data,
470 : &issuer_unique_id.length);
471 11 : gnutls_x509_crt_deinit(x509_cert);
472 11 : if (rc != GNUTLS_E_SUCCESS) {
473 0 : torture_comment(tctx,
474 : "gnutls_x509_crt_get_issuer_unique_id failed - %s",
475 : gnutls_strerror(rc));
476 0 : return NULL;
477 : }
478 :
479 11 : status = GUID_from_data_blob(&issuer_unique_id, guid);
480 11 : if (!NT_STATUS_IS_OK(status)) {
481 0 : return NULL;
482 : }
483 :
484 11 : return guid;
485 : }
486 :
487 : /*
488 : * Encrypt a blob with the private key of the certificate
489 : * passed as a parameter.
490 : */
491 11 : 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 11 : gnutls_datum_t x509_crt_data = {
499 : .data = cert_data,
500 : .size = cert_len,
501 : };
502 : gnutls_pubkey_t pubkey;
503 22 : gnutls_datum_t plaintext = {
504 11 : .data = to_encrypt->data,
505 11 : .size = to_encrypt->length,
506 : };
507 11 : gnutls_datum_t ciphertext = {
508 : .data = NULL,
509 : };
510 : DATA_BLOB *blob;
511 : int rc;
512 :
513 11 : rc = gnutls_x509_crt_init(&x509_cert);
514 11 : if (rc != GNUTLS_E_SUCCESS) {
515 0 : return NULL;
516 : }
517 :
518 11 : rc = gnutls_x509_crt_import(x509_cert,
519 : &x509_crt_data,
520 : GNUTLS_X509_FMT_DER);
521 11 : if (rc != GNUTLS_E_SUCCESS) {
522 0 : gnutls_x509_crt_deinit(x509_cert);
523 0 : return NULL;
524 : }
525 :
526 11 : rc = gnutls_pubkey_init(&pubkey);
527 11 : if (rc != GNUTLS_E_SUCCESS) {
528 0 : gnutls_x509_crt_deinit(x509_cert);
529 0 : return NULL;
530 : }
531 :
532 11 : rc = gnutls_pubkey_import_x509(pubkey,
533 : x509_cert,
534 : 0);
535 11 : gnutls_x509_crt_deinit(x509_cert);
536 11 : if (rc != GNUTLS_E_SUCCESS) {
537 0 : gnutls_pubkey_deinit(pubkey);
538 0 : return NULL;
539 : }
540 :
541 11 : rc = gnutls_pubkey_encrypt_data(pubkey,
542 : 0,
543 : &plaintext,
544 : &ciphertext);
545 11 : gnutls_pubkey_deinit(pubkey);
546 11 : if (rc != GNUTLS_E_SUCCESS) {
547 0 : return NULL;
548 : }
549 :
550 11 : blob = talloc_zero(mem_ctx, DATA_BLOB);
551 11 : if (blob == NULL) {
552 0 : gnutls_pubkey_deinit(pubkey);
553 0 : return NULL;
554 : }
555 :
556 11 : *blob = data_blob_talloc(blob, ciphertext.data, ciphertext.size);
557 11 : gnutls_free(ciphertext.data);
558 11 : if (blob->data == NULL) {
559 0 : gnutls_pubkey_deinit(pubkey);
560 0 : return NULL;
561 : }
562 :
563 11 : return blob;
564 : }
565 :
566 65 : 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 65 : struct GUID *g = talloc(tctx, struct GUID);
572 65 : 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 65 : if (r == NULL) {
578 0 : return NULL;
579 : }
580 :
581 65 : binding = dcerpc_binding_dup(tctx, p->binding);
582 65 : if (binding == NULL) {
583 0 : return NULL;
584 : }
585 :
586 65 : status = dcerpc_binding_set_flags(binding, DCERPC_SEAL|DCERPC_AUTH_SPNEGO, 0);
587 65 : if (!NT_STATUS_IS_OK(status)) {
588 0 : return NULL;
589 : }
590 :
591 65 : ZERO_STRUCT(data);
592 65 : status = GUID_from_string(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID, g);
593 65 : if (!NT_STATUS_IS_OK(status)) {
594 0 : return NULL;
595 : }
596 :
597 65 : r->in.guidActionAgent = g;
598 65 : data.version = version;
599 65 : ndr_err = ndr_push_struct_blob(&blob, tctx, &data,
600 : (ndr_push_flags_fn_t)ndr_push_bkrp_client_side_wrapped);
601 65 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
602 0 : return NULL;
603 : }
604 65 : r->in.data_in = blob.data;
605 65 : r->in.data_in_len = blob.length;
606 65 : r->out.data_out = &out->data;
607 65 : r->out.data_out_len = talloc(r, uint32_t);
608 65 : return r;
609 : }
610 :
611 11 : 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 11 : struct dcerpc_binding_handle *b = p->binding_handle;
622 : struct bkrp_client_side_wrapped data;
623 : DATA_BLOB *xs;
624 : DATA_BLOB *sec;
625 11 : DATA_BLOB *enc_sec = NULL;
626 11 : 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 11 : struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, version, &out_blob);
640 11 : if (r == NULL) {
641 0 : return NULL;
642 : }
643 :
644 11 : if (broken_user) {
645 : /* we take a fake user*/
646 1 : user = "guest";
647 : } else {
648 10 : user = cli_credentials_get_username(
649 : samba_cmdline_get_creds());
650 : }
651 :
652 :
653 11 : torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
654 : "Get GUID");
655 11 : 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 11 : out_blob.length = *r->out.data_out_len;
664 :
665 11 : sec = create_unencryptedsecret(tctx, broken_magic_secret, version);
666 11 : if (sec == NULL) {
667 0 : return NULL;
668 : }
669 :
670 11 : xs = create_access_check(tctx, p, tctx, user, broken_hash_access, version);
671 11 : if (xs == NULL) {
672 0 : return NULL;
673 : }
674 :
675 11 : if (broken_magic_access){
676 : /* The start of the access_check structure contains the
677 : * GUID of the certificate
678 : */
679 1 : xs->data[0]++;
680 : }
681 :
682 11 : enc_sec = encrypt_blob_pk(tctx, tctx, out_blob.data, out_blob.length, sec);
683 11 : if (!enc_sec) {
684 0 : return NULL;
685 : }
686 11 : enc_sec_reverted.data = talloc_array(tctx, uint8_t, enc_sec->length);
687 11 : if (enc_sec_reverted.data == NULL) {
688 0 : return NULL;
689 : }
690 11 : 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 11 : if (norevert) {
697 257 : for(t=0; t< enc_sec->length; t++) {
698 256 : enc_sec_reverted.data[t] = ((uint8_t*)enc_sec->data)[t];
699 : }
700 : } else {
701 2570 : for(t=0; t< enc_sec->length; t++) {
702 2560 : enc_sec_reverted.data[t] = ((uint8_t*)enc_sec->data)[enc_sec->length - t -1];
703 : }
704 : }
705 :
706 11 : size = sec->length;
707 11 : switch (version) {
708 7 : case 2:
709 7 : cipher_algo = GNUTLS_CIPHER_3DES_CBC;
710 7 : break;
711 4 : case 3:
712 4 : cipher_algo = GNUTLS_CIPHER_AES_256_CBC;
713 4 : break;
714 0 : default:
715 0 : return NULL;
716 : }
717 11 : iv.length = gnutls_cipher_get_iv_size(cipher_algo);
718 11 : iv.data = sec->data + (size - iv.length);
719 :
720 11 : key.length = gnutls_cipher_get_key_size(cipher_algo);
721 11 : key.data = sec->data + (size - (key.length + iv.length));
722 :
723 11 : enc_xs = encrypt_blob(tctx, tctx, &key, &iv, xs, cipher_algo);
724 11 : if (!enc_xs) {
725 0 : return NULL;
726 : }
727 :
728 : /* To cope with the fact that heimdal do padding at the end for the moment */
729 11 : enc_xs->length = xs->length;
730 :
731 11 : guid = get_cert_guid(tctx, tctx, out_blob.data, out_blob.length);
732 11 : if (guid == NULL) {
733 0 : return NULL;
734 : }
735 :
736 11 : if (broken_version) {
737 1 : data.version = 1;
738 : } else {
739 10 : data.version = version;
740 : }
741 :
742 11 : data.guid = *guid;
743 11 : data.encrypted_secret = enc_sec_reverted.data;
744 11 : data.access_check = enc_xs->data;
745 11 : data.encrypted_secret_len = enc_sec->length;
746 11 : 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 11 : blob2 = talloc(tctx, DATA_BLOB);
752 11 : if (blob2 == NULL) {
753 0 : return NULL;
754 : }
755 :
756 11 : ndr_err = ndr_push_struct_blob(blob2, tctx, &data,
757 : (ndr_push_flags_fn_t)ndr_push_bkrp_client_side_wrapped);
758 11 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
759 0 : return NULL;
760 : }
761 :
762 11 : if (broken_cert_guid) {
763 2 : blob2->data[12]++;
764 : }
765 :
766 11 : ZERO_STRUCT(*r);
767 :
768 11 : g = talloc(tctx, struct GUID);
769 11 : if (g == NULL) {
770 0 : return NULL;
771 : }
772 :
773 11 : status = GUID_from_string(BACKUPKEY_RESTORE_GUID, g);
774 11 : if (!NT_STATUS_IS_OK(status)) {
775 0 : return NULL;
776 : }
777 :
778 11 : r->in.guidActionAgent = g;
779 11 : r->in.data_in = blob2->data;
780 11 : r->in.data_in_len = blob2->length;
781 11 : r->in.param = 0;
782 11 : r->out.data_out = &(out->data);
783 11 : r->out.data_out_len = talloc(r, uint32_t);
784 11 : 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 : */
790 5 : static bool test_RetrieveBackupKeyGUID(struct torture_context *tctx,
791 : struct dcerpc_pipe *p)
792 : {
793 5 : struct dcerpc_binding_handle *b = p->binding_handle;
794 : DATA_BLOB out_blob;
795 5 : struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
796 : enum dcerpc_AuthType auth_type;
797 : enum dcerpc_AuthLevel auth_level;
798 :
799 5 : if (r == NULL) {
800 0 : return false;
801 : }
802 :
803 5 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
804 :
805 5 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
806 1 : torture_assert_ntstatus_ok(tctx,
807 : dcerpc_bkrp_BackupKey_r(b, tctx, r),
808 : "Get GUID");
809 :
810 1 : out_blob.length = *r->out.data_out_len;
811 1 : torture_assert_werr_equal(tctx,
812 : r->out.result,
813 : WERR_OK,
814 : "Wrong dce/rpc error code");
815 : } else {
816 4 : torture_assert_ntstatus_equal(tctx,
817 : dcerpc_bkrp_BackupKey_r(b, tctx, r),
818 : NT_STATUS_ACCESS_DENIED,
819 : "Get GUID");
820 : }
821 5 : return true;
822 : }
823 :
824 : /* Test to check the failure to recover a secret because the
825 : * secret blob is not reversed
826 : */
827 5 : static bool test_RestoreGUID_ko(struct torture_context *tctx,
828 : struct dcerpc_pipe *p)
829 : {
830 : enum ndr_err_code ndr_err;
831 5 : 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 5 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
838 :
839 5 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
840 1 : struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
841 : true, false, false, false, false, false, false);
842 1 : torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
843 1 : torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
844 1 : out_blob.length = *r->out.data_out_len;
845 1 : ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
846 1 : torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
847 1 : torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAMETER, "Wrong error code");
848 : } else {
849 4 : struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
850 4 : torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
851 : NT_STATUS_ACCESS_DENIED, "Get GUID");
852 : }
853 :
854 5 : return true;
855 : }
856 :
857 5 : static bool test_RestoreGUID_wrongversion(struct torture_context *tctx,
858 : struct dcerpc_pipe *p)
859 : {
860 : enum ndr_err_code ndr_err;
861 5 : 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 5 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
868 :
869 5 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
870 1 : struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
871 : false, true, false, false, false, false, false);
872 1 : torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
873 1 : torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
874 1 : out_blob.length = *r->out.data_out_len;
875 1 : ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
876 1 : torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
877 1 : torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAMETER, "Wrong error code on wrong version");
878 : } else {
879 4 : struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
880 4 : torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
881 : NT_STATUS_ACCESS_DENIED, "Get GUID");
882 : }
883 :
884 5 : return true;
885 : }
886 :
887 5 : static bool test_RestoreGUID_wronguser(struct torture_context *tctx,
888 : struct dcerpc_pipe *p)
889 : {
890 : enum ndr_err_code ndr_err;
891 5 : 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 5 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
898 :
899 5 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
900 1 : struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
901 : false, false, true, false, false, false, false);
902 1 : torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
903 1 : torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
904 1 : out_blob.length = *r->out.data_out_len;
905 1 : ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
906 1 : torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
907 1 : torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_ACCESS, "Restore GUID");
908 : } else {
909 4 : struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
910 4 : torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
911 : NT_STATUS_ACCESS_DENIED, "Get GUID");
912 : }
913 :
914 5 : return true;
915 : }
916 :
917 5 : static bool test_RestoreGUID_v3(struct torture_context *tctx,
918 : struct dcerpc_pipe *p)
919 : {
920 : enum ndr_err_code ndr_err;
921 5 : 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 5 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
928 :
929 5 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
930 1 : struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob,
931 : false, false, false, false, false, false, false);
932 1 : torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
933 1 : torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
934 1 : out_blob.length = *r->out.data_out_len;
935 1 : ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
936 1 : torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 1, "Unable to unmarshall bkrp_client_side_unwrapped");
937 1 : torture_assert_werr_equal(tctx, r->out.result, WERR_OK, "Restore GUID");
938 1 : torture_assert_str_equal(tctx, (char*)resp.secret.data, secret, "Wrong secret");
939 : } else {
940 4 : struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
941 4 : torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
942 : NT_STATUS_ACCESS_DENIED, "Get GUID");
943 : }
944 :
945 5 : return true;
946 : }
947 :
948 10 : static bool test_RestoreGUID(struct torture_context *tctx,
949 : struct dcerpc_pipe *p)
950 : {
951 10 : 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 10 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
958 :
959 10 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
960 2 : struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
961 : false, false, false, false, false, false, false);
962 2 : torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
963 2 : torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
964 2 : out_blob.length = *r->out.data_out_len;
965 2 : torture_assert_werr_equal(tctx, r->out.result, WERR_OK, "Restore GUID");
966 2 : 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 2 : torture_assert_str_equal(tctx, (char*)resp.secret.data, secret, "Wrong secret");
972 : } else {
973 8 : struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
974 8 : torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
975 : NT_STATUS_ACCESS_DENIED, "Get GUID");
976 : }
977 :
978 10 : return true;
979 : }
980 :
981 5 : static bool test_RestoreGUID_badmagiconsecret(struct torture_context *tctx,
982 : struct dcerpc_pipe *p)
983 : {
984 : enum ndr_err_code ndr_err;
985 5 : 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 5 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
992 :
993 5 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
994 1 : struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob,
995 : false, false, false, true, false, false, false);
996 1 : torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
997 1 : torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
998 1 : out_blob.length = *r->out.data_out_len;
999 1 : ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
1000 1 : torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1001 1 : torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Wrong error code while providing bad magic in secret");
1002 : } else {
1003 4 : struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
1004 4 : torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
1005 : NT_STATUS_ACCESS_DENIED, "Get GUID");
1006 : }
1007 :
1008 5 : return true;
1009 : }
1010 :
1011 5 : static bool test_RestoreGUID_emptyrequest(struct torture_context *tctx,
1012 : struct dcerpc_pipe *p)
1013 : {
1014 5 : 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 5 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1020 :
1021 5 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1022 1 : struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob,
1023 : false, false, false, true, false, false, true);
1024 :
1025 1 : torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
1026 1 : r->in.data_in = talloc(tctx, uint8_t);
1027 1 : r->in.data_in_len = 0;
1028 1 : r->in.param = 0;
1029 1 : torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
1030 1 : out_blob.length = *r->out.data_out_len;
1031 1 : torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_PARAMETER, "Bad error code on wrong has in access check");
1032 : } else {
1033 4 : struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
1034 4 : torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
1035 : NT_STATUS_ACCESS_DENIED, "Get GUID");
1036 : }
1037 :
1038 5 : return true;
1039 : }
1040 :
1041 5 : static bool test_RestoreGUID_badcertguid(struct torture_context *tctx,
1042 : struct dcerpc_pipe *p)
1043 : {
1044 : enum ndr_err_code ndr_err;
1045 5 : 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 5 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1052 :
1053 5 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1054 1 : struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 3, &out_blob,
1055 : false, false, false, false, false, false, true);
1056 1 : torture_assert(tctx, r != NULL, "createRestoreGUIDStruct() failed");
1057 1 : torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
1058 1 : out_blob.length = *r->out.data_out_len;
1059 1 : ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
1060 1 : 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 1 : if (W_ERROR_V(r->out.result) != NT_STATUS_V(NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1067 1 : torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Bad error code on wrong has in access check");
1068 : }
1069 : } else {
1070 4 : struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
1071 4 : torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
1072 : NT_STATUS_ACCESS_DENIED, "Get GUID");
1073 : }
1074 :
1075 5 : return true;
1076 : }
1077 :
1078 5 : static bool test_RestoreGUID_badmagicaccesscheck(struct torture_context *tctx,
1079 : struct dcerpc_pipe *p)
1080 : {
1081 : enum ndr_err_code ndr_err;
1082 5 : 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 5 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1089 :
1090 5 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1091 1 : struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
1092 : false, false, false, false, true, false, false);
1093 1 : torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
1094 1 : torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
1095 1 : out_blob.length = *r->out.data_out_len;
1096 1 : ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
1097 1 : torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1098 1 : torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Bad error code on wrong has in access check");
1099 : } else {
1100 4 : struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
1101 4 : torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
1102 : NT_STATUS_ACCESS_DENIED, "Get GUID");
1103 : }
1104 :
1105 5 : return true;
1106 : }
1107 :
1108 5 : static bool test_RestoreGUID_badhashaccesscheck(struct torture_context *tctx,
1109 : struct dcerpc_pipe *p)
1110 : {
1111 : enum ndr_err_code ndr_err;
1112 5 : 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 5 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1119 :
1120 5 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1121 1 : struct bkrp_BackupKey *r = createRestoreGUIDStruct(tctx, p, 2, &out_blob,
1122 : false, false, false, false, false, true, false);
1123 1 : torture_assert(tctx, r != NULL, "createRestoreGUIDStruct failed");
1124 1 : torture_assert_ntstatus_ok(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r), "Restore GUID");
1125 1 : out_blob.length = *r->out.data_out_len;
1126 1 : ndr_err = ndr_pull_struct_blob(&out_blob, tctx, &resp, (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_unwrapped);
1127 1 : torture_assert_int_equal(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), 0, "Unable to unmarshall bkrp_client_side_unwrapped");
1128 1 : torture_assert_werr_equal(tctx, r->out.result, WERR_INVALID_DATA, "Bad error code on wrong has in access check");
1129 : } else {
1130 4 : struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
1131 4 : torture_assert_ntstatus_equal(tctx, dcerpc_bkrp_BackupKey_r(b, tctx, r),
1132 : NT_STATUS_ACCESS_DENIED, "Get GUID");
1133 : }
1134 :
1135 5 : return true;
1136 : }
1137 :
1138 : /*
1139 : * Check that the RSA modulus in the certificate of the DCs has 2048 bits.
1140 : */
1141 5 : static bool test_RetrieveBackupKeyGUID_validate(struct torture_context *tctx,
1142 : struct dcerpc_pipe *p)
1143 : {
1144 5 : struct dcerpc_binding_handle *b = p->binding_handle;
1145 : DATA_BLOB out_blob;
1146 5 : struct bkrp_BackupKey *r = createRetrieveBackupKeyGUIDStruct(tctx, p, 2, &out_blob);
1147 : enum dcerpc_AuthType auth_type;
1148 : enum dcerpc_AuthLevel auth_level;
1149 :
1150 5 : torture_assert(tctx, r != NULL, "test_RetrieveBackupKeyGUID_validate failed");
1151 :
1152 5 : if (r == NULL) {
1153 0 : return false;
1154 : }
1155 :
1156 5 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1157 :
1158 5 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1159 1 : gnutls_x509_crt_t x509_cert = NULL;
1160 1 : gnutls_pubkey_t pubkey = NULL;
1161 : gnutls_datum_t x509_crt_data;
1162 : gnutls_pk_algorithm_t pubkey_algo;
1163 1 : uint8_t dummy[1] = {0};
1164 1 : DATA_BLOB subject_unique_id = {
1165 : .data = dummy,
1166 : .length = 0,
1167 : };
1168 1 : DATA_BLOB issuer_unique_id = {
1169 : .data = dummy,
1170 : .length = 0,
1171 : };
1172 1 : DATA_BLOB reversed = {
1173 : .data = dummy,
1174 : .length = 0,
1175 : };
1176 : DATA_BLOB serial_number;
1177 1 : unsigned int RSA_returned_bits = 0;
1178 : int version;
1179 : size_t i;
1180 : int cmp;
1181 : int rc;
1182 :
1183 1 : torture_assert_ntstatus_ok(tctx,
1184 : dcerpc_bkrp_BackupKey_r(b, tctx, r),
1185 : "Get GUID");
1186 :
1187 1 : torture_assert_werr_ok(tctx, r->out.result,
1188 : "Get GUID");
1189 :
1190 1 : out_blob.length = *r->out.data_out_len;
1191 :
1192 1 : x509_crt_data.data = out_blob.data;
1193 1 : x509_crt_data.size = out_blob.length;
1194 :
1195 1 : rc = gnutls_x509_crt_init(&x509_cert);
1196 1 : if (rc != GNUTLS_E_SUCCESS) {
1197 0 : return NULL;
1198 : }
1199 :
1200 1 : rc = gnutls_x509_crt_import(x509_cert,
1201 : &x509_crt_data,
1202 : GNUTLS_X509_FMT_DER);
1203 1 : 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 1 : rc = gnutls_x509_crt_get_subject_unique_id(x509_cert,
1212 1 : (char *)subject_unique_id.data,
1213 : &subject_unique_id.length);
1214 1 : 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 1 : subject_unique_id = data_blob_talloc_zero(tctx,
1221 : subject_unique_id.length);
1222 :
1223 1 : rc = gnutls_x509_crt_get_subject_unique_id(x509_cert,
1224 1 : (char *)subject_unique_id.data,
1225 : &subject_unique_id.length);
1226 1 : torture_assert_int_equal(tctx,
1227 : rc,
1228 : GNUTLS_E_SUCCESS,
1229 : "gnutls_x509_crt_get_subject_unique_id failed");
1230 :
1231 1 : rc = gnutls_x509_crt_get_issuer_unique_id(x509_cert,
1232 1 : (char *)issuer_unique_id.data,
1233 : &issuer_unique_id.length);
1234 1 : 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 1 : issuer_unique_id = data_blob_talloc_zero(tctx,
1241 : issuer_unique_id.length);
1242 :
1243 1 : rc = gnutls_x509_crt_get_issuer_unique_id(x509_cert,
1244 1 : (char *)issuer_unique_id.data,
1245 : &issuer_unique_id.length);
1246 1 : torture_assert_int_equal(tctx,
1247 : rc,
1248 : GNUTLS_E_SUCCESS,
1249 : "gnutls_x509_crt_get_issuer_unique_id failed");
1250 :
1251 1 : cmp = data_blob_cmp(&subject_unique_id, &issuer_unique_id);
1252 1 : torture_assert(tctx,
1253 : cmp == 0,
1254 : "The GUID to identify the public key is not "
1255 : "identical");
1256 :
1257 1 : rc = gnutls_x509_crt_get_serial(x509_cert,
1258 1 : reversed.data,
1259 : &reversed.length);
1260 1 : 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 1 : reversed = data_blob_talloc_zero(tctx,
1267 : reversed.length);
1268 :
1269 1 : rc = gnutls_x509_crt_get_serial(x509_cert,
1270 1 : reversed.data,
1271 : &reversed.length);
1272 1 : 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 1 : serial_number = data_blob_talloc_zero(tctx,
1283 : subject_unique_id.length);
1284 :
1285 17 : for (i = 0; i < serial_number.length; i++) {
1286 16 : serial_number.data[i] = reversed.data[reversed.length - i - 1];
1287 : }
1288 :
1289 1 : cmp = data_blob_cmp(&subject_unique_id, &serial_number);
1290 1 : torture_assert(tctx,
1291 : cmp == 0,
1292 : "The GUID to identify the public key is not "
1293 : "identical");
1294 :
1295 : /* Check certificate version */
1296 1 : version = gnutls_x509_crt_get_version(x509_cert);
1297 1 : torture_assert_int_equal(tctx,
1298 : version,
1299 : 3,
1300 : "Invalid certificate version");
1301 :
1302 : /* Get the public key */
1303 1 : rc = gnutls_pubkey_init(&pubkey);
1304 1 : torture_assert_int_equal(tctx,
1305 : rc,
1306 : GNUTLS_E_SUCCESS,
1307 : "gnutls_pubkey_init failed");
1308 :
1309 1 : rc = gnutls_pubkey_import_x509(pubkey,
1310 : x509_cert,
1311 : 0);
1312 1 : gnutls_x509_crt_deinit(x509_cert);
1313 1 : torture_assert_int_equal(tctx,
1314 : rc,
1315 : GNUTLS_E_SUCCESS,
1316 : "gnutls_pubkey_import_x509 failed");
1317 :
1318 1 : pubkey_algo = gnutls_pubkey_get_pk_algorithm(pubkey,
1319 : &RSA_returned_bits);
1320 1 : gnutls_pubkey_deinit(pubkey);
1321 1 : 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 1 : torture_assert_int_equal(tctx,
1327 : RSA_returned_bits,
1328 : 2048,
1329 : "RSA Key doesn't have 2048 bits");
1330 : } else {
1331 4 : torture_assert_ntstatus_equal(tctx,
1332 : dcerpc_bkrp_BackupKey_r(b, tctx, r),
1333 : NT_STATUS_ACCESS_DENIED,
1334 : "Get GUID");
1335 : }
1336 :
1337 5 : return true;
1338 : }
1339 :
1340 5 : 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 5 : 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 5 : struct dcerpc_binding_handle *b = p->binding_handle;
1351 : enum dcerpc_AuthType auth_type;
1352 : enum dcerpc_AuthLevel auth_level;
1353 5 : ZERO_STRUCT(r);
1354 :
1355 5 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1356 :
1357 : /* Encrypt */
1358 5 : torture_assert_ntstatus_ok(tctx,
1359 : GUID_from_string(BACKUPKEY_BACKUP_GUID, &guid),
1360 : "obtain GUID");
1361 :
1362 5 : r.in.guidActionAgent = &guid;
1363 5 : r.in.data_in = plaintext.data;
1364 5 : r.in.data_in_len = plaintext.length;
1365 5 : r.in.param = 0;
1366 5 : r.out.data_out = &encrypted.data;
1367 5 : r.out.data_out_len = &enclen;
1368 5 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1369 1 : torture_assert_ntstatus_ok(tctx,
1370 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1371 : "encrypt");
1372 : } else {
1373 4 : torture_assert_ntstatus_equal(tctx,
1374 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1375 : NT_STATUS_ACCESS_DENIED,
1376 : "encrypt");
1377 4 : return true;
1378 : }
1379 1 : torture_assert_werr_ok(tctx,
1380 : r.out.result,
1381 : "encrypt");
1382 1 : encrypted.length = *r.out.data_out_len;
1383 :
1384 : /* Decrypt */
1385 1 : torture_assert_ntstatus_ok(tctx,
1386 : GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1387 : "obtain GUID");
1388 :
1389 1 : r.in.guidActionAgent = &guid;
1390 1 : r.in.data_in = encrypted.data;
1391 1 : r.in.data_in_len = encrypted.length;
1392 1 : r.in.param = 0;
1393 1 : r.out.data_out = &(decrypted.data);
1394 1 : r.out.data_out_len = &declen;
1395 1 : torture_assert_ntstatus_ok(tctx,
1396 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1397 : "decrypt");
1398 1 : torture_assert_werr_ok(tctx,
1399 : r.out.result,
1400 : "decrypt");
1401 1 : decrypted.length = *r.out.data_out_len;
1402 :
1403 : /* Compare */
1404 1 : torture_assert_data_blob_equal(tctx, plaintext, decrypted, "Decrypt failed");
1405 :
1406 : /* Decrypt */
1407 1 : torture_assert_ntstatus_ok(tctx,
1408 : GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1409 : "obtain GUID");
1410 :
1411 1 : r.in.guidActionAgent = &guid;
1412 1 : r.in.data_in = encrypted.data;
1413 1 : r.in.data_in_len = encrypted.length;
1414 1 : r.in.param = 0;
1415 1 : r.out.data_out = &(decrypted.data);
1416 1 : r.out.data_out_len = &declen;
1417 1 : torture_assert_ntstatus_ok(tctx,
1418 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1419 : "decrypt");
1420 1 : torture_assert_werr_ok(tctx,
1421 : r.out.result,
1422 : "decrypt");
1423 1 : decrypted.length = *r.out.data_out_len;
1424 :
1425 : /* Compare */
1426 1 : torture_assert_data_blob_equal(tctx, plaintext, decrypted, "Decrypt failed");
1427 1 : return true;
1428 : }
1429 :
1430 5 : 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 5 : 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 5 : 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 5 : ZERO_STRUCT(r);
1446 :
1447 5 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1448 :
1449 : /* Encrypt */
1450 5 : torture_assert_ntstatus_ok(tctx,
1451 : GUID_from_string(BACKUPKEY_BACKUP_GUID, &guid),
1452 : "obtain GUID");
1453 :
1454 5 : r.in.guidActionAgent = &guid;
1455 5 : r.in.data_in = plaintext.data;
1456 5 : r.in.data_in_len = plaintext.length;
1457 5 : r.in.param = 0;
1458 5 : r.out.data_out = &encrypted.data;
1459 5 : r.out.data_out_len = &enclen;
1460 5 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1461 1 : torture_assert_ntstatus_ok(tctx,
1462 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1463 : "encrypt");
1464 : } else {
1465 4 : torture_assert_ntstatus_equal(tctx,
1466 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1467 : NT_STATUS_ACCESS_DENIED,
1468 : "encrypt");
1469 4 : return true;
1470 : }
1471 1 : torture_assert_werr_ok(tctx,
1472 : r.out.result,
1473 : "encrypt");
1474 1 : encrypted.length = *r.out.data_out_len;
1475 :
1476 1 : ndr_err = ndr_pull_struct_blob(&encrypted, tctx, &server_side_wrapped,
1477 : (ndr_pull_flags_fn_t)ndr_pull_bkrp_server_side_wrapped);
1478 1 : torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "pull of server_side_wrapped");
1479 :
1480 : /* Change the GUID */
1481 1 : server_side_wrapped.guid = GUID_random();
1482 :
1483 1 : ndr_err = ndr_push_struct_blob(&encrypted, tctx, &server_side_wrapped,
1484 : (ndr_push_flags_fn_t)ndr_push_bkrp_server_side_wrapped);
1485 1 : torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "push of server_side_wrapped");
1486 :
1487 : /* Decrypt */
1488 1 : torture_assert_ntstatus_ok(tctx,
1489 : GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1490 : "obtain GUID");
1491 :
1492 1 : r.in.guidActionAgent = &guid;
1493 1 : r.in.data_in = encrypted.data;
1494 1 : r.in.data_in_len = encrypted.length;
1495 1 : r.in.param = 0;
1496 1 : r.out.data_out = &(decrypted.data);
1497 1 : r.out.data_out_len = &declen;
1498 1 : torture_assert_ntstatus_ok(tctx,
1499 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1500 : "decrypt");
1501 1 : 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 1 : torture_assert_ntstatus_ok(tctx,
1508 : GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1509 : "obtain GUID");
1510 :
1511 1 : r.in.guidActionAgent = &guid;
1512 1 : r.in.data_in = encrypted.data;
1513 1 : r.in.data_in_len = encrypted.length;
1514 1 : r.in.param = 0;
1515 1 : r.out.data_out = &(decrypted.data);
1516 1 : r.out.data_out_len = &declen;
1517 1 : torture_assert_ntstatus_ok(tctx,
1518 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1519 : "decrypt");
1520 1 : torture_assert_werr_equal(tctx,
1521 : r.out.result,
1522 : WERR_INVALID_DATA,
1523 : "decrypt should fail with WERR_INVALID_DATA");
1524 :
1525 1 : return true;
1526 : }
1527 :
1528 5 : 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 5 : struct dcerpc_binding_handle *b = p->binding_handle;
1536 5 : uint8_t short_request[4] = { 1, 0, 0, 0 };
1537 : enum dcerpc_AuthType auth_type;
1538 : enum dcerpc_AuthLevel auth_level;
1539 5 : ZERO_STRUCT(r);
1540 :
1541 5 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1542 :
1543 : /* Decrypt */
1544 5 : torture_assert_ntstatus_ok(tctx,
1545 : GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1546 : "obtain GUID");
1547 :
1548 5 : r.in.guidActionAgent = &guid;
1549 5 : r.in.data_in = short_request;
1550 5 : r.in.data_in_len = 0;
1551 5 : r.in.param = 0;
1552 5 : r.out.data_out = &(decrypted.data);
1553 5 : r.out.data_out_len = &declen;
1554 5 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1555 1 : torture_assert_ntstatus_ok(tctx,
1556 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1557 : "encrypt");
1558 : } else {
1559 4 : torture_assert_ntstatus_equal(tctx,
1560 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1561 : NT_STATUS_ACCESS_DENIED,
1562 : "encrypt");
1563 4 : return true;
1564 : }
1565 1 : 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 1 : torture_assert_ntstatus_ok(tctx,
1572 : GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1573 : "obtain GUID");
1574 :
1575 1 : r.in.guidActionAgent = &guid;
1576 1 : r.in.data_in = short_request;
1577 1 : r.in.data_in_len = 0;
1578 1 : r.in.param = 0;
1579 1 : r.out.data_out = &(decrypted.data);
1580 1 : r.out.data_out_len = &declen;
1581 1 : torture_assert_ntstatus_ok(tctx,
1582 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1583 : "decrypt");
1584 1 : 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 1 : torture_assert_ntstatus_ok(tctx,
1591 : GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1592 : "obtain GUID");
1593 :
1594 1 : r.in.guidActionAgent = &guid;
1595 1 : r.in.data_in = NULL;
1596 1 : r.in.data_in_len = 0;
1597 1 : r.in.param = 0;
1598 1 : r.out.data_out = &(decrypted.data);
1599 1 : r.out.data_out_len = &declen;
1600 1 : 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 1 : torture_assert_ntstatus_ok(tctx,
1607 : GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1608 : "obtain GUID");
1609 :
1610 1 : r.in.guidActionAgent = &guid;
1611 1 : r.in.data_in = NULL;
1612 1 : r.in.data_in_len = 0;
1613 1 : r.in.param = 0;
1614 1 : r.out.data_out = &(decrypted.data);
1615 1 : r.out.data_out_len = &declen;
1616 1 : torture_assert_ntstatus_equal(tctx,
1617 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1618 : NT_STATUS_INVALID_PARAMETER_MIX,
1619 : "decrypt");
1620 :
1621 1 : return true;
1622 : }
1623 :
1624 :
1625 5 : 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 5 : struct dcerpc_binding_handle *b = p->binding_handle;
1633 5 : uint8_t short_request[4] = { 1, 0, 0, 0 };
1634 : enum dcerpc_AuthType auth_type;
1635 : enum dcerpc_AuthLevel auth_level;
1636 5 : ZERO_STRUCT(r);
1637 :
1638 5 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
1639 :
1640 : /* Decrypt */
1641 5 : torture_assert_ntstatus_ok(tctx,
1642 : GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1643 : "obtain GUID");
1644 :
1645 5 : r.in.guidActionAgent = &guid;
1646 5 : r.in.data_in = short_request;
1647 5 : r.in.data_in_len = 4;
1648 5 : r.in.param = 0;
1649 5 : r.out.data_out = &(decrypted.data);
1650 5 : r.out.data_out_len = &declen;
1651 5 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
1652 1 : torture_assert_ntstatus_ok(tctx,
1653 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1654 : "encrypt");
1655 : } else {
1656 4 : torture_assert_ntstatus_equal(tctx,
1657 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1658 : NT_STATUS_ACCESS_DENIED,
1659 : "encrypt");
1660 4 : return true;
1661 : }
1662 1 : 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 1 : torture_assert_ntstatus_ok(tctx,
1669 : GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1670 : "obtain GUID");
1671 :
1672 1 : r.in.guidActionAgent = &guid;
1673 1 : r.in.data_in = short_request;
1674 1 : r.in.data_in_len = 4;
1675 1 : r.in.param = 0;
1676 1 : r.out.data_out = &(decrypted.data);
1677 1 : r.out.data_out_len = &declen;
1678 1 : torture_assert_ntstatus_ok(tctx,
1679 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1680 : "decrypt");
1681 1 : 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 1 : torture_assert_ntstatus_ok(tctx,
1688 : GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
1689 : "obtain GUID");
1690 :
1691 1 : r.in.guidActionAgent = &guid;
1692 1 : r.in.data_in = short_request;
1693 1 : r.in.data_in_len = 1;
1694 1 : r.in.param = 0;
1695 1 : r.out.data_out = &(decrypted.data);
1696 1 : r.out.data_out_len = &declen;
1697 1 : torture_assert_ntstatus_ok(tctx,
1698 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1699 : "decrypt");
1700 1 : 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 1 : torture_assert_ntstatus_ok(tctx,
1707 : GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
1708 : "obtain GUID");
1709 :
1710 1 : r.in.guidActionAgent = &guid;
1711 1 : r.in.data_in = short_request;
1712 1 : r.in.data_in_len = 1;
1713 1 : r.in.param = 0;
1714 1 : r.out.data_out = &(decrypted.data);
1715 1 : r.out.data_out_len = &declen;
1716 1 : torture_assert_ntstatus_ok(tctx,
1717 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
1718 : "decrypt");
1719 1 : torture_assert_werr_equal(tctx,
1720 : r.out.result,
1721 : WERR_INVALID_PARAMETER,
1722 : "decrypt should fail with WERR_INVALID_PARAMETER");
1723 :
1724 1 : return true;
1725 : }
1726 :
1727 3 : 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 3 : char *lsa_binding_string = NULL;
1732 3 : struct dcerpc_binding *lsa_binding = NULL;
1733 3 : struct dcerpc_pipe *lsa_p = NULL;
1734 3 : 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 3 : 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 3 : ZERO_STRUCT(r);
1758 3 : ZERO_STRUCT(r_secret);
1759 3 : 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 3 : lsa_binding_string = talloc_asprintf(tctx, "ncacn_np:%s",
1765 : torture_setting_string(tctx, "host", NULL));
1766 3 : torture_assert(tctx, lsa_binding_string != NULL, "lsa_binding_string");
1767 :
1768 3 : torture_assert_ntstatus_ok(tctx,
1769 : dcerpc_parse_binding(tctx, lsa_binding_string, &lsa_binding),
1770 : "Failed to parse dcerpc binding");
1771 :
1772 3 : torture_assert_ntstatus_ok(tctx,
1773 : dcerpc_pipe_connect_b(tctx, &lsa_p,
1774 : lsa_binding, &ndr_table_lsarpc,
1775 : samba_cmdline_get_creds(),
1776 : tctx->ev, tctx->lp_ctx),
1777 : "Opening LSA pipe");
1778 3 : lsa_b = lsa_p->binding_handle;
1779 :
1780 3 : torture_assert(tctx, test_lsa_OpenPolicy2(lsa_b, tctx, &handle), "OpenPolicy failed");
1781 3 : r_secret.in.name.string = "G$BCKUPKEY_P";
1782 :
1783 3 : r_secret.in.handle = handle;
1784 3 : r_secret.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1785 3 : r_secret.out.sec_handle = &sec_handle;
1786 :
1787 3 : torture_comment(tctx, "Testing OpenSecret\n");
1788 :
1789 3 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(lsa_b, tctx, &r_secret),
1790 : "OpenSecret failed");
1791 3 : torture_assert_ntstatus_ok(tctx, r_secret.out.result,
1792 : "OpenSecret failed");
1793 :
1794 3 : r_query_secret.in.sec_handle = &sec_handle;
1795 3 : r_query_secret.in.new_val = &bufp1;
1796 3 : bufp1.buf = NULL;
1797 :
1798 3 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(lsa_b, tctx, &r_query_secret),
1799 : "QuerySecret failed");
1800 3 : torture_assert_ntstatus_ok(tctx, r_query_secret.out.result,
1801 : "QuerySecret failed");
1802 :
1803 :
1804 3 : preferred_key.data = r_query_secret.out.new_val->buf->data;
1805 3 : preferred_key.length = r_query_secret.out.new_val->buf->size;
1806 3 : torture_assert_ntstatus_ok(tctx, dcerpc_fetch_session_key(lsa_p, &session_key),
1807 : "dcerpc_fetch_session_key failed");
1808 :
1809 3 : 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 3 : torture_assert_ntstatus_ok(tctx, GUID_from_ndr_blob(&preferred_key_clear, &preferred_key_guid),
1815 : "GUID parse failed");
1816 :
1817 3 : 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 3 : key_guid_string = GUID_string(tctx, &server_side_wrapped->guid);
1824 3 : r_secret.in.name.string = talloc_asprintf(tctx, "G$BCKUPKEY_%s", key_guid_string);
1825 :
1826 3 : r_secret.in.handle = handle;
1827 3 : r_secret.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1828 3 : r_secret.out.sec_handle = &sec_handle;
1829 :
1830 3 : torture_comment(tctx, "Testing OpenSecret\n");
1831 :
1832 3 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenSecret_r(lsa_b, tctx, &r_secret),
1833 : "OpenSecret failed");
1834 3 : torture_assert_ntstatus_ok(tctx, r_secret.out.result,
1835 : "OpenSecret failed");
1836 :
1837 3 : r_query_secret.in.sec_handle = &sec_handle;
1838 3 : r_query_secret.in.new_val = &bufp1;
1839 :
1840 3 : torture_assert_ntstatus_ok(tctx, dcerpc_lsa_QuerySecret_r(lsa_b, tctx, &r_query_secret),
1841 : "QuerySecret failed");
1842 3 : torture_assert_ntstatus_ok(tctx, r_query_secret.out.result,
1843 : "QuerySecret failed");
1844 :
1845 :
1846 3 : decrypt_key.data = r_query_secret.out.new_val->buf->data;
1847 3 : decrypt_key.length = r_query_secret.out.new_val->buf->size;
1848 :
1849 3 : 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 3 : 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 3 : 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 3 : gnutls_hmac_init(&hmac_hnd,
1865 : GNUTLS_MAC_SHA1,
1866 : server_key.key,
1867 : sizeof(server_key.key));
1868 3 : gnutls_hmac(hmac_hnd,
1869 3 : server_side_wrapped->r2,
1870 : sizeof(server_side_wrapped->r2));
1871 3 : gnutls_hmac_output(hmac_hnd, symkey);
1872 :
1873 : /* rc4 decrypt sid and secret using sym key */
1874 3 : cipher_key.data = symkey;
1875 3 : cipher_key.size = sizeof(symkey);
1876 :
1877 3 : encrypted_blob = data_blob_talloc(tctx, server_side_wrapped->rc4encryptedpayload,
1878 : server_side_wrapped->ciphertext_length);
1879 :
1880 3 : rc = gnutls_cipher_init(&cipher_hnd,
1881 : GNUTLS_CIPHER_ARCFOUR_128,
1882 : &cipher_key,
1883 : NULL);
1884 3 : torture_assert_int_equal(tctx,
1885 : rc,
1886 : GNUTLS_E_SUCCESS,
1887 : "gnutls_cipher_init failed");
1888 9 : rc = gnutls_cipher_encrypt2(cipher_hnd,
1889 3 : encrypted_blob.data,
1890 : encrypted_blob.length,
1891 3 : encrypted_blob.data,
1892 : encrypted_blob.length);
1893 3 : torture_assert_int_equal(tctx,
1894 : rc,
1895 : GNUTLS_E_SUCCESS,
1896 : "gnutls_cipher_encrypt failed");
1897 3 : gnutls_cipher_deinit(cipher_hnd);
1898 :
1899 3 : 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 3 : 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 3 : gnutls_hmac(hmac_hnd,
1912 : rc4payload.r3,
1913 : sizeof(rc4payload.r3));
1914 3 : gnutls_hmac_deinit(hmac_hnd, mackey);
1915 :
1916 3 : 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 3 : gnutls_hmac_init(&hmac_hnd,
1921 : GNUTLS_MAC_SHA1,
1922 : mackey,
1923 : sizeof(mackey));
1924 : /* SID field */
1925 6 : gnutls_hmac(hmac_hnd,
1926 3 : sid_blob.data,
1927 : sid_blob.length);
1928 : /* Secret field */
1929 6 : gnutls_hmac(hmac_hnd,
1930 3 : rc4payload.secret_data.data,
1931 : rc4payload.secret_data.length);
1932 3 : gnutls_hmac_output(hmac_hnd, mac);
1933 :
1934 3 : torture_assert_mem_equal(tctx, mac, rc4payload.mac, sizeof(mac), "mac not correct");
1935 3 : torture_assert_int_equal(tctx, rc4payload.secret_data.length,
1936 : plaintext.length, "decrypted data is not correct length");
1937 3 : 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 3 : caller_sid = get_user_sid(tctx, tctx,
1943 : cli_credentials_get_username(
1944 : samba_cmdline_get_creds()));
1945 :
1946 3 : torture_assert_sid_equal(tctx, &rc4payload.sid, caller_sid, "Secret saved with wrong SID");
1947 :
1948 :
1949 : /* RE-encrypt */
1950 :
1951 3 : if (wrong == WRONG_SID) {
1952 1 : rc4payload.sid.sub_auths[rc4payload.sid.num_auths - 1] = DOMAIN_RID_KRBTGT;
1953 : }
1954 :
1955 3 : dump_data_pw("mackey: \n", mackey, sizeof(mackey));
1956 :
1957 3 : 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 6 : gnutls_hmac(hmac_hnd,
1965 3 : sid_blob.data,
1966 : sid_blob.length);
1967 : /* Secret field */
1968 6 : gnutls_hmac(hmac_hnd,
1969 3 : rc4payload.secret_data.data,
1970 : rc4payload.secret_data.length);
1971 3 : gnutls_hmac_deinit(hmac_hnd, rc4payload.mac);
1972 :
1973 3 : dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac));
1974 :
1975 3 : 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 3 : if (wrong == WRONG_KEY) {
1982 1 : symkey[0] = 78;
1983 1 : symkey[1] = 78;
1984 1 : symkey[2] = 78;
1985 : }
1986 :
1987 : /* rc4 encrypt sid and secret using sym key */
1988 3 : cipher_key.data = symkey;
1989 3 : cipher_key.size = sizeof(symkey);
1990 :
1991 3 : rc = gnutls_cipher_init(&cipher_hnd,
1992 : GNUTLS_CIPHER_ARCFOUR_128,
1993 : &cipher_key,
1994 : NULL);
1995 3 : torture_assert_int_equal(tctx,
1996 : rc,
1997 : GNUTLS_E_SUCCESS,
1998 : "gnutls_cipher_init failed");
1999 9 : rc = gnutls_cipher_encrypt2(cipher_hnd,
2000 3 : encrypted_blob.data,
2001 : encrypted_blob.length,
2002 3 : encrypted_blob.data,
2003 : encrypted_blob.length);
2004 3 : torture_assert_int_equal(tctx,
2005 : rc,
2006 : GNUTLS_E_SUCCESS,
2007 : "gnutls_cipher_encrypt failed");
2008 3 : gnutls_cipher_deinit(cipher_hnd);
2009 :
2010 :
2011 : /* re-create server wrap structure */
2012 :
2013 3 : torture_assert_int_equal(tctx, encrypted_blob.length,
2014 : server_side_wrapped->ciphertext_length,
2015 : "expected encrypted length not to change");
2016 3 : if (wrong == RIGHT_KEY) {
2017 1 : 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 3 : server_side_wrapped->payload_length = rc4payload.secret_data.length;
2024 3 : server_side_wrapped->ciphertext_length = encrypted_blob.length;
2025 3 : server_side_wrapped->rc4encryptedpayload = encrypted_blob.data;
2026 :
2027 3 : return true;
2028 : }
2029 :
2030 :
2031 55 : 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 55 : 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 55 : 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 55 : bool repush = false;
2046 : enum dcerpc_AuthType auth_type;
2047 : enum dcerpc_AuthLevel auth_level;
2048 55 : ZERO_STRUCT(r);
2049 :
2050 55 : dcerpc_binding_handle_auth_info(b, &auth_type, &auth_level);
2051 :
2052 : /* Encrypt */
2053 55 : torture_assert_ntstatus_ok(tctx,
2054 : GUID_from_string(BACKUPKEY_BACKUP_GUID, &guid),
2055 : "obtain GUID");
2056 :
2057 55 : r.in.guidActionAgent = &guid;
2058 55 : r.in.data_in = plaintext.data;
2059 55 : r.in.data_in_len = plaintext.length;
2060 55 : r.in.param = 0;
2061 55 : r.out.data_out = &encrypted.data;
2062 55 : r.out.data_out_len = &enclen;
2063 55 : if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2064 11 : torture_assert_ntstatus_ok(tctx,
2065 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
2066 : "encrypt");
2067 : } else {
2068 44 : torture_assert_ntstatus_equal(tctx,
2069 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
2070 : NT_STATUS_ACCESS_DENIED,
2071 : "encrypt");
2072 44 : return true;
2073 : }
2074 11 : torture_assert_werr_ok(tctx,
2075 : r.out.result,
2076 : "encrypt");
2077 11 : encrypted.length = *r.out.data_out_len;
2078 :
2079 11 : ndr_err = ndr_pull_struct_blob(&encrypted, tctx, &server_side_wrapped,
2080 : (ndr_pull_flags_fn_t)ndr_pull_bkrp_server_side_wrapped);
2081 11 : torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "pull of server_side_wrapped");
2082 :
2083 11 : torture_assert_int_equal(tctx, server_side_wrapped.payload_length, plaintext.length,
2084 : "wrong payload length");
2085 :
2086 11 : switch (wrong) {
2087 1 : case WRONG_MAGIC:
2088 : /* Change the magic. Forced by our NDR layer, so do it raw */
2089 1 : SIVAL(encrypted.data, 0, 78); /* valid values are 1-3 */
2090 1 : break;
2091 1 : case WRONG_R2:
2092 1 : server_side_wrapped.r2[0] = 78;
2093 1 : server_side_wrapped.r2[1] = 78;
2094 1 : server_side_wrapped.r2[3] = 78;
2095 1 : repush = true;
2096 1 : break;
2097 1 : case WRONG_PAYLOAD_LENGTH:
2098 1 : server_side_wrapped.payload_length = UINT32_MAX - 8;
2099 1 : repush = true;
2100 1 : break;
2101 1 : 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 1 : SIVAL(encrypted.data, 8, UINT32_MAX - 8); /* valid values are 1-3 */
2107 1 : break;
2108 1 : case SHORT_PAYLOAD_LENGTH:
2109 1 : server_side_wrapped.payload_length = server_side_wrapped.payload_length - 8;
2110 1 : repush = true;
2111 1 : break;
2112 1 : 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 1 : SIVAL(encrypted.data, 8, server_side_wrapped.ciphertext_length - 8); /* valid values are 1-3 */
2118 1 : break;
2119 1 : case ZERO_PAYLOAD_LENGTH:
2120 1 : server_side_wrapped.payload_length = 0;
2121 1 : repush = true;
2122 1 : break;
2123 1 : 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 1 : SIVAL(encrypted.data, 8, 0); /* valid values are 1-3 */
2129 1 : break;
2130 :
2131 3 : case RIGHT_KEY:
2132 : case WRONG_KEY:
2133 : case WRONG_SID:
2134 3 : torture_assert(tctx,
2135 : test_ServerWrap_encrypt_decrypt_manual(tctx, &server_side_wrapped, wrong),
2136 : "test_ServerWrap_encrypt_decrypt_manual failed");
2137 3 : repush = true;
2138 3 : break;
2139 : }
2140 :
2141 11 : if (repush) {
2142 7 : ndr_err = ndr_push_struct_blob(&encrypted, tctx, &server_side_wrapped,
2143 : (ndr_push_flags_fn_t)ndr_push_bkrp_server_side_wrapped);
2144 7 : torture_assert_ndr_err_equal(tctx, ndr_err, NDR_ERR_SUCCESS, "push of server_side_wrapped");
2145 : }
2146 :
2147 : /* Decrypt */
2148 11 : torture_assert_ntstatus_ok(tctx,
2149 : GUID_from_string(BACKUPKEY_RESTORE_GUID, &guid),
2150 : "obtain GUID");
2151 :
2152 11 : r.in.guidActionAgent = &guid;
2153 11 : r.in.data_in = encrypted.data;
2154 11 : r.in.data_in_len = encrypted.length;
2155 11 : r.in.param = 0;
2156 11 : r.out.data_out = &(decrypted.data);
2157 11 : r.out.data_out_len = &declen;
2158 11 : torture_assert_ntstatus_ok(tctx,
2159 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
2160 : "decrypt");
2161 :
2162 11 : if ((wrong == WRONG_R2 || wrong == WRONG_KEY)
2163 2 : && W_ERROR_EQUAL(r.out.result, WERR_INVALID_SID)) {
2164 0 : 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 11 : } else if (wrong == RIGHT_KEY) {
2169 1 : torture_assert_werr_equal(tctx,
2170 : r.out.result,
2171 : WERR_OK,
2172 : "decrypt should succeed!");
2173 10 : } else if (wrong == WRONG_SID) {
2174 1 : torture_assert_werr_equal(tctx,
2175 : r.out.result,
2176 : WERR_INVALID_ACCESS,
2177 : "decrypt should fail with WERR_INVALID_ACCESS");
2178 : } else {
2179 9 : if (!W_ERROR_EQUAL(r.out.result, WERR_INVALID_ACCESS)
2180 9 : && !W_ERROR_EQUAL(r.out.result, WERR_INVALID_PARAMETER)) {
2181 0 : 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 11 : torture_assert_ntstatus_ok(tctx,
2189 : GUID_from_string(BACKUPKEY_RESTORE_GUID_WIN2K, &guid),
2190 : "obtain GUID");
2191 :
2192 11 : r.in.guidActionAgent = &guid;
2193 11 : r.in.data_in = encrypted.data;
2194 11 : r.in.data_in_len = encrypted.length;
2195 11 : r.in.param = 0;
2196 11 : r.out.data_out = &(decrypted.data);
2197 11 : r.out.data_out_len = &declen;
2198 11 : torture_assert_ntstatus_ok(tctx,
2199 : dcerpc_bkrp_BackupKey_r(b, tctx, &r),
2200 : "decrypt");
2201 :
2202 11 : if ((wrong == WRONG_R2 || wrong == WRONG_KEY)
2203 2 : && W_ERROR_EQUAL(r.out.result, WERR_INVALID_SID)) {
2204 0 : 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 11 : } else if (wrong == RIGHT_KEY) {
2209 1 : torture_assert_werr_equal(tctx,
2210 : r.out.result,
2211 : WERR_OK,
2212 : "decrypt should succeed!");
2213 10 : } else if (wrong == WRONG_SID) {
2214 1 : torture_assert_werr_equal(tctx,
2215 : r.out.result,
2216 : WERR_INVALID_ACCESS,
2217 : "decrypt should fail with WERR_INVALID_ACCESS");
2218 : } else {
2219 9 : torture_assert_werr_equal(tctx,
2220 : r.out.result,
2221 : WERR_INVALID_PARAMETER,
2222 : "decrypt should fail with WERR_INVALID_PARAMETER");
2223 : }
2224 :
2225 11 : return true;
2226 : }
2227 :
2228 5 : static bool test_ServerWrap_decrypt_wrong_magic(struct torture_context *tctx,
2229 : struct dcerpc_pipe *p)
2230 : {
2231 5 : return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_MAGIC);
2232 : }
2233 :
2234 5 : static bool test_ServerWrap_decrypt_wrong_r2(struct torture_context *tctx,
2235 : struct dcerpc_pipe *p)
2236 : {
2237 5 : return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_R2);
2238 : }
2239 :
2240 5 : static bool test_ServerWrap_decrypt_wrong_payload_length(struct torture_context *tctx,
2241 : struct dcerpc_pipe *p)
2242 : {
2243 5 : return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_PAYLOAD_LENGTH);
2244 : }
2245 :
2246 5 : static bool test_ServerWrap_decrypt_short_payload_length(struct torture_context *tctx,
2247 : struct dcerpc_pipe *p)
2248 : {
2249 5 : return test_ServerWrap_decrypt_wrong_stuff(tctx, p, SHORT_PAYLOAD_LENGTH);
2250 : }
2251 :
2252 5 : static bool test_ServerWrap_decrypt_zero_payload_length(struct torture_context *tctx,
2253 : struct dcerpc_pipe *p)
2254 : {
2255 5 : return test_ServerWrap_decrypt_wrong_stuff(tctx, p, ZERO_PAYLOAD_LENGTH);
2256 : }
2257 :
2258 5 : static bool test_ServerWrap_decrypt_wrong_ciphertext_length(struct torture_context *tctx,
2259 : struct dcerpc_pipe *p)
2260 : {
2261 5 : return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_CIPHERTEXT_LENGTH);
2262 : }
2263 :
2264 5 : static bool test_ServerWrap_decrypt_short_ciphertext_length(struct torture_context *tctx,
2265 : struct dcerpc_pipe *p)
2266 : {
2267 5 : return test_ServerWrap_decrypt_wrong_stuff(tctx, p, SHORT_CIPHERTEXT_LENGTH);
2268 : }
2269 :
2270 5 : static bool test_ServerWrap_decrypt_zero_ciphertext_length(struct torture_context *tctx,
2271 : struct dcerpc_pipe *p)
2272 : {
2273 5 : return test_ServerWrap_decrypt_wrong_stuff(tctx, p, ZERO_CIPHERTEXT_LENGTH);
2274 : }
2275 :
2276 5 : static bool test_ServerWrap_encrypt_decrypt_remote_key(struct torture_context *tctx,
2277 : struct dcerpc_pipe *p)
2278 : {
2279 5 : return test_ServerWrap_decrypt_wrong_stuff(tctx, p, RIGHT_KEY);
2280 : }
2281 :
2282 5 : static bool test_ServerWrap_encrypt_decrypt_wrong_key(struct torture_context *tctx,
2283 : struct dcerpc_pipe *p)
2284 : {
2285 5 : return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_KEY);
2286 : }
2287 :
2288 5 : static bool test_ServerWrap_encrypt_decrypt_wrong_sid(struct torture_context *tctx,
2289 : struct dcerpc_pipe *p)
2290 : {
2291 5 : return test_ServerWrap_decrypt_wrong_stuff(tctx, p, WRONG_SID);
2292 : }
2293 :
2294 964 : struct torture_suite *torture_rpc_backupkey(TALLOC_CTX *mem_ctx)
2295 : {
2296 964 : struct torture_suite *suite = torture_suite_create(mem_ctx, "backupkey");
2297 :
2298 : struct torture_rpc_tcase *tcase;
2299 :
2300 964 : tcase = torture_suite_add_rpc_iface_tcase(suite, "backupkey",
2301 : &ndr_table_backupkey);
2302 :
2303 964 : torture_rpc_tcase_add_test(tcase, "retreive_backup_key_guid",
2304 : test_RetrieveBackupKeyGUID);
2305 :
2306 964 : torture_rpc_tcase_add_test(tcase, "restore_guid",
2307 : test_RestoreGUID);
2308 :
2309 964 : 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 964 : torture_rpc_tcase_add_test(tcase, "restore_guid_2nd",
2315 : test_RestoreGUID);
2316 :
2317 964 : torture_rpc_tcase_add_test(tcase, "unable_to_decrypt_secret",
2318 : test_RestoreGUID_ko);
2319 :
2320 964 : torture_rpc_tcase_add_test(tcase, "wrong_user_restore_guid",
2321 : test_RestoreGUID_wronguser);
2322 :
2323 964 : torture_rpc_tcase_add_test(tcase, "wrong_version_restore_guid",
2324 : test_RestoreGUID_wrongversion);
2325 :
2326 964 : torture_rpc_tcase_add_test(tcase, "bad_magic_on_secret_restore_guid",
2327 : test_RestoreGUID_badmagiconsecret);
2328 :
2329 964 : torture_rpc_tcase_add_test(tcase, "bad_hash_on_secret_restore_guid",
2330 : test_RestoreGUID_badhashaccesscheck);
2331 :
2332 964 : torture_rpc_tcase_add_test(tcase, "bad_magic_on_accesscheck_restore_guid",
2333 : test_RestoreGUID_badmagicaccesscheck);
2334 :
2335 964 : torture_rpc_tcase_add_test(tcase, "bad_cert_guid_restore_guid",
2336 : test_RestoreGUID_badcertguid);
2337 :
2338 964 : torture_rpc_tcase_add_test(tcase, "empty_request_restore_guid",
2339 : test_RestoreGUID_emptyrequest);
2340 :
2341 964 : torture_rpc_tcase_add_test(tcase, "retreive_backup_key_guid_validate",
2342 : test_RetrieveBackupKeyGUID_validate);
2343 :
2344 964 : torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt",
2345 : test_ServerWrap_encrypt_decrypt);
2346 :
2347 964 : torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_keyGUID",
2348 : test_ServerWrap_decrypt_wrong_keyGUID);
2349 :
2350 964 : torture_rpc_tcase_add_test(tcase, "server_wrap_empty_request",
2351 : test_ServerWrap_decrypt_empty_request);
2352 :
2353 964 : torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_short_request",
2354 : test_ServerWrap_decrypt_short_request);
2355 :
2356 964 : torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_magic",
2357 : test_ServerWrap_decrypt_wrong_magic);
2358 :
2359 964 : torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_r2",
2360 : test_ServerWrap_decrypt_wrong_r2);
2361 :
2362 964 : torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_payload_length",
2363 : test_ServerWrap_decrypt_wrong_payload_length);
2364 :
2365 964 : torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_short_payload_length",
2366 : test_ServerWrap_decrypt_short_payload_length);
2367 :
2368 964 : torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_zero_payload_length",
2369 : test_ServerWrap_decrypt_zero_payload_length);
2370 :
2371 964 : torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_wrong_ciphertext_length",
2372 : test_ServerWrap_decrypt_wrong_ciphertext_length);
2373 :
2374 964 : torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_short_ciphertext_length",
2375 : test_ServerWrap_decrypt_short_ciphertext_length);
2376 :
2377 964 : torture_rpc_tcase_add_test(tcase, "server_wrap_decrypt_zero_ciphertext_length",
2378 : test_ServerWrap_decrypt_zero_ciphertext_length);
2379 :
2380 964 : torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt_remote_key",
2381 : test_ServerWrap_encrypt_decrypt_remote_key);
2382 :
2383 964 : torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt_wrong_key",
2384 : test_ServerWrap_encrypt_decrypt_wrong_key);
2385 :
2386 964 : torture_rpc_tcase_add_test(tcase, "server_wrap_encrypt_decrypt_wrong_sid",
2387 : test_ServerWrap_encrypt_decrypt_wrong_sid);
2388 :
2389 964 : return suite;
2390 : }
|