Add a script to generate builds signed using the official keys.

The script sign_official_build.sh does the appropriate signing depending on whether an ssd, recovery or factory-install image is desired.

Also re-factors some common functionality into common.sh.

BUG=3496
TEST=manual

I haven't had a chance to test this on an actual machine running our firmware but will do that before I actually check-in. Thoughts I'd atleast get this out to get the review going.

Review URL: http://codereview.chromium.org/3066034
diff --git a/scripts/image_signing/common.sh b/scripts/image_signing/common.sh
new file mode 100644
index 0000000..0d15cb4
--- /dev/null
+++ b/scripts/image_signing/common.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Determine script directory
+SCRIPT_DIR=$(dirname $0)
+GPT=cgpt
+
+# Read GPT table to find the starting location of a specific partition.
+# Args: DEVICE PARTNUM
+# Returns: offset (in sectors) of partition PARTNUM
+partoffset() {
+  sudo $GPT show -b -i $2 $1
+}
+
+# Read GPT table to find the size of a specific partition.
+# Args: DEVICE PARTNUM
+# Returns: size (in sectors) of partition PARTNUM
+partsize() {
+  sudo $GPT show -s -i $2 $1
+}
+
+# Mount a partition from an image into a local directory
+# Args: IMAGE PARTNUM MOUNTDIRECTORY
+mount_image_partition() {
+  local image=$1
+  local partnum=$2
+  local mount_dir=$3
+  local offset=$(partoffset "$image" "$partnum")
+  sudo mount -o loop,offset=$((offset * 512)) "$image" "$mount_dir"
+}
+
+# Extract a partition to a file
+# Args: IMAGE PARTNUM OUTPUTFILE
+extract_image_partition() {
+  local image=$1
+  local partnum=$2
+  local output_file=$3
+  local offset=$(partoffset "$image" "$partnum")
+  local size=$(partsize "$image" "$partnum")
+  dd if=$image of=$output_file bs=512 skip=$offset count=$size
+}
+  
diff --git a/scripts/image_signing/customize_image b/scripts/image_signing/customize_image.sh
similarity index 72%
rename from scripts/image_signing/customize_image
rename to scripts/image_signing/customize_image.sh
index 2496c39..08b5bd3 100755
--- a/scripts/image_signing/customize_image
+++ b/scripts/image_signing/customize_image.sh
@@ -10,7 +10,10 @@
 # The following changes are applied:
 # - Set the root password.
 
-# Usage: ./customize_image <image.bin> <root_password>
+# Usage: ./customize_image.sh <image.bin> <root_password>
+
+# Load common constants and variables.
+. "$(dirname "$0")/common.sh"
 
 readonly ROOTFS_DIR=$(mktemp -d)
 readonly GPT=cgpt
@@ -27,20 +30,6 @@
   exit 1
 }
 
-# Read GPT table to find the starting location of a specific partition.
-# Args: DEVICE PARTNUM
-# Returns: offset (in sectors) of partition PARTNUM
-partoffset() {
-  sudo $GPT show -b -i $2 $1
-}
-
-mount_image() {
-  local image=$1
-  echo "Mounting image '$image'..."
-  local offset=$(partoffset "$image" 3)
-  sudo mount -o loop,offset=$((offset * 512)) "$image" "$ROOTFS_DIR"
-}
-
 change_root_password() {
   local password=$1
   echo "Changing root password to '$password'..."
@@ -63,7 +52,7 @@
 
   set -e
   trap failure EXIT
-  mount_image "$image"
+  mount_image_partition "$image" 3 $ROOTFS_DIR
   change_root_password "$root_password"
   cleanup
   echo "Done."
diff --git a/scripts/image_signing/sign_official_build.sh b/scripts/image_signing/sign_official_build.sh
new file mode 100755
index 0000000..01e581b
--- /dev/null
+++ b/scripts/image_signing/sign_official_build.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Sign the final build image using the "official" keys.
+
+# Usage: sign_for_ssd.sh <type> input_image /path/to/keys/dir output_image
+# 
+# where <type> is one of:
+#               ssd  (sign an SSD image)
+#               recovery (sign a USB recovery image)               
+#               install (sign a factory install image) 
+
+# Load common constants and variables.
+. "$(dirname "$0")/common.sh"
+
+if [ $# -ne 4 ]; then
+  cat <<EOF
+Usage: $0 <type> input_image /path/to/keys/dir output_image"
+where <type> is one of:
+             ssd  (sign an SSD image)
+             recovery (sign a USB recovery image)               
+             install (sign a factory install image) 
+EOF
+  exit 1
+fi
+
+# Abort on errors.
+set -e
+
+TYPE=$1
+INPUT_IMAGE=$2
+KEY_DIR=$3
+OUTPUT_IMAGE=$4
+
+
+# Generate the SSD image
+sign_for_ssd() {
+  ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \
+    ${KEY_DIR}/kernel_data_key.vbprivk \
+    ${KEY_DIR}/kernel.keyblock
+  echo "Output signed SSD image to ${OUTPUT_IMAGE}"
+}
+
+# Generate the USB (recovery + install) image
+sign_for_recovery() {
+  ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \
+    ${KEY_DIR}/recovery_kernel_data_key.vbprivk \
+    ${KEY_DIR}/recovery_kernel.keyblock 
+
+  # Now generate the installer vblock with the SSD keys.
+  temp_kimage=$(mktemp)
+  trap "rm -f ${temp_kimage}" EXIT
+  temp_out_vb=$(mktemp)
+  trap "rm -f ${temp_out_vb}" EXIT
+  extract_image_partition ${OUTPUT_IMAGE} 2 ${temp_kimage}
+  ${SCRIPT_DIR}/resign_kernel_partition.sh ${temp_kimage} ${temp_out_vb} \
+    ${KEY_DIR}/kernel_data_key.vbprivk \
+    ${KEY_DIR}/kernel.keyblock
+
+  # Copy the installer vblock to the stateful partition.
+  local stateful_dir=$(mktemp -d)
+  trap "sudo umount -d $stateful_dir; rm -rf $stateful_dir" EXIT
+  mount_image_partition ${OUTPUT_IMAGE} 1 ${stateful_dir}
+  sudo cp ${temp_out_vb} ${stateful_dir}/vmlinuz_hd.vblock
+
+  echo "Output signed recovery image to ${OUTPUT_IMAGE}"
+}
+
+# Generate the factory install image.
+sign_for_factory_install() {
+  ${SCRIPT_DIR}/resign_image.sh ${INPUT_IMAGE} ${OUTPUT_IMAGE} \
+    ${KEY_DIR}/recovery_kernel_data_key.vbprivk \
+    ${KEY_DIR}/installer_kernel.keyblock
+  echo "Output signed factory install image to ${OUTPUT_IMAGE}"
+}
+
+if [ "${TYPE}" == "ssd" ]; then
+  sign_for_ssd
+elif [ "${TYPE}" == "recovery" ]; then
+  sign_for_recovery
+elif [ "${TYPE}" == "install" ]; then
+  sign_for_factory_install
+else
+  echo "Invalid type ${TYPE}"
+  exit 1
+fi
+  
+