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