1fb299fa2Sopenharmony_ci/*
2fb299fa2Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at
6fb299fa2Sopenharmony_ci *
7fb299fa2Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fb299fa2Sopenharmony_ci *
9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and
13fb299fa2Sopenharmony_ci * limitations under the License.
14fb299fa2Sopenharmony_ci */
15fb299fa2Sopenharmony_ci
16fb299fa2Sopenharmony_ci#include "pkcs7_signed_data.h"
17fb299fa2Sopenharmony_ci#include <openssl/asn1.h>
18fb299fa2Sopenharmony_ci#include <openssl/bio.h>
19fb299fa2Sopenharmony_ci#include <openssl/pkcs7.h>
20fb299fa2Sopenharmony_ci#include <openssl/rsa.h>
21fb299fa2Sopenharmony_ci#include <openssl/sha.h>
22fb299fa2Sopenharmony_ci#include <openssl/x509.h>
23fb299fa2Sopenharmony_ci#include "cert_verify.h"
24fb299fa2Sopenharmony_ci#include "dump.h"
25fb299fa2Sopenharmony_ci#include "openssl_util.h"
26fb299fa2Sopenharmony_ci#include "pkg_utils.h"
27fb299fa2Sopenharmony_ci
28fb299fa2Sopenharmony_cinamespace Hpackage {
29fb299fa2Sopenharmony_cinamespace {
30fb299fa2Sopenharmony_ciconstexpr size_t g_digestAlgoLength[][2] = {
31fb299fa2Sopenharmony_ci    {NID_sha256, SHA256_DIGEST_LENGTH},
32fb299fa2Sopenharmony_ci};
33fb299fa2Sopenharmony_ci
34fb299fa2Sopenharmony_cisize_t GetDigestLength(const size_t digestNid)
35fb299fa2Sopenharmony_ci{
36fb299fa2Sopenharmony_ci    for (size_t i = 0; i < sizeof(g_digestAlgoLength) / sizeof(g_digestAlgoLength[0]); i++) {
37fb299fa2Sopenharmony_ci        if (digestNid == g_digestAlgoLength[i][0]) {
38fb299fa2Sopenharmony_ci            return g_digestAlgoLength[i][1];
39fb299fa2Sopenharmony_ci        }
40fb299fa2Sopenharmony_ci    }
41fb299fa2Sopenharmony_ci    return 0;
42fb299fa2Sopenharmony_ci}
43fb299fa2Sopenharmony_ci}
44fb299fa2Sopenharmony_ci
45fb299fa2Sopenharmony_ciPkcs7SignedData::~Pkcs7SignedData()
46fb299fa2Sopenharmony_ci{
47fb299fa2Sopenharmony_ci    if (pkcs7_ != nullptr) {
48fb299fa2Sopenharmony_ci        PKCS7_free(pkcs7_);
49fb299fa2Sopenharmony_ci        pkcs7_ = nullptr;
50fb299fa2Sopenharmony_ci    }
51fb299fa2Sopenharmony_ci}
52fb299fa2Sopenharmony_ci
53fb299fa2Sopenharmony_ciint32_t Pkcs7SignedData::GetHashFromSignBlock(const uint8_t *srcData, const size_t dataLen,
54fb299fa2Sopenharmony_ci    std::vector<uint8_t> &hash)
55fb299fa2Sopenharmony_ci{
56fb299fa2Sopenharmony_ci    int32_t ret = ParsePkcs7Data(srcData, dataLen);
57fb299fa2Sopenharmony_ci    if (ret != 0) {
58fb299fa2Sopenharmony_ci        PKG_LOGE("parse pkcs7 data fail");
59fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(ret);
60fb299fa2Sopenharmony_ci        return ret;
61fb299fa2Sopenharmony_ci    }
62fb299fa2Sopenharmony_ci
63fb299fa2Sopenharmony_ci    ret = Verify();
64fb299fa2Sopenharmony_ci    if (ret != 0) {
65fb299fa2Sopenharmony_ci        PKG_LOGE("verify pkcs7 data fail");
66fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(ret);
67fb299fa2Sopenharmony_ci        return ret;
68fb299fa2Sopenharmony_ci    }
69fb299fa2Sopenharmony_ci    hash.assign(digest_.begin(), digest_.end());
70fb299fa2Sopenharmony_ci
71fb299fa2Sopenharmony_ci    return 0;
72fb299fa2Sopenharmony_ci}
73fb299fa2Sopenharmony_ci
74fb299fa2Sopenharmony_ciint32_t Pkcs7SignedData::ParsePkcs7Data(const uint8_t *srcData, const size_t dataLen)
75fb299fa2Sopenharmony_ci{
76fb299fa2Sopenharmony_ci    if (srcData == nullptr || dataLen == 0) {
77fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
78fb299fa2Sopenharmony_ci        return -1;
79fb299fa2Sopenharmony_ci    }
80fb299fa2Sopenharmony_ci    if (Init(srcData, dataLen) != 0) {
81fb299fa2Sopenharmony_ci        PKG_LOGE("init pkcs7 data fail");
82fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
83fb299fa2Sopenharmony_ci        return -1;
84fb299fa2Sopenharmony_ci    }
85fb299fa2Sopenharmony_ci
86fb299fa2Sopenharmony_ci    return DoParse();
87fb299fa2Sopenharmony_ci}
88fb299fa2Sopenharmony_ci
89fb299fa2Sopenharmony_ciint32_t Pkcs7SignedData::Verify() const
90fb299fa2Sopenharmony_ci{
91fb299fa2Sopenharmony_ci    std::vector<uint8_t> digestForEVP;
92fb299fa2Sopenharmony_ci    for (unsigned int i = 0; i < signatureInfo.overall.length; i++) {
93fb299fa2Sopenharmony_ci        digestForEVP.push_back(static_cast<uint8_t>(signatureInfo.overall.buffer[i]));
94fb299fa2Sopenharmony_ci    }
95fb299fa2Sopenharmony_ci    if (Verify(digestForEVP, {}, true) == 0) {
96fb299fa2Sopenharmony_ci        return 0;
97fb299fa2Sopenharmony_ci    }
98fb299fa2Sopenharmony_ci    return Verify(digest_, {}, true);
99fb299fa2Sopenharmony_ci}
100fb299fa2Sopenharmony_ci
101fb299fa2Sopenharmony_ciint32_t Pkcs7SignedData::Verify(const std::vector<uint8_t> &hash, const std::vector<uint8_t> &sig,
102fb299fa2Sopenharmony_ci    bool sigInSignerInfo) const
103fb299fa2Sopenharmony_ci{
104fb299fa2Sopenharmony_ci    if (hash.empty()) {
105fb299fa2Sopenharmony_ci        return -1;
106fb299fa2Sopenharmony_ci    }
107fb299fa2Sopenharmony_ci    int32_t ret = -1;
108fb299fa2Sopenharmony_ci    for (auto &signerInfo : signerInfos_) {
109fb299fa2Sopenharmony_ci        ret = Pkcs7SignleSignerVerify(signerInfo, hash, sigInSignerInfo ? signerInfo.digestEncryptData : sig);
110fb299fa2Sopenharmony_ci        if (ret == 0) {
111fb299fa2Sopenharmony_ci            PKG_LOGI("p7sourceData check success");
112fb299fa2Sopenharmony_ci            break;
113fb299fa2Sopenharmony_ci        }
114fb299fa2Sopenharmony_ci        PKG_LOGI("p7sourceData continue");
115fb299fa2Sopenharmony_ci    }
116fb299fa2Sopenharmony_ci
117fb299fa2Sopenharmony_ci    return ret;
118fb299fa2Sopenharmony_ci}
119fb299fa2Sopenharmony_ci
120fb299fa2Sopenharmony_ciint32_t Pkcs7SignedData::Init(const uint8_t *sourceData, const uint32_t sourceDataLen)
121fb299fa2Sopenharmony_ci{
122fb299fa2Sopenharmony_ci    Updater::UPDATER_INIT_RECORD;
123fb299fa2Sopenharmony_ci    BIO *p7Bio = BIO_new(BIO_s_mem());
124fb299fa2Sopenharmony_ci    if (p7Bio == nullptr) {
125fb299fa2Sopenharmony_ci        PKG_LOGE("BIO_new error!");
126fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
127fb299fa2Sopenharmony_ci        return -1;
128fb299fa2Sopenharmony_ci    }
129fb299fa2Sopenharmony_ci    if (static_cast<uint32_t>(BIO_write(p7Bio, sourceData, sourceDataLen)) != sourceDataLen) {
130fb299fa2Sopenharmony_ci        PKG_LOGE("BIO_write error!");
131fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
132fb299fa2Sopenharmony_ci        BIO_free(p7Bio);
133fb299fa2Sopenharmony_ci        return -1;
134fb299fa2Sopenharmony_ci    }
135fb299fa2Sopenharmony_ci
136fb299fa2Sopenharmony_ci    if (pkcs7_ != nullptr) {
137fb299fa2Sopenharmony_ci        PKCS7_free(pkcs7_);
138fb299fa2Sopenharmony_ci        pkcs7_ = nullptr;
139fb299fa2Sopenharmony_ci    }
140fb299fa2Sopenharmony_ci    pkcs7_ = d2i_PKCS7_bio(p7Bio, nullptr);
141fb299fa2Sopenharmony_ci    if (pkcs7_ == nullptr) {
142fb299fa2Sopenharmony_ci        PKG_LOGE("d2i_PKCS7_bio failed!");
143fb299fa2Sopenharmony_ci        BIO_free(p7Bio);
144fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
145fb299fa2Sopenharmony_ci        return -1;
146fb299fa2Sopenharmony_ci    }
147fb299fa2Sopenharmony_ci
148fb299fa2Sopenharmony_ci    int32_t type = OBJ_obj2nid(pkcs7_->type);
149fb299fa2Sopenharmony_ci    if (type != NID_pkcs7_signed) {
150fb299fa2Sopenharmony_ci        PKG_LOGE("Invalid pkcs7 data type %d", type);
151fb299fa2Sopenharmony_ci        BIO_free(p7Bio);
152fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
153fb299fa2Sopenharmony_ci        return -1;
154fb299fa2Sopenharmony_ci    }
155fb299fa2Sopenharmony_ci
156fb299fa2Sopenharmony_ci    BIO_free(p7Bio);
157fb299fa2Sopenharmony_ci    if (CertVerify::GetInstance().Init() != 0) {
158fb299fa2Sopenharmony_ci        PKG_LOGE("init cert verify fail");
159fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
160fb299fa2Sopenharmony_ci        return -1;
161fb299fa2Sopenharmony_ci    }
162fb299fa2Sopenharmony_ci    return 0;
163fb299fa2Sopenharmony_ci}
164fb299fa2Sopenharmony_ci
165fb299fa2Sopenharmony_ci/*
166fb299fa2Sopenharmony_ci * tools.ietf.org/html/rfc2315#section-9.1
167fb299fa2Sopenharmony_ci * SignedData ::= SEQUENCE(0x30) {
168fb299fa2Sopenharmony_ci *     INTEGER(0x02)            version Version,
169fb299fa2Sopenharmony_ci *     SET(0x31)                digestAlgorithms DigestAlgorithmIdentifiers,
170fb299fa2Sopenharmony_ci *     SEQUENCE(0x30)           contentInfo ContentInfo,
171fb299fa2Sopenharmony_ci *     CONTET_SPECIFIC[0](0xA0) certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL,
172fb299fa2Sopenharmony_ci *     CONTET_SPECIFIC[1](0xA1) crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
173fb299fa2Sopenharmony_ci *     SET(0x31)                signerInfos SignerInfos }
174fb299fa2Sopenharmony_ci */
175fb299fa2Sopenharmony_ciint32_t Pkcs7SignedData::DoParse()
176fb299fa2Sopenharmony_ci{
177fb299fa2Sopenharmony_ci    std::vector<uint8_t> contentInfo;
178fb299fa2Sopenharmony_ci    int32_t ret = ParseContentInfo(contentInfo);
179fb299fa2Sopenharmony_ci    if (ret != 0) {
180fb299fa2Sopenharmony_ci        PKG_LOGE("parse pkcs7 contentInfo fail");
181fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
182fb299fa2Sopenharmony_ci        return -1;
183fb299fa2Sopenharmony_ci    }
184fb299fa2Sopenharmony_ci
185fb299fa2Sopenharmony_ci    if (GetInstance().GetDigest(contentInfo, signatureInfo, digest_) != 0) {
186fb299fa2Sopenharmony_ci        ret = GetDigestFromContentInfo(contentInfo);
187fb299fa2Sopenharmony_ci        if (ret != 0) {
188fb299fa2Sopenharmony_ci            PKG_LOGE("invalid pkcs7 contentInfo fail");
189fb299fa2Sopenharmony_ci            UPDATER_LAST_WORD(-1);
190fb299fa2Sopenharmony_ci            return -1;
191fb299fa2Sopenharmony_ci        }
192fb299fa2Sopenharmony_ci    }
193fb299fa2Sopenharmony_ci
194fb299fa2Sopenharmony_ci    return SignerInfosParse();
195fb299fa2Sopenharmony_ci}
196fb299fa2Sopenharmony_ci
197fb299fa2Sopenharmony_ci/*
198fb299fa2Sopenharmony_ci * tools.ietf.org/html/rfc2315#section-7
199fb299fa2Sopenharmony_ci * ContentInfo ::= SEQUENCE(0x30) {
200fb299fa2Sopenharmony_ci *     OBJECT_IDENTIFIER(0x06)  contentType ContentType,
201fb299fa2Sopenharmony_ci *     CONTET_SPECIFIC[0](0xA0) content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
202fb299fa2Sopenharmony_ci *
203fb299fa2Sopenharmony_ci * tools.ietf.org/html/rfc2315#section-8
204fb299fa2Sopenharmony_ci *     Data ::= OCTET STRING
205fb299fa2Sopenharmony_ci */
206fb299fa2Sopenharmony_ciint32_t Pkcs7SignedData::ParseContentInfo(std::vector<uint8_t> &digestBlock) const
207fb299fa2Sopenharmony_ci{
208fb299fa2Sopenharmony_ci    Updater::UPDATER_INIT_RECORD;
209fb299fa2Sopenharmony_ci    PKCS7_SIGNED *signData = pkcs7_->d.sign;
210fb299fa2Sopenharmony_ci    if (signData == nullptr) {
211fb299fa2Sopenharmony_ci        PKG_LOGE("invalid pkcs7 signed data!");
212fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
213fb299fa2Sopenharmony_ci        return -1;
214fb299fa2Sopenharmony_ci    }
215fb299fa2Sopenharmony_ci
216fb299fa2Sopenharmony_ci    PKCS7 *contentInfo = signData->contents;
217fb299fa2Sopenharmony_ci    if (contentInfo == nullptr) {
218fb299fa2Sopenharmony_ci        PKG_LOGE("pkcs7 content is nullptr!");
219fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
220fb299fa2Sopenharmony_ci        return -1;
221fb299fa2Sopenharmony_ci    }
222fb299fa2Sopenharmony_ci    if (OBJ_obj2nid(contentInfo->type) != NID_pkcs7_data) {
223fb299fa2Sopenharmony_ci        PKG_LOGE("invalid pkcs7 signed data type");
224fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
225fb299fa2Sopenharmony_ci        return -1;
226fb299fa2Sopenharmony_ci    }
227fb299fa2Sopenharmony_ci
228fb299fa2Sopenharmony_ci    if (GetASN1OctetStringData(contentInfo->d.data, digestBlock) != 0) {
229fb299fa2Sopenharmony_ci        PKG_LOGE("get pkcs7 contentInfo fail");
230fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
231fb299fa2Sopenharmony_ci        return -1;
232fb299fa2Sopenharmony_ci    }
233fb299fa2Sopenharmony_ci
234fb299fa2Sopenharmony_ci    return 0;
235fb299fa2Sopenharmony_ci}
236fb299fa2Sopenharmony_ci
237fb299fa2Sopenharmony_ciint32_t Pkcs7SignedData::GetDigestFromContentInfo(std::vector<uint8_t> &digestBlock)
238fb299fa2Sopenharmony_ci{
239fb299fa2Sopenharmony_ci    Updater::UPDATER_INIT_RECORD;
240fb299fa2Sopenharmony_ci    if (digestBlock.size() <= sizeof(uint32_t)) {
241fb299fa2Sopenharmony_ci        PKG_LOGE("invalid digest block info.");
242fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
243fb299fa2Sopenharmony_ci        return -1;
244fb299fa2Sopenharmony_ci    }
245fb299fa2Sopenharmony_ci
246fb299fa2Sopenharmony_ci    size_t offset = 0;
247fb299fa2Sopenharmony_ci    size_t algoId = static_cast<size_t>(ReadLE16(digestBlock.data() + offset));
248fb299fa2Sopenharmony_ci    offset += static_cast<size_t>(sizeof(uint16_t));
249fb299fa2Sopenharmony_ci    size_t digestLen = static_cast<size_t>(ReadLE16(digestBlock.data() + offset));
250fb299fa2Sopenharmony_ci    offset += static_cast<size_t>(sizeof(uint16_t));
251fb299fa2Sopenharmony_ci    if ((GetDigestLength(algoId) != digestLen) || ((digestLen + offset) != digestBlock.size())) {
252fb299fa2Sopenharmony_ci        PKG_LOGE("invalid digestLen[%zu] and digestBlock len[%zu]", digestLen, digestBlock.size());
253fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
254fb299fa2Sopenharmony_ci        return -1;
255fb299fa2Sopenharmony_ci    }
256fb299fa2Sopenharmony_ci    digest_.assign(digestBlock.begin() + offset, digestBlock.end());
257fb299fa2Sopenharmony_ci    return 0;
258fb299fa2Sopenharmony_ci}
259fb299fa2Sopenharmony_ci
260fb299fa2Sopenharmony_ciPkcs7SignedData &Pkcs7SignedData::GetInstance()
261fb299fa2Sopenharmony_ci{
262fb299fa2Sopenharmony_ci    static Pkcs7SignedData checkPackagesInfo;
263fb299fa2Sopenharmony_ci    return checkPackagesInfo;
264fb299fa2Sopenharmony_ci}
265fb299fa2Sopenharmony_ci
266fb299fa2Sopenharmony_ciextern "C" __attribute__((constructor)) void RegisterVerifyHelper(void)
267fb299fa2Sopenharmony_ci{
268fb299fa2Sopenharmony_ci    Pkcs7SignedData::GetInstance().RegisterVerifyHelper(std::make_unique<Pkcs7VerifyHelper>());
269fb299fa2Sopenharmony_ci}
270fb299fa2Sopenharmony_ci
271fb299fa2Sopenharmony_civoid Pkcs7SignedData::RegisterVerifyHelper(std::unique_ptr<VerifyHelper> ptr)
272fb299fa2Sopenharmony_ci{
273fb299fa2Sopenharmony_ci    helper_ = std::move(ptr);
274fb299fa2Sopenharmony_ci}
275fb299fa2Sopenharmony_ci
276fb299fa2Sopenharmony_ciPkcs7VerifyHelper::~Pkcs7VerifyHelper()
277fb299fa2Sopenharmony_ci{
278fb299fa2Sopenharmony_ci    return;
279fb299fa2Sopenharmony_ci}
280fb299fa2Sopenharmony_ci
281fb299fa2Sopenharmony_ciint32_t Pkcs7VerifyHelper::GetDigestFromSubBlocks(std::vector<uint8_t> &digestBlock,
282fb299fa2Sopenharmony_ci    HwSigningSigntureInfo &signatureInfo, std::vector<uint8_t> &digest)
283fb299fa2Sopenharmony_ci{
284fb299fa2Sopenharmony_ci    PKG_LOGE("Pkcs7VerifyHelper in");
285fb299fa2Sopenharmony_ci    return -1;
286fb299fa2Sopenharmony_ci}
287fb299fa2Sopenharmony_ci
288fb299fa2Sopenharmony_ciint32_t Pkcs7SignedData::GetDigest(std::vector<uint8_t> &digestBlock,
289fb299fa2Sopenharmony_ci    HwSigningSigntureInfo &signatureInfo, std::vector<uint8_t> &digest)
290fb299fa2Sopenharmony_ci{
291fb299fa2Sopenharmony_ci    if (helper_ == nullptr) {
292fb299fa2Sopenharmony_ci        PKG_LOGE("helper_ null error");
293fb299fa2Sopenharmony_ci        return -1;
294fb299fa2Sopenharmony_ci    }
295fb299fa2Sopenharmony_ci    return helper_->GetDigestFromSubBlocks(digestBlock, signatureInfo, digest);
296fb299fa2Sopenharmony_ci}
297fb299fa2Sopenharmony_ci
298fb299fa2Sopenharmony_ci/*
299fb299fa2Sopenharmony_ci * tools.ietf.org/html/rfc2315#section-9.2
300fb299fa2Sopenharmony_ci * SignerInfo ::= SEQUENCE(0x30) {
301fb299fa2Sopenharmony_ci *     INTEGER(0x02)             version Version,
302fb299fa2Sopenharmony_ci *     SEQUENCE(0x30)            issuerAndSerialNumber IssuerAndSerialNumber,
303fb299fa2Sopenharmony_ci *     SEQUENCE(0x30)            digestAlgorithm DigestAlgorithmIdentifier,
304fb299fa2Sopenharmony_ci *     CONTET_SPECIFIC[0](0xA0)  authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,
305fb299fa2Sopenharmony_ci *     SEQUENCE(0x30)            digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
306fb299fa2Sopenharmony_ci *     OCTET_STRING(0x30)        encryptedDigest EncryptedDigest,
307fb299fa2Sopenharmony_ci *     CONTET_SPECIFIC[1](0xA1)  unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL }
308fb299fa2Sopenharmony_ci */
309fb299fa2Sopenharmony_ciint32_t Pkcs7SignedData::ReadSig(const uint8_t *sourceData, const uint32_t sourceDataLen,
310fb299fa2Sopenharmony_ci    std::vector<std::vector<uint8_t>> &sigs)
311fb299fa2Sopenharmony_ci{
312fb299fa2Sopenharmony_ci    if (sourceData == nullptr || sourceDataLen == 0) {
313fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(PKCS7_INVALID_PARAM_ERR);
314fb299fa2Sopenharmony_ci        return PKCS7_INVALID_PARAM_ERR;
315fb299fa2Sopenharmony_ci    }
316fb299fa2Sopenharmony_ci    if (Init(sourceData, sourceDataLen) != 0) {
317fb299fa2Sopenharmony_ci        PKG_LOGE("init pkcs7 data fail");
318fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(PKCS7_INIT_ERR);
319fb299fa2Sopenharmony_ci        return PKCS7_INIT_ERR;
320fb299fa2Sopenharmony_ci    }
321fb299fa2Sopenharmony_ci    STACK_OF(PKCS7_SIGNER_INFO) *p7SignerInfos = PKCS7_get_signer_info(pkcs7_);
322fb299fa2Sopenharmony_ci    if (p7SignerInfos == nullptr) {
323fb299fa2Sopenharmony_ci        PKG_LOGE("get pkcs7 signers failed!");
324fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(PKCS7_INVALID_VALUE_ERR);
325fb299fa2Sopenharmony_ci        return PKCS7_INVALID_VALUE_ERR;
326fb299fa2Sopenharmony_ci    }
327fb299fa2Sopenharmony_ci    int signerInfoNum = sk_PKCS7_SIGNER_INFO_num(p7SignerInfos);
328fb299fa2Sopenharmony_ci    if (signerInfoNum <= 0) {
329fb299fa2Sopenharmony_ci        PKG_LOGE("invalid signers info num %d!", signerInfoNum);
330fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(PKCS7_INVALID_VALUE_ERR);
331fb299fa2Sopenharmony_ci        return PKCS7_INVALID_VALUE_ERR;
332fb299fa2Sopenharmony_ci    }
333fb299fa2Sopenharmony_ci    for (int i = 0; i < signerInfoNum; i++) {
334fb299fa2Sopenharmony_ci        PKCS7_SIGNER_INFO *p7SiTmp = sk_PKCS7_SIGNER_INFO_value(p7SignerInfos, i);
335fb299fa2Sopenharmony_ci        Pkcs7SignerInfo signer;
336fb299fa2Sopenharmony_ci        int32_t ret = SignerInfoParse(p7SiTmp, signer);
337fb299fa2Sopenharmony_ci        if (ret != 0) {
338fb299fa2Sopenharmony_ci            PKG_LOGE("SignerInfo Parse failed!");
339fb299fa2Sopenharmony_ci            continue;
340fb299fa2Sopenharmony_ci        }
341fb299fa2Sopenharmony_ci        sigs.push_back(signer.digestEncryptData);
342fb299fa2Sopenharmony_ci    }
343fb299fa2Sopenharmony_ci    if (sigs.size() == 0) {
344fb299fa2Sopenharmony_ci        PKG_LOGE("no valid sigs!");
345fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(PKCS7_HAS_NO_VALID_SIG_ERR);
346fb299fa2Sopenharmony_ci        return PKCS7_HAS_NO_VALID_SIG_ERR;
347fb299fa2Sopenharmony_ci    }
348fb299fa2Sopenharmony_ci    return PKCS7_SUCCESS;
349fb299fa2Sopenharmony_ci}
350fb299fa2Sopenharmony_ci
351fb299fa2Sopenharmony_ciint32_t Pkcs7SignedData::SignerInfosParse()
352fb299fa2Sopenharmony_ci{
353fb299fa2Sopenharmony_ci    Updater::UPDATER_INIT_RECORD;
354fb299fa2Sopenharmony_ci    STACK_OF(PKCS7_SIGNER_INFO) *p7SignerInfos = PKCS7_get_signer_info(pkcs7_);
355fb299fa2Sopenharmony_ci    if (p7SignerInfos == nullptr) {
356fb299fa2Sopenharmony_ci        PKG_LOGE("get pkcs7 signers info failed!");
357fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
358fb299fa2Sopenharmony_ci        return -1;
359fb299fa2Sopenharmony_ci    }
360fb299fa2Sopenharmony_ci
361fb299fa2Sopenharmony_ci    int signerInfoNum = sk_PKCS7_SIGNER_INFO_num(p7SignerInfos);
362fb299fa2Sopenharmony_ci    if (signerInfoNum <= 0) {
363fb299fa2Sopenharmony_ci        PKG_LOGE("invalid signers info num %d!", signerInfoNum);
364fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
365fb299fa2Sopenharmony_ci        return -1;
366fb299fa2Sopenharmony_ci    }
367fb299fa2Sopenharmony_ci
368fb299fa2Sopenharmony_ci    for (int i = 0; i < signerInfoNum; i++) {
369fb299fa2Sopenharmony_ci        PKCS7_SIGNER_INFO *p7SiTmp = sk_PKCS7_SIGNER_INFO_value(p7SignerInfos, i);
370fb299fa2Sopenharmony_ci        Pkcs7SignerInfo signer;
371fb299fa2Sopenharmony_ci        int32_t ret = SignerInfoParse(p7SiTmp, signer);
372fb299fa2Sopenharmony_ci        if (ret != 0) {
373fb299fa2Sopenharmony_ci            PKG_LOGE("SignerInfoParse failed!");
374fb299fa2Sopenharmony_ci            continue;
375fb299fa2Sopenharmony_ci        }
376fb299fa2Sopenharmony_ci        signerInfos_.push_back(std::move(signer));
377fb299fa2Sopenharmony_ci    }
378fb299fa2Sopenharmony_ci
379fb299fa2Sopenharmony_ci    return 0;
380fb299fa2Sopenharmony_ci}
381fb299fa2Sopenharmony_ci
382fb299fa2Sopenharmony_ciint32_t Pkcs7SignedData::SignerInfoParse(PKCS7_SIGNER_INFO *p7SignerInfo, Pkcs7SignerInfo &signerInfo)
383fb299fa2Sopenharmony_ci{
384fb299fa2Sopenharmony_ci    if (p7SignerInfo == nullptr) {
385fb299fa2Sopenharmony_ci        return -1;
386fb299fa2Sopenharmony_ci    }
387fb299fa2Sopenharmony_ci    PKCS7_ISSUER_AND_SERIAL *p7IssuerAndSerial = p7SignerInfo->issuer_and_serial;
388fb299fa2Sopenharmony_ci    if (p7IssuerAndSerial == nullptr) {
389fb299fa2Sopenharmony_ci        PKG_LOGE("signer cert info is nullptr!");
390fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
391fb299fa2Sopenharmony_ci        return -1;
392fb299fa2Sopenharmony_ci    }
393fb299fa2Sopenharmony_ci    signerInfo.issuerName = p7IssuerAndSerial->issuer;
394fb299fa2Sopenharmony_ci    signerInfo.serialNumber = p7IssuerAndSerial->serial;
395fb299fa2Sopenharmony_ci
396fb299fa2Sopenharmony_ci    int32_t ret = GetX509AlgorithmNid(p7SignerInfo->digest_alg, signerInfo.digestNid);
397fb299fa2Sopenharmony_ci    if (ret != 0) {
398fb299fa2Sopenharmony_ci        PKG_LOGE("Parse signer info digest_alg failed!");
399fb299fa2Sopenharmony_ci        return ret;
400fb299fa2Sopenharmony_ci    }
401fb299fa2Sopenharmony_ci    ret = GetX509AlgorithmNid(p7SignerInfo->digest_enc_alg, signerInfo.digestEncryptNid);
402fb299fa2Sopenharmony_ci    if (ret != 0) {
403fb299fa2Sopenharmony_ci        PKG_LOGE("Parse signer info digest_enc_alg failed!");
404fb299fa2Sopenharmony_ci        return ret;
405fb299fa2Sopenharmony_ci    }
406fb299fa2Sopenharmony_ci
407fb299fa2Sopenharmony_ci    ret = GetASN1OctetStringData(p7SignerInfo->enc_digest, signerInfo.digestEncryptData);
408fb299fa2Sopenharmony_ci    if (ret != 0) {
409fb299fa2Sopenharmony_ci        PKG_LOGE("parse signer info enc_digest failed!");
410fb299fa2Sopenharmony_ci        return ret;
411fb299fa2Sopenharmony_ci    }
412fb299fa2Sopenharmony_ci
413fb299fa2Sopenharmony_ci    return 0;
414fb299fa2Sopenharmony_ci}
415fb299fa2Sopenharmony_ci
416fb299fa2Sopenharmony_ciint32_t Pkcs7SignedData::Pkcs7SignleSignerVerify(const Pkcs7SignerInfo &signerInfo, const std::vector<uint8_t> &hash,
417fb299fa2Sopenharmony_ci    const std::vector<uint8_t> &sig) const
418fb299fa2Sopenharmony_ci{
419fb299fa2Sopenharmony_ci    if (pkcs7_ == nullptr) {
420fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
421fb299fa2Sopenharmony_ci        return -1;
422fb299fa2Sopenharmony_ci    }
423fb299fa2Sopenharmony_ci    STACK_OF(X509) *certStack = pkcs7_->d.sign->cert;
424fb299fa2Sopenharmony_ci    if (certStack == nullptr) {
425fb299fa2Sopenharmony_ci        PKG_LOGE("certStack is empty!");
426fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
427fb299fa2Sopenharmony_ci        return -1;
428fb299fa2Sopenharmony_ci    }
429fb299fa2Sopenharmony_ci
430fb299fa2Sopenharmony_ci    X509 *cert = X509_find_by_issuer_and_serial(certStack, signerInfo.issuerName, signerInfo.serialNumber);
431fb299fa2Sopenharmony_ci    if (cert == nullptr) {
432fb299fa2Sopenharmony_ci        PKG_LOGE("cert is empty");
433fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
434fb299fa2Sopenharmony_ci        return -1;
435fb299fa2Sopenharmony_ci    }
436fb299fa2Sopenharmony_ci
437fb299fa2Sopenharmony_ci    if (CertVerify::GetInstance().CheckCertChain(certStack, cert) != 0) {
438fb299fa2Sopenharmony_ci        PKG_LOGE("public cert check fail");
439fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
440fb299fa2Sopenharmony_ci        return -1;
441fb299fa2Sopenharmony_ci    }
442fb299fa2Sopenharmony_ci
443fb299fa2Sopenharmony_ci    return VerifyDigest(cert, signerInfo, hash, sig);
444fb299fa2Sopenharmony_ci}
445fb299fa2Sopenharmony_ci
446fb299fa2Sopenharmony_ciint32_t Pkcs7SignedData::VerifyDigest(X509 *cert, const Pkcs7SignerInfo &signer, const std::vector<uint8_t> &hash,
447fb299fa2Sopenharmony_ci    const std::vector<uint8_t> &sig) const
448fb299fa2Sopenharmony_ci{
449fb299fa2Sopenharmony_ci    Updater::UPDATER_INIT_RECORD;
450fb299fa2Sopenharmony_ci    if (cert == nullptr) {
451fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
452fb299fa2Sopenharmony_ci        return -1;
453fb299fa2Sopenharmony_ci    }
454fb299fa2Sopenharmony_ci
455fb299fa2Sopenharmony_ci    EVP_PKEY *pubKey = X509_get_pubkey(cert);
456fb299fa2Sopenharmony_ci    if (pubKey == nullptr) {
457fb299fa2Sopenharmony_ci        PKG_LOGE("get pubkey from cert fail");
458fb299fa2Sopenharmony_ci        UPDATER_LAST_WORD(-1);
459fb299fa2Sopenharmony_ci        return -1;
460fb299fa2Sopenharmony_ci    }
461fb299fa2Sopenharmony_ci
462fb299fa2Sopenharmony_ci    auto ret = VerifyDigestByPubKey(pubKey, signer.digestNid, hash, sig);
463fb299fa2Sopenharmony_ci    EVP_PKEY_free(pubKey);
464fb299fa2Sopenharmony_ci    return ret;
465fb299fa2Sopenharmony_ci}
466fb299fa2Sopenharmony_ci} // namespace Hpackage
467