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