| // | 
 | // 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/common/platform_constants.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); | 
 |   // 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 a man-in-the-middle 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; | 
 |  | 
 |   // 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_ |