aboutsummaryrefslogtreecommitdiff
path: root/SBO-Lib/lib/SBO/Lib/Cryptography.pm
diff options
context:
space:
mode:
Diffstat (limited to 'SBO-Lib/lib/SBO/Lib/Cryptography.pm')
-rw-r--r--SBO-Lib/lib/SBO/Lib/Cryptography.pm114
1 files changed, 84 insertions, 30 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);
}