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