package Crypt::OpenPGP::KeyBlock; use strict; use Crypt::OpenPGP::PacketFactory; sub primary_uid { $_[0]->{pkt}{ 'Crypt::OpenPGP::UserID' } ? $_[0]->{pkt}{ 'Crypt::OpenPGP::UserID' }->[0]->id : undef; } sub key { $_[0]->get('Crypt::OpenPGP::Certificate')->[0] } sub subkey { $_[0]->get('Crypt::OpenPGP::Certificate')->[1] } sub encrypting_key { my $kb = shift; my $keys = $kb->get('Crypt::OpenPGP::Certificate'); return unless $keys && @$keys; for my $key (@$keys) { return $key if $key->can_encrypt; } } sub signing_key { my $kb = shift; my $keys = $kb->get('Crypt::OpenPGP::Certificate'); return unless $keys && @$keys; for my $key (@$keys) { return $key if $key->can_sign; } } sub key_by_id { $_[0]->{keys_by_id}->{$_[1]} || $_[0]->{keys_by_short_id}->{$_[1]} } sub new { my $class = shift; my $kb = bless { }, $class; $kb->init(@_); } sub init { my $kb = shift; $kb->{pkt} = { }; $kb->{order} = [ ]; $kb->{keys_by_id} = { }; $kb; } sub add { my $kb = shift; my($pkt) = @_; push @{ $kb->{pkt}->{ ref($pkt) } }, $pkt; push @{ $kb->{order} }, $pkt; if (ref($pkt) eq 'Crypt::OpenPGP::Certificate') { my $kid = $pkt->key_id; $kb->{keys_by_id}{ $kid } = $pkt; $kb->{keys_by_short_id}{ substr $kid, -4, 4 } = $pkt; } } sub get { $_[0]->{pkt}->{ $_[1] } } sub save { my $kb = shift; Crypt::OpenPGP::PacketFactory->save( @{ $kb->{order} } ); } sub save_armoured { my $kb = shift; require Crypt::OpenPGP::Armour; Crypt::OpenPGP::Armour->armour( Data => $kb->save, Object => 'PUBLIC KEY BLOCK' ); } 1; __END__ =head1 NAME Crypt::OpenPGP::KeyBlock - Key block object =head1 SYNOPSIS use Crypt::OpenPGP::KeyBlock; my $packet = Crypt::OpenPGP::UserID->new( Identity => 'foo' ); my $kb = Crypt::OpenPGP::KeyBlock->new; $kb->add($packet); my $serialized = $kb->save; =head1 DESCRIPTION I represents a single keyblock in a keyring. A key block is essentially just a set of associated keys containing exactly one master key, zero or more subkeys, some user ID packets, some signatures, etc. The key is that there is only one master key associated with each keyblock. =head1 USAGE =head2 Crypt::OpenPGP::KeyBlock->new Constructs a new key block object and returns that object. =head2 $kb->encrypting_key Returns the key that performs encryption in this key block. For example, if a DSA key is the master key in a key block with an ElGamal subkey, I returns the ElGamal subkey certificate, because DSA keys do not perform encryption/decryption. =head2 $kb->signing_key Returns the key that performs signing in this key block. For example, if a DSA key is the master key in a key block with an ElGamal subkey, I returns the DSA master key certificate, because DSA supports signing/verification. =head2 $kb->add($packet) Adds the packet I<$packet> to the key block. If the packet is a PGP certificate (a I object), the certificate is also added to the internal key-management mechanism. =head2 $kb->save Serializes each of the packets contained in the I object, in order, and returns the serialized data. This output can then be fed to I for ASCII-armouring, for example, or can be written out to a keyring file. =head2 $kb->save_armoured Saves an armoured version of the keyblock (this is useful for exporting public keys). =head1 AUTHOR & COPYRIGHTS Please see the Crypt::OpenPGP manpage for author, copyright, and license information. =cut