#!/usr/athena/bin/perl

"             pub A public key
              ret A revoked key
              sec A secret key
              sub A sub-key (in 5.0, this  is  always  a  Diffie-
              Hellman key)
              SIG A signature issued by a public key to which you
              have thecorresponding private key (i.e., your key)
              sig A signature issued by a public key to which you
              do  NOT  have  the corresponding private key (i.e.,
              someone else's key)
              uid A user ID

              Following this column is a single  character  which
              describes other attributes of the object:

              %  The object is not valid (it does not have enough
              trusted signatures)
              ?  No information is  available  about  the  object
              (generally  because  it  is  a signature from a key
              that is not on your keyring)
              !  The object has been checked
              * The object has been tried
              @ The object is disabled
              + The object is axiomatically trusted  (i.e.,  it's
              your key)";

BEGIN { push(@INC, "/afs/net.mit.edu/project/pks/perl-mysql/perllib"); }

use PGP::Constants;
use PGP::Keyring;
use PGP::Certificate;
use IO::File;
use Mmap;

$ringname = shift(@ARGV);

$file = new IO::File($ringname) || die "Couldn't open keyring $ringname: $!\n";

$mmap = mmap($ringbuf, 0, PROT_READ, MAP_SHARED, $file);

$ring = new PGP::Keyring(\$ringbuf);

while ($cert = $ring->NextCert()) {
    $name{$cert->keyid} = $cert->primary_userid->name;
    push(@certs, $cert);
}

print "Type Bits KeyID      Created    Expires    Algorithm       Use\n";

for $cert (@certs) {
    $cert->verify();

    if ($cert->created) {
	@created = gmtime($cert->created);
	$created = sprintf("%04s-%02s-%02s",
			   1900+$created[5], 1+$created[4], $created[3]);
    }
    if ($cert->expires) {
	@expires = gmtime($cert->expires);
	$expires = sprintf("%04s-%02s-%02s",
			   1900+$expires[5], 1+$expires[4], $expires[3]);
    } else {
	$expires = "-"x10;
    }

    printf("pub %5d 0x%s %s %s %-15s %s\n",
	   $cert->modlength,
	   uc unpack("x4H8", $cert->keyid),
	   $created, $expires,
	 PGP::Constants::pkalgstr($cert->pkalg),
	   $cert->usagestr);

    if (length($cert->fingerprint) == 16) {
	print("f16    Fingerprint16 = ",
	      uc sprintf("%s %s %s %s %s %s %s %s  %s %s %s %s %s %s %s %s\n",
			unpack("H2"x16, $cert->fingerprint)));
    } elsif (length($cert->fingerprint) == 20) {
	print("f20    Fingerprint20 = ",
	      uc sprintf("%s%s %s%s %s%s %s%s %s%s  ".
			 "%s%s %s%s %s%s %s%s %s%s\n",
			 unpack("H2"x20, $cert->fingerprint)));
    }

    for $sub (@{$cert->subkeys}) {
	printf("sub %5d 0x%s %s %s %s\n",
	       $sub->modlength,
	       uc unpack("x4H8", $sub->keyid),
	       $created, $expires,
	     PGP::Constants::pkalgstr($sub->pkalg));

	if (length($sub->fingerprint) == 16) {
	    print("f16    Fingerprint16 = ",
		  uc sprintf("%s %s %s %s %s %s %s %s  ".
			     "%s %s %s %s %s %s %s %s\n",
			     unpack("H2"x16, $sub->fingerprint)));
	} elsif (length($sub->fingerprint) == 20) {
	    print("f20    Fingerprint20 = ",
		  uc sprintf("%s%s %s%s %s%s %s%s %s%s  ".
			     "%s%s %s%s %s%s %s%s %s%s\n",
			     unpack("H2"x20, $sub->fingerprint)));
	}
    }

    for $uid (@{$cert->userids}) {
	printf("%s  %s\n",
	       ($uid->primary_userid)?"UID":"uid",
	       $uid->name);

	for $sig (@{$uid->signatures}) {
	    if ($sig->created) {
		@created = gmtime($sig->created);
		$created = sprintf("%04s-%02s-%02s", 1900+$created[5],
				   1+$created[4], $created[3]);
	    } else {
		$created = "-"x10;
	    }

	    printf("sig%s      0x%s %s %s\n",
		   $name{$sig->issuer}?" ":"?",
		   $sig->issuertext,
		   $created,
		   $name{$sig->issuer} ||
		   "(Unknown signator, can't be checked)");
	}
    }

    print "\n";
}

print scalar(@certs), " matching keys found.\n";
