#!/bin/bash -e # Parse the data directory of a PE/COFF file and returns two hex values: # the file offset and size of the signature table. function sigtable_params() { filename="$1" objdump -p "$filename" | awk '/^Entry 4/ {print "0x"$3 " " "0x"$4}' } # Extract the signature from a file containing a signature table, # and write to stdout function extract_sig() { filename="$1" cert_table_header_size=8 params=($(hexdump -n$cert_table_header_size \ -e '/4 "%u " /2 "%04x " /2 "%04x\n"' \ "$filename")) cert_size=${params[0]} cert_revision=${params[1]} cert_type=${params[2]} # check type & revision [ "$cert_revision" -eq '0200' ] [ "$cert_type" -eq '0002' ] dd if="$filename" bs=1 skip=$cert_table_header_size \ count=$(($cert_size - $cert_table_header_size)) 2>/dev/null } function repeat() { str=$1 count=$2 for (( i = 0; $i < $count; i++ )) do echo -n "$str" done } cert="test.cert" signed="test.signed" for i in {1..8} do # generate a variable-length parameter for the certificate subject subj="/CN=$(repeat 'x' $i)" # create a temporary cert, and sign the image with it openssl req -x509 -sha256 -subj "$subj" -new -key "$key" -out "$cert" "$sbsign" --cert "$cert" --key "$key" --output "$signed" "$image" # extract the sigtable params=($(sigtable_params "$signed")) # split and convert to base-10 sigtable_offset=$((${params[0]})) sigtable_size=$((${params[1]})) # check that we have a correctly-padded sigtable [ $(($sigtable_size % 8)) -eq 0 ] sigtable='test.sigtable' dd if="$signed" bs=1 skip=$sigtable_offset count=$sigtable_size \ of=$sigtable 2>/dev/null # extract sig, and feed to openssl's PKCS7 parser extract_sig "$sigtable" | openssl pkcs7 -inform DER -noout done