* options.h, export.c (do_export_stream), keyedit.c (keyedit_menu,
[gnupg.git] / g10 / export.c
1 /* export.c
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3  *               2005 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20  * USA.
21  */
22
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <assert.h>
29
30 #include "options.h"
31 #include "packet.h"
32 #include "errors.h"
33 #include "keydb.h"
34 #include "memory.h"
35 #include "util.h"
36 #include "main.h"
37 #include "i18n.h"
38 #include "trustdb.h"
39
40 static int do_export( STRLIST users, int secret, unsigned int options );
41 static int do_export_stream( IOBUF out, STRLIST users, int secret,
42                              KBNODE *keyblock_out, unsigned int options,
43                              int *any );
44
45 int
46 parse_export_options(char *str,unsigned int *options,int noisy)
47 {
48   struct parse_options export_opts[]=
49     {
50       {"export-local-sigs",EXPORT_LOCAL_SIGS,NULL},
51       {"export-attributes",EXPORT_ATTRIBUTES,NULL},
52       {"export-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL},
53       {"export-minimal",EXPORT_MINIMAL|EXPORT_CLEAN_SIGS|EXPORT_CLEAN_UIDS,NULL},
54       {"export-clean",EXPORT_CLEAN_SIGS|EXPORT_CLEAN_UIDS,NULL},
55       {"export-clean-sigs",EXPORT_CLEAN_SIGS,NULL},
56       {"export-clean-uids",EXPORT_CLEAN_UIDS,NULL},
57       /* Aliases for backward compatibility */
58       {"include-local-sigs",EXPORT_LOCAL_SIGS,NULL},
59       {"include-attributes",EXPORT_ATTRIBUTES,NULL},
60       {"include-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL},
61       /* dummy */
62       {"export-unusable-sigs",0,NULL},
63       {NULL,0,NULL}
64       /* add tags for include revoked and disabled? */
65     };
66
67   return parse_options(str,options,export_opts,noisy);
68 }
69
70 /****************
71  * Export the public keys (to standard out or --output).
72  * Depending on opt.armor the output is armored.
73  * options are defined in main.h.
74  * If USERS is NULL, the complete ring will be exported.  */
75 int
76 export_pubkeys( STRLIST users, unsigned int options )
77 {
78     return do_export( users, 0, options );
79 }
80
81 /****************
82  * Export to an already opened stream; return -1 if no keys have
83  * been exported
84  */
85 int
86 export_pubkeys_stream( IOBUF out, STRLIST users,
87                        KBNODE *keyblock_out, unsigned int options )
88 {
89     int any, rc;
90
91     rc = do_export_stream( out, users, 0, keyblock_out, options, &any );
92     if( !rc && !any )
93         rc = -1;
94     return rc;
95 }
96
97 int
98 export_seckeys( STRLIST users )
99 {
100     return do_export( users, 1, 0 );
101 }
102
103 int
104 export_secsubkeys( STRLIST users )
105 {
106     return do_export( users, 2, 0 );
107 }
108
109 static int
110 do_export( STRLIST users, int secret, unsigned int options )
111 {
112     IOBUF out = NULL;
113     int any, rc;
114     armor_filter_context_t afx;
115     compress_filter_context_t zfx;
116
117     memset( &afx, 0, sizeof afx);
118     memset( &zfx, 0, sizeof zfx);
119
120     rc = open_outfile( NULL, 0, &out );
121     if( rc )
122         return rc;
123
124     if( opt.armor ) {
125         afx.what = secret?5:1;
126         iobuf_push_filter( out, armor_filter, &afx );
127     }
128     if( opt.compress_keys )
129       push_compress_filter(out,&zfx,default_compress_algo());
130
131     rc = do_export_stream( out, users, secret, NULL, options, &any );
132     if( rc || !any )
133         iobuf_cancel(out);
134     else
135         iobuf_close(out);
136     return rc;
137 }
138
139
140 /* If keyblock_out is non-NULL, AND the exit code is zero, then it
141    contains a pointer to the first keyblock found and exported.  No
142    other keyblocks are exported.  The caller must free it. */
143 static int
144 do_export_stream( IOBUF out, STRLIST users, int secret,
145                   KBNODE *keyblock_out, unsigned int options, int *any )
146 {
147     int rc = 0;
148     PACKET pkt;
149     KBNODE keyblock = NULL;
150     KBNODE kbctx, node;
151     size_t ndesc, descindex;
152     KEYDB_SEARCH_DESC *desc = NULL;
153     KEYDB_HANDLE kdbhd;
154     STRLIST sl;
155     u32 keyid[2];
156
157     *any = 0;
158     init_packet( &pkt );
159     kdbhd = keydb_new (secret);
160
161     if (!users) {
162         ndesc = 1;
163         desc = m_alloc_clear ( ndesc * sizeof *desc);
164         desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
165     }
166     else {
167         for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++) 
168             ;
169         desc = m_alloc ( ndesc * sizeof *desc);
170         
171         for (ndesc=0, sl=users; sl; sl = sl->next) {
172             if (classify_user_id (sl->d, desc+ndesc))
173                 ndesc++;
174             else
175                 log_error (_("key \"%s\" not found: %s\n"),
176                            sl->d, g10_errstr (G10ERR_INV_USER_ID));
177         }
178
179         /* it would be nice to see which of the given users did
180            actually match one in the keyring.  To implement this we
181            need to have a found flag for each entry in desc and to set
182            this we must check all those entries after a match to mark
183            all matched one - currently we stop at the first match.  To
184            do this we need an extra flag to enable this feature so */
185     }
186
187 #ifdef ENABLE_SELINUX_HACKS
188     if (secret) {
189         log_error (_("exporting secret keys not allowed\n"));
190         rc = G10ERR_GENERAL;
191         goto leave;
192     }
193 #endif
194
195     while (!(rc = keydb_search2 (kdbhd, desc, ndesc, &descindex))) {
196         int sha1_warned=0,skip_until_subkey=0;
197         u32 sk_keyid[2];
198
199         if (!users) 
200             desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
201
202         /* read the keyblock */
203         rc = keydb_get_keyblock (kdbhd, &keyblock );
204         if( rc ) {
205             log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
206             goto leave;
207         }
208
209         if((node=find_kbnode(keyblock,PKT_SECRET_KEY)))
210           {
211             PKT_secret_key *sk=node->pkt->pkt.secret_key;
212
213             keyid_from_sk(sk,sk_keyid);
214
215             /* we can't apply GNU mode 1001 on an unprotected key */
216             if( secret == 2 && !sk->is_protected )
217               {
218                 log_info(_("key %s: not protected - skipped\n"),
219                          keystr(sk_keyid));
220                 continue;
221               }
222
223             /* no v3 keys with GNU mode 1001 */
224             if( secret == 2 && sk->version == 3 )
225               {
226                 log_info(_("key %s: PGP 2.x style key - skipped\n"),
227                          keystr(sk_keyid));
228                 continue;
229               }
230           }
231         else
232           {
233             /* It's a public key export */
234             if((options&EXPORT_MINIMAL)
235                && (node=find_kbnode(keyblock,PKT_PUBLIC_KEY)))
236               keyid_from_pk(node->pkt->pkt.public_key,keyid);
237
238             if(options&EXPORT_CLEAN_UIDS)
239               clean_uids_from_key(keyblock,opt.verbose);
240           }
241
242         /* and write it */
243         for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) {
244             if( skip_until_subkey )
245               {
246                 if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY
247                    || node->pkt->pkttype==PKT_SECRET_SUBKEY)
248                   skip_until_subkey=0;
249                 else
250                   continue;
251               }
252
253             /* We used to use comment packets, but not any longer.  In
254                case we still have comments on a key, strip them here
255                before we call build_packet(). */
256             if( node->pkt->pkttype == PKT_COMMENT )
257               continue;
258
259             /* make sure that ring_trust packets never get exported */
260             if (node->pkt->pkttype == PKT_RING_TRUST)
261               continue;
262
263             /* If exact is set, then we only export what was requested
264                (plus the primary key, if the user didn't specifically
265                request it) */
266             if(desc[descindex].exact
267                && (node->pkt->pkttype==PKT_PUBLIC_SUBKEY
268                    || node->pkt->pkttype==PKT_SECRET_SUBKEY))
269               {
270                 u32 kid[2];
271                 byte fpr[MAX_FINGERPRINT_LEN];
272                 size_t fprlen;
273
274                 switch(desc[descindex].mode)
275                   {
276                   case KEYDB_SEARCH_MODE_SHORT_KID:
277                   case KEYDB_SEARCH_MODE_LONG_KID:
278                     if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
279                       keyid_from_pk(node->pkt->pkt.public_key,kid);
280                     else
281                       keyid_from_sk(node->pkt->pkt.secret_key,kid);
282                     break;
283
284                   case KEYDB_SEARCH_MODE_FPR16:
285                   case KEYDB_SEARCH_MODE_FPR20:
286                   case KEYDB_SEARCH_MODE_FPR:
287                     if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
288                       fingerprint_from_pk(node->pkt->pkt.public_key,
289                                           fpr,&fprlen);
290                     else
291                       fingerprint_from_sk(node->pkt->pkt.secret_key,
292                                           fpr,&fprlen);
293                     break;
294
295                   default:
296                     break;
297                   }
298
299                 switch(desc[descindex].mode)
300                   {
301                   case KEYDB_SEARCH_MODE_SHORT_KID:
302                     if (desc[descindex].u.kid[1] != kid[1])
303                       skip_until_subkey=1;
304                     break;
305                   case KEYDB_SEARCH_MODE_LONG_KID:
306                     if (desc[descindex].u.kid[0] != kid[0]
307                         || desc[descindex].u.kid[1] != kid[1])
308                       skip_until_subkey=1;
309                     break;
310                   case KEYDB_SEARCH_MODE_FPR16:
311                     if (memcmp (desc[descindex].u.fpr, fpr, 16))
312                       skip_until_subkey=1;
313                     break;
314                   case KEYDB_SEARCH_MODE_FPR20:
315                   case KEYDB_SEARCH_MODE_FPR:
316                     if (memcmp (desc[descindex].u.fpr, fpr, 20))
317                       skip_until_subkey=1;
318                     break;
319                   default:
320                     break;
321                   }
322
323                 if(skip_until_subkey)
324                   continue;
325               }
326
327             if(node->pkt->pkttype==PKT_USER_ID)
328               {
329                 /* Run clean_sigs_from_uid against each uid if
330                    export-clean-sigs is on. */
331                 if(options&EXPORT_CLEAN_SIGS)
332                   clean_sigs_from_uid(keyblock,node,opt.verbose);
333               }
334             else if(node->pkt->pkttype==PKT_SIGNATURE)
335               {
336                 /* If we have export-minimal turned on, do not include
337                    any signature that isn't a selfsig.  Note that this
338                    only applies to uid sigs (0x10, 0x11, 0x12, and
339                    0x13).  A designated revocation is not stripped. */
340                 if((options&EXPORT_MINIMAL)
341                    && IS_UID_SIG(node->pkt->pkt.signature)
342                    && (node->pkt->pkt.signature->keyid[0]!=keyid[0]
343                        || node->pkt->pkt.signature->keyid[1]!=keyid[1]))
344                   continue;
345
346                 /* do not export packets which are marked as not
347                    exportable */
348                 if(!(options&EXPORT_LOCAL_SIGS)
349                    && !node->pkt->pkt.signature->flags.exportable)
350                   continue; /* not exportable */
351
352                 /* Do not export packets with a "sensitive" revocation
353                    key unless the user wants us to.  Note that we do
354                    export these when issuing the actual revocation
355                    (see revoke.c). */
356                 if(!(options&EXPORT_SENSITIVE_REVKEYS)
357                    && node->pkt->pkt.signature->revkey)
358                   {
359                     int i;
360
361                     for(i=0;i<node->pkt->pkt.signature->numrevkeys;i++)
362                       if(node->pkt->pkt.signature->revkey[i]->class & 0x40)
363                         break;
364
365                     if(i<node->pkt->pkt.signature->numrevkeys)
366                       continue;
367                   }
368               }
369
370             /* Don't export attribs? */
371             if( !(options&EXPORT_ATTRIBUTES) &&
372                 node->pkt->pkttype == PKT_USER_ID &&
373                 node->pkt->pkt.user_id->attrib_data ) {
374               /* Skip until we get to something that is not an attrib
375                  or a signature on an attrib */
376               while(kbctx->next && kbctx->next->pkt->pkttype==PKT_SIGNATURE) {
377                 kbctx=kbctx->next;
378               }
379  
380               continue;
381             }
382
383             if( secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY )
384               {
385                 /* we don't want to export the secret parts of the
386                  * primary key, this is done by using GNU protection mode 1001
387                  */
388                 int save_mode = node->pkt->pkt.secret_key->protect.s2k.mode;
389                 node->pkt->pkt.secret_key->protect.s2k.mode = 1001;
390                 rc = build_packet( out, node->pkt );
391                 node->pkt->pkt.secret_key->protect.s2k.mode = save_mode;
392               }
393             else
394               {
395                 /* Warn the user if the secret key or any of the secret
396                    subkeys are protected with SHA1 and we have
397                    simple_sk_checksum set. */
398                 if(!sha1_warned && opt.simple_sk_checksum &&
399                    (node->pkt->pkttype==PKT_SECRET_KEY ||
400                     node->pkt->pkttype==PKT_SECRET_SUBKEY) &&
401                    node->pkt->pkt.secret_key->protect.sha1chk)
402                   {
403                     /* I hope this warning doesn't confuse people. */
404                     log_info(_("WARNING: secret key %s does not have a "
405                                "simple SK checksum\n"),keystr(sk_keyid));
406
407                     sha1_warned=1;
408                   }
409
410                 rc = build_packet( out, node->pkt );
411               }
412
413             if( rc ) {
414                 log_error("build_packet(%d) failed: %s\n",
415                             node->pkt->pkttype, g10_errstr(rc) );
416                 rc = G10ERR_WRITE_FILE;
417                 goto leave;
418             }
419         }
420         ++*any;
421         if(keyblock_out)
422           {
423             *keyblock_out=keyblock;
424             break;
425           }
426     }
427     if( rc == -1 )
428         rc = 0;
429
430   leave:
431     m_free(desc);
432     keydb_release (kdbhd);
433     if(rc || keyblock_out==NULL)
434       release_kbnode( keyblock );
435     if( !*any )
436         log_info(_("WARNING: nothing exported\n"));
437     return rc;
438 }