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