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 #define LOG_TAG "SecurityManager"
16
17 #include "security_manager.h"
18
19 #include <chrono>
20 #include <fcntl.h>
21 #include <limits>
22 #include <sys/file.h>
23 #include <unistd.h>
24
25 #include "file_ex.h"
26 #include "hks_api.h"
27 #include "hks_param.h"
28 #include "log_print.h"
29 #include "securec.h"
30 #include "store_types.h"
31 #include "store_util.h"
32 #include "task_executor.h"
33
34 namespace OHOS::DistributedKv {
35 static constexpr int HOURS_PER_YEAR = (24 * 365);
36 static constexpr const char *ROOT_KEY_ALIAS = "distributeddb_client_root_key";
37 static constexpr const char *HKS_BLOB_TYPE_NONCE = "Z5s0Bo571KoqwIi6";
38 static constexpr const char *HKS_BLOB_TYPE_AAD = "distributeddata_client";
39 static constexpr const char *SUFFIX_KEY = ".key";
40 static constexpr const char *SUFFIX_KEY_V1 = ".key_v1";
41 static constexpr const char *SUFFIX_KEY_LOCK = ".key_lock";
42 static constexpr const char *KEY_DIR = "/key";
43 static constexpr const char *SLASH = "/";
44
SecurityManager()45 SecurityManager::SecurityManager()
46 {
47 vecRootKeyAlias_ = std::vector<uint8_t>(ROOT_KEY_ALIAS, ROOT_KEY_ALIAS + strlen(ROOT_KEY_ALIAS));
48 vecNonce_ = std::vector<uint8_t>(HKS_BLOB_TYPE_NONCE, HKS_BLOB_TYPE_NONCE + strlen(HKS_BLOB_TYPE_NONCE));
49 vecAad_ = std::vector<uint8_t>(HKS_BLOB_TYPE_AAD, HKS_BLOB_TYPE_AAD + strlen(HKS_BLOB_TYPE_AAD));
50 }
51
~SecurityManager()52 SecurityManager::~SecurityManager()
53 {}
54
GetInstance()55 SecurityManager &SecurityManager::GetInstance()
56 {
57 static SecurityManager instance;
58 return instance;
59 }
60
Retry()61 bool SecurityManager::Retry()
62 {
63 auto status = CheckRootKey();
64 if (status == HKS_SUCCESS) {
65 hasRootKey_ = true;
66 ZLOGE("Root key already exist.");
67 return true;
68 }
69
70 if (status == HKS_ERROR_NOT_EXIST && GenerateRootKey() == HKS_SUCCESS) {
71 hasRootKey_ = true;
72 ZLOGE("GenerateRootKey success.");
73 return true;
74 }
75
76 constexpr int32_t interval = 100;
77 TaskExecutor::GetInstance().Schedule(std::chrono::milliseconds(interval), [this] {
78 Retry();
79 });
80 return false;
81 }
82
Random(int32_t length)83 std::vector<uint8_t> SecurityManager::Random(int32_t length)
84 {
85 std::vector<uint8_t> value(length, 0);
86 struct HksBlob blobValue = { .size = length, .data = &(value[0]) };
87 auto ret = HksGenerateRandom(nullptr, &blobValue);
88 if (ret != HKS_SUCCESS) {
89 ZLOGE("HksGenerateRandom failed, status: %{public}d", ret);
90 return {};
91 }
92 return value;
93 }
94
LoadContent(SecurityManager::SecurityContent & content,const std::string & path)95 bool SecurityManager::LoadContent(SecurityManager::SecurityContent &content, const std::string &path)
96 {
97 if (!FileExists(path)) {
98 return false;
99 }
100 LoadKeyFromFile(path, content);
101 if (content.encryptValue.empty() || !Decrypt(content)) {
102 return false;
103 }
104 return true;
105 }
106
GetDBPassword(const std::string & name,const std::string & path,bool needCreate)107 SecurityManager::DBPassword SecurityManager::GetDBPassword(const std::string &name, const std::string &path,
108 bool needCreate)
109 {
110 KeyFiles keyFiles(name, path);
111 KeyFilesAutoLock fileLock(keyFiles);
112 DBPassword dbPassword;
113 auto oldKeyPath = path + KEY_DIR + SLASH + name + SUFFIX_KEY;
114 auto newKeyPath = path + KEY_DIR + SLASH + name + SUFFIX_KEY_V1;
115 SecurityContent content;
116 auto result = LoadContent(content, newKeyPath);
117 if (!result) {
118 content.isNewStyle = false;
119 result = LoadContent(content, oldKeyPath);
120 }
121 content.encryptValue.assign(content.encryptValue.size(), 0);
122 std::vector<uint8_t> key;
123 if (result) {
124 size_t offset = 0;
125 if (content.isNewStyle && content.fullKeyValue.size() > (sizeof(time_t) / sizeof(uint8_t)) + 1) {
126 content.version = content.fullKeyValue[offset++];
127 content.time.assign(content.fullKeyValue.begin() + offset,
128 content.fullKeyValue.begin() + offset + (sizeof(time_t) / sizeof(uint8_t)));
129 }
130 offset = content.isNewStyle ? (sizeof(time_t) / sizeof(uint8_t)) + 1 : 0;
131 if (content.fullKeyValue.size() > offset) {
132 key.assign(content.fullKeyValue.begin() + offset, content.fullKeyValue.end());
133 }
134 // old security key file and update key file
135 if (!content.isNewStyle && !key.empty() && SaveKeyToFile(name, path, key)) {
136 StoreUtil::Remove(oldKeyPath);
137 }
138 content.fullKeyValue.assign(content.fullKeyValue.size(), 0);
139 }
140 if (!result && needCreate) {
141 key = Random(SecurityContent::KEY_SIZE);
142 if (key.empty() || !SaveKeyToFile(name, path, key)) {
143 key.assign(key.size(), 0);
144 return dbPassword;
145 }
146 StoreUtil::Remove(oldKeyPath);
147 }
148 if (!content.time.empty()) {
149 dbPassword.isKeyOutdated = IsKeyOutdated(content.time);
150 }
151 dbPassword.SetValue(key.data(), key.size());
152 key.assign(key.size(), 0);
153 return dbPassword;
154 }
155
SaveDBPassword(const std::string & name,const std::string & path,const DistributedDB::CipherPassword & key)156 bool SecurityManager::SaveDBPassword(const std::string &name, const std::string &path,
157 const DistributedDB::CipherPassword &key)
158 {
159 KeyFiles keyFiles(name, path);
160 KeyFilesAutoLock fileLock(keyFiles);
161 std::vector<uint8_t> pwd(key.GetData(), key.GetData() + key.GetSize());
162 auto result = SaveKeyToFile(name, path, pwd);
163 pwd.assign(pwd.size(), 0);
164 return result;
165 }
166
DelDBPassword(const std::string & name,const std::string & path)167 void SecurityManager::DelDBPassword(const std::string &name, const std::string &path)
168 {
169 KeyFiles keyFiles(name, path);
170 KeyFilesAutoLock fileLock(keyFiles);
171 auto oldKeyPath = path + KEY_DIR + SLASH + name + SUFFIX_KEY;
172 auto newKeyPath = path + KEY_DIR + SLASH + name + SUFFIX_KEY_V1;
173 StoreUtil::Remove(oldKeyPath);
174 StoreUtil::Remove(newKeyPath);
175 fileLock.UnLockAndDestroy();
176 }
177
LoadKeyFromFile(const std::string & path,SecurityManager::SecurityContent & securityContent)178 void SecurityManager::LoadKeyFromFile(const std::string &path, SecurityManager::SecurityContent &securityContent)
179 {
180 std::vector<char> content;
181 auto loaded = LoadBufferFromFile(path, content);
182 if (!loaded) {
183 return;
184 }
185 if (securityContent.isNewStyle) {
186 LoadNewKey(content, securityContent);
187 } else {
188 LoadOldKey(content, securityContent);
189 }
190 content.assign(content.size(), 0);
191 }
192
LoadNewKey(const std::vector<char> & content,SecurityManager::SecurityContent & securityContent)193 void SecurityManager::LoadNewKey(const std::vector<char> &content, SecurityManager::SecurityContent &securityContent)
194 {
195 if (content.size() < SecurityContent::MAGIC_NUM + SecurityContent::NONCE_SIZE + 1) {
196 return;
197 }
198 for (size_t index = 0; index < SecurityContent::MAGIC_NUM; ++index) {
199 if (content[index] != char(SecurityContent::MAGIC_CHAR)) {
200 return;
201 }
202 }
203 size_t offset = SecurityContent::MAGIC_NUM;
204 securityContent.nonceValue.assign(content.begin() + offset, content.begin() + offset + SecurityContent::NONCE_SIZE);
205 offset += SecurityContent::NONCE_SIZE;
206 securityContent.encryptValue.assign(content.begin() + offset, content.end());
207 }
208
LoadOldKey(const std::vector<char> & content,SecurityManager::SecurityContent & securityContent)209 void SecurityManager::LoadOldKey(const std::vector<char> &content, SecurityManager::SecurityContent &securityContent)
210 {
211 size_t offset = 0;
212 if (content.size() < (sizeof(time_t) / sizeof(uint8_t)) + SecurityContent::KEY_SIZE + 1) {
213 return;
214 }
215 if (content[offset] != char((sizeof(time_t) / sizeof(uint8_t)) + SecurityContent::KEY_SIZE)) {
216 return;
217 }
218 ++offset;
219 securityContent.time.assign(content.begin() + offset, content.begin() +
220 (sizeof(time_t) / sizeof(uint8_t)) + offset);
221 offset += (sizeof(time_t) / sizeof(uint8_t));
222 securityContent.encryptValue.assign(content.begin() + offset, content.end());
223 }
224
SaveKeyToFile(const std::string & name,const std::string & path,std::vector<uint8_t> & key)225 bool SecurityManager::SaveKeyToFile(const std::string &name, const std::string &path,
226 std::vector<uint8_t> &key)
227 {
228 if (!hasRootKey_ && !Retry()) {
229 ZLOGE("Failed! no root key and generation failed");
230 return false;
231 }
232 SecurityContent securityContent;
233 securityContent.version = SecurityContent::CURRENT_VERSION;
234 auto time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
235 securityContent.time = { reinterpret_cast<uint8_t *>(&time), reinterpret_cast<uint8_t *>(&time) + sizeof(time) };
236 std::vector<uint8_t> keyContent;
237 keyContent.push_back(securityContent.version);
238 keyContent.insert(keyContent.end(), securityContent.time.begin(), securityContent.time.end());
239 keyContent.insert(keyContent.end(), key.begin(), key.end());
240 if (!Encrypt(keyContent, securityContent)) {
241 keyContent.assign(keyContent.size(), 0);
242 return false;
243 }
244 keyContent.assign(keyContent.size(), 0);
245 auto keyPath = path + KEY_DIR;
246 StoreUtil::InitPath(keyPath);
247 auto keyFullPath = keyPath + SLASH + name + SUFFIX_KEY_V1;
248 auto fd = open(keyFullPath.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
249 if (fd < 0) {
250 ZLOGE("Create file failed, ret:%{public}d", errno);
251 return false;
252 }
253 std::string content(SecurityContent::MAGIC_NUM, static_cast<char>(SecurityContent::MAGIC_CHAR));
254 content.append(reinterpret_cast<const char *>(securityContent.nonceValue.data()),
255 securityContent.nonceValue.size());
256 content.append(reinterpret_cast<const char *>(securityContent.encryptValue.data()),
257 securityContent.encryptValue.size());
258 auto ret = SaveStringToFd(fd, content);
259 std::fill(content.begin(), content.end(), '\0');
260 close(fd);
261 if (!ret) {
262 ZLOGE("Save key to file fail, ret:%{public}d", ret);
263 return false;
264 }
265 StoreUtil::RemoveRWXForOthers(keyFullPath);
266 return ret;
267 }
268
Encrypt(const std::vector<uint8_t> & key,SecurityManager::SecurityContent & content)269 bool SecurityManager::Encrypt(const std::vector<uint8_t> &key, SecurityManager::SecurityContent &content)
270 {
271 struct HksParamSet *params = nullptr;
272 int32_t ret = HksInitParamSet(¶ms);
273 if (ret != HKS_SUCCESS) {
274 ZLOGE("HksInitParamSet failed, status: %{public}d", ret);
275 return false;
276 }
277 content.nonceValue = Random(SecurityContent::NONCE_SIZE);
278 if (content.nonceValue.empty()) {
279 HksFreeParamSet(¶ms);
280 return false;
281 }
282 struct HksParam hksParam[] = {
283 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
284 { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT },
285 { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
286 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
287 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
288 { .tag = HKS_TAG_NONCE, .blob = { SecurityContent::NONCE_SIZE, &(content.nonceValue[0]) } },
289 { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = { uint32_t(vecAad_.size()), &(vecAad_[0]) } },
290 { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
291 };
292 ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
293 if (ret != HKS_SUCCESS) {
294 ZLOGE("HksAddParams failed, status: %{public}d", ret);
295 HksFreeParamSet(¶ms);
296 return false;
297 }
298 ret = HksBuildParamSet(¶ms);
299 if (ret != HKS_SUCCESS) {
300 ZLOGE("HksBuildParamSet failed, status: %{public}d", ret);
301 HksFreeParamSet(¶ms);
302 return false;
303 }
304 uint8_t cipherBuf[256] = { 0 };
305 struct HksBlob cipherText = { sizeof(cipherBuf), cipherBuf };
306 struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
307 struct HksBlob plainKey = { uint32_t(key.size()), const_cast<uint8_t *>(key.data()) };
308 ret = HksEncrypt(&rootKeyName, params, &plainKey, &cipherText);
309 (void)HksFreeParamSet(¶ms);
310 if (ret != HKS_SUCCESS) {
311 ZLOGE("HksEncrypt failed, status: %{public}d", ret);
312 return false;
313 }
314 content.encryptValue = std::vector<uint8_t>(cipherText.data, cipherText.data + cipherText.size);
315 std::fill(cipherBuf, cipherBuf + sizeof(cipherBuf), 0);
316 return true;
317 }
318
Decrypt(SecurityManager::SecurityContent & content)319 bool SecurityManager::Decrypt(SecurityManager::SecurityContent &content)
320 {
321 struct HksParamSet *params = nullptr;
322 int32_t ret = HksInitParamSet(¶ms);
323 if (ret != HKS_SUCCESS) {
324 ZLOGE("HksInitParamSet failed, status: %{public}d", ret);
325 return false;
326 }
327 struct HksBlob blobNonce = { .size = uint32_t(vecNonce_.size()), .data = &(vecNonce_[0]) };
328 if (!(content.nonceValue.empty())) {
329 blobNonce.size = uint32_t(content.nonceValue.size());
330 blobNonce.data = const_cast<uint8_t*>(&(content.nonceValue[0]));
331 }
332 struct HksParam hksParam[] = {
333 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
334 { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
335 { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
336 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
337 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
338 { .tag = HKS_TAG_NONCE, .blob = blobNonce },
339 { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = { uint32_t(vecAad_.size()), &(vecAad_[0]) } },
340 { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
341 };
342 ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
343 if (ret != HKS_SUCCESS) {
344 ZLOGE("HksAddParams failed, status: %{public}d", ret);
345 HksFreeParamSet(¶ms);
346 return false;
347 }
348 ret = HksBuildParamSet(¶ms);
349 if (ret != HKS_SUCCESS) {
350 ZLOGE("HksBuildParamSet failed, status: %{public}d", ret);
351 HksFreeParamSet(¶ms);
352 return false;
353 }
354 uint8_t plainBuf[256] = { 0 };
355 struct HksBlob plainKeyBlob = { sizeof(plainBuf), plainBuf };
356 struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), &(vecRootKeyAlias_[0]) };
357 struct HksBlob encryptedKeyBlob = { uint32_t(content.encryptValue.size()),
358 const_cast<uint8_t *>(content.encryptValue.data()) };
359 ret = HksDecrypt(&rootKeyName, params, &encryptedKeyBlob, &plainKeyBlob);
360 (void)HksFreeParamSet(¶ms);
361 if (ret != HKS_SUCCESS) {
362 ZLOGE("HksDecrypt, status: %{public}d", ret);
363 return false;
364 }
365 content.fullKeyValue.assign(plainKeyBlob.data, plainKeyBlob.data + plainKeyBlob.size);
366 std::fill(plainBuf, plainBuf + sizeof(plainBuf), 0);
367 return true;
368 }
369
GenerateRootKey()370 int32_t SecurityManager::GenerateRootKey()
371 {
372 struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
373 struct HksParamSet *params = nullptr;
374 int32_t ret = HksInitParamSet(¶ms);
375 if (ret != HKS_SUCCESS) {
376 ZLOGE("HksInitParamSet failed, status: %{public}d", ret);
377 return ret;
378 }
379
380 struct HksParam hksParam[] = {
381 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
382 { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
383 { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
384 { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
385 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
386 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
387 { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
388 };
389
390 ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
391 if (ret != HKS_SUCCESS) {
392 ZLOGE("HksAddParams failed, status: %{public}d", ret);
393 HksFreeParamSet(¶ms);
394 return ret;
395 }
396
397 ret = HksBuildParamSet(¶ms);
398 if (ret != HKS_SUCCESS) {
399 ZLOGE("HksBuildParamSet failed, status: %{public}d", ret);
400 HksFreeParamSet(¶ms);
401 return ret;
402 }
403
404 ret = HksGenerateKey(&rootKeyName, params, nullptr);
405 HksFreeParamSet(¶ms);
406 ZLOGI("HksGenerateKey status: %{public}d", ret);
407 return ret;
408 }
409
CheckRootKey()410 int32_t SecurityManager::CheckRootKey()
411 {
412 struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
413 struct HksParamSet *params = nullptr;
414 int32_t ret = HksInitParamSet(¶ms);
415 if (ret != HKS_SUCCESS) {
416 ZLOGE("HksInitParamSet failed, status: %{public}d", ret);
417 return ret;
418 }
419
420 struct HksParam hksParam[] = {
421 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
422 { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
423 { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
424 { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
425 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
426 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
427 { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
428 };
429
430 ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
431 if (ret != HKS_SUCCESS) {
432 ZLOGE("HksAddParams failed, status: %{public}d", ret);
433 HksFreeParamSet(¶ms);
434 return ret;
435 }
436
437 ret = HksBuildParamSet(¶ms);
438 if (ret != HKS_SUCCESS) {
439 ZLOGE("HksBuildParamSet failed, status: %{public}d", ret);
440 HksFreeParamSet(¶ms);
441 return ret;
442 }
443
444 ret = HksKeyExist(&rootKeyName, params);
445 HksFreeParamSet(¶ms);
446 ZLOGI("HksKeyExist status: %{public}d", ret);
447 return ret;
448 }
449
IsKeyOutdated(const std::vector<uint8_t> & date)450 bool SecurityManager::IsKeyOutdated(const std::vector<uint8_t> &date)
451 {
452 time_t time = *reinterpret_cast<time_t *>(const_cast<uint8_t *>(&date[0]));
453 auto createTime = std::chrono::system_clock::from_time_t(time);
454 return ((createTime + std::chrono::hours(HOURS_PER_YEAR)) < std::chrono::system_clock::now());
455 }
456
KeyFiles(const std::string & name,const std::string & path,bool openFile)457 SecurityManager::KeyFiles::KeyFiles(const std::string &name, const std::string &path, bool openFile)
458 {
459 lockFile_ = path + KEY_DIR + SLASH + name + SUFFIX_KEY_LOCK;
460 StoreUtil::InitPath(path + KEY_DIR);
461 if (!openFile) {
462 return;
463 }
464 lockFd_ = open(lockFile_.c_str(), O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR);
465 if (lockFd_ < 0) {
466 ZLOGE("Open failed, errno:%{public}d, path:%{public}s", errno, StoreUtil::Anonymous(lockFile_).c_str());
467 }
468 }
469
~KeyFiles()470 SecurityManager::KeyFiles::~KeyFiles()
471 {
472 if (lockFd_ < 0) {
473 return;
474 }
475 close(lockFd_);
476 lockFd_ = -1;
477 }
478
Lock()479 int32_t SecurityManager::KeyFiles::Lock()
480 {
481 return FileLock(LOCK_EX);
482 }
483
UnLock()484 int32_t SecurityManager::KeyFiles::UnLock()
485 {
486 return FileLock(LOCK_UN);
487 }
488
DestroyLock()489 int32_t SecurityManager::KeyFiles::DestroyLock()
490 {
491 if (lockFd_ > 0) {
492 close(lockFd_);
493 lockFd_ = -1;
494 }
495 StoreUtil::Remove(lockFile_);
496 return Status::SUCCESS;
497 }
498
FileLock(int32_t lockType)499 int32_t SecurityManager::KeyFiles::FileLock(int32_t lockType)
500 {
501 if (lockFd_ < 0) {
502 return Status::INVALID_ARGUMENT;
503 }
504 int32_t errCode = 0;
505 do {
506 errCode = flock(lockFd_, lockType);
507 } while (errCode < 0 && errno == EINTR);
508 if (errCode < 0) {
509 ZLOGE("This flock is failed, type:%{public}d, errno:%{public}d, path:%{public}s", lockType, errno,
510 StoreUtil::Anonymous(lockFile_).c_str());
511 return Status::ERROR;
512 }
513 return Status::SUCCESS;
514 }
515
KeyFilesAutoLock(KeyFiles & keyFiles)516 SecurityManager::KeyFilesAutoLock::KeyFilesAutoLock(KeyFiles& keyFiles) : keyFiles_(keyFiles)
517 {
518 keyFiles_.Lock();
519 }
520
~KeyFilesAutoLock()521 SecurityManager::KeyFilesAutoLock::~KeyFilesAutoLock()
522 {
523 keyFiles_.UnLock();
524 }
525
UnLockAndDestroy()526 int32_t SecurityManager::KeyFilesAutoLock::UnLockAndDestroy()
527 {
528 keyFiles_.UnLock();
529 return keyFiles_.DestroyLock();
530 }
531 } // namespace OHOS::DistributedKv
532