our
$VERSION
=
'0.01'
;
my
@BACKENDS
=
qw(
sop
sq
gpg
)
;
my
%BACKEND
= (
sop
=>
'SOP'
,
sq
=>
'Sequoia'
,
gpg
=>
'GnuPG'
,
);
sub
new {
my
(
$this
,
%opts
) =
@_
;
my
$class
=
ref
(
$this
) ||
$this
;
my
$self
= {};
bless
$self
,
$class
;
my
$backend
=
$opts
{backend} //
'auto'
;
my
%backend_opts
= (
cmdv
=>
$opts
{cmdv} //
'auto'
,
cmd
=>
$opts
{cmd} //
'auto'
,
);
if
(
$backend
eq
'auto'
) {
$opts
{needs}{api} //=
'full'
;
$opts
{needs}{keystore} //= 0;
if
(none {
$opts
{needs}{api} eq
$_
}
qw(full verify)
) {
error(g_(
'unknown OpenPGP api requested %s'
),
$opts
{needs}{api});
}
$self
->{backend} =
$self
->_auto_backend(
$opts
{needs},
%backend_opts
);
}
elsif
(
exists
$BACKEND
{
$backend
}) {
$self
->{backend} =
$self
->_load_backend(
$BACKEND
{
$backend
},
%backend_opts
);
if
(!
$self
->{backend}) {
error(g_(
'cannot load OpenPGP backend %s'
),
$backend
);
}
}
else
{
error(g_(
'unknown OpenPGP backend %s'
),
$backend
);
}
return
$self
;
}
sub
_load_backend {
my
(
$self
,
$backend
,
%opts
) =
@_
;
my
$module
=
"Dpkg::OpenPGP::Backend::$backend"
;
eval
qq{
pop \@INC if \$INC[-1] eq '.';
require $module;
}
;
return
if
$@;
return
$module
->new(
%opts
);
}
sub
_auto_backend {
my
(
$self
,
$needs
,
%opts
) =
@_
;
foreach
my
$backend
(
@BACKENDS
) {
my
$module
=
$self
->_load_backend(
$BACKEND
{
$backend
},
%opts
);
if
(
$needs
->{api} eq
'verify'
) {
next
if
!
$module
->has_verify_cmd();
}
else
{
next
if
!
$module
->has_backend_cmd();
}
next
if
$needs
->{keystore} && !
$module
->has_keystore();
return
$module
;
}
return
Dpkg::OpenPGP::Backend->new();
}
sub
can_use_secrets {
my
(
$self
,
$key
) =
@_
;
return
0
unless
$self
->{backend}->has_backend_cmd();
return
0
if
$key
->type eq
'keyfile'
&& ! -f
$key
->handle;
return
0
if
$key
->type eq
'keystore'
&& ! -e
$key
->handle;
return
0
unless
$self
->{backend}->can_use_key(
$key
);
return
1;
}
sub
get_trusted_keyrings {
my
$self
=
shift
;
return
$self
->{backend}->get_trusted_keyrings();
}
sub
armor {
my
(
$self
,
$type
,
$in
,
$out
) =
@_
;
return
$self
->{backend}->armor(
$type
,
$in
,
$out
);
}
sub
dearmor {
my
(
$self
,
$type
,
$in
,
$out
) =
@_
;
return
$self
->{backend}->dearmor(
$type
,
$in
,
$out
);
}
sub
inline_verify {
my
(
$self
,
$inlinesigned
,
$data
,
@certs
) =
@_
;
return
$self
->{backend}->inline_verify(
$inlinesigned
,
$data
,
@certs
);
}
sub
verify {
my
(
$self
,
$data
,
$sig
,
@certs
) =
@_
;
return
$self
->{backend}->verify(
$data
,
$sig
,
@certs
);
}
sub
inline_sign {
my
(
$self
,
$data
,
$inlinesigned
,
$key
) =
@_
;
return
$self
->{backend}->inline_sign(
$data
,
$inlinesigned
,
$key
);
}
1;