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