1#!/bin/bash
2set -eo pipefail
3
4help=$'Generate Tarball with PSU image and MANIFEST Script
5usage: generate-psu-tar [OPTION] <parameter>...
6Options:
7   --image        <file>          PSU FW image
8   --version      <version>       PSU FW version
9   --model        <model>         PSU FW model
10   --manufacture  <version>       PSU FW manufacture
11   --machineName  <machineName>   Optionally specify the target machine name of this image.
12   --outfile      <filename>      Outfile name
13		                  For example : -o psufw.tar
14                                  The default outfile name is image.tar,and
15                                  "image" is what you input.
16   --sign         <path>          Sign the image. The optional path argument specifies
17                                  the private key file. Defaults to the bash variable
18                                  PRIVATE_KEY_PATH if available, or else uses the
19                                  open-source private key in this script.
20   --help                         Display this help text and exit.
21'
22
23private_key=$'-----BEGIN PRIVATE KEY-----
24MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAPvSDLu6slkP1gri
25PaeQXL9ysD69J/HjbBCIQ0RPfeWBb75US1tRTjPP0Ub8CtH8ExVf8iF1ulsZA78B
26zIjBYZVp9pyD6LbpZ/hjV7rIH6dTNhoVpdA+F8LzmQ7cyhHG8l2JMvdunwF2uX5k
27D4WDcZt/ITKZNQNavPtmIyD5HprdAgMBAAECgYEAuQkTSi5ZNpAoWz76xtGRFSwU
28zUT4wQi3Mz6tDtjKTYXasiQGa0dHC1M9F8fDu6BZ9W7W4Dc9hArRcdzEighuxoI/
29nZI/0uL89iUEywnDEIHuS6D5JlZaj86/nx9YvQnO8F/seM+MX0EAWVrd5wC7aAF1
30h6Fu7ykZB4ggUjQAWwECQQD+AUiDOEO+8btLJ135dQfSGc5VFcZiequnKWVm6uXt
31rX771hEYjYMjLqWGFg9G4gE3GuABM5chMINuQQUivy8tAkEA/cxfy19XkjtqcMgE
32x/UDt6Nr+Ky/tk+4Y65WxPRDas0uxFOPk/vEjgVmz1k/TAy9G4giisluTvtmltr5
33DCLocQJBAJnRHx9PiD7uVhRJz6/L/iNuOzPtTsi+Loq5F83+O6T15qsM1CeBMsOw
34cM5FN5UeMcwz+yjfHAsePMkcmMaU7jUCQHlg9+N8upXuIo7Dqj2zOU7nMmkgvSNE
355yuNImRZabC3ZolwaTdd7nf5r1y1Eyec5Ag5yENV6JKPe1Xkbb1XKJECQDngA0h4
366ATvfP1Vrx4CbP11eKXbCsZ9OGPHSgyvVjn68oY5ZP3uPsIattoN7dE2BRfuJm7m
37F0nIdUAhR0yTfKM=
38-----END PRIVATE KEY-----
39'
40
41do_sign=false
42# shellcheck disable=SC2153
43private_key_path="${PRIVATE_KEY_PATH}"
44image=""
45outfile=""
46version=""
47model=""
48manufacture=""
49machineName=""
50
51
52while [[ $# -gt 0 ]]; do
53  key="$1"
54  case $key in
55    --image)
56      image="$2"
57      shift 2
58      ;;
59    --version)
60      version="$2"
61      shift 2
62      ;;
63    --model)
64      model="$2"
65      shift 2
66      ;;
67    --manufacture)
68      manufacture="$2"
69      shift 2
70      ;;
71    --machineName)
72      machineName="$2"
73      shift 2
74      ;;
75    --outfile)
76      outfile="$2"
77      shift 2
78      ;;
79    --sign)
80      do_sign=true
81      if [[ -n "${2}"  && "${2}" != -* ]]; then
82        private_key_path="$2"
83        shift 2
84      else
85        shift 1
86      fi
87      ;;
88    --help)
89      echo "$help"
90      exit
91      ;;
92    *)
93      echo "Please enter the correct parameters."
94      echo "$help"
95      exit 1
96      ;;
97  esac
98done
99
100if [ ! -f "${image}" ]; then
101  echo "Please enter a valid PSU FW image file."
102  echo "$help"
103  exit 1
104fi
105
106if [  -z "${version}" ]; then
107  echo "Please enter a valid PSU FW image version."
108  echo "$help"
109  exit 1
110fi
111
112
113if [  -z "${model}" ]; then
114  echo "Please enter a valid PSU FW image model."
115  echo "$help"
116  exit 1
117fi
118
119if [  -z "${manufacture}" ]; then
120  echo "Please enter a valid PSU FW image manufacture."
121  echo "$help"
122  exit 1
123fi
124
125if [  -z "${outfile}" ]; then
126    outfile=$(pwd)/$image.tar
127else
128    outfile=$(pwd)/$outfile
129fi
130
131scratch_dir=$(mktemp -d)
132# shellcheck disable=SC2064
133trap "{ rm -r ${scratch_dir}; }" EXIT
134
135if [[ "${do_sign}" == true ]]; then
136  if [[ -z "${private_key_path}" ]]; then
137    private_key_path=${scratch_dir}/OpenBMC.priv
138    echo "${private_key}" > "${private_key_path}"
139    echo "Image is NOT secure!! Signing with the open private key!"
140  else
141    if [[ ! -f "${private_key_path}" ]]; then
142      echo "Couldn't find private key ${private_key_path}."
143      exit 1
144    fi
145
146    echo "Signing with ${private_key_path}."
147  fi
148
149  public_key_file=publickey
150  public_key_path=${scratch_dir}/$public_key_file
151  openssl pkey -in "${private_key_path}" -pubout -out "${public_key_path}"
152
153  cp "${private_key_path}" "${scratch_dir}/private_key"
154
155fi
156
157manifest_location="MANIFEST"
158files_to_sign="$manifest_location $public_key_file $image"
159
160cp "${image}" "${scratch_dir}"
161cd "${scratch_dir}"
162
163echo "Creating MANIFEST for the image"
164echo -e "purpose=xyz.openbmc_project.Software.Version.VersionPurpose.PSU\nversion=$version\n\
165extended_version=model=$model,manufacture=$manufacture" > $manifest_location
166
167if [[ -n "${machineName}" ]]; then
168    echo -e "MachineName=${machineName}" >> $manifest_location
169fi
170
171if [[ "${do_sign}" == true ]]; then
172  private_key_name=$(basename "${private_key_path}")
173  key_type="${private_key_name%.*}"
174  echo KeyType="${key_type}" >> $manifest_location
175  echo HashType="RSA-SHA256" >> $manifest_location
176
177  for file in $files_to_sign; do
178    openssl dgst -sha256 -sign private_key -out "${file}.sig" "$file"
179  done
180
181  additional_files="*.sig"
182fi
183
184tar -cvf "$outfile" "$files_to_sign" "$additional_files"
185echo "PSU FW tarball at $outfile"
186exit
187