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