File: mozilla-trust-gen.sh

package info (click to toggle)
libwebsockets 4.3.5-3
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 31,404 kB
  • sloc: ansic: 194,409; javascript: 1,550; sh: 1,387; cpp: 505; java: 461; perl: 405; xml: 118; makefile: 76; awk: 5
file content (194 lines) | stat: -rwxr-xr-x 6,340 bytes parent folder | download | duplicates (2)
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#!/bin/bash

# This script fetches the current list of trusted CAs blessed by Mozilla
# for web tls validation, and processes it into two outputs
#
# - ./trust/webroot/* consisting of ./_trust/webroot/der  a static, serveable set
#     of trusted DER certs, with symlinks in ./_trust/webroot/by-skid and
#     ./_trust/webroot/by-iss allowing serving the DER matching a given
#     SubjectKeyIdentifier or Issuer + serial combination (suitably encoded)
#
# - ./_trust/blob-XXXX.bin  a single blob containing indexes and DER CA certs
#
# - ./_trust/trust_blob.h   a C uint8_t array formatted copy of blob-XXXX.bin

# The trust blob layout is currently
#
# 54 42 4c 42     Magic "TBLB"
# 00 01           MSB-first trust blob layout version
# XX XX           MSB-first count of certificates
# XX XX XX XX     MSB-first trust blob generation unix time
# XX XX XX XX     MSB-first offset of cert length table (MSB-first 16-bit length-per-cert)
# XX XX XX XX     MSB-first offset of SKID length table (8-bit length-per-cert)
# XX XX XX XX     MSB-first offset of SKID table
# XX XX XX XX     MSB-first total blob length
#
# XX .. XX        DER certs (start at +0x1c)
# XX .. XX        DER cert length table (MSB-first 16-bit per cert)
# XX .. XX        SKID length table (8-bit per cert)
# XX .. XX        SKID table (variable per cert)
#

echo "Mozilla trust bundle for TLS validation processing  Andy Green <andy@warmcat.com>"
echo

rm -rf _trust
mkdir _trust

wget -O _trust/trusted.txt "https://ccadb-public.secure.force.com/mozilla/IncludedRootsPEMTxt?TrustBitsInclude=Websites"
#cp ~/Downloads/IncludedRootsPEM.txt _trust/trusted.txt

if [ $? -ne 0 ]; then
	echo "Failed to get current website trust bundle"
	exit 1
fi

mkdir -p _trust/webroot/by-skid _trust/webroot/by-iss _trust/webroot/der

echo 0 > _trust/ofs
echo 0 > _trust/count
echo 0 > _trust/skidtab

GT=`date +%s`
BN=_trust/blob-$GT.bin

cat _trust/trusted.txt | while read _line ; do
	line=`echo -n $_line | sed 's/\r$//g'`
	if [ "$line" == "-----BEGIN CERTIFICATE-----" ] ; then
		echo $line > _trust/single
	else
		echo $line >> _trust/single

		if [ "$line" == "-----END CERTIFICATE-----" ] ; then
			openssl x509 -in _trust/single -text -noout > _trust/c1
			if [ $? -ne 0 ] ; then
				echo "FAILED"
				exit 1
			fi

			ISS=`cat _trust/c1 | grep Issuer: | sed "s/.*://g" | sed "s/^\ *//g"`
			SER=`cat _trust/c1 | grep "Serial Number:" | sed "s/.*://g" | sed "s/^\ *//g" | sed "s/\ .*//g"`
			if [ -z "$SER" ] ; then
				SER=`cat _trust/c1 | sed -e "1,/.*Serial Number:/ d" | head -n 1 | sed "s/^\ *//g" | sed "s/\ .*//g"`
			fi
			SKID=`cat _trust/c1 | sed -e '1,/.*X509v3 Subject Key Identifier:/ d' | sed -n '/Signature.*/q;p' | \
				grep ':' | grep -v ': ' | grep -v ':$' | grep -v U | grep -v k | grep -v T | grep -v "i" | \
				grep -v "S" | grep -v "V" | sed "s/^\ *//g"`
			SKID_NO_COLONS=`echo -n $SKID | sed "s/://g"`

			na=`cat _trust/c1 | grep "Not\ After\ :" | sed "s/.*\ :\ //g"`
			ct=`date +%s`
			ts=`date --date="$na" +%s`
			life_days=`echo -n "$(( ( $ts - $ct ) / 86400 ))"`

			echo "$life_days $safe" >> _trust/life
			if [ $life_days -lt 1095 ] ; then
				echo "$life_days $safe" >> _trust/life_lt_3y
			fi

			echo "issuer=\"$ISS\", serial=\"${SER^^}\", skid=\"${SKID_NO_COLONS^^}\", life_days=\"${life_days}\""

			issname=`echo -n "$ISS"_"$SER" | tr -cd '[a-zA-Z0-9]_'`
			skidname=`echo -n "$SKID_NO_COLONS" | tr -cd '[a-zA-Z0-9]_'`
			safe=$issname"_"$skidname

			cat _trust/single | grep -v -- '---' | base64 -d > _trust/webroot/der/$safe
			cd _trust/webroot/by-skid
			ln -sf ../der/$safe $SKID_NO_COLONS
			cd ../../..
			cd _trust/webroot/by-iss
			ln -sf ../der/$safe $issname
			cd ../../..

			DERSIZ=`cat _trust/single | grep -v -- '---' | base64 -d | wc -c | cut -d' ' -f1`

			cat _trust/single | grep -v -- '---' | base64 -d | hexdump -C | tr -s ' ' | sed 's/\ $//g' | \
				cut -d' ' -f 2-17 | cut -d'|' -f1 | grep -v 000 | sed "s/\ //g" | sed ':a;N;$!ba;s/\n//g' | xxd -r -p >> _trust/_ders

			printf "%04x" $DERSIZ | xxd -r -p  >> _trust/_derlens

