1/* 2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "pkcs7_data.h" 17 18#include <string> 19#include <openssl/asn1.h> 20#include <securec.h> 21 22#include "log.h" 23#include "openssl_utils.h" 24 25 26namespace OHOS { 27namespace Security { 28namespace CodeSign { 29PKCS7Data::PKCS7Data(const EVP_MD *md, X509 *cert) 30 : cert_(cert), md_(md) 31{ 32} 33 34PKCS7Data::~PKCS7Data() 35{ 36 cert_ = nullptr; 37 md_ = nullptr; 38 if (p7_ != nullptr) { 39 // signerinfo would be freed with p7 40 PKCS7_free(p7_); 41 p7_ = nullptr; 42 } 43} 44 45bool PKCS7Data::InitPKCS7Data(const std::vector<ByteBuffer> &certChain) 46{ 47 uint32_t flags = PKCS7_BINARY | PKCS7_DETACHED | PKCS7_NOATTR | PKCS7_PARTIAL; 48 STACK_OF(X509) *certs = nullptr; 49 if (certChain.empty()) { 50 flags = flags | PKCS7_NOCERTS; 51 } else { 52 certs = MakeStackOfCerts(certChain); 53 } 54 p7_ = PKCS7_sign(nullptr, nullptr, certs, nullptr, static_cast<int>(flags)); 55 if (p7_ == nullptr) { 56 sk_X509_pop_free(certs, X509_free); 57 return false; 58 } 59 return true; 60} 61 62bool PKCS7Data::GetPKCS7Data(ByteBuffer &pkcs7Data) 63{ 64 BIO *bio = BIO_new(BIO_s_mem()); 65 bool ret = false; 66 do { 67 if (bio == nullptr) { 68 break; 69 } 70 if (!i2d_PKCS7_bio(bio, p7_)) { 71 ERR_LOG_WITH_OPEN_SSL_MSG("Encode pkcs7 data failed."); 72 break; 73 } 74 uint8_t *tmp = nullptr; 75 long tmpSize = BIO_get_mem_data(bio, &tmp); 76 if ((tmpSize < 0) || (tmpSize > UINT32_MAX)) { 77 break; 78 } 79 if (!pkcs7Data.CopyFrom(tmp, static_cast<uint32_t>(tmpSize))) { 80 break; 81 } 82 ret = true; 83 } while (0); 84 BIO_free(bio); 85 return ret; 86} 87 88bool PKCS7Data::AddSignerInfo(PKCS7_SIGNER_INFO *p7i) 89{ 90 if (!PKCS7_add_signer(p7_, p7i)) { 91 PKCS7_SIGNER_INFO_free(p7i); 92 LOG_ERROR("Add signer to pkcs7 failed"); 93 return false; 94 } 95 return true; 96} 97} 98} 99}