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_generator.h"
178e920a95Sopenharmony_ci
188e920a95Sopenharmony_ci#include "errcode.h"
198e920a95Sopenharmony_ci#include "log.h"
208e920a95Sopenharmony_ci#include "openssl_utils.h"
218e920a95Sopenharmony_ci#include "pkcs7_data.h"
228e920a95Sopenharmony_ci#include "securec.h"
238e920a95Sopenharmony_ci
248e920a95Sopenharmony_cinamespace OHOS {
258e920a95Sopenharmony_cinamespace Security {
268e920a95Sopenharmony_cinamespace CodeSign {
278e920a95Sopenharmony_ciint32_t PKCS7Generator::GenerateSignature(const std::string &ownerID, SignKey &key, const char *hashAlg,
288e920a95Sopenharmony_ci                                          const ByteBuffer &contentData, ByteBuffer &out)
298e920a95Sopenharmony_ci{
308e920a95Sopenharmony_ci    LOG_INFO("GenerateSignature called.");
318e920a95Sopenharmony_ci    int32_t ret = CS_ERR_OPENSSL_PKCS7;
328e920a95Sopenharmony_ci    X509 *cert = nullptr;
338e920a95Sopenharmony_ci    do {
348e920a95Sopenharmony_ci        const ByteBuffer *certBuffer = key.GetSignCert();
358e920a95Sopenharmony_ci        if (certBuffer == nullptr) {
368e920a95Sopenharmony_ci            ret = CS_ERR_HUKS_OBTAIN_CERT;
378e920a95Sopenharmony_ci            break;
388e920a95Sopenharmony_ci        }
398e920a95Sopenharmony_ci        cert = LoadCertFromBuffer(certBuffer->GetBuffer(), certBuffer->GetSize());
408e920a95Sopenharmony_ci        if (cert == nullptr) {
418e920a95Sopenharmony_ci            ret = CS_ERR_OPENSSL_LOAD_CERT;
428e920a95Sopenharmony_ci            break;
438e920a95Sopenharmony_ci        }
448e920a95Sopenharmony_ci        const EVP_MD *md = EVP_get_digestbyname(hashAlg);
458e920a95Sopenharmony_ci        if (md == nullptr) {
468e920a95Sopenharmony_ci            break;
478e920a95Sopenharmony_ci        }
488e920a95Sopenharmony_ci        PKCS7Data pkcs7(md, cert);
498e920a95Sopenharmony_ci        if (!pkcs7.InitPKCS7Data(key.GetCarriedCerts())) {
508e920a95Sopenharmony_ci            break;
518e920a95Sopenharmony_ci        }
528e920a95Sopenharmony_ci        SignerInfo signerInfo;
538e920a95Sopenharmony_ci        if (!signerInfo.InitSignerInfo(ownerID, cert, md, contentData)) {
548e920a95Sopenharmony_ci            break;
558e920a95Sopenharmony_ci        }
568e920a95Sopenharmony_ci        if (!pkcs7.AddSignerInfo(signerInfo.GetSignerInfo())) {
578e920a95Sopenharmony_ci            break;
588e920a95Sopenharmony_ci        }
598e920a95Sopenharmony_ci        ret = SignData(key, signerInfo);
608e920a95Sopenharmony_ci        if (ret != CS_SUCCESS) {
618e920a95Sopenharmony_ci            break;
628e920a95Sopenharmony_ci        }
638e920a95Sopenharmony_ci        if (!pkcs7.GetPKCS7Data(out)) {
648e920a95Sopenharmony_ci            ret = CS_ERR_OPENSSL_PKCS7;
658e920a95Sopenharmony_ci            break;
668e920a95Sopenharmony_ci        }
678e920a95Sopenharmony_ci        ret = CS_SUCCESS;
688e920a95Sopenharmony_ci    } while (0);
698e920a95Sopenharmony_ci    X509_free(cert);
708e920a95Sopenharmony_ci    if (ret != CS_SUCCESS) {
718e920a95Sopenharmony_ci        LOG_ERROR("Generate signature failed, ret = %{public}d", ret);
728e920a95Sopenharmony_ci    }
738e920a95Sopenharmony_ci    return ret;
748e920a95Sopenharmony_ci}
758e920a95Sopenharmony_ci
768e920a95Sopenharmony_ciint32_t PKCS7Generator::SignData(SignKey &key, SignerInfo &signerInfo)
778e920a95Sopenharmony_ci{
788e920a95Sopenharmony_ci    uint32_t dataSize = 0;
798e920a95Sopenharmony_ci    uint8_t *data = signerInfo.GetDataToSign(dataSize);
808e920a95Sopenharmony_ci    if (data == nullptr) {
818e920a95Sopenharmony_ci        LOG_ERROR("GetDataToSign fail");
828e920a95Sopenharmony_ci        return CS_ERR_OPENSSL_PKCS7;
838e920a95Sopenharmony_ci    }
848e920a95Sopenharmony_ci    ByteBuffer unsignedData;
858e920a95Sopenharmony_ci    if (!unsignedData.CopyFrom(data, dataSize)) {
868e920a95Sopenharmony_ci        return CS_ERR_MEMORY;
878e920a95Sopenharmony_ci    }
888e920a95Sopenharmony_ci    ByteBuffer rawSignature;
898e920a95Sopenharmony_ci    if (!key.Sign(unsignedData, rawSignature)) {
908e920a95Sopenharmony_ci        return CS_ERR_HUKS_SIGN;
918e920a95Sopenharmony_ci    }
928e920a95Sopenharmony_ci    if (!signerInfo.AddSignatureInSignerInfo(rawSignature)) {
938e920a95Sopenharmony_ci        LOG_ERROR("AddSignatureInSignerInfo fail");
948e920a95Sopenharmony_ci        return CS_ERR_OPENSSL_PKCS7;
958e920a95Sopenharmony_ci    }
968e920a95Sopenharmony_ci    return CS_SUCCESS;
978e920a95Sopenharmony_ci}
988e920a95Sopenharmony_ci}
998e920a95Sopenharmony_ci}
1008e920a95Sopenharmony_ci}