1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "rdb_security_manager.h"
17
18 #include <securec.h>
19
20 #include <string>
21 #include <utility>
22
23 #include "directory_ex.h"
24 #include "file_ex.h"
25 #include "hks_param.h"
26 #include "hks_mem.h"
27 #include "logger.h"
28 #include "sqlite_database_utils.h"
29
30 namespace OHOS {
31 namespace NativeRdb {
32 RdbPassword::RdbPassword() = default;
33
~RdbPassword()34 RdbPassword::~RdbPassword()
35 {
36 (void)Clear();
37 }
38
operator ==(const RdbPassword & input) const39 bool RdbPassword::operator==(const RdbPassword &input) const
40 {
41 if (size_ != input.GetSize()) {
42 return false;
43 }
44 return memcmp(data_, input.GetData(), size_) == 0;
45 }
46
operator !=(const RdbPassword & input) const47 bool RdbPassword::operator!=(const RdbPassword &input) const
48 {
49 return !(*this == input);
50 }
51
GetSize() const52 size_t RdbPassword::GetSize() const
53 {
54 return size_;
55 }
56
GetData() const57 const uint8_t *RdbPassword::GetData() const
58 {
59 return data_;
60 }
61
SetValue(const uint8_t * inputData,size_t inputSize)62 int RdbPassword::SetValue(const uint8_t *inputData, size_t inputSize)
63 {
64 if (inputSize > MAX_PASSWORD_SIZE) {
65 return E_ERROR;
66 }
67 if (inputSize != 0 && inputData == nullptr) {
68 return E_ERROR;
69 }
70
71 if (inputSize != 0) {
72 std::copy(inputData, inputData + inputSize, data_);
73 }
74
75 size_t filledSize = std::min(size_, MAX_PASSWORD_SIZE);
76 if (inputSize < filledSize) {
77 std::fill(data_ + inputSize, data_ + filledSize, UCHAR_MAX);
78 }
79
80 size_ = inputSize;
81 return E_OK;
82 }
83
Clear()84 int RdbPassword::Clear()
85 {
86 return SetValue(nullptr, 0);
87 }
88
MallocAndCheckBlobData(struct HksBlob * blob,const uint32_t blobSize)89 int32_t RdbSecurityManager::MallocAndCheckBlobData(struct HksBlob *blob, const uint32_t blobSize)
90 {
91 blob->data = (uint8_t *)malloc(blobSize);
92 if (blob->data == NULL) {
93 LOG_ERROR("Blob data is NULL.");
94 return HKS_FAILURE;
95 }
96 return HKS_SUCCESS;
97 }
98
HksLoopUpdate(const struct HksBlob * handle,const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData)99 int32_t RdbSecurityManager::HksLoopUpdate(const struct HksBlob *handle, const struct HksParamSet *paramSet,
100 const struct HksBlob *inData, struct HksBlob *outData)
101 {
102 struct HksBlob inDataSeg = *inData;
103 uint8_t *lastPtr = inData->data + inData->size - 1;
104 struct HksBlob outDataSeg = { MAX_OUTDATA_SIZE, NULL };
105 uint8_t *cur = outData->data;
106 outData->size = 0;
107
108 inDataSeg.size = MAX_UPDATE_SIZE;
109
110 bool isFinished = false;
111
112 while (inDataSeg.data <= lastPtr) {
113 if (inDataSeg.data + MAX_UPDATE_SIZE <= lastPtr) {
114 outDataSeg.size = MAX_OUTDATA_SIZE;
115 } else {
116 isFinished = true;
117 inDataSeg.size = lastPtr - inDataSeg.data + 1;
118 break;
119 }
120 if (MallocAndCheckBlobData(&outDataSeg, outDataSeg.size) != HKS_SUCCESS) {
121 LOG_ERROR("MallocAndCheckBlobData outDataSeg Failed.");
122 return HKS_FAILURE;
123 }
124 if (HksUpdate(handle, paramSet, &inDataSeg, &outDataSeg) != HKS_SUCCESS) {
125 LOG_ERROR("HksUpdate Failed.");
126 HksFree(outDataSeg.data);
127 return HKS_FAILURE;
128 }
129 if (memcpy_s(cur, outDataSeg.size, outDataSeg.data, outDataSeg.size) != 0) {
130 LOG_ERROR("Method memcpy_s failed");
131 HksFree(outDataSeg.data);
132 return HKS_FAILURE;
133 }
134 cur += outDataSeg.size;
135 outData->size += outDataSeg.size;
136 HksFree(outDataSeg.data);
137 if ((!isFinished) && (inDataSeg.data + MAX_UPDATE_SIZE > lastPtr)) {
138 LOG_ERROR("isFinished and inDataSeg data Error");
139 return HKS_FAILURE;
140 }
141 inDataSeg.data += MAX_UPDATE_SIZE;
142 }
143
144 struct HksBlob outDataFinish = { inDataSeg.size * TIMES, NULL };
145 if (MallocAndCheckBlobData(&outDataFinish, outDataFinish.size) != HKS_SUCCESS) {
146 LOG_ERROR("MallocAndCheckBlobData outDataFinish Failed.");
147 return HKS_FAILURE;
148 }
149 if (HksFinish(handle, paramSet, &inDataSeg, &outDataFinish) != HKS_SUCCESS) {
150 LOG_ERROR("HksFinish Failed.");
151 HksFree(outDataFinish.data);
152 return HKS_FAILURE;
153 }
154 if (memcpy_s(cur, outDataFinish.size, outDataFinish.data, outDataFinish.size) != 0) {
155 LOG_ERROR("Method memcpy_s failed");
156 HksFree(outDataFinish.data);
157 return HKS_FAILURE;
158 }
159 outData->size += outDataFinish.size;
160 HksFree(outDataFinish.data);
161
162 return HKS_SUCCESS;
163 }
164
HksEncryptThreeStage(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * plainText,struct HksBlob * cipherText)165 int32_t RdbSecurityManager::HksEncryptThreeStage(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
166 const struct HksBlob *plainText, struct HksBlob *cipherText)
167 {
168 uint8_t handle[sizeof(uint64_t)] = { 0 };
169 struct HksBlob handleBlob = { sizeof(uint64_t), handle };
170 int32_t result = HksInit(keyAlias, paramSet, &handleBlob, nullptr);
171 if (result != HKS_SUCCESS) {
172 LOG_ERROR("HksEncrypt failed with error %{public}d", result);
173 return result;
174 }
175 return HksLoopUpdate(&handleBlob, paramSet, plainText, cipherText);
176 }
177
HksDecryptThreeStage(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * cipherText,struct HksBlob * plainText)178 int32_t RdbSecurityManager::HksDecryptThreeStage(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
179 const struct HksBlob *cipherText, struct HksBlob *plainText)
180 {
181 uint8_t handle[sizeof(uint64_t)] = { 0 };
182 struct HksBlob handleBlob = { sizeof(uint64_t), handle };
183 int32_t result = HksInit(keyAlias, paramSet, &handleBlob, nullptr);
184 if (result != HKS_SUCCESS) {
185 LOG_ERROR("HksEncrypt failed with error %{public}d", result);
186 return result;
187 }
188 return HksLoopUpdate(&handleBlob, paramSet, cipherText, plainText);
189 }
190
191 RdbSecurityManager::RdbSecurityManager() = default;
192
193 RdbSecurityManager::~RdbSecurityManager() = default;
194
GenerateRandomNum(int32_t len)195 std::vector<uint8_t> RdbSecurityManager::GenerateRandomNum(int32_t len)
196 {
197 std::random_device randomDevice;
198 std::uniform_int_distribution<int> distribution(0, std::numeric_limits<uint8_t>::max());
199 std::vector<uint8_t> key(len);
200 for (int32_t i = 0; i < len; i++) {
201 key[i] = static_cast<uint8_t>(distribution(randomDevice));
202 }
203 return key;
204 }
205
SaveSecretKeyToFile(RdbSecurityManager::KeyFileType keyFile,const std::vector<uint8_t> & key)206 bool RdbSecurityManager::SaveSecretKeyToFile(RdbSecurityManager::KeyFileType keyFile, const std::vector<uint8_t> &key)
207 {
208 LOG_INFO("SaveSecretKeyToFile begin.");
209 if (!CheckRootKeyExists()) {
210 LOG_ERROR("Root key not exists!");
211 return false;
212 }
213 RdbSecretKeyData keyData;
214 keyData.timeValue = std::chrono::system_clock::to_time_t(std::chrono::system_clock::system_clock::now());
215 keyData.distributed = 0;
216 keyData.secretKey = EncryptWorkKey(key);
217
218 if (keyData.secretKey.size() == 0) {
219 return false;
220 }
221
222 if (!RdbSecurityManager::InitPath(dbKeyDir_)) {
223 return false;
224 }
225
226 std::string keyPath;
227 if (keyFile == KeyFileType::PUB_KEY_FILE) {
228 keyPath = keyPath_;
229 } else {
230 keyPath = keyBakPath_;
231 }
232
233 return SaveSecretKeyToDisk(keyPath, keyData);
234 }
235
SaveSecretKeyToDisk(const std::string & path,RdbSecretKeyData & keyData)236 bool RdbSecurityManager::SaveSecretKeyToDisk(const std::string &path, RdbSecretKeyData &keyData)
237 {
238 LOG_INFO("SaveSecretKeyToDisk begin.");
239 std::lock_guard<std::mutex> lock(mutex_);
240 std::vector<uint8_t> distributedInByte = TransferTypeToByteArray<uint8_t>(keyData.distributed);
241 std::vector<uint8_t> timeInByte = TransferTypeToByteArray<time_t>(keyData.timeValue);
242 std::vector<char> secretKeyInChar;
243 secretKeyInChar.insert(secretKeyInChar.end(), distributedInByte.begin(), distributedInByte.end());
244 secretKeyInChar.insert(secretKeyInChar.end(), timeInByte.begin(), timeInByte.end());
245 secretKeyInChar.insert(secretKeyInChar.end(), keyData.secretKey.begin(), keyData.secretKey.end());
246
247 bool ret = SaveBufferToFile(path, secretKeyInChar);
248 if (!ret) {
249 LOG_ERROR("SaveBufferToFile failed!");
250 return false;
251 }
252
253 return true;
254 }
255
GenerateRootKey()256 int RdbSecurityManager::GenerateRootKey()
257 {
258 LOG_INFO("RDB GenerateRootKey begin.");
259 struct HksBlob rootKeyName = { uint32_t(rootKeyAlias_.size()), rootKeyAlias_.data() };
260 struct HksParamSet *params = nullptr;
261 int32_t ret = HksInitParamSet(¶ms);
262 if (ret != HKS_SUCCESS) {
263 LOG_ERROR("HksInitParamSet()-client failed with error %{public}d", ret);
264 return ret;
265 }
266
267 struct HksParam hksParam[] = {
268 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
269 { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
270 { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
271 { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
272 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
273 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
274 };
275
276 ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
277 if (ret != HKS_SUCCESS) {
278 LOG_ERROR("HksAddParams-client failed with error %{public}d", ret);
279 HksFreeParamSet(¶ms);
280 return ret;
281 }
282
283 ret = HksBuildParamSet(¶ms);
284 if (ret != HKS_SUCCESS) {
285 LOG_ERROR("HksBuildParamSet-client failed with error %{public}d", ret);
286 HksFreeParamSet(¶ms);
287 return ret;
288 }
289
290 ret = HksGenerateKey(&rootKeyName, params, nullptr);
291 HksFreeParamSet(¶ms);
292 if (ret != HKS_SUCCESS) {
293 LOG_ERROR("HksGenerateKey-client failed with error %{public}d", ret);
294 }
295 LOG_INFO("RDB root key generated successful.");
296 return ret;
297 }
298
EncryptWorkKey(const std::vector<uint8_t> & key)299 std::vector<uint8_t> RdbSecurityManager::EncryptWorkKey(const std::vector<uint8_t> &key)
300 {
301 struct HksBlob blobAad = { uint32_t(aad_.size()), aad_.data() };
302 struct HksBlob blobNonce = { uint32_t(nonce_.size()), nonce_.data() };
303 struct HksBlob rootKeyName = { uint32_t(rootKeyAlias_.size()), rootKeyAlias_.data() };
304 struct HksBlob plainKey = { uint32_t(key.size()), const_cast<uint8_t *>(key.data()) };
305 struct HksParamSet *params = nullptr;
306 int32_t ret = HksInitParamSet(¶ms);
307 if (ret != HKS_SUCCESS) {
308 LOG_ERROR("HksInitParamSet() failed with error %{public}d", ret);
309 return {};
310 }
311 struct HksParam hksParam[] = {
312 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
313 { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT },
314 { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
315 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
316 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
317 { .tag = HKS_TAG_NONCE, .blob = blobNonce },
318 { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = blobAad },
319 };
320 ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
321 if (ret != HKS_SUCCESS) {
322 LOG_ERROR("HksAddParams failed with error %{public}d", ret);
323 HksFreeParamSet(¶ms);
324 return {};
325 }
326
327 ret = HksBuildParamSet(¶ms);
328 if (ret != HKS_SUCCESS) {
329 LOG_ERROR("HksBuildParamSet failed with error %{public}d", ret);
330 HksFreeParamSet(¶ms);
331 return {};
332 }
333
334 uint8_t cipherBuf[256] = { 0 };
335 struct HksBlob cipherText = { sizeof(cipherBuf), cipherBuf };
336 ret = HksEncryptThreeStage(&rootKeyName, params, &plainKey, &cipherText);
337 (void)HksFreeParamSet(¶ms);
338 if (ret != HKS_SUCCESS) {
339 LOG_ERROR("HksEncrypt failed with error %{public}d", ret);
340 return {};
341 }
342
343 std::vector<uint8_t> encryptedKey(cipherText.data, cipherText.data + cipherText.size);
344 (void)memset_s(cipherBuf, sizeof(cipherBuf), 0, sizeof(cipherBuf));
345
346 return encryptedKey;
347 }
348
DecryptWorkKey(std::vector<uint8_t> & source,std::vector<uint8_t> & key)349 bool RdbSecurityManager::DecryptWorkKey(std::vector<uint8_t> &source, std::vector<uint8_t> &key)
350 {
351 uint8_t aead_[AEAD_LEN] = { 0 };
352 struct HksBlob blobAad = { uint32_t(aad_.size()), &(aad_[0]) };
353 struct HksBlob blobNonce = { uint32_t(nonce_.size()), &(nonce_[0]) };
354 struct HksBlob rootKeyName = { uint32_t(rootKeyAlias_.size()), &(rootKeyAlias_[0]) };
355 struct HksBlob encryptedKeyBlob = { uint32_t(source.size()), source.data() };
356 struct HksBlob blobAead = { AEAD_LEN, aead_ };
357
358 struct HksParamSet *params = nullptr;
359 int32_t ret = HksInitParamSet(¶ms);
360 if (ret != HKS_SUCCESS) {
361 LOG_ERROR("HksInitParamSet() failed with error %{public}d", ret);
362 return false;
363 }
364 struct HksParam hksParam[] = {
365 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
366 { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
367 { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
368 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
369 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
370 { .tag = HKS_TAG_NONCE, .blob = blobNonce },
371 { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = blobAad },
372 { .tag = HKS_TAG_AE_TAG, .blob = blobAead },
373 };
374 ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
375 if (ret != HKS_SUCCESS) {
376 LOG_ERROR("HksAddParams failed with error %{public}d", ret);
377 HksFreeParamSet(¶ms);
378 return false;
379 }
380
381 ret = HksBuildParamSet(¶ms);
382 if (ret != HKS_SUCCESS) {
383 LOG_ERROR("HksBuildParamSet failed with error %{public}d", ret);
384 HksFreeParamSet(¶ms);
385 return false;
386 }
387
388 encryptedKeyBlob.size -= AEAD_LEN;
389 for (uint32_t i = 0; i < params->paramsCnt; i++) {
390 if (params->params[i].tag == HKS_TAG_AE_TAG) {
391 uint8_t *tempPtr = encryptedKeyBlob.data;
392 if (memcpy_s(params->params[i].blob.data, AEAD_LEN, tempPtr + encryptedKeyBlob.size, AEAD_LEN) != 0) {
393 LOG_ERROR("Method memcpy_s failed");
394 HksFreeParamSet(¶ms);
395 return false;
396 }
397 break;
398 }
399 }
400
401 uint8_t plainBuf[256] = { 0 };
402 struct HksBlob plainKeyBlob = { sizeof(plainBuf), plainBuf };
403 ret = HksDecryptThreeStage(&rootKeyName, params, &encryptedKeyBlob, &plainKeyBlob);
404 (void)HksFreeParamSet(¶ms);
405 if (ret != HKS_SUCCESS) {
406 LOG_ERROR("HksDecrypt failed with error %{public}d", ret);
407 return false;
408 }
409
410 key.assign(plainKeyBlob.data, plainKeyBlob.data + plainKeyBlob.size);
411 (void)memset_s(plainBuf, sizeof(plainBuf), 0, sizeof(plainBuf));
412 return true;
413 }
414
Init(const std::string & bundleName,const std::string & path)415 void RdbSecurityManager::Init(const std::string &bundleName, const std::string &path)
416 {
417 rootKeyAlias_ = GenerateRootKeyAlias(bundleName);
418 nonce_ = std::vector<uint8_t>(RDB_HKS_BLOB_TYPE_NONCE, RDB_HKS_BLOB_TYPE_NONCE + strlen(RDB_HKS_BLOB_TYPE_NONCE));
419 aad_ = std::vector<uint8_t>(RDB_HKS_BLOB_TYPE_AAD, RDB_HKS_BLOB_TYPE_AAD + strlen(RDB_HKS_BLOB_TYPE_AAD));
420
421 ParsePath(path);
422 if (CheckRootKeyExists()) {
423 return;
424 }
425 constexpr uint32_t RETRY_MAX_TIMES = 5;
426 uint32_t retryCount = 0;
427 constexpr int RETRY_TIME_INTERVAL_MILLISECOND = 1 * 1000 * 1000;
428 while (retryCount < RETRY_MAX_TIMES) {
429 auto ret = GenerateRootKey();
430 if (ret == HKS_SUCCESS) {
431 break;
432 }
433 retryCount++;
434 LOG_ERROR("RDB generate root key failed, try count:%{public}u", retryCount);
435 usleep(RETRY_TIME_INTERVAL_MILLISECOND);
436 }
437 }
438
CheckRootKeyExists()439 bool RdbSecurityManager::CheckRootKeyExists()
440 {
441 LOG_INFO("RDB checkRootKeyExist begin.");
442 struct HksBlob rootKeyName = { uint32_t(rootKeyAlias_.size()), rootKeyAlias_.data() };
443 struct HksParamSet *params = nullptr;
444 int32_t ret = HksInitParamSet(¶ms);
445 if (ret != HKS_SUCCESS) {
446 LOG_ERROR("HksInitParamSet()-client failed with error %{public}d", ret);
447 return ret;
448 }
449
450 struct HksParam hksParam[] = {
451 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
452 { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
453 { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
454 { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
455 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
456 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
457 };
458
459 ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
460 if (ret != HKS_SUCCESS) {
461 LOG_ERROR("HksAddParams failed with error %{public}d", ret);
462 HksFreeParamSet(¶ms);
463 return ret;
464 }
465
466 ret = HksBuildParamSet(¶ms);
467 if (ret != HKS_SUCCESS) {
468 LOG_ERROR("HksBuildParamSet failed with error %{public}d", ret);
469 HksFreeParamSet(¶ms);
470 return ret;
471 }
472
473 ret = HksKeyExist(&rootKeyName, params);
474 HksFreeParamSet(¶ms);
475 if (ret != HKS_SUCCESS) {
476 LOG_ERROR("HksEncrypt failed with error %{public}d", ret);
477 }
478 return ret == HKS_SUCCESS;
479 }
480
InitPath(const std::string & path)481 bool RdbSecurityManager::InitPath(const std::string &path)
482 {
483 constexpr mode_t DEFAULT_UMASK = 0002;
484 if (access(path.c_str(), F_OK) == 0) {
485 return true;
486 }
487 umask(DEFAULT_UMASK);
488 if (mkdir(path.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) != 0 && errno != EEXIST) {
489 LOG_ERROR("mkdir error:%{public}d, dbDir:%{public}s", errno, path.c_str());
490 return false;
491 }
492 return true;
493 }
494
LoadSecretKeyFromDisk(const std::string & keyPath,RdbSecretKeyData & keyData)495 bool RdbSecurityManager::LoadSecretKeyFromDisk(const std::string &keyPath, RdbSecretKeyData &keyData)
496 {
497 LOG_INFO("LoadSecretKeyFromDisk begin.");
498 std::vector<char> content;
499 if (!LoadBufferFromFile(keyPath, content)) {
500 LOG_ERROR("LoadBufferFromFile failed!");
501 return false;
502 }
503
504 std::vector<uint8_t> distribute;
505 auto iter = content.begin();
506 distribute.push_back(*iter);
507 iter++;
508 uint8_t distributeStatus = TransferByteArrayToType<uint8_t>(distribute);
509
510 std::vector<uint8_t> createTime;
511 for (int i = 0; i < static_cast<int>(sizeof(time_t) / sizeof(uint8_t)); i++) {
512 createTime.push_back(*iter);
513 iter++;
514 }
515
516 keyData.distributed = distributeStatus;
517 keyData.timeValue = TransferByteArrayToType<time_t>(createTime);
518 keyData.secretKey.insert(keyData.secretKey.end(), iter, content.end());
519
520 return true;
521 }
522
GetRdbPassword(KeyFileType keyFile)523 RdbPassword RdbSecurityManager::GetRdbPassword(KeyFileType keyFile)
524 {
525 LOG_INFO("GetRdbPassword Begin.");
526 std::string keyPath;
527 if (keyFile == KeyFileType::PUB_KEY_FILE) {
528 keyPath = keyPath_;
529 } else {
530 keyPath = keyBakPath_;
531 }
532 RdbSecretKeyData keyData;
533 if (!LoadSecretKeyFromDisk(keyPath, keyData)) {
534 return {};
535 }
536 std::vector<uint8_t> key;
537 if (!DecryptWorkKey(keyData.secretKey, key)) {
538 LOG_ERROR("GetRdbPassword failed!");
539 return {};
540 }
541
542 RdbPassword password;
543 password.SetValue(key.data(), key.size());
544 key.assign(key.size(), 0);
545 return password;
546 }
547
GenerateRootKeyAlias(const std::string & bundleName)548 std::vector<uint8_t> RdbSecurityManager::GenerateRootKeyAlias(const std::string &bundleName)
549 {
550 bundleName_ = bundleName;
551 if (bundleName_.empty()) {
552 LOG_ERROR("BundleName is empty!");
553 return {};
554 }
555 std::vector<uint8_t> rootKeyAlias = std::vector<uint8_t>(
556 RDB_ROOT_KEY_ALIAS_PREFIX, RDB_ROOT_KEY_ALIAS_PREFIX + strlen(RDB_ROOT_KEY_ALIAS_PREFIX));
557 rootKeyAlias.insert(rootKeyAlias.end(), bundleName.begin(), bundleName.end());
558 return rootKeyAlias;
559 }
560
DelRdbSecretDataFile(const std::string & path)561 void RdbSecurityManager::DelRdbSecretDataFile(const std::string &path)
562 {
563 LOG_INFO("Delete all key files begin.");
564 std::lock_guard<std::mutex> lock(mutex_);
565 ParsePath(path);
566 SqliteDatabaseUtils::DeleteFile(keyPath_);
567 SqliteDatabaseUtils::DeleteFile(keyBakPath_);
568 }
569
IsKeyOutOfdate(const time_t & createTime) const570 bool RdbSecurityManager::IsKeyOutOfdate(const time_t &createTime) const
571 {
572 std::chrono::system_clock::time_point createTimeChrono = std::chrono::system_clock::from_time_t(createTime);
573 return ((createTimeChrono + std::chrono::hours(HOURS_PER_YEAR)) < std::chrono::system_clock::now());
574 }
575
GetInstance()576 RdbSecurityManager &RdbSecurityManager::GetInstance()
577 {
578 static RdbSecurityManager instance;
579 return instance;
580 }
581
RemoveSuffix(const std::string & name)582 static std::string RemoveSuffix(const std::string &name)
583 {
584 std::string suffix(".db");
585 auto pos = name.rfind(suffix);
586 if (pos == std::string::npos || pos < name.length() - suffix.length()) {
587 return name;
588 }
589 return { name, 0, pos };
590 }
591
ParsePath(const std::string & path)592 void RdbSecurityManager::ParsePath(const std::string &path)
593 {
594 dbDir_ = ExtractFilePath(path);
595 const std::string dbName = ExtractFileName(path);
596 dbName_ = RemoveSuffix(dbName);
597 dbKeyDir_ = dbDir_ + std::string("key/");
598 keyPath_ = dbKeyDir_ + dbName_ + std::string(RdbSecurityManager::SUFFIX_PUB_KEY);
599 keyBakPath_ = dbKeyDir_ + dbName_ + std::string(RdbSecurityManager::SUFFIX_PUB_KEY_BAK);
600 }
601
CheckKeyDataFileExists(RdbSecurityManager::KeyFileType fileType)602 bool RdbSecurityManager::CheckKeyDataFileExists(RdbSecurityManager::KeyFileType fileType)
603 {
604 if (fileType == KeyFileType::PUB_KEY_FILE) {
605 return FileExists(keyPath_);
606 } else {
607 return FileExists(keyBakPath_);
608 }
609 }
610
GetKeyDistributedStatus(KeyFileType keyFile,bool & status)611 int RdbSecurityManager::GetKeyDistributedStatus(KeyFileType keyFile, bool &status)
612 {
613 LOG_INFO("GetKeyDistributedStatus start.");
614 std::string keyPath;
615 if (keyFile == KeyFileType::PUB_KEY_FILE) {
616 keyPath = keyPath_;
617 } else {
618 keyPath = keyBakPath_;
619 }
620
621 RdbSecretKeyData keyData;
622 if (!LoadSecretKeyFromDisk(keyPath, keyData)) {
623 return E_ERROR;
624 }
625
626 status = (keyData.distributed == DISTRIBUTED);
627 return E_OK;
628 }
629
SetKeyDistributedStatus(KeyFileType keyFile,bool status)630 int RdbSecurityManager::SetKeyDistributedStatus(KeyFileType keyFile, bool status)
631 {
632 LOG_INFO("SetKeyDistributedStatus start.");
633 std::string keyPath;
634 if (keyFile == KeyFileType::PUB_KEY_FILE) {
635 keyPath = keyPath_;
636 } else {
637 keyPath = keyBakPath_;
638 }
639 RdbSecretKeyData keyData;
640 if (!LoadSecretKeyFromDisk(keyPath, keyData)) {
641 return E_ERROR;
642 }
643
644 keyData.distributed = (status ? DISTRIBUTED : UNDISTRIBUTED);
645 if (!SaveSecretKeyToDisk(keyPath, keyData)) {
646 return E_ERROR;
647 }
648
649 return E_OK;
650 }
651 } // namespace NativeRdb
652 } // namespace OHOS
653