• 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 "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(&params);
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(&params);
280         return ret;
281     }
282 
283     ret = HksBuildParamSet(&params);
284     if (ret != HKS_SUCCESS) {
285         LOG_ERROR("HksBuildParamSet-client failed with error %{public}d", ret);
286         HksFreeParamSet(&params);
287         return ret;
288     }
289 
290     ret = HksGenerateKey(&rootKeyName, params, nullptr);
291     HksFreeParamSet(&params);
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(&params);
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(&params);
324         return {};
325     }
326 
327     ret = HksBuildParamSet(&params);
328     if (ret != HKS_SUCCESS) {
329         LOG_ERROR("HksBuildParamSet failed with error %{public}d", ret);
330         HksFreeParamSet(&params);
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(&params);
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(&params);
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(&params);
378         return false;
379     }
380 
381     ret = HksBuildParamSet(&params);
382     if (ret != HKS_SUCCESS) {
383         LOG_ERROR("HksBuildParamSet failed with error %{public}d", ret);
384         HksFreeParamSet(&params);
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(&params);
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(&params);
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(&params);
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(&params);
463         return ret;
464     }
465 
466     ret = HksBuildParamSet(&params);
467     if (ret != HKS_SUCCESS) {
468         LOG_ERROR("HksBuildParamSet failed with error %{public}d", ret);
469         HksFreeParamSet(&params);
470         return ret;
471     }
472 
473     ret = HksKeyExist(&rootKeyName, params);
474     HksFreeParamSet(&params);
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