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}