* 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;
}
}
}
}