echo $SKID

			if [ ! -z "$SKID" ] ; then
				echo -n "$SKID_NO_COLONS" | xxd -r -p >> _trust/_skid
			fi
			SKIDSIZ=`echo -n $SKID_NO_COLONS | xxd -r -p | wc -c | cut -d' ' -f1`
			printf "%02x" $SKIDSIZ | xxd -r -p  >> _trust/_skidlens

			OFS=`cat _trust/ofs`
			echo -n $(( $OFS + $DERSIZ )) > _trust/ofs
			COUNT=`cat _trust/count`
			echo -n $(( $COUNT +1 )) > _trust/count
			ST=`cat _trust/skidtab`
			echo -n $(( $ST + ( `echo -n $skidname | wc -c | cut -d' ' -f1` / 2 ) )) > _trust/skidtab

			rm -f _trust/single

		fi
	fi

done

	COUNT=`cat _trust/count`
	OFS=`cat _trust/ofs`
	ST=`cat _trust/skidtab`

	# everything in the layout framing is MSB-first

	# magic
	echo -n "TBLB" > $BN
	# blob layout version
	echo -n 0001 | xxd -r -p >> $BN
	# number of certs in the blob
	printf "%04x" $COUNT | xxd -r -p >> $BN
	# unix time blob was created
	printf "%08x" $GT | xxd -r -p >> $BN

	POS=28
	POS=$(( $POS + `cat _trust/_ders | wc -c | cut -d' ' -f1` ))

	# blob offset of start of cert length table
	printf "%08x" $POS | xxd -r -p >> $BN

	POS=$(( $POS + `cat _trust/_derlens | wc -c | cut -d' ' -f1` ))

	# blob offset of start of SKID length table
	printf "%08x" $POS | xxd -r -p >> $BN

	POS=$(( $POS + `cat _trust/_skidlens | wc -c | cut -d' ' -f1` ))

	# blob offset of start of SKID table
	printf "%08x" $POS | xxd -r -p >> $BN

	POS=$(( $POS + `cat _trust/_skid | wc -c | cut -d' ' -f1` ))

	# blob total length
	printf "%08x" $POS | xxd -r -p >> $BN


	# the DER table, start at +0x1c
	cat _trust/_ders >> $BN
	# the DER length table
	cat _trust/_derlens >> $BN
	# the SKID length table
	cat _trust/_skidlens >> $BN
	# the SKID table
	cat _trust/_skid >> $BN

# produce a C-friendly version of the blob

	cat $BN | hexdump -v -C | tr -s ' ' | sed 's/\ $//g' | \
		cut -d' ' -f 2-17 | cut -d'|' -f1 | grep -v 000 | sed "s/\ /,\ 0x/g" | sed "s/^/0x/g" | \
		sed 's/\, 0x$//g' | sed 's/$/,/g' >> _trust/trust_blob.h


	echo
	echo "$COUNT CA certs, $POS byte blob"
	echo
	echo "CAs expiring in less than 3 years (days left):"
	sort -h _trust/life_lt_3y

	rm -f _trust/count _trust/_idx _trust/_idx_skid _trust/ofs _trust/_skid _trust/skidtab _trust/life _trust/life_lt_3y _trust/c1 _trust/single _trust/_derlens _trust/_ders _trust/_skid _trust/_skidlens

exit 0