package PGP::Packet::base_pubkey;
# this is a terrible name.  better names are invited.

use strict;
use vars qw(@ISA %pkmpicount %sigmpicount);
use PGP::Packet;

@ISA = qw(PGP::Packet);

use Carp;
use PGP::Unpackable;
use Digest::MD5;
use Digest::SHA1;

BEGIN {
    %pkmpicount = (1,  2,	# RSA
		   2,  2,	# RSA
		   3,  2,	# RSA
		   17, 4,	# DSA
		   16, 3);	# El Gamal

    %sigmpicount = (1,  1,	# RSA
		    2,  1,	# RSA
		    3,  1,	# RSA
		    17, 2);	# DSA

    no strict 'refs';

    foreach my $accessor (qw(ctag created expires pkalg modlength
			     fingerprint keyid)) {
	*{$accessor} = sub {
	    my ($this) = @_;
	    $this->{"parsed"} || $this->_parse();
	    $this->{$accessor};
	};
    }
};

sub _parse {
    my ($self) = @_;

    my $body = new PGP::Unpackable($self->{"bodyref"});

    my $version = $body->unpackC();
    $self->{"version"} = $version;
    if (($version == 2) || ($version == 3)) {
	# parse out stuff

	$self->{"created"} = $body->unpack("N");
	$self->{"expires"} = $body->unpack("n");
	if ($self->{"expires"} > 0) {
	    $self->{"expires"} *= 86400;
	    $self->{"expires"} += $self->{"created"};
	}
	$self->{"pkalg"} = $body->unpackC();

	my $modulus = $body->unpack_mpi();
	my $exponent = $body->unpack_mpi();

	$self->{"modlength"} = $modulus->{"length"};

	# compute the fingerprint

	my $fingerprint = new Digest::MD5;
	$fingerprint->add($modulus->{"bits"});
	$fingerprint->add($exponent->{"bits"});
	$self->{"fingerprint"} = $fingerprint->digest;

	# "compute" the keyid

	$self->{"keyid"} = substr($modulus->{"bits"}, -8, 8);
    } elsif ($version == 4) {
	# parse out stuff

	$self->{"created"} = $body->unpack("N");
	$self->{"pkalg"} = $body->unpackC();

	my $nmpis = $pkmpicount{$self->{"pkalg"}};
	my @mpis;
	for my $i (1..$nmpis) {
	    push(@mpis, $body->unpack_mpi());
	}

	$self->{"modlength"} = $mpis[0]->{"length"};

	# compute the fingerprint
	my $fingerprint = new Digest::SHA1;
	$fingerprint->add("\x99");
	$fingerprint->add(pack("n",length($ {$self->{"bodyref"}})));
	$fingerprint->add($ {$self->{"bodyref"}});
	$self->{"fingerprint"} = $fingerprint->digest;

	# "compute" the keyid
	$self->{"keyid"} = substr($self->{"fingerprint"}, -8, 8);
    } else {
	confess("unknown public key version $version");
    }

    $self->{"parsed"} = 1;
}

sub hashdata {
    my ($self) = @_;
    
    ("\x99".
     pack("n", length($ {$self->bodyref}).
     $ {$self->bodyref}));
}

1;
