aboutsummaryrefslogtreecommitdiff
path: root/SBO-Lib/lib/SBO/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'SBO-Lib/lib/SBO/Lib')
-rw-r--r--SBO-Lib/lib/SBO/Lib/Cryptography.pm114
-rw-r--r--SBO-Lib/lib/SBO/Lib/Repo.pm30
2 files changed, 106 insertions, 38 deletions
diff --git a/SBO-Lib/lib/SBO/Lib/Cryptography.pm b/SBO-Lib/lib/SBO/Lib/Cryptography.pm
index 4fca277..0022b8f 100644
--- a/SBO-Lib/lib/SBO/Lib/Cryptography.pm
+++ b/SBO-Lib/lib/SBO/Lib/Cryptography.pm
@@ -10,22 +10,36 @@ use Cwd;
use File::Temp "tempdir";
use IPC::Open3;
+use Exporter 'import';
+
+# Minimal definitions of some GPG raw output messages.
use constant {
- BAD_SIGNATURE => 'bad signature',
- EXPIRED_KEY => 'expired key',
- VALID_SIGNATURE => 'good signature',
+ BADSIG => 'bad signature',
+ EXPSIG => 'signature expired',
+ EXPKEYSIG => 'signed by expired key',
+ ERRSIG => 'signature verification not possible',
+ GOODSIG => 'good signature',
+ REVKEYSIG => 'good signature by revoked public key',
+ NO_PUBKEY => 'public key unavailable',
+ VALIDSIG => 'valid signature',
+ # An unknown message type.
+ UNKNOWN => 'unknown',
};
-use Exporter 'import';
-
our @EXPORT_OK = qw{
- has_valid_gpg_signature
import_gpg_key
+ parse_gpg_output
verify_gpg_signed_file
- BAD_SIGNATURE
- EXPIRED_KEY
- VALID_SIGNATURE
+ BADSIG
+ EXPSIG
+ EXPKEYSIG
+ ERRSIG
+ GOODSIG
+ REVKEYSIG
+ NO_PUBKEY
+ VALIDSIG
+ UNKNOWN
};
our %EXPORT_TAGS = (
@@ -36,38 +50,80 @@ our %EXPORT_TAGS = (
=encoding UTF-8
-=head2
+=cut
- has_valid_gpg_signature(@output, $key_id);
+# Messages on Signature status which should only turn up once.
+our %is_signature_status = (
+ &BADSIG => 1,
+ &ERRSIG => 1,
+ &EXPSIG => 1,
+ &EXPKEYSIG => 1,
+ &GOODSIG => 1,
+ &REVKEYSIG => 1,
+);
+
+=head2
-C<has_valid_gpg_siganture()> validates whether the captured gpg status output
-contains a good signature for the given GPG key.
+ parse_gpg_output(@output, $key_id);
=cut
-sub has_valid_gpg_signature {
+sub parse_gpg_output {
my $output = shift;
my $key_id = shift;
- # VALIDSIG contains the hex key ID, GOODSIG is required for certainty. More
- # information can be found in 'DETAILS' in the gnupg2 documentation folder.
- my $is_good_sig = 0;
- my $is_valid_sig = 0;
my $line;
+ my $status = '';
+
foreach $line (@$output) {
- if ($line =~ /^\[GNUPG\:] VALIDSIG $key_id/) {
- $is_valid_sig = 1;
- } elsif ($line =~ /^\[GNUPG\:] GOODSIG /) {
- $is_good_sig = 1;
+ my $msg = parse_gpg_line($line, $key_id);
+
+ if (exists($is_signature_status{$msg})) {
+ # Only one signature expected.
+ if ($status ne '') {
+ return UNKNOWN;
+ }
+
+ $status = $msg;
}
- if ($is_good_sig && $is_valid_sig) {
- return 1;
+ if ($msg eq NO_PUBKEY) {
+ return NO_PUBKEY;
+ } elsif ($msg eq VALIDSIG) {
+ # VALIDSIG contains the full hex key ID to be certain it is signed by the
+ # right key. information can be found in 'DETAILS' in the gnupg2
+ # documentation folder.
+ return $status;
}
}
- return 0;
+ return UNKNOWN;
+}
+
+sub parse_gpg_line {
+ my $line = shift;
+ my $key_id = shift;
+
+ if ($line =~ /^\[GNUPG\:] BADSIG/) {
+ return BADSIG;
+ } elsif ($line =~ /^\[GNUPG\:] EXPSIG/) {
+ return EXPSIG;
+ } elsif ($line =~ /^\[GNUPG\:] EXPKEYSIG/) {
+ return EXPKEYSIG;
+ } elsif ($line =~ /^\[GNUPG\:] ERRSIG/) {
+ return ERRSIG;
+ } elsif ($line =~ /^\[GNUPG\:] GOODSIG/) {
+ return GOODSIG;
+ } elsif ($line =~ /^\[GNUPG\:] REVKEYSIG/) {
+ return REVKEYSIG;
+ } elsif ($line =~ /^\[GNUPG\:] NO_PUBKEY/) {
+ return NO_PUBKEY;
+ } elsif ($line =~ /^\[GNUPG\:] VALIDSIG $key_id/) {
+ return VALIDSIG;
+ } else {
+ return UNKNOWN;
+ }
}
=head2 import_gpg_key
@@ -127,6 +183,8 @@ sub import_gpg_key {
close($gpg_export);
close($gpg_import);
+ sleep(1);
+
print("key imported\n");
}
@@ -151,9 +209,5 @@ sub verify_gpg_signed_file {
}
close($std_out);
- if (! has_valid_gpg_signature(\@output, $key_id)) {
- return BAD_SIGNATURE;
- }
-
- return VALID_SIGNATURE;
+ return parse_gpg_output(\@output, $key_id);
}
diff --git a/SBO-Lib/lib/SBO/Lib/Repo.pm b/SBO-Lib/lib/SBO/Lib/Repo.pm
index 5337ea8..eaf1f2f 100644
--- a/SBO-Lib/lib/SBO/Lib/Repo.pm
+++ b/SBO-Lib/lib/SBO/Lib/Repo.pm
@@ -7,7 +7,7 @@ use warnings;
our $VERSION = '2.7.2';
use SBO::Lib::Util qw/ %config prompt usage_error get_slack_version get_slack_version_key get_slack_version_url script_error open_fh open_read in _ERR_DOWNLOAD /;
-use SBO::Lib::Cryptography qw/ has_valid_gpg_signature verify_gpg_signed_file VALID_SIGNATURE /;
+use SBO::Lib::Cryptography qw/ GOODSIG NO_PUBKEY parse_gpg_output verify_gpg_signed_file /;
use Cwd;
use File::Copy;
@@ -280,15 +280,22 @@ sub git_sbo_tree {
if ($key_id) {
my @output;
- print("Verifying $git_ref...\n");
+ print("Verifying $git_ref...");
open3(undef, undef, my $std_err = gensym, "git", $verify_cmd, "--raw", "$git_ref");
while (my $line = <$std_err>) {
push(@output, $line);
}
close($std_err);
- if (! has_valid_gpg_signature(\@output, $key_id)) {
- print(STDERR "Repository GPG verification failed.\n");
+ my $res = parse_gpg_output(\@output, $key_id);
+ if ($res eq GOODSIG) {
+ print("OK\n");
+ } else {
+ print(STDERR "Repository GPG verification failed: $res.");
+ if ($res == NO_PUBKEY) {
+ print(STDERR " Did you import the GPG key?");
+ }
+ print(STDERR "\n");
chdir $cwd;
return 0;
@@ -407,10 +414,16 @@ sub rsync_sbo_tree {
print("GPG verification is not present for 14.0 and earlier. You should consider disabling GPG verification.")
}
- print("Verifying CHECKSUMS.md5...\n");
+ print("Verifying CHECKSUMS.md5...");
my $res = verify_gpg_signed_file('CHECKSUMS.md5.asc', $key_id);
- if ($res ne VALID_SIGNATURE) {
- print(STDERR "Respository CHECKSUMS.md5 GPG verification failed.\n");
+ if ($res eq GOODSIG) {
+ print("OK\n");
+ } else {
+ print(STDERR "Respository CHECKSUMS.md5 GPG verification failed: $res.");
+ if ($res eq NO_PUBKEY) {
+ print(STDERR " Did you import the GPG key?");
+ }
+ print(STDERR "\n");
chdir($cwd);
return 0;
@@ -418,11 +431,12 @@ sub rsync_sbo_tree {
}
if ( -e "CHECKSUMS.md5" ) {
- print("Verifying file integrity using CHECKSUMS.md5...\n");
+ print("Verifying file integrity using CHECKSUMS.md5...");
if (system('tail +13 CHECKSUMS.md5 | md5sum -c --quiet -')) {
chdir($cwd);
return 0;
}
+ print("OK\n");
}
return chdir($cwd);