Revert "update_engine: Deprecate major version 1"

This partially reverts commit 55c75417e22d5026971276997924a345d9973bbc.

It turns out that we forgot a scenario when we deprecated major version
1. We use update_engine in lab tests (specifically
autoupdate_EndToEndTests on stable channel) to update a DUT to an
old (very old) versions using actual update payloads so we can test that
they can get updated to newer versions. However, deprecating major
version 1 in the update_engine caused trouble because we no longer can
update from a newer version to a version before M72 (to prepare the
device for update test). We need to put this feature back until we find
a better solution for it.

On this CL, we only support major version 1 in the client and only for
test (non-official) images. We don't even bother adding paygen support
for it.

This CL should be reverted once we figured out what to do with
provisioning the autoupdate end to end tests.

BUG=chromium:1043428
TEST=FEATURES=test emerge-reef update_engine
TEST=cros deployed it, then cros flash using an m71 payload, it succeeded.

Change-Id: I1fecbe3ae845b2e419f0999adc53e4732b1f7696
Reviewed-on: https://chromium-review.googlesource.com/c/aosp/platform/system/update_engine/+/2013884
Reviewed-by: Tianjie Xu <xunchang@google.com>
Reviewed-by: Sen Jiang <senj@chromium.org>
Tested-by: Amin Hassani <ahassani@chromium.org>
Commit-Queue: Amin Hassani <ahassani@chromium.org>
diff --git a/payload_consumer/payload_metadata.cc b/payload_consumer/payload_metadata.cc
index b83001a..69ccb46 100644
--- a/payload_consumer/payload_metadata.cc
+++ b/payload_consumer/payload_metadata.cc
@@ -20,6 +20,7 @@
 
 #include <brillo/data_encoding.h>
 
+#include "update_engine/common/hardware_interface.h"
 #include "update_engine/common/hash_calculator.h"
 #include "update_engine/common/utils.h"
 #include "update_engine/payload_consumer/payload_constants.h"
@@ -36,18 +37,36 @@
 const uint64_t PayloadMetadata::kDeltaManifestSizeSize = 8;
 const uint64_t PayloadMetadata::kDeltaMetadataSignatureSizeSize = 4;
 
