154aa6d63Sopenharmony_ci/*
254aa6d63Sopenharmony_ci * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
354aa6d63Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
454aa6d63Sopenharmony_ci * you may not use this file except in compliance with the License.
554aa6d63Sopenharmony_ci * You may obtain a copy of the License at
654aa6d63Sopenharmony_ci *
754aa6d63Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
854aa6d63Sopenharmony_ci *
954aa6d63Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1054aa6d63Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1154aa6d63Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1254aa6d63Sopenharmony_ci * See the License for the specific language governing permissions and
1354aa6d63Sopenharmony_ci * limitations under the License.
1454aa6d63Sopenharmony_ci */
1554aa6d63Sopenharmony_ci#include <string>
1654aa6d63Sopenharmony_ci#include <cstring>
1754aa6d63Sopenharmony_ci
1854aa6d63Sopenharmony_ci#include "localization_adapter.h"
1954aa6d63Sopenharmony_ci#include "constant.h"
2054aa6d63Sopenharmony_ci
2154aa6d63Sopenharmony_cinamespace OHOS {
2254aa6d63Sopenharmony_cinamespace SignatureTools {
2354aa6d63Sopenharmony_ci
2454aa6d63Sopenharmony_ciLocalizationAdapter::LocalizationAdapter(Options* options)
2554aa6d63Sopenharmony_ci{
2654aa6d63Sopenharmony_ci    this->options = options;
2754aa6d63Sopenharmony_ci    this->keyStoreHelper = std::make_unique<KeyStoreHelper>();
2854aa6d63Sopenharmony_ci    this->isIssuerKeyStoreFile = false;
2954aa6d63Sopenharmony_ci}
3054aa6d63Sopenharmony_ci
3154aa6d63Sopenharmony_ciint LocalizationAdapter::IsAliasExist(const std::string& alias)
3254aa6d63Sopenharmony_ci{
3354aa6d63Sopenharmony_ci    std::string keyStoreFile = options->GetString(Options::KEY_STORE_FILE);
3454aa6d63Sopenharmony_ci    if (!keyStoreHelper->IsKeyStoreFileExist(keyStoreFile)) {
3554aa6d63Sopenharmony_ci        return RET_FAILED;
3654aa6d63Sopenharmony_ci    }
3754aa6d63Sopenharmony_ci
3854aa6d63Sopenharmony_ci    EVP_PKEY* keyPair = nullptr;
3954aa6d63Sopenharmony_ci    char* keyStorePwd = options->GetChars(Options::KEY_STORE_RIGHTS);
4054aa6d63Sopenharmony_ci    char* keyPwd = options->GetChars(Options::KEY_RIGHTS);
4154aa6d63Sopenharmony_ci    keyStoreHelper->SetIsRegen(true);
4254aa6d63Sopenharmony_ci    int status = keyStoreHelper->ReadKeyStore(keyStoreFile, keyStorePwd, alias, keyPwd, &keyPair);
4354aa6d63Sopenharmony_ci    EVP_PKEY_free(keyPair);
4454aa6d63Sopenharmony_ci    if (status == RET_OK) {
4554aa6d63Sopenharmony_ci        return RET_OK;
4654aa6d63Sopenharmony_ci    }
4754aa6d63Sopenharmony_ci
4854aa6d63Sopenharmony_ci    return RET_FAILED;
4954aa6d63Sopenharmony_ci}
5054aa6d63Sopenharmony_ci
5154aa6d63Sopenharmony_civoid LocalizationAdapter::ResetPwd()
5254aa6d63Sopenharmony_ci{
5354aa6d63Sopenharmony_ci    char* keyRights = options->GetChars(Options::KEY_RIGHTS);
5454aa6d63Sopenharmony_ci    if (keyRights != nullptr) {
5554aa6d63Sopenharmony_ci        ResetChars(keyRights);
5654aa6d63Sopenharmony_ci    }
5754aa6d63Sopenharmony_ci    char* keyStoreRights = options->GetChars(Options::KEY_STORE_RIGHTS);
5854aa6d63Sopenharmony_ci    if (keyStoreRights != nullptr) {
5954aa6d63Sopenharmony_ci        ResetChars(keyStoreRights);
6054aa6d63Sopenharmony_ci    }
6154aa6d63Sopenharmony_ci    char* issuerKeyRights = options->GetChars(Options::ISSUER_KEY_RIGHTS);
6254aa6d63Sopenharmony_ci    if (issuerKeyRights != nullptr) {
6354aa6d63Sopenharmony_ci        ResetChars(issuerKeyRights);
6454aa6d63Sopenharmony_ci    }
6554aa6d63Sopenharmony_ci    char* issuerKeyStoreRights = options->GetChars(Options::ISSUER_KEY_STORE_RIGHTS);
6654aa6d63Sopenharmony_ci    if (issuerKeyStoreRights != nullptr) {
6754aa6d63Sopenharmony_ci        ResetChars(issuerKeyStoreRights);
6854aa6d63Sopenharmony_ci    }
6954aa6d63Sopenharmony_ci}
7054aa6d63Sopenharmony_ci
7154aa6d63Sopenharmony_civoid LocalizationAdapter::ResetChars(char* chars)
7254aa6d63Sopenharmony_ci{
7354aa6d63Sopenharmony_ci    if (chars == NULL) {
7454aa6d63Sopenharmony_ci        return;
7554aa6d63Sopenharmony_ci    }
7654aa6d63Sopenharmony_ci    for (size_t i = 0; i < strlen(chars); i++) {
7754aa6d63Sopenharmony_ci        chars[i] = 0;
7854aa6d63Sopenharmony_ci    }
7954aa6d63Sopenharmony_ci}
8054aa6d63Sopenharmony_ci
8154aa6d63Sopenharmony_ciEVP_PKEY* LocalizationAdapter::GetAliasKey(bool autoCreate)
8254aa6d63Sopenharmony_ci{
8354aa6d63Sopenharmony_ci    EVP_PKEY* keyPair = nullptr;
8454aa6d63Sopenharmony_ci    if (keyStoreHelper == nullptr) {
8554aa6d63Sopenharmony_ci        keyStoreHelper = std::make_unique<KeyStoreHelper>();
8654aa6d63Sopenharmony_ci    }
8754aa6d63Sopenharmony_ci
8854aa6d63Sopenharmony_ci    int status = GetKeyPair(autoCreate, &keyPair);
8954aa6d63Sopenharmony_ci    if (status == RET_FAILED) {
9054aa6d63Sopenharmony_ci        EVP_PKEY_free(keyPair);
9154aa6d63Sopenharmony_ci        return nullptr;
9254aa6d63Sopenharmony_ci    }
9354aa6d63Sopenharmony_ci
9454aa6d63Sopenharmony_ci    return keyPair;
9554aa6d63Sopenharmony_ci}
9654aa6d63Sopenharmony_ci
9754aa6d63Sopenharmony_ciint LocalizationAdapter::GetKeyPair(bool autoCreate, EVP_PKEY** keyPair)
9854aa6d63Sopenharmony_ci{
9954aa6d63Sopenharmony_ci    keyStoreHelper->SetPassWordStatus(true);
10054aa6d63Sopenharmony_ci    keyStoreHelper->SetIsRegen(autoCreate);
10154aa6d63Sopenharmony_ci
10254aa6d63Sopenharmony_ci    int status = RET_FAILED;
10354aa6d63Sopenharmony_ci    if (isIssuerKeyStoreFile) {
10454aa6d63Sopenharmony_ci        status = IssuerKeyStoreFile(keyPair, autoCreate);
10554aa6d63Sopenharmony_ci    } else {
10654aa6d63Sopenharmony_ci        status = KeyStoreFile(keyPair, autoCreate);
10754aa6d63Sopenharmony_ci    }
10854aa6d63Sopenharmony_ci    isIssuerKeyStoreFile = false;
10954aa6d63Sopenharmony_ci    return status;
11054aa6d63Sopenharmony_ci}
11154aa6d63Sopenharmony_ci
11254aa6d63Sopenharmony_ciint LocalizationAdapter::KeyStoreFile(EVP_PKEY** keyPair, bool autoCreate)
11354aa6d63Sopenharmony_ci{
11454aa6d63Sopenharmony_ci    std::string keyStorePath = "";
11554aa6d63Sopenharmony_ci    keyStorePath = options->GetString(Options::KEY_STORE_FILE);
11654aa6d63Sopenharmony_ci    char* keyStorePwd = options->GetChars(Options::KEY_STORE_RIGHTS);
11754aa6d63Sopenharmony_ci    char* keyPwd = options->GetChars(Options::KEY_RIGHTS);
11854aa6d63Sopenharmony_ci    std::string keyAlias = options->GetString(Options::KEY_ALIAS);
11954aa6d63Sopenharmony_ci    bool fileStatus = keyStoreHelper->IsKeyStoreFileExist(keyStorePath);
12054aa6d63Sopenharmony_ci    if (fileStatus) {
12154aa6d63Sopenharmony_ci        int status = keyStoreHelper->ReadKeyStore(keyStorePath, keyStorePwd, keyAlias, keyPwd, keyPair);
12254aa6d63Sopenharmony_ci        if (status == RET_OK) {
12354aa6d63Sopenharmony_ci            return RET_OK;
12454aa6d63Sopenharmony_ci        }
12554aa6d63Sopenharmony_ci
12654aa6d63Sopenharmony_ci        if (!keyStoreHelper->GetPassWordStatus()) {
12754aa6d63Sopenharmony_ci                autoCreate = false;
12854aa6d63Sopenharmony_ci        }
12954aa6d63Sopenharmony_ci    }
13054aa6d63Sopenharmony_ci    if (autoCreate) {
13154aa6d63Sopenharmony_ci        std::string keyAlg = options->GetString(Options::KEY_ALG);
13254aa6d63Sopenharmony_ci        int keySize = options->GetInt(Options::KEY_SIZE);
13354aa6d63Sopenharmony_ci        *keyPair = keyStoreHelper->GenerateKeyPair(keyAlg, keySize);
13454aa6d63Sopenharmony_ci        int status = keyStoreHelper->WriteKeyStore(*keyPair, keyStorePath, keyStorePwd, keyAlias, keyPwd);
13554aa6d63Sopenharmony_ci        if (status == RET_OK) {
13654aa6d63Sopenharmony_ci            PrintMsg("Remind: generate new keypair ,the keyalias is " + keyAlias + " !");
13754aa6d63Sopenharmony_ci            return RET_OK;
13854aa6d63Sopenharmony_ci        }
13954aa6d63Sopenharmony_ci    }
14054aa6d63Sopenharmony_ci
14154aa6d63Sopenharmony_ci    return RET_FAILED;
14254aa6d63Sopenharmony_ci}
14354aa6d63Sopenharmony_ci
14454aa6d63Sopenharmony_ciint LocalizationAdapter::IssuerKeyStoreFile(EVP_PKEY** keyPair, bool autoCreate)
14554aa6d63Sopenharmony_ci{
14654aa6d63Sopenharmony_ci    std::string keyStore = options->GetString(Options::ISSUER_KEY_STORE_FILE);
14754aa6d63Sopenharmony_ci    char* keyStorePwd = options->GetChars(Options::ISSUER_KEY_STORE_RIGHTS);
14854aa6d63Sopenharmony_ci    std::string keyAlias = options->GetString(Options::ISSUER_KEY_ALIAS);
14954aa6d63Sopenharmony_ci    char* keyPwd = options->GetChars(Options::ISSUER_KEY_RIGHTS);
15054aa6d63Sopenharmony_ci
15154aa6d63Sopenharmony_ci    if (keyStore.empty()) {
15254aa6d63Sopenharmony_ci        keyStore = options->GetString(Options::KEY_STORE_FILE);
15354aa6d63Sopenharmony_ci        keyStorePwd = options->GetChars(Options::KEY_STORE_RIGHTS);
15454aa6d63Sopenharmony_ci    }
15554aa6d63Sopenharmony_ci
15654aa6d63Sopenharmony_ci    bool fileStatus = keyStoreHelper->IsKeyStoreFileExist(keyStore);
15754aa6d63Sopenharmony_ci    if (fileStatus) {
15854aa6d63Sopenharmony_ci        int status = keyStoreHelper->ReadKeyStore(keyStore, keyStorePwd, keyAlias, keyPwd, keyPair);
15954aa6d63Sopenharmony_ci        if (status == RET_OK) {
16054aa6d63Sopenharmony_ci            return RET_OK;
16154aa6d63Sopenharmony_ci        }
16254aa6d63Sopenharmony_ci
16354aa6d63Sopenharmony_ci        if (!keyStoreHelper->GetPassWordStatus()) {
16454aa6d63Sopenharmony_ci                autoCreate = false;
16554aa6d63Sopenharmony_ci        }
16654aa6d63Sopenharmony_ci    }
16754aa6d63Sopenharmony_ci
16854aa6d63Sopenharmony_ci    if (!fileStatus && !keyStore.empty() && !autoCreate) {
16954aa6d63Sopenharmony_ci        PrintErrorNumberMsg("KEY_ALIAS_ERROR", KEY_ALIAS_ERROR, "keyAlias: '"
17054aa6d63Sopenharmony_ci                            + keyAlias + "' is not exist in" + keyStore);
17154aa6d63Sopenharmony_ci    }
17254aa6d63Sopenharmony_ci
17354aa6d63Sopenharmony_ci    if (autoCreate) {
17454aa6d63Sopenharmony_ci        std::string keyAlg = options->GetString(Options::KEY_ALG);
17554aa6d63Sopenharmony_ci        int keySize = options->GetInt(Options::KEY_SIZE);
17654aa6d63Sopenharmony_ci        *keyPair = keyStoreHelper->GenerateKeyPair(keyAlg, keySize);
17754aa6d63Sopenharmony_ci        if (keyStore.empty()) {
17854aa6d63Sopenharmony_ci            return keyStoreHelper->WriteKeyStore(*keyPair, keyStore, keyStorePwd, keyAlias, keyPwd);
17954aa6d63Sopenharmony_ci        }
18054aa6d63Sopenharmony_ci    }
18154aa6d63Sopenharmony_ci
18254aa6d63Sopenharmony_ci    return RET_FAILED;
18354aa6d63Sopenharmony_ci}
18454aa6d63Sopenharmony_ci
18554aa6d63Sopenharmony_civoid LocalizationAdapter::SetIssuerKeyStoreFile(bool issuerKeyStoreFile)
18654aa6d63Sopenharmony_ci{
18754aa6d63Sopenharmony_ci    this->isIssuerKeyStoreFile = issuerKeyStoreFile;
18854aa6d63Sopenharmony_ci}
18954aa6d63Sopenharmony_ci
19054aa6d63Sopenharmony_ciSTACK_OF(X509)* LocalizationAdapter::GetSignCertChain()
19154aa6d63Sopenharmony_ci{
19254aa6d63Sopenharmony_ci    STACK_OF(X509)* certificates = NULL;
19354aa6d63Sopenharmony_ci    std::string certPath = options->GetString(Options::PROFILE_CERT_FILE);
19454aa6d63Sopenharmony_ci    if (certPath.empty()) {
19554aa6d63Sopenharmony_ci        certPath = options->GetString(Options::APP_CERT_FILE);
19654aa6d63Sopenharmony_ci    }
19754aa6d63Sopenharmony_ci    certificates = sk_X509_new(NULL);
19854aa6d63Sopenharmony_ci    if (certificates == NULL) {
19954aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("sk_X509_new failed");
20054aa6d63Sopenharmony_ci        return  NULL;
20154aa6d63Sopenharmony_ci    }
20254aa6d63Sopenharmony_ci    std::vector<X509*> certs = GetCertsFromFile(certPath, Options::PROFILE_CERT_FILE);
20354aa6d63Sopenharmony_ci    for (int i = 0; i < static_cast<int>(certs.size()); i++) {
20454aa6d63Sopenharmony_ci        sk_X509_push(certificates, certs[i]);
20554aa6d63Sopenharmony_ci    }
20654aa6d63Sopenharmony_ci    if (sk_X509_num(certificates) < MIN_CERT_CHAIN_SIZE || sk_X509_num(certificates) > MAX_CERT_CHAIN_SIZE) {
20754aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("Profile cert '%s' must a cert chain", certPath.c_str());
20854aa6d63Sopenharmony_ci        goto err;
20954aa6d63Sopenharmony_ci    }
21054aa6d63Sopenharmony_ci    return certificates;
21154aa6d63Sopenharmony_cierr:
21254aa6d63Sopenharmony_ci    sk_X509_pop_free(certificates, X509_free);
21354aa6d63Sopenharmony_ci    return NULL;
21454aa6d63Sopenharmony_ci}
21554aa6d63Sopenharmony_ci
21654aa6d63Sopenharmony_ciEVP_PKEY* LocalizationAdapter::GetIssuerKeyByAlias()
21754aa6d63Sopenharmony_ci{
21854aa6d63Sopenharmony_ci    return GetAliasKey(false);
21954aa6d63Sopenharmony_ci}
22054aa6d63Sopenharmony_ci
22154aa6d63Sopenharmony_cibool LocalizationAdapter::IsOutFormChain()
22254aa6d63Sopenharmony_ci{
22354aa6d63Sopenharmony_ci    std::string checkStr = OUT_FORM_CERT_CHAIN;
22454aa6d63Sopenharmony_ci    std::string outForm = options->GetString(Options::OUT_FORM, checkStr);
22554aa6d63Sopenharmony_ci    if (outForm.compare(OUT_FORM_CERT_CHAIN) == 0) {
22654aa6d63Sopenharmony_ci        return true;
22754aa6d63Sopenharmony_ci    }
22854aa6d63Sopenharmony_ci    return false;
22954aa6d63Sopenharmony_ci}
23054aa6d63Sopenharmony_ci
23154aa6d63Sopenharmony_ciX509* LocalizationAdapter::GetSubCaCertFile()
23254aa6d63Sopenharmony_ci{
23354aa6d63Sopenharmony_ci    std::string certPath = options->GetString(Options::SUB_CA_CERT_FILE);
23454aa6d63Sopenharmony_ci    return GetCertsFromFile(certPath, Options::SUB_CA_CERT_FILE).at(0);
23554aa6d63Sopenharmony_ci}
23654aa6d63Sopenharmony_ci
23754aa6d63Sopenharmony_ciconst std::string LocalizationAdapter::GetSignAlg() const
23854aa6d63Sopenharmony_ci{
23954aa6d63Sopenharmony_ci    return options->GetString(Options::SIGN_ALG);
24054aa6d63Sopenharmony_ci}
24154aa6d63Sopenharmony_ci
24254aa6d63Sopenharmony_ciX509* LocalizationAdapter::GetCaCertFile()
24354aa6d63Sopenharmony_ci{
24454aa6d63Sopenharmony_ci    std::string certPath = options->GetString(Options::CA_CERT_FILE);
24554aa6d63Sopenharmony_ci    return GetCertsFromFile(certPath, Options::CA_CERT_FILE).at(0);
24654aa6d63Sopenharmony_ci}
24754aa6d63Sopenharmony_ci
24854aa6d63Sopenharmony_ciconst std::string LocalizationAdapter::GetOutFile()
24954aa6d63Sopenharmony_ci{
25054aa6d63Sopenharmony_ci    return options->GetString(Options::OUT_FILE);
25154aa6d63Sopenharmony_ci}
25254aa6d63Sopenharmony_ci
25354aa6d63Sopenharmony_cistd::vector<X509*> LocalizationAdapter::GetCertsFromFile(std::string& certPath, const std::string& logTitle)
25454aa6d63Sopenharmony_ci{
25554aa6d63Sopenharmony_ci    SIGNATURE_TOOLS_LOGD("outPutPath = %s , logTitle = %s", certPath.c_str(), logTitle.c_str());
25654aa6d63Sopenharmony_ci    std::vector<X509*> certs;
25754aa6d63Sopenharmony_ci    if (certPath.empty()) {
25854aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("cert path not exist!");
25954aa6d63Sopenharmony_ci        return certs;
26054aa6d63Sopenharmony_ci    }
26154aa6d63Sopenharmony_ci    // Read And Get Cert
26254aa6d63Sopenharmony_ci    BIO* bio = BIO_new_file(certPath.c_str(), "rb");
26354aa6d63Sopenharmony_ci    if (!bio) {
26454aa6d63Sopenharmony_ci        PrintErrorNumberMsg("IO_ERROR", IO_ERROR, "open file:" + certPath + "failed");
26554aa6d63Sopenharmony_ci        DigestCommon::GetOpensslErrorMessage();
26654aa6d63Sopenharmony_ci        BIO_free(bio);
26754aa6d63Sopenharmony_ci        return certs;
26854aa6d63Sopenharmony_ci    }
26954aa6d63Sopenharmony_ci    X509* cert = nullptr;
27054aa6d63Sopenharmony_ci    while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != nullptr) {
27154aa6d63Sopenharmony_ci        certs.emplace_back(cert);
27254aa6d63Sopenharmony_ci    }
27354aa6d63Sopenharmony_ci    BIO_free(bio);
27454aa6d63Sopenharmony_ci    return certs;
27554aa6d63Sopenharmony_ci}
27654aa6d63Sopenharmony_ci
27754aa6d63Sopenharmony_ciconst std::string LocalizationAdapter::GetInFile()
27854aa6d63Sopenharmony_ci{
27954aa6d63Sopenharmony_ci    return options->GetString(Options::IN_FILE);
28054aa6d63Sopenharmony_ci}
28154aa6d63Sopenharmony_ci
28254aa6d63Sopenharmony_cibool LocalizationAdapter::IsRemoteSigner()
28354aa6d63Sopenharmony_ci{
28454aa6d63Sopenharmony_ci    std::string mode = options->GetString(Options::MODE, LOCAL_SIGN);
28554aa6d63Sopenharmony_ci    return mode == REMOTE_SIGN;
28654aa6d63Sopenharmony_ci}
28754aa6d63Sopenharmony_ci
28854aa6d63Sopenharmony_ciOptions* LocalizationAdapter::GetOptions()
28954aa6d63Sopenharmony_ci{
29054aa6d63Sopenharmony_ci    return options;
29154aa6d63Sopenharmony_ci}
29254aa6d63Sopenharmony_ci
29354aa6d63Sopenharmony_civoid LocalizationAdapter::AppAndProfileAssetsRealse(std::initializer_list<EVP_PKEY*> keys,
29454aa6d63Sopenharmony_ci                                                    std::initializer_list<X509_REQ*> reqs,
29554aa6d63Sopenharmony_ci                                                    std::initializer_list<X509*> certs)
29654aa6d63Sopenharmony_ci{
29754aa6d63Sopenharmony_ci    for (auto cert : certs) {
29854aa6d63Sopenharmony_ci        if (cert) {
29954aa6d63Sopenharmony_ci            X509_free(cert);
30054aa6d63Sopenharmony_ci            cert = nullptr;
30154aa6d63Sopenharmony_ci        }
30254aa6d63Sopenharmony_ci    }
30354aa6d63Sopenharmony_ci    for (auto req : reqs) {
30454aa6d63Sopenharmony_ci        if (req) {
30554aa6d63Sopenharmony_ci            X509_REQ_free(req);
30654aa6d63Sopenharmony_ci            req = nullptr;
30754aa6d63Sopenharmony_ci        }
30854aa6d63Sopenharmony_ci    }
30954aa6d63Sopenharmony_ci    for (auto key : keys) {
31054aa6d63Sopenharmony_ci        if (key) {
31154aa6d63Sopenharmony_ci            EVP_PKEY_free(key);
31254aa6d63Sopenharmony_ci            key = nullptr;
31354aa6d63Sopenharmony_ci        }
31454aa6d63Sopenharmony_ci    }
31554aa6d63Sopenharmony_ci}
31654aa6d63Sopenharmony_ci
31754aa6d63Sopenharmony_ci} // namespace SignatureTools
31854aa6d63Sopenharmony_ci} // namespace OHOS
31954aa6d63Sopenharmony_ci
320