LCOV - code coverage report
Current view: top level - source4/dsdb/samdb/ldb_modules/tests - test_encrypted_secrets.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 377 382 98.7 %
Date: 2024-04-21 15:09:00 Functions: 20 21 95.2 %

          Line data    Source code
       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          24 : 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          24 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
      57          24 :         struct ldb_message *msg = ldb_msg_new(ldb);
      58          24 :         struct ldb_result  *res = talloc_zero(mem_ctx, struct ldb_result);
      59             : 
      60          24 :         msg->dn = ldb_dn_new(msg, ldb, "@SAMBA_DSDB");
      61          24 :         ldb_msg_add_string(
      62             :                 msg,
      63             :                 SAMBA_REQUIRED_FEATURES_ATTR,
      64             :                 SAMBA_ENCRYPTED_SECRETS_FEATURE);
      65             : 
      66          24 :         res->msgs = talloc_array(mem_ctx, struct ldb_message*, 1);
      67          24 :         res->msgs[0] = msg;
      68          24 :         *_res = res;
      69          24 :         return LDB_SUCCESS;
      70             : }
      71             : 
      72           0 : 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           0 :         return LDB_SUCCESS;
      81             : }
      82             : /* -------------------------------------------------------------------------- */
      83             : 
      84          52 : static void unlink_old_db(struct ldbtest_ctx *test_ctx)
      85             : {
      86          52 :         int ret;
      87             : 
      88          52 :         errno = 0;
      89          52 :         ret = unlink(test_ctx->lockfile);
      90          52 :         if (ret == -1 && errno != ENOENT) {
      91           0 :                 fail();
      92             :         }
      93             : 
      94          52 :         errno = 0;
      95          52 :         ret = unlink(test_ctx->dbfile);
      96          52 :         if (ret == -1 && errno != ENOENT) {
      97           0 :                 fail();
      98             :         }
      99             : 
     100          52 :         errno = 0;
     101          52 :         ret = unlink(test_ctx->keyfile);
     102          52 :         if (ret == -1 && errno != ENOENT) {
     103           0 :                 fail();
     104             :         }
     105          52 : }
     106             : 
     107          22 : static void write_key(void **state, DATA_BLOB key) {
     108             : 
     109          22 :         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
     110             :                                                         struct ldbtest_ctx);
     111          22 :         FILE *fp = NULL;
     112          22 :         int written = 0;
     113             : 
     114          22 :         fp = fopen(test_ctx->keyfile, "wb");
     115          22 :         assert_non_null(fp);
     116             : 
     117          22 :         written = fwrite(key.data, 1, key.length, fp);
     118          22 :         assert_int_equal(written, key.length);
     119          22 :         fclose(fp);
     120          22 : }
     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          26 : static int setup(void **state)
     133             : {
     134          26 :         struct ldbtest_ctx *test_ctx = NULL;
     135          26 :         struct ldb_module *eol = NULL;
     136          26 :         int rc;
     137             : 
     138          26 :         test_ctx = talloc_zero(NULL, struct ldbtest_ctx);
     139          26 :         assert_non_null(test_ctx);
     140             : 
     141          26 :         test_ctx->ev = tevent_context_init(test_ctx);
     142          26 :         assert_non_null(test_ctx->ev);
     143             : 
     144          26 :         test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev);
     145          26 :         assert_non_null(test_ctx->ldb);
     146             : 
     147             : 
     148             : 
     149          26 :         test_ctx->module = ldb_module_new(
     150             :                 test_ctx,
     151             :                 test_ctx->ldb,
     152             :                 "encrypted_secrets",
     153             :                 &ldb_encrypted_secrets_module_ops);
     154          26 :         assert_non_null(test_ctx->module);
     155          26 :         eol = ldb_module_new(test_ctx, test_ctx->ldb, "eol", &eol_ops);
     156          26 :         assert_non_null(eol);
     157          26 :         ldb_module_set_next(test_ctx->module, eol);
     158             : 
     159          26 :         test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb");
     160          26 :         assert_non_null(test_ctx->dbfile);
     161             : 
     162          26 :         test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock",
     163             :                                              test_ctx->dbfile);
     164          26 :         assert_non_null(test_ctx->lockfile);
     165             : 
     166          26 :         test_ctx->keyfile = talloc_strdup(test_ctx, SECRETS_KEY_FILE);
     167          26 :         assert_non_null(test_ctx->keyfile);
     168             : 
     169          26 :         test_ctx->dbpath = talloc_asprintf(test_ctx,
     170             :                         TEST_BE"://%s", test_ctx->dbfile);
     171          26 :         assert_non_null(test_ctx->dbpath);
     172             : 
     173          26 :         unlink_old_db(test_ctx);
     174             : 
     175          26 :         rc = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL);
     176          26 :         assert_int_equal(rc, 0);
     177          26 :         *state = test_ctx;
     178          26 :         return 0;
     179             : }
     180             : 
     181          16 : static int setup_with_key(void **state)
     182             : {
     183          16 :         struct ldbtest_ctx *test_ctx = NULL;
     184          16 :         DATA_BLOB key = data_blob_null;
     185          16 :         uint8_t key_data[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     186             :                               0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
     187          16 :         int rc;
     188             : 
     189          16 :         setup(state);
     190          16 :         key.data   = key_data;
     191          16 :         key.length = sizeof(key_data);
     192             : 
     193          16 :         write_key(state, key);
     194             : 
     195          16 :         test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx);
     196             :         {
     197          16 :                 struct ldb_message *msg = ldb_msg_new(test_ctx->ldb);
     198          16 :                 msg->dn = ldb_dn_new(msg, test_ctx->ldb, "@SAMBA_DSDB");
     199          16 :                 ldb_msg_add_string(
     200             :                         msg,
     201             :                         SAMBA_REQUIRED_FEATURES_ATTR,
     202             :                         SAMBA_ENCRYPTED_SECRETS_FEATURE);
     203          16 :                 ldb_add(test_ctx->ldb, msg);
     204             :         }
     205             : 
     206          16 :         rc = es_init(test_ctx->module);
     207          16 :         assert_int_equal(rc, LDB_SUCCESS);
     208             : 
     209          16 :         return 0;
     210             : }
     211             : 
     212          26 : static int teardown(void **state)
     213             : {
     214          26 :         struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state,
     215             :                                                         struct ldbtest_ctx);
     216             : 
     217          26 :         unlink_old_db(test_ctx);
     218          26 :         talloc_free(test_ctx);
     219          26 :         return 0;
     220             : }
     221             : /*
     222             :  * No key file present.
     223             :  *
     224             :  * The key should be empty and encrypt_secrets should be false.
     225             :  */
     226           2 : static void test_no_key_file(void **state)
     227             : {
     228           2 :         struct ldbtest_ctx *test_ctx =
     229           2 :                 talloc_get_type_abort(*state, struct ldbtest_ctx);
     230           2 :         struct es_data *data = NULL;
     231             : 
     232           2 :         int rc;
     233             : 
     234           2 :         rc = es_init(test_ctx->module);
     235           2 :         assert_int_equal(rc, LDB_SUCCESS);
     236             : 
     237           2 :         data = talloc_get_type(ldb_module_get_private(test_ctx->module),
     238             :                                struct es_data);
     239             : 
     240           2 :         assert_false(data->encrypt_secrets);
     241           2 :         assert_int_equal(0, data->keys[0].length);
     242             : 
     243           2 : }
     244             : 
     245             : /*
     246             :  * Key file present.
     247             :  *
     248             :  * The key should be loaded and encrypt secrets should be true;
     249             :  */
     250           2 : static void test_key_file(void **state)
     251             : {
     252           2 :         struct ldbtest_ctx *test_ctx =
     253           2 :                 talloc_get_type_abort(*state, struct ldbtest_ctx);
     254           2 :         struct es_data *data = NULL;
     255           2 :         int rc;
     256           2 :         DATA_BLOB key = data_blob_null;
     257           2 :         uint8_t key_data[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     258             :                               0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
     259             : 
     260           2 :         key.data   = key_data;
     261           2 :         key.length = sizeof(key_data);
     262             : 
     263           2 :         write_key(state, key);
     264             : 
     265             : 
     266           2 :         rc = es_init(test_ctx->module);
     267           2 :         assert_int_equal(rc, LDB_SUCCESS);
     268             : 
     269           2 :         data = talloc_get_type(ldb_module_get_private(test_ctx->module),
     270             :                                struct es_data);
     271             : 
     272           2 :         assert_true(data->encrypt_secrets);
     273           2 :         assert_int_equal(16, data->keys[0].length);
     274           2 :         assert_int_equal(0, data_blob_cmp(&key, &data->keys[0]));
     275             : 
     276           2 : }
     277             : 
     278             : /*
     279             :  * Key file present, short key.
     280             :  *
     281             :  * The key should be not be loaded and an error returned.
     282             :  */
     283           2 : static void test_key_file_short_key(void **state)
     284             : {
     285           2 :         struct ldbtest_ctx *test_ctx =
     286           2 :                 talloc_get_type_abort(*state, struct ldbtest_ctx);
     287           2 :         int rc;
     288           2 :         DATA_BLOB key = data_blob_null;
     289           2 :         uint8_t key_data[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     290             :                               0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e};
     291             : 
     292           2 :         key.data   = key_data;
     293           2 :         key.length = sizeof(key_data);
     294             : 
     295           2 :         write_key(state, key);
     296             : 
     297             : 
     298           2 :         rc = es_init(test_ctx->module);
     299           2 :         assert_int_equal(rc, LDB_ERR_OPERATIONS_ERROR);
     300           2 : }
     301             : 
     302             : /*
     303             :  * Key file present, long key.
     304             :  *
     305             :  * Only the first 16 bytes of the key should be loaded.
     306             :  */
     307           2 : static void test_key_file_long_key(void **state)
     308             : {
     309           2 :         struct ldbtest_ctx *test_ctx =
     310           2 :                 talloc_get_type_abort(*state, struct ldbtest_ctx);
     311           2 :         struct es_data *data = NULL;
     312           2 :         int rc;
     313           2 :         DATA_BLOB key = data_blob_null;
     314           2 :         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           2 :         key.data   = key_data;
     319           2 :         key.length = sizeof(key_data);
     320             : 
     321           2 :         write_key(state, key);
     322             : 
     323           2 :         rc = es_init(test_ctx->module);
     324           2 :         assert_int_equal(rc, LDB_SUCCESS);
     325             : 
     326           2 :         data = talloc_get_type(ldb_module_get_private(test_ctx->module),
     327             :                                struct es_data);
     328             : 
     329           2 :         assert_true(data->encrypt_secrets);
     330           2 :         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           2 :         key.length = 16;
     336           2 :         assert_int_equal(0, data_blob_cmp(&key, &data->keys[0]));
     337           2 : }
     338             : 
     339             : /*
     340             :  *  Test gnutls_encryption and decryption.
     341             :  */
     342           2 : static void test_gnutls_value_decryption(void **state)
     343             : {
     344           2 :         struct ldbtest_ctx *test_ctx =
     345           2 :                 talloc_get_type_abort(*state, struct ldbtest_ctx);
     346           2 :         const struct ldb_val plain_text =
     347           2 :                 data_blob_string_const("A text value");
     348           2 :         unsigned char iv_data[] = {
     349             :                 0xe7, 0xa3, 0x85, 0x17, 0x45, 0x73, 0xf4, 0x25,
     350             :                 0xa5, 0x56, 0xde, 0x4c,
     351             :         };
     352           2 :         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           2 :         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           2 :         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           2 :         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           2 :         struct PlaintextSecret *decrypted =
     386           2 :                 talloc_zero(test_ctx, struct PlaintextSecret);
     387           2 :         int err = LDB_SUCCESS;
     388             : 
     389           2 :         gnutls_decrypt_aead(&err,
     390             :                             test_ctx,
     391             :                             test_ctx->ldb,
     392             :                             &es,
     393             :                             decrypted,
     394             :                             &data);
     395           2 :         assert_int_equal(LDB_SUCCESS, err);
     396           2 :         assert_int_equal(plain_text.length, decrypted->cleartext.length);
     397           2 :         assert_int_equal(0, data_blob_cmp(&decrypted->cleartext, &plain_text));
     398           2 : }
     399             : 
     400             : /*
     401             :  *  Test gnutls_encryption and decryption.
     402             :  */
     403           2 : static void test_gnutls_value_encryption(void **state)
     404             : {
     405           2 :         struct ldbtest_ctx *test_ctx =
     406           2 :                 talloc_get_type_abort(*state, struct ldbtest_ctx);
     407           2 :         struct ldb_val plain_text = data_blob_null;
     408           2 :         struct ldb_val cipher_text = data_blob_null;
     409           2 :         struct EncryptedSecret es;
     410             : 
     411           2 :         struct es_data *data = talloc_get_type(
     412             :                 ldb_module_get_private(test_ctx->module),
     413             :                 struct es_data);
     414           2 :         int err = LDB_SUCCESS;
     415           2 :         int rc;
     416             : 
     417           2 :         plain_text = data_blob_string_const("A text value");
     418           2 :         cipher_text = gnutls_encrypt_aead(
     419             :                         &err,
     420             :                         test_ctx,
     421             :                         test_ctx->ldb,
     422             :                         plain_text,
     423             :                         data);
     424           2 :         assert_int_equal(LDB_SUCCESS, err);
     425             : 
     426           2 :         rc = ndr_pull_struct_blob(
     427             :                 &cipher_text,
     428             :                 test_ctx,
     429             :                 &es,
     430             :                 (ndr_pull_flags_fn_t) ndr_pull_EncryptedSecret);
     431           2 :         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
     432           4 :         assert_true(check_header(&es));
     433             : 
     434             :         {
     435           2 :                 struct PlaintextSecret *decrypted =
     436           2 :                         talloc_zero(test_ctx, struct PlaintextSecret);
     437           2 :                 gnutls_decrypt_aead(
     438             :                         &err,
     439             :                         test_ctx,
     440             :                         test_ctx->ldb,
     441             :                         &es,
     442             :                         decrypted,
     443             :                         data);
     444           2 :                 assert_int_equal(LDB_SUCCESS, err);
     445           2 :                 assert_int_equal(
     446             :                         plain_text.length,
     447             :                         decrypted->cleartext.length);
     448           2 :                 assert_int_equal(0,
     449             :                         data_blob_cmp(
     450             :                                 &decrypted->cleartext,
     451             :                                 &plain_text));
     452             :         }
     453           2 : }
     454             : 
     455           2 : static void test_gnutls_altered_header(void **state)
     456             : {
     457           2 :         struct ldbtest_ctx *test_ctx =
     458           2 :                 talloc_get_type_abort(*state, struct ldbtest_ctx);
     459           2 :         struct ldb_val plain_text = data_blob_null;
     460           2 :         struct ldb_val cipher_text = data_blob_null;
     461           2 :         struct EncryptedSecret es;
     462             : 
     463           2 :         struct es_data *data = talloc_get_type(
     464             :                 ldb_module_get_private(test_ctx->module),
     465             :                 struct es_data);
     466           2 :         int err = LDB_SUCCESS;
     467           2 :         int rc;
     468             : 
     469           2 :         plain_text = data_blob_string_const("A text value");
     470           2 :         cipher_text = gnutls_encrypt_aead(
     471             :                         &err,
     472             :                         test_ctx,
     473             :                         test_ctx->ldb,
     474             :                         plain_text,
     475             :                         data);
     476           2 :         assert_int_equal(LDB_SUCCESS, err);
     477             : 
     478           2 :         rc = ndr_pull_struct_blob(
     479             :                 &cipher_text,
     480             :                 test_ctx,
     481             :                 &es,
     482             :                 (ndr_pull_flags_fn_t) ndr_pull_EncryptedSecret);
     483           2 :         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
     484           4 :         assert_true(check_header(&es));
     485             : 
     486             :         {
     487           2 :                 struct PlaintextSecret *decrypted =
     488           2 :                         talloc_zero(test_ctx, struct PlaintextSecret);
     489           2 :                 gnutls_decrypt_aead(
     490             :                         &err,
     491             :                         test_ctx,
     492             :                         test_ctx->ldb,
     493             :                         &es,
     494             :                         decrypted,
     495             :                         data);
     496           2 :                 assert_int_equal(LDB_SUCCESS, err);
     497           2 :                 assert_int_equal(
     498             :                         plain_text.length,
     499             :                         decrypted->cleartext.length);
     500           2 :                 assert_int_equal(0,
     501             :                         data_blob_cmp(
     502             :                                 &decrypted->cleartext,
     503             :                                 &plain_text));
     504             :         }
     505           2 :         es.header.flags = es.header.flags ^ 0xffffffff;
     506             :         {
     507           2 :                 struct PlaintextSecret *decrypted =
     508           2 :                         talloc_zero(test_ctx, struct PlaintextSecret);
     509           2 :                 gnutls_decrypt_aead(
     510             :                         &err,
     511             :                         test_ctx,
     512             :                         test_ctx->ldb,
     513             :                         &es,
     514             :                         decrypted,
     515             :                         data);
     516           2 :                 assert_int_equal(LDB_ERR_OPERATIONS_ERROR, err);
     517             :         }
     518           2 : }
     519             : 
     520           2 : static void test_gnutls_altered_data(void **state)
     521             : {
     522           2 :         struct ldbtest_ctx *test_ctx =
     523           2 :                 talloc_get_type_abort(*state, struct ldbtest_ctx);
     524           2 :         struct ldb_val plain_text = data_blob_null;
     525           2 :         struct ldb_val cipher_text = data_blob_null;
     526           2 :         struct EncryptedSecret es;
     527             : 
     528           2 :         struct es_data *data = talloc_get_type(
     529             :                 ldb_module_get_private(test_ctx->module),
     530             :                 struct es_data);
     531           2 :         int err = LDB_SUCCESS;
     532           2 :         int rc;
     533             : 
     534           2 :         plain_text = data_blob_string_const("A text value");
     535           2 :         cipher_text = gnutls_encrypt_aead(
     536             :                         &err,
     537             :                         test_ctx,
     538             :                         test_ctx->ldb,
     539             :                         plain_text,
     540             :                         data);
     541           2 :         assert_int_equal(LDB_SUCCESS, err);
     542             : 
     543           2 :         rc = ndr_pull_struct_blob(
     544             :                 &cipher_text,
     545             :                 test_ctx,
     546             :                 &es,
     547             :                 (ndr_pull_flags_fn_t) ndr_pull_EncryptedSecret);
     548           2 :         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
     549           4 :         assert_true(check_header(&es));
     550             : 
     551             :         {
     552           2 :                 struct PlaintextSecret *decrypted =
     553           2 :                         talloc_zero(test_ctx, struct PlaintextSecret);
     554           2 :                 gnutls_decrypt_aead(
     555             :                         &err,
     556             :                         test_ctx,
     557             :                         test_ctx->ldb,
     558             :                         &es,
     559             :                         decrypted,
     560             :                         data);
     561           2 :                 assert_int_equal(LDB_SUCCESS, err);
     562           2 :                 assert_int_equal(
     563             :                         plain_text.length,
     564             :                         decrypted->cleartext.length);
     565           2 :                 assert_int_equal(0,
     566             :                         data_blob_cmp(
     567             :                                 &decrypted->cleartext,
     568             :                                 &plain_text));
     569             :         }
     570           2 :         es.encrypted.data[0] = es.encrypted.data[0] ^ 0xff;
     571             :         {
     572           2 :                 struct PlaintextSecret *decrypted =
     573           2 :                         talloc_zero(test_ctx, struct PlaintextSecret);
     574           2 :                 gnutls_decrypt_aead(
     575             :                         &err,
     576             :                         test_ctx,
     577             :                         test_ctx->ldb,
     578             :                         &es,
     579             :                         decrypted,
     580             :                         data);
     581           2 :                 assert_int_equal(LDB_ERR_OPERATIONS_ERROR, err);
     582             :         }
     583           2 : }
     584             : 
     585           2 : static void test_gnutls_altered_iv(void **state)
     586             : {
     587           2 :         struct ldbtest_ctx *test_ctx =
     588           2 :                 talloc_get_type_abort(*state, struct ldbtest_ctx);
     589           2 :         struct ldb_val plain_text = data_blob_null;
     590           2 :         struct ldb_val cipher_text = data_blob_null;
     591           2 :         struct EncryptedSecret es;
     592             : 
     593           2 :         struct es_data *data = talloc_get_type(
     594             :                 ldb_module_get_private(test_ctx->module),
     595             :                 struct es_data);
     596           2 :         int err = LDB_SUCCESS;
     597           2 :         int rc;
     598             : 
     599           2 :         plain_text = data_blob_string_const("A text value");
     600           2 :         cipher_text = gnutls_encrypt_aead(
     601             :                         &err,
     602             :                         test_ctx,
     603             :                         test_ctx->ldb,
     604             :                         plain_text,
     605             :                         data);
     606           2 :         assert_int_equal(LDB_SUCCESS, err);
     607             : 
     608           2 :         rc = ndr_pull_struct_blob(
     609             :                 &cipher_text,
     610             :                 test_ctx,
     611             :                 &es,
     612             :                 (ndr_pull_flags_fn_t) ndr_pull_EncryptedSecret);
     613           2 :         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
     614           4 :         assert_true(check_header(&es));
     615             : 
     616             :         {
     617           2 :                 struct PlaintextSecret *decrypted =
     618           2 :                         talloc_zero(test_ctx, struct PlaintextSecret);
     619           2 :                 gnutls_decrypt_aead(
     620             :                         &err,
     621             :                         test_ctx,
     622             :                         test_ctx->ldb,
     623             :                         &es,
     624             :                         decrypted,
     625             :                         data);
     626           2 :                 assert_int_equal(LDB_SUCCESS, err);
     627           2 :                 assert_int_equal(
     628             :                         plain_text.length,
     629             :                         decrypted->cleartext.length);
     630           2 :                 assert_int_equal(0,
     631             :                         data_blob_cmp(
     632             :                                 &decrypted->cleartext,
     633             :                                 &plain_text));
     634             :         }
     635           2 :         es.iv.data[0] = es.iv.data[0] ^ 0xff;
     636             :         {
     637           2 :                 struct PlaintextSecret *decrypted =
     638           2 :                         talloc_zero(test_ctx, struct PlaintextSecret);
     639           2 :                 gnutls_decrypt_aead(
     640             :                         &err,
     641             :                         test_ctx,
     642             :                         test_ctx->ldb,
     643             :                         &es,
     644             :                         decrypted,
     645             :                         data);
     646           2 :                 assert_int_equal(LDB_ERR_OPERATIONS_ERROR, err);
     647             :         }
     648           2 : }
     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           2 : static void test_message_encryption_decryption(void **state)
     661             : {
     662           2 :         struct ldbtest_ctx *test_ctx =
     663           2 :                 talloc_get_type_abort(*state, struct ldbtest_ctx);
     664           2 :         struct ldb_context *ldb = test_ctx->ldb;
     665           2 :         const char * const secrets[] = {DSDB_SECRET_ATTRIBUTES};
     666           2 :         const size_t num_secrets
     667             :                 = (sizeof(secrets)/sizeof(secrets[0]));
     668           2 :         struct ldb_message *msg = ldb_msg_new(ldb);
     669           2 :         const struct ldb_message *encrypted_msg = NULL;
     670           2 :         struct es_data *data = talloc_get_type(
     671             :                 ldb_module_get_private(test_ctx->module),
     672             :                 struct es_data);
     673           2 :         struct ldb_message_element *el = NULL;
     674           2 :         int ret = LDB_SUCCESS;
     675           2 :         size_t i;
     676           2 :         unsigned int j;
     677             : 
     678           2 :         msg->dn = ldb_dn_new(msg, ldb, "dc=test");
     679           2 :         ldb_msg_add_string(msg, "cmocka_test_name01", "value01");
     680          32 :         for (i=0; i < num_secrets; i++) {
     681          28 :                 ldb_msg_add_string(
     682             :                         msg,
     683             :                         secrets[i],
     684          28 :                         secrets[i]);
     685             :         }
     686           2 :         ldb_msg_add_string(msg, "cmocka_test_name02", "value02");
     687             : 
     688           2 :         encrypted_msg = encrypt_secret_attributes(
     689             :                 &ret,
     690             :                 test_ctx,
     691             :                 test_ctx->ldb,
     692             :                 msg,
     693             :                 data);
     694           2 :         assert_int_equal(LDB_SUCCESS, ret);
     695             : 
     696             :         /*
     697             :          * Check that all the secret attributes have been encrypted
     698             :          *
     699             :          */
     700          32 :         for (i=0; i < num_secrets; i++) {
     701          28 :                 el = ldb_msg_find_element(encrypted_msg, secrets[i]);
     702          28 :                 assert_non_null(el);
     703          84 :                 for (j = 0; j < el->num_values; j++) {
     704          28 :                         int rc = LDB_SUCCESS;
     705          56 :                         struct ldb_val dc = decrypt_value(
     706             :                                 &rc,
     707             :                                 test_ctx,
     708             :                                 test_ctx->ldb,
     709          28 :                                 el->values[j],
     710             :                                 data);
     711          28 :                         assert_int_equal(LDB_SUCCESS, rc);
     712          28 :                         assert_memory_equal(
     713             :                                 secrets[i],
     714             :                                 dc.data,
     715             :                                 dc.length);
     716          28 :                         TALLOC_FREE(dc.data);
     717             :                 }
     718             :         }
     719             : 
     720             :         /*
     721             :          * Check that the normal attributes have not been encrypted
     722             :          */
     723           2 :         el = ldb_msg_find_element(encrypted_msg, "cmocka_test_name01");
     724           2 :         assert_non_null(el);
     725           2 :         assert_memory_equal(
     726             :                 "value01",
     727             :                 el->values[0].data,
     728             :                 el->values[0].length);
     729             : 
     730           2 :         el = ldb_msg_find_element(encrypted_msg, "cmocka_test_name02");
     731           2 :         assert_non_null(el);
     732           2 :         assert_memory_equal(
     733             :                 "value02",
     734             :                 el->values[0].data,
     735             :                 el->values[0].length);
     736             : 
     737             :         /*
     738             :          * Now decrypt the message
     739             :          */
     740           2 :         ret = decrypt_secret_attributes(test_ctx->ldb,
     741             :                                         discard_const(encrypted_msg),
     742             :                                         data);
     743           2 :         assert_int_equal(LDB_SUCCESS, ret);
     744             : 
     745             :         /*
     746             :          * Check that all the secret attributes have been decrypted
     747             :          */
     748          32 :         for (i=0; i < num_secrets; i++) {
     749          28 :                 el = ldb_msg_find_element(encrypted_msg, secrets[i]);
     750          28 :                 assert_non_null(el);
     751          84 :                 for (j = 0; j < el->num_values; j++) {
     752          28 :                         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           2 :         el = ldb_msg_find_element(msg, "cmocka_test_name01");
     763           2 :         assert_non_null(el);
     764           2 :         assert_memory_equal(
     765             :                 "value01",
     766             :                 el->values[0].data,
     767             :                 el->values[0].length);
     768             : 
     769           2 :         el = ldb_msg_find_element(msg, "cmocka_test_name02");
     770           2 :         assert_non_null(el);
     771           2 :         assert_memory_equal(
     772             :                 "value02",
     773             :                 el->values[0].data,
     774             :                 el->values[0].length);
     775             : 
     776           2 : }
     777             : 
     778           2 : static void test_check_header(void **state)
     779             : {
     780           2 :         struct ldbtest_ctx *test_ctx =
     781           2 :                 talloc_get_type_abort(*state, struct ldbtest_ctx);
     782             : 
     783           2 :         struct ldb_val enc = data_blob_null;
     784           2 :         struct EncryptedSecret *es = NULL;
     785           2 :         int rc;
     786             : 
     787             :         /*
     788             :          * Valid EncryptedSecret
     789             :          */
     790           2 :         es = makeEncryptedSecret(test_ctx->ldb, test_ctx);
     791           2 :         rc = ndr_push_struct_blob(
     792             :                 &enc,
     793             :                 test_ctx,
     794             :                 es,
     795             :                 (ndr_push_flags_fn_t) ndr_push_EncryptedSecret);
     796           2 :         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
     797           4 :         assert_true(check_header(es));
     798           2 :         TALLOC_FREE(enc.data);
     799           2 :         TALLOC_FREE(es);
     800             : 
     801             :         /*
     802             :          * invalid magic value
     803             :          */
     804           2 :         es = makeEncryptedSecret(test_ctx->ldb, test_ctx);
     805           2 :         es->header.magic = 0xca5cadee;
     806           2 :         rc = ndr_push_struct_blob(
     807             :                 &enc,
     808             :                 test_ctx,
     809             :                 es,
     810             :                 (ndr_push_flags_fn_t) ndr_push_EncryptedSecret);
     811           2 :         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
     812           2 :         assert_false(check_header(es));
     813           2 :         TALLOC_FREE(enc.data);
     814           2 :         TALLOC_FREE(es);
     815             : 
     816             :         /*
     817             :          * invalid version
     818             :          */
     819           2 :         es = makeEncryptedSecret(test_ctx->ldb, test_ctx);
     820           2 :         es->header.version = SECRET_ATTRIBUTE_VERSION + 1;
     821           2 :         rc = ndr_push_struct_blob(
     822             :                 &enc,
     823             :                 test_ctx,
     824             :                 es,
     825             :                 (ndr_push_flags_fn_t) ndr_push_EncryptedSecret);
     826           2 :         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
     827           4 :         assert_false(check_header(es));
     828           2 :         TALLOC_FREE(enc.data);
     829           2 :         TALLOC_FREE(es);
     830             : 
     831             :         /*
     832             :          * invalid algorithm
     833             :          */
     834           2 :         es = makeEncryptedSecret(test_ctx->ldb, test_ctx);
     835           2 :         es->header.algorithm = SECRET_ENCRYPTION_ALGORITHM + 1;
     836           2 :         rc = ndr_push_struct_blob(
     837             :                 &enc,
     838             :                 test_ctx,
     839             :                 es,
     840             :                 (ndr_push_flags_fn_t) ndr_push_EncryptedSecret);
     841           2 :         assert_true(NDR_ERR_CODE_IS_SUCCESS(rc));
     842           4 :         assert_false(check_header(es));
     843           2 :         TALLOC_FREE(enc.data);
     844           2 :         TALLOC_FREE(es);
     845           2 : }
     846             : 
     847             : /*
     848             :  * Attempt to decrypt a message containing an unencrypted secret attribute
     849             :  * this should fail
     850             :  */
     851           2 : static void test_unencrypted_secret(void **state)
     852             : {
     853           2 :         struct ldbtest_ctx *test_ctx =
     854           2 :                 talloc_get_type_abort(*state, struct ldbtest_ctx);
     855           2 :         struct ldb_context *ldb = test_ctx->ldb;
     856           2 :         struct ldb_message *msg = ldb_msg_new(ldb);
     857           2 :         struct es_data *data = talloc_get_type(
     858             :                 ldb_module_get_private(test_ctx->module),
     859             :                 struct es_data);
     860           2 :         int ret = LDB_SUCCESS;
     861             : 
     862           2 :         msg->dn = ldb_dn_new(msg, ldb, "dc=test");
     863           2 :         ldb_msg_add_string(msg, "unicodePwd", "value01");
     864             : 
     865           2 :         ret = decrypt_secret_attributes(test_ctx->ldb, msg, data);
     866           2 :         assert_int_equal(LDB_ERR_OPERATIONS_ERROR, ret);
     867           2 : }
     868             : 
     869             : /*
     870             :  *  Test full decryption of a static value with static key
     871             :  */
     872           2 : static void test_record_decryption(void **state)
     873             : {
     874           2 :         struct ldbtest_ctx *test_ctx =
     875           2 :                 talloc_get_type_abort(*state, struct ldbtest_ctx);
     876           2 :         unsigned char plain_data[] = {
     877             :                 0xe6, 0xa6, 0xb8, 0xff, 0xdf, 0x06, 0x6c, 0xe3,
     878             :                 0xea, 0xd0, 0x94, 0xbb, 0x79, 0xbd, 0x0a, 0x24
     879             :         };
     880           2 :         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           2 :         struct ldb_val cipher_text
     892           2 :                 = data_blob_const(encrypted_data,
     893             :                                   sizeof(encrypted_data));
     894           2 :         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           2 :         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           2 :         int err = LDB_SUCCESS;
     907           2 :         struct ldb_val dec = decrypt_value(&err, test_ctx, test_ctx->ldb, cipher_text,
     908             :                                            &data);
     909           2 :         assert_int_equal(LDB_SUCCESS, err);
     910           2 :         assert_int_equal(sizeof(plain_data), dec.length);
     911           2 :         assert_memory_equal(dec.data, plain_data, sizeof(plain_data));
     912           2 : }
     913             : 
     914             : 
     915           2 : int main(void) {
     916           2 :         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           2 :         cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
     972           2 :         return cmocka_run_group_tests(tests, NULL, NULL);
     973             : }

Generated by: LCOV version 1.14