* gpg-key2ps: add --list-key to gpg call (works around #382794).
[pgp-tools.git] / gpg-key2ps / gpg-key2ps
1 #!/usr/bin/perl -w
2 #
3 # gpg-key2ps: convert a PGP/GnuPG key into paper slips.
4 # Copyright (C) 2001-2005 Simon Richter
5 # Copyright (C) 2005-2006 Thijs Kinkhorst
6 # Copyright (C) 2005-2006 Christoph Berg <cb@df7cb.de>
7 # Licenced under the GNU General Public License,
8 # version 2 or later.
9 #
10 # $Id$
11
12 use strict;
13 use Getopt::Long;
14
15 my $version = '$Rev$';
16 $version =~ s/\$Rev:\s*(\d+)\s*\$/$1/;
17 my $revokestyle = "hide";
18 my $creationdate = scalar(localtime);
19
20 sub version($) {
21 my $fd = shift;
22 print $fd "gpg-key2ps $version - (c) 2001-2006 Simon Richter, Thijs Kinkhorst, Christoph Berg\n";
23 }
24
25 sub usage($$) {
26 my ($fd, $exitcode) = @_;
27 version ($fd);
28 print $fd <<EOF;
29 Usage: $0 [-p papersize] [-r revoked-style] keyid-or-name ...
30 Options:
31 -p --paper-size
32 -r --revoked-style
33 hide - Don't show revoked uids (default)
34 grey - Print text in grey
35 note - Add "[revoked]"
36 show - List revoked uids normally
37 strike - Strike through lines
38 -h --help
39 -v --version
40 EOF
41 exit $exitcode;
42 }
43
44 # fetch command line parameters
45 my $opts;
46 Getopt::Long::config('bundling');
47 if (!GetOptions (
48 '-h' => \$opts->{help},
49 '--help' => \$opts->{help},
50 '-v' => \$opts->{version},
51 '--version' => \$opts->{version},
52 '-p=s' => \$opts->{papersize},
53 '--paper-size=s' => \$opts->{papersize},
54 '-r=s' => \$opts->{revokestyle},
55 '--revoked-style=s' => \$opts->{revokestyle},
56 )) {
57 usage(\*STDERR, 1);
58 }
59
60 if ($opts->{help}) {
61 usage (\*STDOUT, 0);
62 }
63
64 if ($opts->{version}) {
65 version (\*STDOUT);
66 exit 0;
67 }
68
69 if ( $opts->{revokestyle} ) { $revokestyle = $opts->{revokestyle}; }
70 if ( $opts->{papersize} ) { $ENV{'PAPERSIZE'} = $opts->{papersize}; }
71
72 if ( $revokestyle !~ /^(grey|hide|note|show|strike)$/ ) {
73 print STDERR "Unknown revoked-style \"$revokestyle\".\n";
74 usage (\*STDERR, 1);
75 }
76
77 usage(\*STDERR, 1) unless scalar @ARGV >= 1;
78
79 # determine the paper size through the paperconf tool
80 my $w; my $h;
81 if ( `which paperconf` && $? == 0 ) {
82 $w=`paperconf -w`;
83 $h=`paperconf -h`;
84 chomp($w);
85 chomp($h);
86 } else {
87 # Default to A4.
88 print STDERR "Warning: libpaper-utils is not installed, defaulting to A4.\n";
89 $w=596;
90 $h=842;
91 }
92
93 # open a gpg process we'll be reading from below
94 map { s/'/'\\''/g; } @ARGV; # quote single quotes
95 # --list-key due to #382794
96 open(GPG, "gpg --list-key --with-fingerprint --with-colons '". (join "' '", @ARGV) ."' |");
97
98 sub start_postscript {
99 # start the PostScript output
100 print <<EOF;
101 %!PS-Adobe-3.0
102 %%BoundingBox: 0 0 $w $h
103 %%Title:
104 %%Creator: gpg-key2ps $version
105 %%CreationDate: $creationdate
106 %%Pages: 1
107 %%EndComments
108
109 %%Page: 1 1
110
111 /w $w def
112 /h $h def
113
114 /Times-Roman findfont 9 scalefont setfont
115
116 /newline {
117 /y y 10 sub def
118 } def
119
120 /hline {
121 30 y 3 add moveto
122 w 2 div 30 sub y 3 add lineto stroke
123 newline
124 } def
125
126 /needhline {
127 /condhline { hline } def
128 } def
129
130 /noneedhline {
131 /condhline { } def
132 } def
133
134 /showAlgorithm {
135 << 1 (R) 2 (r) 3 (s) 16 (g) 20 (G) 17 (D) >> exch get
136 show
137 } def
138
139 /pub {
140 condhline
141 50 y moveto (pub) show
142 70 y moveto show showAlgorithm (/) show show
143 150 y moveto show
144 200 y moveto show
145 newline
146 needhline
147 } def
148
149 /fpr {
150 70 y moveto (Key fingerprint = ) show show
151 newline
152 } def
153
154 /uid {
155 50 y moveto (uid) show
156 200 y moveto show
157 newline
158 } def
159
160 EOF
161
162 # output the desired display for revoked uids
163 if ( $revokestyle eq "grey" ) {
164 print "/revuid {\n";
165 print " .5 setgray\n";
166 print " uid\n";
167 print " 0 setgray\n";
168 print "} def\n";
169 } elsif ( $revokestyle eq "note" ) {
170 print "/revuid {\n";
171 print " 50 y moveto (uid) show\n";
172 print " 200 y moveto show ( [revoked]) show\n";
173 print " newline\n";
174 print "} def\n";
175 } elsif ( $revokestyle eq "show" ) {
176 print "/revuid { uid } def\n";
177 } elsif ( $revokestyle eq "strike" ) {
178 print "/revuid {\n";
179 print " uid\n";
180 print " 45 y 9 add moveto h 2 div 45 sub y 18 add lineto stroke\n";
181 print "} def\n";
182 }
183
184 print <<EOF;
185
186 /sbk {
187 50 y moveto (sub) show
188 70 y moveto show showAlgorithm (/) show show
189 150 y moveto show
190 newline
191 } def
192
193 /key {
194 noneedhline
195 EOF
196 } # sub start_postscript
197
198 # walk the output of gpg line by line
199 # $numlines has the total number of lines so we'll know how many to put on page
200 my $numlines = 0;
201 my $started = 0;
202 while(<GPG>) {
203 # we don't use these
204 if ( /^(tru|uat):/ ) { next; }
205 # every primary uid causes an extra line because of the separator
206 if ( /^pub:/ ) {
207 start_postscript() unless $started;
208 $started = 1;
209 $numlines++;
210 }
211 # primary uid
212 s/^pub:[^:]*:([^:]*):([0-9]*):.{8,8}(.{8,8}):([^:]*):[^:]*:[^:]*:[^:]*:([^:]*):[^:]*:[^:]*:.*/ ($5) ($4) ($3) $2 ($1) pub/;
213 # fingerprint, format it nicely with spaces
214 if ( /^fpr:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:([^:]*):.*/ ) {
215 my $fpr = $1;
216 # v4 key
217 $fpr =~ s/(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})(\w{4})/$1 $2 $3 $4 $5 $6 $7 $8 $9 $10/;
218 # v3 key
219 $fpr =~ s/(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})(\w{2})/$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16/g;
220 $_ = " ($fpr) fpr\n";
221 }
222 # user ids
223 s/^uid:[^:r]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:([^:]*):.*/ ($1) uid/;
224 # revoked user id
225 if (s/^uid:r[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:([^:]*):.*/ ($1) revuid/) {
226 next if $revokestyle eq "hide";
227 }
228 # subkey
229 s/^sub:[^:]*:([^:]*):([0-9]*):.{8,8}(.{8,8}):([^:]*):[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:.*/ ($4) ($3) $2 ($1) sbk/;
230 $numlines++;
231 # print this line
232 print;
233 }
234 close(GPG);
235
236 unless ($started) {
237 print STDERR "No public key found.\n";
238 exit 1;
239 }
240
241 # output the remaining postscript
242 print <<EOF;
243 } def
244
245 /numlines $numlines def
246 /num w 16 sub 10 div numlines div def
247
248 /column {
249 /y w 20 sub def
250 1 1 num {
251 gsave
252 0 0 h 2 div w rectclip
253 /upper y 11 add def
254 key
255 newline
256 /lower y 11 add def
257 0 upper h 2 div upper h 2 div lower 0 lower 0 upper moveto lineto lineto lineto lineto stroke
258 grestore
259 } for
260 } def
261
262 w 0 translate
263 90 rotate
264 column
265 h 2 div 0 translate
266 column
267
268 showpage
269
270 %%Trailer
271 %%EOF
272 EOF
273
274 # done!
275 exit 0;
276
277
278 __END__
279
280 =head1 NAME
281
282 B<gpg-key2ps> - generates a PS file from a GnuPG keyring
283
284 =head1 SYNOPSIS
285
286 B<gpg-key2ps> [B<-r> I<revoked-style>] [B<-p> I<papersize>] I<keyid-or-name> [ I<...> ]
287
288 =head1 DESCRIPTION
289
290 gpg-key2ps generates a PostScript file with your OpenPGP key fingerprint (repeated
291 as often as it fits) useful for keysigning parties. The only argument is the same
292 as you would pass to GPG's list-keys command, either a key-id or a (partial) name.
293 The PS data is written to stdout.
294
295 =head1 OPTIONS
296
297 =over
298
299 =item B<-p> B<--paper-size> I<paper-size>
300
301 Select the output paper size. Default is to look into /etc/papersize or A4 if
302 libpaper isn't installed.
303
304 =item B<-r> B<--revoked-style> I<revoked-style>
305
306 Select how to mark revoked UIDs. Five styles are available:
307 B<hide> don't show at all (default),
308 B<show> show normally,
309 B<grey> display in 50% grey,
310 B<note> add "[revoked]", and
311 B<strike> strike through.
312
313 =item I<keyid>
314
315 Keyids to print. Multiple can be separated by spaces.
316
317 =item B<-h> B<--help>
318
319 Print usage and exit.
320
321 =item B<-v> B<--version>
322
323 Print version and exit.
324
325 =back
326
327
328 =head1 SEE ALSO
329
330 gpg(1)
331
332 http://pgp-tools.alioth.debian.org/
333
334 =head1 AUTHORS AND COPYRIGHT
335
336 (c) 2001 - 2005 Simon Richter <sjr@debian.org>
337
338 (c) 2005 Thijs Kinkhorst <thijs@kinkhorst.com>
339
340 (c) 2005 Christoph Berg <cb@df7cb.de>
341