154aa6d63Sopenharmony_ci/* 254aa6d63Sopenharmony_ci * Copyright (c) 2024-2024 Huawei Device Co., Ltd. 354aa6d63Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 454aa6d63Sopenharmony_ci * you may not use this file except in compliance with the License. 554aa6d63Sopenharmony_ci * You may obtain a copy of the License at 654aa6d63Sopenharmony_ci * 754aa6d63Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 854aa6d63Sopenharmony_ci * 954aa6d63Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1054aa6d63Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1154aa6d63Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1254aa6d63Sopenharmony_ci * See the License for the specific language governing permissions and 1354aa6d63Sopenharmony_ci * limitations under the License. 1454aa6d63Sopenharmony_ci */ 1554aa6d63Sopenharmony_ci 1654aa6d63Sopenharmony_ci#include "signature_tools_log.h" 1754aa6d63Sopenharmony_ci#include "signature_tools_errno.h" 1854aa6d63Sopenharmony_ci#include "verify_hap_openssl_utils.h" 1954aa6d63Sopenharmony_ci#include "signer.h" 2054aa6d63Sopenharmony_ci#include "securec.h" 2154aa6d63Sopenharmony_ci#include "constant.h" 2254aa6d63Sopenharmony_ci#include "pkcs7_data.h" 2354aa6d63Sopenharmony_ci 2454aa6d63Sopenharmony_cinamespace OHOS { 2554aa6d63Sopenharmony_cinamespace SignatureTools { 2654aa6d63Sopenharmony_ci 2754aa6d63Sopenharmony_cistatic constexpr int BUFFER_SIZE = 4096; 2854aa6d63Sopenharmony_ci 2954aa6d63Sopenharmony_cistatic int PKCS7AddAttribute(PKCS7* p7, const std::vector<PKCS7Attr>& attrs) 3054aa6d63Sopenharmony_ci{ 3154aa6d63Sopenharmony_ci STACK_OF(PKCS7_SIGNER_INFO)* signerInfos = PKCS7_get_signer_info(p7); 3254aa6d63Sopenharmony_ci if (signerInfos == NULL || sk_PKCS7_SIGNER_INFO_num(signerInfos) != 1) { 3354aa6d63Sopenharmony_ci PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR, 3454aa6d63Sopenharmony_ci "signer info count not equal 1,pkcs7 add customize attribute failed"); 3554aa6d63Sopenharmony_ci return INVALIDPARAM_ERROR; 3654aa6d63Sopenharmony_ci } 3754aa6d63Sopenharmony_ci PKCS7_SIGNER_INFO* signerInfo = sk_PKCS7_SIGNER_INFO_value(signerInfos, 0); 3854aa6d63Sopenharmony_ci for (PKCS7Attr attr : attrs) { 3954aa6d63Sopenharmony_ci if (PKCS7_add_signed_attribute(signerInfo, attr.nid, attr.atrtype, attr.value) != 1) { 4054aa6d63Sopenharmony_ci if (attr.atrtype == V_ASN1_UTF8STRING) 4154aa6d63Sopenharmony_ci ASN1_STRING_free(reinterpret_cast<ASN1_STRING*>(attr.value)); 4254aa6d63Sopenharmony_ci PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR, 4354aa6d63Sopenharmony_ci "pkcs7 add customize attribute failed"); 4454aa6d63Sopenharmony_ci return RET_FAILED; 4554aa6d63Sopenharmony_ci } 4654aa6d63Sopenharmony_ci } 4754aa6d63Sopenharmony_ci return RET_OK; 4854aa6d63Sopenharmony_ci} 4954aa6d63Sopenharmony_ci 5054aa6d63Sopenharmony_cistatic int I2dPkcs7Str(PKCS7* p7, std::string& ret) 5154aa6d63Sopenharmony_ci{ 5254aa6d63Sopenharmony_ci /* raw data exported in pkcs7 */ 5354aa6d63Sopenharmony_ci unsigned char* out = NULL; 5454aa6d63Sopenharmony_ci int outSize = 0; 5554aa6d63Sopenharmony_ci /* Deserialize to obtain the p7b byte stream */ 5654aa6d63Sopenharmony_ci outSize = i2d_PKCS7(p7, &out); 5754aa6d63Sopenharmony_ci if (out == NULL || outSize <= 0) { 5854aa6d63Sopenharmony_ci PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR, 5954aa6d63Sopenharmony_ci "pkcs7 is invalid"); 6054aa6d63Sopenharmony_ci return INVALIDPARAM_ERROR; 6154aa6d63Sopenharmony_ci } 6254aa6d63Sopenharmony_ci ret.clear(); 6354aa6d63Sopenharmony_ci ret.resize(outSize); 6454aa6d63Sopenharmony_ci std::copy(out, out + outSize, &ret[0]); 6554aa6d63Sopenharmony_ci OPENSSL_free(out); 6654aa6d63Sopenharmony_ci return RET_OK; 6754aa6d63Sopenharmony_ci} 6854aa6d63Sopenharmony_ci 6954aa6d63Sopenharmony_cistatic int SetSignerInfoSignAlgor(PKCS7_SIGNER_INFO* info) 7054aa6d63Sopenharmony_ci{ 7154aa6d63Sopenharmony_ci int signNid = 0; 7254aa6d63Sopenharmony_ci int hashNid = 0; 7354aa6d63Sopenharmony_ci X509_ALGOR* dig; 7454aa6d63Sopenharmony_ci X509_ALGOR* sig; 7554aa6d63Sopenharmony_ci PKCS7_SIGNER_INFO_get0_algs(info, NULL, &dig, &sig); 7654aa6d63Sopenharmony_ci if (dig == NULL || dig->algorithm == NULL || 7754aa6d63Sopenharmony_ci (hashNid = OBJ_obj2nid(dig->algorithm)) == NID_undef || 7854aa6d63Sopenharmony_ci !OBJ_find_sigid_by_algs(&signNid, hashNid, NID_X9_62_id_ecPublicKey) || 7954aa6d63Sopenharmony_ci X509_ALGOR_set0(sig, OBJ_nid2obj(signNid), V_ASN1_UNDEF, 0) != 1) { 8054aa6d63Sopenharmony_ci return 0; 8154aa6d63Sopenharmony_ci } 8254aa6d63Sopenharmony_ci return 1; 8354aa6d63Sopenharmony_ci} 8454aa6d63Sopenharmony_ci 8554aa6d63Sopenharmony_cistatic int VerifySignature(PKCS7* pkcs7, BIO* p7bio) 8654aa6d63Sopenharmony_ci{ 8754aa6d63Sopenharmony_ci /* signature information */ 8854aa6d63Sopenharmony_ci STACK_OF(PKCS7_SIGNER_INFO)* skSignerInfo = NULL; 8954aa6d63Sopenharmony_ci /* signature count */ 9054aa6d63Sopenharmony_ci int signerCount = 0; 9154aa6d63Sopenharmony_ci /* verify signature value */ 9254aa6d63Sopenharmony_ci skSignerInfo = PKCS7_get_signer_info(pkcs7); 9354aa6d63Sopenharmony_ci signerCount = sk_PKCS7_SIGNER_INFO_num(skSignerInfo); 9454aa6d63Sopenharmony_ci for (int i = 0; i < signerCount; i++) { 9554aa6d63Sopenharmony_ci PKCS7_SIGNER_INFO* signerInfo = sk_PKCS7_SIGNER_INFO_value(skSignerInfo, i); 9654aa6d63Sopenharmony_ci X509* sigCert = PKCS7_cert_from_signer_info(pkcs7, signerInfo); 9754aa6d63Sopenharmony_ci if (PKCS7_signatureVerify(p7bio, pkcs7, signerInfo, sigCert) != 1) { 9854aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "signature value verify failed"); 9954aa6d63Sopenharmony_ci return VERIFY_ERROR; 10054aa6d63Sopenharmony_ci } 10154aa6d63Sopenharmony_ci } 10254aa6d63Sopenharmony_ci return RET_OK; 10354aa6d63Sopenharmony_ci} 10454aa6d63Sopenharmony_ci 10554aa6d63Sopenharmony_ciPKCS7Data::PKCS7Data(int flags) : m_p7(nullptr), m_flags(flags) 10654aa6d63Sopenharmony_ci{ 10754aa6d63Sopenharmony_ci} 10854aa6d63Sopenharmony_ci 10954aa6d63Sopenharmony_ciPKCS7Data::~PKCS7Data() 11054aa6d63Sopenharmony_ci{ 11154aa6d63Sopenharmony_ci PKCS7_free(m_p7); 11254aa6d63Sopenharmony_ci m_p7 = NULL; 11354aa6d63Sopenharmony_ci} 11454aa6d63Sopenharmony_ci 11554aa6d63Sopenharmony_ciint PKCS7Data::Sign(const std::string& content, const std::shared_ptr<Signer>& signer, 11654aa6d63Sopenharmony_ci const std::string& sigAlg, std::string& ret, std::vector<PKCS7Attr> attrs) 11754aa6d63Sopenharmony_ci{ 11854aa6d63Sopenharmony_ci int result = RET_OK; 11954aa6d63Sopenharmony_ci if ((result = InitPkcs7(content, signer, sigAlg, attrs)) < 0) { 12054aa6d63Sopenharmony_ci goto err; 12154aa6d63Sopenharmony_ci } 12254aa6d63Sopenharmony_ci 12354aa6d63Sopenharmony_ci /* serialization */ 12454aa6d63Sopenharmony_ci if ((result = I2dPkcs7Str(m_p7, ret)) < 0) { 12554aa6d63Sopenharmony_ci goto err; 12654aa6d63Sopenharmony_ci } 12754aa6d63Sopenharmony_ci /* release resources */ 12854aa6d63Sopenharmony_cierr: 12954aa6d63Sopenharmony_ci if (result < 0) { 13054aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("sign failed"); 13154aa6d63Sopenharmony_ci } 13254aa6d63Sopenharmony_ci return result; 13354aa6d63Sopenharmony_ci} 13454aa6d63Sopenharmony_ci 13554aa6d63Sopenharmony_ciint PKCS7Data::Parse(const std::string& p7bBytes) 13654aa6d63Sopenharmony_ci{ 13754aa6d63Sopenharmony_ci const unsigned char* data = reinterpret_cast<const unsigned char*>(&p7bBytes[0]); 13854aa6d63Sopenharmony_ci return Parse(&data, static_cast<long>(p7bBytes.size())); 13954aa6d63Sopenharmony_ci} 14054aa6d63Sopenharmony_ciint PKCS7Data::Parse(const std::vector<int8_t>& p7bBytes) 14154aa6d63Sopenharmony_ci{ 14254aa6d63Sopenharmony_ci const unsigned char* data = reinterpret_cast<const unsigned char*>(&p7bBytes[0]); 14354aa6d63Sopenharmony_ci return Parse(&data, static_cast<long>(p7bBytes.size())); 14454aa6d63Sopenharmony_ci} 14554aa6d63Sopenharmony_ciint PKCS7Data::Parse(const unsigned char** in, long len) 14654aa6d63Sopenharmony_ci{ 14754aa6d63Sopenharmony_ci /* If p7 has been initialized, it will be released */ 14854aa6d63Sopenharmony_ci if (m_p7) { 14954aa6d63Sopenharmony_ci PKCS7_free(m_p7); 15054aa6d63Sopenharmony_ci m_p7 = NULL; 15154aa6d63Sopenharmony_ci } 15254aa6d63Sopenharmony_ci /* Deserialize */ 15354aa6d63Sopenharmony_ci m_p7 = d2i_PKCS7(NULL, in, len); 15454aa6d63Sopenharmony_ci if (m_p7 == NULL) { 15554aa6d63Sopenharmony_ci PrintErrorNumberMsg("PARSE_ERROR", PARSE_ERROR, "invalid p7b data, parse failed"); 15654aa6d63Sopenharmony_ci return PARSE_ERROR; 15754aa6d63Sopenharmony_ci } 15854aa6d63Sopenharmony_ci return RET_OK; 15954aa6d63Sopenharmony_ci} 16054aa6d63Sopenharmony_ci 16154aa6d63Sopenharmony_ciint PKCS7Data::Verify(const std::string& content) const 16254aa6d63Sopenharmony_ci{ 16354aa6d63Sopenharmony_ci if (VerifySign(content) < 0) { 16454aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "signature verify failed"); 16554aa6d63Sopenharmony_ci return VERIFY_ERROR; 16654aa6d63Sopenharmony_ci } 16754aa6d63Sopenharmony_ci if (VerifyCertChain() < 0) { 16854aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "cert Chain verify failed"); 16954aa6d63Sopenharmony_ci PrintCertChainSub(m_p7->d.sign->cert); 17054aa6d63Sopenharmony_ci return VERIFY_ERROR; 17154aa6d63Sopenharmony_ci } 17254aa6d63Sopenharmony_ci return RET_OK; 17354aa6d63Sopenharmony_ci} 17454aa6d63Sopenharmony_ci 17554aa6d63Sopenharmony_ciint PKCS7Data::GetContent(std::string& originalRawData) const 17654aa6d63Sopenharmony_ci{ 17754aa6d63Sopenharmony_ci BIO* oriBio = PKCS7_dataDecode(m_p7, NULL, NULL, NULL); 17854aa6d63Sopenharmony_ci if (oriBio == NULL) { 17954aa6d63Sopenharmony_ci PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR, "pkcs7 get content data failed!"); 18054aa6d63Sopenharmony_ci return INVALIDPARAM_ERROR; 18154aa6d63Sopenharmony_ci } 18254aa6d63Sopenharmony_ci char buf[BUFFER_SIZE]{0}; 18354aa6d63Sopenharmony_ci size_t readBytes = 0; 18454aa6d63Sopenharmony_ci while (BIO_read_ex(oriBio, buf, sizeof(buf), &readBytes) == 1) { 18554aa6d63Sopenharmony_ci originalRawData.append(buf, readBytes); 18654aa6d63Sopenharmony_ci } 18754aa6d63Sopenharmony_ci BIO_free_all(oriBio); 18854aa6d63Sopenharmony_ci return RET_OK; 18954aa6d63Sopenharmony_ci} 19054aa6d63Sopenharmony_ci 19154aa6d63Sopenharmony_cistatic void PKCS7AddCrls(PKCS7* p7, STACK_OF(X509_CRL)* crls) 19254aa6d63Sopenharmony_ci{ 19354aa6d63Sopenharmony_ci for (int i = 0; i < sk_X509_CRL_num(crls); i++) { 19454aa6d63Sopenharmony_ci PKCS7_add_crl(p7, sk_X509_CRL_value(crls, i)); 19554aa6d63Sopenharmony_ci } 19654aa6d63Sopenharmony_ci} 19754aa6d63Sopenharmony_ci 19854aa6d63Sopenharmony_ciint PKCS7Data::InitPkcs7(const std::string& content, const std::shared_ptr<Signer>& signer, 19954aa6d63Sopenharmony_ci const std::string& sigAlg, std::vector<PKCS7Attr> attrs) 20054aa6d63Sopenharmony_ci{ 20154aa6d63Sopenharmony_ci STACK_OF(X509)* certs = NULL; 20254aa6d63Sopenharmony_ci /* hash algorithm */ 20354aa6d63Sopenharmony_ci const EVP_MD* md = NULL; 20454aa6d63Sopenharmony_ci /* entity certificate */ 20554aa6d63Sopenharmony_ci X509* cert = NULL; 20654aa6d63Sopenharmony_ci int result = RET_OK; 20754aa6d63Sopenharmony_ci if (signer == NULL) { 20854aa6d63Sopenharmony_ci PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR, "signer is NULL , sign failed"); 20954aa6d63Sopenharmony_ci result = INVALIDPARAM_ERROR; 21054aa6d63Sopenharmony_ci goto err; 21154aa6d63Sopenharmony_ci } 21254aa6d63Sopenharmony_ci m_signer = signer; 21354aa6d63Sopenharmony_ci m_sigAlg = sigAlg; 21454aa6d63Sopenharmony_ci certs = signer->GetCertificates(); 21554aa6d63Sopenharmony_ci if (SortX509Stack(certs) < 0) { 21654aa6d63Sopenharmony_ci result = RET_FAILED; 21754aa6d63Sopenharmony_ci goto err; 21854aa6d63Sopenharmony_ci } 21954aa6d63Sopenharmony_ci if (sigAlg == SIGN_ALG_SHA384) { 22054aa6d63Sopenharmony_ci md = EVP_sha384(); 22154aa6d63Sopenharmony_ci } else if (sigAlg == SIGN_ALG_SHA256) { 22254aa6d63Sopenharmony_ci md = EVP_sha256(); 22354aa6d63Sopenharmony_ci } else { 22454aa6d63Sopenharmony_ci PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR, 22554aa6d63Sopenharmony_ci sigAlg + "is invalid sigAlg, please use SHA256withECDSA/SHA384withECDSA, sign failed"); 22654aa6d63Sopenharmony_ci result = INVALIDPARAM_ERROR; 22754aa6d63Sopenharmony_ci goto err; 22854aa6d63Sopenharmony_ci } 22954aa6d63Sopenharmony_ci /* Extract the entity certificate from the certificate chain */ 23054aa6d63Sopenharmony_ci cert = sk_X509_delete(certs, 0); 23154aa6d63Sopenharmony_ci m_p7 = Pkcs7Sign(cert, certs, md, content, m_flags, attrs); 23254aa6d63Sopenharmony_ci if (m_p7 == NULL) { 23354aa6d63Sopenharmony_ci PrintErrorNumberMsg("INVALIDPARAM_ERROR", SIGN_ERROR, "p7 is NULL, pkcs7 sign failed"); 23454aa6d63Sopenharmony_ci result = SIGN_ERROR; 23554aa6d63Sopenharmony_ci goto err; 23654aa6d63Sopenharmony_ci } 23754aa6d63Sopenharmony_ci PKCS7AddCrls(m_p7, signer->GetCrls()); 23854aa6d63Sopenharmony_ci 23954aa6d63Sopenharmony_cierr: 24054aa6d63Sopenharmony_ci sk_X509_pop_free(certs, X509_free); 24154aa6d63Sopenharmony_ci X509_free(cert); 24254aa6d63Sopenharmony_ci return result; 24354aa6d63Sopenharmony_ci} 24454aa6d63Sopenharmony_ci 24554aa6d63Sopenharmony_civoid PKCS7Data::PrintCertChainSub(const STACK_OF(X509)* certs) 24654aa6d63Sopenharmony_ci{ 24754aa6d63Sopenharmony_ci if (certs == NULL) 24854aa6d63Sopenharmony_ci return; 24954aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGI("certChainSubject:"); 25054aa6d63Sopenharmony_ci int certNum = sk_X509_num(certs); 25154aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGI("certNum%s", std::to_string(certNum).c_str()); 25254aa6d63Sopenharmony_ci for (int i = 0; i < certNum; i++) { 25354aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGI("certificate %s", std::to_string(i).c_str()); 25454aa6d63Sopenharmony_ci std::string sub; 25554aa6d63Sopenharmony_ci VerifyCertOpensslUtils::GetSubjectFromX509(sk_X509_value(certs, i), sub); 25654aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGI("%s", sub.c_str()); 25754aa6d63Sopenharmony_ci } 25854aa6d63Sopenharmony_ci} 25954aa6d63Sopenharmony_ci 26054aa6d63Sopenharmony_cistd::string PKCS7Data::GetASN1Time(const ASN1_TIME* tm) 26154aa6d63Sopenharmony_ci{ 26254aa6d63Sopenharmony_ci if (tm == NULL) { 26354aa6d63Sopenharmony_ci return ""; 26454aa6d63Sopenharmony_ci } 26554aa6d63Sopenharmony_ci /* Convert the ASN1_TIME structure to a standard tm structure. */ 26654aa6d63Sopenharmony_ci struct tm time; 26754aa6d63Sopenharmony_ci ASN1_TIME_to_tm(tm, &time); 26854aa6d63Sopenharmony_ci /* Convert to local time(considering the time zone) */ 26954aa6d63Sopenharmony_ci time_t t = mktime(&time); 27054aa6d63Sopenharmony_ci if (t < 0) { 27154aa6d63Sopenharmony_ci return ""; 27254aa6d63Sopenharmony_ci } 27354aa6d63Sopenharmony_ci struct tm* localTime = localtime(&t); 27454aa6d63Sopenharmony_ci if (localTime == nullptr) { 27554aa6d63Sopenharmony_ci return ""; 27654aa6d63Sopenharmony_ci } 27754aa6d63Sopenharmony_ci /* Print local time */ 27854aa6d63Sopenharmony_ci char buf[128] = {0}; 27954aa6d63Sopenharmony_ci if (sprintf_s(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d", 28054aa6d63Sopenharmony_ci localTime->tm_year + YEAR1900, localTime->tm_mon + 1, localTime->tm_mday, 28154aa6d63Sopenharmony_ci localTime->tm_hour, localTime->tm_min, localTime->tm_sec) == -1) { 28254aa6d63Sopenharmony_ci return ""; 28354aa6d63Sopenharmony_ci } 28454aa6d63Sopenharmony_ci return std::string(buf, strlen(buf)); 28554aa6d63Sopenharmony_ci} 28654aa6d63Sopenharmony_ci 28754aa6d63Sopenharmony_cibool PKCS7Data::X509NameCompare(const X509* cert, const X509* issuerCert) 28854aa6d63Sopenharmony_ci{ 28954aa6d63Sopenharmony_ci if (cert == nullptr || issuerCert == nullptr) { 29054aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, 29154aa6d63Sopenharmony_ci "input cert is NULL"); 29254aa6d63Sopenharmony_ci return false; 29354aa6d63Sopenharmony_ci } 29454aa6d63Sopenharmony_ci X509_NAME* aName = X509_get_issuer_name(cert); 29554aa6d63Sopenharmony_ci X509_NAME* bName = X509_get_subject_name(issuerCert); 29654aa6d63Sopenharmony_ci if (X509_NAME_cmp(aName, bName) != 0) { 29754aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, 29854aa6d63Sopenharmony_ci "cert issuer name is not equal to its issuer\'s name"); 29954aa6d63Sopenharmony_ci return false; 30054aa6d63Sopenharmony_ci } 30154aa6d63Sopenharmony_ci return true; 30254aa6d63Sopenharmony_ci} 30354aa6d63Sopenharmony_ci 30454aa6d63Sopenharmony_ciint PKCS7Data::CheckSignTimeInValidPeriod(const ASN1_TYPE* signTime, 30554aa6d63Sopenharmony_ci const ASN1_TIME* notBefore, const ASN1_TIME* notAfter) 30654aa6d63Sopenharmony_ci{ 30754aa6d63Sopenharmony_ci if (notBefore == nullptr || notBefore->data == nullptr || notAfter == nullptr || notAfter->data == nullptr) { 30854aa6d63Sopenharmony_ci PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR, 30954aa6d63Sopenharmony_ci "invalid period, check signtime failed please use valid period to to check signtime"); 31054aa6d63Sopenharmony_ci return INVALIDPARAM_ERROR; 31154aa6d63Sopenharmony_ci } 31254aa6d63Sopenharmony_ci if (signTime == nullptr || signTime->value.asn1_string == nullptr || 31354aa6d63Sopenharmony_ci signTime->value.asn1_string->data == nullptr) { 31454aa6d63Sopenharmony_ci PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR, "signtime is NULL"); 31554aa6d63Sopenharmony_ci return INVALIDPARAM_ERROR; 31654aa6d63Sopenharmony_ci } 31754aa6d63Sopenharmony_ci ASN1_TIME* tm = ASN1_TIME_new(); 31854aa6d63Sopenharmony_ci ASN1_TIME_set_string(tm, (reinterpret_cast<const char*>(signTime->value.asn1_string->data))); 31954aa6d63Sopenharmony_ci if (ASN1_TIME_compare(notBefore, signTime->value.asn1_string) > 0 || 32054aa6d63Sopenharmony_ci ASN1_TIME_compare(notAfter, signTime->value.asn1_string) < 0) { 32154aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("sign time invalid, signTime: %s, notBefore: %s, " 32254aa6d63Sopenharmony_ci "notAfter: %s", GetASN1Time(tm).c_str(), 32354aa6d63Sopenharmony_ci GetASN1Time(notBefore).c_str(), GetASN1Time(notAfter).c_str()); 32454aa6d63Sopenharmony_ci ASN1_TIME_free(tm); 32554aa6d63Sopenharmony_ci return RET_FAILED; 32654aa6d63Sopenharmony_ci } 32754aa6d63Sopenharmony_ci ASN1_TIME_free(tm); 32854aa6d63Sopenharmony_ci return RET_OK; 32954aa6d63Sopenharmony_ci} 33054aa6d63Sopenharmony_ci 33154aa6d63Sopenharmony_cistatic X509* FindSubCertThenEraseItFromSets(X509* cert, std::unordered_set<X509*>& x509Sets) 33254aa6d63Sopenharmony_ci{ 33354aa6d63Sopenharmony_ci X509* ret = NULL; 33454aa6d63Sopenharmony_ci for (X509* c : x509Sets) { 33554aa6d63Sopenharmony_ci X509_NAME* name1 = X509_get_subject_name(cert); 33654aa6d63Sopenharmony_ci X509_NAME* name2 = X509_get_issuer_name(c); 33754aa6d63Sopenharmony_ci if (X509_NAME_cmp(name1, name2) == 0) { 33854aa6d63Sopenharmony_ci x509Sets.erase(c); 33954aa6d63Sopenharmony_ci ret = c; 34054aa6d63Sopenharmony_ci break; 34154aa6d63Sopenharmony_ci } 34254aa6d63Sopenharmony_ci } 34354aa6d63Sopenharmony_ci return ret; 34454aa6d63Sopenharmony_ci} 34554aa6d63Sopenharmony_ci 34654aa6d63Sopenharmony_ciint PKCS7Data::SortX509Stack(STACK_OF(X509)* certs) 34754aa6d63Sopenharmony_ci{ 34854aa6d63Sopenharmony_ci std::unordered_set<X509*> x509Sets; 34954aa6d63Sopenharmony_ci std::list<X509*>certChain; 35054aa6d63Sopenharmony_ci X509* tmp = NULL; 35154aa6d63Sopenharmony_ci int result = RET_FAILED; 35254aa6d63Sopenharmony_ci 35354aa6d63Sopenharmony_ci if (sk_X509_num(certs) < MIN_CERTS_NUM) { 35454aa6d63Sopenharmony_ci PrintErrorNumberMsg("CERTIFICATE_ERROR", CERTIFICATE_ERROR, "cert of certchain count less than two!"); 35554aa6d63Sopenharmony_ci goto err; 35654aa6d63Sopenharmony_ci } 35754aa6d63Sopenharmony_ci for (int i = 0; i < sk_X509_num(certs); i++) { 35854aa6d63Sopenharmony_ci x509Sets.insert(sk_X509_value(certs, i)); 35954aa6d63Sopenharmony_ci } 36054aa6d63Sopenharmony_ci if (sk_X509_num(certs) != static_cast<int>(x509Sets.size())) { 36154aa6d63Sopenharmony_ci PrintErrorNumberMsg("CERTIFICATE_ERROR", CERTIFICATE_ERROR, "sort x509 certchain failed!"); 36254aa6d63Sopenharmony_ci goto err; 36354aa6d63Sopenharmony_ci } 36454aa6d63Sopenharmony_ci for (X509* cert : x509Sets) { 36554aa6d63Sopenharmony_ci if (X509_name_cmp(X509_get_subject_name(cert), X509_get_issuer_name(cert)) == 0) { 36654aa6d63Sopenharmony_ci tmp = cert; 36754aa6d63Sopenharmony_ci x509Sets.erase(cert); 36854aa6d63Sopenharmony_ci break; 36954aa6d63Sopenharmony_ci } 37054aa6d63Sopenharmony_ci } 37154aa6d63Sopenharmony_ci if (tmp == NULL) { 37254aa6d63Sopenharmony_ci PrintErrorNumberMsg("CERTIFICATE_ERROR", CERTIFICATE_ERROR, 37354aa6d63Sopenharmony_ci "can't find root cert from certchain ,sort x509 certchain failed!"); 37454aa6d63Sopenharmony_ci goto err; 37554aa6d63Sopenharmony_ci } 37654aa6d63Sopenharmony_ci certChain.push_front(tmp); 37754aa6d63Sopenharmony_ci while ((tmp = FindSubCertThenEraseItFromSets(tmp, x509Sets))) { 37854aa6d63Sopenharmony_ci certChain.push_front(tmp); 37954aa6d63Sopenharmony_ci } 38054aa6d63Sopenharmony_ci if (x509Sets.size() != 0) { 38154aa6d63Sopenharmony_ci PrintErrorNumberMsg("CERTIFICATE_ERROR", CERTIFICATE_ERROR, 38254aa6d63Sopenharmony_ci "certchain contain invalid cert, sort x509 certchain failed!"); 38354aa6d63Sopenharmony_ci goto err; 38454aa6d63Sopenharmony_ci } 38554aa6d63Sopenharmony_ci while (sk_X509_num(certs)) { 38654aa6d63Sopenharmony_ci sk_X509_pop(certs); 38754aa6d63Sopenharmony_ci } 38854aa6d63Sopenharmony_ci for (X509* cert : certChain) { 38954aa6d63Sopenharmony_ci sk_X509_push(certs, cert); 39054aa6d63Sopenharmony_ci } 39154aa6d63Sopenharmony_ci result = RET_OK; 39254aa6d63Sopenharmony_cierr: 39354aa6d63Sopenharmony_ci return result; 39454aa6d63Sopenharmony_ci} 39554aa6d63Sopenharmony_ci 39654aa6d63Sopenharmony_ciint PKCS7Data::VerifySign(const std::string& content)const 39754aa6d63Sopenharmony_ci{ 39854aa6d63Sopenharmony_ci BIO* inBio = NULL; 39954aa6d63Sopenharmony_ci if ((m_flags & PKCS7_DETACHED)) { 40054aa6d63Sopenharmony_ci inBio = BIO_new_mem_buf(reinterpret_cast<const void*>(content.c_str()), 40154aa6d63Sopenharmony_ci static_cast<int>(content.size())); 40254aa6d63Sopenharmony_ci if (inBio == NULL) { 40354aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, 40454aa6d63Sopenharmony_ci "new mem buf error!,pkcs7 verify signature failed"); 40554aa6d63Sopenharmony_ci return VERIFY_ERROR; 40654aa6d63Sopenharmony_ci } 40754aa6d63Sopenharmony_ci } 40854aa6d63Sopenharmony_ci if (PKCS7_verify(m_p7, NULL, NULL, inBio, NULL, m_flags) != 1) { 40954aa6d63Sopenharmony_ci PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "pkcs7 verify signature failed"); 41054aa6d63Sopenharmony_ci BIO_free(inBio); 41154aa6d63Sopenharmony_ci return VERIFY_ERROR; 41254aa6d63Sopenharmony_ci } 41354aa6d63Sopenharmony_ci BIO_free(inBio); 41454aa6d63Sopenharmony_ci return RET_OK; 41554aa6d63Sopenharmony_ci} 41654aa6d63Sopenharmony_ci 41754aa6d63Sopenharmony_ciint PKCS7Data::VerifyCertChain()const 41854aa6d63Sopenharmony_ci{ 41954aa6d63Sopenharmony_ci /* Validate the certificate chain */ 42054aa6d63Sopenharmony_ci STACK_OF(PKCS7_SIGNER_INFO)* skSignerInfo = PKCS7_get_signer_info(m_p7); 42154aa6d63Sopenharmony_ci int signerCount = sk_PKCS7_SIGNER_INFO_num(skSignerInfo); 42254aa6d63Sopenharmony_ci int c = signerCount; 42354aa6d63Sopenharmony_ci STACK_OF(X509)* certs = NULL; 42454aa6d63Sopenharmony_ci int result = RET_FAILED; 42554aa6d63Sopenharmony_ci /* Original certificate chain */ 42654aa6d63Sopenharmony_ci STACK_OF(X509)* certChain = m_p7->d.sign->cert; 42754aa6d63Sopenharmony_ci /* Copy of the certificate chain, with the entity certificate removed later */ 42854aa6d63Sopenharmony_ci certs = sk_X509_dup(certChain); 42954aa6d63Sopenharmony_ci if (SortX509Stack(certs) < 0) { 43054aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("sort x509 stack failed, verify certchain failed"); 43154aa6d63Sopenharmony_ci goto err; 43254aa6d63Sopenharmony_ci } 43354aa6d63Sopenharmony_ci /* Retrieve the certificate chain without the entity certificate */ 43454aa6d63Sopenharmony_ci while (c--) { 43554aa6d63Sopenharmony_ci sk_X509_delete(certs, 0); 43654aa6d63Sopenharmony_ci } 43754aa6d63Sopenharmony_ci for (int i = 0; i < signerCount; i++) { 43854aa6d63Sopenharmony_ci PKCS7_SIGNER_INFO* signerInfo = sk_PKCS7_SIGNER_INFO_value(skSignerInfo, i); 43954aa6d63Sopenharmony_ci if ((result = VerifySignerInfoCertchain(m_p7, signerInfo, certs, certChain)) < 0) { 44054aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("verify certchain failed"); 44154aa6d63Sopenharmony_ci goto err; 44254aa6d63Sopenharmony_ci } 44354aa6d63Sopenharmony_ci } 44454aa6d63Sopenharmony_ci result = RET_OK; 44554aa6d63Sopenharmony_cierr: 44654aa6d63Sopenharmony_ci sk_X509_free(certs); 44754aa6d63Sopenharmony_ci return result; 44854aa6d63Sopenharmony_ci} 44954aa6d63Sopenharmony_ci 45054aa6d63Sopenharmony_ciint PKCS7Data::CheckSginerInfoSignTimeInCertChainValidPeriod(PKCS7_SIGNER_INFO* signerInfo, 45154aa6d63Sopenharmony_ci STACK_OF(X509)* certs) const 45254aa6d63Sopenharmony_ci{ 45354aa6d63Sopenharmony_ci if (signerInfo == NULL || certs == NULL) { 45454aa6d63Sopenharmony_ci PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR, "input is NULL, check signtime invalid"); 45554aa6d63Sopenharmony_ci return INVALIDPARAM_ERROR; 45654aa6d63Sopenharmony_ci } 45754aa6d63Sopenharmony_ci ASN1_TYPE* signTime = PKCS7_get_signed_attribute(signerInfo, NID_pkcs9_signingTime); 45854aa6d63Sopenharmony_ci for (int i = 0; i < sk_X509_num(certs); i++) { 45954aa6d63Sopenharmony_ci X509* cert = sk_X509_value(certs, i); 46054aa6d63Sopenharmony_ci const ASN1_TIME* notBefore = X509_get0_notBefore(cert); 46154aa6d63Sopenharmony_ci const ASN1_TIME* notAfter = X509_get0_notAfter(cert); 46254aa6d63Sopenharmony_ci if (CheckSignTimeInValidPeriod(signTime, notBefore, notAfter) < 0) { 46354aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("pkcs7 sign time check failed"); 46454aa6d63Sopenharmony_ci return INVALIDPARAM_ERROR; 46554aa6d63Sopenharmony_ci } 46654aa6d63Sopenharmony_ci } 46754aa6d63Sopenharmony_ci return RET_OK; 46854aa6d63Sopenharmony_ci} 46954aa6d63Sopenharmony_ci 47054aa6d63Sopenharmony_ciint PKCS7Data::VerifySignerInfoCertchain(PKCS7* pkcs7, PKCS7_SIGNER_INFO* signerInfo, 47154aa6d63Sopenharmony_ci STACK_OF(X509)* certs, STACK_OF(X509)* certChain)const 47254aa6d63Sopenharmony_ci{ 47354aa6d63Sopenharmony_ci X509* sigCert = PKCS7_cert_from_signer_info(pkcs7, signerInfo); 47454aa6d63Sopenharmony_ci int j = 0; 47554aa6d63Sopenharmony_ci /* Trace back through the subject information and validate the signature value of each certificate */ 47654aa6d63Sopenharmony_ci if (!X509NameCompare(sigCert, sk_X509_value(certs, 0))) { 47754aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("entity name compare not equal, verify failed"); 47854aa6d63Sopenharmony_ci return VERIFY_ERROR; 47954aa6d63Sopenharmony_ci } 48054aa6d63Sopenharmony_ci /* verify entity certificate signature value */ 48154aa6d63Sopenharmony_ci if (!VerifyCertOpensslUtils::CertVerify(sigCert, sk_X509_value(certs, 0))) { 48254aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("entity cert signature verify failed"); 48354aa6d63Sopenharmony_ci return VERIFY_ERROR; 48454aa6d63Sopenharmony_ci } 48554aa6d63Sopenharmony_ci for (; j + 1 < sk_X509_num(certs); j++) { 48654aa6d63Sopenharmony_ci if (!X509NameCompare(sk_X509_value(certs, j), sk_X509_value(certs, j + 1))) { 48754aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("sub cert name compare not equal, verify failed"); 48854aa6d63Sopenharmony_ci return VERIFY_ERROR; 48954aa6d63Sopenharmony_ci } 49054aa6d63Sopenharmony_ci /* Verify the signature value of the intermediate certificate */ 49154aa6d63Sopenharmony_ci if (!VerifyCertOpensslUtils::CertVerify(sk_X509_value(certs, j), sk_X509_value(certs, j + 1))) { 49254aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("sub cert signature verify failed"); 49354aa6d63Sopenharmony_ci return VERIFY_ERROR; 49454aa6d63Sopenharmony_ci } 49554aa6d63Sopenharmony_ci } 49654aa6d63Sopenharmony_ci if (!X509NameCompare(sk_X509_value(certs, j), sk_X509_value(certs, j))) { 49754aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("root cert name compare not equal, verify failed"); 49854aa6d63Sopenharmony_ci return VERIFY_ERROR; 49954aa6d63Sopenharmony_ci } 50054aa6d63Sopenharmony_ci /* Verify the signature value of the root certificate */ 50154aa6d63Sopenharmony_ci if (!VerifyCertOpensslUtils::CertVerify(sk_X509_value(certs, j), sk_X509_value(certs, j))) { 50254aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("root cert signature verify failed"); 50354aa6d63Sopenharmony_ci return VERIFY_ERROR; 50454aa6d63Sopenharmony_ci } 50554aa6d63Sopenharmony_ci /* Verify that the signature time in the signature information is within the validity period of 50654aa6d63Sopenharmony_ci the certificate chain (entity certificate will be verified in PKCS7_verify) */ 50754aa6d63Sopenharmony_ci if (CheckSginerInfoSignTimeInCertChainValidPeriod(signerInfo, certChain) < 0) { 50854aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("sign time is invalid,verify failed"); 50954aa6d63Sopenharmony_ci return VERIFY_ERROR; 51054aa6d63Sopenharmony_ci } 51154aa6d63Sopenharmony_ci return RET_OK; 51254aa6d63Sopenharmony_ci} 51354aa6d63Sopenharmony_ci 51454aa6d63Sopenharmony_ciint PKCS7Data::Pkcs7SignAttr(PKCS7_SIGNER_INFO* info) 51554aa6d63Sopenharmony_ci{ 51654aa6d63Sopenharmony_ci unsigned char* attrBuf = NULL; 51754aa6d63Sopenharmony_ci int attrLen; 51854aa6d63Sopenharmony_ci 51954aa6d63Sopenharmony_ci std::string data; 52054aa6d63Sopenharmony_ci std::string signature; 52154aa6d63Sopenharmony_ci unsigned char* sigRet = NULL; 52254aa6d63Sopenharmony_ci int sigLen = 0; 52354aa6d63Sopenharmony_ci 52454aa6d63Sopenharmony_ci attrLen = ASN1_item_i2d((ASN1_VALUE*)info->auth_attr, &attrBuf, 52554aa6d63Sopenharmony_ci ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); 52654aa6d63Sopenharmony_ci if (!attrBuf) { 52754aa6d63Sopenharmony_ci OPENSSL_free(attrBuf); 52854aa6d63Sopenharmony_ci return 0; 52954aa6d63Sopenharmony_ci } 53054aa6d63Sopenharmony_ci 53154aa6d63Sopenharmony_ci data.assign(reinterpret_cast<const char*>(attrBuf), attrLen); 53254aa6d63Sopenharmony_ci signature = m_signer->GetSignature(data, m_sigAlg); 53354aa6d63Sopenharmony_ci if (signature.empty()) { 53454aa6d63Sopenharmony_ci OPENSSL_free(attrBuf); 53554aa6d63Sopenharmony_ci return 0; 53654aa6d63Sopenharmony_ci } 53754aa6d63Sopenharmony_ci sigLen = signature.size(); 53854aa6d63Sopenharmony_ci sigRet = reinterpret_cast<unsigned char*>(OPENSSL_malloc(sigLen)); 53954aa6d63Sopenharmony_ci if (sigRet == NULL) { 54054aa6d63Sopenharmony_ci OPENSSL_free(attrBuf); 54154aa6d63Sopenharmony_ci return 0; 54254aa6d63Sopenharmony_ci } 54354aa6d63Sopenharmony_ci std::copy(&signature[0], &signature[0] + signature.size(), sigRet); 54454aa6d63Sopenharmony_ci ASN1_STRING_set0(info->enc_digest, sigRet, sigLen); 54554aa6d63Sopenharmony_ci OPENSSL_free(attrBuf); 54654aa6d63Sopenharmony_ci return 1; 54754aa6d63Sopenharmony_ci} 54854aa6d63Sopenharmony_ci 54954aa6d63Sopenharmony_cistatic ASN1_OCTET_STRING* PKCS7GetASN1Content(PKCS7* pkcs7) 55054aa6d63Sopenharmony_ci{ 55154aa6d63Sopenharmony_ci if (PKCS7_type_is_data(pkcs7)) { 55254aa6d63Sopenharmony_ci return pkcs7->d.data; 55354aa6d63Sopenharmony_ci } 55454aa6d63Sopenharmony_ci return NULL; 55554aa6d63Sopenharmony_ci} 55654aa6d63Sopenharmony_ci 55754aa6d63Sopenharmony_ciint PKCS7Data::Pkcs7AddTimeDigestAndSignAttr(PKCS7_SIGNER_INFO* info, EVP_MD_CTX* hashCtx) 55854aa6d63Sopenharmony_ci{ 55954aa6d63Sopenharmony_ci unsigned char hashData[EVP_MAX_MD_SIZE]; 56054aa6d63Sopenharmony_ci unsigned int hashLen; 56154aa6d63Sopenharmony_ci 56254aa6d63Sopenharmony_ci /* add signing time */ 56354aa6d63Sopenharmony_ci if (!PKCS7_get_signed_attribute(info, NID_pkcs9_signingTime)) { 56454aa6d63Sopenharmony_ci if (!PKCS7_add0_attrib_signing_time(info, NULL)) { 56554aa6d63Sopenharmony_ci return 0; 56654aa6d63Sopenharmony_ci } 56754aa6d63Sopenharmony_ci } 56854aa6d63Sopenharmony_ci 56954aa6d63Sopenharmony_ci /* add digest */ 57054aa6d63Sopenharmony_ci if (!EVP_DigestFinal_ex(hashCtx, hashData, &hashLen)) { 57154aa6d63Sopenharmony_ci return 0; 57254aa6d63Sopenharmony_ci } 57354aa6d63Sopenharmony_ci if (!PKCS7_add1_attrib_digest(info, hashData, hashLen)) { 57454aa6d63Sopenharmony_ci return 0; 57554aa6d63Sopenharmony_ci } 57654aa6d63Sopenharmony_ci 57754aa6d63Sopenharmony_ci /* sign the attributes */ 57854aa6d63Sopenharmony_ci if (!Pkcs7SignAttr(info)) { 57954aa6d63Sopenharmony_ci return 0; 58054aa6d63Sopenharmony_ci } 58154aa6d63Sopenharmony_ci 58254aa6d63Sopenharmony_ci return 1; 58354aa6d63Sopenharmony_ci} 58454aa6d63Sopenharmony_ci 58554aa6d63Sopenharmony_cistatic BIO* PKCS7SearchDigest(EVP_MD_CTX** pHash, BIO* io, int numberID) 58654aa6d63Sopenharmony_ci{ 58754aa6d63Sopenharmony_ci while ((io = BIO_find_type(io, BIO_TYPE_MD))) { 58854aa6d63Sopenharmony_ci BIO_get_md_ctx(io, pHash); 58954aa6d63Sopenharmony_ci if (*pHash == NULL) { 59054aa6d63Sopenharmony_ci return NULL; 59154aa6d63Sopenharmony_ci } 59254aa6d63Sopenharmony_ci if (EVP_MD_CTX_type(*pHash) == numberID) { 59354aa6d63Sopenharmony_ci return io; 59454aa6d63Sopenharmony_ci } 59554aa6d63Sopenharmony_ci io = BIO_next(io); 59654aa6d63Sopenharmony_ci } 59754aa6d63Sopenharmony_ci return NULL; 59854aa6d63Sopenharmony_ci} 59954aa6d63Sopenharmony_ci 60054aa6d63Sopenharmony_cistatic int PKCS7DataFinalCheck(PKCS7* pkcs7, BIO* bio, 60154aa6d63Sopenharmony_ci STACK_OF(PKCS7_SIGNER_INFO)** psk, ASN1_OCTET_STRING** pos) 60254aa6d63Sopenharmony_ci{ 60354aa6d63Sopenharmony_ci int id = 0; 60454aa6d63Sopenharmony_ci 60554aa6d63Sopenharmony_ci if (pkcs7 == NULL || pkcs7->d.ptr == NULL) { 60654aa6d63Sopenharmony_ci return 0; 60754aa6d63Sopenharmony_ci } 60854aa6d63Sopenharmony_ci 60954aa6d63Sopenharmony_ci id = OBJ_obj2nid(pkcs7->type); 61054aa6d63Sopenharmony_ci pkcs7->state = PKCS7_S_HEADER; 61154aa6d63Sopenharmony_ci 61254aa6d63Sopenharmony_ci if (id == NID_pkcs7_signed) { 61354aa6d63Sopenharmony_ci *psk = pkcs7->d.sign->signer_info; 61454aa6d63Sopenharmony_ci *pos = PKCS7GetASN1Content(pkcs7->d.sign->contents); 61554aa6d63Sopenharmony_ci if (PKCS7_type_is_data(pkcs7->d.sign->contents) && pkcs7->detached) { 61654aa6d63Sopenharmony_ci ASN1_OCTET_STRING_free(*pos); 61754aa6d63Sopenharmony_ci *pos = NULL; 61854aa6d63Sopenharmony_ci pkcs7->d.sign->contents->d.data = NULL; 61954aa6d63Sopenharmony_ci } 62054aa6d63Sopenharmony_ci return 1; 62154aa6d63Sopenharmony_ci } 62254aa6d63Sopenharmony_ci return 0; 62354aa6d63Sopenharmony_ci} 62454aa6d63Sopenharmony_ci 62554aa6d63Sopenharmony_ciint PKCS7Data::Pkcs7DataFinalSignAttr(STACK_OF(PKCS7_SIGNER_INFO)* infoStack, BIO* bio) 62654aa6d63Sopenharmony_ci{ 62754aa6d63Sopenharmony_ci EVP_MD_CTX* hashCtx = NULL; 62854aa6d63Sopenharmony_ci STACK_OF(X509_ATTRIBUTE)* attrStack = NULL; 62954aa6d63Sopenharmony_ci BIO* ioTmp = NULL; 63054aa6d63Sopenharmony_ci int result = 0; 63154aa6d63Sopenharmony_ci EVP_MD_CTX* ctxTmp = EVP_MD_CTX_new(); 63254aa6d63Sopenharmony_ci if (ctxTmp == NULL) { 63354aa6d63Sopenharmony_ci return 0; 63454aa6d63Sopenharmony_ci } 63554aa6d63Sopenharmony_ci 63654aa6d63Sopenharmony_ci if (infoStack == NULL) { 63754aa6d63Sopenharmony_ci goto err; 63854aa6d63Sopenharmony_ci } 63954aa6d63Sopenharmony_ci for (int i = 0; i < sk_PKCS7_SIGNER_INFO_num(infoStack); i++) { 64054aa6d63Sopenharmony_ci PKCS7_SIGNER_INFO* info = sk_PKCS7_SIGNER_INFO_value(infoStack, i); 64154aa6d63Sopenharmony_ci 64254aa6d63Sopenharmony_ci int numberID = OBJ_obj2nid(info->digest_alg->algorithm); 64354aa6d63Sopenharmony_ci 64454aa6d63Sopenharmony_ci ioTmp = bio; 64554aa6d63Sopenharmony_ci 64654aa6d63Sopenharmony_ci ioTmp = PKCS7SearchDigest(&hashCtx, ioTmp, numberID); 64754aa6d63Sopenharmony_ci 64854aa6d63Sopenharmony_ci if (ioTmp == NULL || !EVP_MD_CTX_copy_ex(ctxTmp, hashCtx)) { 64954aa6d63Sopenharmony_ci goto err; 65054aa6d63Sopenharmony_ci } 65154aa6d63Sopenharmony_ci 65254aa6d63Sopenharmony_ci attrStack = info->auth_attr; 65354aa6d63Sopenharmony_ci 65454aa6d63Sopenharmony_ci if (sk_X509_ATTRIBUTE_num(attrStack) > 0) { 65554aa6d63Sopenharmony_ci if (!Pkcs7AddTimeDigestAndSignAttr(info, ctxTmp)) { 65654aa6d63Sopenharmony_ci goto err; 65754aa6d63Sopenharmony_ci } 65854aa6d63Sopenharmony_ci } else { 65954aa6d63Sopenharmony_ci goto err; 66054aa6d63Sopenharmony_ci } 66154aa6d63Sopenharmony_ci } 66254aa6d63Sopenharmony_ci result = 1; 66354aa6d63Sopenharmony_cierr: 66454aa6d63Sopenharmony_ci EVP_MD_CTX_free(ctxTmp); 66554aa6d63Sopenharmony_ci return result; 66654aa6d63Sopenharmony_ci} 66754aa6d63Sopenharmony_ci 66854aa6d63Sopenharmony_cistatic int PKCS7DataFinalSetContent(PKCS7* pkcs7, ASN1_OCTET_STRING* asn1Str, BIO* io) 66954aa6d63Sopenharmony_ci{ 67054aa6d63Sopenharmony_ci BIO* ioTmp = NULL; 67154aa6d63Sopenharmony_ci if (!PKCS7_is_detached(pkcs7)) { 67254aa6d63Sopenharmony_ci if (asn1Str == NULL) { 67354aa6d63Sopenharmony_ci return 0; 67454aa6d63Sopenharmony_ci } 67554aa6d63Sopenharmony_ci if (!(asn1Str->flags & ASN1_STRING_FLAG_NDEF)) { 67654aa6d63Sopenharmony_ci char* contentData; 67754aa6d63Sopenharmony_ci long contentLen; 67854aa6d63Sopenharmony_ci ioTmp = BIO_find_type(io, BIO_TYPE_MEM); 67954aa6d63Sopenharmony_ci if (ioTmp == NULL) { 68054aa6d63Sopenharmony_ci return 0; 68154aa6d63Sopenharmony_ci } 68254aa6d63Sopenharmony_ci contentLen = BIO_get_mem_data(ioTmp, &contentData); 68354aa6d63Sopenharmony_ci 68454aa6d63Sopenharmony_ci BIO_set_flags(ioTmp, BIO_FLAGS_MEM_RDONLY); 68554aa6d63Sopenharmony_ci BIO_set_mem_eof_return(ioTmp, 0); 68654aa6d63Sopenharmony_ci ASN1_STRING_set0(asn1Str, (unsigned char*)contentData, contentLen); 68754aa6d63Sopenharmony_ci } 68854aa6d63Sopenharmony_ci } 68954aa6d63Sopenharmony_ci return 1; 69054aa6d63Sopenharmony_ci} 69154aa6d63Sopenharmony_ciint PKCS7Data::Pkcs7DataFinal(PKCS7* pkcs7, BIO* io) 69254aa6d63Sopenharmony_ci{ 69354aa6d63Sopenharmony_ci STACK_OF(PKCS7_SIGNER_INFO)* infoStack = NULL; 69454aa6d63Sopenharmony_ci ASN1_OCTET_STRING* os = NULL; 69554aa6d63Sopenharmony_ci 69654aa6d63Sopenharmony_ci if (!PKCS7DataFinalCheck(pkcs7, io, &infoStack, &os) || 69754aa6d63Sopenharmony_ci !Pkcs7DataFinalSignAttr(infoStack, io) || 69854aa6d63Sopenharmony_ci !PKCS7DataFinalSetContent(pkcs7, os, io)) { 69954aa6d63Sopenharmony_ci return 0; 70054aa6d63Sopenharmony_ci } 70154aa6d63Sopenharmony_ci return 1; 70254aa6d63Sopenharmony_ci} 70354aa6d63Sopenharmony_ci 70454aa6d63Sopenharmony_ciint PKCS7Data::Pkcs7Final(PKCS7* pkcs7, const std::string& content, int flags) 70554aa6d63Sopenharmony_ci{ 70654aa6d63Sopenharmony_ci BIO* p7bio; 70754aa6d63Sopenharmony_ci int result = 0; 70854aa6d63Sopenharmony_ci 70954aa6d63Sopenharmony_ci if ((p7bio = PKCS7_dataInit(pkcs7, NULL)) == NULL) { 71054aa6d63Sopenharmony_ci return 0; 71154aa6d63Sopenharmony_ci } 71254aa6d63Sopenharmony_ci 71354aa6d63Sopenharmony_ci if (BIO_write(p7bio, content.c_str(), static_cast<int>(content.size())) <= 0) { 71454aa6d63Sopenharmony_ci SIGNATURE_TOOLS_LOGE("add json data to pkcs7 failed"); 71554aa6d63Sopenharmony_ci goto err; 71654aa6d63Sopenharmony_ci } 71754aa6d63Sopenharmony_ci 71854aa6d63Sopenharmony_ci (void)BIO_flush(p7bio); 71954aa6d63Sopenharmony_ci 72054aa6d63Sopenharmony_ci if (!Pkcs7DataFinal(pkcs7, p7bio)) { 72154aa6d63Sopenharmony_ci goto err; 72254aa6d63Sopenharmony_ci } 72354aa6d63Sopenharmony_ci /* Verify the signature value */ 72454aa6d63Sopenharmony_ci if (VerifySignature(pkcs7, p7bio) < 0) { 72554aa6d63Sopenharmony_ci goto err; 72654aa6d63Sopenharmony_ci } 72754aa6d63Sopenharmony_ci result = 1; 72854aa6d63Sopenharmony_ci 72954aa6d63Sopenharmony_cierr: 73054aa6d63Sopenharmony_ci BIO_free_all(p7bio); 73154aa6d63Sopenharmony_ci return result; 73254aa6d63Sopenharmony_ci} 73354aa6d63Sopenharmony_ci 73454aa6d63Sopenharmony_cistatic int Pkcs7SetSignerInfo(PKCS7_SIGNER_INFO* info, X509* cert, const EVP_MD* hash) 73554aa6d63Sopenharmony_ci{ 73654aa6d63Sopenharmony_ci if (!ASN1_INTEGER_set(info->version, 1) || 73754aa6d63Sopenharmony_ci !X509_NAME_set(&info->issuer_and_serial->issuer, X509_get_issuer_name(cert))) { 73854aa6d63Sopenharmony_ci return 0; 73954aa6d63Sopenharmony_ci } 74054aa6d63Sopenharmony_ci 74154aa6d63Sopenharmony_ci ASN1_INTEGER_free(info->issuer_and_serial->serial); 74254aa6d63Sopenharmony_ci if (!(info->issuer_and_serial->serial = 74354aa6d63Sopenharmony_ci ASN1_INTEGER_dup(X509_get_serialNumber(cert)))) { 74454aa6d63Sopenharmony_ci return 0; 74554aa6d63Sopenharmony_ci } 74654aa6d63Sopenharmony_ci 74754aa6d63Sopenharmony_ci X509_ALGOR_set0(info->digest_alg, OBJ_nid2obj(EVP_MD_type(hash)), 74854aa6d63Sopenharmony_ci V_ASN1_NULL, NULL); 74954aa6d63Sopenharmony_ci 75054aa6d63Sopenharmony_ci if (!SetSignerInfoSignAlgor(info)) { 75154aa6d63Sopenharmony_ci return 0; 75254aa6d63Sopenharmony_ci } 75354aa6d63Sopenharmony_ci return 1; 75454aa6d63Sopenharmony_ci} 75554aa6d63Sopenharmony_ci 75654aa6d63Sopenharmony_cistatic PKCS7_SIGNER_INFO* Pkcs7AddSignature(PKCS7* pkcs7, X509* cert, const EVP_MD* hash) 75754aa6d63Sopenharmony_ci{ 75854aa6d63Sopenharmony_ci PKCS7_SIGNER_INFO* info = NULL; 75954aa6d63Sopenharmony_ci 76054aa6d63Sopenharmony_ci if (!(info = PKCS7_SIGNER_INFO_new()) || 76154aa6d63Sopenharmony_ci !Pkcs7SetSignerInfo(info, cert, hash) || 76254aa6d63Sopenharmony_ci !PKCS7_add_signer(pkcs7, info)) { 76354aa6d63Sopenharmony_ci goto err; 76454aa6d63Sopenharmony_ci } 76554aa6d63Sopenharmony_ci return info; 76654aa6d63Sopenharmony_cierr: 76754aa6d63Sopenharmony_ci PKCS7_SIGNER_INFO_free(info); 76854aa6d63Sopenharmony_ci return NULL; 76954aa6d63Sopenharmony_ci} 77054aa6d63Sopenharmony_ci 77154aa6d63Sopenharmony_ci 77254aa6d63Sopenharmony_cistatic PKCS7_SIGNER_INFO* Pkcs7AddSignerInfo(PKCS7* pkcs7, X509* entityCert, const EVP_MD* hash, int flags) 77354aa6d63Sopenharmony_ci{ 77454aa6d63Sopenharmony_ci PKCS7_SIGNER_INFO* info = NULL; 77554aa6d63Sopenharmony_ci if ((info = Pkcs7AddSignature(pkcs7, entityCert, hash)) == NULL) { 77654aa6d63Sopenharmony_ci return NULL; 77754aa6d63Sopenharmony_ci } 77854aa6d63Sopenharmony_ci if (!PKCS7_add_certificate(pkcs7, entityCert)) { 77954aa6d63Sopenharmony_ci return NULL; 78054aa6d63Sopenharmony_ci } 78154aa6d63Sopenharmony_ci if (!PKCS7_add_attrib_content_type(info, NULL)) { 78254aa6d63Sopenharmony_ci return NULL; 78354aa6d63Sopenharmony_ci } 78454aa6d63Sopenharmony_ci return info; 78554aa6d63Sopenharmony_ci} 78654aa6d63Sopenharmony_ci 78754aa6d63Sopenharmony_ciPKCS7* PKCS7Data::Pkcs7Sign(X509* entityCert, STACK_OF(X509)* certs, const EVP_MD* hash, 78854aa6d63Sopenharmony_ci const std::string& content, int flags, const std::vector<PKCS7Attr>& attrs) 78954aa6d63Sopenharmony_ci{ 79054aa6d63Sopenharmony_ci PKCS7* pkcs7; 79154aa6d63Sopenharmony_ci 79254aa6d63Sopenharmony_ci if (!(pkcs7 = PKCS7_new()) || 79354aa6d63Sopenharmony_ci !PKCS7_set_type(pkcs7, NID_pkcs7_signed) || 79454aa6d63Sopenharmony_ci !PKCS7_content_new(pkcs7, NID_pkcs7_data) || 79554aa6d63Sopenharmony_ci !Pkcs7AddSignerInfo(pkcs7, entityCert, hash, flags) || 79654aa6d63Sopenharmony_ci (PKCS7AddAttribute(pkcs7, attrs) < 0)) { 79754aa6d63Sopenharmony_ci PKCS7_free(pkcs7); 79854aa6d63Sopenharmony_ci return NULL; 79954aa6d63Sopenharmony_ci } 80054aa6d63Sopenharmony_ci 80154aa6d63Sopenharmony_ci if (!(flags & PKCS7_NOCERTS)) { 80254aa6d63Sopenharmony_ci for (int i = 0; i < sk_X509_num(certs); i++) { 80354aa6d63Sopenharmony_ci if (!PKCS7_add_certificate(pkcs7, sk_X509_value(certs, i))) { 80454aa6d63Sopenharmony_ci PKCS7_free(pkcs7); 80554aa6d63Sopenharmony_ci return NULL; 80654aa6d63Sopenharmony_ci } 80754aa6d63Sopenharmony_ci } 80854aa6d63Sopenharmony_ci } 80954aa6d63Sopenharmony_ci 81054aa6d63Sopenharmony_ci if (flags & PKCS7_DETACHED) { 81154aa6d63Sopenharmony_ci PKCS7_set_detached(pkcs7, 1); 81254aa6d63Sopenharmony_ci } 81354aa6d63Sopenharmony_ci 81454aa6d63Sopenharmony_ci if (Pkcs7Final(pkcs7, content, flags)) { 81554aa6d63Sopenharmony_ci return pkcs7; 81654aa6d63Sopenharmony_ci } 81754aa6d63Sopenharmony_ci PKCS7_free(pkcs7); 81854aa6d63Sopenharmony_ci return NULL; 81954aa6d63Sopenharmony_ci} 82054aa6d63Sopenharmony_ci} // namespace SignatureTools 82154aa6d63Sopenharmony_ci} // namespace OHOS