Crypt-OpenPGP
view release on metacpan or search on metacpan
lib/Crypt/OpenPGP.pm view on Meta::CPAN
return $pgp->error("Could not find public key with KeyID " .
unpack('H*', $key_id))
unless $kb;
}
$cert = $kb->key_by_id($sig->key_id);
}
## pgp2 and pgp5 do not trim trailing whitespace from "canonical text"
## signatures, only from cleartext signatures. So we first try to verify
## the signature using proper RFC4880 canonical text, then if that fails,
## retry without trimming trailing whitespace.
## See:
## http://cert.uni-stuttgart.de/archive/ietf-openpgp/2000/01/msg00033.html
my($dgst, $found);
for (1, 0) {
local $Crypt::OpenPGP::Globals::Trim_trailing_ws = $_;
$dgst = $sig->hash_data($data) or
return $pgp->error( $sig->errstr );
$found++, last if substr($dgst, 0, 2) eq $sig->{chk};
}
return $pgp->error("Message hash does not match signature checkbytes")
unless $found;
my $valid = $cert->key->public_key->verify($sig, $dgst) ?
($kb && $kb->primary_uid ? $kb->primary_uid : 1) : 0;
$wants_object ? ($valid, $sig) : $valid;
}
sub encrypt {
my $pgp = shift;
my %param = @_;
$pgp->_merge_compat(\%param, 'encrypt') or
return $pgp->error( $pgp->errstr );
my($data);
require Crypt::OpenPGP::Cipher;
require Crypt::OpenPGP::Ciphertext;
unless (defined($data = $param{Data})) {
my $file = $param{Filename} or
return $pgp->error("Need either 'Data' or 'Filename' to encrypt");
$data = $pgp->_read_files($file) or return $pgp->error($pgp->errstr);
}
my $ptdata;
if ($param{SignKeyID}) {
$ptdata = $pgp->sign(
Data => $data,
KeyID => $param{SignKeyID},
Compat => $param{Compat},
Armour => 0,
Passphrase => $param{SignPassphrase},
PassphraseCallback => $param{SignPassphraseCallback},
)
or return;
} else {
my $pt = Crypt::OpenPGP::Plaintext->new( Data => $data,
$param{Filename} ? (Filename => $param{Filename}) : () );
$ptdata = Crypt::OpenPGP::PacketFactory->save($pt);
}
if (my $alg = $param{Compress}) {
require Crypt::OpenPGP::Compressed;
$alg = Crypt::OpenPGP::Compressed->alg_id($alg);
my $cdata = Crypt::OpenPGP::Compressed->new( Data => $ptdata,
Alg => $alg ) or return $pgp->error("Compression error: " .
Crypt::OpenPGP::Compressed->errstr);
$ptdata = Crypt::OpenPGP::PacketFactory->save($cdata);
}
my $key_data = Crypt::OpenPGP::Util::get_random_bytes(32);
my $sym_alg = $param{Cipher} ?
Crypt::OpenPGP::Cipher->alg_id($param{Cipher}) : DEFAULT_CIPHER;
my(@sym_keys);
if ($param{Recipients} && !ref($param{Recipients})) {
$param{Recipients} = [ $param{Recipients} ];
}
if (my $kid = delete $param{KeyID}) {
my @kid = ref $kid eq 'ARRAY' ? @$kid : $kid;
push @{ $param{Recipients} }, @kid;
}
if ($param{Key} || $param{Recipients}) {
require Crypt::OpenPGP::SessionKey;
my @keys;
if (my $recips = $param{Recipients}) {
my @recips = ref $recips eq 'ARRAY' ? @$recips : $recips;
my $ring = $pgp->pubrings->[0];
my %seen;
my $server;
my $cfg = $pgp->{cfg};
if ($cfg->get('AutoKeyRetrieve') && $cfg->get('KeyServer')) {
require Crypt::OpenPGP::KeyServer;
$server = Crypt::OpenPGP::KeyServer->new(
Server => $cfg->get('KeyServer'),
);
}
for my $r (@recips) {
my($lr, @kb) = (length($r));
if (($lr == 8 || $lr == 16) && $r !~ /[^\da-fA-F]/) {
my $id = pack 'H*', $r;
@kb = $ring->find_keyblock_by_keyid($id) if $ring;
@kb = $server->find_keyblock_by_keyid($id)
if !@kb && $server;
} else {
@kb = $ring->find_keyblock_by_uid($r) if $ring;
@kb = $server->find_keyblock_by_uid($r)
if !@kb && $server;
}
for my $kb (@kb) {
next unless my $cert = $kb->encrypting_key;
next if $seen{ $cert->key_id }++;
$cert->uid($kb->primary_uid);
push @keys, $cert;
}
}
if (my $cb = $param{RecipientsCallback}) {
@keys = @{ $cb->(\@keys) };
}
}
if ($param{Key}) {
push @keys, ref $param{Key} eq 'ARRAY' ? @{$param{Key}} :
$param{Key};
}
return $pgp->error("No known recipients for encryption")
unless @keys;
for my $key (@keys) {
push @sym_keys, Crypt::OpenPGP::SessionKey->new(
Key => $key,
SymKey => $key_data,
( run in 0.731 second using v1.01-cache-2.11-cpan-6aa56a78535 )