18e920a95Sopenharmony_ci/*
28e920a95Sopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
38e920a95Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48e920a95Sopenharmony_ci * you may not use this file except in compliance with the License.
58e920a95Sopenharmony_ci * You may obtain a copy of the License at
68e920a95Sopenharmony_ci *
78e920a95Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88e920a95Sopenharmony_ci *
98e920a95Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108e920a95Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118e920a95Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128e920a95Sopenharmony_ci * See the License for the specific language governing permissions and
138e920a95Sopenharmony_ci * limitations under the License.
148e920a95Sopenharmony_ci */
158e920a95Sopenharmony_ci
168e920a95Sopenharmony_ci#ifndef CODE_SIGN_FSVERITY_UTILS_HELPER_H
178e920a95Sopenharmony_ci#define CODE_SIGN_FSVERITY_UTILS_HELPER_H
188e920a95Sopenharmony_ci
198e920a95Sopenharmony_ci#include <cerrno>
208e920a95Sopenharmony_ci#include <cstdint>
218e920a95Sopenharmony_ci#include <cstdlib>
228e920a95Sopenharmony_ci#include <cstring>
238e920a95Sopenharmony_ci#include <fcntl.h>
248e920a95Sopenharmony_ci#include <libfsverity.h>
258e920a95Sopenharmony_ci#include <sys/stat.h>
268e920a95Sopenharmony_ci#include <unistd.h>
278e920a95Sopenharmony_ci
288e920a95Sopenharmony_ci#include "errcode.h"
298e920a95Sopenharmony_ci#include "byte_buffer.h"
308e920a95Sopenharmony_ci#include "log.h"
318e920a95Sopenharmony_ci
328e920a95Sopenharmony_cinamespace OHOS {
338e920a95Sopenharmony_cinamespace Security {
348e920a95Sopenharmony_cinamespace CodeSign {
358e920a95Sopenharmony_ciclass FsverityUtilsHelper {
368e920a95Sopenharmony_cipublic:
378e920a95Sopenharmony_ci    static FsverityUtilsHelper &GetInstance();
388e920a95Sopenharmony_ci    bool GenerateFormattedDigest(const char *path, ByteBuffer &ret);
398e920a95Sopenharmony_ci    static void ErrorMsgLogCallback(const char *msg);
408e920a95Sopenharmony_ci
418e920a95Sopenharmony_ciprivate:
428e920a95Sopenharmony_ci    FsverityUtilsHelper();
438e920a95Sopenharmony_ci    ~FsverityUtilsHelper();
448e920a95Sopenharmony_ci
458e920a95Sopenharmony_ci    FsverityUtilsHelper(const FsverityUtilsHelper &source) = delete;
468e920a95Sopenharmony_ci    FsverityUtilsHelper &operator = (const FsverityUtilsHelper &source) = delete;
478e920a95Sopenharmony_ci
488e920a95Sopenharmony_ci    void Init();
498e920a95Sopenharmony_ci    bool ComputeDigest(const char *path, struct libfsverity_digest **digest);
508e920a95Sopenharmony_ci    bool FormatDigest(libfsverity_digest *digest, uint8_t *buffer);
518e920a95Sopenharmony_ci
528e920a95Sopenharmony_ci    class FileReader {
538e920a95Sopenharmony_ci    public:
548e920a95Sopenharmony_ci        bool Open(const char *path)
558e920a95Sopenharmony_ci        {
568e920a95Sopenharmony_ci            if (fd_ > 0) {
578e920a95Sopenharmony_ci                LOG_ERROR("File is already opened.");
588e920a95Sopenharmony_ci                return false;
598e920a95Sopenharmony_ci            }
608e920a95Sopenharmony_ci            fd_ = open(path, O_RDONLY);
618e920a95Sopenharmony_ci            if (fd_ <= 0) {
628e920a95Sopenharmony_ci                LOG_ERROR("Open file failed, path = %{public}s, errno = <%{public}d, %{public}s>",
638e920a95Sopenharmony_ci                    path, errno, strerror(errno));
648e920a95Sopenharmony_ci                return false;
658e920a95Sopenharmony_ci            }
668e920a95Sopenharmony_ci            return true;
678e920a95Sopenharmony_ci        }
688e920a95Sopenharmony_ci
698e920a95Sopenharmony_ci        bool GetFileSize(uint64_t *size)
708e920a95Sopenharmony_ci        {
718e920a95Sopenharmony_ci            struct stat st;
728e920a95Sopenharmony_ci            if (fstat(fd_, &st) != 0) {
738e920a95Sopenharmony_ci                LOG_ERROR("Stat file failed, errno = <%{public}d, %{public}s>",
748e920a95Sopenharmony_ci                    errno, strerror(errno));
758e920a95Sopenharmony_ci                return false;
768e920a95Sopenharmony_ci            }
778e920a95Sopenharmony_ci            *size = st.st_size;
788e920a95Sopenharmony_ci            return true;
798e920a95Sopenharmony_ci        }
808e920a95Sopenharmony_ci
818e920a95Sopenharmony_ci        ~FileReader()
828e920a95Sopenharmony_ci        {
838e920a95Sopenharmony_ci            if (fd_ > 0) {
848e920a95Sopenharmony_ci                close(fd_);
858e920a95Sopenharmony_ci                fd_ = -1;
868e920a95Sopenharmony_ci            }
878e920a95Sopenharmony_ci        }
888e920a95Sopenharmony_ci
898e920a95Sopenharmony_ci        static int ReadFileCallback(void *f, void *buf, size_t count)
908e920a95Sopenharmony_ci        {
918e920a95Sopenharmony_ci            FileReader *reader = static_cast<FileReader *>(f);
928e920a95Sopenharmony_ci            return reader->ReadBytes(static_cast<uint8_t *>(buf), count);
938e920a95Sopenharmony_ci        }
948e920a95Sopenharmony_ci
958e920a95Sopenharmony_ci    private:
968e920a95Sopenharmony_ci        int ReadBytes(uint8_t *buf, size_t count)
978e920a95Sopenharmony_ci        {
988e920a95Sopenharmony_ci            if (fd_ <= 0) {
998e920a95Sopenharmony_ci                return CS_ERR_FILE_READ;
1008e920a95Sopenharmony_ci            }
1018e920a95Sopenharmony_ci            while (count) {
1028e920a95Sopenharmony_ci                ssize_t bytesRead = read(fd_, buf, count);
1038e920a95Sopenharmony_ci                if (bytesRead <= 0) {
1048e920a95Sopenharmony_ci                    return CS_ERR_FILE_READ;
1058e920a95Sopenharmony_ci                }
1068e920a95Sopenharmony_ci                buf += bytesRead;
1078e920a95Sopenharmony_ci                count -= static_cast<size_t>(bytesRead);
1088e920a95Sopenharmony_ci            }
1098e920a95Sopenharmony_ci            return CS_SUCCESS;
1108e920a95Sopenharmony_ci        }
1118e920a95Sopenharmony_ci
1128e920a95Sopenharmony_ci        int fd_ = -1;
1138e920a95Sopenharmony_ci    };
1148e920a95Sopenharmony_ci};
1158e920a95Sopenharmony_ci}
1168e920a95Sopenharmony_ci}
1178e920a95Sopenharmony_ci}
1188e920a95Sopenharmony_ci#endif