xref: /aosp_15_r20/external/libwebsockets/scripts/mozilla-trust-gen.sh (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1#!/bin/bash
2
3# This script fetches the current list of trusted CAs blessed by Mozilla
4# for web tls validation, and processes it into two outputs
5#
6# - ./trust/webroot/* consisting of ./_trust/webroot/der  a static, serveable set
7#     of trusted DER certs, with symlinks in ./_trust/webroot/by-skid and
8#     ./_trust/webroot/by-iss allowing serving the DER matching a given
9#     SubjectKeyIdentifier or Issuer + serial combination (suitably encoded)
10#
11# - ./_trust/blob-XXXX.bin  a single blob containing indexes and DER CA certs
12#
13# - ./_trust/trust_blob.h   a C uint8_t array formatted copy of blob-XXXX.bin
14
15# The trust blob layout is currently
16#
17# 54 42 4c 42     Magic "TBLB"
18# 00 01           MSB-first trust blob layout version
19# XX XX           MSB-first count of certificates
20# XX XX XX XX     MSB-first trust blob generation unix time
21# XX XX XX XX     MSB-first offset of cert length table (MSB-first 16-bit length-per-cert)
22# XX XX XX XX     MSB-first offset of SKID length table (8-bit length-per-cert)
23# XX XX XX XX     MSB-first offset of SKID table
24# XX XX XX XX     MSB-first total blob length
25#
26# XX .. XX        DER certs (start at +0x1c)
27# XX .. XX        DER cert length table (MSB-first 16-bit per cert)
28# XX .. XX        SKID length table (8-bit per cert)
29# XX .. XX        SKID table (variable per cert)
30#
31
32echo "Mozilla trust bundle for TLS validation processing  Andy Green <[email protected]>"
33echo
34
35rm -rf _trust
36mkdir _trust
37
38wget -O _trust/trusted.txt "https://ccadb-public.secure.force.com/mozilla/IncludedRootsPEMTxt?TrustBitsInclude=Websites"
39#cp ~/Downloads/IncludedRootsPEM.txt _trust/trusted.txt
40
41if [ $? -ne 0 ]; then
42	echo "Failed to get current website trust bundle"
43	exit 1
44fi
45
46mkdir -p _trust/webroot/by-skid _trust/webroot/by-iss _trust/webroot/der
47
48echo 0 > _trust/ofs
49echo 0 > _trust/count
50echo 0 > _trust/skidtab
51
52GT=`date +%s`
53BN=_trust/blob-$GT.bin
54
55cat _trust/trusted.txt | while read _line ; do
56	line=`echo -n $_line | sed 's/\r$//g'`
57	if [ "$line" == "-----BEGIN CERTIFICATE-----" ] ; then
58		echo $line > _trust/single
59	else
60		echo $line >> _trust/single
61
62		if [ "$line" == "-----END CERTIFICATE-----" ] ; then
63			openssl x509 -in _trust/single -text -noout > _trust/c1
64			if [ $? -ne 0 ] ; then
65				echo "FAILED"
66				exit 1
67			fi
68
69			ISS=`cat _trust/c1 | grep Issuer: | sed "s/.*://g" | sed "s/^\ *//g"`
70			SER=`cat _trust/c1 | grep "Serial Number:" | sed "s/.*://g" | sed "s/^\ *//g" | sed "s/\ .*//g"`
71			if [ -z "$SER" ] ; then
72				SER=`cat _trust/c1 | sed -e "1,/.*Serial Number:/ d" | head -n 1 | sed "s/^\ *//g" | sed "s/\ .*//g"`
73			fi
74			SKID=`cat _trust/c1 | sed -e '1,/.*X509v3 Subject Key Identifier:/ d' | sed -n '/Signature.*/q;p' | \
75				grep ':' | grep -v ': ' | grep -v ':$' | grep -v U | grep -v k | grep -v T | grep -v "i" | \
76				grep -v "S" | grep -v "V" | sed "s/^\ *//g"`
77			SKID_NO_COLONS=`echo -n $SKID | sed "s/://g"`
78
79			na=`cat _trust/c1 | grep "Not\ After\ :" | sed "s/.*\ :\ //g"`
80			ct=`date +%s`
81			ts=`date --date="$na" +%s`
82			life_days=`echo -n "$(( ( $ts - $ct ) / 86400 ))"`
83
84			echo "$life_days $safe" >> _trust/life
85			if [ $life_days -lt 1095 ] ; then
86				echo "$life_days $safe" >> _trust/life_lt_3y
87			fi
88
89			echo "issuer=\"$ISS\", serial=\"${SER^^}\", skid=\"${SKID_NO_COLONS^^}\", life_days=\"${life_days}\""
90
91			issname=`echo -n "$ISS"_"$SER" | tr -cd '[a-zA-Z0-9]_'`
92			skidname=`echo -n "$SKID_NO_COLONS" | tr -cd '[a-zA-Z0-9]_'`
93			safe=$issname"_"$skidname
94
95			cat _trust/single | grep -v -- '---' | base64 -d > _trust/webroot/der/$safe
96			cd _trust/webroot/by-skid
97			ln -sf ../der/$safe $SKID_NO_COLONS
98			cd ../../..
99			cd _trust/webroot/by-iss
100			ln -sf ../der/$safe $issname
101			cd ../../..
102
103			DERSIZ=`cat _trust/single | grep -v -- '---' | base64 -d | wc -c | cut -d' ' -f1`
104
105			cat _trust/single | grep -v -- '---' | base64 -d | hexdump -C | tr -s ' ' | sed 's/\ $//g' | \
106				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
107
108			printf "%04x" $DERSIZ | xxd -r -p  >> _trust/_derlens
109
110echo $SKID
111
112			if [ ! -z "$SKID" ] ; then
113				echo -n "$SKID_NO_COLONS" | xxd -r -p >> _trust/_skid
114			fi
115			SKIDSIZ=`echo -n $SKID_NO_COLONS | xxd -r -p | wc -c | cut -d' ' -f1`
116			printf "%02x" $SKIDSIZ | xxd -r -p  >> _trust/_skidlens
117
118			OFS=`cat _trust/ofs`
119			echo -n $(( $OFS + $DERSIZ )) > _trust/ofs
120			COUNT=`cat _trust/count`
121			echo -n $(( $COUNT +1 )) > _trust/count
122			ST=`cat _trust/skidtab`
123			echo -n $(( $ST + ( `echo -n $skidname | wc -c | cut -d' ' -f1` / 2 ) )) > _trust/skidtab
124
125			rm -f _trust/single
126
127		fi
128	fi
129
130done
131
132	COUNT=`cat _trust/count`
133	OFS=`cat _trust/ofs`
134	ST=`cat _trust/skidtab`
135
136	# everything in the layout framing is MSB-first
137
138	# magic
139	echo -n "TBLB" > $BN
140	# blob layout version
141	echo -n 0001 | xxd -r -p >> $BN
142	# number of certs in the blob
143	printf "%04x" $COUNT | xxd -r -p >> $BN
144	# unix time blob was created
145	printf "%08x" $GT | xxd -r -p >> $BN
146
147	POS=28
148	POS=$(( $POS + `cat _trust/_ders | wc -c | cut -d' ' -f1` ))
149
150	# blob offset of start of cert length table
151	printf "%08x" $POS | xxd -r -p >> $BN
152
153	POS=$(( $POS + `cat _trust/_derlens | wc -c | cut -d' ' -f1` ))
154
155	# blob offset of start of SKID length table
156	printf "%08x" $POS | xxd -r -p >> $BN
157
158	POS=$(( $POS + `cat _trust/_skidlens | wc -c | cut -d' ' -f1` ))
159
160	# blob offset of start of SKID table
161	printf "%08x" $POS | xxd -r -p >> $BN
162
163	POS=$(( $POS + `cat _trust/_skid | wc -c | cut -d' ' -f1` ))
164
165	# blob total length
166	printf "%08x" $POS | xxd -r -p >> $BN
167
168
169	# the DER table, start at +0x1c
170	cat _trust/_ders >> $BN
171	# the DER length table
172	cat _trust/_derlens >> $BN
173	# the SKID length table
174	cat _trust/_skidlens >> $BN
175	# the SKID table
176	cat _trust/_skid >> $BN
177
178# produce a C-friendly version of the blob
179
180	cat $BN | hexdump -v -C | tr -s ' ' | sed 's/\ $//g' | \
181		cut -d' ' -f 2-17 | cut -d'|' -f1 | grep -v 000 | sed "s/\ /,\ 0x/g" | sed "s/^/0x/g" | \
182		sed 's/\, 0x$//g' | sed 's/$/,/g' >> _trust/trust_blob.h
183
184
185	echo
186	echo "$COUNT CA certs, $POS byte blob"
187	echo
188	echo "CAs expiring in less than 3 years (days left):"
189	sort -h _trust/life_lt_3y
190
191	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
192
193exit 0
194
195