diff --git a/docs/en/update_signing-keys.pl b/docs/en/update_signing-keys.pl index 5cdc1006..3fcafec8 100755 --- a/docs/en/update_signing-keys.pl +++ b/docs/en/update_signing-keys.pl @@ -1,13 +1,46 @@ #!/usr/bin/env perl use strict; use warnings; +use Getopt::Long; +use Time::Piece; -# This script automatically updates the .wmi file with gpg as per: -my $keysfile = "include/keys.txt"; -my $wmifile = 'include/keys.wmi'; -my $fpfile = 'include/subkey_fingerprints.wmi'; -my $forcekeyupdates = 0; -my $skipkeyupdates = 0; +# Set Defaults +my %opts = ( + 'keysfile' => 'include/keys.txt', + 'wmifile' => 'include/keys.wmi', + 'fpfile' => 'include/subkey_fingerprints.wmi', + 'force-key-updates' => 0, + 'no-refresh-keys' => 0, + 'refresh-keys' => 1, # set >1 to always force +); + +sub print_help { + print " +This script loads the GPG keys of Tor Project release teams from +$opts{'keysfile'}, refreshes them and updates +$opts{'fpfile'} and $opts{'wmifile'} +which is included in docs/en/signing-keys.wml. + +It expects gpg >= v2.1 to be installed and working. + +Usage: $0 [options] +\t--keysfile\t\tPath to file with GPG key IDs (Default: $opts{'keysfile'}) +\t--wmifile\t\tPath to wmi file to be generated (Default: $opts{'wmifile'}) +\t--fpfile\t\tPath to wmi file for Tor Browser subkey fingerprints to be generated (Default: $opts{'fpfile'}) +\t--refresh-keys\t\tRefresh GPG keys no matter what. +\t--no-refresh-keys\tDon't refresh GPG keys.\n"; + exit 0; +} + +# Parse Options +GetOptions( + 'keysfile=s' => \$opts{'keysfile'}, + 'wmifile=s' => \$opts{'wmifile'}, + 'fpfile=s' => \$opts{'fpfile'}, + 'refresh-keys' => \$opts{'force-key-updates'}, + 'no-refresh-keys' => \$opts{'no-refresh-keys'}, + 'help' => sub { &print_help } +) or die "Error parsing arguments. Please try again.\n"; # First we load the keys, then we create a wmi file which is included by # https://www.torproject.org/docs/signing-keys.html.en @@ -17,9 +50,9 @@ $0 =~ /^(.+)\/[^\/]+$/; my $root = "$1/../.."; chdir $root or die "Could not enter $root: $! (script path: $0)\n"; +open my $kf, '<', $opts{'keysfile'} or die "Could not open $opts{'keysfile'}: $!\n"; -open my $kf, '<', "$keysfile" # read keys - or die "Could not open $keysfile: $!\n"; +## Load keys txt my %sections; # project => key owners my %owners; # key owner => string with all keys @@ -39,53 +72,51 @@ my $owner = "$1"; my $keys = "$2"; push( @{$sections{"$section"}}, $owner); - $owners{"$owner"} = "$keys"; + $owners{"$owner.$section"} = "$keys"; # tell about unrecognized lines } else { print "Ignored line: $_\n"; } } close $kf; my @owners = keys %owners; -print "Loaded $keysfile. Found $#owners key owners for $#apps applications.\n"; +print "Loaded $opts{'keysfile'}. Found $#owners key owners for $#apps applications.\n"; -# If the keysfile did not change since the last run, we will not update them. -# To update all keys anyway, set $forcekeyupdates = 1 above, or comment: -if (-f $wmifile && qx/[ $wmifile -nt $keysfile ]/) { - $forcekeyupdates or $skipkeyupdates++; -} + +## Update keys and generate wmi + +if ($opts{'no-refresh-keys'}) { + print "Not refreshing keys.\n"; + undef $opts{'refresh-keys'}; +} elsif ($opts{'force-key-updates'}) { + print "Refreshing keys requested.\n"; + $opts{'refresh-keys'}++; + # If the keysfile did not change since the last run, we will not update them. +} elsif (-f $opts{'wmifile'} && system "test $opts{'wmifile'} -ot $opts{'keysfile'}") { + print "No need to refresh keys.\n"; + $opts{'refresh-keys'}--; +} else { print "Wil refresh GPG keys.\n"; } my $buffer = ''; # project overview string my %fingerprints; foreach my $app (@apps) { - print "\nUpdating keys for '$app':\n"; - my ($keys, $subkey_fingerprints, $owners, $suf) = ('', '', '', 's'); + print "\nUpdating keys for '$app':\n" if ($opts{'refresh-keys'}); + my ($keys, $subkey_fingerprints, $owners) = ('', '', ''); my @keysforapp; # we grab the key owners for each project and iterate over their keys foreach my $owner (@{$sections{"$app"}}) { # iterate over owners - my $keys = $owners{"$owner"}; + my $keys = $owners{"$owner.$app"}; # example for $keys: 0x165733EA, 0x8D29319A(signing key) - my ($inbrackets, $inbrackets_html) = ('', ''); - $suf = '' if ($owners ne ''); + my ($inbrackets, $inbrackets_html); my @keys = split (',', $keys); foreach my $key (@keys) { # iterate over keys - # validate key format. all regexp are beautiful. - if ($key =~ /^\s?(0x[^\(]+)(\(([^\)]+)\))?/) { - my $key = $1; - my $keylink = "$key"; - push (@keysforapp, $key); - # named alternative key - if ($2) { - $inbrackets .= " with its $3 $key"; - # first key - } elsif ($inbrackets eq '') { - $inbrackets = "$key"; - $inbrackets_html = "$keylink"; - # second key - } else { - $inbrackets = " and $key"; + $key =~ s/\s*//g; + my $keylink = "$key"; + push (@keysforapp, $key); + unless ($inbrackets) { # first key + $inbrackets = $key; + $inbrackets_html = $keylink; + } else { # second key + $inbrackets .= " and $key"; $inbrackets_html .= " and $keylink"; - } - } else { # tell if the format is wrong - print "Unrecognized key format: $key\n"; } } my $sep = ($owners eq '') ? '' : ', '; @@ -93,18 +124,13 @@ $owners .= "$sep$owner ($inbrackets_html)"; print " - $owner ($inbrackets)\n"; } - if ($app eq 'other') { - $buffer .= "
\n$keys\n"; if ($app eq "Tor Browser releases") { my $owner = "The Tor Browser Developers"; - die "Did not findTor Browser signing key.\n" if ($owners{$owner} eq ''); + die "Did not findTor Browser signing key.\n" unless ($owners{"$owner.$app"}); # save Tor Browser signing key subkey fingerprints to $fpfile - my @fp = qx/$gpgcmd $owners{$owner}|grep "Key fingerprint"/; + my @fp = qx/$gpgcmd $owners{"$owner.$app"}|grep "Key fingerprint"/; shift @fp; # remove primary key fingerprint $subkey_fingerprints .= join ('', map { s/^\s+Key fingerprint = //; "$_" } @fp); - if (open my $fpout, '>', "$fpfile.temp") { + if (open my $fpout, '>', "$opts{'fpfile'}.temp") { print $fpout "#!/usr/bin/env wml\n$subkey_fingerprints"; close $fpout; # check that the written file is not empty - my $written_lines = qx/wc -l "$fpfile.temp"|wc -l/; + my $written_lines = qx/wc -l "$opts{'fpfile'}.temp"|wc -l/; if ($written_lines gt 0) { - rename "$fpfile.temp", "$fpfile" and - print "\nWrote following subkey fingerprints to $fpfile:\n$subkey_fingerprints" - or die "Could not overwrite $fpfile: $!\n"; - } else { die "Created $fpfile.temp but it is empty.\n"; } - } else { die "Could not create temporary file $fpfile.temp.\n"; } + rename "$opts{'fpfile'}.temp", $opts{'fpfile'} and + print "\nWrote following subkey fingerprints to $opts{'fpfile'}:\n$subkey_fingerprints\n" + or die "Could not overwrite $opts{'fpfile'}: $!\n"; + } else { die "Created $opts{'fpfile'}.temp but it is empty.\n"; } + } else { die "Could not create temporary file $opts{'fpfile'}.temp.\n"; } } } -my @date = localtime; -my $date = "$date[4]/$date[5]"; # Month/Year +my $date = localtime; +my $date_str = $date->strftime("%B %Y"); # month name year # print keys for each project to file -open my $html, '>', "$wmifile" - or die "Could not write to $wmifile; $!\n"; +open my $html, '>', $opts{'wmifile'} + or die "Could not write to $opts{'wmifile'}; $!\n"; print $html "#!/usr/bin/env wml
-This page was automatically generated page from
-this file listing the gpg keys of our release teams.
+This page lists GPG signing keys of our release
+teams as of $date_str.
To learn how to verify signatures, see \">
our manual.
-As of $date the signing keys we use are: -
The fingerprints for the keys are:
\n"; +\n"; foreach my $app (@apps) { print $html "
-This page was automatically generated page from
-this file listing the gpg keys of our release teams.
+This page lists GPG signing keys of our release
+teams as of November 2018.
To learn how to verify signatures, see
our manual.
-As of 8/118 the signing keys we use are: -
The fingerprints for the keys are:
+
pub rsa4096/0x4E2C6E8793298290 2014-12-15 [C] [expires: 2020-08-24]
Key fingerprint = EF6E 286D DA85 EA2A 4BA7 DE68 4E2C 6E87 9329 8290
uid [ unknown] Tor Browser Developers (signing key) <torbrowser#torproject.org>
sub rsa4096/0xEB774491D9FF06E2 2018-05-26 [S] [expires: 2020-09-12]
Key fingerprint = 1107 75B5 D101 FB36 BC6C 911B EB77 4491 D9FF 06E2
+
pub rsa8192/0x29846B3C683686CC 2013-09-11 [SC]
Key fingerprint = C963 C21D 6356 4E2B 10BB 335B 2984 6B3C 6836 86CC
uid [ unknown] Mike Perry <mikeperry#endarken.info>
uid [ unknown] Mike Perry <mikeperry#unencrypted.info>
uid [ unknown] Mike Perry (Regular use key) <mikeperry#fscked.org>
uid [ unknown] Mike Perry (Regular use key) <mikeperry#torproject.org>
-sub rsa4096/0x004AD1045BA0FE28 2017-10-31 [S] [expires: 2018-10-31]
- Key fingerprint = 7AB6 A050 C544 CB16 60A9 F1E9 004A D104 5BA0 FE28
-sub rsa4096/0xEEC50E9938F9F4E9 2017-10-31 [E] [expires: 2018-10-31]
- Key fingerprint = B403 E911 BA38 63DB ED82 C57C EEC5 0E99 38F9 F4E9
+
pub rsa4096/0x4E2C6E8793298290 2014-12-15 [C] [expires: 2020-08-24]
Key fingerprint = EF6E 286D DA85 EA2A 4BA7 DE68 4E2C 6E87 9329 8290
@@ -48,6 +42,7 @@ uid [ unknown] Tor Browser Developers (signing key) <torbro
sub rsa4096/0xEB774491D9FF06E2 2018-05-26 [S] [expires: 2020-09-12]
Key fingerprint = 1107 75B5 D101 FB36 BC6C 911B EB77 4491 D9FF 06E2
+
pub rsa4096/0x3E39CEABFC69F6F7 2015-09-24 [SC]
Key fingerprint = 6AB6 AEE9 776E 7827 23C8 ACE8 3E39 CEAB FC69 F6F7
uid [ unknown] Nicolas Vigier (boklm) <boklm#torproject.org>
@@ -59,6 +54,7 @@ sub rsa4096/0x07B7CFD7A0FBA062 2017-01-25 [S] [expires: 2019-01-22]
sub rsa4096/0x6DB4024DAA111CE4 2017-01-25 [E] [expires: 2019-01-22]
Key fingerprint = B995 3CFA C0C7 A2ED C780 24ED 6DB4 024D AA11 1CE4
+
pub rsa2048/0xD752F538C0D38C3A 2014-12-10 [SC]
Key fingerprint = 20B2 4CEF E6AF D615 0B6A 6F18 D752 F538 C0D3 8C3A
uid [ unknown] Arthur Edelstein <arthuredelstein#gmail.com>
@@ -68,6 +64,7 @@ sub rsa2048/0x3306E88D27211E0B 2014-12-10 [E]
+
pub dsa1024/0xEB5A896A28988BF5 2000-02-27 [SCA]
Key fingerprint = B117 2656 DFF9 83C3 042B C699 EB5A 896A 2898 8BF5
uid [ unknown] Roger Dingledine <arma#mit.edu>
@@ -78,6 +75,7 @@ pub rsa1024/0x9C01813428988BF5 2014-06-16 [SCEA] [revoked: 2016-08-16]
Key fingerprint = 2629 5471 A26A B9F9 6C0C 45BB 9C01 8134 2898 8BF5
uid [ revoked] Roger Dingledine <arma#mit.edu>
+
pub rsa4096/0xC218525819F78451 2010-05-07 [SC]
Key fingerprint = F65C E37F 04BA 5B36 0AE6 EE17 C218 5258 19F7 8451
uid [ unknown] Roger Dingledine <arma#mit.edu>
@@ -90,35 +88,18 @@ pub rsa4096/0x468FAE2919F78451 2014-06-16 [SCEA] [revoked: 2016-08-16]
Key fingerprint = 9C95 0D05 FC80 2DFA 79C3 7629 468F AE29 19F7 8451
uid [ revoked] Roger Dingledine <arma#mit.edu>
-pub rsa1024/0xD50624EC165733EA 2014-06-16 [SCEA] [revoked: 2016-08-16]
- Key fingerprint = 33DC 81DC C099 4E0A 10D8 048B D506 24EC 1657 33EA
-uid [ revoked] Nick Mathewson <nickm#alum.mit.edu>
-
-pub rsa3072/0x21194EBB165733EA 2004-07-03 [SC]
- Key fingerprint = B35B F85B F194 89D0 4E28 C33C 2119 4EBB 1657 33EA
-uid [ unknown] Nick Mathewson <nickm#alum.mit.edu>
-uid [ unknown] Nick Mathewson <nickm#wangafu.net>
-uid [ unknown] Nick Mathewson <nickm#freehaven.net>
-uid [ unknown] [jpeg image of size 3369]
-sub rsa3072/0x910397D88D29319A 2004-07-03 [S]
- Key fingerprint = EF00 F369 1387 FCC5 8CD6 8E13 9103 97D8 8D29 319A
-sub rsa3072/0xD2CA27F3F25B8E5E 2004-07-03 [E]
- Key fingerprint = 11F2 E464 48C8 0F44 8F64 FC54 D2CA 27F3 F25B 8E5E
-pub rsa3072/0x21194EBB165733EA 2004-07-03 [SC]
- Key fingerprint = B35B F85B F194 89D0 4E28 C33C 2119 4EBB 1657 33EA
+pub rsa4096/0xFE43009C4607B1FB 2016-09-21 [C] [expires: 2019-09-21]
+ Key fingerprint = 2133 BC60 0AB1 33E1 D826 D173 FE43 009C 4607 B1FB
uid [ unknown] Nick Mathewson <nickm#alum.mit.edu>
uid [ unknown] Nick Mathewson <nickm#wangafu.net>
uid [ unknown] Nick Mathewson <nickm#freehaven.net>
-uid [ unknown] [jpeg image of size 3369]
-sub rsa3072/0x910397D88D29319A 2004-07-03 [S]
- Key fingerprint = EF00 F369 1387 FCC5 8CD6 8E13 9103 97D8 8D29 319A
-sub rsa3072/0xD2CA27F3F25B8E5E 2004-07-03 [E]
- Key fingerprint = 11F2 E464 48C8 0F44 8F64 FC54 D2CA 27F3 F25B 8E5E
+uid [ unknown] Nick Mathewson <nickm#torproject.org>
+
pub rsa1024/0xD50624EC165733EA 2014-06-16 [SCEA] [revoked: 2016-08-16]
Key fingerprint = 33DC 81DC C099 4E0A 10D8 048B D506 24EC 1657 33EA
uid [ revoked] Nick Mathewson <nickm#alum.mit.edu>
@@ -134,6 +115,7 @@ sub rsa3072/0x910397D88D29319A 2004-07-03 [S]
sub rsa3072/0xD2CA27F3F25B8E5E 2004-07-03 [E]
Key fingerprint = 11F2 E464 48C8 0F44 8F64 FC54 D2CA 27F3 F25B 8E5E
+
pub rsa3072/0x21194EBB165733EA 2004-07-03 [SC]
Key fingerprint = B35B F85B F194 89D0 4E28 C33C 2119 4EBB 1657 33EA
uid [ unknown] Nick Mathewson <nickm#alum.mit.edu>
@@ -148,6 +130,7 @@ sub rsa3072/0xD2CA27F3F25B8E5E 2004-07-03 [E]
+
pub rsa2048/0xEE8CBC9E886DDD89 2009-09-04 [SC] [expires: 2022-08-05]
Key fingerprint = A3C4 F0F9 79CA A22C DBA8 F512 EE8C BC9E 886D DD89
uid [ unknown] deb.torproject.org archive signing key
@@ -157,6 +140,7 @@ sub rsa2048/0x74A941BA219EC810 2009-09-04 [S] [expires: 2020-11-23]
+
pub rsa1024/0xF94ABB509ABBEEC6 2014-06-16 [SCEA] [revoked: 2016-08-16]
Key fingerprint = D8AA CF11 9067 89E8 91DD 2C27 F94A BB50 9ABB EEC6
uid [ revoked] Damian Johnson (www.atagar.com) <atagar1#gmail.com>
@@ -173,6 +157,7 @@ sub elg2048/0x04F1B63D146276B2 2009-06-17 [E]
+
pub rsa4096/0xDBB802B258ACD84F 2015-01-18 [C] [expires: 2020-01-11]
Key fingerprint = A490 D0F4 D311 A415 3E2B B7CA DBB8 02B2 58AC D84F
uid [ unknown] Tails developers (offline long-term identity key) <tails#boum.org>
@@ -189,6 +174,7 @@ sub rsa4096/0xA8B0F4E45B1B50E2 2018-08-30 [S] [expires: 2020-01-11]
+
pub rsa2048/0x42E86A2A11F48D36 2011-05-11 [SC] [expires: 2019-05-01]
Key fingerprint = B744 17ED DF22 AC9F 9E90 F491 42E8 6A2A 11F4 8D36
uid [ unknown] David Goulet <dgoulet#ev0ke.net>
@@ -200,6 +186,7 @@ sub rsa4096/0x2AC6036C93CC198D 2013-09-10 [E] [expires: 2019-08-17]
+
pub rsa4096/0xB01C8B006DA77FAA 2016-02-25 [SC] [expires: 2020-02-24]
Key fingerprint = E4AC D397 5427 A5BA 8450 A1BE B01C 8B00 6DA7 7FAA
uid [ unknown] Sukhbir Singh <azadi#riseup.net>
@@ -210,6 +197,7 @@ sub rsa4096/0x1AF20C043D9F9289 2016-02-25 [E] [expires: 2020-02-24]
+
pub rsa4096/0x62AF4031C82E0039 2003-03-24 [SC] [expires: 2024-08-28]
Key fingerprint = 25FC 1614 B8F8 7B52 FF2F 99B9 62AF 4031 C82E 0039
uid [ unknown] Peter Palfrader