<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package PGP::Packet::Signature;

use strict;
use vars qw(@ISA %subpacket);

@ISA = qw(PGP::Packet);

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

BEGIN {
    no strict 'refs';

# v3 fields:
# version sigtype created issuer
# pkalg hashalg
# hashbegin hashlen hashmsb16

# v4 fields:
# version sigtype subpacket:created subpacket:issuer
# pkalg hashalg
# hashbegin hashlen hashmsb16
# hashsubs unhashsubs

    foreach my $accessor (qw(version sigtype created issuer
			     pkalg hashalg
			     hashbegin hashlen hashmsb16
			     hashsubs unhashsubs)) {
	*{$accessor} = sub {
	    my ($this) = @_;
	    $this-&gt;{"parsed"} || $this-&gt;_parse();
	    $this-&gt;{$accessor};
	};
    }
}

sub new {
    my ($classname, $bodyref, $packetref) = @_;

    bless $classname-&gt;SUPER::new(2, $bodyref, $packetref), $classname;
}

sub _subpackets {
    my ($self, $subpackets) = @_;

    my $sps = {};

    while ($subpackets-&gt;remaining()) {
	my $plen;

	my $lbyte = $subpackets-&gt;unpackC();

	if ($lbyte &lt; 192) {
	    $plen = $lbyte;
	} elsif ($lbyte &lt; 224) {
	    my $octet = $subpackets-&gt;unpackC();
	    $plen = (($lbyte - 192) &lt;&lt; 8) + $octet + 192;
	} elsif ($lbyte == 255) {
	    $plen = $subpackets-&gt;unpack("N");
	} else {
	    confess("partial body lengths are not permitted in subpackets");
	}

	my $type = $subpackets-&gt;unpackC();
	my $data = $subpackets-&gt;unpacka($plen-1);

	unshift(@{$sps-&gt;{$type}}, $data);
    }

    return($sps);
}

sub _parse {
    my ($self) = @_;
    my $body = new PGP::Unpackable($self-&gt;{"bodyref"});

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

	if ($body-&gt;unpackC() != 5) {
	    confess("hash material length != 5");
	}

	# clobber the above hashbegin
	$self-&gt;{"hashbegin"} = $body-&gt;offset;
	$self-&gt;{"sigtype"} = $body-&gt;unpackC();
	$self-&gt;{"created"} = $body-&gt;unpack("N");
	$self-&gt;{"hashlen"} = $body-&gt;offset - $self-&gt;{"hashbegin"};
	$self-&gt;{"issuer"} = $body-&gt;unpacka(8);
	$self-&gt;{"pkalg"} = $body-&gt;unpackC();
	$self-&gt;{"hashalg"} = $body-&gt;unpackC();
	$self-&gt;{"hashmsb16"} = $body-&gt;unpacka(2);

	# the parser can ignore the rest
    } elsif ($version == 4) {
	# parse out stuff

	$self-&gt;{"sigtype"} = $body-&gt;unpackC();
	$self-&gt;{"pkalg"} = $body-&gt;unpackC();
	$self-&gt;{"hashalg"} = $body-&gt;unpackC();

	my $hashsubslen = $body-&gt;unpack("n");
	my $hashsubs = new PGP::Unpackable(\$body-&gt;unpacka($hashsubslen));
	$self-&gt;{"hashsubs"} = $self-&gt;_subpackets($hashsubs);

	$self-&gt;{"hashlen"} = $body-&gt;offset - $self-&gt;{"hashbegin"};

	$self-&gt;{"unhashsubsbegin"} = $body-&gt;offset;

	my $unhashsubslen = $body-&gt;unpack("n");
	my $unhashsubs = new PGP::Unpackable(\$body-&gt;unpacka($unhashsubslen));
	$self-&gt;{"unhashsubs"} = $self-&gt;_subpackets($unhashsubs);

	$self-&gt;{"hashmsb16"} = $body-&gt;unpacka(2);
    } else {
	confess("unknown signature version $version");
    }

    $self-&gt;{"parsed"} = 1;
}

1;
</pre></body></html>