#!/usr/bin/perl -w # (c) Christoph Berg # This program is free software covered by the GPL. # $Id: purgesigs,v 1.7 2004/07/05 23:03:09 cb Exp $ # # This program removes all uids except one and all unknown signatures from a # gpg key. # # 031017 cb v0.1 # 031017 cb v0.1a: -qmfu flags # 031019 cb v0.1b: removed stray [ from regexps # 040222 cb v0.2: support for revoked keys (Tollef Fog Heen) # 2004-07-02 cb # 2004-07-06 cb: purging subkeys use strict; my $version = "2004-07-06"; $ENV{LC_ALL} = "C"; my %opts; use Getopt::Std; getopts('v', \%opts); sub help { print < Syntax: $0 keyring keyid uid_nr EOT exit 0; } my $keyring = shift || help(); my $keyid = shift || help(); my $uid_nr = shift || help(); my $uid_count = 0; my $found = 0; my $uid_string; open G, "gpg --no-default-keyring --keyring $keyring --list-key --fixed-list-mode --with-colon $keyid |" or die "gpg: $!"; while () { print if $opts{v}; chomp; next if /^tru:/; # TODO: what's that? trust? next if /^sub:/; #pub:q:1024:17:0596CD7FCA9EADCF:1062764361:::-:::scESC: if(/^pub:[-qmfu]:\d{3,}:\d+:[0-9A-F]+:\d+:\d*::[-qmfu]:::[escESC]+:$/) { $found = 1; } elsif(/^uid:[-qmfu]::::::::(.+):$/) { $uid_count++; $uid_string = $1 if $uid_count == $uid_nr; } elsif(/^(uid|uat):[-qmfur]::::::::(.+):$/) { $uid_count++; } else { die "unknown line format: $_"; } } close G; die "Key '$keyid' not found" unless $found; die "uid_nr $uid_nr > uid_count $uid_count" if $uid_nr > $uid_count; print "$keyring: purging key $keyid / uid $uid_nr/$uid_count\n" if $opts{v}; system "expect purgesigs.expect $keyring $keyid $uid_nr $uid_count > /dev/null"; die "Something went wrong with purgesigs.expect" if $? >> 8 > 0; sleep 1; $uid_count = 0; $found = 0; open G, "gpg --no-default-keyring --keyring $keyring --list-key --fixed-list-mode --with-colon $keyid |" or die "gpg: $!"; while () { print if $opts{v}; chomp; next if /^tru:/; # TODO: what's that? trust? next if /^sub:/; #pub:q:1024:17:0596CD7FCA9EADCF:1062764361:::-:::scESC: if(/^pub:[-qmfu]:\d{3,}:\d+:[0-9A-F]+:\d+:\d*::[-qmfu]:::[escESC]+:$/) { $found = 1; } elsif(/^uid:[-qmfu]::::::::(.+):$/) { $uid_count++; die "purgesigs failed: more than one uid left in $keyring" if $uid_count > 1; die "wrong uid ($1) cut out, expected $uid_string" if $1 ne $uid_string; } elsif(/^(uid|uat):[-qmfu]::::::::(.+):$/) { $uid_count++; } else { die "unknown line format: $_"; } } close G; die "Key '$keyid' not found" unless $found or $uid_count == 0;