//
// Copyright (C) 2018 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_PAYLOAD_METADATA_H_
#define UPDATE_ENGINE_PAYLOAD_CONSUMER_PAYLOAD_METADATA_H_

#include <inttypes.h>

#include <string>
#include <vector>

#include <base/macros.h>
#include <brillo/secure_blob.h>

#include "update_engine/common/error_code.h"
#include "update_engine/payload_consumer/payload_verifier.h"
#include "update_engine/update_metadata.pb.h"

namespace chromeos_update_engine {

enum class MetadataParseResult {
  kSuccess,
  kError,
  kInsufficientData,
};

// This class parses payload metadata and validate its signature.
class PayloadMetadata {
 public:
  static const uint64_t kDeltaVersionOffset;
  static const uint64_t kDeltaVersionSize;
  static const uint64_t kDeltaManifestSizeOffset;
  static const uint64_t kDeltaManifestSizeSize;
  static const uint64_t kDeltaMetadataSignatureSizeSize;

  PayloadMetadata() = default;

  // Attempts to parse the update payload header starting from the beginning of
  // |payload|. On success, returns kMetadataParseSuccess. Returns
  // kMetadataParseInsufficientData if more data is needed to parse the complete
  // metadata. Returns kMetadataParseError if the metadata can't be parsed given
  // the payload.
  MetadataParseResult ParsePayloadHeader(const brillo::Blob& payload,
                                         ErrorCode* error);
  MetadataParseResult ParsePayloadHeader(const unsigned char* payload,
                                         size_t size,
                                         ErrorCode* error);
  // Simpler version of the above, returns true on success.
  bool ParsePayloadHeader(const brillo::Blob& payload);

  // Given the |payload|, verifies that the signed hash of its metadata matches
  // |metadata_signature| (if present) or the metadata signature in payload
  // itself (if present). Returns ErrorCode::kSuccess on match or a suitable
  // error code otherwise. This method must be called before any part of the
  // metadata is parsed so that an on-path attack on the SSL connection
  // to the payload server doesn't exploit any vulnerability in the code that
  // parses the protocol buffer.
  ErrorCode ValidateMetadataSignature(
      const brillo::Blob& payload,
      const std::string& metadata_signature,
      const PayloadVerifier& payload_verifier) const;

  // Returns the major payload version. If the version was not yet parsed,
  // returns zero.
  uint64_t GetMajorVersion() const { return major_payload_version_; }

  // Returns the size of the payload metadata, which includes the payload header
  // and the manifest. If the header was not yet parsed, returns zero.
  uint64_t GetMetadataSize() const { return metadata_size_; }

  // Returns the size of the payload metadata signature. If the header was not
  // yet parsed, returns zero.
  uint32_t GetMetadataSignatureSize() const { return metadata_signature_size_; }

  // Set |*out_manifest| to the manifest in |payload|.
  // Returns true on success.
  bool GetManifest(const brillo::Blob& payload,
                   DeltaArchiveManifest* out_manifest) const;

  bool GetManifest(const unsigned char* payload,
                   size_t size,
                   DeltaArchiveManifest* out_manifest) const;

  // Parses a payload file |payload_path| and prepares the metadata properties,
  // manifest and metadata signatures. Can be used as an easy to use utility to
  // get the payload information without manually the process.
  bool ParsePayloadFile(const std::string& payload_path,
                        DeltaArchiveManifest* manifest,
                        Signatures* metadata_signatures);

 private:
  // Returns the byte offset at which the manifest protobuf begins in a payload.
  uint64_t GetManifestOffset() const;

  // Returns the byte offset where the size of the metadata signature is stored
  // in a payload.
  uint64_t GetMetadataSignatureSizeOffset() const;

  uint64_t metadata_size_{0};
  uint64_t manifest_size_{0};
  uint32_t metadata_signature_size_{0};
  uint64_t major_payload_version_{0};

  DISALLOW_COPY_AND_ASSIGN(PayloadMetadata);
};

}  // namespace chromeos_update_engine

#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_PAYLOAD_METADATA_H_
