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
1654aa6d63Sopenharmony_ci#include <cinttypes>
1754aa6d63Sopenharmony_ci
1854aa6d63Sopenharmony_ci#include "endof_central_directory.h"
1954aa6d63Sopenharmony_ci#include "signature_tools_log.h"
2054aa6d63Sopenharmony_ci
2154aa6d63Sopenharmony_cinamespace OHOS {
2254aa6d63Sopenharmony_cinamespace SignatureTools {
2354aa6d63Sopenharmony_cistd::optional<EndOfCentralDirectory*> EndOfCentralDirectory::GetEOCDByBytes(const std::string& bytes)
2454aa6d63Sopenharmony_ci{
2554aa6d63Sopenharmony_ci    return GetEOCDByBytes(bytes, 0);
2654aa6d63Sopenharmony_ci}
2754aa6d63Sopenharmony_ci
2854aa6d63Sopenharmony_cistd::optional<EndOfCentralDirectory*> EndOfCentralDirectory::GetEOCDByBytes(const std::string& bytes, int offset)
2954aa6d63Sopenharmony_ci{
3054aa6d63Sopenharmony_ci    EndOfCentralDirectory* eocd = new EndOfCentralDirectory();
3154aa6d63Sopenharmony_ci    int remainingDataLen = bytes.size() - offset;
3254aa6d63Sopenharmony_ci    if (remainingDataLen < EOCD_LENGTH) {
3354aa6d63Sopenharmony_ci        delete eocd;
3454aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("remainingDataLen is less than EOCD_LENGTH, remainingDataLen: %d, "
3554aa6d63Sopenharmony_ci                             "EOCD_LENGTH: %d", remainingDataLen, EOCD_LENGTH);
3654aa6d63Sopenharmony_ci        return std::nullopt;
3754aa6d63Sopenharmony_ci    }
3854aa6d63Sopenharmony_ci
3954aa6d63Sopenharmony_ci    ByteBuffer bf(bytes.c_str(), bytes.size());
4054aa6d63Sopenharmony_ci
4154aa6d63Sopenharmony_ci    int signValue;
4254aa6d63Sopenharmony_ci    bf.GetInt32(signValue);
4354aa6d63Sopenharmony_ci    if (signValue != SIGNATURE) {
4454aa6d63Sopenharmony_ci        delete eocd;
4554aa6d63Sopenharmony_ci        return std::nullopt;
4654aa6d63Sopenharmony_ci    }
4754aa6d63Sopenharmony_ci
4854aa6d63Sopenharmony_ci    SetEndOfCentralDirectoryValues(bf, eocd);
4954aa6d63Sopenharmony_ci
5054aa6d63Sopenharmony_ci    uint16_t commentLength = eocd->GetCommentLength();
5154aa6d63Sopenharmony_ci    if (bf.Remaining() != commentLength) {
5254aa6d63Sopenharmony_ci        delete eocd;
5354aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("bf.Remaining() is not equal to commentLength, bf.Remaining(): %d, "
5454aa6d63Sopenharmony_ci                             "commentLength: %" PRIu16, bf.Remaining(), commentLength);
5554aa6d63Sopenharmony_ci        return std::nullopt;
5654aa6d63Sopenharmony_ci    }
5754aa6d63Sopenharmony_ci    if (commentLength > 0) {
5854aa6d63Sopenharmony_ci        std::string readComment(commentLength, 0);
5954aa6d63Sopenharmony_ci        bf.GetData(&readComment[0], commentLength);
6054aa6d63Sopenharmony_ci        eocd->SetComment(readComment);
6154aa6d63Sopenharmony_ci    }
6254aa6d63Sopenharmony_ci    eocd->SetLength(EOCD_LENGTH + commentLength);
6354aa6d63Sopenharmony_ci    if (bf.Remaining() != 0) {
6454aa6d63Sopenharmony_ci        delete eocd;
6554aa6d63Sopenharmony_ci        SIGNATURE_TOOLS_LOGE("bf.Remaining() is not equal to 0, bf.Remaining(): %d", bf.Remaining());
6654aa6d63Sopenharmony_ci        return std::nullopt;
6754aa6d63Sopenharmony_ci    }
6854aa6d63Sopenharmony_ci    return std::make_optional(eocd);
6954aa6d63Sopenharmony_ci}
7054aa6d63Sopenharmony_ci
7154aa6d63Sopenharmony_civoid EndOfCentralDirectory::SetEndOfCentralDirectoryValues(ByteBuffer& bf, EndOfCentralDirectory* eocd)
7254aa6d63Sopenharmony_ci{
7354aa6d63Sopenharmony_ci    uint16_t eocdUInt16Value = 0;
7454aa6d63Sopenharmony_ci    bf.GetUInt16(eocdUInt16Value);
7554aa6d63Sopenharmony_ci    eocd->SetDiskNum(eocdUInt16Value);
7654aa6d63Sopenharmony_ci
7754aa6d63Sopenharmony_ci    bf.GetUInt16(eocdUInt16Value);
7854aa6d63Sopenharmony_ci    eocd->SetcDStartDiskNum(eocdUInt16Value);
7954aa6d63Sopenharmony_ci
8054aa6d63Sopenharmony_ci    bf.GetUInt16(eocdUInt16Value);
8154aa6d63Sopenharmony_ci    eocd->SetThisDiskCDNum(eocdUInt16Value);
8254aa6d63Sopenharmony_ci
8354aa6d63Sopenharmony_ci    bf.GetUInt16(eocdUInt16Value);
8454aa6d63Sopenharmony_ci    eocd->SetcDTotal(eocdUInt16Value);
8554aa6d63Sopenharmony_ci
8654aa6d63Sopenharmony_ci    uint32_t eocdUInt32Value;
8754aa6d63Sopenharmony_ci    bf.GetUInt32(eocdUInt32Value);
8854aa6d63Sopenharmony_ci    eocd->SetcDSize(eocdUInt32Value);
8954aa6d63Sopenharmony_ci
9054aa6d63Sopenharmony_ci    bf.GetUInt32(eocdUInt32Value);
9154aa6d63Sopenharmony_ci    eocd->SetOffset(eocdUInt32Value);
9254aa6d63Sopenharmony_ci
9354aa6d63Sopenharmony_ci    bf.GetUInt16(eocdUInt16Value);
9454aa6d63Sopenharmony_ci    eocd->SetCommentLength(eocdUInt16Value);
9554aa6d63Sopenharmony_ci}
9654aa6d63Sopenharmony_ci
9754aa6d63Sopenharmony_cistd::string EndOfCentralDirectory::ToBytes()
9854aa6d63Sopenharmony_ci{
9954aa6d63Sopenharmony_ci    ByteBuffer bf(m_length);
10054aa6d63Sopenharmony_ci
10154aa6d63Sopenharmony_ci    bf.PutInt32(SIGNATURE);
10254aa6d63Sopenharmony_ci    bf.PutUInt16(m_diskNum);
10354aa6d63Sopenharmony_ci    bf.PutUInt16(m_cDStartDiskNum);
10454aa6d63Sopenharmony_ci    bf.PutUInt16(m_thisDiskCDNum);
10554aa6d63Sopenharmony_ci    bf.PutUInt16(m_cDTotal);
10654aa6d63Sopenharmony_ci    bf.PutUInt32(m_cDSize);
10754aa6d63Sopenharmony_ci    bf.PutUInt32(m_offset);
10854aa6d63Sopenharmony_ci    bf.PutUInt16(m_commentLength);
10954aa6d63Sopenharmony_ci
11054aa6d63Sopenharmony_ci    if (m_commentLength > 0) {
11154aa6d63Sopenharmony_ci        bf.PutData(m_comment.data(), m_comment.size());
11254aa6d63Sopenharmony_ci    }
11354aa6d63Sopenharmony_ci
11454aa6d63Sopenharmony_ci    return bf.ToString();
11554aa6d63Sopenharmony_ci}
11654aa6d63Sopenharmony_ci
11754aa6d63Sopenharmony_ciint EndOfCentralDirectory::GetEocdLength()
11854aa6d63Sopenharmony_ci{
11954aa6d63Sopenharmony_ci    return EOCD_LENGTH;
12054aa6d63Sopenharmony_ci}
12154aa6d63Sopenharmony_ci
12254aa6d63Sopenharmony_ciint EndOfCentralDirectory::GetSIGNATURE()
12354aa6d63Sopenharmony_ci{
12454aa6d63Sopenharmony_ci    return SIGNATURE;
12554aa6d63Sopenharmony_ci}
12654aa6d63Sopenharmony_ci
12754aa6d63Sopenharmony_ciuint16_t EndOfCentralDirectory::GetDiskNum()
12854aa6d63Sopenharmony_ci{
12954aa6d63Sopenharmony_ci    return m_diskNum;
13054aa6d63Sopenharmony_ci}
13154aa6d63Sopenharmony_ci
13254aa6d63Sopenharmony_civoid EndOfCentralDirectory::SetDiskNum(uint16_t diskNum)
13354aa6d63Sopenharmony_ci{
13454aa6d63Sopenharmony_ci    m_diskNum = diskNum;
13554aa6d63Sopenharmony_ci}
13654aa6d63Sopenharmony_ci
13754aa6d63Sopenharmony_ciuint16_t EndOfCentralDirectory::GetcDStartDiskNum()
13854aa6d63Sopenharmony_ci{
13954aa6d63Sopenharmony_ci    return m_cDStartDiskNum;
14054aa6d63Sopenharmony_ci}
14154aa6d63Sopenharmony_ci
14254aa6d63Sopenharmony_civoid EndOfCentralDirectory::SetcDStartDiskNum(uint16_t cDStartDiskNum)
14354aa6d63Sopenharmony_ci{
14454aa6d63Sopenharmony_ci    m_cDStartDiskNum = cDStartDiskNum;
14554aa6d63Sopenharmony_ci}
14654aa6d63Sopenharmony_ci
14754aa6d63Sopenharmony_ciuint16_t EndOfCentralDirectory::GetThisDiskCDNum()
14854aa6d63Sopenharmony_ci{
14954aa6d63Sopenharmony_ci    return m_thisDiskCDNum;
15054aa6d63Sopenharmony_ci}
15154aa6d63Sopenharmony_ci
15254aa6d63Sopenharmony_civoid EndOfCentralDirectory::SetThisDiskCDNum(uint16_t thisDiskCDNum)
15354aa6d63Sopenharmony_ci{
15454aa6d63Sopenharmony_ci    m_thisDiskCDNum = thisDiskCDNum;
15554aa6d63Sopenharmony_ci}
15654aa6d63Sopenharmony_ci
15754aa6d63Sopenharmony_ciuint16_t EndOfCentralDirectory::GetcDTotal()
15854aa6d63Sopenharmony_ci{
15954aa6d63Sopenharmony_ci    return m_cDTotal;
16054aa6d63Sopenharmony_ci}
16154aa6d63Sopenharmony_ci
16254aa6d63Sopenharmony_civoid EndOfCentralDirectory::SetcDTotal(uint16_t cDTotal)
16354aa6d63Sopenharmony_ci{
16454aa6d63Sopenharmony_ci    m_cDTotal = cDTotal;
16554aa6d63Sopenharmony_ci}
16654aa6d63Sopenharmony_ci
16754aa6d63Sopenharmony_ciuint32_t EndOfCentralDirectory::GetcDSize()
16854aa6d63Sopenharmony_ci{
16954aa6d63Sopenharmony_ci    return m_cDSize;
17054aa6d63Sopenharmony_ci}
17154aa6d63Sopenharmony_ci
17254aa6d63Sopenharmony_civoid EndOfCentralDirectory::SetcDSize(uint32_t cDSize)
17354aa6d63Sopenharmony_ci{
17454aa6d63Sopenharmony_ci    m_cDSize = cDSize;
17554aa6d63Sopenharmony_ci}
17654aa6d63Sopenharmony_ci
17754aa6d63Sopenharmony_ciuint32_t EndOfCentralDirectory::GetOffset()
17854aa6d63Sopenharmony_ci{
17954aa6d63Sopenharmony_ci    return m_offset;
18054aa6d63Sopenharmony_ci}
18154aa6d63Sopenharmony_ci
18254aa6d63Sopenharmony_civoid EndOfCentralDirectory::SetOffset(uint32_t offset)
18354aa6d63Sopenharmony_ci{
18454aa6d63Sopenharmony_ci    m_offset = offset;
18554aa6d63Sopenharmony_ci}
18654aa6d63Sopenharmony_ci
18754aa6d63Sopenharmony_ciuint16_t EndOfCentralDirectory::GetCommentLength()
18854aa6d63Sopenharmony_ci{
18954aa6d63Sopenharmony_ci    return m_commentLength;
19054aa6d63Sopenharmony_ci}
19154aa6d63Sopenharmony_ci
19254aa6d63Sopenharmony_civoid EndOfCentralDirectory::SetCommentLength(uint16_t commentLength)
19354aa6d63Sopenharmony_ci{
19454aa6d63Sopenharmony_ci    m_commentLength = commentLength;
19554aa6d63Sopenharmony_ci}
19654aa6d63Sopenharmony_ci
19754aa6d63Sopenharmony_cistd::string EndOfCentralDirectory::GetComment()
19854aa6d63Sopenharmony_ci{
19954aa6d63Sopenharmony_ci    return m_comment;
20054aa6d63Sopenharmony_ci}
20154aa6d63Sopenharmony_ci
20254aa6d63Sopenharmony_civoid EndOfCentralDirectory::SetComment(const std::string& comment)
20354aa6d63Sopenharmony_ci{
20454aa6d63Sopenharmony_ci    m_comment = comment;
20554aa6d63Sopenharmony_ci}
20654aa6d63Sopenharmony_ci
20754aa6d63Sopenharmony_ciint EndOfCentralDirectory::GetLength()
20854aa6d63Sopenharmony_ci{
20954aa6d63Sopenharmony_ci    return m_length;
21054aa6d63Sopenharmony_ci}
21154aa6d63Sopenharmony_ci
21254aa6d63Sopenharmony_civoid EndOfCentralDirectory::SetLength(uint32_t length)
21354aa6d63Sopenharmony_ci{
21454aa6d63Sopenharmony_ci    m_length = length;
21554aa6d63Sopenharmony_ci}
21654aa6d63Sopenharmony_ci} // namespace SignatureTools
21754aa6d63Sopenharmony_ci} // namespace OHOS