1/* 2 * Copyright (c) 2024-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 "signature_tools_log.h" 17#include "pkcs7_data.h" 18#include "constant.h" 19#include "local_signer.h" 20 21namespace OHOS { 22namespace SignatureTools { 23/** 24* Create local signer. 25* 26* @param keyPair Private key to sign 27* @param certificates Cert chain to sign 28*/ 29LocalSigner::LocalSigner(EVP_PKEY* keyPair, STACK_OF(X509)* certificates) :m_keyPair(keyPair), 30m_certificates(certificates) 31{ 32 bool check = m_keyPair == NULL || 33 PKCS7Data::SortX509Stack(m_certificates) < 0 || 34 X509_check_private_key(sk_X509_value(m_certificates, 0), m_keyPair) != 1; 35 if (check) { 36 SIGNATURE_TOOLS_LOGW("Warning: invalid local signer!\n"); 37 sk_X509_pop_free(m_certificates, X509_free); 38 m_certificates = NULL; 39 } 40} 41LocalSigner::~LocalSigner() 42{ 43 if (m_keyPair) { 44 EVP_PKEY_free(m_keyPair); 45 m_keyPair = NULL; 46 } 47 if (m_certificates) { 48 sk_X509_pop_free(m_certificates, X509_free); 49 m_certificates = NULL; 50 } 51} 52STACK_OF(X509_CRL)* LocalSigner::GetCrls() const 53{ 54 return NULL; 55} 56 57static X509* X509Dup(const X509* x509) 58{ 59 return X509_dup(const_cast<X509*>(x509)); 60} 61 62STACK_OF(X509)* LocalSigner::GetCertificates() const 63{ 64 if (m_certificates == NULL) { 65 return m_certificates; 66 } 67 return sk_X509_deep_copy(m_certificates, X509Dup, X509_free); 68} 69std::string LocalSigner::GetSignature(const std::string& data, const std::string& signAlg) const 70{ 71 EVP_MD_CTX* hashCtx = NULL; 72 EVP_PKEY_CTX* privateKeyCtx = NULL; 73 unsigned char* sigResult = NULL; 74 const EVP_MD* hash = NULL; 75 size_t sigLen; 76 std::string ret; 77 78 if (signAlg == SIGN_ALG_SHA256) { 79 hash = EVP_sha256(); 80 } else if (signAlg == SIGN_ALG_SHA384) { 81 hash = EVP_sha384(); 82 } else { 83 PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR, 84 signAlg + "is invalid sigAlg, please use SHA256withECDSA/SHA384withECDSA, sign failed"); 85 return ret; 86 } 87 88 /* calculate signature value */ 89 bool result = !(hashCtx = EVP_MD_CTX_new()) || 90 (EVP_DigestSignInit(hashCtx, &privateKeyCtx, hash, NULL, m_keyPair) <= 0) || 91 (EVP_DigestSignUpdate(hashCtx, data.data(), data.size()) <= 0) || 92 (EVP_DigestSignFinal(hashCtx, NULL, &sigLen) <= 0) || 93 !(sigResult = reinterpret_cast<unsigned char*>(OPENSSL_malloc(sigLen))) || 94 (EVP_DigestSignFinal(hashCtx, sigResult, &sigLen) <= 0); 95 if (result) { 96 PrintErrorNumberMsg("SIGN_ERROR", SIGN_ERROR, "compute signature value failed"); 97 goto err; 98 } 99 ret.assign(reinterpret_cast<const char*>(sigResult), sigLen); 100err: 101 OPENSSL_free(sigResult); 102 EVP_MD_CTX_free(hashCtx); 103 return ret; 104} 105} // namespace SignatureTools 106} // namespace OHOS