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
21 namespace OHOS {
22 namespace SignatureTools {
23 /**
24 * Create local signer.
25 *
26 * @param keyPair Private key to sign
27 * @param certificates Cert chain to sign
28 */
LocalSigner(EVP_PKEY* keyPair, STACK_OF(X509)* certificates)29 LocalSigner::LocalSigner(EVP_PKEY* keyPair, STACK_OF(X509)* certificates) :m_keyPair(keyPair),
30 m_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 }
41 LocalSigner::~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 }
52 STACK_OF(X509_CRL)* LocalSigner::GetCrls() const
53 {
54 return NULL;
55 }
56
57 static X509* X509Dup(const X509* x509)
58 {
59 return X509_dup(const_cast<X509*>(x509));
60 }
61
62 STACK_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 }
69 std::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);
100 err:
101 OPENSSL_free(sigResult);
102 EVP_MD_CTX_free(hashCtx);
103 return ret;
104 }
105 } // namespace SignatureTools
106 } // namespace OHOS