pylibsmb: Fix a typo
[samba.git] / source4 / dsdb / samdb / ldb_modules / tests / test_encrypted_secrets.c
1 /*
2    Unit tests for the encrypted secrets code in encrypted_secrets.c
3
4    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2017
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <stdarg.h>
21 #include <stddef.h>
22 #include <setjmp.h>
23 #include <unistd.h>
24 #include <cmocka.h>
25
26 int ldb_encrypted_secrets_module_init(const char *version);
27 #define TEST_ENCRYPTED_SECRETS
28 #include "../encrypted_secrets.c"
29
30 struct ldbtest_ctx {
31         struct tevent_context *ev;
32         struct ldb_context *ldb;
33         struct ldb_module *module;
34
35         const char *dbfile;
36         const char *lockfile;   /* lockfile is separate */
37         const char *keyfile;
38
39         const char *dbpath;
40 };
41
42 /* -------------------------------------------------------------------------- */
43 /*
44  * Replace the dsdb helper routines used by the operational_init function
45  *
46  */
47 int dsdb_module_search_dn(
48         struct ldb_module *module,
49         TALLOC_CTX *mem_ctx,
50         struct ldb_result **_res,
51         struct ldb_dn *basedn,
52         const char * const *attrs,
53         uint32_t dsdb_flags,
54         struct ldb_request *parent)
55 {
56         struct ldb_context *ldb = ldb_module_get_ctx(module);
57         struct ldb_message *msg = ldb_msg_new(ldb);
58         struct ldb_result  *res = talloc_zero(mem_ctx, struct ldb_result);
59
60         msg->dn = ldb_dn_new(msg, ldb, "@SAMBA_DSDB");
61         ldb_msg_add_string(
62                 msg,
63                 SAMBA_REQUIRED_FEATURES_ATTR,
64                 SAMBA_ENCRYPTED_SECRETS_FEATURE);
65
66         res->msgs = talloc_array(mem_ctx, struct ldb_message*, 1);
67         res->msgs[0] = msg;
68         *_res = res;
69         return LDB_SUCCESS;
70 }
71
72 int dsdb_module_reference_dn(
73         struct ldb_module *module,
74         TALLOC_CTX *mem_ctx,
75         struct ldb_dn *base,
76         const char *attribute,
77         struct ldb_dn **dn,
78         struct ldb_request *parent)
79 {
80         return LDB_SUCCESS;
81 }
82 /* -------------------------------------------------------------------------- */
83
84 static void unlink_old_db(struct ldbtest_ctx *test_ctx)
85 {
86         int ret;
87
88         errno = 0;
89         ret = unlink(test_ctx->lockfile);
90         if (ret == -1 && errno != ENOENT) {
91                 fail();
92         }
93
94         errno = 0;
95         ret = unlink(test_ctx->dbfile);
96         if (ret == -1 && errno != ENOENT) {
97                 fail();
98         }
99
100         errno = 0;
101         ret = unlink(test_ctx->keyfile);
102         if (ret == -1 && errno != ENOENT) {
103                 fail();
104         }
105 }
106
107 static void write_key(void **state, DATA_BLOB key) {
108
109         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
110                                                         struct ldbtest_ctx);
111         FILE *fp = NULL;
112         int written = 0;
113
114         fp = fopen(test_ctx->keyfile, "wb");
115         assert_non_null(fp);
116
117         written = fwrite(key.data, 1, key.length, fp);
118         assert_int_equal(written, key.length);
119         fclose(fp);
120 }
121
122 static const struct ldb_module_ops eol_ops = {
123         .name              = "eol",
124         .search            = NULL,
125         .add               = NULL,
126         .modify            = NULL,
127         .del               = NULL,
128         .rename            = NULL,
129         .init_context      = NULL
130 };
131
132 static int setup(void **state)
133 {
134         struct ldbtest_ctx *test_ctx = NULL;
135         struct ldb_module *eol = NULL;
136         int rc;
137
138         test_ctx = talloc_zero(NULL, struct ldbtest_ctx);
139         assert_non_null(test_ctx);
140
141         test_ctx->ev = tevent_context_init(test_ctx);
142         assert_non_null(test_ctx->ev);
143
144         test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
145         assert_non_null(test_ctx->ldb);
146
147
148
149         test_ctx->module = ldb_module_new(
150                 test_ctx,
151                 test_ctx->ldb,
152                 "encrypted_secrets",
153                 &ldb_encrypted_secrets_module_ops);
154         assert_non_null(test_ctx->module);
155         eol = ldb_module_new(test_ctx, test_ctx->ldb, "eol", &eol_ops);
156         assert_non_null(eol);
157         ldb_module_set_next(test_ctx->module, eol);
158
159         test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb");
160         assert_non_null(test_ctx->dbfile);
161
162         test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock",
163                                              test_ctx->dbfile);
164         assert_non_null(test_ctx->lockfile);
165
166         test_ctx->keyfile = talloc_strdup(test_ctx, SECRETS_KEY_FILE);
167         assert_non_null(test_ctx->keyfile);
168
169         test_ctx->dbpath = talloc_asprintf(test_ctx,
170                         TEST_BE"://%s", test_ctx->dbfile);
171         assert_non_null(test_ctx->dbpath);
172
173         unlink_old_db(test_ctx);
174
175         rc = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
176         assert_int_equal(rc, 0);
177         *state = test_ctx;
178         return 0;
179 }
180
181 static int setup_with_key(void **state)
182 {
183         struct ldbtest_ctx *test_ctx = NULL;
184         DATA_BLOB key = data_blob_null;
185         uint8_t key_data[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
186                               0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
187         int rc;
188
189         setup(state);
190         key.data   = key_data;
191         key.length = sizeof(key_data);
192
193         write_key(state, key);
194
195         test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
196         {
197                 struct ldb_message *msg = ldb_msg_new(test_ctx->ldb);
198                 msg->dn = ldb_dn_new(msg, test_ctx->ldb, "@SAMBA_DSDB");
199                 ldb_msg_add_string(
200                         msg,
201                         SAMBA_REQUIRED_FEATURES_ATTR,
202                         SAMBA_ENCRYPTED_SECRETS_FEATURE);
203                 ldb_add(test_ctx->ldb, msg);
204         }
205
206         rc = es_init(test_ctx->module);
207         assert_int_equal(rc, LDB_SUCCESS);
208
209         return 0;
210 }
211
212 static int teardown(void **state)
213 {
214         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
215                                                         struct ldbtest_ctx);
216
217         unlink_old_db(test_ctx);
218         talloc_free(test_ctx);
219         return 0;
220 }
221 /*
222  * No key file present.
223  *
224  * The key should be empty and encrypt_secrets should be false.
225  */
226 static void test_no_key_file(void **state)
227 {
228         struct ldbtest_ctx *test_ctx =
229                 talloc_get_type_abort(*state, struct ldbtest_ctx);
230         struct es_data *data = NULL;
231
232         int rc;
233
234         rc = es_init(test_ctx->module);
235         assert_int_equal(rc, LDB_SUCCESS);
236
237         data = talloc_get_type(ldb_module_get_private(test_ctx->module),
238                                struct es_data);
239
240         assert_false(data->encrypt_secrets);
241         assert_int_equal(0, data->keys[0].length);
242
243 }
244
245 /*
246  * Key file present.
247  *
248  * The key should be loaded and encrypt secrets should be true;
249  */
250 static void test_key_file(void **state)
251 {
252         struct ldbtest_ctx *test_ctx =
253                 talloc_get_type_abort(*state, struct ldbtest_ctx);
254         struct es_data *data = NULL;
255         int rc;
256         DATA_BLOB key = data_blob_null;
257         uint8_t key_data[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
258                               0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
259
260         key.data   = key_data;
261         key.length = sizeof(key_data);
262
263         write_key(state, key);
264
265
266         rc = es_init(test_ctx->module);
267         assert_int_equal(rc, LDB_SUCCESS);
268
269         data = talloc_get_type(ldb_module_get_private(test_ctx->module),
270                                struct es_data);
271
272         assert_true(data->encrypt_secrets);
273         assert_int_equal(16, data->keys[0].length);
274         assert_int_equal(0, data_blob_cmp(&key, &data->keys[0]));
275
276 }
277
278 /*
279  * Key file present, short key.
280  *
281  * The key should be not be loaded and an error returned.
282  */
283 static void test_key_file_short_key(void **state)
284 {
285         struct ldbtest_ctx *test_ctx =
286                 talloc_get_type_abort(*state, struct ldbtest_ctx);
287         int rc;
288         DATA_BLOB key = data_blob_null;
289         uint8_t key_data[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
290                               0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e};
291
292         key.data   = key_data;
293         key.length = sizeof(key_data);
294
295         write_key(state, key);
296
297
298         rc = es_init(test_ctx->module);
299         assert_int_equal(rc, LDB_ERR_OPERATIONS_ERROR);
300 }
301
302 /*
303  * Key file present, long key.
304  *
305  * Only the first 16 bytes of the key should be loaded.
306  */
307 static void test_key_file_long_key(void **state)
308 {
309         struct ldbtest_ctx *test_ctx =
310                 talloc_get_type_abort(*state, struct ldbtest_ctx);
311         struct es_data *data = NULL;
312         int rc;
313         DATA_BLOB key = data_blob_null;
314         uint8_t key_data[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
315                               0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0xf,
316                               0x10};
317
318         key.data   = key_data;
319         key.length = sizeof(key_data);
320
321         write_key(state, key);
322
323         rc = es_init(test_ctx->module);
324         assert_int_equal(rc, LDB_SUCCESS);
325
326         data = talloc_get_type(ldb_module_get_private(test_ctx->module),
327                                struct es_data);
328
329         assert_true(data->encrypt_secrets);
330         assert_int_equal(16, data->keys[0].length);
331
332         /*
333          * Should have only read the first 16 bytes of the written key
334          */
335         key.length = 16;
336         assert_int_equal(0, data_blob_cmp(&key, &data->keys[0]));
337 }
338
339 /*
340  *  Test gnutls_encryption and decryption.
341  */
342 static void test_gnutls_value_decryption(void **state)
343 {
344         struct ldbtest_ctx *test_ctx =
345                 talloc_get_type_abort(*state, struct ldbtest_ctx);
346         const struct ldb_val plain_text =
347                 data_blob_string_const("A text value");
348         unsigned char iv_data[] = {
349                 0xe7, 0xa3, 0x85, 0x17, 0x45, 0x73, 0xf4, 0x25,
350                 0xa5, 0x56, 0xde, 0x4c,
351         };
352         unsigned char encrypted_data[] = {
353                 0xac, 0x13, 0x86, 0x94, 0x3b, 0xed, 0xf2, 0x51,
354                 0xec, 0x85, 0x4d, 0x00, 0x37, 0x81, 0x46, 0x15,
355                 0x42, 0x13, 0xb1, 0x69, 0x49, 0x10, 0xe7, 0x9e,
356                 0x15, 0xbd, 0x95, 0x75, 0x6b, 0x0c, 0xc0, 0xa4,
357         };
358         struct EncryptedSecret es = {
359                 .iv = {
360                         .data = iv_data,
361                         .length = sizeof(iv_data),
362                 },
363                 .header = {
364                         .magic = ENCRYPTED_SECRET_MAGIC_VALUE,
365                         .version = SECRET_ATTRIBUTE_VERSION,
366                         .algorithm = ENC_SECRET_AES_128_AEAD,
367                 },
368                 .encrypted = {
369                         .data = encrypted_data,
370                         .length = sizeof(encrypted_data),
371                 }
372         };
373         unsigned char es_keys_blob[] = {
374                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
375                 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
376         };
377         struct es_data data = {
378                 .encrypt_secrets = true,
379                 .keys[0] = {
380                         .data = es_keys_blob,
381                         .length = sizeof(es_keys_blob),
382                 },
383                 .encryption_algorithm = GNUTLS_CIPHER_AES_128_GCM,
384         };
385         struct PlaintextSecret *decrypted =
386                 talloc_zero(test_ctx, struct PlaintextSecret);
387         int err = LDB_SUCCESS;
388
389         gnutls_decrypt_aead(&err,
390                             test_ctx,
391                             test_ctx->ldb,
392                             &es,
393                             decrypted,
394                             &data);
395         assert_int_equal(LDB_SUCCESS, err);
396         assert_int_equal(plain_text.length, decrypted->cleartext.length);
397         assert_int_equal(0, data_blob_cmp(&decrypted->cleartext, &plain_text));
398 }
399
400 /*
401  *  Test gnutls_encryption and decryption.
402  */
403 static void test_gnutls_value_encryption(void **state)
404 {
405         struct ldbtest_ctx *test_ctx =
406                 talloc_get_type_abort(*state, struct ldbtest_ctx);
407         struct ldb_val plain_text = data_blob_null;
408         struct ldb_val cipher_text = data_blob_null;
409         struct EncryptedSecret es;
410
411         struct es_data *data = talloc_get_type(
412                 ldb_module_get_private(test_ctx->module),
413                 struct es_data);
414         int err = LDB_SUCCESS;
415         int rc;
416
417         plain_text = data_blob_string_const("A text value");
418         cipher_text = gnutls_encrypt_aead(
419                         &err,
420                         test_ctx,
421                         test_ctx->ldb,
422                         plain_text,
423                         data);
424         assert_int_equal(LDB_SUCCESS, err);
425
426         rc = ndr_pull_struct_blob(
427                 &cipher_text,
428                 test_ctx,
429                 &es,
430                 (ndr_pull_flags_fn_t) ndr_pull_EncryptedSecret);
431         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
432         assert_true(check_header(&es));
433
434         {
435                 struct PlaintextSecret *decrypted =
436                         talloc_zero(test_ctx, struct PlaintextSecret);
437                 gnutls_decrypt_aead(
438                         &err,
439                         test_ctx,
440                         test_ctx->ldb,
441                         &es,
442                         decrypted,
443                         data);
444                 assert_int_equal(LDB_SUCCESS, err);
445                 assert_int_equal(
446                         plain_text.length,
447                         decrypted->cleartext.length);
448                 assert_int_equal(0,
449                         data_blob_cmp(
450                                 &decrypted->cleartext,
451                                 &plain_text));
452         }
453 }
454
455 static void test_gnutls_altered_header(void **state)
456 {
457         struct ldbtest_ctx *test_ctx =
458                 talloc_get_type_abort(*state, struct ldbtest_ctx);
459         struct ldb_val plain_text = data_blob_null;
460         struct ldb_val cipher_text = data_blob_null;
461         struct EncryptedSecret es;
462
463         struct es_data *data = talloc_get_type(
464                 ldb_module_get_private(test_ctx->module),
465                 struct es_data);
466         int err = LDB_SUCCESS;
467         int rc;
468
469         plain_text = data_blob_string_const("A text value");
470         cipher_text = gnutls_encrypt_aead(
471                         &err,
472                         test_ctx,
473                         test_ctx->ldb,
474                         plain_text,
475                         data);
476         assert_int_equal(LDB_SUCCESS, err);
477
478         rc = ndr_pull_struct_blob(
479                 &cipher_text,
480                 test_ctx,
481                 &es,
482                 (ndr_pull_flags_fn_t) ndr_pull_EncryptedSecret);
483         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
484         assert_true(check_header(&es));
485
486         {
487                 struct PlaintextSecret *decrypted =
488                         talloc_zero(test_ctx, struct PlaintextSecret);
489                 gnutls_decrypt_aead(
490                         &err,
491                         test_ctx,
492                         test_ctx->ldb,
493                         &es,
494                         decrypted,
495                         data);
496                 assert_int_equal(LDB_SUCCESS, err);
497                 assert_int_equal(
498                         plain_text.length,
499                         decrypted->cleartext.length);
500                 assert_int_equal(0,
501                         data_blob_cmp(
502                                 &decrypted->cleartext,
503                                 &plain_text));
504         }
505         es.header.flags = es.header.flags ^ 0xffffffff;
506         {
507                 struct PlaintextSecret *decrypted =
508                         talloc_zero(test_ctx, struct PlaintextSecret);
509                 gnutls_decrypt_aead(
510                         &err,
511                         test_ctx,
512                         test_ctx->ldb,
513                         &es,
514                         decrypted,
515                         data);
516                 assert_int_equal(LDB_ERR_OPERATIONS_ERROR, err);
517         }
518 }
519
520 static void test_gnutls_altered_data(void **state)
521 {
522         struct ldbtest_ctx *test_ctx =
523                 talloc_get_type_abort(*state, struct ldbtest_ctx);
524         struct ldb_val plain_text = data_blob_null;
525         struct ldb_val cipher_text = data_blob_null;
526         struct EncryptedSecret es;
527
528         struct es_data *data = talloc_get_type(
529                 ldb_module_get_private(test_ctx->module),
530                 struct es_data);
531         int err = LDB_SUCCESS;
532         int rc;
533
534         plain_text = data_blob_string_const("A text value");
535         cipher_text = gnutls_encrypt_aead(
536                         &err,
537                         test_ctx,
538                         test_ctx->ldb,
539                         plain_text,
540                         data);
541         assert_int_equal(LDB_SUCCESS, err);
542
543         rc = ndr_pull_struct_blob(
544                 &cipher_text,
545                 test_ctx,
546                 &es,
547                 (ndr_pull_flags_fn_t) ndr_pull_EncryptedSecret);
548         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
549         assert_true(check_header(&es));
550
551         {
552                 struct PlaintextSecret *decrypted =
553                         talloc_zero(test_ctx, struct PlaintextSecret);
554                 gnutls_decrypt_aead(
555                         &err,
556                         test_ctx,
557                         test_ctx->ldb,
558                         &es,
559                         decrypted,
560                         data);
561                 assert_int_equal(LDB_SUCCESS, err);
562                 assert_int_equal(
563                         plain_text.length,
564                         decrypted->cleartext.length);
565                 assert_int_equal(0,
566                         data_blob_cmp(
567                                 &decrypted->cleartext,
568                                 &plain_text));
569         }
570         es.encrypted.data[0] = es.encrypted.data[0] ^ 0xff;
571         {
572                 struct PlaintextSecret *decrypted =
573                         talloc_zero(test_ctx, struct PlaintextSecret);
574                 gnutls_decrypt_aead(
575                         &err,
576                         test_ctx,
577                         test_ctx->ldb,
578                         &es,
579                         decrypted,
580                         data);
581                 assert_int_equal(LDB_ERR_OPERATIONS_ERROR, err);
582         }
583 }
584
585 static void test_gnutls_altered_iv(void **state)
586 {
587         struct ldbtest_ctx *test_ctx =
588                 talloc_get_type_abort(*state, struct ldbtest_ctx);
589         struct ldb_val plain_text = data_blob_null;
590         struct ldb_val cipher_text = data_blob_null;
591         struct EncryptedSecret es;
592
593         struct es_data *data = talloc_get_type(
594                 ldb_module_get_private(test_ctx->module),
595                 struct es_data);
596         int err = LDB_SUCCESS;
597         int rc;
598
599         plain_text = data_blob_string_const("A text value");
600         cipher_text = gnutls_encrypt_aead(
601                         &err,
602                         test_ctx,
603                         test_ctx->ldb,
604                         plain_text,
605                         data);
606         assert_int_equal(LDB_SUCCESS, err);
607
608         rc = ndr_pull_struct_blob(
609                 &cipher_text,
610                 test_ctx,
611                 &es,
612                 (ndr_pull_flags_fn_t) ndr_pull_EncryptedSecret);
613         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
614         assert_true(check_header(&es));
615
616         {
617                 struct PlaintextSecret *decrypted =
618                         talloc_zero(test_ctx, struct PlaintextSecret);
619                 gnutls_decrypt_aead(
620                         &err,
621                         test_ctx,
622                         test_ctx->ldb,
623                         &es,
624                         decrypted,
625                         data);
626                 assert_int_equal(LDB_SUCCESS, err);
627                 assert_int_equal(
628                         plain_text.length,
629                         decrypted->cleartext.length);
630                 assert_int_equal(0,
631                         data_blob_cmp(
632                                 &decrypted->cleartext,
633                                 &plain_text));
634         }
635         es.iv.data[0] = es.iv.data[0] ^ 0xff;
636         {
637                 struct PlaintextSecret *decrypted =
638                         talloc_zero(test_ctx, struct PlaintextSecret);
639                 gnutls_decrypt_aead(
640                         &err,
641                         test_ctx,
642                         test_ctx->ldb,
643                         &es,
644                         decrypted,
645                         data);
646                 assert_int_equal(LDB_ERR_OPERATIONS_ERROR, err);
647         }
648 }
649
650 /*
651  *  Test samba encryption and decryption and decryption.
652  */
653
654 /*
655  *  Test message encryption.
656  *  Test the secret attributes of a message are encrypted and decrypted.
657  *  Test that the non secret attributes are not encrypted.
658  *
659  */
660 static void test_message_encryption_decryption(void **state)
661 {
662         struct ldbtest_ctx *test_ctx =
663                 talloc_get_type_abort(*state, struct ldbtest_ctx);
664         struct ldb_context *ldb = test_ctx->ldb;
665         const char * const secrets[] = {DSDB_SECRET_ATTRIBUTES};
666         const size_t num_secrets
667                 = (sizeof(secrets)/sizeof(secrets[0]));
668         struct ldb_message *msg = ldb_msg_new(ldb);
669         const struct ldb_message *encrypted_msg = NULL;
670         struct es_data *data = talloc_get_type(
671                 ldb_module_get_private(test_ctx->module),
672                 struct es_data);
673         struct ldb_message_element *el = NULL;
674         int ret = LDB_SUCCESS;
675         size_t i;
676         unsigned int j;
677
678         msg->dn = ldb_dn_new(msg, ldb, "dc=test");
679         ldb_msg_add_string(msg, "cmocka_test_name01", "value01");
680         for (i=0; i < num_secrets; i++) {
681                 ldb_msg_add_string(
682                         msg,
683                         secrets[i],
684                         secrets[i]);
685         }
686         ldb_msg_add_string(msg, "cmocka_test_name02", "value02");
687
688         encrypted_msg = encrypt_secret_attributes(
689                 &ret,
690                 test_ctx,
691                 test_ctx->ldb,
692                 msg,
693                 data);
694         assert_int_equal(LDB_SUCCESS, ret);
695
696         /*
697          * Check that all the secret attributes have been encrypted
698          *
699          */
700         for (i=0; i < num_secrets; i++) {
701                 el = ldb_msg_find_element(encrypted_msg, secrets[i]);
702                 assert_non_null(el);
703                 for (j = 0; j < el->num_values; j++) {
704                         int rc = LDB_SUCCESS;
705                         struct ldb_val dc = decrypt_value(
706                                 &rc,
707                                 test_ctx,
708                                 test_ctx->ldb,
709                                 el->values[j],
710                                 data);
711                         assert_int_equal(LDB_SUCCESS, rc);
712                         assert_memory_equal(
713                                 secrets[i],
714                                 dc.data,
715                                 dc.length);
716                         TALLOC_FREE(dc.data);
717                 }
718         }
719
720         /*
721          * Check that the normal attributes have not been encrypted
722          */
723         el = ldb_msg_find_element(encrypted_msg, "cmocka_test_name01");
724         assert_non_null(el);
725         assert_memory_equal(
726                 "value01",
727                 el->values[0].data,
728                 el->values[0].length);
729
730         el = ldb_msg_find_element(encrypted_msg, "cmocka_test_name02");
731         assert_non_null(el);
732         assert_memory_equal(
733                 "value02",
734                 el->values[0].data,
735                 el->values[0].length);
736
737         /*
738          * Now decrypt the message
739          */
740         ret = decrypt_secret_attributes(test_ctx->ldb,
741                                         discard_const(encrypted_msg),
742                                         data);
743         assert_int_equal(LDB_SUCCESS, ret);
744
745         /*
746          * Check that all the secret attributes have been decrypted
747          */
748         for (i=0; i < num_secrets; i++) {
749                 el = ldb_msg_find_element(encrypted_msg, secrets[i]);
750                 assert_non_null(el);
751                 for (j = 0; j < el->num_values; j++) {
752                         assert_memory_equal(
753                                 secrets[i],
754                                 el->values[j].data,
755                                 el->values[j].length);
756                 }
757         }
758
759         /*
760          * Check that the normal attributes are intact
761          */
762         el = ldb_msg_find_element(msg, "cmocka_test_name01");
763         assert_non_null(el);
764         assert_memory_equal(
765                 "value01",
766                 el->values[0].data,
767                 el->values[0].length);
768
769         el = ldb_msg_find_element(msg, "cmocka_test_name02");
770         assert_non_null(el);
771         assert_memory_equal(
772                 "value02",
773                 el->values[0].data,
774                 el->values[0].length);
775
776 }
777
778 static void test_check_header(void **state)
779 {
780         struct ldbtest_ctx *test_ctx =
781                 talloc_get_type_abort(*state, struct ldbtest_ctx);
782
783         struct ldb_val enc = data_blob_null;
784         struct EncryptedSecret *es = NULL;
785         int rc;
786
787         /*
788          * Valid EncryptedSecret
789          */
790         es = makeEncryptedSecret(test_ctx->ldb, test_ctx);
791         rc = ndr_push_struct_blob(
792                 &enc,
793                 test_ctx,
794                 es,
795                 (ndr_push_flags_fn_t) ndr_push_EncryptedSecret);
796         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
797         assert_true(check_header(es));
798         TALLOC_FREE(enc.data);
799         TALLOC_FREE(es);
800
801         /*
802          * invalid magic value
803          */
804         es = makeEncryptedSecret(test_ctx->ldb, test_ctx);
805         es->header.magic = 0xca5cadee;
806         rc = ndr_push_struct_blob(
807                 &enc,
808                 test_ctx,
809                 es,
810                 (ndr_push_flags_fn_t) ndr_push_EncryptedSecret);
811         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
812         assert_false(check_header(es));
813         TALLOC_FREE(enc.data);
814         TALLOC_FREE(es);
815
816         /*
817          * invalid version
818          */
819         es = makeEncryptedSecret(test_ctx->ldb, test_ctx);
820         es->header.version = SECRET_ATTRIBUTE_VERSION + 1;
821         rc = ndr_push_struct_blob(
822                 &enc,
823                 test_ctx,
824                 es,
825                 (ndr_push_flags_fn_t) ndr_push_EncryptedSecret);
826         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
827         assert_false(check_header(es));
828         TALLOC_FREE(enc.data);
829         TALLOC_FREE(es);
830
831         /*
832          * invalid algorithm
833          */
834         es = makeEncryptedSecret(test_ctx->ldb, test_ctx);
835         es->header.algorithm = SECRET_ENCRYPTION_ALGORITHM + 1;
836         rc = ndr_push_struct_blob(
837                 &enc,
838                 test_ctx,
839                 es,
840                 (ndr_push_flags_fn_t) ndr_push_EncryptedSecret);
841         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
842         assert_false(check_header(es));
843         TALLOC_FREE(enc.data);
844         TALLOC_FREE(es);
845 }
846
847 /*
848  * Attempt to decrypt a message containing an unencrypted secret attribute
849  * this should fail
850  */
851 static void test_unencrypted_secret(void **state)
852 {
853         struct ldbtest_ctx *test_ctx =
854                 talloc_get_type_abort(*state, struct ldbtest_ctx);
855         struct ldb_context *ldb = test_ctx->ldb;
856         struct ldb_message *msg = ldb_msg_new(ldb);
857         struct es_data *data = talloc_get_type(
858                 ldb_module_get_private(test_ctx->module),
859                 struct es_data);
860         int ret = LDB_SUCCESS;
861
862         msg->dn = ldb_dn_new(msg, ldb, "dc=test");
863         ldb_msg_add_string(msg, "unicodePwd", "value01");
864
865         ret = decrypt_secret_attributes(test_ctx->ldb, msg, data);
866         assert_int_equal(LDB_ERR_OPERATIONS_ERROR, ret);
867 }
868
869 /*
870  *  Test full decryption of a static value with static key
871  */
872 static void test_record_decryption(void **state)
873 {
874         struct ldbtest_ctx *test_ctx =
875                 talloc_get_type_abort(*state, struct ldbtest_ctx);
876         unsigned char plain_data[] = {
877                 0xe6, 0xa6, 0xb8, 0xff, 0xdf, 0x06, 0x6c, 0xe3,
878                 0xea, 0xd0, 0x94, 0xbb, 0x79, 0xbd, 0x0a, 0x24
879         };
880         unsigned char encrypted_data[] = {
881                 0x0c, 0x00, 0x00, 0x00, 0x33, 0x91, 0x74, 0x25,
882                 0x26, 0xcc, 0x0b, 0x8c, 0x21, 0xc1, 0x13, 0xe2,
883                 0xed, 0xad, 0x5c, 0xca, 0x01, 0x00, 0x00, 0x00,
884                 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
885                 0x1a, 0xdc, 0xc9, 0x11, 0x08, 0xca, 0x2c, 0xfb,
886                 0xc8, 0x32, 0x6b, 0x1b, 0x25, 0x7f, 0x52, 0xbb,
887                 0xae, 0x9b, 0x88, 0x52, 0xb0, 0x18, 0x6d, 0x9d,
888                 0x9b, 0xdd, 0xcd, 0x1b, 0x5f, 0x4a, 0x5c, 0x29,
889                 0xca, 0x0b, 0x36, 0xaa
890         };
891         struct ldb_val cipher_text
892                 = data_blob_const(encrypted_data,
893                                   sizeof(encrypted_data));
894         unsigned char es_keys_blob[] = {
895                 0x1d, 0xae, 0xf5, 0xaa, 0xa3, 0x85, 0x0d, 0x0a,
896                 0x8c, 0x24, 0x5c, 0x4c, 0xa7, 0x0f, 0x81, 0x79
897         };
898         struct es_data data = {
899                 .encrypt_secrets = true,
900                 .keys[0] = {
901                         .data = es_keys_blob,
902                         .length = sizeof(es_keys_blob),
903                 },
904                 .encryption_algorithm = GNUTLS_CIPHER_AES_128_GCM,
905         };
906         int err = LDB_SUCCESS;
907         struct ldb_val dec = decrypt_value(&err, test_ctx, test_ctx->ldb, cipher_text,
908                                            &data);
909         assert_int_equal(LDB_SUCCESS, err);
910         assert_int_equal(sizeof(plain_data), dec.length);
911         assert_memory_equal(dec.data, plain_data, sizeof(plain_data));
912 }
913
914
915 int main(void) {
916         const struct CMUnitTest tests[] = {
917                 cmocka_unit_test_setup_teardown(
918                         test_no_key_file,
919                         setup,
920                         teardown),
921                 cmocka_unit_test_setup_teardown(
922                         test_key_file,
923                         setup,
924                         teardown),
925                 cmocka_unit_test_setup_teardown(
926                         test_key_file_short_key,
927                         setup,
928                         teardown),
929                 cmocka_unit_test_setup_teardown(
930                         test_key_file_long_key,
931                         setup,
932                         teardown),
933                 cmocka_unit_test_setup_teardown(
934                         test_check_header,
935                         setup,
936                         teardown),
937                 cmocka_unit_test_setup_teardown(
938                         test_gnutls_value_decryption,
939                         setup_with_key,
940                         teardown),
941                 cmocka_unit_test_setup_teardown(
942                         test_gnutls_value_encryption,
943                         setup_with_key,
944                         teardown),
945                 cmocka_unit_test_setup_teardown(
946                         test_gnutls_altered_header,
947                         setup_with_key,
948                         teardown),
949                 cmocka_unit_test_setup_teardown(
950                         test_gnutls_altered_data,
951                         setup_with_key,
952                         teardown),
953                 cmocka_unit_test_setup_teardown(
954                         test_gnutls_altered_iv,
955                         setup_with_key,
956                         teardown),
957                 cmocka_unit_test_setup_teardown(
958                         test_message_encryption_decryption,
959                         setup_with_key,
960                         teardown),
961                 cmocka_unit_test_setup_teardown(
962                         test_unencrypted_secret,
963                         setup_with_key,
964                         teardown),
965                 cmocka_unit_test_setup_teardown(
966                         test_record_decryption,
967                         setup_with_key,
968                         teardown),
969         };
970
971         cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
972         return cmocka_run_group_tests(tests, NULL, NULL);
973 }