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 #include <string>
16 #include <cstring>
17
18 #include "localization_adapter.h"
19 #include "constant.h"
20 #include <openssl/evp.h>
21 #include <openssl/types.h>
22 #include <openssl/x509.h>
23 #include <openssl/x509v3.h>
24 #include <openssl/err.h>
25
26 namespace OHOS {
27 namespace SignatureTools {
28
LocalizationAdapter(Options * options)29 LocalizationAdapter::LocalizationAdapter(Options* options)
30 {
31 this->options = options;
32 this->keyStoreHelper = std::make_unique<KeyStoreHelper>();
33 this->isIssuerKeyStoreFile = false;
34 }
35
IsAliasExist(const std::string & alias)36 int LocalizationAdapter::IsAliasExist(const std::string& alias)
37 {
38 std::string keyStoreFile = options->GetString(Options::KEY_STORE_FILE);
39 if (!keyStoreHelper->IsKeyStoreFileExist(keyStoreFile)) {
40 return RET_FAILED;
41 }
42
43 EVP_PKEY* keyPair = nullptr;
44 char* keyStorePwd = options->GetChars(Options::KEY_STORE_RIGHTS);
45 char* keyPwd = options->GetChars(Options::KEY_RIGHTS);
46 keyStoreHelper->SetIsRegen(true);
47 int status = keyStoreHelper->ReadKeyStore(keyStoreFile, keyStorePwd, alias, keyPwd, &keyPair);
48 EVP_PKEY_free(keyPair);
49 if (status == RET_OK) {
50 return RET_OK;
51 }
52
53 return RET_FAILED;
54 }
55
ResetPwd()56 void LocalizationAdapter::ResetPwd()
57 {
58 char* keyRights = options->GetChars(Options::KEY_RIGHTS);
59 if (keyRights != nullptr) {
60 ResetChars(keyRights);
61 }
62 char* keyStoreRights = options->GetChars(Options::KEY_STORE_RIGHTS);
63 if (keyStoreRights != nullptr) {
64 ResetChars(keyStoreRights);
65 }
66 char* issuerKeyRights = options->GetChars(Options::ISSUER_KEY_RIGHTS);
67 if (issuerKeyRights != nullptr) {
68 ResetChars(issuerKeyRights);
69 }
70 char* issuerKeyStoreRights = options->GetChars(Options::ISSUER_KEY_STORE_RIGHTS);
71 if (issuerKeyStoreRights != nullptr) {
72 ResetChars(issuerKeyStoreRights);
73 }
74 }
75
ResetChars(char * chars)76 void LocalizationAdapter::ResetChars(char* chars)
77 {
78 if (chars == NULL) {
79 return;
80 }
81 for (size_t i = 0; i < strlen(chars); i++) {
82 chars[i] = 0;
83 }
84 }
85
GetAliasKey(bool autoCreate)86 EVP_PKEY* LocalizationAdapter::GetAliasKey(bool autoCreate)
87 {
88 EVP_PKEY* keyPair = nullptr;
89 if (keyStoreHelper == nullptr) {
90 keyStoreHelper = std::make_unique<KeyStoreHelper>();
91 }
92
93 int status = GetKeyPair(autoCreate, &keyPair);
94 if (status == RET_FAILED) {
95 EVP_PKEY_free(keyPair);
96 return nullptr;
97 }
98
99 return keyPair;
100 }
101
GetKeyPair(bool autoCreate,EVP_PKEY ** keyPair)102 int LocalizationAdapter::GetKeyPair(bool autoCreate, EVP_PKEY** keyPair)
103 {
104 keyStoreHelper->SetPassWordStatus(true);
105 keyStoreHelper->SetIsRegen(autoCreate);
106
107 int status = RET_FAILED;
108 if (isIssuerKeyStoreFile) {
109 status = IssuerKeyStoreFile(keyPair, autoCreate);
110 } else {
111 status = KeyStoreFile(keyPair, autoCreate);
112 }
113 isIssuerKeyStoreFile = false;
114 return status;
115 }
116
KeyStoreFile(EVP_PKEY ** keyPair,bool autoCreate)117 int LocalizationAdapter::KeyStoreFile(EVP_PKEY** keyPair, bool autoCreate)
118 {
119 std::string keyStorePath = "";
120 keyStorePath = options->GetString(Options::KEY_STORE_FILE);
121 char* keyStorePwd = options->GetChars(Options::KEY_STORE_RIGHTS);
122 char* keyPwd = options->GetChars(Options::KEY_RIGHTS);
123 std::string keyAlias = options->GetString(Options::KEY_ALIAS);
124 bool fileStatus = keyStoreHelper->IsKeyStoreFileExist(keyStorePath);
125 if (fileStatus) {
126 int status = keyStoreHelper->ReadKeyStore(keyStorePath, keyStorePwd, keyAlias, keyPwd, keyPair);
127 if (status == RET_OK) {
128 return RET_OK;
129 }
130
131 if (!keyStoreHelper->GetPassWordStatus()) {
132 autoCreate = false;
133 }
134 }
135 if (autoCreate) {
136 std::string keyAlg = options->GetString(Options::KEY_ALG);
137 int keySize = options->GetInt(Options::KEY_SIZE);
138 *keyPair = keyStoreHelper->GenerateKeyPair(keyAlg, keySize);
139 int status = keyStoreHelper->WriteKeyStore(*keyPair, keyStorePath, keyStorePwd, keyAlias, keyPwd);
140 if (status == RET_OK) {
141 PrintMsg("Remind: generate new keypair ,the keyalias is " + keyAlias + " !");
142 return RET_OK;
143 }
144 }
145
146 return RET_FAILED;
147 }
148
IssuerKeyStoreFile(EVP_PKEY ** keyPair,bool autoCreate)149 int LocalizationAdapter::IssuerKeyStoreFile(EVP_PKEY** keyPair, bool autoCreate)
150 {
151 std::string keyStore = options->GetString(Options::ISSUER_KEY_STORE_FILE);
152 char* keyStorePwd = options->GetChars(Options::ISSUER_KEY_STORE_RIGHTS);
153 std::string keyAlias = options->GetString(Options::ISSUER_KEY_ALIAS);
154 char* keyPwd = options->GetChars(Options::ISSUER_KEY_RIGHTS);
155
156 if (keyStore.empty()) {
157 keyStore = options->GetString(Options::KEY_STORE_FILE);
158 keyStorePwd = options->GetChars(Options::KEY_STORE_RIGHTS);
159 }
160
161 bool fileStatus = keyStoreHelper->IsKeyStoreFileExist(keyStore);
162 if (fileStatus) {
163 int status = keyStoreHelper->ReadKeyStore(keyStore, keyStorePwd, keyAlias, keyPwd, keyPair);
164 if (status == RET_OK) {
165 return RET_OK;
166 }
167
168 if (!keyStoreHelper->GetPassWordStatus()) {
169 autoCreate = false;
170 }
171 }
172
173 if (!fileStatus && !keyStore.empty() && !autoCreate) {
174 PrintErrorNumberMsg("KEY_ALIAS_ERROR", KEY_ALIAS_ERROR, "keyAlias: '"
175 + keyAlias + "' is not exist in" + keyStore);
176 }
177
178 if (autoCreate) {
179 std::string keyAlg = options->GetString(Options::KEY_ALG);
180 int keySize = options->GetInt(Options::KEY_SIZE);
181 *keyPair = keyStoreHelper->GenerateKeyPair(keyAlg, keySize);
182 if (keyStore.empty()) {
183 return keyStoreHelper->WriteKeyStore(*keyPair, keyStore, keyStorePwd, keyAlias, keyPwd);
184 }
185 }
186
187 return RET_FAILED;
188 }
189
SetIssuerKeyStoreFile(bool issuerKeyStoreFile)190 void LocalizationAdapter::SetIssuerKeyStoreFile(bool issuerKeyStoreFile)
191 {
192 this->isIssuerKeyStoreFile = issuerKeyStoreFile;
193 }
194
STACK_OF(X509)195 STACK_OF(X509)* LocalizationAdapter::GetSignCertChain()
196 {
197 STACK_OF(X509)* certificates = NULL;
198 std::string certPath = options->GetString(Options::PROFILE_CERT_FILE);
199 if (certPath.empty()) {
200 certPath = options->GetString(Options::APP_CERT_FILE);
201 }
202 certificates = sk_X509_new(NULL);
203 if (certificates == NULL) {
204 SIGNATURE_TOOLS_LOGE("sk_X509_new failed");
205 return NULL;
206 }
207 std::vector<X509*> certs = GetCertsFromFile(certPath, Options::PROFILE_CERT_FILE);
208 for (int i = 0; i < static_cast<int>(certs.size()); i++) {
209 sk_X509_push(certificates, certs[i]);
210 }
211 if (sk_X509_num(certificates) < MIN_CERT_CHAIN_SIZE || sk_X509_num(certificates) > MAX_CERT_CHAIN_SIZE) {
212 SIGNATURE_TOOLS_LOGE("Profile cert '%s' must a cert chain", certPath.c_str());
213 goto err;
214 }
215 return certificates;
216 err:
217 sk_X509_pop_free(certificates, X509_free);
218 return NULL;
219 }
220
GetIssuerKeyByAlias()221 EVP_PKEY* LocalizationAdapter::GetIssuerKeyByAlias()
222 {
223 return GetAliasKey(false);
224 }
225
IsOutFormChain()226 bool LocalizationAdapter::IsOutFormChain()
227 {
228 std::string checkStr = OUT_FORM_CERT_CHAIN;
229 std::string outForm = options->GetString(Options::OUT_FORM, checkStr);
230 if (outForm.compare(OUT_FORM_CERT_CHAIN) == 0) {
231 return true;
232 }
233 return false;
234 }
235
GetSubCaCertFile()236 X509* LocalizationAdapter::GetSubCaCertFile()
237 {
238 std::string certPath = options->GetString(Options::SUB_CA_CERT_FILE);
239 return GetCertsFromFile(certPath, Options::SUB_CA_CERT_FILE).at(0);
240 }
241
GetSignAlg() const242 const std::string LocalizationAdapter::GetSignAlg() const
243 {
244 return options->GetString(Options::SIGN_ALG);
245 }
246
GetCaCertFile()247 X509* LocalizationAdapter::GetCaCertFile()
248 {
249 std::string certPath = options->GetString(Options::CA_CERT_FILE);
250 return GetCertsFromFile(certPath, Options::CA_CERT_FILE).at(0);
251 }
252
GetOutFile()253 const std::string LocalizationAdapter::GetOutFile()
254 {
255 return options->GetString(Options::OUT_FILE);
256 }
257
GetCertsFromFile(std::string & certPath,const std::string & logTitle)258 std::vector<X509*> LocalizationAdapter::GetCertsFromFile(std::string& certPath, const std::string& logTitle)
259 {
260 SIGNATURE_TOOLS_LOGD("outPutPath = %s , logTitle = %s", certPath.c_str(), logTitle.c_str());
261 std::vector<X509*> certs;
262 if (certPath.empty()) {
263 SIGNATURE_TOOLS_LOGE("cert path not exist!");
264 return certs;
265 }
266 // Read And Get Cert
267 BIO* bio = BIO_new_file(certPath.c_str(), "rb");
268 if (!bio) {
269 PrintErrorNumberMsg("IO_ERROR", IO_ERROR, "open file:" + certPath + "failed");
270 DigestCommon::GetOpensslErrorMessage();
271 BIO_free(bio);
272 return certs;
273 }
274 X509* cert = nullptr;
275 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != nullptr) {
276 certs.emplace_back(cert);
277 }
278 BIO_free(bio);
279 return certs;
280 }
281
GetInFile()282 const std::string LocalizationAdapter::GetInFile()
283 {
284 return options->GetString(Options::IN_FILE);
285 }
286
IsRemoteSigner()287 bool LocalizationAdapter::IsRemoteSigner()
288 {
289 std::string mode = options->GetString(Options::MODE, LOCAL_SIGN);
290 return mode == REMOTE_SIGN;
291 }
292
GetOptions()293 Options* LocalizationAdapter::GetOptions()
294 {
295 return options;
296 }
297
AppAndProfileAssetsRealse(std::initializer_list<EVP_PKEY * > keys,std::initializer_list<X509_REQ * > reqs,std::initializer_list<X509 * > certs)298 void LocalizationAdapter::AppAndProfileAssetsRealse(std::initializer_list<EVP_PKEY*> keys,
299 std::initializer_list<X509_REQ*> reqs,
300 std::initializer_list<X509*> certs)
301 {
302 for (auto cert : certs) {
303 if (cert) {
304 X509_free(cert);
305 cert = nullptr;
306 }
307 }
308 for (auto req : reqs) {
309 if (req) {
310 X509_REQ_free(req);
311 req = nullptr;
312 }
313 }
314 for (auto key : keys) {
315 if (key) {
316 EVP_PKEY_free(key);
317 key = nullptr;
318 }
319 }
320 }
321
322 } // namespace SignatureTools
323 } // namespace OHOS
324
325