File: basic.t

package info (click to toggle)
libpgp-sign-perl 1.04-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 380 kB
  • sloc: perl: 1,165; makefile: 6
file content (137 lines) | stat: -rwxr-xr-x 4,522 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/perl
#
# Basic tests for PGP::Sign functionality.
#
# Copyright 1998-2001, 2004, 2007, 2018, 2020 Russ Allbery <rra@cpan.org>
#
# This program is free software; you may redistribute it and/or modify it
# under the same terms as Perl itself.
#
# SPDX-License-Identifier: GPL-1.0-or-later OR Artistic-1.0-Perl

use 5.020;
use autodie;
use warnings;

use lib 't/lib';

use File::Spec;
use IO::File;
use IPC::Cmd qw(can_run);
use Test::More;
use Test::PGP qw(gpg_is_gpg1 gpg_is_new_enough);

# Check that GnuPG is available.  If so, load the module and set the plan.
BEGIN {
    if (!can_run('gpg')) {
        plan skip_all => 'gpg binary not available';
    } elsif (!gpg_is_new_enough('gpg')) {
        plan skip_all => 'gpg binary is older than 1.4.20 or 2.1.23';
    } else {
        use_ok('PGP::Sign');
    }
}

# Locate our test data directory for later use.
my $data = 't/data';

# Open and load our data file.  This is the sample data that we'll be signing
# and checking signatures against.
open(my $fh, '<', "$data/message");
my @data = <$fh>;
close($fh);

# The key ID and pass phrase to use for testing.
my $keyid      = 'testing';
my $passphrase = 'testing';

# There are three possibilities: gpg is GnuPG v1, gpg is GnuPG v2 and v1 is
# not available, or gpg is GnuPG v2 and gpg1 is GnuPG v1.  We ideally want to
# test both styles, but we'll take what we can get.
my @styles;
if (gpg_is_gpg1()) {
    @styles = qw(GPG1);
} elsif (!can_run('gpg1')) {
    @styles = qw(GPG);
} else {
    @styles = qw(GPG GPG1);
}

# Run all the tests twice, once with GnuPG v2 and then with GnuPG v1.
for my $style (@styles) {
    note("Testing PGPSTYLE $style");
    local $PGP::Sign::PGPSTYLE = $style;
    my $pgpdir = ($style eq 'GPG') ? 'gnupg2' : 'gnupg1';
    local $PGP::Sign::PGPPATH = File::Spec->catdir($data, $pgpdir);
    if ($style eq 'GPG1' && gpg_is_gpg1()) {
        $PGP::Sign::PGPS = 'gpg';
        $PGP::Sign::PGPV = 'gpg';
    }

    # Generate a signature.
    my ($signature, $version) = pgp_sign($keyid, $passphrase, @data);
    ok($signature, 'Sign');
    is(PGP::Sign::pgp_error(), q{}, '...with no errors');
    isnt($signature, undef, 'Signature');
    is(PGP::Sign::pgp_error(), q{}, '...with no errors');

    # Check signature.
    is(pgp_verify($signature, $version, @data), $keyid, 'Verify');
    is(PGP::Sign::pgp_error(),                  q{},    '...with no errors');

    # The same without version, which shouldn't matter.
    is(pgp_verify($signature, undef, @data), $keyid, 'Verify without version');
    is(PGP::Sign::pgp_error(),               q{},    '...with no errors');

    # Check a failed signature by appending some nonsense to the data.
    is(pgp_verify($signature, $version, @data, 'xyzzy'), q{},
        'Verify invalid');
    is(PGP::Sign::pgp_error(), q{}, '...with no errors');

    # Test taking code from a code ref and then verifying the reulting
    # signature.  Also test accepting only one return value from pgp_sign().
    my @code_input = @data;
    my $data_ref   = sub {
        my $line = shift(@code_input);
        return $line;
    };
    $signature = pgp_sign($keyid, $passphrase, $data_ref);
    isnt($signature, undef, 'Signature from code ref');
    is(PGP::Sign::pgp_error(),                  q{},    '...with no errors');
    is(pgp_verify($signature, $version, @data), $keyid, 'Verifies');
    is(PGP::Sign::pgp_error(),                  q{},    '...with no errors');

    # Test whitespace munging.
    {
        local $PGP::Sign::MUNGE = 1;
        ($signature, $version) = pgp_sign($keyid, $passphrase, q{       });
    }
    is(pgp_verify($signature, $version, q{       }),
        q{}, 'Munged does not match');
    is(pgp_verify($signature, $version, q{}),
        $keyid, '...but does match empty');
    {
        local $PGP::Sign::MUNGE = 1;
        is(pgp_verify($signature, $version, q{  }),
            $keyid, '...and does match munged');
    }

    # Test error handling.
    is(pgp_verify('asfasdfasf', undef, @data), undef, 'Invalid signature');
    my @errors = PGP::Sign::pgp_error();
    my $errors = PGP::Sign::pgp_error();
    like(
        $errors[-1],
        qr{^ Execution [ ] of [ ] gpg.? [ ] failed}xms,
        'Invalid signature',
    );
    like(
        $errors,
        qr{\n Execution [ ] of [ ] gpg.? [ ] failed}xms,
        'Errors contain newlines',
    );
    is($errors, join(q{}, @errors), 'Two presentations of errors match');
}

# Report the end of testing.
done_testing(21 * scalar(@styles) + 1);