Skip to content

Commit 3504851

Browse files
committed
MB-65568: Compaction removes 'Unencrypted' key
When running "compaction" and encryption is turned off it'll remove the "unencrypted" key from the internal cache. If one enable encryption at a later time we start reporting the current active key, but given we've removed the unencrypted key we would only return the active key to ns_server and it would think that all data is encrypted with that key Change-Id: Ie70ee7b58658177f2bbe0cbc5b9eaa1eece70be2 Reviewed-on: https://review.couchbase.org/c/kv_engine/+/224537 Tested-by: Build Bot <build@couchbase.com> Reviewed-by: Dan Owen <owend@couchbase.com>
1 parent af726f9 commit 3504851

File tree

5 files changed

+55
-12
lines changed

5 files changed

+55
-12
lines changed

engines/ep/src/kvstore/couch-kvstore/couch-kvstore.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1556,7 +1556,10 @@ CompactDBStatus CouchKVStore::compactDBInternal(
15561556
if (ret) {
15571557
vbucketEncryptionKeysManager.setNextKey(vbid, ret->id);
15581558
} else {
1559-
vbucketEncryptionKeysManager.removeNextKey(vbid);
1559+
vbucketEncryptionKeysManager.setNextKey(
1560+
vbid,
1561+
cb::crypto::DataEncryptionKey::
1562+
UnencryptedKeyId);
15601563
}
15611564
return ret;
15621565
},

engines/ewouldblock_engine/ewouldblock_engine.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@ class EWB_Engine : public EngineIface,
249249
cb::engine_errc wait_for_seqno_persistence(CookieIface& cookie,
250250
uint64_t seqno,
251251
Vbid vbid) override;
252+
cb::engine_errc set_active_encryption_keys(
253+
const nlohmann::json& json) override;
252254
cb::engine_errc prepare_snapshot(
253255
CookieIface& cookie,
254256
Vbid vbid,
@@ -1414,6 +1416,12 @@ cb::engine_errc EWB_Engine::wait_for_seqno_persistence(CookieIface& cookie,
14141416
Vbid vbid) {
14151417
return real_engine->wait_for_seqno_persistence(cookie, seqno, vbid);
14161418
}
1419+
1420+
cb::engine_errc EWB_Engine::set_active_encryption_keys(
1421+
const nlohmann::json& json) {
1422+
return real_engine->set_active_encryption_keys(json);
1423+
}
1424+
14171425
cb::engine_errc EWB_Engine::prepare_snapshot(
14181426
CookieIface& cookie,
14191427
Vbid vbid,

tests/testapp/testapp_encryption.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,41 @@ TEST_P(EncryptionTest, TestPruneDeks) {
210210
ASSERT_EQ(stats["@logs"].front().get<std::string>(),
211211
dekManager.lookup(cb::dek::Entity::Logs)->getId());
212212
}
213+
214+
TEST_P(EncryptionTest, TestDisableEncryption) {
215+
// Verify that the bucket is encrypted
216+
auto connection = adminConnection->clone();
217+
connection->authenticate("@admin");
218+
connection->selectBucket(bucketName);
219+
220+
nlohmann::json stats;
221+
connection->stats(
222+
[&stats](auto& k, auto& v) { stats = nlohmann::json::parse(v); },
223+
"encryption-key-ids");
224+
225+
ASSERT_EQ(1, stats.size()) << stats.dump();
226+
ASSERT_NE("unencrypted", stats.front().get<std::string>());
227+
228+
// Disable encryption
229+
mcd_env->getTestBucket().keystore.setActiveKey({});
230+
std::string config =
231+
nlohmann::json(mcd_env->getTestBucket().keystore).dump();
232+
233+
auto rsp = connection->execute(BinprotGenericCommand{
234+
cb::mcbp::ClientOpcode::SetActiveEncryptionKeys,
235+
bucketName,
236+
config});
237+
ASSERT_EQ(cb::mcbp::Status::Success, rsp.getStatus());
238+
239+
// Compact the vbucket
240+
rsp = connection->execute(BinprotCompactDbCommand{});
241+
ASSERT_EQ(cb::mcbp::Status::Success, rsp.getStatus());
242+
243+
// fetch the stats and it should be "unencrypted"
244+
connection->stats(
245+
[&stats](auto& k, auto& v) { stats = nlohmann::json::parse(v); },
246+
"encryption-key-ids");
247+
248+
ASSERT_EQ(1, stats.size()) << stats.dump();
249+
ASSERT_EQ("unencrypted", stats.front().get<std::string>());
250+
}

tests/testapp/testapp_environment.cc

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ void TestBucketImpl::setParam(
122122
TestBucketImpl::TestBucketImpl(const std::filesystem::path& test_directory,
123123
std::string extraConfig)
124124
: dbPath(test_directory / "dbase"), extraConfig(std::move(extraConfig)) {
125-
encryption_keys.emplace_back(cb::crypto::DataEncryptionKey::generate());
125+
keystore.setActiveKey(cb::crypto::DataEncryptionKey::generate());
126126
}
127127

128128
void TestBucketImpl::createBucket(const std::string& name,
@@ -211,13 +211,7 @@ bool TestBucketImpl::isFullEviction() const {
211211
}
212212

213213
std::string TestBucketImpl::getEncryptionConfig() const {
214-
nlohmann::json encryption = {{"active", encryption_keys.front()->id}};
215-
auto keys = nlohmann::json::array();
216-
for (const auto& key : encryption_keys) {
217-
keys.push_back(*key);
218-
}
219-
encryption["keys"] = std::move(keys);
220-
return encryption.dump();
214+
return nlohmann::json(keystore).dump();
221215
}
222216

223217
McdEnvironment::McdEnvironment(std::string engineConfig)

tests/testapp/testapp_environment.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ class TestBucketImpl {
144144
return extraConfig;
145145
}
146146

147+
/// The keystore used to keep track of the encrypt keys for the bucket
148+
cb::crypto::KeyStore keystore;
149+
147150
protected:
148151
static void createEwbBucket(const std::string& name,
149152
BucketType type,
@@ -159,9 +162,6 @@ class TestBucketImpl {
159162

160163
std::string extraConfig;
161164

162-
/// The key to use for encryption@rest
163-
std::vector<std::shared_ptr<cb::crypto::DataEncryptionKey>> encryption_keys;
164-
165165
BucketCreateMode bucketCreateMode = BucketCreateMode::Clean;
166166
};
167167

0 commit comments

Comments
 (0)