forked from coreos/scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
core_sign_update
executable file
·118 lines (96 loc) · 3.33 KB
/
core_sign_update
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/bin/bash
# Copyright (c) 2014 CoreOS, Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# usage: ./core_generate_update_payload --image coreos_production_update.bin \
# --output update.gz \
# --private_keys update.key.pem:update2.key.pem
# --public_keys update.pub.pem:update2.pub.pem
SCRIPT_ROOT=$(dirname $(readlink -f "$0"))
# We have to simple-mindedly set GCLIENT_ROOT in case we're running from
# au-generator.zip because common.sh will fail while auto-detect it.
export GCLIENT_ROOT=$(readlink -f "${SCRIPT_ROOT}/../../")
. "${SCRIPT_ROOT}/common.sh" || exit 1
DEFINE_string image "" "The image that should be sent to clients."
DEFINE_string output "" "Output file"
DEFINE_string private_keys "" "Path to private key in .pem format."
DEFINE_string public_keys "" "Path to public key in .pem format."
# Parse command line
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
set -e
cleanup() {
rm -f padding
rm -f update
rm -f update.hash
rm -f update.padhash
rm -f update.signed
rm -f update.sig.*
}
trap cleanup INT TERM EXIT
delta_generator \
-new_image "$FLAGS_image" \
-out_file update
IFS=: read -a private_keys <<< "$FLAGS_private_keys"
IFS=: read -a public_keys <<< "$FLAGS_public_keys"
if [ ${#private_keys} -ne ${#public_keys} ]; then
echo "mismatch in count of private keys and public keys"
exit 1
fi
i=0
signature_sizes=""
for key in "${private_keys[@]}"; do
signature_sizes=${signature_sizes}:256
let "i += 1"
done
signature_sizes="${signature_sizes:1:${#signature_sizes}}"
delta_generator \
--signature_size ${signature_sizes} \
--in_file update \
--out_hash_file update.hash
# The following is a standard PKCS1-v1_5 padding for SHA256 signatures, as
# defined in RFC3447. It is prepended to the actual signature (32 bytes) to
# form a sequence of 256 bytes (2048 bits) that is amenable to RSA signing. The
# padded hash will look as follows:
#
# 0x00 0x01 0xff ... 0xff 0x00 ASN1HEADER SHA256HASH
# |--------------205-----------||----19----||----32----|
#
# where ASN1HEADER is the ASN.1 description of the signed data. The complete 51
# bytes of actual data (i.e. the ASN.1 header complete with the hash) are
# packed as follows:
#
# SEQUENCE(2+49) {
# SEQUENCE(2+13) {
# OBJECT(2+9) id-sha256
# NULL(2+0)
# }
# OCTET STRING(2+32) <actual signature bytes...>
# }
echo "AAH/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ADAxMA0GCWCGSAFlAwQCAQUABCA=" | base64 -d > padding
cat padding update.hash > update.padhash
i=1
signature_sizes=""
for key in "${private_keys[@]}"; do
openssl rsautl -raw -sign -inkey ${key} -in update.padhash -out update.sig.${i}
let "i += 1"
done
files=""
for i in update.sig.*; do
files=${files}:${i}
done
files="${files:1:${#files}}"
echo ${files}
delta_generator --signature_file ${files} --in_file update --out_file update.signed
i=1
for key in "${public_keys[@]}"; do
delta_generator \
--public_key_version "${i}" \
--public_key "${key}" \
--in_file update.signed
let "i += 1"
done
mv update.signed ${FLAGS_output}
trap - INT TERM EXIT
cleanup noexit
echo "Done generating full update."