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