YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/ent/src/yb/master/universe_key_registry_service.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) YugaByte, Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4
// in compliance with the License.  You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software distributed under the License
9
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10
// or implied.  See the License for the specific language governing permissions and limitations
11
// under the License.
12
//
13
14
#include "yb/master/universe_key_registry_service.h"
15
16
#include "yb/encryption/encryption_util.h"
17
#include "yb/encryption/encryption.pb.h"
18
19
#include "yb/master/catalog_entity_info.pb.h"
20
21
#include "yb/util/pb_util.h"
22
#include "yb/util/random_util.h"
23
24
#include "yb/gutil/endian.h"
25
26
namespace yb {
27
namespace master {
28
namespace enterprise {
29
30
18
Result<std::string> DecryptUniverseKeyRegistry(const Slice& s, const Slice& universe_key) {
31
18
  string output;
32
18
  output.resize(s.size());
33
18
  auto encryption_params = VERIFY_RESULT(encryption::EncryptionParams::FromSlice(universe_key));
34
18
  auto stream = VERIFY_RESULT(
35
18
      encryption::BlockAccessCipherStream::FromEncryptionParams(std::move(encryption_params)));
36
18
  RETURN_NOT_OK(stream->Decrypt(0, s, &output[0]));
37
18
  return output;
38
18
}
39
40
6
Result<std::string> EncryptUniverseKeyRegistry(const Slice& s, const Slice& universe_key) {
41
6
  return DecryptUniverseKeyRegistry(s, universe_key);
42
6
}
43
44
CHECKED_STATUS RotateUniverseKey(const Slice& old_universe_key,
45
                                 const Slice& new_universe_key,
46
                                 const encryption::UniverseKeyId& new_key_version_id,
47
                                 bool enable,
48
6
                                 EncryptionInfoPB* encryption_info) {
49
6
  bool prev_enabled = encryption_info->encryption_enabled();
50
51
6
  LOG(INFO) << Format("RotateUniverseKey: prev_enabled: $0, enable: $1, new_key_version_id: $2",
52
6
                      prev_enabled, enable, new_key_version_id);
53
54
6
  if (!prev_enabled && !enable) {
55
0
    return STATUS(InvalidArgument, "Cannot disable encryption for an already plaintext cluster.");
56
0
  }
57
58
6
  Slice registry_decrypted(encryption_info->universe_key_registry_encoded());
59
6
  string decrypted_registry;
60
6
  if (prev_enabled) {
61
    // The registry is encrypted, decrypt it and set registry_encoded_decrypted to the newly
62
    // decrypted registry.
63
3
    LOG_IF(DFATAL, old_universe_key.empty());
64
3
    decrypted_registry = VERIFY_RESULT(DecryptUniverseKeyRegistry(
65
3
        registry_decrypted, old_universe_key));
66
3
    registry_decrypted = Slice(decrypted_registry);
67
3
  }
68
69
  // Decode the registry.
70
6
  auto universe_key_registry =
71
6
      VERIFY_RESULT(pb_util::ParseFromSlice<encryption::UniverseKeyRegistryPB>(registry_decrypted));
72
6
  universe_key_registry.set_encryption_enabled(enable);
73
6
  faststring encoded;
74
6
  Slice registry_for_flush;
75
6
  string encrypted;
76
6
  if (!enable) {
77
0
    pb_util::SerializeToString(universe_key_registry, &encoded);
78
0
    registry_for_flush = Slice(encoded);
79
6
  } else {
80
6
    LOG_IF(DFATAL, new_universe_key.empty());
81
6
    auto params = VERIFY_RESULT(encryption::EncryptionParams::FromSlice(new_universe_key));
82
6
    encryption::EncryptionParamsPB params_pb;
83
6
    params->ToEncryptionParamsPB(&params_pb);
84
6
    (*universe_key_registry.mutable_universe_keys())[new_key_version_id] = params_pb;
85
6
    universe_key_registry.set_latest_version_id(new_key_version_id);
86
6
    pb_util::SerializeToString(universe_key_registry, &encoded);
87
88
6
    encrypted = VERIFY_RESULT(EncryptUniverseKeyRegistry(Slice(encoded), new_universe_key));
89
6
    registry_for_flush = Slice(encrypted);
90
6
  }
91
92
6
  encryption_info->set_encryption_enabled(enable);
93
6
  encryption_info->set_universe_key_registry_encoded(
94
6
      registry_for_flush.data(), registry_for_flush.size());
95
6
  encryption_info->set_latest_version_id(new_key_version_id);
96
97
6
  return Status::OK();
98
6
}
99
100
} // namespace enterprise
101
} // namespace master
102
} // namespace yb