• 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::vector<uint8_t> distributedInByte = TransferTypeToByteArray<uint8_t>(keyData.distributed);
240     std::vector<uint8_t> timeInByte = TransferTypeToByteArray<time_t>(keyData.timeValue);
241     std::vector<char> secretKeyInChar;
242     secretKeyInChar.insert(secretKeyInChar.end(), distributedInByte.begin(), distributedInByte.end());
243     secretKeyInChar.insert(secretKeyInChar.end(), timeInByte.begin(), timeInByte.end());
244     secretKeyInChar.insert(secretKeyInChar.end(), keyData.secretKey.begin(), keyData.secretKey.end());
245 
246     std::lock_guard<std::mutex> lock(mutex_);
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     {
500         std::lock_guard<std::mutex> lock(mutex_);
501         if (!LoadBufferFromFile(keyPath, content) || content.empty()) {
502             LOG_ERROR("LoadBufferFromFile failed!");
503             return false;
504         }
505     }
506 
507     std::vector<uint8_t> distribute;
508     auto iter = content.begin();
509     distribute.push_back(*iter);
510     iter++;
511     uint8_t distributeStatus = TransferByteArrayToType<uint8_t>(distribute);
512 
513     std::vector<uint8_t> createTime;
514     for (int i = 0; i < static_cast<int>(sizeof(time_t) / sizeof(uint8_t)); i++) {
515         createTime.push_back(*iter);
516         iter++;
517     }
518 
519     keyData.distributed = distributeStatus;
520     keyData.timeValue = TransferByteArrayToType<time_t>(createTime);
521     keyData.secretKey.insert(keyData.secretKey.end(), iter, content.end());
522 
523     return true;
524 }
525 
GetRdbPassword(KeyFileType keyFile)526 RdbPassword RdbSecurityManager::GetRdbPassword(KeyFileType keyFile)
527 {
528     LOG_INFO("GetRdbPassword Begin.");
529     std::string keyPath;
530     if (keyFile == KeyFileType::PUB_KEY_FILE) {
531         keyPath = keyPath_;
532     } else {
533         keyPath = keyBakPath_;
534     }
535     RdbSecretKeyData keyData;
536     if (!LoadSecretKeyFromDisk(keyPath, keyData)) {
537         return {};
538     }
539     std::vector<uint8_t> key;
540     if (!DecryptWorkKey(keyData.secretKey, key)) {
541         LOG_ERROR("GetRdbPassword failed!");
542         return {};
543     }
544 
545     RdbPassword password;
546     password.SetValue(key.data(), key.size());
547     key.assign(key.size(), 0);
548     return password;
549 }
550 
GenerateRootKeyAlias(const std::string & bundleName)551 std::vector<uint8_t> RdbSecurityManager::GenerateRootKeyAlias(const std::string &bundleName)
552 {
553     bundleName_ = bundleName;
554     if (bundleName_.empty()) {
555         LOG_ERROR("BundleName is empty!");
556         return {};
557     }
558     std::vector<uint8_t> rootKeyAlias = std::vector<uint8_t>(
559         RDB_ROOT_KEY_ALIAS_PREFIX, RDB_ROOT_KEY_ALIAS_PREFIX + strlen(RDB_ROOT_KEY_ALIAS_PREFIX));
560     rootKeyAlias.insert(rootKeyAlias.end(), bundleName.begin(), bundleName.end());
561     return rootKeyAlias;
562 }
563 
DelRdbSecretDataFile(const std::string & path)564 void RdbSecurityManager::DelRdbSecretDataFile(const std::string &path)
565 {
566     LOG_INFO("Delete all key files begin.");
567     std::lock_guard<std::mutex> lock(mutex_);
568     ParsePath(path);
569     SqliteDatabaseUtils::DeleteFile(keyPath_);
570     SqliteDatabaseUtils::DeleteFile(keyBakPath_);
571 }
572 
IsKeyOutOfdate(const time_t & createTime) const573 bool RdbSecurityManager::IsKeyOutOfdate(const time_t &createTime) const
574 {
575     std::chrono::system_clock::time_point createTimeChrono = std::chrono::system_clock::from_time_t(createTime);
576     return ((createTimeChrono + std::chrono::hours(HOURS_PER_YEAR)) < std::chrono::system_clock::now());
577 }
578 
GetInstance()579 RdbSecurityManager &RdbSecurityManager::GetInstance()
580 {
581     static RdbSecurityManager instance;
582     return instance;
583 }
584 
RemoveSuffix(const std::string & name)585 static std::string RemoveSuffix(const std::string &name)
586 {
587     std::string suffix(".db");
588     auto pos = name.rfind(suffix);
589     if (pos == std::string::npos || pos < name.length() - suffix.length()) {
590         return name;
591     }
592     return { name, 0, pos };
593 }
594 
ParsePath(const std::string & path)595 void RdbSecurityManager::ParsePath(const std::string &path)
596 {
597     dbDir_ = ExtractFilePath(path);
598     const std::string dbName = ExtractFileName(path);
599     dbName_ = RemoveSuffix(dbName);
600     dbKeyDir_ = dbDir_ + std::string("key/");
601     keyPath_ = dbKeyDir_ + dbName_ + std::string(RdbSecurityManager::SUFFIX_PUB_KEY);
602     keyBakPath_ = dbKeyDir_ + dbName_ + std::string(RdbSecurityManager::SUFFIX_PUB_KEY_BAK);
603 }
604 
CheckKeyDataFileExists(RdbSecurityManager::KeyFileType fileType)605 bool RdbSecurityManager::CheckKeyDataFileExists(RdbSecurityManager::KeyFileType fileType)
606 {
607     if (fileType == KeyFileType::PUB_KEY_FILE) {
608         return FileExists(keyPath_);
609     } else {
610         return FileExists(keyBakPath_);
611     }
612 }
613 
GetKeyDistributedStatus(KeyFileType keyFile,bool & status)614 int RdbSecurityManager::GetKeyDistributedStatus(KeyFileType keyFile, bool &status)
615 {
616     LOG_INFO("GetKeyDistributedStatus start.");
617     std::string keyPath;
618     if (keyFile == KeyFileType::PUB_KEY_FILE) {
619         keyPath = keyPath_;
620     } else {
621         keyPath = keyBakPath_;
622     }
623 
624     RdbSecretKeyData keyData;
625     if (!LoadSecretKeyFromDisk(keyPath, keyData)) {
626         return E_ERROR;
627     }
628 
629     status = (keyData.distributed == DISTRIBUTED);
630     return E_OK;
631 }
632 
SetKeyDistributedStatus(KeyFileType keyFile,bool status)633 int RdbSecurityManager::SetKeyDistributedStatus(KeyFileType keyFile, bool status)
634 {
635     LOG_INFO("SetKeyDistributedStatus start.");
636     std::string keyPath;
637     if (keyFile == KeyFileType::PUB_KEY_FILE) {
638         keyPath = keyPath_;
639     } else {
640         keyPath = keyBakPath_;
641     }
642     RdbSecretKeyData keyData;
643     if (!LoadSecretKeyFromDisk(keyPath, keyData)) {
644         return E_ERROR;
645     }
646 
647     keyData.distributed = (status ? DISTRIBUTED : UNDISTRIBUTED);
648     if (!SaveSecretKeyToDisk(keyPath, keyData)) {
649         return E_ERROR;
650     }
651 
652     return E_OK;
653 }
654 } // namespace NativeRdb
655 } // namespace OHOS
656