9cea60c7创建于 2024年3月6日历史提交
/*

 * Copyright (c) 2023-2024 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



#include "pkcs7_generator.h"



#include "errcode.h"

#include "log.h"

#include "openssl_utils.h"

#include "pkcs7_data.h"

#include "securec.h"



namespace OHOS {

namespace Security {

namespace CodeSign {

int32_t PKCS7Generator::GenerateSignature(const std::string &ownerID, SignKey &key, const char *hashAlg,

                                          const ByteBuffer &contentData, ByteBuffer &out)

{

    LOG_INFO("GenerateSignature called.");

    int32_t ret = CS_ERR_OPENSSL_PKCS7;

    X509 *cert = nullptr;

    do {

        const ByteBuffer *certBuffer = key.GetSignCert();

        if (certBuffer == nullptr) {

            ret = CS_ERR_HUKS_OBTAIN_CERT;

            break;

        }

        cert = LoadCertFromBuffer(certBuffer->GetBuffer(), certBuffer->GetSize());

        if (cert == nullptr) {

            ret = CS_ERR_OPENSSL_LOAD_CERT;

            break;

        }

        const EVP_MD *md = EVP_get_digestbyname(hashAlg);

        if (md == nullptr) {

            break;

        }

        PKCS7Data pkcs7(md, cert);

        if (!pkcs7.InitPKCS7Data(key.GetCarriedCerts())) {

            break;

        }

        SignerInfo signerInfo;

        if (!signerInfo.InitSignerInfo(ownerID, cert, md, contentData)) {

            break;

        }

        if (!pkcs7.AddSignerInfo(signerInfo.GetSignerInfo())) {

            break;

        }

        ret = SignData(key, signerInfo);

        if (ret != CS_SUCCESS) {

            break;

        }

        if (!pkcs7.GetPKCS7Data(out)) {

            ret = CS_ERR_OPENSSL_PKCS7;

            break;

        }

        ret = CS_SUCCESS;

    } while (0);

    X509_free(cert);

    if (ret != CS_SUCCESS) {

        LOG_ERROR("Generate signature failed, ret = %{public}d", ret);

    }

    return ret;

}



int32_t PKCS7Generator::SignData(SignKey &key, SignerInfo &signerInfo)

{

    uint32_t dataSize = 0;

    uint8_t *data = signerInfo.GetDataToSign(dataSize);

    if (data == nullptr) {

        LOG_ERROR("GetDataToSign fail");

        return CS_ERR_OPENSSL_PKCS7;

    }

    ByteBuffer unsignedData;

    if (!unsignedData.CopyFrom(data, dataSize)) {

        return CS_ERR_MEMORY;

    }

    ByteBuffer rawSignature;

    if (!key.Sign(unsignedData, rawSignature)) {

        return CS_ERR_HUKS_SIGN;

    }

    if (!signerInfo.AddSignatureInSignerInfo(rawSignature)) {

        LOG_ERROR("AddSignatureInSignerInfo fail");

        return CS_ERR_OPENSSL_PKCS7;

    }

    return CS_SUCCESS;

}

}

}

}