1515from datetime import datetime , timezone
1616
1717import click
18+ import gnupg
1819import parver # type: ignore
1920import requests
2021
@@ -37,13 +38,15 @@ def download_tzdb_tarballs(
3738 """Download the tzdata and tzcode tarballs."""
3839 tzdata_file = f"tzdata{ version } .tar.gz"
3940 tzcode_file = f"tzcode{ version } .tar.gz"
41+ tzdata_file_asc = tzdata_file + ".asc"
42+ tzcode_file_asc = tzcode_file + ".asc"
4043
4144 target_dir = working_dir / version / "download"
4245 # mkdir -p target_dir
4346 target_dir .mkdir (parents = True , exist_ok = True )
4447
4548 download_locations = []
46- for filename in [tzdata_file , tzcode_file ]:
49+ for filename in [tzdata_file , tzcode_file , tzdata_file_asc , tzcode_file_asc ]:
4750 download_location = target_dir / filename
4851 download_locations .append (download_location )
4952
@@ -58,6 +61,25 @@ def download_tzdb_tarballs(
5861 with open (download_location , "wb" ) as f :
5962 f .write (r .content )
6063
64+ # Verify tarballs
65+ gpg_home = tempfile .TemporaryDirectory ()
66+ gpg = gnupg .GPG (gnupghome = gpg_home .name )
67+ gpg .recv_keys ("hkps://keyserver.ubuntu.com" , "ed97e90e62aa7e34" )
68+
69+ for tar , asc in [(tzdata_file , tzdata_file_asc ), (tzcode_file , tzcode_file_asc )]:
70+ tar_path = target_dir / tar
71+ sig_path = target_dir / asc
72+
73+ if not tar_path .exists () or not sig_path .exists ():
74+ raise FileNotFoundError (
75+ f"Missing file or signature: { tar_path } , { sig_path } "
76+ )
77+
78+ with open (sig_path , "rb" ) as f :
79+ check = gpg .verify_file (f , str (tar_path ))
80+ if not check .valid :
81+ raise RuntimeError (f"signature verification failed for { tar_path } " )
82+
6183 return download_locations
6284
6385
@@ -95,7 +117,7 @@ def retrieve_local_tarballs(
95117def unpack_tzdb_tarballs (
96118 download_locations : Sequence [pathlib .Path ],
97119) -> pathlib .Path :
98- assert len (download_locations ) == 2
120+ assert len (download_locations ) == 4
99121 assert download_locations [0 ].parent == download_locations [1 ].parent
100122 base_dir = download_locations [0 ].parent .parent
101123 target_dir = base_dir / "tzdb"
@@ -107,6 +129,8 @@ def unpack_tzdb_tarballs(
107129 target_dir .mkdir ()
108130
109131 for tarball in download_locations :
132+ if tarball .suffix == ".asc" :
133+ continue
110134 logging .info ("Unpacking %s to %s" , tarball , target_dir )
111135 subprocess .run (
112136 ["tar" , "-xf" , os .fspath (tarball .absolute ())],
0 commit comments