-uint64_t PayloadMetadata::GetMetadataSignatureSizeOffset() const {
-  return kDeltaManifestSizeOffset + kDeltaManifestSizeSize;
+bool PayloadMetadata::GetMetadataSignatureSizeOffset(
+    uint64_t* out_offset) const {
+  if (GetMajorVersion() == kBrilloMajorPayloadVersion) {
+    *out_offset = kDeltaManifestSizeOffset + kDeltaManifestSizeSize;
+    return true;
+  }
+  return false;
 }
 
-uint64_t PayloadMetadata::GetManifestOffset() const {
-  // Actual manifest begins right after the metadata signature size field.
-  return kDeltaManifestSizeOffset + kDeltaManifestSizeSize +
-         kDeltaMetadataSignatureSizeSize;
+bool PayloadMetadata::GetManifestOffset(uint64_t* out_offset) const {
+  // Actual manifest begins right after the manifest size field or
+  // metadata signature size field if major version >= 2.
+  if (major_payload_version_ == kChromeOSMajorPayloadVersion) {
+    *out_offset = kDeltaManifestSizeOffset + kDeltaManifestSizeSize;
+    return true;
+  }
+  if (major_payload_version_ == kBrilloMajorPayloadVersion) {
+    *out_offset = kDeltaManifestSizeOffset + kDeltaManifestSizeSize +
+                  kDeltaMetadataSignatureSizeSize;
+    return true;
+  }
+  LOG(ERROR) << "Unknown major payload version: " << major_payload_version_;
+  return false;
 }
 
 MetadataParseResult PayloadMetadata::ParsePayloadHeader(
-    const brillo::Blob& payload, ErrorCode* error) {
+    const brillo::Blob& payload,
+    HardwareInterface* hardware,
+    ErrorCode* error) {
+  uint64_t manifest_offset;
   // Ensure we have data to cover the major payload version.
   if (payload.size() < kDeltaManifestSizeOffset)
     return MetadataParseResult::kInsufficientData;
@@ -59,11 +78,6 @@
     return MetadataParseResult::kError;
   }
 
-  uint64_t manifest_offset = GetManifestOffset();
-  // Check again with the manifest offset.
-  if (payload.size() < manifest_offset)
-    return MetadataParseResult::kInsufficientData;
-
   // Extract the payload version from the metadata.
   static_assert(sizeof(major_payload_version_) == kDeltaVersionSize,
                 "Major payload version size mismatch");
@@ -73,14 +87,26 @@
   // Switch big endian to host.
   major_payload_version_ = be64toh(major_payload_version_);
 
-  if (major_payload_version_ < kMinSupportedMajorPayloadVersion ||
-      major_payload_version_ > kMaxSupportedMajorPayloadVersion) {
+  // We only want to test major version 1 for test images.
+  if (major_payload_version_ == kChromeOSMajorPayloadVersion
+          ? hardware != nullptr && hardware->IsOfficialBuild()
+          : major_payload_version_ < kMinSupportedMajorPayloadVersion ||
+                major_payload_version_ > kMaxSupportedMajorPayloadVersion) {
     LOG(ERROR) << "Bad payload format -- unsupported payload version: "
                << major_payload_version_;
     *error = ErrorCode::kUnsupportedMajorPayloadVersion;
     return MetadataParseResult::kError;
   }
 
+  // Get the manifest offset now that we have payload version.
+  if (!GetManifestOffset(&manifest_offset)) {
+    *error = ErrorCode::kUnsupportedMajorPayloadVersion;
+    return MetadataParseResult::kError;
+  }
+  // Check again with the manifest offset.
+  if (payload.size() < manifest_offset)
+    return MetadataParseResult::kInsufficientData;
+
   // Next, parse the manifest size.
   static_assert(sizeof(manifest_size_) == kDeltaManifestSizeSize,
                 "manifest_size size mismatch");
@@ -97,33 +123,43 @@
     return MetadataParseResult::kError;
   }
 
-  // Parse the metadata signature size.
-  static_assert(
-      sizeof(metadata_signature_size_) == kDeltaMetadataSignatureSizeSize,
-      "metadata_signature_size size mismatch");
-  uint64_t metadata_signature_size_offset = GetMetadataSignatureSizeOffset();
-  memcpy(&metadata_signature_size_,
-         &payload[metadata_signature_size_offset],
-         kDeltaMetadataSignatureSizeSize);
-  metadata_signature_size_ = be32toh(metadata_signature_size_);
+  if (GetMajorVersion() == kBrilloMajorPayloadVersion) {
+    // Parse the metadata signature size.
+    static_assert(
+        sizeof(metadata_signature_size_) == kDeltaMetadataSignatureSizeSize,
+        "metadata_signature_size size mismatch");
+    uint64_t metadata_signature_size_offset;
+    if (!GetMetadataSignatureSizeOffset(&metadata_signature_size_offset)) {
+      *error = ErrorCode::kError;
+      return MetadataParseResult::kError;
+    }
+    memcpy(&metadata_signature_size_,
+           &payload[metadata_signature_size_offset],
+           kDeltaMetadataSignatureSizeSize);
+    metadata_signature_size_ = be32toh(metadata_signature_size_);
 
-  if (metadata_size_ + metadata_signature_size_ < metadata_size_) {
-    // Overflow detected.
-    LOG(ERROR) << "Overflow detected on metadata and signature size.";
-    *error = ErrorCode::kDownloadInvalidMetadataSize;
-    return MetadataParseResult::kError;
+    if (metadata_size_ + metadata_signature_size_ < metadata_size_) {
+      // Overflow detected.
+      LOG(ERROR) << "Overflow detected on metadata and signature size.";
+      *error = ErrorCode::kDownloadInvalidMetadataSize;
+      return MetadataParseResult::kError;
+    }
   }
   return MetadataParseResult::kSuccess;
 }
 
-bool PayloadMetadata::ParsePayloadHeader(const brillo::Blob& payload) {
+bool PayloadMetadata::ParsePayloadHeader(const brillo::Blob& payload,
+                                         HardwareInterface* hardware) {
   ErrorCode error;
-  return ParsePayloadHeader(payload, &error) == MetadataParseResult::kSuccess;
+  return ParsePayloadHeader(payload, hardware, &error) ==
+         MetadataParseResult::kSuccess;
 }
 
 bool PayloadMetadata::GetManifest(const brillo::Blob& payload,
                                   DeltaArchiveManifest* out_manifest) const {
-  uint64_t manifest_offset = GetManifestOffset();
+  uint64_t manifest_offset;
+  if (!GetManifestOffset(&manifest_offset))
+    return false;
   CHECK_GE(payload.size(), manifest_offset + manifest_size_);
   return out_manifest->ParseFromArray(&payload[manifest_offset],
                                       manifest_size_);
@@ -145,7 +181,7 @@
                  << metadata_signature;
       return ErrorCode::kDownloadMetadataSignatureError;
     }
-  } else {
+  } else if (major_payload_version_ == kBrilloMajorPayloadVersion) {
     metadata_signature_protobuf_blob.assign(
         payload.begin() + metadata_size_,
         payload.begin() + metadata_size_ + metadata_signature_size_);
@@ -206,7 +242,7 @@
   brillo::Blob payload;
   TEST_AND_RETURN_FALSE(
       utils::ReadFileChunk(payload_path, 0, kMaxPayloadHeaderSize, &payload));
-  TEST_AND_RETURN_FALSE(ParsePayloadHeader(payload));
+  TEST_AND_RETURN_FALSE(ParsePayloadHeader(payload, nullptr));
 
   if (manifest != nullptr) {
     TEST_AND_RETURN_FALSE(
@@ -217,7 +253,8 @@
     TEST_AND_RETURN_FALSE(GetManifest(payload, manifest));
   }
 
-  if (metadata_signatures != nullptr) {
+  if (metadata_signatures != nullptr &&
+      GetMajorVersion() >= kBrilloMajorPayloadVersion) {
     payload.clear();
     TEST_AND_RETURN_FALSE(utils::ReadFileChunk(
         payload_path, GetMetadataSize(), GetMetadataSignatureSize(), &payload));