diff options
author | Werner Koch <wk@gnupg.org> | 2010-10-01 22:33:53 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2010-10-01 22:33:53 +0200 |
commit | bfbd80feb95fba36292cd9dab43016f17b1e6972 (patch) | |
tree | 9afbfd29e8aeb78fa34a1a49d8b8071554d4f593 /g10 | |
parent | * options.skel: Make the example for force-v3-sigs match reality (it (diff) | |
download | gnupg2-bfbd80feb95fba36292cd9dab43016f17b1e6972.tar.xz gnupg2-bfbd80feb95fba36292cd9dab43016f17b1e6972.zip |
Exporting secret keys via gpg-agent is now basically supported.
A couple of forward ported changes.
Doc updates.
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 64 | ||||
-rw-r--r-- | g10/build-packet.c | 12 | ||||
-rw-r--r-- | g10/call-agent.c | 142 | ||||
-rw-r--r-- | g10/call-agent.h | 10 | ||||
-rw-r--r-- | g10/card-util.c | 10 | ||||
-rw-r--r-- | g10/compress.c | 4 | ||||
-rw-r--r-- | g10/decrypt-data.c | 4 | ||||
-rw-r--r-- | g10/decrypt.c | 12 | ||||
-rw-r--r-- | g10/encrypt.c | 10 | ||||
-rw-r--r-- | g10/export.c | 751 | ||||
-rw-r--r-- | g10/free-packet.c | 2 | ||||
-rw-r--r-- | g10/getkey.c | 16 | ||||
-rw-r--r-- | g10/gpg.c | 78 | ||||
-rw-r--r-- | g10/gpgv.c | 14 | ||||
-rw-r--r-- | g10/import.c | 46 | ||||
-rw-r--r-- | g10/keydb.h | 9 | ||||
-rw-r--r-- | g10/keyedit.c | 20 | ||||
-rw-r--r-- | g10/keygen.c | 2 | ||||
-rw-r--r-- | g10/keyid.c | 14 | ||||
-rw-r--r-- | g10/keylist.c | 14 | ||||
-rw-r--r-- | g10/keyserver-internal.h | 33 | ||||
-rw-r--r-- | g10/keyserver.c | 112 | ||||
-rw-r--r-- | g10/main.h | 35 | ||||
-rw-r--r-- | g10/mainproc.c | 41 | ||||
-rw-r--r-- | g10/options.h | 2 | ||||
-rw-r--r-- | g10/packet.h | 13 | ||||
-rw-r--r-- | g10/parse-packet.c | 2 | ||||
-rw-r--r-- | g10/photoid.c | 2 | ||||
-rw-r--r-- | g10/pkclist.c | 16 | ||||
-rw-r--r-- | g10/server.c | 6 | ||||
-rw-r--r-- | g10/sign.c | 5 | ||||
-rw-r--r-- | g10/verify.c | 16 |
32 files changed, 1105 insertions, 412 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index 554c12b11..17f3e3269 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,67 @@ +2010-10-01 Werner Koch <wk@g10code.com> + + * export.c (do_export_stream): Rewrite to take the secret keys + from the agent. + (canon_pubkey_algo, transfer_format_to_openpgp): New. + +2010-09-29 Werner Koch <wk@g10code.com> + + * keygen.c (key_from_sexp): Fix memory leak in the error case. + + * call-agent.c (agent_export_key): New. + +2010-09-29 Werner Koch <wk@g10code.com> + + * build-packet.c (build_packet): Fix up the pkttype. + + * keyid.c (keystr_with_sub): Make SUB_KID optional. + (keystr_from_pk_with_sub): Ditto. + + * call-agent.c (agent_scd_pksign): Add missing space. + + * mainproc.c (struct mainproc_context): Add field CTRL. + (proc_packets): Add arg CTRL. Change all callers. + (proc_signature_packets, proc_signature_packets_by_fd) + (proc_encryption_packets): Add arg CTRL. Change all callers. + * compress.c (handle_compressed): Ditto. + * getkey.c (get_pubkey_byname): Ditto. + * keyserver.c (keyserver_spawn, keyserver_work): Ditto. + (show_prompt, keyserver_export, keyserver_import) + (keyserver_import_fprint, keyserver_import_keyid) + (keyserver_refresh, keyserver_search, keyserver_fetch) + (keyserver_import_name, keyserver_search_prompt) + (keyserver_import_pka, keyserver_import_cert): Ditto. + callers. + * verify.c (verify_signatures, verify_files): Ditto. + * sign.c (sign_file): Ditto. + * encrypt.c (encrypt_crypt, encrypt_crypt_files): Ditto. + * pkclist.c (find_and_check_key, build_pk_list): Ditto. + * keylist.c (locate_one, public_key_list, secret_key_list): Ditto. + * card-util.c (fetch_url, card_edit): Ditto. + * import.c (check_prefs, import_one, revocation_present): Ditto. + * keyedit.c (menu_addrevoker, keyedit_menu): Ditto. + * decrypt-data.c (decrypt_data): Ditto. + * decrypt.c (decrypt_message, decrypt_messages) + (decrypt_message_fd): Ditto. + * gpgv.c (main): Add CTRL structure. + +2010-09-28 Werner Koch <wk@g10code.com> + + * options.h (struct opt): Remove SIMPLE_SK_CHECKSUM. + + * export.c (parse_export_options): Remove option + export-resert-subkey-passwd. + (do_export_stream, do_export, export_pubkeys) + (export_pubkeys_stream, export_seckeys, export_secsubkeys): Add + arg CTRL. Change all callers. + + * call-agent.c (hash_algo_option): New. + (agent_scd_pksign): Use it. + +2010-09-17 Werner Koch <wk@g10code.com> + + * call-agent.c (agent_probe_any_secret_key): New. + 2010-09-28 David Shaw <dshaw@jabberwocky.com> * options.skel: Make the example for force-v3-sigs match diff --git a/g10/build-packet.c b/g10/build-packet.c index 354afece7..83d6c7a73 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -26,10 +26,10 @@ #include <ctype.h> #include "gpg.h" +#include "util.h" #include "packet.h" #include "status.h" #include "iobuf.h" -#include "util.h" #include "cipher.h" #include "i18n.h" #include "options.h" @@ -71,8 +71,16 @@ build_packet( IOBUF out, PACKET *pkt ) log_debug("build_packet() type=%d\n", pkt->pkttype ); assert( pkt->pkt.generic ); - switch( (pkttype = pkt->pkttype) ) + switch ((pkttype = pkt->pkttype)) { + case PKT_PUBLIC_KEY: + if (pkt->pkt.public_key->seckey_info) + pkttype = PKT_SECRET_KEY; + break; + case PKT_PUBLIC_SUBKEY: + if (pkt->pkt.public_key->seckey_info) + pkttype = PKT_SECRET_SUBKEY; + break; case PKT_PLAINTEXT: new_ctb = pkt->pkt.plaintext->new_ctb; break; case PKT_ENCRYPTED: case PKT_ENCRYPTED_MDC: new_ctb = pkt->pkt.encrypted->new_ctb; break; diff --git a/g10/call-agent.c b/g10/call-agent.c index 90fa40e1d..bdf4c9589 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -901,7 +901,27 @@ membuf_data_cb (void *opaque, const void *buffer, size_t length) put_membuf (data, buffer, length); return 0; } - + + +/* Helper returning a command option to describe the used hash + algorithm. See scd/command.c:cmd_pksign. */ +static const char * +hash_algo_option (int algo) +{ + switch (algo) + { + case GCRY_MD_RMD160: return "--hash=rmd160"; + case GCRY_MD_SHA1 : return "--hash=sha1"; + case GCRY_MD_SHA224: return "--hash=sha224"; + case GCRY_MD_SHA256: return "--hash=sha256"; + case GCRY_MD_SHA384: return "--hash=sha384"; + case GCRY_MD_SHA512: return "--hash=sha512"; + case GCRY_MD_MD5 : return "--hash=md5"; + default: return ""; + } +} + + /* Send a sign command to the scdaemon via gpg-agent's pass thru mechanism. */ int @@ -942,14 +962,11 @@ agent_scd_pksign (const char *serialno, int hashalgo, return rc; init_membuf (&data, 1024); -#if 0 - if (!hashalgo) /* Temporary test hack. */ - snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno); - else -#endif - snprintf (line, DIM(line)-1, "SCD PKSIGN %s%s", - hashalgo == GCRY_MD_RMD160? "--hash=rmd160 " : "", - serialno); + /* if (!hashalgo) /\* Temporary test hack. *\/ */ + /* snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno); */ + /* else */ + snprintf (line, DIM(line)-1, "SCD PKSIGN %s %s", + hash_algo_option (hashalgo), serialno); line[DIM(line)-1] = 0; rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data, default_inq_cb, NULL, NULL, NULL); @@ -1325,6 +1342,57 @@ agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk) return err; } +/* Ask the agent whether a secret key is availabale for any of the + keys (primary or sub) in KEYBLOCK. Returns 0 if available. */ +gpg_error_t +agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock) +{ + gpg_error_t err; + char line[ASSUAN_LINELENGTH]; + char *p; + kbnode_t kbctx, node; + int nkeys; + unsigned char grip[20]; + + err = start_agent (ctrl, 0); + if (err) + return err; + + err = gpg_error (GPG_ERR_NO_SECKEY); /* Just in case no key was + found in KEYBLOCK. */ + p = stpcpy (line, "HAVEKEY"); + for (kbctx=NULL, nkeys=0; (node = walk_kbnode (keyblock, &kbctx, 0)); ) + if (node->pkt->pkttype == PKT_PUBLIC_KEY + || node->pkt->pkttype == PKT_PUBLIC_SUBKEY + || node->pkt->pkttype == PKT_SECRET_KEY + || node->pkt->pkttype == PKT_SECRET_SUBKEY) + { + if (nkeys && ((p - line) + 41) > (ASSUAN_LINELENGTH - 2)) + { + err = assuan_transact (agent_ctx, line, + NULL, NULL, NULL, NULL, NULL, NULL); + if (err != gpg_err_code (GPG_ERR_NO_SECKEY)) + break; /* Seckey available or unexpected error - ready. */ + p = stpcpy (line, "HAVEKEY"); + nkeys = 0; + } + + err = keygrip_from_pk (node->pkt->pkt.public_key, grip); + if (err) + return err; + *p++ = ' '; + bin2hex (grip, 20, p); + p += 40; + nkeys++; + } + + if (!err && nkeys) + err = assuan_transact (agent_ctx, line, + NULL, NULL, NULL, NULL, NULL, NULL); + + return err; +} + static gpg_error_t @@ -1393,7 +1461,8 @@ agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno) } -/* Status callback for agent_import_key and agent_genkey. */ +/* Status callback for agent_import_key, agent_export_key and + agent_genkey. */ static gpg_error_t cache_nonce_status_cb (void *opaque, const char *line) { @@ -1849,3 +1918,56 @@ agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr, } + +/* Receive a secret key from the agent. HEXKEYGRIP is the hexified + keygrip, DESC a prompt to be displayed with the agent's passphrase + question (needs to be plus+percent escaped). On success the key is + stored as a canonical S-expression at R_RESULT and R_RESULTLEN. */ +gpg_error_t +agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc, + char **cache_nonce_addr, + unsigned char **r_result, size_t *r_resultlen) +{ + gpg_error_t err; + membuf_t data; + size_t len; + unsigned char *buf; + char line[ASSUAN_LINELENGTH]; + + *r_result = NULL; + + err = start_agent (ctrl, 0); + if (err) + return err; + + if (desc) + { + snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc); + err = assuan_transact (agent_ctx, line, + NULL, NULL, NULL, NULL, NULL, NULL); + if (err) + return err; + } + + snprintf (line, DIM(line)-1, "EXPORT_KEY --openpgp %s%s %s", + cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"", + cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"", + hexkeygrip); + + init_membuf_secure (&data, 1024); + err = assuan_transact (agent_ctx, line, + membuf_data_cb, &data, + default_inq_cb, ctrl, + cache_nonce_status_cb, cache_nonce_addr); + if (err) + { + xfree (get_membuf (&data, &len)); + return err; + } + buf = get_membuf (&data, &len); + if (!buf) + return gpg_error_from_syserror (); + *r_result = buf; + *r_resultlen = len; + return 0; +} diff --git a/g10/call-agent.h b/g10/call-agent.h index f33f15d6a..5496e596e 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -144,6 +144,11 @@ gpg_error_t agent_get_s2k_count (unsigned long *r_count); 0 if the secret key is available. */ gpg_error_t agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk); +/* Ask the agent whether a secret key is availabale for any of the + keys (primary or sub) in KEYBLOCK. Returns 0 if available. */ +gpg_error_t agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock); + + /* Return infos about the secret key with HEXKEYGRIP. */ gpg_error_t agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno); @@ -174,6 +179,11 @@ gpg_error_t agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr, const void *key, size_t keylen); +/* Receive a key from the agent. */ +gpg_error_t agent_export_key (ctrl_t ctrl, const char *keygrip, + const char *desc, char **cache_nonce_addr, + unsigned char **r_result, size_t *r_resultlen); + #endif /*GNUPG_G10_CALL_AGENT_H*/ diff --git a/g10/card-util.c b/g10/card-util.c index 1dd7a9219..1abcde894 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -721,7 +721,7 @@ change_url (void) /* Fetch the key from the URL given on the card or try to get it from the default keyserver. */ static int -fetch_url(void) +fetch_url (ctrl_t ctrl) { int rc; struct agent_card_info_s info; @@ -751,13 +751,13 @@ fetch_url(void) event, the fpr/keyid is not meaningful for straight HTTP fetches, but using it allows the card to point to HKP and LDAP servers as well. */ - rc=keyserver_import_fprint(info.fpr1,20,spec); + rc = keyserver_import_fprint (ctrl, info.fpr1, 20, spec); free_keyserver_spec(spec); } } else if (info.fpr1valid) { - rc = keyserver_import_fprint (info.fpr1, 20, opt.keyserver); + rc = keyserver_import_fprint (ctrl, info.fpr1, 20, opt.keyserver); } } @@ -1765,7 +1765,7 @@ card_edit_completion(const char *text, int start, int end) /* Menu to edit all user changeable values on an OpenPGP card. Only Key creation is not handled here. */ void -card_edit (strlist_t commands) +card_edit (ctrl_t ctrl, strlist_t commands) { enum cmdids cmd = cmdNOP; int have_commands = !!commands; @@ -1924,7 +1924,7 @@ card_edit (strlist_t commands) break; case cmdFETCH: - fetch_url(); + fetch_url (ctrl); break; case cmdLOGIN: diff --git a/g10/compress.c b/g10/compress.c index db9fedb64..5dd3591df 100644 --- a/g10/compress.c +++ b/g10/compress.c @@ -300,7 +300,7 @@ release_context (compress_filter_context_t *ctx) * Handle a compressed packet */ int -handle_compressed( void *procctx, PKT_compressed *cd, +handle_compressed (ctrl_t ctrl, void *procctx, PKT_compressed *cd, int (*callback)(IOBUF, void *), void *passthru ) { compress_filter_context_t *cfx; @@ -315,7 +315,7 @@ handle_compressed( void *procctx, PKT_compressed *cd, if( callback ) rc = callback(cd->buf, passthru ); else - rc = proc_packets(procctx, cd->buf); + rc = proc_packets (ctrl,procctx, cd->buf); cd->buf = NULL; return rc; } diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c index c9da9be97..3779f6a92 100644 --- a/g10/decrypt-data.c +++ b/g10/decrypt-data.c @@ -74,7 +74,7 @@ release_dfx_context (decode_filter_ctx_t dfx) * Decrypt the data, specified by ED with the key DEK. */ int -decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek ) +decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek) { decode_filter_ctx_t dfx; byte *p; @@ -191,7 +191,7 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek ) else iobuf_push_filter ( ed->buf, decode_filter, dfx ); - proc_packets ( procctx, ed->buf ); + proc_packets (ctrl, procctx, ed->buf ); ed->buf = NULL; if (dfx->eof_seen > 1 ) rc = gpg_error (GPG_ERR_INV_PACKET); diff --git a/g10/decrypt.c b/g10/decrypt.c index 210e1feec..595b2879e 100644 --- a/g10/decrypt.c +++ b/g10/decrypt.c @@ -43,7 +43,7 @@ * rejects files which don't begin with an encrypted message. */ int -decrypt_message (const char *filename) +decrypt_message (ctrl_t ctrl, const char *filename) { IOBUF fp; armor_filter_context_t *afx = NULL; @@ -86,7 +86,7 @@ decrypt_message (const char *filename) no_out = 1; opt.outfile = "-"; } - rc = proc_encryption_packets ( NULL, fp ); + rc = proc_encryption_packets (ctrl, NULL, fp ); if (no_out) opt.outfile = NULL; @@ -100,7 +100,7 @@ decrypt_message (const char *filename) /* Same as decrypt_message but takes a file descriptor for input and output. */ gpg_error_t -decrypt_message_fd (int input_fd, int output_fd) +decrypt_message_fd (ctrl_t ctrl, int input_fd, int output_fd) { gpg_error_t err; IOBUF fp; @@ -158,7 +158,7 @@ decrypt_message_fd (int input_fd, int output_fd) } } - err = proc_encryption_packets ( NULL, fp ); + err = proc_encryption_packets (ctrl, NULL, fp ); iobuf_close (fp); fclose (opt.outfp); @@ -170,7 +170,7 @@ decrypt_message_fd (int input_fd, int output_fd) void -decrypt_messages (int nfiles, char *files[]) +decrypt_messages (ctrl_t ctrl, int nfiles, char *files[]) { IOBUF fp; armor_filter_context_t *afx = NULL; @@ -251,7 +251,7 @@ decrypt_messages (int nfiles, char *files[]) push_armor_filter ( afx, fp ); } } - rc = proc_packets(NULL, fp); + rc = proc_packets (ctrl,NULL, fp); iobuf_close(fp); if (rc) log_error("%s: decryption failed: %s\n", print_fname_stdin(filename), diff --git a/g10/encrypt.c b/g10/encrypt.c index 881fecfc1..55f9b27fb 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -461,7 +461,7 @@ write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek, * PROVIDED_PKS; if not the function builds a list of keys on its own. */ int -encrypt_crypt (int filefd, const char *filename, +encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, strlist_t remusr, int use_symkey, pk_list_t provided_keys, int outputfd) { @@ -503,7 +503,7 @@ encrypt_crypt (int filefd, const char *filename, pk_list = provided_keys; else { - if ((rc = build_pk_list (remusr, &pk_list, PUBKEY_USAGE_ENC))) + if ((rc = build_pk_list (ctrl, remusr, &pk_list, PUBKEY_USAGE_ENC))) { release_progress_context (pfx); return rc; @@ -939,7 +939,7 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out) void -encrypt_crypt_files (int nfiles, char **files, strlist_t remusr) +encrypt_crypt_files (ctrl_t ctrl, int nfiles, char **files, strlist_t remusr) { int rc = 0; @@ -963,7 +963,7 @@ encrypt_crypt_files (int nfiles, char **files, strlist_t remusr) } line[strlen(line)-1] = '\0'; print_file_status(STATUS_FILE_START, line, 2); - rc = encrypt_crypt (-1, line, remusr, 0, NULL, -1); + rc = encrypt_crypt (ctrl, -1, line, remusr, 0, NULL, -1); if (rc) log_error ("encryption of `%s' failed: %s\n", print_fname_stdin(line), g10_errstr(rc) ); @@ -975,7 +975,7 @@ encrypt_crypt_files (int nfiles, char **files, strlist_t remusr) while (nfiles--) { print_file_status(STATUS_FILE_START, *files, 2); - if ( (rc = encrypt_crypt (-1, *files, remusr, 0, NULL, -1)) ) + if ( (rc = encrypt_crypt (ctrl, -1, *files, remusr, 0, NULL, -1)) ) log_error("encryption of `%s' failed: %s\n", print_fname_stdin(*files), g10_errstr(rc) ); write_status( STATUS_FILE_DONE ); diff --git a/g10/export.c b/g10/export.c index bea798e47..91c6a73d7 100644 --- a/g10/export.c +++ b/g10/export.c @@ -1,6 +1,6 @@ -/* export.c +/* export.c - Export keys in the OpenPGP defined format. * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, - * 2005 Free Software Foundation, Inc. + * 2005, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -34,7 +34,7 @@ #include "main.h" #include "i18n.h" #include "trustdb.h" - +#include "call-agent.h" /* An object to keep track of subkeys. */ struct subkey_list_s @@ -45,10 +45,12 @@ struct subkey_list_s typedef struct subkey_list_s *subkey_list_t; -static int do_export( strlist_t users, int secret, unsigned int options ); -static int do_export_stream( IOBUF out, strlist_t users, int secret, - KBNODE *keyblock_out, unsigned int options, - int *any ); +static int do_export (ctrl_t ctrl, + strlist_t users, int secret, unsigned int options ); +static int do_export_stream (ctrl_t ctrl, iobuf_t out, + strlist_t users, int secret, + kbnode_t *keyblock_out, unsigned int options, + int *any); static int build_sexp (iobuf_t out, PACKET *pkt, int *indent); @@ -63,8 +65,6 @@ parse_export_options(char *str,unsigned int *options,int noisy) N_("export attribute user IDs (generally photo IDs)")}, {"export-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL, N_("export revocation keys marked as \"sensitive\"")}, - {"export-reset-subkey-passwd",EXPORT_RESET_SUBKEY_PASSWD,NULL, - N_("remove the passphrase from exported subkeys")}, {"export-clean",EXPORT_CLEAN,NULL, N_("remove unusable parts from key during export")}, {"export-minimal",EXPORT_MINIMAL|EXPORT_CLEAN,NULL, @@ -93,9 +93,9 @@ parse_export_options(char *str,unsigned int *options,int noisy) * options are defined in main.h. * If USERS is NULL, the complete ring will be exported. */ int -export_pubkeys( strlist_t users, unsigned int options ) +export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options ) { - return do_export( users, 0, options ); + return do_export (ctrl, users, 0, options ); } /**************** @@ -103,35 +103,41 @@ export_pubkeys( strlist_t users, unsigned int options ) * been exported */ int -export_pubkeys_stream( IOBUF out, strlist_t users, - KBNODE *keyblock_out, unsigned int options ) +export_pubkeys_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, + kbnode_t *keyblock_out, unsigned int options ) { - int any, rc; - - rc = do_export_stream( out, users, 0, keyblock_out, options, &any ); - if( !rc && !any ) - rc = -1; - return rc; + int any, rc; + + rc = do_export_stream (ctrl, out, users, 0, keyblock_out, options, &any); + if (!rc && !any) + rc = -1; + return rc; } int -export_seckeys( strlist_t users ) +export_seckeys (ctrl_t ctrl, strlist_t users ) { /* Use only relevant options for the secret key. */ unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT); - return do_export( users, 1, options ); + return do_export (ctrl, users, 1, options); } int -export_secsubkeys( strlist_t users ) +export_secsubkeys (ctrl_t ctrl, strlist_t users ) { /* Use only relevant options for the secret key. */ unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT); - return do_export( users, 2, options ); + return do_export (ctrl, users, 2, options); } + +/* Export the keys identified by the list of strings in USERS. If + Secret is false public keys will be exported. With secret true + secret keys will be exported; in this case 1 means the entire + secret keyblock and 2 only the subkeys. OPTIONS are the export + options to apply. */ static int -do_export( strlist_t users, int secret, unsigned int options ) +do_export (ctrl_t ctrl, strlist_t users, int secret, unsigned int options ) { IOBUF out = NULL; int any, rc; @@ -156,7 +162,7 @@ do_export( strlist_t users, int secret, unsigned int options ) push_compress_filter (out,&zfx,default_compress_algo()); } - rc = do_export_stream ( out, users, secret, NULL, options, &any ); + rc = do_export_stream (ctrl, out, users, secret, NULL, options, &any ); if ( rc || !any ) iobuf_cancel (out); @@ -275,11 +281,324 @@ exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node) } -/* If keyblock_out is non-NULL, AND the exit code is zero, then it - contains a pointer to the first keyblock found and exported. No - other keyblocks are exported. The caller must free it. */ +/* Return a canonicalized public key algoithms. This is used to + compare different flavors of algorithms (e.g. ELG and ELG_E are + considered the same). */ +static int +canon_pubkey_algo (int algo) +{ + switch (algo) + { + case GCRY_PK_RSA: + case GCRY_PK_RSA_E: + case GCRY_PK_RSA_S: return GCRY_PK_RSA; + case GCRY_PK_ELG: + case GCRY_PK_ELG_E: return GCRY_PK_ELG; + default: return algo; + } +} + + +/* Use the key transfer format given in S_PGP to create the secinfo + structure in PK and chnage the parameter array in PK to include the + secret parameters. */ +static gpg_error_t +transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk) +{ + gpg_error_t err; + gcry_sexp_t top_list; + gcry_sexp_t list = NULL; + const char *value; + size_t valuelen; + char *string; + int idx; + int is_v4, is_protected; + int pubkey_algo; + int protect_algo = 0; + char iv[16]; + int ivlen = 0; + int s2k_mode = 0; + int s2k_algo = 0; + byte s2k_salt[8]; + u32 s2k_count = 0; + size_t npkey, nskey; + gcry_mpi_t skey[10]; /* We support up to 9 parameters. */ + u16 desired_csum; + int skeyidx = 0; + struct seckey_info *ski; + + top_list = gcry_sexp_find_token (s_pgp, "openpgp-private-key", 0); + if (!top_list) + goto bad_seckey; + + list = gcry_sexp_find_token (top_list, "version", 0); + if (!list) + goto bad_seckey; + value = gcry_sexp_nth_data (list, 1, &valuelen); + if (!value || valuelen != 1 || !(value[0] == '3' || value[0] == '4')) + goto bad_seckey; + is_v4 = (value[0] == '4'); + + gcry_sexp_release (list); + list = gcry_sexp_find_token (top_list, "protection", 0); + if (!list) + goto bad_seckey; + value = gcry_sexp_nth_data (list, 1, &valuelen); + if (!value) + goto bad_seckey; + if (valuelen == 4 && !memcmp (value, "sha1", 4)) + is_protected = 2; + else if (valuelen == 3 && !memcmp (value, "sum", 3)) + is_protected = 1; + else if (valuelen == 4 && !memcmp (value, "none", 4)) + is_protected = 0; + else + goto bad_seckey; + if (is_protected) + { + string = gcry_sexp_nth_string (list, 2); + if (!string) + goto bad_seckey; + protect_algo = gcry_cipher_map_name (string); + xfree (string); + + value = gcry_sexp_nth_data (list, 3, &valuelen); + if (!value || !valuelen || valuelen > sizeof iv) + goto bad_seckey; + memcpy (iv, value, valuelen); + ivlen = valuelen; + + string = gcry_sexp_nth_string (list, 4); + if (!string) + goto bad_seckey; + s2k_mode = strtol (string, NULL, 10); + xfree (string); + + string = gcry_sexp_nth_string (list, 5); + if (!string) + goto bad_seckey; + s2k_algo = gcry_md_map_name (string); + xfree (string); + + value = gcry_sexp_nth_data (list, 6, &valuelen); + if (!value || !valuelen || valuelen > sizeof s2k_salt) + goto bad_seckey; + memcpy (s2k_salt, value, valuelen); + + string = gcry_sexp_nth_string (list, 7); + if (!string) + goto bad_seckey; + s2k_count = strtoul (string, NULL, 10); + xfree (string); + } + + gcry_sexp_release (list); + list = gcry_sexp_find_token (top_list, "algo", 0); + if (!list) + goto bad_seckey; + string = gcry_sexp_nth_string (list, 1); + if (!string) + goto bad_seckey; + pubkey_algo = gcry_pk_map_name (string); + xfree (string); + + if (gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &npkey) + || gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &nskey) + || !npkey || npkey >= nskey || nskey > PUBKEY_MAX_NSKEY) + goto bad_seckey; + + gcry_sexp_release (list); + list = gcry_sexp_find_token (top_list, "skey", 0); + if (!list) + goto bad_seckey; + for (idx=0;;) + { + int is_enc; + + value = gcry_sexp_nth_data (list, ++idx, &valuelen); + if (!value && skeyidx >= npkey) + break; /* Ready. */ + + /* Check for too many parameters. Note that depending on the + protection mode and version number we may see less than NSKEY + (but at least NPKEY+1) parameters. */ + if (idx >= 2*nskey) + goto bad_seckey; + if (skeyidx >= DIM (skey)-1) + goto bad_seckey; + + if (!value || valuelen != 1 || !(value[0] == '_' || value[0] == 'e')) + goto bad_seckey; + is_enc = (value[0] == 'e'); + value = gcry_sexp_nth_data (list, ++idx, &valuelen); + if (!value || !valuelen) + goto bad_seckey; + if (is_enc) + { + void *p = xtrymalloc (valuelen); + if (!p) + goto outofmem; + memcpy (p, value, valuelen); + skey[skeyidx] = gcry_mpi_set_opaque (NULL, p, valuelen*8); + if (!skey[skeyidx]) + goto outofmem; + } + else + { + if (gcry_mpi_scan (skey + skeyidx, GCRYMPI_FMT_STD, + value, valuelen, NULL)) + goto bad_seckey; + } + skeyidx++; + } + skey[skeyidx++] = NULL; + + gcry_sexp_release (list); + list = gcry_sexp_find_token (top_list, "csum", 0); + if (list) + { + string = gcry_sexp_nth_string (list, 1); + if (!string) + goto bad_seckey; + desired_csum = strtoul (string, NULL, 10); + xfree (string); + } + else + desired_csum = 0; + + + gcry_sexp_release (list); list = NULL; + gcry_sexp_release (top_list); top_list = NULL; + + /* log_debug ("XXX is_v4=%d\n", is_v4); */ + /* log_debug ("XXX pubkey_algo=%d\n", pubkey_algo); */ + /* log_debug ("XXX is_protected=%d\n", is_protected); */ + /* log_debug ("XXX protect_algo=%d\n", protect_algo); */ + /* log_printhex ("XXX iv", iv, ivlen); */ + /* log_debug ("XXX ivlen=%d\n", ivlen); */ + /* log_debug ("XXX s2k_mode=%d\n", s2k_mode); */ + /* log_debug ("XXX s2k_algo=%d\n", s2k_algo); */ + /* log_printhex ("XXX s2k_salt", s2k_salt, sizeof s2k_salt); */ + /* log_debug ("XXX s2k_count=%lu\n", (unsigned long)s2k_count); */ + /* for (idx=0; skey[idx]; idx++) */ + /* { */ + /* int is_enc = gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE); */ + /* log_info ("XXX skey[%d]%s:", idx, is_enc? " (enc)":""); */ + /* if (is_enc) */ + /* { */ + /* void *p; */ + /* unsigned int nbits; */ + /* p = gcry_mpi_get_opaque (skey[idx], &nbits); */ + /* log_printhex (NULL, p, (nbits+7)/8); */ + /* } */ + /* else */ + /* gcry_mpi_dump (skey[idx]); */ + /* log_printf ("\n"); */ + /* } */ + + if (!is_v4 || is_protected != 2 ) + { + /* We only support the v4 format and a SHA-1 checksum. */ + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + goto leave; + } + + /* Do some sanity checks. */ + if (s2k_count <= 1024) + { + /* The count must be larger so that encode_s2k_iterations does + not fall into a backward compatibility mode. */ + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + if (canon_pubkey_algo (pubkey_algo) != canon_pubkey_algo (pk->pubkey_algo)) + { + err = gpg_error (GPG_ERR_PUBKEY_ALGO); + goto leave; + } + err = openpgp_cipher_test_algo (protect_algo); + if (err) + goto leave; + err = openpgp_md_test_algo (s2k_algo); + if (err) + goto leave; + + /* Check that the public key parameters match. */ + for (idx=0; idx < npkey; idx++) + if (gcry_mpi_get_flag (pk->pkey[idx], GCRYMPI_FLAG_OPAQUE) + || gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE) + || gcry_mpi_cmp (pk->pkey[idx], skey[idx])) + { + err = gpg_error (GPG_ERR_BAD_PUBKEY); + goto leave; + } + + /* Check that the first secret key parameter in SKEY is encrypted + and that there are no more secret key parameters. The latter is + guaranteed by the v4 packet format. */ + if (!gcry_mpi_get_flag (skey[npkey], GCRYMPI_FLAG_OPAQUE)) + goto bad_seckey; + if (npkey+1 < DIM (skey) && skey[npkey+1]) + goto bad_seckey; + + /* Check that the secret key parameters in PK are all set to NULL. */ + for (idx=npkey; idx < nskey; idx++) + if (pk->pkey[idx]) + goto bad_seckey; + + /* Now build the protection info. */ + pk->seckey_info = ski = xtrycalloc (1, sizeof *ski); + if (!ski) + { + err = gpg_error_from_syserror (); + goto leave; + } + + ski->is_protected = 1; + ski->sha1chk = 1; + ski->algo = protect_algo; + ski->s2k.mode = s2k_mode; + ski->s2k.hash_algo = s2k_algo; + assert (sizeof ski->s2k.salt == sizeof s2k_salt); + memcpy (ski->s2k.salt, s2k_salt, sizeof s2k_salt); + ski->s2k.count = encode_s2k_iterations (s2k_count); + assert (ivlen <= sizeof ski->iv); + memcpy (ski->iv, iv, ivlen); + ski->ivlen = ivlen; + + /* Store the protected secret key parameter. */ + pk->pkey[npkey] = skey[npkey]; + skey[npkey] = NULL; + + /* That's it. */ + + leave: + gcry_sexp_release (list); + gcry_sexp_release (top_list); + for (idx=0; idx < skeyidx; idx++) + gcry_mpi_release (skey[idx]); + return err; + + bad_seckey: + err = gpg_error (GPG_ERR_BAD_SECKEY); + goto leave; + + outofmem: + err = gpg_error (GPG_ERR_ENOMEM); + goto leave; +} + +/* Export the keys identified by the list of strings in USERS to the + stream OUT. If Secret is false public keys will be exported. With + secret true secret keys will be exported; in this case 1 means the + entire secret keyblock and 2 only the subkeys. OPTIONS are the + export options to apply. If KEYBLOCK_OUT is not NULL, AND the exit + code is zero, a pointer to the first keyblock found and exported + will be stored at this address; no other keyblocks are exported in + this case. The caller must free it the returned keyblock. If any + key has been exported true is stored at ANY. */ static int -do_export_stream (iobuf_t out, strlist_t users, int secret, +do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, kbnode_t *keyblock_out, unsigned int options, int *any) { gpg_error_t err = 0; @@ -292,6 +611,7 @@ do_export_stream (iobuf_t out, strlist_t users, int secret, KEYDB_HANDLE kdbhd; strlist_t sl; int indent = 0; + gcry_cipher_hd_t cipherhd = NULL; *any = 0; init_packet (&pkt); @@ -330,21 +650,51 @@ do_export_stream (iobuf_t out, strlist_t users, int secret, if (secret) { log_error (_("exporting secret keys not allowed\n")); - err = G10ERR_GENERAL; + err = gpg_error (GPG_ERR_NOT_SUPPORTED); goto leave; } #endif + + /* For secret key export we need to setup a decryption context. */ + if (secret) + { + void *kek = NULL; + size_t keklen; + + err = agent_keywrap_key (ctrl, 1, &kek, &keklen); + if (err) + { + log_error ("error getting the KEK: %s\n", gpg_strerror (err)); + goto leave; + } + + /* Prepare a cipher context. */ + err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128, + GCRY_CIPHER_MODE_AESWRAP, 0); + if (!err) + err = gcry_cipher_setkey (cipherhd, kek, keklen); + if (err) + { + log_error ("error setting up an encryption context: %s\n", + gpg_strerror (err)); + goto leave; + } + xfree (kek); + kek = NULL; + } while (!(err = keydb_search2 (kdbhd, desc, ndesc, &descindex))) { - int sha1_warned = 0; int skip_until_subkey = 0; u32 keyid[2]; + PKT_public_key *pk; if (!users) desc[0].mode = KEYDB_SEARCH_MODE_NEXT; /* Read the keyblock. */ + release_kbnode (keyblock); + keyblock = NULL; err = keydb_get_keyblock (kdbhd, &keyblock); if (err) { @@ -352,60 +702,57 @@ do_export_stream (iobuf_t out, strlist_t users, int secret, goto leave; } - if ((node=find_kbnode(keyblock, PKT_SECRET_KEY))) + node = find_kbnode (keyblock, PKT_PUBLIC_KEY); + if (!node) { - PKT_public_key *pk = node->pkt->pkt.public_key; - - keyid_from_pk (pk, keyid); + log_error ("public key packet not found in keyblock - skipped\n"); + continue; + } + pk = node->pkt->pkt.public_key; + keyid_from_pk (pk, keyid); - /* We can't apply GNU mode 1001 on an unprotected key. */ - if( secret == 2 - && pk->seckey_info && !pk->seckey_info->is_protected ) - { - log_info (_("key %s: not protected - skipped\n"), - keystr (keyid)); - continue; - } + /* If a secret key export is required we need to check whether + we have a secret key at all and if so create the seckey_info + structure. */ + if (secret) + { + if (agent_probe_any_secret_key (ctrl, keyblock)) + continue; /* No secret key (neither primary nor subkey). */ /* No v3 keys with GNU mode 1001. */ - if( secret == 2 && pk->version == 3 ) + if (secret == 2 && pk->version == 3) { - log_info(_("key %s: PGP 2.x style key - skipped\n"), - keystr (keyid)); + log_info (_("key %s: PGP 2.x style key - skipped\n"), + keystr (keyid)); continue; } - /* It does not make sense to export a key with a primary - key on card using a non-key stub. We simply skip those - keys when used with --export-secret-subkeys. */ - if (secret == 2 - && pk->seckey_info && pk->seckey_info->is_protected - && pk->seckey_info->s2k.mode == 1002 ) + /* The agent does not yet allow to export v3 packets. It is + actually questionable whether we should allow them at + all. */ + if (pk->version == 3) { - log_info(_("key %s: key material on-card - skipped\n"), - keystr (keyid)); + log_info ("key %s: PGP 2.x style key (v3) export " + "not yet supported - skipped\n", keystr (keyid)); continue; } } - else - { - /* It's a public key export, so do the cleaning if - requested. Note that both export-clean and - export-minimal only apply to UID sigs (0x10, 0x11, 0x12, - and 0x13). A designated revocation is never stripped, - even with export-minimal set. */ - if ( (options & EXPORT_CLEAN) ) - clean_key (keyblock, opt.verbose, options&EXPORT_MINIMAL, - NULL, NULL); - } + + /* Always do the cleaning on the public key part if requested. + Note that we don't yet set this option if we are exporting + secret keys. Note that both export-clean and export-minimal + only apply to UID sigs (0x10, 0x11, 0x12, and 0x13). A + designated revocation is never stripped, even with + export-minimal set. */ + if ((options & EXPORT_CLEAN)) + clean_key (keyblock, opt.verbose, (options&EXPORT_MINIMAL), NULL, NULL); /* And write it. */ for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); ) { if (skip_until_subkey) { - if (node->pkt->pkttype==PKT_PUBLIC_SUBKEY - || node->pkt->pkttype==PKT_SECRET_SUBKEY) + if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) skip_until_subkey = 0; else continue; @@ -425,8 +772,7 @@ do_export_stream (iobuf_t out, strlist_t users, int secret, (plus the primary key, if the user didn't specifically request it). */ if (desc[descindex].exact - && (node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY)) + && node->pkt->pkttype == PKT_PUBLIC_SUBKEY) { if (!exact_subkey_match_p (desc+descindex, node)) { @@ -440,9 +786,9 @@ do_export_stream (iobuf_t out, strlist_t users, int secret, skip in any case if the key is in that list. We need this whole mess because the import - function is not able to merge secret keys and - thus it is useless to output them as two separate - keys and have import merge them. */ + function of GnuPG < 2.1 is not able to merge + secret keys and thus it is useless to output them + as two separate keys and have import merge them. */ if (subkey_in_list_p (subkey_list, node)) skip_until_subkey = 1; /* Already processed this one. */ else @@ -508,88 +854,181 @@ do_export_stream (iobuf_t out, strlist_t users, int secret, continue; } - if (secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY) + if (secret && (node->pkt->pkttype == PKT_PUBLIC_KEY + || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)) { - /* We don't want to export the secret parts of the - * primary key, this is done by temporary switching to - * GNU protection mode 1001. */ - int save_mode = node->pkt->pkt.public_key->seckey_info->s2k.mode; - node->pkt->pkt.public_key->seckey_info->s2k.mode = 1001; - if ((options&EXPORT_SEXP_FORMAT)) - err = build_sexp (out, node->pkt, &indent); + u32 subkidbuf[2], *subkid; + char *hexgrip, *serialno; + + pk = node->pkt->pkt.public_key; + if (node->pkt->pkttype == PKT_PUBLIC_KEY) + subkid = NULL; else - err = build_packet (out, node->pkt); - node->pkt->pkt.public_key->seckey_info->s2k.mode = save_mode; - } - else if (secret == 2 && node->pkt->pkttype == PKT_SECRET_SUBKEY - && (opt.export_options&EXPORT_RESET_SUBKEY_PASSWD)) - { - /* If the subkey is protected reset the passphrase to - export an unprotected subkey. This feature is useful - in cases of a subkey copied to an unattended machine - where a passphrase is not required. */ - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); - goto leave; -#warning We need to implement this - /* PKT_secret_key *sk_save, *sk; */ - - /* sk_save = node->pkt->pkt.secret_key; */ - /* sk = copy_secret_key (NULL, sk_save); */ - /* node->pkt->pkt.secret_key = sk; */ - - /* log_info (_("about to export an unprotected subkey\n")); */ - /* switch (is_secret_key_protected (sk)) */ - /* { */ - /* case -1: */ - /* err = gpg_error (GPG_ERR_PUBKEY_ALGO); */ - /* break; */ - /* case 0: */ - /* break; */ - /* default: */ - /* if (sk->protect.s2k.mode == 1001) */ - /* ; /\* No secret parts. *\/ */ - /* else if( sk->protect.s2k.mode == 1002 ) */ - /* ; /\* Card key stub. *\/ */ - /* else */ - /* { */ - /* /\* err = check_secret_key( sk, 0 ); *\/ */ - /* } */ - /* break; */ - /* } */ - /* if (err) */ - /* { */ - /* node->pkt->pkt.secret_key = sk_save; */ - /* free_secret_key (sk); */ - /* log_error (_("failed to unprotect the subkey: %s\n"), */ - /* g10_errstr (rc)); */ - /* goto leave; */ - /* } */ - - /* if ((options&EXPORT_SEXP_FORMAT)) */ - /* err = build_sexp (out, node->pkt, &indent); */ - /* else */ - /* err = build_packet (out, node->pkt); */ - - /* node->pkt->pkt.secret_key = sk_save; */ - /* free_secret_key (sk); */ - } - 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.public_key->seckey_info->sha1chk) { - /* I hope this warning doesn't confuse people. */ - log_info(_("WARNING: secret key %s does not have a " - "simple SK checksum\n"), keystr (keyid)); + keyid_from_pk (pk, subkidbuf); + subkid = subkidbuf; + } + + if (pk->seckey_info) + { + log_error ("key %s: oops: seckey_info already set" + " - skipped\n", keystr_with_sub (keyid, subkid)); + skip_until_subkey = 1; + continue; + } + + err = hexkeygrip_from_pk (pk, &hexgrip); + if (err) + { + log_error ("key %s: error computing keygrip: %s" + " - skipped\n", keystr_with_sub (keyid, subkid), + gpg_strerror (err)); + skip_until_subkey = 1; + err = 0; + continue; + } - sha1_warned = 1; + if (secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY) + { + /* We are asked not to export the secret parts of + the primary key. Make up an error code to create + the stub. */ + err = GPG_ERR_NOT_FOUND; + serialno = NULL; } + else + err = agent_get_keyinfo (ctrl, hexgrip, &serialno); + if ((!err && serialno) + && secret == 2 && node->pkt->pkttype == PKT_PUBLIC_KEY) + { + /* It does not make sense to export a key with its + primary key on card using a non-key stub. Thus + we skip those keys when used with + --export-secret-subkeys. */ + log_info (_("key %s: key material on-card - skipped\n"), + keystr_with_sub (keyid, subkid)); + skip_until_subkey = 1; + } + else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND + || (!err && serialno)) + { + /* Create a key stub. */ + struct seckey_info *ski; + const char *s; + + pk->seckey_info = ski = xtrycalloc (1, sizeof *ski); + if (!ski) + { + err = gpg_error_from_syserror (); + xfree (hexgrip); + goto leave; + } + + ski->is_protected = 1; + if (err) + ski->s2k.mode = 1001; /* GNU dummy (no secret key). */ + else + { + ski->s2k.mode = 1002; /* GNU-divert-to-card. */ + for (s=serialno; sizeof (ski->ivlen) && *s && s[1]; + ski->ivlen++, s += 2) + ski->iv[ski->ivlen] = xtoi_2 (s); + } + + if ((options&EXPORT_SEXP_FORMAT)) + err = build_sexp (out, node->pkt, &indent); + else + err = build_packet (out, node->pkt); + } + else if (!err) + { + /* FIXME: Move this spaghetti code into a separate + function. */ + unsigned char *wrappedkey = NULL; + size_t wrappedkeylen; + unsigned char *key = NULL; + size_t keylen, realkeylen; + gcry_sexp_t s_skey; + + if (opt.verbose) + log_info ("key %s: asking agent for the secret parts\n", + keystr_with_sub (keyid, subkid)); + + err = agent_export_key (ctrl, hexgrip, "Key foo", NULL, + &wrappedkey, &wrappedkeylen); + if (err) + goto unwraperror; + if (wrappedkeylen < 24) + { + err = gpg_error (GPG_ERR_INV_LENGTH); + goto unwraperror; + } + keylen = wrappedkeylen - 8; + key = xtrymalloc_secure (keylen); + if (!key) + { + err = gpg_error_from_syserror (); + goto unwraperror; + } + err = gcry_cipher_decrypt (cipherhd, key, keylen, + wrappedkey, wrappedkeylen); + if (err) + goto unwraperror; + realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err); + if (!realkeylen) + goto unwraperror; /* Invalid csexp. */ + + err = gcry_sexp_sscan (&s_skey, NULL, key, realkeylen); + xfree (key); + key = NULL; + if (err) + goto unwraperror; + err = transfer_format_to_openpgp (s_skey, pk); + gcry_sexp_release (s_skey); + if (err) + goto unwraperror; + + if ((options&EXPORT_SEXP_FORMAT)) + err = build_sexp (out, node->pkt, &indent); + else + err = build_packet (out, node->pkt); + goto unwraperror_leave; + + unwraperror: + xfree (wrappedkey); + xfree (key); + if (err) + { + log_error ("key %s: error receiving key from agent:" + " %s%s\n", + keystr_with_sub (keyid, subkid), + gpg_strerror (err), + gpg_err_code (err) == GPG_ERR_FULLY_CANCELED? + "":_(" - skipped")); + if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED) + goto leave; + skip_until_subkey = 1; + err = 0; + } + unwraperror_leave: + ; + } + else + { + log_error ("key %s: error getting keyinfo from agent: %s" + " - skipped\n", keystr_with_sub (keyid, subkid), + gpg_strerror (err)); + skip_until_subkey = 1; + err = 0; + } + + xfree (pk->seckey_info); + pk->seckey_info = NULL; + xfree (hexgrip); + } + else + { if ((options&EXPORT_SEXP_FORMAT)) err = build_sexp (out, node->pkt, &indent); else @@ -602,6 +1041,9 @@ do_export_stream (iobuf_t out, strlist_t users, int secret, node->pkt->pkttype, gpg_strerror (err)); goto leave; } + + if (!skip_until_subkey) + *any = 1; } if ((options&EXPORT_SEXP_FORMAT) && indent) @@ -611,10 +1053,9 @@ do_export_stream (iobuf_t out, strlist_t users, int secret, iobuf_put (out, '\n'); } - ++*any; - if(keyblock_out) + if (keyblock_out) { - *keyblock_out=keyblock; + *keyblock_out = keyblock; break; } } @@ -624,10 +1065,11 @@ do_export_stream (iobuf_t out, strlist_t users, int secret, iobuf_put (out, ')'); iobuf_put (out, '\n'); } - if( err == -1 ) + if (err == -1) err = 0; leave: + gcry_cipher_close (cipherhd); release_subkey_list (subkey_list); xfree(desc); keydb_release (kdbhd); @@ -672,6 +1114,10 @@ do_export_stream (iobuf_t out, strlist_t users, int secret, static int build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent) { + (void)out; + (void)pkt; + (void)indent; + /* FIXME: Not yet implemented. */ return gpg_error (GPG_ERR_NOT_IMPLEMENTED); /* PKT_secret_key *sk = pkt->pkt.secret_key; */ @@ -759,4 +1205,3 @@ build_sexp (iobuf_t out, PACKET *pkt, int *indent) } return rc; } - diff --git a/g10/free-packet.c b/g10/free-packet.c index 47d89eed5..5c4a0fcb5 100644 --- a/g10/free-packet.c +++ b/g10/free-packet.c @@ -25,9 +25,9 @@ #include <assert.h> #include "gpg.h" +#include "util.h" #include "packet.h" #include "../common/iobuf.h" -#include "util.h" #include "cipher.h" #include "options.h" diff --git a/g10/getkey.c b/g10/getkey.c index 401e66879..8d983487b 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -676,7 +676,7 @@ key_byname (GETKEY_CTX *retctx, strlist_t namelist, to import the key via the online mechanisms defined by --auto-key-locate. */ int -get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk, +get_pubkey_byname (ctrl_t ctrl, GETKEY_CTX * retctx, PKT_public_key * pk, const char *name, KBNODE * ret_keyblock, KEYDB_HANDLE * ret_kdbhd, int include_unusable, int no_akl) { @@ -770,21 +770,21 @@ get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk, case AKL_CERT: mechanism = "DNS CERT"; glo_ctrl.in_auto_key_retrieve++; - rc = keyserver_import_cert (name, &fpr, &fpr_len); + rc = keyserver_import_cert (ctrl, name, &fpr, &fpr_len); glo_ctrl.in_auto_key_retrieve--; break; case AKL_PKA: mechanism = "PKA"; glo_ctrl.in_auto_key_retrieve++; - rc = keyserver_import_pka (name, &fpr, &fpr_len); + rc = keyserver_import_pka (ctrl, name, &fpr, &fpr_len); glo_ctrl.in_auto_key_retrieve--; break; case AKL_LDAP: mechanism = "LDAP"; glo_ctrl.in_auto_key_retrieve++; - rc = keyserver_import_ldap (name, &fpr, &fpr_len); + rc = keyserver_import_ldap (ctrl, name, &fpr, &fpr_len); glo_ctrl.in_auto_key_retrieve--; break; @@ -797,9 +797,8 @@ get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk, { mechanism = opt.keyserver->uri; glo_ctrl.in_auto_key_retrieve++; - rc = - keyserver_import_name (name, &fpr, &fpr_len, - opt.keyserver); + rc = keyserver_import_name (ctrl, name, &fpr, &fpr_len, + opt.keyserver); glo_ctrl.in_auto_key_retrieve--; } else @@ -816,7 +815,8 @@ get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk, mechanism = akl->spec->uri; keyserver = keyserver_match (akl->spec); glo_ctrl.in_auto_key_retrieve++; - rc = keyserver_import_name (name, &fpr, &fpr_len, keyserver); + rc = keyserver_import_name (ctrl, + name, &fpr, &fpr_len, keyserver); glo_ctrl.in_auto_key_retrieve--; } break; @@ -37,9 +37,9 @@ #define INCLUDED_BY_MAIN_MODULE 1 #include "gpg.h" #include <assuan.h> -#include "packet.h" #include "../common/iobuf.h" #include "util.h" +#include "packet.h" #include "main.h" #include "options.h" #include "keydb.h" @@ -273,7 +273,6 @@ enum cmd_and_opt_values oS2KDigest, oS2KCipher, oS2KCount, - oSimpleSKChecksum, oDisplayCharset, oNotDashEscaped, oEscapeFrom, @@ -565,7 +564,6 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_s (oS2KDigest, "s2k-digest-algo", "@"), ARGPARSE_s_s (oS2KCipher, "s2k-cipher-algo", "@"), ARGPARSE_s_i (oS2KCount, "s2k-count", "@"), - ARGPARSE_s_n (oSimpleSKChecksum, "simple-sk-checksum", "@"), ARGPARSE_s_s (oCipherAlgo, "cipher-algo", "@"), ARGPARSE_s_s (oDigestAlgo, "digest-algo", "@"), ARGPARSE_s_s (oCertDigestAlgo, "cert-digest-algo", "@"), @@ -2504,7 +2502,6 @@ main (int argc, char **argv) else opt.s2k_count = 0; /* Auto-calibrate when needed. */ break; - case oSimpleSKChecksum: opt.simple_sk_checksum = 1; break; case oNoEncryptTo: opt.no_encrypt_to = 1; break; case oEncryptTo: /* store the recipient in the second list */ sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); @@ -2966,8 +2963,8 @@ main (int argc, char **argv) } } - - if( configfp ) { + if (configfp) + { fclose( configfp ); configfp = NULL; /* Remember the first config file name. */ @@ -2977,10 +2974,10 @@ main (int argc, char **argv) xfree(configname); configname = NULL; goto next_pass; - } - xfree( configname ); configname = NULL; - if( log_get_errorcount(0) ) - g10_exit(2); + } + xfree(configname); configname = NULL; + if (log_get_errorcount (0)) + g10_exit(2); /* The command --gpgconf-list is pretty simple and may be called directly after the option parsing. */ @@ -3405,7 +3402,7 @@ main (int argc, char **argv) if(fname && utf8_strings) opt.flags.utf8_filename=1; - ctrl = xtrycalloc (1, sizeof *ctrl); + ctrl = xcalloc (1, sizeof *ctrl); gpg_init_default_ctrl (ctrl); switch( cmd ) { @@ -3463,12 +3460,12 @@ main (int argc, char **argv) case aEncr: /* encrypt the given file */ if(multifile) - encrypt_crypt_files(argc, argv, remusr); + encrypt_crypt_files (ctrl, argc, argv, remusr); else { if( argc > 1 ) wrong_args(_("--encrypt [filename]")); - if( (rc = encrypt_crypt (-1, fname, remusr, 0, NULL, -1)) ) + if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 0, NULL, -1)) ) log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) ); } @@ -3489,7 +3486,7 @@ main (int argc, char **argv) " while in %s mode\n"),compliance_option_string()); else { - if( (rc = encrypt_crypt (-1, fname, remusr, 1, NULL, -1)) ) + if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 1, NULL, -1)) ) log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) ); } @@ -3509,7 +3506,7 @@ main (int argc, char **argv) strcpy(sl->d, fname); } } - if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) ) + if( (rc = sign_file (ctrl, sl, detached_sig, locusr, 0, NULL, NULL)) ) log_error("signing failed: %s\n", g10_errstr(rc) ); free_strlist(sl); break; @@ -3523,7 +3520,7 @@ main (int argc, char **argv) } else sl = NULL; - if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) ) + if ((rc = sign_file (ctrl, sl, detached_sig, locusr, 1, remusr, NULL))) log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) ); free_strlist(sl); @@ -3547,7 +3544,8 @@ main (int argc, char **argv) } else sl = NULL; - if( (rc = sign_file(sl, detached_sig, locusr, 2, remusr, NULL)) ) + if ((rc = sign_file (ctrl, sl, detached_sig, locusr, + 2, remusr, NULL))) log_error("%s: symmetric+sign+encrypt failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) ); free_strlist(sl); @@ -3572,26 +3570,26 @@ main (int argc, char **argv) break; case aVerify: - if(multifile) + if (multifile) { - if( (rc = verify_files( argc, argv ) )) + if ((rc = verify_files (ctrl, argc, argv))) log_error("verify files failed: %s\n", g10_errstr(rc) ); } else { - if( (rc = verify_signatures( argc, argv ) )) + if ((rc = verify_signatures (ctrl, argc, argv))) log_error("verify signatures failed: %s\n", g10_errstr(rc) ); } break; case aDecrypt: - if(multifile) - decrypt_messages(argc, argv); + if (multifile) + decrypt_messages (ctrl, argc, argv); else { if( argc > 1 ) wrong_args(_("--decrypt [filename]")); - if( (rc = decrypt_message( fname ) )) + if( (rc = decrypt_message (ctrl, fname) )) log_error("decrypt_message failed: %s\n", g10_errstr(rc) ); } break; @@ -3616,7 +3614,7 @@ main (int argc, char **argv) append_to_strlist( &sl, "save" ); username = make_username( fname ); - keyedit_menu (username, locusr, sl, 0, 0 ); + keyedit_menu (ctrl, username, locusr, sl, 0, 0 ); xfree(username); free_strlist(sl); break; @@ -3629,11 +3627,11 @@ main (int argc, char **argv) sl = NULL; for( argc--, argv++ ; argc; argc--, argv++ ) append_to_strlist( &sl, *argv ); - keyedit_menu( username, locusr, sl, 0, 1 ); + keyedit_menu (ctrl, username, locusr, sl, 0, 1 ); free_strlist(sl); } else - keyedit_menu(username, locusr, NULL, 0, 1 ); + keyedit_menu (ctrl, username, locusr, NULL, 0, 1 ); xfree(username); break; @@ -3669,21 +3667,21 @@ main (int argc, char **argv) sl = NULL; for( ; argc; argc--, argv++ ) add_to_strlist2( &sl, *argv, utf8_strings ); - public_key_list( sl, 0 ); + public_key_list (ctrl, sl, 0); free_strlist(sl); break; case aListSecretKeys: sl = NULL; for( ; argc; argc--, argv++ ) add_to_strlist2( &sl, *argv, utf8_strings ); - secret_key_list( sl ); + secret_key_list (ctrl, sl); free_strlist(sl); break; case aLocateKeys: sl = NULL; for (; argc; argc--, argv++) add_to_strlist2( &sl, *argv, utf8_strings ); - public_key_list (sl, 1); + public_key_list (ctrl, sl, 1); free_strlist (sl); break; @@ -3718,11 +3716,11 @@ main (int argc, char **argv) for( ; argc; argc--, argv++ ) append_to_strlist2( &sl, *argv, utf8_strings ); if( cmd == aSendKeys ) - rc=keyserver_export( sl ); + rc = keyserver_export (ctrl, sl ); else if( cmd == aRecvKeys ) - rc=keyserver_import( sl ); + rc = keyserver_import (ctrl, sl ); else - rc=export_pubkeys( sl, opt.export_options ); + rc = export_pubkeys (ctrl, sl, opt.export_options); if(rc) { if(cmd==aSendKeys) @@ -3739,7 +3737,7 @@ main (int argc, char **argv) sl = NULL; for( ; argc; argc--, argv++ ) append_to_strlist2( &sl, *argv, utf8_strings ); - rc=keyserver_search( sl ); + rc = keyserver_search (ctrl, sl); if(rc) log_error(_("keyserver search failed: %s\n"),g10_errstr(rc)); free_strlist(sl); @@ -3749,7 +3747,7 @@ main (int argc, char **argv) sl = NULL; for( ; argc; argc--, argv++ ) append_to_strlist2( &sl, *argv, utf8_strings ); - rc=keyserver_refresh(sl); + rc = keyserver_refresh (ctrl, sl); if(rc) log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc)); free_strlist(sl); @@ -3759,7 +3757,7 @@ main (int argc, char **argv) sl = NULL; for( ; argc; argc--, argv++ ) append_to_strlist2( &sl, *argv, utf8_strings ); - rc=keyserver_fetch(sl); + rc = keyserver_fetch (ctrl, sl); if(rc) log_error("key fetch failed: %s\n",g10_errstr(rc)); free_strlist(sl); @@ -3769,7 +3767,7 @@ main (int argc, char **argv) sl = NULL; for( ; argc; argc--, argv++ ) add_to_strlist2( &sl, *argv, utf8_strings ); - export_seckeys( sl ); + export_seckeys (ctrl, sl); free_strlist(sl); break; @@ -3777,7 +3775,7 @@ main (int argc, char **argv) sl = NULL; for( ; argc; argc--, argv++ ) add_to_strlist2( &sl, *argv, utf8_strings ); - export_secsubkeys( sl ); + export_secsubkeys (ctrl, sl); free_strlist(sl); break; @@ -3987,11 +3985,11 @@ main (int argc, char **argv) sl = NULL; for (argc--, argv++ ; argc; argc--, argv++) append_to_strlist (&sl, *argv); - card_edit (sl); + card_edit (ctrl, sl); free_strlist (sl); } else - card_edit (NULL); + card_edit (ctrl, NULL); break; case aChangePIN: @@ -4045,7 +4043,7 @@ main (int argc, char **argv) set_packet_list_mode(1); opt.list_packets=1; } - rc = proc_packets(NULL, a ); + rc = proc_packets (ctrl, NULL, a ); if( rc ) log_error("processing message failed: %s\n", g10_errstr(rc) ); iobuf_close(a); diff --git a/g10/gpgv.c b/g10/gpgv.c index b56b1c046..b342d2481 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -35,9 +35,9 @@ #define INCLUDED_BY_MAIN_MODULE 1 #include "gpg.h" +#include "util.h" #include "packet.h" #include "iobuf.h" -#include "util.h" #include "main.h" #include "options.h" #include "keydb.h" @@ -140,8 +140,9 @@ main( int argc, char **argv ) ARGPARSE_ARGS pargs; int rc=0; strlist_t sl; - strlist_t nrings=NULL; + strlist_t nrings = NULL; unsigned configlineno; + ctrl_t ctrl; set_strusage (my_strusage); log_set_prefix ("gpgv", 1); @@ -201,10 +202,14 @@ main( int argc, char **argv ) keydb_add_resource (sl->d, 8); FREE_STRLIST (nrings); + + ctrl = xcalloc (1, sizeof *ctrl); - if ( (rc = verify_signatures( argc, argv ) )) + if ((rc = verify_signatures (ctrl, argc, argv))) log_error("verify signatures failed: %s\n", g10_errstr(rc) ); + xfree (ctrl); + /* cleanup */ g10_exit (0); return 8; /*NOTREACHED*/ @@ -377,8 +382,9 @@ get_override_session_key (DEK *dek, const char *string) /* Stub: */ int -decrypt_data (void *procctx, PKT_encrypted *ed, DEK *dek) +decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek) { + (void)ctrl; (void)procctx; (void)ed; (void)dek; diff --git a/g10/import.c b/g10/import.c index e3e7824a2..605c3b8ab 100644 --- a/g10/import.c +++ b/g10/import.c @@ -64,10 +64,11 @@ static int import (ctrl_t ctrl, IOBUF inp, const char* fname, struct stats_s *stats, unsigned char **fpr, size_t *fpr_len, unsigned int options); static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root ); -static void revocation_present(KBNODE keyblock); -static int import_one(const char *fname, KBNODE keyblock,struct stats_s *stats, - unsigned char **fpr,size_t *fpr_len, - unsigned int options,int from_sk); +static void revocation_present (ctrl_t ctrl, kbnode_t keyblock); +static int import_one (ctrl_t ctrl, + const char *fname, KBNODE keyblock,struct stats_s *stats, + unsigned char **fpr,size_t *fpr_len, + unsigned int options,int from_sk); static int import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock, struct stats_s *stats, unsigned int options); static int import_revoke_cert( const char *fname, KBNODE node, @@ -265,7 +266,8 @@ import (ctrl_t ctrl, IOBUF inp, const char* fname,struct stats_s *stats, while( !(rc = read_block( inp, &pending_pkt, &keyblock) )) { if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY ) - rc = import_one( fname, keyblock, stats, fpr, fpr_len, options, 0); + rc = import_one (ctrl, fname, keyblock, + stats, fpr, fpr_len, options, 0); else if( keyblock->pkt->pkttype == PKT_SECRET_KEY ) rc = import_secret_one (ctrl, fname, keyblock, stats, options); else if( keyblock->pkt->pkttype == PKT_SIGNATURE @@ -614,9 +616,9 @@ check_prefs_warning(PKT_public_key *pk) } static void -check_prefs(KBNODE keyblock) +check_prefs (ctrl_t ctrl, kbnode_t keyblock) { - KBNODE node; + kbnode_t node; PKT_public_key *pk; int problem=0; @@ -711,7 +713,7 @@ check_prefs(KBNODE keyblock) append_to_strlist(&sl,"updpref"); append_to_strlist(&sl,"save"); - keyedit_menu( username, locusr, sl, 1, 1 ); + keyedit_menu (ctrl, username, locusr, sl, 1, 1 ); free_strlist(sl); free_strlist(locusr); } @@ -728,7 +730,8 @@ check_prefs(KBNODE keyblock) * which called gpg. */ static int -import_one( const char *fname, KBNODE keyblock, struct stats_s *stats, +import_one (ctrl_t ctrl, + const char *fname, KBNODE keyblock, struct stats_s *stats, unsigned char **fpr,size_t *fpr_len,unsigned int options, int from_sk ) { @@ -1060,15 +1063,15 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats, if (mod_key) { - revocation_present (keyblock_orig); + revocation_present (ctrl, keyblock_orig); if (!from_sk && have_secret_key_with_kid (keyid)) - check_prefs (keyblock_orig); + check_prefs (ctrl, keyblock_orig); } else if (new_key) { - revocation_present (keyblock); + revocation_present (ctrl, keyblock); if (!from_sk && have_secret_key_with_kid (keyid)) - check_prefs (keyblock); + check_prefs (ctrl, keyblock); } release_kbnode( keyblock_orig ); @@ -1425,7 +1428,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock, keystr_from_pk (pk)); else { - import_one (fname, pub_keyblock, stats, + import_one (ctrl, fname, pub_keyblock, stats, NULL, NULL, opt.import_options, 1); /* Fixme: We should check for an invalid keyblock and cancel the secret key import in this case. */ @@ -1448,7 +1451,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock, keystr_from_pk (pk)); if (is_status_enabled ()) print_import_ok (pk, 1|16); - check_prefs (node); + check_prefs (ctrl, node); } release_kbnode (node); } @@ -2051,10 +2054,10 @@ collapse_uids( KBNODE *keyblock ) present. This may be called without the benefit of merge_xxxx so you can't rely on pk->revkey and friends. */ static void -revocation_present(KBNODE keyblock) +revocation_present (ctrl_t ctrl, kbnode_t keyblock) { - KBNODE onode,inode; - PKT_public_key *pk=keyblock->pkt->pkt.public_key; + kbnode_t onode, inode; + PKT_public_key *pk = keyblock->pkt->pkt.public_key; for(onode=keyblock->next;onode;onode=onode->next) { @@ -2106,9 +2109,10 @@ revocation_present(KBNODE keyblock) log_info(_("WARNING: key %s may be revoked:" " fetching revocation key %s\n"), tempkeystr,keystr(keyid)); - keyserver_import_fprint(sig->revkey[idx]->fpr, - MAX_FINGERPRINT_LEN, - opt.keyserver); + keyserver_import_fprint (ctrl, + sig->revkey[idx]->fpr, + MAX_FINGERPRINT_LEN, + opt.keyserver); /* Do we have it now? */ rc=get_pubkey_byfprint_fast (NULL, diff --git a/g10/keydb.h b/g10/keydb.h index 63f42a572..eab59e0a5 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -157,8 +157,10 @@ void show_revocation_reason( PKT_public_key *pk, int mode ); int check_signatures_trust( PKT_signature *sig ); void release_pk_list (PK_LIST pk_list); -int build_pk_list (strlist_t rcpts, PK_LIST *ret_pk_list, unsigned use); -gpg_error_t find_and_check_key (const char *name, unsigned int use, +int build_pk_list (ctrl_t ctrl, + strlist_t rcpts, PK_LIST *ret_pk_list, unsigned use); +gpg_error_t find_and_check_key (ctrl_t ctrl, + const char *name, unsigned int use, int mark_hidden, pk_list_t *pk_list_addr); int algo_available( preftype_t preftype, int algo, @@ -204,7 +206,8 @@ void getkey_disable_caches(void); int get_pubkey( PKT_public_key *pk, u32 *keyid ); int get_pubkey_fast ( PKT_public_key *pk, u32 *keyid ); KBNODE get_pubkeyblock( u32 *keyid ); -int get_pubkey_byname (GETKEY_CTX *rx, PKT_public_key *pk, const char *name, +int get_pubkey_byname (ctrl_t ctrl, + GETKEY_CTX *rx, PKT_public_key *pk, const char *name, KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd, int include_unusable, int no_akl ); int get_pubkey_bynames( GETKEY_CTX *rx, PKT_public_key *pk, diff --git a/g10/keyedit.c b/g10/keyedit.c index 86dacfff5..d1cacaf39 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -60,7 +60,7 @@ static void menu_deluid (KBNODE pub_keyblock); static int menu_delsig (KBNODE pub_keyblock); static int menu_clean (KBNODE keyblock, int self_only); static void menu_delkey (KBNODE pub_keyblock); -static int menu_addrevoker (KBNODE pub_keyblock, int sensitive); +static int menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive); static int menu_expire (KBNODE pub_keyblock); static int menu_backsign (KBNODE pub_keyblock); static int menu_set_primary_uid (KBNODE pub_keyblock); @@ -1586,7 +1586,7 @@ keyedit_completion (const char *text, int start, int end) /* Main function of the menu driven key editor. */ void -keyedit_menu (const char *username, strlist_t locusr, +keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, strlist_t commands, int quiet, int seckey_check) { enum cmdids cmd = 0; @@ -1599,7 +1599,6 @@ keyedit_menu (const char *username, strlist_t locusr, int modified = 0; int toggle; int have_commands = !!commands; - ctrl_t ctrl = NULL; /* Dummy for now. */ if (opt.command_fd != -1) ; @@ -1623,7 +1622,7 @@ keyedit_menu (const char *username, strlist_t locusr, #endif /* Get the public key */ - err = get_pubkey_byname (NULL, NULL, username, &keyblock, &kdbhd, 1, 1); + err = get_pubkey_byname (ctrl, NULL, NULL, username, &keyblock, &kdbhd, 1, 1); if (err) goto leave; if (fix_keyblock (keyblock)) @@ -2095,7 +2094,7 @@ keyedit_menu (const char *username, strlist_t locusr, if (ascii_strcasecmp (arg_string, "sensitive") == 0) sensitive = 1; - if (menu_addrevoker (keyblock, sensitive)) + if (menu_addrevoker (ctrl, keyblock, sensitive)) { redisplay = 1; modified = 1; @@ -2886,9 +2885,10 @@ show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker, if (pk->is_revoked) { char *user = get_user_id_string_native (pk->revoked.keyid); - const char *algo = gcry_pk_algo_name (pk->revoked.algo); - tty_printf (_("This key was revoked on %s by %s key %s\n"), - revokestr_from_pk (pk), algo ? algo : "?", user); + tty_printf (_("The following key was revoked on" + " %s by %s key %s\n"), + revokestr_from_pk (pk), + gcry_pk_algo_name (pk->revoked.algo), user); xfree (user); } @@ -3444,7 +3444,7 @@ menu_delkey (KBNODE pub_keyblock) * the keyblock. Returns true if there is a new revoker. */ static int -menu_addrevoker (KBNODE pub_keyblock, int sensitive) +menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive) { PKT_public_key *pk = NULL; PKT_public_key *revoker_pk = NULL; @@ -3508,7 +3508,7 @@ menu_addrevoker (KBNODE pub_keyblock, int sensitive) primary keys only, but some casual testing shows that PGP and GnuPG both can handle a designated revocation from a subkey. */ revoker_pk->req_usage = PUBKEY_USAGE_CERT; - rc = get_pubkey_byname (NULL, revoker_pk, answer, NULL, NULL, 1, 1); + rc = get_pubkey_byname (ctrl, NULL, revoker_pk, answer, NULL, NULL, 1, 1); if (rc) { log_error (_("key \"%s\" not found: %s\n"), answer, diff --git a/g10/keygen.c b/g10/keygen.c index 33a5a217c..00ad26ecb 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1123,7 +1123,7 @@ key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, { for (i=0; i<idx; i++) { - xfree (array[i]); + gcry_mpi_release (array[i]); array[i] = NULL; } gcry_sexp_release (list); diff --git a/g10/keyid.c b/g10/keyid.c index 1d0972649..a11769d67 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -242,9 +242,12 @@ keystr_with_sub (u32 *main_kid, u32 *sub_kid) char *p; mem2str (buffer, keystr (main_kid), KEYID_STR_SIZE); - p = buffer + strlen (buffer); - *p++ = '/'; - mem2str (p, keystr (sub_kid), KEYID_STR_SIZE); + if (sub_kid) + { + p = buffer + strlen (buffer); + *p++ = '/'; + mem2str (p, keystr (sub_kid), KEYID_STR_SIZE); + } return buffer; } @@ -262,9 +265,10 @@ const char * keystr_from_pk_with_sub (PKT_public_key *main_pk, PKT_public_key *sub_pk) { keyid_from_pk (main_pk, NULL); - keyid_from_pk (sub_pk, NULL); + if (sub_pk) + keyid_from_pk (sub_pk, NULL); - return keystr_with_sub (main_pk->keyid, sub_pk->keyid); + return keystr_with_sub (main_pk->keyid, sub_pk? sub_pk->keyid:NULL); } diff --git a/g10/keylist.c b/g10/keylist.c index 2d3574a6d..254513a76 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -43,7 +43,7 @@ static void list_all (int); static void list_one (strlist_t names, int secret); -static void locate_one (strlist_t names); +static void locate_one (ctrl_t ctrl, strlist_t names); static void print_card_serialno (PKT_public_key *sk); struct sig_stats @@ -61,7 +61,7 @@ static estream_t attrib_fp; With LOCATE_MODE set the locate algorithm is used to find a key. */ void -public_key_list (strlist_t list, int locate_mode) +public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode) { if (opt.with_colons) { @@ -107,7 +107,7 @@ public_key_list (strlist_t list, int locate_mode) check_trustdb_stale (); if (locate_mode) - locate_one (list); + locate_one (ctrl, list); else if (!list) list_all (0); else @@ -116,8 +116,10 @@ public_key_list (strlist_t list, int locate_mode) void -secret_key_list (strlist_t list) +secret_key_list (ctrl_t ctrl, strlist_t list) { + (void)ctrl; + check_trustdb_stale (); if (!list) @@ -533,7 +535,7 @@ list_one (strlist_t names, int secret) static void -locate_one (strlist_t names) +locate_one (ctrl_t ctrl, strlist_t names) { int rc = 0; strlist_t sl; @@ -545,7 +547,7 @@ locate_one (strlist_t names) for (sl = names; sl; sl = sl->next) { - rc = get_pubkey_byname (&ctx, NULL, sl->d, &keyblock, NULL, 1, 0); + rc = get_pubkey_byname (ctrl, &ctx, NULL, sl->d, &keyblock, NULL, 1, 0); if (rc) { if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY) diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h index 9f05c1880..cbf3c04a8 100644 --- a/g10/keyserver-internal.h +++ b/g10/keyserver-internal.h @@ -33,20 +33,23 @@ struct keyserver_spec *parse_keyserver_uri(const char *string, const char *configname, unsigned int configlineno); struct keyserver_spec *parse_preferred_keyserver(PKT_signature *sig); -int keyserver_export(strlist_t users); -int keyserver_import(strlist_t users); -int keyserver_import_fprint(const byte *fprint,size_t fprint_len, - struct keyserver_spec *keyserver); -int keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver); -int keyserver_refresh(strlist_t users); -int keyserver_search(strlist_t tokens); -int keyserver_fetch(strlist_t urilist); -int keyserver_import_cert(const char *name, - unsigned char **fpr,size_t *fpr_len); -int keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len); -int keyserver_import_name(const char *name,unsigned char **fpr,size_t *fpr_len, - struct keyserver_spec *keyserver); -int keyserver_import_ldap(const char *name, - unsigned char **fpr,size_t *fpr_len); +int keyserver_export (ctrl_t ctrl, strlist_t users); +int keyserver_import (ctrl_t ctrl, strlist_t users); +int keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len, + struct keyserver_spec *keyserver); +int keyserver_import_keyid (ctrl_t ctrl, u32 *keyid, + struct keyserver_spec *keyserver); +int keyserver_refresh (ctrl_t ctrl, strlist_t users); +int keyserver_search (ctrl_t ctrl, strlist_t tokens); +int keyserver_fetch (ctrl_t ctrl, strlist_t urilist); +int keyserver_import_cert (ctrl_t ctrl, const char *name, + unsigned char **fpr,size_t *fpr_len); +int keyserver_import_pka (ctrl_t ctrl, + const char *name,unsigned char **fpr,size_t *fpr_len); +int keyserver_import_name (ctrl_t ctrl, + const char *name,unsigned char **fpr,size_t *fpr_len, + struct keyserver_spec *keyserver); +int keyserver_import_ldap (ctrl_t ctrl, const char *name, + unsigned char **fpr,size_t *fpr_len); #endif /* !_KEYSERVER_INTERNAL_H_ */ diff --git a/g10/keyserver.c b/g10/keyserver.c index 39c3d69d9..730c52fb9 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -89,10 +89,10 @@ static struct parse_options keyserver_opts[]= {NULL,0,NULL,NULL} }; -static int keyserver_work(enum ks_action action,strlist_t list, - KEYDB_SEARCH_DESC *desc,int count, - unsigned char **fpr,size_t *fpr_len, - struct keyserver_spec *keyserver); +static int keyserver_work (ctrl_t ctrl, enum ks_action action,strlist_t list, + KEYDB_SEARCH_DESC *desc,int count, + unsigned char **fpr,size_t *fpr_len, + struct keyserver_spec *keyserver); /* Reasonable guess */ #define DEFAULT_MAX_CERT_SIZE 16384 @@ -732,7 +732,8 @@ parse_keyrec(char *keystring) (cosmetics, really) and to better take advantage of the keyservers that can do multiple fetches in one go (LDAP). */ static int -show_prompt(KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search) +show_prompt (ctrl_t ctrl, + KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search) { char *answer; @@ -765,8 +766,8 @@ show_prompt(KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search) while((num=strsep(&split," ,"))!=NULL) if(atoi(num)>=1 && atoi(num)<=numdesc) - keyserver_work(KS_GET,NULL,&desc[atoi(num)-1],1, - NULL,NULL,opt.keyserver); + keyserver_work (ctrl, KS_GET,NULL,&desc[atoi(num)-1],1, + NULL,NULL,opt.keyserver); xfree(answer); return 1; @@ -779,7 +780,7 @@ show_prompt(KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search) small, it will grow safely. If negative it disables the "Key x-y of z" messages. searchstr should be UTF-8 (rather than native). */ static void -keyserver_search_prompt(IOBUF buffer,const char *searchstr) +keyserver_search_prompt (ctrl_t ctrl, IOBUF buffer,const char *searchstr) { int i=0,validcount=0,started=0,header=0,count=1; unsigned int maxlen,buflen,numlines=0; @@ -872,7 +873,7 @@ keyserver_search_prompt(IOBUF buffer,const char *searchstr) for(;;) { - if(show_prompt(desc,i,validcount?count:0,localstr)) + if (show_prompt (ctrl, desc, i, validcount?count:0, localstr)) break; validcount=0; } @@ -901,7 +902,7 @@ keyserver_search_prompt(IOBUF buffer,const char *searchstr) /* screen_lines - 1 for the prompt. */ if(numlines+keyrec->lines>opt.screen_lines-1) { - if(show_prompt(desc,i,validcount?count:0,localstr)) + if (show_prompt (ctrl, desc, i, validcount?count:0, localstr)) break; else numlines=0; @@ -977,9 +978,10 @@ direct_uri_map(const char *scheme,unsigned int is_direct) #define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\"" static int -keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, - int count,int *prog,unsigned char **fpr,size_t *fpr_len, - struct keyserver_spec *keyserver) +keyserver_spawn (ctrl_t ctrl, + enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, + int count,int *prog,unsigned char **fpr,size_t *fpr_len, + struct keyserver_spec *keyserver) { int ret=0,i,gotversion=0,outofband=0; strlist_t temp; @@ -1243,8 +1245,8 @@ keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, /* TODO: Remove Comment: lines from keys exported this way? */ - if(export_pubkeys_stream(buffer,temp,&block, - opt.keyserver_options.export_options)==-1) + if(export_pubkeys_stream (ctrl, buffer,temp,&block, + opt.keyserver_options.export_options)==-1) iobuf_close(buffer); else { @@ -1510,7 +1512,7 @@ keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, break; case KS_SEARCH: - keyserver_search_prompt(spawn->fromchild,searchstr); + keyserver_search_prompt (ctrl, spawn->fromchild,searchstr); break; default: @@ -1529,9 +1531,10 @@ keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, } static int -keyserver_work(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, - int count,unsigned char **fpr,size_t *fpr_len, - struct keyserver_spec *keyserver) +keyserver_work (ctrl_t ctrl, + enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, + int count,unsigned char **fpr,size_t *fpr_len, + struct keyserver_spec *keyserver) { int rc=0,ret=0; @@ -1549,7 +1552,8 @@ keyserver_work(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, #else /* Spawn a handler */ - rc=keyserver_spawn(action,list,desc,count,&ret,fpr,fpr_len,keyserver); + rc = keyserver_spawn (ctrl, action, list, desc, count, + &ret, fpr, fpr_len, keyserver); if(ret) { switch(ret) @@ -1599,7 +1603,7 @@ keyserver_work(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, } int -keyserver_export(strlist_t users) +keyserver_export (ctrl_t ctrl, strlist_t users) { gpg_error_t err; strlist_t sl=NULL; @@ -1624,7 +1628,7 @@ keyserver_export(strlist_t users) if(sl) { - rc=keyserver_work(KS_SEND,sl,NULL,0,NULL,NULL,opt.keyserver); + rc = keyserver_work (ctrl, KS_SEND,sl,NULL,0,NULL,NULL,opt.keyserver); free_strlist(sl); } @@ -1632,7 +1636,7 @@ keyserver_export(strlist_t users) } int -keyserver_import(strlist_t users) +keyserver_import (ctrl_t ctrl, strlist_t users) { gpg_error_t err; KEYDB_SEARCH_DESC *desc; @@ -1663,7 +1667,8 @@ keyserver_import(strlist_t users) } if(count>0) - rc=keyserver_work(KS_GET,NULL,desc,count,NULL,NULL,opt.keyserver); + rc=keyserver_work (ctrl, KS_GET, NULL, desc, count, + NULL, NULL, opt.keyserver); xfree(desc); @@ -1671,8 +1676,8 @@ keyserver_import(strlist_t users) } int -keyserver_import_fprint(const byte *fprint,size_t fprint_len, - struct keyserver_spec *keyserver) +keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len, + struct keyserver_spec *keyserver) { KEYDB_SEARCH_DESC desc; @@ -1689,11 +1694,12 @@ keyserver_import_fprint(const byte *fprint,size_t fprint_len, /* TODO: Warn here if the fingerprint we got doesn't match the one we asked for? */ - return keyserver_work(KS_GET,NULL,&desc,1,NULL,NULL,keyserver); + return keyserver_work (ctrl, KS_GET, NULL, &desc, 1, NULL, NULL, keyserver); } int -keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver) +keyserver_import_keyid (ctrl_t ctrl, + u32 *keyid,struct keyserver_spec *keyserver) { KEYDB_SEARCH_DESC desc; @@ -1703,7 +1709,7 @@ keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver) desc.u.kid[0]=keyid[0]; desc.u.kid[1]=keyid[1]; - return keyserver_work(KS_GET,NULL,&desc,1,NULL,NULL,keyserver); + return keyserver_work (ctrl, KS_GET,NULL,&desc,1,NULL,NULL,keyserver); } /* code mostly stolen from do_export_stream */ @@ -1865,7 +1871,7 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3) usernames to refresh only part of the keyring. */ int -keyserver_refresh(strlist_t users) +keyserver_refresh (ctrl_t ctrl, strlist_t users) { int rc,count,numdesc,fakev3=0; KEYDB_SEARCH_DESC *desc; @@ -1908,7 +1914,8 @@ keyserver_refresh(strlist_t users) Note that a preferred keyserver without a scheme:// will be interpreted as hkp:// */ - rc=keyserver_work(KS_GET,NULL,&desc[i],1,NULL,NULL,keyserver); + rc = keyserver_work (ctrl, KS_GET, NULL, &desc[i], 1, + NULL, NULL, keyserver); if(rc) log_info(_("WARNING: unable to refresh key %s" " via %s: %s\n"),keystr_from_desc(&desc[i]), @@ -1938,7 +1945,8 @@ keyserver_refresh(strlist_t users) count,opt.keyserver->uri); } - rc=keyserver_work(KS_GET,NULL,desc,numdesc,NULL,NULL,opt.keyserver); + rc=keyserver_work (ctrl, KS_GET, NULL, desc, numdesc, + NULL, NULL, opt.keyserver); } xfree(desc); @@ -1954,16 +1962,16 @@ keyserver_refresh(strlist_t users) } int -keyserver_search(strlist_t tokens) +keyserver_search (ctrl_t ctrl, strlist_t tokens) { - if(tokens) - return keyserver_work(KS_SEARCH,tokens,NULL,0,NULL,NULL,opt.keyserver); - else - return 0; + if (tokens) + return keyserver_work (ctrl, KS_SEARCH, tokens, NULL, 0, + NULL, NULL, opt.keyserver); + return 0; } int -keyserver_fetch(strlist_t urilist) +keyserver_fetch (ctrl_t ctrl, strlist_t urilist) { KEYDB_SEARCH_DESC desc; strlist_t sl; @@ -1988,7 +1996,7 @@ keyserver_fetch(strlist_t urilist) { int rc; - rc=keyserver_work(KS_GET,NULL,&desc,1,NULL,NULL,spec); + rc = keyserver_work (ctrl, KS_GET, NULL, &desc, 1, NULL, NULL, spec); if(rc) log_info (_("WARNING: unable to fetch URI %s: %s\n"), sl->d,g10_errstr(rc)); @@ -2011,7 +2019,8 @@ keyserver_fetch(strlist_t urilist) /* Import key in a CERT or pointed to by a CERT */ int -keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len) +keyserver_import_cert (ctrl_t ctrl, + const char *name,unsigned char **fpr,size_t *fpr_len) { char *domain,*look,*url; IOBUF key; @@ -2058,7 +2067,7 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len) spec=parse_keyserver_uri(url,1,NULL,0); if(spec) { - rc=keyserver_import_fprint(*fpr,*fpr_len,spec); + rc = keyserver_import_fprint (ctrl, *fpr,*fpr_len,spec); free_keyserver_spec(spec); } } @@ -2067,7 +2076,7 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len) /* If only a fingerprint is provided, try and fetch it from our --keyserver */ - rc=keyserver_import_fprint(*fpr,*fpr_len,opt.keyserver); + rc = keyserver_import_fprint (ctrl, *fpr,*fpr_len,opt.keyserver); } else log_info(_("no keyserver known (use option --keyserver)\n")); @@ -2087,7 +2096,8 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len) /* Import key pointed to by a PKA record. Return the requested fingerprint in fpr. */ int -keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len) +keyserver_import_pka (ctrl_t ctrl, + const char *name,unsigned char **fpr,size_t *fpr_len) { char *uri; int rc = G10ERR_NO_PUBKEY; @@ -2103,7 +2113,7 @@ keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len) spec = parse_keyserver_uri (uri, 1, NULL, 0); if (spec) { - rc = keyserver_import_fprint (*fpr, 20, spec); + rc = keyserver_import_fprint (ctrl, *fpr, 20, spec); free_keyserver_spec (spec); } xfree (uri); @@ -2120,15 +2130,17 @@ keyserver_import_pka(const char *name,unsigned char **fpr,size_t *fpr_len) /* Import all keys that match name */ int -keyserver_import_name(const char *name,unsigned char **fpr,size_t *fpr_len, - struct keyserver_spec *keyserver) +keyserver_import_name (ctrl_t ctrl, const char *name, + unsigned char **fpr, size_t *fpr_len, + struct keyserver_spec *keyserver) { strlist_t list=NULL; int rc; append_to_strlist(&list,name); - rc=keyserver_work(KS_GETNAME,list,NULL,0,fpr,fpr_len,keyserver); + rc = keyserver_work (ctrl, KS_GETNAME, list, NULL, + 0, fpr, fpr_len, keyserver); free_strlist(list); @@ -2137,7 +2149,8 @@ keyserver_import_name(const char *name,unsigned char **fpr,size_t *fpr_len, /* Import a key by name using LDAP */ int -keyserver_import_ldap(const char *name,unsigned char **fpr,size_t *fpr_len) +keyserver_import_ldap (ctrl_t ctrl, + const char *name,unsigned char **fpr,size_t *fpr_len) { char *domain; struct keyserver_spec *keyserver; @@ -2200,7 +2213,8 @@ keyserver_import_ldap(const char *name,unsigned char **fpr,size_t *fpr_len) append_to_strlist(&list,name); - rc=keyserver_work(KS_GETNAME,list,NULL,0,fpr,fpr_len,keyserver); + rc = keyserver_work (ctrl, KS_GETNAME, list, NULL, + 0, fpr, fpr_len, keyserver); free_strlist(list); diff --git a/g10/main.h b/g10/main.h index ba8afbafa..3804effd3 100644 --- a/g10/main.h +++ b/g10/main.h @@ -192,10 +192,11 @@ void display_online_help( const char *keyword ); int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek); int encrypt_symmetric (const char *filename ); int encrypt_store (const char *filename ); -int encrypt_crypt (int filefd, const char *filename, +int encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, strlist_t remusr, int use_symkey, pk_list_t provided_keys, int outputfd); -void encrypt_crypt_files (int nfiles, char **files, strlist_t remusr); +void encrypt_crypt_files (ctrl_t ctrl, + int nfiles, char **files, strlist_t remusr); int encrypt_filter (void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len); @@ -203,7 +204,7 @@ int encrypt_filter (void *opaque, int control, /*-- sign.c --*/ int complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md, const char *cache_nonce); -int sign_file( strlist_t filenames, int detached, strlist_t locusr, +int sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, int do_encrypt, strlist_t remusr, const char *outfile ); int clearsign_file( const char *fname, strlist_t locusr, const char *outfile ); int sign_symencrypt_file (const char *fname, strlist_t locusr); @@ -221,7 +222,7 @@ int check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk, int delete_keys( strlist_t names, int secret, int allow_both ); /*-- keyedit.c --*/ -void keyedit_menu( const char *username, strlist_t locusr, +void keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, strlist_t commands, int quiet, int seckey_check ); void keyedit_passwd (const char *username); void show_basic_key_info (KBNODE keyblock); @@ -280,11 +281,11 @@ int collapse_uids( KBNODE *keyblock ); /*-- export.c --*/ int parse_export_options(char *str,unsigned int *options,int noisy); -int export_pubkeys( strlist_t users, unsigned int options ); -int export_pubkeys_stream( iobuf_t out, strlist_t users, - KBNODE *keyblock_out, unsigned int options ); -int export_seckeys( strlist_t users ); -int export_secsubkeys( strlist_t users ); +int export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options ); +int export_pubkeys_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, + kbnode_t *keyblock_out, unsigned int options ); +int export_seckeys (ctrl_t ctrl, strlist_t users); +int export_secsubkeys (ctrl_t ctrl, strlist_t users); /* dearmor.c --*/ int dearmor_file( const char *fname ); @@ -300,8 +301,8 @@ struct revocation_reason_info * void release_revocation_reason_info( struct revocation_reason_info *reason ); /*-- keylist.c --*/ -void public_key_list( strlist_t list, int locate_mode ); -void secret_key_list( strlist_t list ); +void public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode ); +void secret_key_list (ctrl_t ctrl, strlist_t list ); void print_subpackets_colon(PKT_signature *sig); void reorder_keyblock (KBNODE keyblock); void list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque ); @@ -318,14 +319,14 @@ void print_card_key_info (estream_t fp, KBNODE keyblock); /*-- verify.c --*/ void print_file_status( int status, const char *name, int what ); -int verify_signatures( int nfiles, char **files ); -int verify_files( int nfiles, char **files ); +int verify_signatures (ctrl_t ctrl, int nfiles, char **files ); +int verify_files (ctrl_t ctrl, int nfiles, char **files ); int gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, estream_t out_fp); /*-- decrypt.c --*/ -int decrypt_message( const char *filename ); -gpg_error_t decrypt_message_fd (int input_fd, int output_fd); -void decrypt_messages(int nfiles, char *files[]); +int decrypt_message (ctrl_t ctrl, const char *filename ); +gpg_error_t decrypt_message_fd (ctrl_t ctrl, int input_fd, int output_fd); +void decrypt_messages (ctrl_t ctrl, int nfiles, char *files[]); /*-- plaintext.c --*/ int hash_datafiles( gcry_md_hd_t md, gcry_md_hd_t md2, @@ -346,7 +347,7 @@ int gpg_server (ctrl_t); /*-- card-util.c --*/ void change_pin (int no, int allow_admin); void card_status (estream_t fp, char *serialno, size_t serialnobuflen); -void card_edit (strlist_t commands); +void card_edit (ctrl_t ctrl, strlist_t commands); int card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock); int card_store_subkey (KBNODE node, int use); #endif diff --git a/g10/mainproc.c b/g10/mainproc.c index 02ffae92e..c2c7aba01 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -26,10 +26,10 @@ #include <time.h> #include "gpg.h" +#include "util.h" #include "packet.h" #include "iobuf.h" #include "options.h" -#include "util.h" #include "cipher.h" #include "keydb.h" #include "filter.h" @@ -56,6 +56,7 @@ struct kidlist_item { typedef struct mainproc_context *CTX; struct mainproc_context { + ctrl_t ctrl; struct mainproc_context *anchor; /* May be useful in the future. */ PKT_public_key *last_pubkey; PKT_user_id *last_user_id; @@ -563,8 +564,8 @@ proc_encrypted( CTX c, PACKET *pkt ) } else if( !c->dek ) result = G10ERR_NO_SECKEY; - if( !result ) - result = decrypt_data( c, pkt->pkt.encrypted, c->dek ); + if (!result) + result = decrypt_data (c->ctrl, c, pkt->pkt.encrypted, c->dek ); if( result == -1 ) ; @@ -757,18 +758,19 @@ proc_compressed_cb( IOBUF a, void *info ) { if ( ((CTX)info)->signed_data.used && ((CTX)info)->signed_data.data_fd != -1) - return proc_signature_packets_by_fd (info, a, + return proc_signature_packets_by_fd (((CTX)info)->ctrl, info, a, ((CTX)info)->signed_data.data_fd); else - return proc_signature_packets (info, a, + return proc_signature_packets (((CTX)info)->ctrl, info, a, ((CTX)info)->signed_data.data_names, ((CTX)info)->sigfilename ); } static int -proc_encrypt_cb( IOBUF a, void *info ) +proc_encrypt_cb (IOBUF a, void *info ) { - return proc_encryption_packets( info, a ); + CTX c = info; + return proc_encryption_packets (c->ctrl, info, a ); } static void @@ -781,11 +783,11 @@ proc_compressed( CTX c, PACKET *pkt ) if( !zd->algorithm ) rc=G10ERR_COMPR_ALGO; else if( c->sigs_only ) - rc = handle_compressed( c, zd, proc_compressed_cb, c ); + rc = handle_compressed (c->ctrl, c, zd, proc_compressed_cb, c ); else if( c->encrypt_only ) - rc = handle_compressed( c, zd, proc_encrypt_cb, c ); + rc = handle_compressed (c->ctrl, c, zd, proc_encrypt_cb, c ); else - rc = handle_compressed( c, zd, NULL, NULL ); + rc = handle_compressed (c->ctrl, c, zd, NULL, NULL ); if( rc ) log_error("uncompressing failed: %s\n", g10_errstr(rc)); free_packet(pkt); @@ -1174,11 +1176,12 @@ list_node( CTX c, KBNODE node ) int -proc_packets( void *anchor, IOBUF a ) +proc_packets (ctrl_t ctrl, void *anchor, IOBUF a ) { int rc; CTX c = xmalloc_clear( sizeof *c ); + c->ctrl = ctrl; c->anchor = anchor; rc = do_proc_packets( c, a ); xfree( c ); @@ -1188,12 +1191,13 @@ proc_packets( void *anchor, IOBUF a ) int -proc_signature_packets( void *anchor, IOBUF a, +proc_signature_packets (ctrl_t ctrl, void *anchor, IOBUF a, strlist_t signedfiles, const char *sigfilename ) { CTX c = xmalloc_clear( sizeof *c ); int rc; + c->ctrl = ctrl; c->anchor = anchor; c->sigs_only = 1; @@ -1228,7 +1232,8 @@ proc_signature_packets( void *anchor, IOBUF a, int -proc_signature_packets_by_fd (void *anchor, IOBUF a, int signed_data_fd ) +proc_signature_packets_by_fd (ctrl_t ctrl, + void *anchor, IOBUF a, int signed_data_fd ) { int rc; CTX c; @@ -1237,6 +1242,7 @@ proc_signature_packets_by_fd (void *anchor, IOBUF a, int signed_data_fd ) if (!c) return gpg_error_from_syserror (); + c->ctrl = ctrl; c->anchor = anchor; c->sigs_only = 1; @@ -1269,11 +1275,12 @@ proc_signature_packets_by_fd (void *anchor, IOBUF a, int signed_data_fd ) int -proc_encryption_packets( void *anchor, IOBUF a ) +proc_encryption_packets (ctrl_t ctrl, void *anchor, IOBUF a ) { CTX c = xmalloc_clear( sizeof *c ); int rc; + c->ctrl = ctrl; c->anchor = anchor; c->encrypt_only = 1; rc = do_proc_packets( c, a ); @@ -1652,7 +1659,7 @@ check_sig_and_print( CTX c, KBNODE node ) int res; glo_ctrl.in_auto_key_retrieve++; - res=keyserver_import_keyid(sig->keyid,spec); + res = keyserver_import_keyid (c->ctrl, sig->keyid,spec); glo_ctrl.in_auto_key_retrieve--; if(!res) rc=do_check_sig(c, node, NULL, &is_expkey, &is_revkey ); @@ -1684,7 +1691,7 @@ check_sig_and_print( CTX c, KBNODE node ) if (spec) { glo_ctrl.in_auto_key_retrieve++; - res = keyserver_import_keyid (sig->keyid, spec); + res = keyserver_import_keyid (c->ctrl, sig->keyid, spec); glo_ctrl.in_auto_key_retrieve--; free_keyserver_spec (spec); if (!res) @@ -1702,7 +1709,7 @@ check_sig_and_print( CTX c, KBNODE node ) int res; glo_ctrl.in_auto_key_retrieve++; - res=keyserver_import_keyid ( sig->keyid, opt.keyserver ); + res=keyserver_import_keyid (c->ctrl, sig->keyid, opt.keyserver ); glo_ctrl.in_auto_key_retrieve--; if(!res) rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey ); diff --git a/g10/options.h b/g10/options.h index cee248f25..968393257 100644 --- a/g10/options.h +++ b/g10/options.h @@ -124,8 +124,6 @@ struct int s2k_cipher_algo; unsigned char s2k_count; /* This is the encoded form, not the raw count */ - int simple_sk_checksum; /* create the deprecated rfc2440 secret key - protection */ int not_dash_escaped; int escape_from; int lock_once; diff --git a/g10/packet.h b/g10/packet.h index 02674a039..643cc5beb 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -370,11 +370,12 @@ struct notation /*-- mainproc.c --*/ void reset_literals_seen(void); -int proc_packets( void *ctx, iobuf_t a ); -int proc_signature_packets( void *ctx, iobuf_t a, +int proc_packets (ctrl_t ctrl, void *ctx, iobuf_t a ); +int proc_signature_packets (ctrl_t ctrl, void *ctx, iobuf_t a, strlist_t signedfiles, const char *sigfile ); -int proc_signature_packets_by_fd ( void *anchor, IOBUF a, int signed_data_fd ); -int proc_encryption_packets( void *ctx, iobuf_t a ); +int proc_signature_packets_by_fd (ctrl_t ctrl, + void *anchor, IOBUF a, int signed_data_fd ); +int proc_encryption_packets (ctrl_t ctrl, void *ctx, iobuf_t a); int list_packets( iobuf_t a ); /*-- parse-packet.c --*/ @@ -475,11 +476,11 @@ gpg_error_t get_session_key (PKT_pubkey_enc *k, DEK *dek); gpg_error_t get_override_session_key (DEK *dek, const char *string); /*-- compress.c --*/ -int handle_compressed( void *ctx, PKT_compressed *cd, +int handle_compressed (ctrl_t ctrl, void *ctx, PKT_compressed *cd, int (*callback)(iobuf_t, void *), void *passthru ); /*-- encr-data.c --*/ -int decrypt_data( void *ctx, PKT_encrypted *ed, DEK *dek ); +int decrypt_data (ctrl_t ctrl, void *ctx, PKT_encrypted *ed, DEK *dek ); /*-- plaintext.c --*/ int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, diff --git a/g10/parse-packet.c b/g10/parse-packet.c index c83524016..89d6f5958 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -25,9 +25,9 @@ #include <assert.h> #include "gpg.h" +#include "util.h" #include "packet.h" #include "iobuf.h" -#include "util.h" #include "cipher.h" #include "filter.h" #include "photoid.h" diff --git a/g10/photoid.c b/g10/photoid.c index 3be42d2fc..2d56d80b6 100644 --- a/g10/photoid.c +++ b/g10/photoid.c @@ -29,11 +29,11 @@ #endif #include "gpg.h" +#include "util.h" #include "packet.h" #include "status.h" #include "exec.h" #include "keydb.h" -#include "util.h" #include "i18n.h" #include "iobuf.h" #include "options.h" diff --git a/g10/pkclist.c b/g10/pkclist.c index cffabd0b4..f76c18648 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -778,7 +778,7 @@ expand_group(strlist_t input) of the key. USE the requested usage and a set MARK_HIDDEN will mark the key in the updated list as a hidden recipient. */ gpg_error_t -find_and_check_key (const char *name, unsigned int use, +find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use, int mark_hidden, pk_list_t *pk_list_addr) { int rc; @@ -793,7 +793,7 @@ find_and_check_key (const char *name, unsigned int use, return gpg_error_from_syserror (); pk->req_usage = use; - rc = get_pubkey_byname (NULL, pk, name, NULL, NULL, 0, 0); + rc = get_pubkey_byname (ctrl, NULL, pk, name, NULL, NULL, 0, 0); if (rc) { /* Key not found or other error. */ @@ -883,7 +883,8 @@ find_and_check_key (const char *name, unsigned int use, not changed. */ int -build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) +build_pk_list (ctrl_t ctrl, + strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) { PK_LIST pk_list = NULL; PKT_public_key *pk=NULL; @@ -929,7 +930,8 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) /* We explicitly allow encrypt-to to an disabled key; thus we pass 1for the second last argument and 1 as the last argument to disable AKL. */ - if ( (rc = get_pubkey_byname (NULL, pk, rov->d, NULL, NULL, 1, 1)) ) + if ( (rc = get_pubkey_byname (ctrl, + NULL, pk, rov->d, NULL, NULL, 1, 1)) ) { free_public_key ( pk ); pk = NULL; log_error (_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) ); @@ -1066,7 +1068,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) free_public_key (pk); pk = xmalloc_clear( sizeof *pk ); pk->req_usage = use; - rc = get_pubkey_byname (NULL, pk, answer, NULL, NULL, 0, 0 ); + rc = get_pubkey_byname (ctrl, NULL, pk, answer, NULL, NULL, 0, 0 ); if (rc) tty_printf(_("No such user ID.\n")); else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo, use)) ) @@ -1140,7 +1142,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) /* The default recipient is allowed to be disabled; thus pass 1 as second last argument. We also don't want an AKL. */ - rc = get_pubkey_byname (NULL, pk, def_rec, NULL, NULL, 1, 1); + rc = get_pubkey_byname (ctrl, NULL, pk, def_rec, NULL, NULL, 1, 1); if (rc) log_error(_("unknown default recipient \"%s\"\n"), def_rec ); else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use)) ) @@ -1178,7 +1180,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use ) if ( (remusr->flags & 1) ) continue; /* encrypt-to keys are already handled. */ - rc = find_and_check_key (remusr->d, use, !!(remusr->flags&2), + rc = find_and_check_key (ctrl, remusr->d, use, !!(remusr->flags&2), &pk_list); if (rc) goto fail; diff --git a/g10/server.c b/g10/server.c index f67a34677..1c534f1e5 100644 --- a/g10/server.c +++ b/g10/server.c @@ -231,7 +231,7 @@ cmd_recipient (assuan_context_t ctx, char *line) remusr = rcpts; */ - err = find_and_check_key (line, PUBKEY_USAGE_ENC, hidden, + err = find_and_check_key (ctrl, line, PUBKEY_USAGE_ENC, hidden, &ctrl->server_local->recplist); if (err) @@ -324,7 +324,7 @@ cmd_encrypt (assuan_context_t ctx, char *line) /* fixme: err = ctrl->audit? 0 : start_audit_session (ctrl);*/ - err = encrypt_crypt (inp_fd, NULL, NULL, 0, + err = encrypt_crypt (ctrl, inp_fd, NULL, NULL, 0, ctrl->server_local->recplist, out_fd); @@ -368,7 +368,7 @@ cmd_decrypt (assuan_context_t ctx, char *line) return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); glo_ctrl.lasterr = 0; - err = decrypt_message_fd (inp_fd, out_fd); + err = decrypt_message_fd (ctrl, inp_fd, out_fd); if (!err) err = glo_ctrl.lasterr; diff --git a/g10/sign.c b/g10/sign.c index eeb4549ca..cf7efe5dc 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -762,7 +762,7 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash, * uncompressed, non-armored and in binary mode. */ int -sign_file( strlist_t filenames, int detached, strlist_t locusr, +sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, int encryptflag, strlist_t remusr, const char *outfile ) { const char *fname; @@ -822,7 +822,8 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr, compliance_failure(); } - if(encryptflag && (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC ))) + if (encryptflag + && (rc=build_pk_list (ctrl, remusr, &pk_list, PUBKEY_USAGE_ENC))) goto leave; /* prepare iobufs */ diff --git a/g10/verify.c b/g10/verify.c index 4dab20717..0810223d0 100644 --- a/g10/verify.c +++ b/g10/verify.c @@ -50,7 +50,7 @@ */ int -verify_signatures( int nfiles, char **files ) +verify_signatures (ctrl_t ctrl, int nfiles, char **files ) { IOBUF fp; armor_filter_context_t *afx = NULL; @@ -110,7 +110,7 @@ verify_signatures( int nfiles, char **files ) sl = NULL; for(i=nfiles-1 ; i > 0 ; i-- ) add_to_strlist( &sl, files[i] ); - rc = proc_signature_packets( NULL, fp, sl, sigfile ); + rc = proc_signature_packets (ctrl, NULL, fp, sl, sigfile ); free_strlist(sl); iobuf_close(fp); if( (afx && afx->no_openpgp_data && rc == -1) || rc == G10ERR_NO_DATA ) { @@ -139,7 +139,7 @@ print_file_status( int status, const char *name, int what ) static int -verify_one_file( const char *name ) +verify_one_file (ctrl_t ctrl, const char *name ) { IOBUF fp; armor_filter_context_t *afx = NULL; @@ -172,7 +172,7 @@ verify_one_file( const char *name ) } } - rc = proc_signature_packets( NULL, fp, NULL, name ); + rc = proc_signature_packets (ctrl, NULL, fp, NULL, name ); iobuf_close(fp); write_status( STATUS_FILE_DONE ); @@ -190,7 +190,7 @@ verify_one_file( const char *name ) * Note: This function can not handle detached signatures. */ int -verify_files( int nfiles, char **files ) +verify_files (ctrl_t ctrl, int nfiles, char **files ) { int i; @@ -208,13 +208,13 @@ verify_files( int nfiles, char **files ) * also no script languages available. We don't strip any * spaces, so that we can process nearly all filenames */ line[strlen(line)-1] = 0; - verify_one_file( line ); + verify_one_file (ctrl, line ); } } else { /* take filenames from the array */ for(i=0; i < nfiles; i++ ) - verify_one_file( files[i] ); + verify_one_file (ctrl, files[i] ); } return 0; } @@ -262,7 +262,7 @@ gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, estream_t out_fp) push_armor_filter (afx, fp); } - rc = proc_signature_packets_by_fd (NULL, fp, data_fd); + rc = proc_signature_packets_by_fd (ctrl, NULL, fp, data_fd); if ( afx && afx->no_openpgp_data && (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) ) |