• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "camera_rotate_param_sign_tools.h"
17 
18 #include <fstream> // ifstream所需
19 #include <iostream>
20 #include <sstream> // stringstream
21 #include "camera_log.h"
22 #include "file_ex.h"
23 #include "camera_util.h"
24 
25 namespace OHOS {
26 namespace CameraStandard {
27 // LCOV_EXCL_START
VerifyFileSign(const std::string & pubKeyPath,const std::string & signPath,const std::string & digestPath)28 bool CameraRoateParamSignTool::VerifyFileSign(const std::string &pubKeyPath, const std::string &signPath,
29     const std::string &digestPath)
30 {
31     if (!(CheckPathExist(pubKeyPath.c_str()) && CheckPathExist(signPath.c_str()) &&
32         CheckPathExist(digestPath.c_str()))) {
33         MEDIA_ERR_LOG("file not exist");
34         return false;
35     }
36 
37     const std::string signStr = GetFileStream(signPath);
38     const std::string digeststr = GetFileStream(digestPath);
39 
40     BIO *bio = BIO_new_file(pubKeyPath.c_str(), "r");
41 
42     RSA *pubKey = RSA_new();
43 
44     CHECK_RETURN_RET_ELOG(
45         PEM_read_bio_RSA_PUBKEY(bio, &pubKey, NULL, NULL) == NULL, false, "get pubKey is failed");
46 
47     bool verify = false;
48     if (!(pubKey == NULL || signStr.empty() || digeststr.empty())) {
49         verify = VerifyRsa(pubKey, digeststr, signStr);
50     } else {
51         MEDIA_ERR_LOG("pubKey == NULL || signStr.empty() || digeststr.empty()");
52     }
53     BIO_free(bio);
54     RSA_free(pubKey);
55     return verify;
56 }
57 
VerifyRsa(RSA * pubKey,const std::string & digest,const std::string & sign)58 bool CameraRoateParamSignTool::VerifyRsa(RSA *pubKey, const std::string &digest, const std::string &sign)
59 {
60     EVP_PKEY *evpKey = NULL;
61     EVP_MD_CTX *ctx = NULL;
62     evpKey = EVP_PKEY_new();
63     CHECK_RETURN_RET_ELOG(evpKey == nullptr, false, "evpKey == nullptr");
64     CHECK_RETURN_RET_ELOG(EVP_PKEY_set1_RSA(evpKey, pubKey) != 1, false, "EVP_PKEY_set1_RSA(evpKey, pubKey) != 1");
65     ctx = EVP_MD_CTX_new();
66     EVP_MD_CTX_init(ctx);
67     if (ctx == nullptr) {
68         MEDIA_ERR_LOG("ctx == nullptr");
69         EVP_PKEY_free(evpKey);
70         return false;
71     }
72     // warnning:需要与签名的hash算法一致,当前使用的是 sha256withrsa ,需要选择 EVP_sha256()
73     if (EVP_VerifyInit_ex(ctx, EVP_sha256(), NULL) != 1) {
74         MEDIA_ERR_LOG("EVP_VerifyInit_ex(ctx, EVP_sha256(), NULL) != 1");
75         EVP_PKEY_free(evpKey);
76         EVP_MD_CTX_free(ctx);
77         return false;
78     }
79     if (EVP_VerifyUpdate(ctx, digest.c_str(), digest.size()) != 1) {
80         MEDIA_ERR_LOG("EVP_VerifyUpdate(ctx, digest.c_str(), digest.size()) != 1");
81         EVP_PKEY_free(evpKey);
82         EVP_MD_CTX_free(ctx);
83         return false;
84     }
85     if (EVP_VerifyFinal(ctx, (unsigned char *)sign.c_str(), sign.size(), evpKey) != 1) {
86         MEDIA_ERR_LOG("EVP_VerifyFinal(ctx, (unsigned char *)sign.c_str(), sign.size(), evpKey) != 1)");
87         EVP_PKEY_free(evpKey);
88         EVP_MD_CTX_free(ctx);
89         return false;
90     }
91     EVP_PKEY_free(evpKey);
92     EVP_MD_CTX_free(ctx);
93     return true;
94 }
95 
CalcFileSha256Digest(const std::string & fpath)96 std::tuple<int, std::string> CameraRoateParamSignTool::CalcFileSha256Digest(const std::string &fpath)
97 {
98     auto res = std::make_unique<unsigned char[]>(SHA256_DIGEST_LENGTH);
99     SHA256_CTX ctx;
100     SHA256_Init(&ctx);
101     auto sha256Update = [ctx = &ctx](char *buf, size_t len) { SHA256_Update(ctx, buf, len); };
102     int err = ForEachFileSegment(fpath, sha256Update);
103     SHA256_Final(res.get(), &ctx);
104     if (err) {
105         return { err, "" };
106     }
107     std::string dist;
108     CalcBase64(res.get(), SHA256_DIGEST_LENGTH, dist);
109     return { err, dist };
110 };
111 
ForEachFileSegment(const std::string & fpath,std::function<void (char *,size_t)> executor)112 int CameraRoateParamSignTool::ForEachFileSegment(const std::string &fpath, std::function<void(char *, size_t)> executor)
113 {
114     char canonicalPath[PATH_MAX + 1] = {0x00};
115     CHECK_RETURN_RET_ELOG(
116         realpath(fpath.c_str(), canonicalPath) == nullptr, errno, "ForEachFileSegment filepath is irregular");
117     std::unique_ptr<FILE, decltype(&fclose)> filp = { fopen(canonicalPath, "r"), fclose };
118     if (!filp) {
119         return errno;
120     }
121     const size_t pageSize { getpagesize() };
122     auto buf = std::make_unique<char[]>(pageSize);
123     size_t actLen;
124     do {
125         actLen = fread(buf.get(), 1, pageSize, filp.get());
126         if (actLen > 0) {
127             executor(buf.get(), actLen);
128         }
129     } while (actLen == pageSize);
130 
131     return ferror(filp.get()) ? errno : 0;
132 };
133 
CalcBase64(uint8_t * input,uint32_t inputLen,std::string & encodedStr)134 void CameraRoateParamSignTool::CalcBase64(uint8_t *input, uint32_t inputLen, std::string &encodedStr)
135 {
136     size_t expectedLength = 4 * ((inputLen + 2) / 3); // 4 3 is Fixed algorithm
137     encodedStr.resize(expectedLength);
138     int lengthTemp = EVP_EncodeBlock(reinterpret_cast<uint8_t *>(&encodedStr[0]), input, inputLen);
139     CHECK_RETURN(lengthTemp < 0);
140     size_t actualLength = static_cast<size_t>(lengthTemp);
141     encodedStr.resize(actualLength);
142     MEDIA_INFO_LOG("expectedLength = %{public}zu, actualLength = %{public}zu", expectedLength, actualLength);
143 }
144 // LCOV_EXCL_STOP
145 } // namespace CameraStandardParamSignTool
146 } // namespace OHOS
147