summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deymo <deymo@chromium.org>2015-11-03 17:50:08 -0800
committerchrome-bot <chrome-bot@chromium.org>2015-11-11 14:56:47 -0800
commitde38188abe87e2bfbaeb14c19833ae2667c16346 (patch)
tree3b56adcce204f5e7b77e925297e0db2055cf61d3
parentf8369fde766ef811a5a65fecf2b405d3ad59736b (diff)
downloadchromite-de38188abe87e2bfbaeb14c19833ae2667c16346.tar.gz
cros payload: --signatures flag shows the metadata signatures
The existing --signatures flag now dumps the metadata signatures embedded in the payload. BUG=None TEST=Added unittests; manually check a signed payload. Change-Id: I4e2eb5cafeabbafd40af31716840d405a79b1023 Reviewed-on: https://chromium-review.googlesource.com/310654 Commit-Ready: Alex Deymo <deymo@chromium.org> Tested-by: Alex Deymo <deymo@chromium.org> Reviewed-by: Sen Jiang <senj@chromium.org>
-rw-r--r--cli/cros/cros_payload.py41
-rw-r--r--cli/cros/cros_payload_unittest.py64
2 files changed, 77 insertions, 28 deletions
diff --git a/cli/cros/cros_payload.py b/cli/cros/cros_payload.py
index 61c41417a..9581b597d 100644
--- a/cli/cros/cros_payload.py
+++ b/cli/cros/cros_payload.py
@@ -8,7 +8,6 @@ from __future__ import print_function
import itertools
import os
-import string
import sys
import textwrap
@@ -37,7 +36,7 @@ def DisplayHexData(data, indent=0):
' '.join('%.2x' % ord(c) for c in chunk) +
' ' * (16 - len(chunk)) +
' | ' +
- ''.join(c if c in string.printable else '.' for c in chunk))
+ ''.join(c if 32 <= ord(c) and ord(c) < 127 else '.' for c in chunk))
@command.CommandDecorator('payload')
@@ -101,22 +100,38 @@ Example:
def _DisplaySignatures(self):
"""Show information about the signatures from the manifest."""
- manifest = self.payload.manifest
- if not manifest.HasField('signatures_offset'):
- print('No signatures stored in the payload')
- return
+ header = self.payload.header
+ if header.metadata_signature_len:
+ offset = header.size + header.manifest_len
+ DisplayValue('Metadata signatures blob',
+ 'file_offset=%d (%d bytes)' %
+ (offset, header.metadata_signature_len))
+ signatures_blob = self.payload.ReadDataBlob(
+ -header.metadata_signature_len,
+ header.metadata_signature_len)
+ self._DisplaySignaturesBlob('Metadata', signatures_blob)
+ else:
+ print('No metadata signatures stored in the payload')
- signature_msg = 'offset=%d' % manifest.signatures_offset
- if manifest.signatures_size:
- signature_msg += ' (%d bytes)' % manifest.signatures_size
- DisplayValue('Signature blob', signature_msg)
- signatures_blob = self.payload.ReadDataBlob(manifest.signatures_offset,
- manifest.signatures_size)
+ manifest = self.payload.manifest
+ if manifest.HasField('signatures_offset'):
+ signature_msg = 'blob_offset=%d' % manifest.signatures_offset
+ if manifest.signatures_size:
+ signature_msg += ' (%d bytes)' % manifest.signatures_size
+ DisplayValue('Payload signatures blob', signature_msg)
+ signatures_blob = self.payload.ReadDataBlob(manifest.signatures_offset,
+ manifest.signatures_size)
+ self._DisplaySignaturesBlob('Payload', signatures_blob)
+ else:
+ print('No payload signatures stored in the payload')
+ @staticmethod
+ def _DisplaySignaturesBlob(signature_name, signatures_blob):
from dev.host.lib.update_payload import update_metadata_pb2
signatures = update_metadata_pb2.Signatures()
signatures.ParseFromString(signatures_blob)
- print('Payload signatures: (%d entries)' % len(signatures.signatures))
+ print('%s signatures: (%d entries)' %
+ (signature_name, len(signatures.signatures)))
for signature in signatures.signatures:
print(' version=%s, hex_data: (%d bytes)' %
(signature.version if signature.HasField('version') else None,
diff --git a/cli/cros/cros_payload_unittest.py b/cli/cros/cros_payload_unittest.py
index f8fd78d20..36f4749bd 100644
--- a/cli/cros/cros_payload_unittest.py
+++ b/cli/cros/cros_payload_unittest.py
@@ -93,19 +93,32 @@ class FakeManifest(object):
"""Fake HasField method based on the python members."""
return hasattr(self, field_name) and getattr(self, field_name) is not None
+class FakeHeader(object):
+ """Fake payload header for testing."""
+
+ def __init__(self, version, manifest_len, metadata_signature_len):
+ self.version = version
+ self.manifest_len = manifest_len
+ self.metadata_signature_len = metadata_signature_len
+
+ @property
+ def size(self):
+ return (20 if self.version == cros_payload.MAJOR_PAYLOAD_VERSION_CHROMEOS
+ else 24)
+
+
class FakePayload(object):
"""Fake payload for testing."""
def __init__(self, major_version):
- FakeHeader = collections.namedtuple('FakeHeader',
- ['version', 'manifest_len'])
- self._header = FakeHeader(major_version, 222)
+ self._header = FakeHeader(major_version, 222, 0)
self.header = None
self._manifest = FakeManifest(major_version)
self.manifest = None
self._blobs = {}
- self._signatures = update_metadata_pb2.Signatures()
+ self._payload_signatures = update_metadata_pb2.Signatures()
+ self._metadata_signatures = update_metadata_pb2.Signatures()
def Init(self):
"""Fake Init that sets header and manifest.
@@ -126,15 +139,28 @@ class FakePayload(object):
'actual: %d)' % (len(blob), length))
return blob
- def AddSignature(self, **kwargs):
- new_signature = self._signatures.signatures.add()
+ @staticmethod
+ def _AddSignatureToProto(proto, **kwargs):
+ """Add a new Signature element to the passed proto."""
+ new_signature = proto.signatures.add()
for key, val in kwargs.iteritems():
setattr(new_signature, key, val)
- blob = self._signatures.SerializeToString()
+
+ def AddPayloadSignature(self, **kwargs):
+ self._AddSignatureToProto(self._payload_signatures, **kwargs)
+ blob = self._payload_signatures.SerializeToString()
self._manifest.signatures_offset = 1234
self._manifest.signatures_size = len(blob)
self._blobs[self._manifest.signatures_offset] = blob
+ def AddMetadataSignature(self, **kwargs):
+ self._AddSignatureToProto(self._metadata_signatures, **kwargs)
+ if self._header.metadata_signature_len:
+ del self._blobs[-self._header.metadata_signature_len]
+ blob = self._metadata_signatures.SerializeToString()
+ self._header.metadata_signature_len = len(blob)
+ self._blobs[-len(blob)] = blob
+
class PayloadCommandTest(cros_test_lib.MockOutputTestCase):
"""Test class for our PayloadCommand class."""
@@ -298,7 +324,8 @@ Number of operations: 1
Number of kernel ops: 1
Block size: 4096
Minor version: 4
-No signatures stored in the payload
+No metadata signatures stored in the payload
+No payload signatures stored in the payload
"""
self.assertEquals(stdout, expected_out)
@@ -307,22 +334,29 @@ No signatures stored in the payload
"""Verify that the --signatures option shows the present signatures."""
payload_cmd = cros_payload.PayloadCommand(
FakeOption(action='show', signatures=True))
- payload = FakePayload(cros_payload.MAJOR_PAYLOAD_VERSION_CHROMEOS)
- payload.AddSignature(version=1, data='12345678abcdefgh\x00\x01\x02\x03')
- payload.AddSignature(data='I am a signature so access is yes.')
+ payload = FakePayload(cros_payload.MAJOR_PAYLOAD_VERSION_BRILLO)
+ payload.AddPayloadSignature(version=1,
+ data='12345678abcdefgh\x00\x01\x02\x03')
+ payload.AddPayloadSignature(data='I am a signature so access is yes.')
+ payload.AddMetadataSignature(data='\x00\x0a\x0c')
self.PatchObject(update_payload, 'Payload', return_value=payload)
with self.OutputCapturer() as output:
payload_cmd.Run()
stdout = output.GetStdout()
- expected_out = """Payload version: 1
+ expected_out = """Payload version: 2
Manifest length: 222
-Number of operations: 1
-Number of kernel ops: 1
+Number of partitions: 2
+ Number of "rootfs" ops: 1
+ Number of "kernel" ops: 1
Block size: 4096
Minor version: 4
-Signature blob: offset=1234 (64 bytes)
+Metadata signatures blob: file_offset=246 (7 bytes)
+Metadata signatures: (1 entries)
+ version=None, hex_data: (3 bytes)
+ 00 0a 0c | ...
+Payload signatures blob: blob_offset=1234 (64 bytes)
Payload signatures: (2 entries)
version=1, hex_data: (20 bytes)
31 32 33 34 35 36 37 38 61 62 63 64 65 66 67 68 | 12345678abcdefgh