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 "sign_info.h"
1654aa6d63Sopenharmony_ci
1754aa6d63Sopenharmony_cinamespace OHOS {
1854aa6d63Sopenharmony_cinamespace SignatureTools {
1954aa6d63Sopenharmony_ci
2054aa6d63Sopenharmony_ciSignInfo::SignInfo()
2154aa6d63Sopenharmony_ci{
2254aa6d63Sopenharmony_ci    saltSize = 0;
2354aa6d63Sopenharmony_ci    sigSize = 0;
2454aa6d63Sopenharmony_ci    flags = 0;
2554aa6d63Sopenharmony_ci    dataSize = 0;
2654aa6d63Sopenharmony_ci    salt = std::vector<int8_t>();
2754aa6d63Sopenharmony_ci    extensionNum = 0;
2854aa6d63Sopenharmony_ci    extensionOffset = 0;
2954aa6d63Sopenharmony_ci    signature = std::vector<int8_t>();
3054aa6d63Sopenharmony_ci    zeroPadding = std::vector<int8_t>();
3154aa6d63Sopenharmony_ci}
3254aa6d63Sopenharmony_ci
3354aa6d63Sopenharmony_ciSignInfo::SignInfo(int32_t saltSize,
3454aa6d63Sopenharmony_ci                   int32_t flags,
3554aa6d63Sopenharmony_ci                   int64_t dataSize,
3654aa6d63Sopenharmony_ci                   const std::vector<int8_t>& salt,
3754aa6d63Sopenharmony_ci                   const std::vector<int8_t>& sig)
3854aa6d63Sopenharmony_ci{
3954aa6d63Sopenharmony_ci    this->saltSize = saltSize;
4054aa6d63Sopenharmony_ci    this->flags = flags;
4154aa6d63Sopenharmony_ci    this->dataSize = dataSize;
4254aa6d63Sopenharmony_ci    if (salt.empty()) {
4354aa6d63Sopenharmony_ci        this->salt = std::vector<int8_t>(SALT_BUFFER_LENGTH, 0);
4454aa6d63Sopenharmony_ci    } else {
4554aa6d63Sopenharmony_ci        this->salt = salt;
4654aa6d63Sopenharmony_ci    }
4754aa6d63Sopenharmony_ci    signature = sig;
4854aa6d63Sopenharmony_ci    sigSize = sig.empty() ? 0 : sig.size();
4954aa6d63Sopenharmony_ci    // align for extension after signature
5054aa6d63Sopenharmony_ci    zeroPadding = std::vector<int8_t>((SignInfo::SIGNATURE_ALIGNMENT
5154aa6d63Sopenharmony_ci                                            - (sigSize % SignInfo::SIGNATURE_ALIGNMENT))
5254aa6d63Sopenharmony_ci                                            % SignInfo::SIGNATURE_ALIGNMENT, 0);
5354aa6d63Sopenharmony_ci    extensionNum = 0;
5454aa6d63Sopenharmony_ci    extensionOffset = 0;
5554aa6d63Sopenharmony_ci}
5654aa6d63Sopenharmony_ci
5754aa6d63Sopenharmony_ciSignInfo::SignInfo(int32_t saltSize,
5854aa6d63Sopenharmony_ci                   int32_t sigSize,
5954aa6d63Sopenharmony_ci                   int32_t flags,
6054aa6d63Sopenharmony_ci                   int64_t dataSize,
6154aa6d63Sopenharmony_ci                   const std::vector<int8_t>& salt,
6254aa6d63Sopenharmony_ci                   int32_t extensionNum,
6354aa6d63Sopenharmony_ci                   int32_t extensionOffset,
6454aa6d63Sopenharmony_ci                   const std::vector<int8_t>& signature,
6554aa6d63Sopenharmony_ci                   const std::vector<int8_t>& zeroPadding,
6654aa6d63Sopenharmony_ci                   const std::vector<MerkleTreeExtension*>& extensionList)
6754aa6d63Sopenharmony_ci{
6854aa6d63Sopenharmony_ci    this->saltSize = saltSize;
6954aa6d63Sopenharmony_ci    this->sigSize = sigSize;
7054aa6d63Sopenharmony_ci    this->flags = flags;
7154aa6d63Sopenharmony_ci    this->dataSize = dataSize;
7254aa6d63Sopenharmony_ci    this->salt = salt;
7354aa6d63Sopenharmony_ci    this->extensionNum = extensionNum;
7454aa6d63Sopenharmony_ci    this->extensionOffset = extensionOffset;
7554aa6d63Sopenharmony_ci    this->signature = signature;
7654aa6d63Sopenharmony_ci    this->zeroPadding = zeroPadding;
7754aa6d63Sopenharmony_ci    this->extensionList = extensionList;
7854aa6d63Sopenharmony_ci}
7954aa6d63Sopenharmony_ci
8054aa6d63Sopenharmony_ciSignInfo::SignInfo(const SignInfo& other)
8154aa6d63Sopenharmony_ci{
8254aa6d63Sopenharmony_ci    this->saltSize = other.saltSize;
8354aa6d63Sopenharmony_ci    this->sigSize = other.sigSize;
8454aa6d63Sopenharmony_ci    this->flags = other.flags;
8554aa6d63Sopenharmony_ci    this->dataSize = other.dataSize;
8654aa6d63Sopenharmony_ci    this->salt = other.salt;
8754aa6d63Sopenharmony_ci    this->extensionNum = other.extensionNum;
8854aa6d63Sopenharmony_ci    this->extensionOffset = other.extensionOffset;
8954aa6d63Sopenharmony_ci    this->signature = other.signature;
9054aa6d63Sopenharmony_ci    this->zeroPadding = other.zeroPadding;
9154aa6d63Sopenharmony_ci    for (MerkleTreeExtension* ext : other.extensionList) {
9254aa6d63Sopenharmony_ci        MerkleTreeExtension* extTmp = new MerkleTreeExtension(*(MerkleTreeExtension*)(ext));
9354aa6d63Sopenharmony_ci        this->extensionList.push_back(extTmp);
9454aa6d63Sopenharmony_ci    }
9554aa6d63Sopenharmony_ci}
9654aa6d63Sopenharmony_ci
9754aa6d63Sopenharmony_ciSignInfo& SignInfo::operator=(const SignInfo& other)
9854aa6d63Sopenharmony_ci{
9954aa6d63Sopenharmony_ci    if (this == &other) {
10054aa6d63Sopenharmony_ci        return *this;
10154aa6d63Sopenharmony_ci    }
10254aa6d63Sopenharmony_ci    this->saltSize = other.saltSize;
10354aa6d63Sopenharmony_ci    this->sigSize = other.sigSize;
10454aa6d63Sopenharmony_ci    this->flags = other.flags;
10554aa6d63Sopenharmony_ci    this->dataSize = other.dataSize;
10654aa6d63Sopenharmony_ci    this->salt = other.salt;
10754aa6d63Sopenharmony_ci    this->extensionNum = other.extensionNum;
10854aa6d63Sopenharmony_ci    this->extensionOffset = other.extensionOffset;
10954aa6d63Sopenharmony_ci    this->signature = other.signature;
11054aa6d63Sopenharmony_ci    this->zeroPadding = other.zeroPadding;
11154aa6d63Sopenharmony_ci    for (Extension* ext : other.extensionList) {
11254aa6d63Sopenharmony_ci        MerkleTreeExtension* extTmp = new MerkleTreeExtension(*(MerkleTreeExtension*)(ext));
11354aa6d63Sopenharmony_ci        this->extensionList.push_back(extTmp);
11454aa6d63Sopenharmony_ci    }
11554aa6d63Sopenharmony_ci    return *this;
11654aa6d63Sopenharmony_ci}
11754aa6d63Sopenharmony_ci
11854aa6d63Sopenharmony_ciSignInfo::~SignInfo()
11954aa6d63Sopenharmony_ci{
12054aa6d63Sopenharmony_ci    for (Extension* ext : extensionList) {
12154aa6d63Sopenharmony_ci        if (ext) {
12254aa6d63Sopenharmony_ci            delete ext;
12354aa6d63Sopenharmony_ci            ext = nullptr;
12454aa6d63Sopenharmony_ci        }
12554aa6d63Sopenharmony_ci    }
12654aa6d63Sopenharmony_ci}
12754aa6d63Sopenharmony_ci
12854aa6d63Sopenharmony_ciint32_t SignInfo::GetSize()
12954aa6d63Sopenharmony_ci{
13054aa6d63Sopenharmony_ci    int blockSize = SignInfo::SIGN_INFO_SIZE_WITHOUT_SIGNATURE + signature.size() + zeroPadding.size();
13154aa6d63Sopenharmony_ci    for (Extension* ext : extensionList) {
13254aa6d63Sopenharmony_ci        blockSize += ext->GetSize();
13354aa6d63Sopenharmony_ci    }
13454aa6d63Sopenharmony_ci    return blockSize;
13554aa6d63Sopenharmony_ci}
13654aa6d63Sopenharmony_ci
13754aa6d63Sopenharmony_civoid SignInfo::AddExtension(MerkleTreeExtension* extension)
13854aa6d63Sopenharmony_ci{
13954aa6d63Sopenharmony_ci    extensionOffset = GetSize();
14054aa6d63Sopenharmony_ci    extensionList.push_back(extension);
14154aa6d63Sopenharmony_ci    extensionNum = extensionList.size();
14254aa6d63Sopenharmony_ci}
14354aa6d63Sopenharmony_ci
14454aa6d63Sopenharmony_ciExtension* SignInfo::GetExtensionByType(int32_t type)
14554aa6d63Sopenharmony_ci{
14654aa6d63Sopenharmony_ci    for (Extension* ext : extensionList) {
14754aa6d63Sopenharmony_ci        if (ext->IsType(type)) {
14854aa6d63Sopenharmony_ci            return ext;
14954aa6d63Sopenharmony_ci        }
15054aa6d63Sopenharmony_ci    }
15154aa6d63Sopenharmony_ci    return nullptr;
15254aa6d63Sopenharmony_ci}
15354aa6d63Sopenharmony_ci
15454aa6d63Sopenharmony_ciint32_t SignInfo::GetExtensionNum()
15554aa6d63Sopenharmony_ci{
15654aa6d63Sopenharmony_ci    return extensionNum;
15754aa6d63Sopenharmony_ci}
15854aa6d63Sopenharmony_ci
15954aa6d63Sopenharmony_cistd::vector<int8_t> SignInfo::GetSignature()
16054aa6d63Sopenharmony_ci{
16154aa6d63Sopenharmony_ci    return signature;
16254aa6d63Sopenharmony_ci}
16354aa6d63Sopenharmony_ci
16454aa6d63Sopenharmony_ciint64_t SignInfo::GetDataSize()
16554aa6d63Sopenharmony_ci{
16654aa6d63Sopenharmony_ci    return dataSize;
16754aa6d63Sopenharmony_ci}
16854aa6d63Sopenharmony_ci
16954aa6d63Sopenharmony_civoid SignInfo::ToByteArray(std::vector<int8_t> &ret)
17054aa6d63Sopenharmony_ci{
17154aa6d63Sopenharmony_ci    std::unique_ptr<ByteBuffer> bf = std::make_unique<ByteBuffer>(ByteBuffer(GetSize()));
17254aa6d63Sopenharmony_ci    std::vector<int8_t> empt(GetSize());
17354aa6d63Sopenharmony_ci    bf->PutData(empt.data(), empt.size());
17454aa6d63Sopenharmony_ci    bf->Clear();
17554aa6d63Sopenharmony_ci    bf->PutInt32(saltSize);
17654aa6d63Sopenharmony_ci    bf->PutInt32(sigSize);
17754aa6d63Sopenharmony_ci    bf->PutInt32(flags);
17854aa6d63Sopenharmony_ci    bf->PutInt64(dataSize);
17954aa6d63Sopenharmony_ci    bf->PutData(salt.data(), salt.size());
18054aa6d63Sopenharmony_ci    bf->PutInt32(extensionNum);
18154aa6d63Sopenharmony_ci    bf->PutInt32(extensionOffset);
18254aa6d63Sopenharmony_ci    bf->PutData(signature.data(), signature.size());
18354aa6d63Sopenharmony_ci    bf->PutData(zeroPadding.data(), zeroPadding.size());
18454aa6d63Sopenharmony_ci    // put extension
18554aa6d63Sopenharmony_ci    for (Extension* ext : extensionList) {
18654aa6d63Sopenharmony_ci        std::vector<int8_t> ret;
18754aa6d63Sopenharmony_ci        ext->ToByteArray(ret);
18854aa6d63Sopenharmony_ci        bf->PutData(ret.data(), ret.size());
18954aa6d63Sopenharmony_ci    }
19054aa6d63Sopenharmony_ci    bf->Flip();
19154aa6d63Sopenharmony_ci    ret = std::vector<int8_t>(bf->GetBufferPtr(), bf->GetBufferPtr() + bf.get()->GetCapacity());
19254aa6d63Sopenharmony_ci    return;
19354aa6d63Sopenharmony_ci}
19454aa6d63Sopenharmony_ci
19554aa6d63Sopenharmony_cistd::vector<MerkleTreeExtension*> SignInfo::ParseMerkleTreeExtension(ByteBuffer* bf, int32_t inExtensionNum)
19654aa6d63Sopenharmony_ci{
19754aa6d63Sopenharmony_ci    std::vector<MerkleTreeExtension*> inExtensionList;
19854aa6d63Sopenharmony_ci    if (inExtensionNum == 1) {
19954aa6d63Sopenharmony_ci        // parse merkle tree extension
20054aa6d63Sopenharmony_ci        int32_t extensionType = 0;
20154aa6d63Sopenharmony_ci        bf->GetInt32(extensionType);
20254aa6d63Sopenharmony_ci        if (extensionType != MerkleTreeExtension::MERKLE_TREE_INLINED) {
20354aa6d63Sopenharmony_ci            PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR,
20454aa6d63Sopenharmony_ci                                "The extension type of SignInfo is incorrect.");
20554aa6d63Sopenharmony_ci            return inExtensionList;
20654aa6d63Sopenharmony_ci        }
20754aa6d63Sopenharmony_ci        int32_t extensionSize = 0;
20854aa6d63Sopenharmony_ci        bf->GetInt32(extensionSize);
20954aa6d63Sopenharmony_ci        if (extensionSize != MerkleTreeExtension::MERKLE_TREE_EXTENSION_DATA_SIZE) {
21054aa6d63Sopenharmony_ci            PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR,
21154aa6d63Sopenharmony_ci                                "The extension size of SignInfo is incorrect.");
21254aa6d63Sopenharmony_ci            return inExtensionList;
21354aa6d63Sopenharmony_ci        }
21454aa6d63Sopenharmony_ci        std::vector<int8_t> merkleTreeExtension(MerkleTreeExtension::MERKLE_TREE_EXTENSION_DATA_SIZE, 0);
21554aa6d63Sopenharmony_ci        bf->GetByte(merkleTreeExtension.data(), merkleTreeExtension.size());
21654aa6d63Sopenharmony_ci        MerkleTreeExtension* pMerkleTreeExtension = MerkleTreeExtension::FromByteArray(merkleTreeExtension);
21754aa6d63Sopenharmony_ci        if (pMerkleTreeExtension) {
21854aa6d63Sopenharmony_ci            inExtensionList.push_back(pMerkleTreeExtension);
21954aa6d63Sopenharmony_ci        }
22054aa6d63Sopenharmony_ci    }
22154aa6d63Sopenharmony_ci    return inExtensionList;
22254aa6d63Sopenharmony_ci}
22354aa6d63Sopenharmony_ci
22454aa6d63Sopenharmony_ciSignInfo SignInfo::FromByteArray(std::vector<int8_t> bytes)
22554aa6d63Sopenharmony_ci{
22654aa6d63Sopenharmony_ci    std::unique_ptr<ByteBuffer> bf = std::make_unique<ByteBuffer>(ByteBuffer(bytes.size()));
22754aa6d63Sopenharmony_ci    bf->PutData(bytes.data(), bytes.size());
22854aa6d63Sopenharmony_ci    bf->Flip();
22954aa6d63Sopenharmony_ci    int32_t inSaltSize = 0;
23054aa6d63Sopenharmony_ci    bool flag = bf->GetInt32(inSaltSize);
23154aa6d63Sopenharmony_ci    int32_t inSigSize = 0;
23254aa6d63Sopenharmony_ci    bool ret = bf->GetInt32(inSigSize);
23354aa6d63Sopenharmony_ci    if (!flag || !ret || inSaltSize < 0 || inSigSize < 0) {
23454aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("Invalid saltSize or sigSize of SignInfo, saltSize: %d, sigSize: %d",
23554aa6d63Sopenharmony_ci            inSaltSize, inSigSize);
23654aa6d63Sopenharmony_ci        return SignInfo();
23754aa6d63Sopenharmony_ci    }
23854aa6d63Sopenharmony_ci    int32_t inFlags = 0;
23954aa6d63Sopenharmony_ci    flag = bf->GetInt32(inFlags);
24054aa6d63Sopenharmony_ci    if (!flag || (inFlags != 0 && inFlags != SignInfo::FLAG_MERKLE_TREE_INCLUDED)) {
24154aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("Invalid flags of SignInfo: %d", inFlags);
24254aa6d63Sopenharmony_ci        return SignInfo();
24354aa6d63Sopenharmony_ci    }
24454aa6d63Sopenharmony_ci    int64_t inDataSize = 0;
24554aa6d63Sopenharmony_ci    flag = bf->GetInt64(inDataSize);
24654aa6d63Sopenharmony_ci    if (!flag || (inDataSize < 0)) {
24754aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("Invalid dataSize of SignInfo");
24854aa6d63Sopenharmony_ci        return SignInfo();
24954aa6d63Sopenharmony_ci    }
25054aa6d63Sopenharmony_ci    std::vector<int8_t> inSalt(SignInfo::SALT_BUFFER_LENGTH, 0);
25154aa6d63Sopenharmony_ci    bf->GetByte(inSalt.data(), SignInfo::SALT_BUFFER_LENGTH);
25254aa6d63Sopenharmony_ci    int32_t inExtensionNum = 0;
25354aa6d63Sopenharmony_ci    flag = bf->GetInt32(inExtensionNum);
25454aa6d63Sopenharmony_ci    if (!flag || inExtensionNum < 0 || inExtensionNum > SignInfo::MAX_EXTENSION_NUM) {
25554aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("Invalid extensionNum of SignInfo: %d", inExtensionNum);
25654aa6d63Sopenharmony_ci        return SignInfo();
25754aa6d63Sopenharmony_ci    }
25854aa6d63Sopenharmony_ci    int32_t inExtensionOffset = 0;
25954aa6d63Sopenharmony_ci    flag = bf->GetInt32(inExtensionOffset);
26054aa6d63Sopenharmony_ci    if (!flag || inExtensionOffset < 0 || inExtensionOffset % SignInfo::SIGNATURE_ALIGNMENT != 0) {
26154aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("Invalid extensionOffset of SignInfo: %d", inExtensionOffset);
26254aa6d63Sopenharmony_ci        return SignInfo();
26354aa6d63Sopenharmony_ci    }
26454aa6d63Sopenharmony_ci    std::vector<int8_t> inSignature(inSigSize, 0);
26554aa6d63Sopenharmony_ci    bf->GetByte(inSignature.data(), inSigSize);
26654aa6d63Sopenharmony_ci    std::vector<int8_t> inZeroPadding((SignInfo::SIGNATURE_ALIGNMENT - (inSigSize % SignInfo::SIGNATURE_ALIGNMENT))
26754aa6d63Sopenharmony_ci                                      % SignInfo::SIGNATURE_ALIGNMENT, 0);
26854aa6d63Sopenharmony_ci    bf->GetByte(inZeroPadding.data(), inZeroPadding.size());
26954aa6d63Sopenharmony_ci    std::vector<MerkleTreeExtension*> inExtensionList = ParseMerkleTreeExtension(bf.get(), inExtensionNum);
27054aa6d63Sopenharmony_ci    return SignInfo(inSaltSize, inSigSize, inFlags, inDataSize, inSalt, inExtensionNum, inExtensionOffset,
27154aa6d63Sopenharmony_ci                    inSignature, inZeroPadding, inExtensionList);
27254aa6d63Sopenharmony_ci}
27354aa6d63Sopenharmony_ci
27454aa6d63Sopenharmony_ci}
27554aa6d63Sopenharmony_ci}