18e920a95Sopenharmony_ci/* 28e920a95Sopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 38e920a95Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48e920a95Sopenharmony_ci * you may not use this file except in compliance with the License. 58e920a95Sopenharmony_ci * You may obtain a copy of the License at 68e920a95Sopenharmony_ci * 78e920a95Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88e920a95Sopenharmony_ci * 98e920a95Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108e920a95Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118e920a95Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128e920a95Sopenharmony_ci * See the License for the specific language governing permissions and 138e920a95Sopenharmony_ci * limitations under the License. 148e920a95Sopenharmony_ci */ 158e920a95Sopenharmony_ci 168e920a95Sopenharmony_ci#include "pkcs7_data.h" 178e920a95Sopenharmony_ci 188e920a95Sopenharmony_ci#include <string> 198e920a95Sopenharmony_ci#include <openssl/asn1.h> 208e920a95Sopenharmony_ci#include <securec.h> 218e920a95Sopenharmony_ci 228e920a95Sopenharmony_ci#include "log.h" 238e920a95Sopenharmony_ci#include "openssl_utils.h" 248e920a95Sopenharmony_ci 258e920a95Sopenharmony_ci 268e920a95Sopenharmony_cinamespace OHOS { 278e920a95Sopenharmony_cinamespace Security { 288e920a95Sopenharmony_cinamespace CodeSign { 298e920a95Sopenharmony_ciPKCS7Data::PKCS7Data(const EVP_MD *md, X509 *cert) 308e920a95Sopenharmony_ci : cert_(cert), md_(md) 318e920a95Sopenharmony_ci{ 328e920a95Sopenharmony_ci} 338e920a95Sopenharmony_ci 348e920a95Sopenharmony_ciPKCS7Data::~PKCS7Data() 358e920a95Sopenharmony_ci{ 368e920a95Sopenharmony_ci cert_ = nullptr; 378e920a95Sopenharmony_ci md_ = nullptr; 388e920a95Sopenharmony_ci if (p7_ != nullptr) { 398e920a95Sopenharmony_ci // signerinfo would be freed with p7 408e920a95Sopenharmony_ci PKCS7_free(p7_); 418e920a95Sopenharmony_ci p7_ = nullptr; 428e920a95Sopenharmony_ci } 438e920a95Sopenharmony_ci} 448e920a95Sopenharmony_ci 458e920a95Sopenharmony_cibool PKCS7Data::InitPKCS7Data(const std::vector<ByteBuffer> &certChain) 468e920a95Sopenharmony_ci{ 478e920a95Sopenharmony_ci uint32_t flags = PKCS7_BINARY | PKCS7_DETACHED | PKCS7_NOATTR | PKCS7_PARTIAL; 488e920a95Sopenharmony_ci STACK_OF(X509) *certs = nullptr; 498e920a95Sopenharmony_ci if (certChain.empty()) { 508e920a95Sopenharmony_ci flags = flags | PKCS7_NOCERTS; 518e920a95Sopenharmony_ci } else { 528e920a95Sopenharmony_ci certs = MakeStackOfCerts(certChain); 538e920a95Sopenharmony_ci } 548e920a95Sopenharmony_ci p7_ = PKCS7_sign(nullptr, nullptr, certs, nullptr, static_cast<int>(flags)); 558e920a95Sopenharmony_ci if (p7_ == nullptr) { 568e920a95Sopenharmony_ci sk_X509_pop_free(certs, X509_free); 578e920a95Sopenharmony_ci return false; 588e920a95Sopenharmony_ci } 598e920a95Sopenharmony_ci return true; 608e920a95Sopenharmony_ci} 618e920a95Sopenharmony_ci 628e920a95Sopenharmony_cibool PKCS7Data::GetPKCS7Data(ByteBuffer &pkcs7Data) 638e920a95Sopenharmony_ci{ 648e920a95Sopenharmony_ci BIO *bio = BIO_new(BIO_s_mem()); 658e920a95Sopenharmony_ci bool ret = false; 668e920a95Sopenharmony_ci do { 678e920a95Sopenharmony_ci if (bio == nullptr) { 688e920a95Sopenharmony_ci break; 698e920a95Sopenharmony_ci } 708e920a95Sopenharmony_ci if (!i2d_PKCS7_bio(bio, p7_)) { 718e920a95Sopenharmony_ci ERR_LOG_WITH_OPEN_SSL_MSG("Encode pkcs7 data failed."); 728e920a95Sopenharmony_ci break; 738e920a95Sopenharmony_ci } 748e920a95Sopenharmony_ci uint8_t *tmp = nullptr; 758e920a95Sopenharmony_ci long tmpSize = BIO_get_mem_data(bio, &tmp); 768e920a95Sopenharmony_ci if ((tmpSize < 0) || (tmpSize > UINT32_MAX)) { 778e920a95Sopenharmony_ci break; 788e920a95Sopenharmony_ci } 798e920a95Sopenharmony_ci if (!pkcs7Data.CopyFrom(tmp, static_cast<uint32_t>(tmpSize))) { 808e920a95Sopenharmony_ci break; 818e920a95Sopenharmony_ci } 828e920a95Sopenharmony_ci ret = true; 838e920a95Sopenharmony_ci } while (0); 848e920a95Sopenharmony_ci BIO_free(bio); 858e920a95Sopenharmony_ci return ret; 868e920a95Sopenharmony_ci} 878e920a95Sopenharmony_ci 888e920a95Sopenharmony_cibool PKCS7Data::AddSignerInfo(PKCS7_SIGNER_INFO *p7i) 898e920a95Sopenharmony_ci{ 908e920a95Sopenharmony_ci if (!PKCS7_add_signer(p7_, p7i)) { 918e920a95Sopenharmony_ci PKCS7_SIGNER_INFO_free(p7i); 928e920a95Sopenharmony_ci LOG_ERROR("Add signer to pkcs7 failed"); 938e920a95Sopenharmony_ci return false; 948e920a95Sopenharmony_ci } 958e920a95Sopenharmony_ci return true; 968e920a95Sopenharmony_ci} 978e920a95Sopenharmony_ci} 988e920a95Sopenharmony_ci} 998e920a95Sopenharmony_ci}