diff options
Diffstat (limited to '')
-rw-r--r-- | g10/export.c | 168 |
1 files changed, 111 insertions, 57 deletions
diff --git a/g10/export.c b/g10/export.c index 9a9cd9859..47d06e651 100644 --- a/g10/export.c +++ b/g10/export.c @@ -1,5 +1,5 @@ /* export.c - * Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -25,11 +25,11 @@ #include <errno.h> #include <assert.h> -#include <gcrypt.h> #include "options.h" #include "packet.h" #include "errors.h" #include "keydb.h" +#include "memory.h" #include "util.h" #include "main.h" #include "i18n.h" @@ -83,8 +83,10 @@ do_export( STRLIST users, int secret, int onlyrfc ) IOBUF out = NULL; int any, rc; armor_filter_context_t afx; + compress_filter_context_t zfx; memset( &afx, 0, sizeof afx); + memset( &zfx, 0, sizeof zfx); rc = open_outfile( NULL, 0, &out ); if( rc ) @@ -94,6 +96,8 @@ do_export( STRLIST users, int secret, int onlyrfc ) afx.what = secret?5:1; iobuf_push_filter( out, armor_filter, &afx ); } + if( opt.compress_keys && opt.compress ) + iobuf_push_filter( out, compress_filter, &zfx ); rc = do_export_stream( out, users, secret, onlyrfc, &any ); if( rc || !any ) @@ -108,54 +112,58 @@ static int do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any ) { int rc = 0; - compress_filter_context_t zfx; PACKET pkt; KBNODE keyblock = NULL; KBNODE kbctx, node; - KBPOS kbpos; + int ndesc; + KEYDB_SEARCH_DESC *desc = NULL; + KEYDB_HANDLE kdbhd; STRLIST sl; - int all = !users; *any = 0; - memset( &zfx, 0, sizeof zfx); init_packet( &pkt ); + kdbhd = keydb_new (secret); - if( opt.compress_keys && opt.compress ) - iobuf_push_filter( out, compress_filter, &zfx ); + if (!users) { + ndesc = 1; + desc = m_alloc_clear ( ndesc * sizeof *desc); + desc[0].mode = KEYDB_SEARCH_MODE_FIRST; + } + else { + for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++) + ; + desc = m_alloc ( ndesc * sizeof *desc); + + for (ndesc=0, sl=users; sl; sl = sl->next) { + if (classify_user_id (sl->d, desc+ndesc)) + ndesc++; + else + log_error (_("key `%s' not found: %s\n"), + sl->d, g10_errstr (G10ERR_INV_USER_ID)); + } - if( all ) { - rc = enum_keyblocks_begin( &kbpos, secret ); - if( rc ) { - if( rc != -1 ) - log_error("enum_keyblocks_begin failed: %s\n", gpg_errstr(rc)); - goto leave; - } - all = 2; + /* it would be nice to see which of the given users did + actually match one in the keyring. To implement this we + need to have a found flag for each entry in desc and to set + this we must check all those entries after a match to mark + all matched one - currently we stop at the first match. To + do this we need an extra flag to enable this feature so */ } - /* use the correct sequence. strlist_last,prev do work correctly with - * NULL pointers :-) */ - for( sl=strlist_last(users); sl || all ; sl=strlist_prev( users, sl )) { - if( all ) { /* get the next user */ - rc = enum_keyblocks_next( kbpos, 1, &keyblock ); - if( rc == -1 ) /* EOF */ - break; - if( rc ) { - log_error("enum_keyblocks_next failed: %s\n", gpg_errstr(rc)); - break; - } - } - else { - /* search the userid */ - rc = secret? find_secret_keyblock_byname( &keyblock, sl->d ) - : find_keyblock_byname( &keyblock, sl->d ); - if( rc ) { - log_error(_("%s: user not found: %s\n"), sl->d, gpg_errstr(rc)); - rc = 0; - continue; - } - } + while (!(rc = keydb_search (kdbhd, desc, ndesc))) { + int sha1_warned=0; + u32 sk_keyid[2]; + + if (!users) + desc[0].mode = KEYDB_SEARCH_MODE_NEXT; + + /* read the keyblock */ + rc = keydb_get_keyblock (kdbhd, &keyblock ); + if( rc ) { + log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) ); + goto leave; + } /* do not export keys which are incompatible with rfc2440 */ if( onlyrfc && (node = find_kbnode( keyblock, PKT_PUBLIC_KEY )) ) { @@ -167,15 +175,29 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any ) } } - /* we can't apply GNU mode 1001 on an unprotected key */ - if( secret == 2 - && (node = find_kbnode( keyblock, PKT_SECRET_KEY )) - && !node->pkt->pkt.secret_key->is_protected ) - { - log_info(_("key %08lX: not protected - skipped\n"), - (ulong)keyid_from_sk( node->pkt->pkt.secret_key, NULL) ); - continue; - } + node=find_kbnode( keyblock, PKT_SECRET_KEY ); + if(node) + { + PKT_secret_key *sk=node->pkt->pkt.secret_key; + + keyid_from_sk(sk,sk_keyid); + + /* we can't apply GNU mode 1001 on an unprotected key */ + if( secret == 2 && !sk->is_protected ) + { + log_info(_("key %08lX: not protected - skipped\n"), + (ulong)sk_keyid[1]); + continue; + } + + /* no v3 keys with GNU mode 1001 */ + if( secret == 2 && sk->version == 3 ) + { + log_info(_("key %08lX: PGP 2.x style key - skipped\n"), + (ulong)sk_keyid[1]); + continue; + } + } /* and write it */ for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) { @@ -183,13 +205,30 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any ) * secret keyring */ if( !secret && node->pkt->pkttype == PKT_COMMENT ) continue; - /* do not export packets which are marked as not exportable */ + /* make sure that ring_trust packets never get exported */ + if (node->pkt->pkttype == PKT_RING_TRUST) + continue; + if( node->pkt->pkttype == PKT_SIGNATURE ) { - const char *p; - p = parse_sig_subpkt2( node->pkt->pkt.signature, - SIGSUBPKT_EXPORTABLE, NULL ); - if( p && !*p ) - continue; /* not exportable */ + /* do not export packets which are marked as not exportable */ + if( !node->pkt->pkt.signature->flags.exportable ) + continue; /* not exportable */ + + /* do not export packets with a "sensitive" revocation + key. This will need revisiting when we start + supporting creating revocation keys and not just + reading them. */ + if( node->pkt->pkt.signature->revkey ) { + int i; + + for(i=0;i<node->pkt->pkt.signature->numrevkeys;i++) + if(node->pkt->pkt.signature->revkey[i]->class & 0x40) + continue; + } + + /* delete our verification cache */ + delete_sig_subpkt (node->pkt->pkt.signature->unhashed, + SIGSUBPKT_PRIV_VERIFY_CACHE); } if( secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY ) { @@ -202,13 +241,28 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any ) node->pkt->pkt.secret_key->protect.s2k.mode = save_mode; } else { + /* Warn the user if the secret key or any of the secret + subkeys are protected with SHA1 and we have + simple_sk_checksum set. */ + if(!sha1_warned && opt.simple_sk_checksum && + (node->pkt->pkttype==PKT_SECRET_KEY || + node->pkt->pkttype==PKT_SECRET_SUBKEY) && + node->pkt->pkt.secret_key->protect.sha1chk) + { + /* I hope this warning doesn't confuse people. */ + log_info("Warning: secret key %08lX does not have a " + "simple SK checksum\n",(ulong)sk_keyid[1]); + + sha1_warned=1; + } + rc = build_packet( out, node->pkt ); } if( rc ) { log_error("build_packet(%d) failed: %s\n", - node->pkt->pkttype, gpg_errstr(rc) ); - rc = GPGERR_WRITE_FILE; + node->pkt->pkttype, g10_errstr(rc) ); + rc = G10ERR_WRITE_FILE; goto leave; } } @@ -218,8 +272,8 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any ) rc = 0; leave: - if( all == 2 ) - enum_keyblocks_end( kbpos ); + m_free(desc); + keydb_release (kdbhd); release_kbnode( keyblock ); if( !*any ) log_info(_("WARNING: nothing exported\n")); |