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