File Coverage

File:Dpkg/OpenPGP.pm
Coverage:75.2%

linestmtbrancondsubpodtimecode
1# Copyright © 2017 Guillem Jover <guillem@debian.org>
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program.  If not, see <https://www.gnu.org/licenses/>.
15
16=encoding utf8
17
18 - 28
=head1 NAME

Dpkg::OpenPGP - multi-backend OpenPGP support

=head1 DESCRIPTION

This module provides a class for transparent multi-backend OpenPGP support.

B<Note>: This is a private module, its API can change at any time.

=cut
29
30package Dpkg::OpenPGP 0.01;
31
32
216
216
216
570
216
4455
use strict;
33
216
216
216
495
144
6786
use warnings;
34
35
216
216
216
495
72
7374
use List::Util qw(none);
36
37
216
216
216
501
207
7035
use Dpkg::Gettext;
38
216
216
216
495
213
9231
use Dpkg::ErrorHandling;
39
216
216
216
498
210
4629
use Dpkg::IPC;
40
216
216
216
432
207
96942
use Dpkg::Path qw(find_command);
41
42my @BACKENDS = qw(
43    sop
44    sq
45    gpg
46);
47my %BACKEND = (
48    sop => 'SOP',
49    sq => 'Sequoia',
50    gpg => 'GnuPG',
51);
52
53sub new {
54
735
0
2927
    my ($this, %opts) = @_;
55
735
4432
    my $class = ref($this) || $this;
56
57
735
844
    my $self = {};
58
735
911
    bless $self, $class;
59
60
735
1823
    my $backend = $opts{backend} // 'auto';
61    my %backend_opts = (
62        cmdv => $opts{cmdv} // 'auto',
63
735
4726
        cmd => $opts{cmd} // 'auto',
64    );
65
66
735
2554
    if ($backend eq 'auto') {
67        # Defaults for stateless full API auto-detection.
68
216
1047
        $opts{needs}{api} //= 'full';
69
216
576
        $opts{needs}{keystore} //= 0;
70
71
216
225
1224
642
        if (none { $opts{needs}{api} eq $_ } qw(full verify)) {
72
0
0
            error(g_('unknown OpenPGP api requested %s'), $opts{needs}{api});
73        }
74
75
216
708
        $self->{backend} = $self->_auto_backend($opts{needs}, %backend_opts);
76    } elsif (exists $BACKEND{$backend}) {
77
519
2806
        $self->{backend} = $self->_load_backend($BACKEND{$backend}, %backend_opts);
78
519
2782
        if (! $self->{backend}) {
79
0
0
            error(g_('cannot load OpenPGP backend %s'), $backend);
80        }
81    } else {
82
0
0
        error(g_('unknown OpenPGP backend %s'), $backend);
83    }
84
85
735
7628
    return $self;
86}
87
88sub _load_backend {
89
735
2156
    my ($self, $backend, %opts) = @_;
90
91
735
1148
    my $module = "Dpkg::OpenPGP::Backend::$backend";
92
735
58995
    eval qq{
93        require $module;
94    };
95
735
3608
    return if $@;
96
97
735
12252
    return $module->new(%opts);
98}
99
100sub _auto_backend {
101
216
291
    my ($self, $needs, %opts) = @_;
102
103
216
282
    foreach my $backend (@BACKENDS) {
104
216
426
        my $module = $self->_load_backend($BACKEND{$backend}, %opts);
105
106
216
504
        if ($needs->{api} eq 'verify') {
107
9
18
            next if ! $module->has_verify_cmd();
108        } else {
109
207
483
            next if ! $module->has_backend_cmd();
110        }
111
216
435
        next if $needs->{keystore} && ! $module->has_keystore();
112
113
216
711
        return $module;
114    }
115
116    # Otherwise load a dummy backend.
117
0
0
    return Dpkg::OpenPGP::Backend->new();
118}
119
120sub can_use_secrets {
121
570
0
1286
    my ($self, $key) = @_;
122
123
570
3752
    return 0 unless $self->{backend}->has_backend_cmd();
124
570
2285
    return 0 if $key->type eq 'keyfile' && ! -f $key->handle;
125
570
994
    return 0 if $key->type eq 'keystore' && ! -e $key->handle;
126
570
3369
    return 0 unless $self->{backend}->can_use_key($key);
127
570
1244
    return 1;
128}
129
130sub get_trusted_keyrings {
131
0
0
0
    my $self = shift;
132
133
0
0
    return $self->{backend}->get_trusted_keyrings();
134}
135
136sub armor {
137
2121
0
8131
    my ($self, $type, $in, $out) = @_;
138
139
2121
10303
    return $self->{backend}->armor($type, $in, $out);
140}
141
142sub dearmor {
143
1404
0
4896
    my ($self, $type, $in, $out) = @_;
144
145
1404
5504
    return $self->{backend}->dearmor($type, $in, $out);
146}
147
148sub inline_verify {
149
1854
0
7034
    my ($self, $inlinesigned, $data, @certs) = @_;
150
151
1854
9362
    return $self->{backend}->inline_verify($inlinesigned, $data, @certs);
152}
153
154sub verify {
155
1212
0
3329
    my ($self, $data, $sig, @certs) = @_;
156
157
1212
5697
    return $self->{backend}->verify($data, $sig, @certs);
158}
159
160sub inline_sign {
161
570
0
1105
    my ($self, $data, $inlinesigned, $key) = @_;
162
163
570
1559
    return $self->{backend}->inline_sign($data, $inlinesigned, $key);
164}
165
166 - 172
=head1 CHANGES

=head2 Version 0.xx

This is a private module.

=cut
173
1741;