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 "signer_factory.h"
1654aa6d63Sopenharmony_ci#include "dynamic_library_handle.h"
1754aa6d63Sopenharmony_ci
1854aa6d63Sopenharmony_cinamespace OHOS {
1954aa6d63Sopenharmony_cinamespace SignatureTools {
2054aa6d63Sopenharmony_ci
2154aa6d63Sopenharmony_cistd::shared_ptr<Signer> SignerFactory::GetSigner(LocalizationAdapter& adapter)const
2254aa6d63Sopenharmony_ci{
2354aa6d63Sopenharmony_ci    if (adapter.IsRemoteSigner()) {
2454aa6d63Sopenharmony_ci        return LoadRemoteSigner(adapter);
2554aa6d63Sopenharmony_ci    }
2654aa6d63Sopenharmony_ci
2754aa6d63Sopenharmony_ci    EVP_PKEY* keyPair = adapter.GetAliasKey(false);
2854aa6d63Sopenharmony_ci    if (keyPair == NULL) {
2954aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("key is NULL, get signer failed");
3054aa6d63Sopenharmony_ci        adapter.ResetPwd();
3154aa6d63Sopenharmony_ci        return NULL;
3254aa6d63Sopenharmony_ci    }
3354aa6d63Sopenharmony_ci    adapter.ResetPwd();
3454aa6d63Sopenharmony_ci    STACK_OF(X509)*certs = adapter.GetSignCertChain();
3554aa6d63Sopenharmony_ci    std::shared_ptr<Signer> signer = std::make_shared<LocalSigner>(keyPair, certs);
3654aa6d63Sopenharmony_ci    if (signer == NULL) {
3754aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("signer is NULL, create LocalSigner failed");
3854aa6d63Sopenharmony_ci        EVP_PKEY_free(keyPair);
3954aa6d63Sopenharmony_ci        sk_X509_pop_free(certs, X509_free);
4054aa6d63Sopenharmony_ci        return NULL;
4154aa6d63Sopenharmony_ci    }
4254aa6d63Sopenharmony_ci    return signer;
4354aa6d63Sopenharmony_ci}
4454aa6d63Sopenharmony_ci
4554aa6d63Sopenharmony_cistd::shared_ptr<Signer> SignerFactory::LoadRemoteSigner(LocalizationAdapter& adapter) const
4654aa6d63Sopenharmony_ci{
4754aa6d63Sopenharmony_ci    std::string keyAlias = adapter.GetOptions()->GetString(ParamConstants::PARAM_BASIC_PRIVATE_KEY);
4854aa6d63Sopenharmony_ci    std::string signServer = adapter.GetOptions()->GetString(ParamConstants::PARAM_REMOTE_SERVER);
4954aa6d63Sopenharmony_ci    std::string signerPlugin = adapter.GetOptions()->GetString(ParamConstants::PARAM_REMOTE_SIGNERPLUGIN);
5054aa6d63Sopenharmony_ci    std::string onlineAuthMode = adapter.GetOptions()->GetString(ParamConstants::PARAM_REMOTE_ONLINEAUTHMODE);
5154aa6d63Sopenharmony_ci    std::string username = adapter.GetOptions()->GetString(ParamConstants::PARAM_REMOTE_USERNAME);
5254aa6d63Sopenharmony_ci    char* userPwd = adapter.GetOptions()->GetChars(ParamConstants::PARAM_REMOTE_USERPWD);
5354aa6d63Sopenharmony_ci
5454aa6d63Sopenharmony_ci    // open so
5554aa6d63Sopenharmony_ci    DynamicLibraryHandle::handle = dlopen(signerPlugin.c_str(), RTLD_NOW | RTLD_GLOBAL);
5654aa6d63Sopenharmony_ci    if (!DynamicLibraryHandle::handle) {
5754aa6d63Sopenharmony_ci        PrintErrorNumberMsg("LoadRemoteSigner", RET_FAILED, dlerror());
5854aa6d63Sopenharmony_ci        return nullptr;
5954aa6d63Sopenharmony_ci    }
6054aa6d63Sopenharmony_ci
6154aa6d63Sopenharmony_ci    // clear previous error
6254aa6d63Sopenharmony_ci    dlerror();
6354aa6d63Sopenharmony_ci
6454aa6d63Sopenharmony_ci    // get "Create" function
6554aa6d63Sopenharmony_ci    RemoteSignerCreator remoteSignerCreator = (RemoteSignerCreator)dlsym(DynamicLibraryHandle::handle, "Create");
6654aa6d63Sopenharmony_ci    char* error = nullptr;
6754aa6d63Sopenharmony_ci    if ((error = dlerror()) != NULL) {
6854aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("%s", error);
6954aa6d63Sopenharmony_ci        return nullptr;
7054aa6d63Sopenharmony_ci    }
7154aa6d63Sopenharmony_ci
7254aa6d63Sopenharmony_ci    RemoteSignerParamType keyAliasType{keyAlias.c_str(), keyAlias.size()};
7354aa6d63Sopenharmony_ci    RemoteSignerParamType signServerType{signServer.c_str(), signServer.size()};
7454aa6d63Sopenharmony_ci    RemoteSignerParamType onlineAuthModeType{onlineAuthMode.c_str(), onlineAuthMode.size()};
7554aa6d63Sopenharmony_ci    RemoteSignerParamType usernameType{username.c_str(), username.size()};
7654aa6d63Sopenharmony_ci    RemoteSignerParamType userPwdType{userPwd, strlen(userPwd)};
7754aa6d63Sopenharmony_ci
7854aa6d63Sopenharmony_ci    Signer* signer = remoteSignerCreator(keyAliasType, signServerType, onlineAuthModeType, usernameType, userPwdType);
7954aa6d63Sopenharmony_ci
8054aa6d63Sopenharmony_ci    for (size_t i = 0; i < strlen(userPwd); i++) {
8154aa6d63Sopenharmony_ci        userPwd[i] = 0;
8254aa6d63Sopenharmony_ci    }
8354aa6d63Sopenharmony_ci
8454aa6d63Sopenharmony_ci    std::shared_ptr<Signer> remoteSigner(signer);
8554aa6d63Sopenharmony_ci    return remoteSigner;
8654aa6d63Sopenharmony_ci}
8754aa6d63Sopenharmony_ci} // namespace SignatureTools
8854aa6d63Sopenharmony_ci} // namespace OHOS