From 80b9a9c6e52819cebfbfa9ad44e1d3b0660250b3 Mon Sep 17 00:00:00 2001 From: wk Date: Mon, 28 Sep 2009 14:37:48 +0000 Subject: [PATCH] Rename encode.c to encrypt.c. Rename function in a simlar way. Re-indent encrypt.c git-svn-id: svn://cvs.gnupg.org/gnupg/trunk@5164 8a63c251-dffc-0310-8ec6-d64dca2275b1 --- g10/ChangeLog | 353 +++++++++++---------- g10/Makefile.am | 2 +- g10/encode.c | 912 ----------------------------------------------------- g10/encrypt.c | 957 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ g10/gpg.c | 12 +- g10/main.h | 12 +- g10/pkglue.c | 19 +- g10/server.c | 20 +- g10/trustdb.c | 18 +- 9 files changed, 1187 insertions(+), 1118 deletions(-) delete mode 100644 g10/encode.c create mode 100644 g10/encrypt.c diff --git a/g10/ChangeLog b/g10/ChangeLog index ea45a315..a44dac6b 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,20 @@ +2009-09-28 Werner Koch + + * encode.c: Rename to encrypt.c. Re-indent all. + * encrypt.c (encode_symmetric, encode_store, encode_seskey) + (encode_simple, encode_crypt, encode_filter) + (encode_crypt_files): Rename all to encrypt_*. Change all callers. + + * trustdb.c (get_validity_info): Take care of a NULL PK. Fixes + bug#1138. + (get_validity_string): Ditto. + +2009-09-25 Werner Koch + + * pkglue.c (pk_sign, pk_verify, pk_encrypt, pk_decrypt) + (pk_check_secret_key): Allow deprecated RSA identifiers 2 and 3. + Fixes bug#1139. + 2009-09-23 Marcus Brinkmann * call-agent.c: Include "scdaemon.h" before because of @@ -153,7 +170,7 @@ * options.h: Include session_env.h. (opt): Add field SESSION_ENV, remove obsolete fields. - + * call-agent.c (start_agent): Adjust start_new_gpg_agent for changed args. @@ -174,7 +191,7 @@ * parse-packet.c (parse): Use a casted -1 instead of a 32 bit constant to check for a garbled package. Fixes bug#1040. - * card-util.c (put_data_to_file, read_cert): New. + * card-util.c (put_data_to_file, read_cert): New. (card_edit): Add command "readcert". (fetch_url): Allow code also for this gnupg major version 2. * call-agent.c (agent_scd_readcert): New. @@ -316,12 +333,12 @@ * keydb.c (keydb_add_resource): Add readonly flag bit. (keydb_rebuild_caches): Don't act on readonly resources. - * keyring.c (keyring_register_filename): Add arg READONLY. + * keyring.c (keyring_register_filename): Add arg READONLY. (struct keyring_name): Add field READONLY. (keyring_is_writable): Implement readonly feature. (keyring_update_keyblock): Return GPG_ERR_EACCES for readonly keyrings. - (keyring_insert_keyblock, keyring_delete_keyblock): + (keyring_insert_keyblock, keyring_delete_keyblock): Ditto. 2009-04-01 Werner Koch @@ -394,7 +411,7 @@ 2009-01-26 Werner Koch - * card-util.c (card_status): Detect a Geldkarte. + * card-util.c (card_status): Detect a Geldkarte. 2009-01-13 Werner Koch @@ -467,7 +484,7 @@ * gpgv.c (main): Ditto. * keylist.c (set_attrib_fd): Do not close ATTRIB_FP if it is the - log stream. + log stream. (set_attrib_fd) [W32]: Set to binary mode. (dump_attribs): Flush the stream after writing. @@ -503,7 +520,7 @@ * card-util.c (generate_card_keys): Remove unused arg SERIALNO and adjust caller. - + * build-packet.c (write_sign_packet_header): Mark unused arg. * gpg.c (gpg_init_default_ctrl, gpg_deinit_default_ctrl): Ditto. * getkey.c (skip_unusable): Ditto. @@ -536,8 +553,8 @@ * server.c (option_handler): Mark non yet used arg. (input_notify, output_notify): Ditto. - (cmd_recipient, cmd_signer, cmd_encrypt, cmd_decrypt, cmd_verify) - (cmd_sign, cmd_import, cmd_export, cmd_delkeys, do_listkeys) + (cmd_recipient, cmd_signer, cmd_encrypt, cmd_decrypt, cmd_verify) + (cmd_sign, cmd_import, cmd_export, cmd_delkeys, do_listkeys) (cmd_genkey): Ditto. * verify.c (gpg_verify): Ditto. @@ -578,7 +595,7 @@ * parse-packet.c (parse): Remove special treatment for compressed new style packets. Fixes bug#931. - + * card-util.c (change_pin): Support setting of the reset code. 2008-09-24 Werner Koch @@ -650,8 +667,8 @@ * gpg.c: Make --fixed-list-mode a dummy. * options.h (struct): Removed FIXED_LIST_MODE. - * keyid.c (colon_strtime, colon_datestr_from_pk) - (colon_datestr_from_sk, colon_datestr_from_sig) + * keyid.c (colon_strtime, colon_datestr_from_pk) + (colon_datestr_from_sk, colon_datestr_from_sig) (colon_expirestr_from_sig): Remove fixed_list_mode case. * keylist.c (list_keyblock_colon): Ditto. Remove all now unsed code and reindent. @@ -680,7 +697,7 @@ 2008-04-18 Werner Koch - * misc.c (map_cipher_openpgp_to_gcry, map_cipher_gcry_to_openpgp) + * misc.c (map_cipher_openpgp_to_gcry, map_cipher_gcry_to_openpgp) (openpgp_cipher_test_algo): Add camellia-192. (openpgp_cipher_blocklen): New. * parse-packet.c (parse_key): Use new function here. @@ -757,16 +774,16 @@ 2008-02-14 Werner Koch * call-agent.c (default_inq_cb): New. - (agent_learn, agent_scd_getattr, agent_scd_pksign) - (agent_scd_pkdecrypt, agent_scd_change_pin, agent_scd_checkpin) + (agent_learn, agent_scd_getattr, agent_scd_pksign) + (agent_scd_pkdecrypt, agent_scd_change_pin, agent_scd_checkpin) (agent_get_passphrase, agent_clear_passphrase): Use new callback. (inq_writekey_parms): Fall back to the new callback for other - inquiries. + inquiries. (start_agent): Tell agent that we accept pinentry notifications. 2008-02-11 Werner Koch - * server.c (cmd_getinfo): New. + * server.c (cmd_getinfo): New. (register_commands): Register GETINFO. 2008-02-09 Marcus Brinkmann @@ -803,7 +820,7 @@ * misc.c (print_pubkey_algo_note): Print a warning if a type 20 key is used. - (openpgp_pk_test_algo, openpgp_pk_test_algo2) + (openpgp_pk_test_algo, openpgp_pk_test_algo2) (openpgp_pk_algo_usage): Allow type 20 keys only in rfc2440 mode. 2007-12-12 David Shaw (wk) @@ -825,7 +842,7 @@ (map_cipher_gcry_to_openpgp): New. (string_to_cipher_algo): Use it. * gpg.c (main): Print a warning if Camellia support is build in. - + * gpg.c (print_algo_names): New. From the 1.4 branch by David. (list_config): Use it here for the "ciphername" and "digestname" config items so we can get a script-parseable list of the names. @@ -1173,7 +1190,7 @@ 2007-03-05 Werner Koch Converted this file to UTF-8. - + Ported David and my multiple messages changes from 1.4.7. * options.h, gpg.c (main), mainproc.c (check_sig_and_print): Allow @@ -1184,7 +1201,7 @@ * status.c (get_status_string): Ditto. * mainproc.c (proc_plaintext): Emit it if multiple messages are detected. Error out if more than one plaintext packet is - encountered. + encountered. * mainproc.c (literals_seen): New. 2007-02-26 Werner Koch @@ -1227,12 +1244,12 @@ required. * gpg.c (main): Let --no-use-agent and --gpg-agent-info print a - warning. + warning. * misc.c (obsolete_option): New. 2007-01-29 Werner Koch - * pkclist.c (do_we_trust_pre): Issue a user-id-hint status code. + * pkclist.c (do_we_trust_pre): Issue a user-id-hint status code. 2007-01-15 Werner Koch @@ -1318,7 +1335,7 @@ * sign.c (sign_file, clearsign_file, sign_symencrypt_file): Ditto. * plaintext.c (ask_for_detached_datafile, hash_datafiles): Ditto. * encode.c (encode_simple, encode_crypt): Ditto. - * decrypt.c (decrypt_message, decrypt_messages): Ditto. + * decrypt.c (decrypt_message, decrypt_messages): Ditto. * keyedit.c (menu_clean): Made strings translatable. @@ -1339,7 +1356,7 @@ * encr-data.c: Allocate DFX context on the heap and not on the stack. Changes at several places. Fixes CVE-2006-6235. - + 2006-11-27 Werner Koch * openfile.c (ask_outfile_name): Fixed buffer overflow occurring @@ -1359,10 +1376,10 @@ (do_check): Made NDATA a size_t. (protect_secret_key): Made NARR a size_t. (protect_secret_key): Made NVYES a size_t. - * pubkey-enc.c (get_it): Made INDATALEN a size_t. + * pubkey-enc.c (get_it): Made INDATALEN a size_t. (get_it): Made NFRAME a size_t. * keyid.c (hash_public_key): Made NBITS an unsigned int. - * misc.c (checksum_mpi): Made NBYTES a size_t. + * misc.c (checksum_mpi): Made NBYTES a size_t. (openpgp_pk_test_algo2): Made USE_BUF a size_t. * seskey.c (encode_session_key): Made NFRAME a size_t. (do_encode_md): Ditto. @@ -1372,7 +1389,7 @@ 2006-11-10 Werner Koch * parse-packet.c (mpi_read): Changed NREAD to size_t to match the - gcry_mpi-scan prototype. + gcry_mpi-scan prototype. (mpi_read): Fixed double increment of bytes read to correctly detect overlong MPIs. @@ -1418,7 +1435,7 @@ * import.c (import_print_stats): Use log_printf. * build-packet.c (do_public_key): Care about mpi_write errors. - (do_secret_key, do_pubkey_enc, do_signature): Ditto. + (do_secret_key, do_pubkey_enc, do_signature): Ditto. (mpi_write): Print an extra warning on error. 2006-10-17 Werner Koch @@ -1459,12 +1476,12 @@ (set_status_fd): Register the progress cb. * seskey.c (encode_md_value): Check that the hash algo is valid - before getting the OID. + before getting the OID. 2006-10-04 Werner Koch * passphrase.c: Allow for a static passphrase in batch mode. - + * call-agent.c (agent_havekey): Removed. (percent_plus_escape): New. (agent_get_passphrase): New. @@ -1525,7 +1542,7 @@ 2006-09-13 Werner Koch - * gpg.c (main): Made --require-cross-certification the default. + * gpg.c (main): Made --require-cross-certification the default. 2006-09-06 Marcus Brinkmann @@ -1586,7 +1603,7 @@ (parse_gpg_control): Skip too large control packets. 2006-07-24 David Shaw (wk) - + * keydb.h, pkclist.c (select_algo_from_prefs, algo_available): Pass a union for preference hints rather than doing void * games. @@ -1609,7 +1626,7 @@ 2006-06-29 Werner Koch * parse-packet.c (parse_signature, parse_key): Need store the - length of opaque data as number of bits. + length of opaque data as number of bits. * card-util.c (card_store_subkey): Ditto. * mainproc.c (print_pkenc_list, check_sig_and_print): Replaced @@ -1668,7 +1685,7 @@ happened, and fail completely if we cannot reopen (should never happen). (main): Call it here. - + * parse-packet.c (dump_sig_subpkt, parse_signature): Fix meaning of key expiration and sig expiration subpackets - zero means "never expire" according to 2440, not "expire instantly". @@ -1734,10 +1751,10 @@ but kept option. 2006-04-28 David Shaw (wk) - + * keyserver.c (direct_uri_map): New. (keyserver_spawn): Used here to add "_uri" to certain gpgkeys_xxx - helpers when the meaning is different if a path is provided (i.e. + helpers when the meaning is different if a path is provided (i.e. ldap). (keyserver_import_cert): Show warning if there is a CERT fingerprint, but no --keyserver set. @@ -1767,7 +1784,7 @@ * sign.c (write_plaintext_packet): Factor common literal packet setup code from here, to... * encode.c (encode_simple): .. there. - + * main.h, plaintext.c (setup_plaintext_name): Here. New. Make sure the literal packet filename field is UTF-8 encoded. @@ -1799,7 +1816,7 @@ * status.c: Removed shared memory coprocess stuff Merged with current gpg 1.4.3 code. - + * keygen.c, keyid.c, misc.c, openfile.c, verify.c, trustdb.c * textfilter.c, tdbio.c, tdbdump.c, status.c, skclist.c, signal.c * sign.c, sig-check.c, seskey.c, seckey-cert.c, revoke.c @@ -1818,7 +1835,7 @@ * comment.c, pipemode.c: Removed. * card-util.c: Updated from gnupg-1.4.3. * compress-bz2.c: New. - + 2005-06-15 Werner Koch * g10.c (print_hashline, add_group): Fixes for signed/unsigned @@ -1953,7 +1970,7 @@ * keyedit.c (trustsig_prompt): Removed a "> 255" term; it is always false due to the data type. - + * passphrase.c (agent_get_passphrase): Use xasprintf and avoid non-literal format strings. @@ -2004,7 +2021,7 @@ 2003-10-01 Werner Koch - * card-util.c: Tweaked to use this source also under 1.3. + * card-util.c: Tweaked to use this source also under 1.3. 2003-09-30 Werner Koch @@ -2013,14 +2030,14 @@ * card-util.c (toggle_forcesig): New. (card_edit): New command "forcesig". - + * card-util.c (print_name, print_isoname): Use 0 and not LF fro the max_n arg of tty_print_utf8_string2. * call-agent.c (agent_scd_getattr): New. (learn_status_cb): Release values before assignment so that it can be used by getattr to update the structure. - + * card-util.c (change_pin): Simplified. We now have only a PIN and an Admin PIN. @@ -2032,7 +2049,7 @@ * card_status (card_status): Do not use fputs since the fp parameter can be NULL. This fixes a segv. - + 2003-09-24 Werner Koch * card-util.c (print_isoname,card_status): Handle opt.with_colons. @@ -2041,7 +2058,7 @@ 2003-09-23 Werner Koch Merged most of David Shaw's changes in 1.3 since 2003-06-03. - + * Makefile.am: Include W32LIBS where appropriate. * armor.c (parse_hash_header,armor_filter): Drop TIGER/192 support. @@ -2062,13 +2079,13 @@ * encode.c (use_mdc), g10.c (main): Use RFC1991 and RFC2440 directly to check for MDC usability. Do not set the force_mdc or disable_mdc flags since there is no point any longer. - + * g10.c (main): Use "keyserver-url" instead of "preferred-keyserver" for the sake of short and simple commands. (add_keyserver_url): Clarify a few strings. It's a "preferred keyserver URL". * keyedit.c (keyedit_menu): Ditto. - * sign.c (mk_notation_policy_etc): Ditto. + * sign.c (mk_notation_policy_etc): Ditto. * main.h, keygen.c (keygen_add_keyserver_url): Signature callback for adding a keyserver URL. @@ -2268,7 +2285,7 @@ (get_parameter_algo): Ditto. * keyedit.c (keyedit_menu): Ditto. * tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/. - * revoke.c (ask_revocation_reason): + * revoke.c (ask_revocation_reason): * keyserver.c (keyserver_spawn): Dito. * parse-packet.c (parse): Disallow old style partial length for @@ -2306,7 +2323,7 @@ * card-util.c (card_status): Free pk in case of an error and return if the card is no OpenPGP card. - + 2003-09-18 Werner Koch * g10.c: New command --card-edit. @@ -2314,8 +2331,8 @@ (print_sha1_fpr, print_isoname): Ditto. (get_one_name,change_name, change_url, change_login,change_lang) (change_sex): New; taken from keygen.c. - * keygen.c (smartcard_get_one_name, smartcard_change_name) - (smartcard_change_url, smartcard_change_login_data) + * keygen.c (smartcard_get_one_name, smartcard_change_name) + (smartcard_change_url, smartcard_change_login_data) (smartcard_change_lang, smartcard_change_sex): Removed. (check_smartcard): Removed most menu items. @@ -2328,9 +2345,9 @@ 2003-09-04 Werner Koch - * keygen.c (do_add_key_flags, parse_parameter_usage) + * keygen.c (do_add_key_flags, parse_parameter_usage) (do_generate_keypair): Add support the proposed AUTH key flag. - * getkey.c (fixup_uidnode, merge_selfsigs_main) + * getkey.c (fixup_uidnode, merge_selfsigs_main) (merge_selfsigs_subkey, premerge_public_with_secret): Ditto. * keylist.c (print_capabilities): Ditto. @@ -2338,7 +2355,7 @@ * pkglue.c (mpi_from_sexp): New. Used to factor out some common code. - + 2003-08-24 Werner Koch * keygen.c (do_generate_keypair): Print a reminder to use --gen-revoke. @@ -2350,7 +2367,7 @@ * mainproc.c (symkey_decrypt_sesskey): Better check for the algorithm and check the return values of some functions. * mdc.c (use_mdc): Simplified. - + 2003-08-07 Werner Koch * pkglue.c (pk_sign): Fix last change. @@ -2443,7 +2460,7 @@ 2003-07-03 Werner Koch - * options.h (DBG_CIPHER): Reintroduced it. + * options.h (DBG_CIPHER): Reintroduced it. * seskey.c (encode_session_key): Debug output of the session key. * pubkey-enc.c (get_it): Handle card case. @@ -2514,9 +2531,9 @@ Fixed all "==" comparisons against error code constants to use gpg_err_code(). - * import.c (import_secret_one): - (import_revoke_cert): - (chk_self_sigs): + * import.c (import_secret_one): + (import_revoke_cert): + (chk_self_sigs): * misc.c (openpgp_md_map_name): Check also for the Hx format. (openpgp_cipher_map_name): Check also for the Sx format. @@ -2535,7 +2552,7 @@ listed below becuause they are too similar and done at far too many places. As of today the code builds using the current libgcrypt from CVS but it is very unlikely that it actually works. - + * sig-check.c (cmp_help): Removed. Was never used. * pkglue.c: New. Most stuff taken from gnupg 1.1.2. @@ -2588,7 +2605,7 @@ s/g10_errstr/gpg_strerror/ s/MPI/gcry_mpi_t/ Adjusted all md_open calls to the libgcrypt API. - + * build-packet.c (do_comment): Return error code from iobuf write function. (do_user_id): Ditto. @@ -2698,7 +2715,7 @@ * seckey-cert.c (do_check): Issue the RSA_OR_IDEA status when the cipher algo is IDEA to make it easier to track down the problem. (From twoaday on stable branch) - + 2003-05-24 David Shaw * armor.c, g10.c, kbnode.c, misc.c, pkclist.c, sign.c, @@ -2717,10 +2734,10 @@ re-fetch a key when we already have that key handy. Cache the result of the check so we don't need to hit the trustdb more than once. - + * getkey.c (skip_disabled): New function to get a pk and call is_disabled on it. (key_byname): Use it here. - + * packet.h, getkey.c (skip_disabled), keylist.c (print_capabilities): New "pk_is_disabled" macro to retrieve the cached disabled value if available, and fill it in via @@ -2747,7 +2764,7 @@ * main.h, keylist.c (dump_attribs), mainproc.c (check_sig_and_print): Dump attribs if --attrib-fd is set when verifying signatures. - + * g10.c (main): New --gnupg option to disable the various --openpgp, --pgpX, etc. options. This is the same as --no-XXXX for those options. @@ -2825,7 +2842,7 @@ * g10.c (main): Use string_to_trust_value here for --force-ownertrust. - + * options.h, g10.c (main), trustdb.c (trust_model_string, init_trustdb, check_trustdb, update_trustdb, get_validity, validate_one_keyblock): An "OpenPGP" trust model is misleading @@ -2875,7 +2892,7 @@ * mainproc.c (check_sig_and_print): Show digest algorithm and sig class when verifying a sig with --verbose on, and add version, pk and hash algorithms and sig class to VALIDSIG. - + * parse-packet.c (enum_sig_subpkt): Make a warning message a --verbose warning message since we don't need to warn every time we see an unknown critical (we only need to invalidate the @@ -3355,14 +3372,14 @@ don't repeat some key information twice. 2002-12-22 Timo Schulz - + * import.c (print_import_check): New. (import_one): Use it here. Use merge_keys_and_selfsig in the interactive mode to avoid wrong key information. * status.h: Add new status code. * status.c: Ditto. - + 2002-12-13 David Shaw * pkclist.c (do_we_trust): Tweak language to refer to the "named @@ -3578,7 +3595,7 @@ list-key operations. This is required because getkey needs to know whether a a key is ultimately trusted. From Werner on stable branch. - + * exec.c [__CYGWIN32__]: Keep cygwin separate from Mingw32; we don't need it here as it behaves more like a Posix system. From Werner on stable branch. @@ -3591,7 +3608,7 @@ * g10.c, gpgv.c (main) [__CYGWIN32__]: Don't get the homedir from the registry. From Werner on stable branch. - + * keyedit.c (show_key_with_all_names_colon): Make --with-colons --edit display match the validity and trust of --with-colons --list-keys. @@ -3819,10 +3836,10 @@ * keylist.c: (print_pubkey_info): New. (print_seckey_info): New. - * main.h: Prototypes for the new functions. + * main.h: Prototypes for the new functions. * delkey.c (do_delete_key): Use it here. * revoke.c (gen_desig_revoke): Ditto. - + 2002-10-17 Werner Koch * pkclist.c (do_edit_ownertrust): Show all user IDs. This should @@ -4234,7 +4251,7 @@ * import.c (import_one): Ask the user if the key shall be imported when the interactive mode is used. Useful to extract selected keys from a file. - + 2002-08-16 Werner Koch * seckey-cert.c: Workaround to allow decryption of v3 keys created @@ -4303,7 +4320,7 @@ checked. The options file and any extension files are checked wherever they are, as well as their enclosing directories. This is Debian bug 147760. - + 2002-08-06 Stefan Bellon * g10.c (main): Use of EXTSEP_S in new gpg.conf string. @@ -4526,7 +4543,7 @@ * photoid.c: Use __MINGW32__ to include windows because HAVE_DOSISH_SYSTEM is also set for OS/2 and plain DOS. Provide - constant missing in older mingw installations. + constant missing in older mingw installations. 2002-06-21 Stefan Bellon @@ -4640,7 +4657,7 @@ 2002-06-14 Timo Schulz * skclist.c (is_insecure): Implemented. - + 2002-06-12 David Shaw * keyserver.c (keyserver_spawn): Properly handle PROGRAM responses @@ -4688,7 +4705,7 @@ * encode.c (encode_symmetric): Disable the compat flag when the expert mode is enabled. - + 2002-06-07 David Shaw * options.skel, options.h, main.h, keydb.h, pkclist.c @@ -4752,18 +4769,18 @@ * encode.c (encode_simple): Ignore the new mode for RFC1991. * mainproc.c (symkey_decrypt_sesskey): Better check for weird keysizes. - + 2002-06-05 Timo Schulz * encode.c (encode_sesskey): New. (encode_simple): Use it here. But by default we use the compat mode which supress to generate encrypted session keys. - + 2002-06-05 Timo Schulz * mainproc.c (symkey_decrypt_sesskey): New. (proc_symkey_enc): Support for encrypted session keys. - + 2002-06-04 David Shaw * sign.c (hash_for, sign_file): When encrypting and signing at the @@ -4791,7 +4808,7 @@ * keylist.c (show_policy_url, show_notation): Display if the policy or notation is critical. - + 2002-06-03 David Shaw * main.h, g10.c (main), keylist.c (dump_attribs, set_attrib_fd, @@ -4811,7 +4828,7 @@ showing the photo for confirmation is not safe when noninteractive since the "user" may not be able to dismiss a viewer window. Noted by Timo Schulz. - + 2002-06-03 David Shaw * options.skel: Sample photo viewers for Win32. @@ -4849,7 +4866,7 @@ letters for non-interactive output. (show_revocation_reason): Now it is global. * pubkey-enc.c (get_it): Show if the key has been revoked. - + 2002-05-30 David Shaw * sign.c (write_signature_packets, sign_file, clearsign_file, @@ -5017,7 +5034,7 @@ 2002-05-14 Timo Schulz * exec.c (make_tempdir) [MINGW32]: Added missing '\'. - + 2002-05-14 Stefan Bellon * exec.c (make_tempdir): Make use of EXTSEP_S instead of hardcoded @@ -5151,7 +5168,7 @@ * mainproc.c (proc_symkey_enc): Don't ask for a passphrase in the list only mode. - + 2002-05-05 David Shaw * keyserver.c (keyserver_refresh): --refresh-keys implies @@ -5238,7 +5255,7 @@ * g10.c, options.h: New options --display, --ttyname, --ttytype, --lc-ctype, --lc-messages to be used with future versions of the - gpg-agent. + gpg-agent. * passphrase.c (agent_send_option,agent_send_all_options): New. (agent_open): Send options to the agent. @@ -5329,7 +5346,7 @@ sync operation done by its callers. (get_validity): Add logic for maintaining a pending_check flag. (clear_ownertrust): New. - + * keyedit.c (sign_uids): Don't call revalidation_mark depending on primary_pk. (keyedit_menu): Call revalidation_mark after "trust". @@ -5338,7 +5355,7 @@ * delkey.c (do_delete_key): Clear the owenertrust information when deleting a public key. - + 2002-04-18 Werner Koch * seskey.c (encode_md_value): Print an error message if a wrong @@ -5515,7 +5532,7 @@ 2002-04-02 Werner Koch * Makefile.am (EXTRA_DIST): Removed OPTIONS an pubring.asc - they - are no longer of any use. + are no longer of any use. 2002-04-03 David Shaw @@ -5654,7 +5671,7 @@ * import.c (import_one): call revocation_present after importing a new key. Note that this applies to --import, --recv-keys, and --search-keys. - + * keyserver-internal.h, keyserver.c (keyserver_import_fprint): import via fingerprint (for revocation keys). @@ -5721,7 +5738,7 @@ * packet.h, parse-packet.c (parse_one_sig_subpkt, can_handle_critical, parse_signature): Get revocation key information out of direct sigs. - + * keylist.c (list_keyblock_print): don't assume that the presence of a 0x20 signature means the key is revoked. With revocation keys, this may not be true if the revocation key is not around to @@ -5736,7 +5753,7 @@ * import.c (import_revoke_cert): don't keep processing after a revocation is rejected. - + * import.c (delete_inv_parts): Allow importing a revocation signature even if it was not issued by the key. This allows a revocation key to issue it. Of course, the sig still needs to be @@ -5801,7 +5818,7 @@ 2002-02-14 Werner Koch - * g10.c: New option --no-use-agent. + * g10.c: New option --no-use-agent. * pkclist.c (check_signatures_trust): Always print the warning for unknown and undefined trust. Removed the did_add cruft. Reported @@ -5828,7 +5845,7 @@ * options.h, g10.c (main), cipher.c (write_header): Add a knob to --disable-mdc/--no-disable-mdc. Off by default, of course, but is used in --pgp2 and --pgp6 modes. - + * pkclist.c (build_pk_list): Allow specifying multiple users in the "Enter the user ID" loop. Enter a blank line to stop. Show each key+id as it is added. @@ -5836,7 +5853,7 @@ * keylist.c (show_policy_url), mainproc.c (print_notation_data): It is not illegal (though possibly silly) to have multiple policy URLs in a given signature, so print all that are present. - + * hkp.c (hkp_search): More efficient implementation of URL-ifying code. @@ -5847,7 +5864,7 @@ * photoid.c (show_photo): Call the new pct_expando function rather than expand strings internally. - + * sign.c (mk_notation_and_policy): Show policy URLs and notations when making a signature if show-policy/show-notation is on. %-expand policy URLs during generation. This lets the user have @@ -5976,7 +5993,7 @@ * helptext.c: Revise the sign_uid.class help text as suggested by Stefan. - + 2002-01-20 Werner Koch * passphrase.c (passphrase_to_dek): Add tryagain_text arg to be @@ -5988,7 +6005,7 @@ * keyedit.c (change_passphrase): Ditto. * passphrase.c (agent_open): Disable opt.use_agent in case of a - problem with the agent. + problem with the agent. (agent_get_passphrase): Ditto. (passphrase_clear_cache): Ditto. @@ -5999,15 +6016,15 @@ (agent_get_passphrase): Implemented new protocol here. (passphrase_clear_cache): Ditto. (readline): New. - + 2002-01-15 Timo Schulz * encode.c (encode_crypt_files): Fail if --output is used. - + * g10.c: New command --decrypt-files. * decrypt.c (decrypt_messages): New. - + 2002-01-09 David Shaw * g10.c, misc.c, gpgv.c: move idea_cipher_warn to misc.c so gpgv.c @@ -6024,7 +6041,7 @@ 2002-01-09 Timo Schulz * encode.c (encode_crypt_files): Now it behaves like verify_files. - + * g10.c (main): We don't need to check argc for encode_crypt_files any longer. @@ -6112,7 +6129,7 @@ 2002-01-03 Timo Schulz * g10.c: New command --encrypt-files. - + * verify.c (print_file_status): Removed the static because encode_crypt_files also uses this function. @@ -6216,7 +6233,7 @@ * encode.c (encode_simple, encode_crypt): i18n 2 strings. 2001-12-22 Timo Schulz - + * encode.c (encode_simple, encode_crypt): Use is_file_compressed to avoid to compress compressed files. @@ -6251,9 +6268,9 @@ * free-packet.c (free_attributes (new)): function to free an attribute packet. - + * gpgv.c: added stub show_photo - + * keyedit.c (keyedit_menu, menu_adduid, menu_showphoto): can add a photo (calls generate_photo_id), or display a photo (calls show_photo) from the --edit menu. New commands are "addphoto", @@ -6261,7 +6278,7 @@ * keylist.c (list_keyblock_print): show photos during key list if --show-photos enabled. - + * keyserver.c (keyserver_spawn): use the generic exec_xxx functions to call keyserver helper. @@ -6269,7 +6286,7 @@ --photo-viewer to give the command line to display a picture. * options.skel: instructions for the photo viewer - + * parse-packet.c (parse_user_id, setup_user_id (new)): common code for both user IDs and attribute IDs moved to setup_user_id. @@ -6317,7 +6334,7 @@ * g10.c. options.h : New option --show-keyring * getkey.c (get_ctx_handle): New. - * keylist.c (list_one): Implement option here. By David Champion. + * keylist.c (list_one): Implement option here. By David Champion. 2001-12-20 David Shaw @@ -6344,7 +6361,7 @@ the permission warning message(s). This also permits use of the keyserver if it had been disabled (see above). Also check the permissions/ownership of random_seed. - + * keyserver.c (keyserver_spawn): The new glibc prints a warning when using mktemp() (the code was already secure, but the warning was bound to cause confusion). Use a different implementation @@ -6417,7 +6434,7 @@ (hkp_search): Ditto for the char* vars. * g10.c (main): Print the IDEA warning also for -c and -se. - + * g10.c (get_temp_dir): Assert that we have dropped privs * encode.c (encode_crypt): Include the first key into the --pgp2 @@ -6569,10 +6586,10 @@ selected. Based on a patch by W Lewis. * pkclist.c (do_edit_ownertrust): Allow to skip over keys, the non - working "show info" is now assigned to "i" + working "show info" is now assigned to "i" * trustdb.c (ask_ownertrust, validate_keys): Implement a real quit here. Both are by David Shaw. - + * trustdb.c (validate_keys): Make sure next_exipire is initialized. * sign.c (make_keysig_packet): Use SHA-1 with v4 RSA keys. @@ -6619,18 +6636,18 @@ (keydb_locate_writable): Make a real implementation. * keyring.c (next_kr): Removed and changed all callers to set the resource directly from the one given with the handle. - (keyring_is_writable): New. + (keyring_is_writable): New. (keyring_rebuild_cache): Add an arg to pass the token from keydb. 2001-10-17 Werner Koch * keyring.c (keyring_search): Enabled word search mode but print a warning that it is buggy. - + 2001-10-11 Werner Koch * hkp.c (hkp_ask_import): No more need to set the port number for - the x-hkp scheme. + the x-hkp scheme. (hkp_export): Ditto. 2001-10-06 Stefan Bellon @@ -6643,7 +6660,7 @@ * export.c (do_export_stream): Do not push the compress filter here because the context would run out of scope due to the iobuf_close done by the caller. - (do_export): Do it here instead. + (do_export): Do it here instead. 2001-09-28 Werner Koch @@ -6657,7 +6674,7 @@ (validate_one_keyblock): this and changed args for direct calling. (mark_usable_uid_certs, validate_one_keyblock) (validate_key_list): Add next_expire arg to keep track of - expiration times. + expiration times. (validate_keys): Ditto for UTKs and write the stamp. * tdbio.c (migrate_from_v2): Check return code of tbdio_sync. @@ -6739,18 +6756,18 @@ PREF, SIG, SDIR and CACH. Changed migration function to work direct on the file. (tdbio_read_nextcheck): New. - (tdbio_write_nextcheck): New. + (tdbio_write_nextcheck): New. 2001-09-21 Werner Koch Revamped the entire key validation system. * trustdb.c: Complete rewrite. No more validation on demand, - removed some functions, adjusted to all callers to use the new + removed some functions, adjusted to all callers to use the new and much simpler interface. Does not use the LID anymore. * tdbio.c, tdbio.h: Add new record types trust and valid. Wrote a migration function to convert to the new trustdb layout. * getkey.c (classify_user_id2): Do not allow the use of the "#" - prefix. + prefix. * keydb.h: Removed the TDBIDX mode add a skipfnc to the descriptor. * keyring.c (keyring_search): Implemented skipfnc. @@ -6761,7 +6778,7 @@ * keylist.c (print_fingerprint): Renamed from fingerprint, made global available. Added new arg to control the print style. - * mainproc.c (print_fingerprint): Removed. + * mainproc.c (print_fingerprint): Removed. * pkclist.c (print_fpr, fpr_info): Removed and changed callers to use print_fingerprint. * keyedit.c (show_fingerprint): Ditto. @@ -6776,7 +6793,7 @@ * keyring.c (keyring_release): Close the iobuf. (keyring_get_keyblock): Init ret_kb to NULL and store error contidion. - * import.c (import_new_stats_handle): New. + * import.c (import_new_stats_handle): New. (import_release_stats_handle): New. (import_print_stats): Renamed from static fnc print_stats. (import_keys, import_keys_stream): Add an optional status handle @@ -6797,7 +6814,7 @@ * mainproc.c (print_notation_data): Wrap notation data status lines after 50 chars. - + * mainproc.c (proc_pubkey_enc): Make option try-all-secrets work. By disastry@saiknes.lv. @@ -6833,7 +6850,7 @@ * keyedit.c (sign_uids): Added experimental ALREADY_SIGNED * hkp.c (hkp_import): Use log_error. Bug reported by Neal H - Walfield. + Walfield. * getkey.c (classify_user_id2): Change args to take the desc union direct. It was a stupid idea to pass the individual fields of an @@ -6852,7 +6869,7 @@ * keyring.c, keyring.h: New. * ringedit.c: Removed. Moved some stuff to keyring.c * getkey.c: Changed everything related to the key retrieving - functions which are now using the keydb_ functions. + functions which are now using the keydb_ functions. (prepare_search, word_match_chars, word_match) (prepare_word_match, compare_name): Moved to keyring.c (get_pubkey_byname): Removed ctx arg and add ret_kdbhd @@ -6864,19 +6881,19 @@ * import.c (import_one): Updated to use the new keydb interface. (import_secret_one): Ditto. (import_revoke_cert): Ditto. - * delkey.c (do_delete_key): Ditto. + * delkey.c (do_delete_key): Ditto. * keyedit.c (keyedit_menu): Ditto. (get_keyblock_byname): Removed. - * revoke.c (gen_revoke): Ditto. + * revoke.c (gen_revoke): Ditto. * export.c (do_export_stream): Ditto. * trustdb.c (update_trustdb): Ditto. * g10.c, gpgv.c (main): Renamed add_keyblock_resource to - keydb_add_resource. + keydb_add_resource. * Makefile.am: Added and removed files. * keydb.h: Moved KBNODE typedef and MAX_FINGERPRINT_LEN to * global.h: this new header. - + 2001-09-03 Werner Koch * passphrase.c (agent_get_passphrase): Changed nread to size_t. @@ -6898,7 +6915,7 @@ * parse-packet.c (parse_key,parse_pubkeyenc) (parse_signature): Return error on reading bad MPIs. - + * mainproc.c (check_sig_and_print): Always print the user ID even if it is not bound by a signature. Use the primary UID in the status messages and encode them in UTF-8 @@ -6952,12 +6969,12 @@ (sign_file, sign_symencrypt_file): Moved common code to .. (write_onepass_sig_packets): .. this new function. (sign_file, clearsign_file, sign_symencrypt_file): Moved common - code to + code to (write_signature_packets): this new function. (write_signature_packets, make_keysig_packet) - (update_keysig_packet): Moved common code to + (update_keysig_packet): Moved common code to (hash_uid, hash_sigclass_to_magic): these new functions - (sign_file, sign_symencrypt_file): Moved common code to + (sign_file, sign_symencrypt_file): Moved common code to (write_plaintext_packet): this new function. 2001-08-21 Stefan Bellon @@ -6987,7 +7004,7 @@ * g10.c [__riscos__]: Some patches and new options foo-file similar to all foo-fd options. * gpgv.c, openfile.c, ringedit.c, tdbio.c: Minor fixes. Mainly - replaced hardcoded path separators with EXTSEP_S like macros. + replaced hardcoded path separators with EXTSEP_S like macros. * passprase.c [__riscos__]: Disabled agent stuff * trustdb.c (check_trust): Changed r_trustlevel to signed int to avoid mismatch problems in pkclist.c @@ -6997,7 +7014,7 @@ * options.h [__riscos__]: Use an extern unless included from the main module. * signal.c (got_fatal_signal) [__riscos__]: Close all files. - + 2001-08-14 Werner Koch * keygen.c (ask_algo): New arg r_usage. Allow for RSA keys. @@ -7015,7 +7032,7 @@ (write_selfsig, write_keybinding): Handle new usage arg. * build-packet.c (build_sig_subpkt): Make sure that key flags go into the hashed area. - + * keygen.c (write_uid): Initialize the reference cunter. * keyedit.c (keyedit_menu): No more need to update the trustdb for @@ -7034,7 +7051,7 @@ * parse-packet.c (parse_user_id,parse_photo_id): Initialize them * free-packet.c (free_user_id): Free them. (copy_user_id): Removed. - (scopy_user_id): New. + (scopy_user_id): New. (cmp_user_ids): Optimized for identical pointers. (release_public_key_parts): Release the uid. (copy_public_key_with_new_namehash): Removed. @@ -7055,7 +7072,7 @@ * pkclist.c (select_algo_from_prefs): Adjusted for the new preference implementation. * pubkey-enc.c (is_algo_in_prefs): New. - (get_it): Use that new function. + (get_it): Use that new function. 2001-08-09 Werner Koch @@ -7176,12 +7193,12 @@ * getkey.c (merge_selfsigs): Exit gracefully when a secret key is encountered. May happen if a secret key is in public keyring. Reported by Francesco Potorti. - + 2001-06-12 Werner Koch * getkey.c (compare_name): Use ascii_memistr(), ascii_memcasecmp() * keyedit.c (keyedit_menu): Use ascii_strcasecmp(). - * armor.c (radix64_read): Use ascii_toupper(). + * armor.c (radix64_read): Use ascii_toupper(). * ringedit.c (do_bm_search): Ditto. * keygen.c (read_parameter_file): Ditto. * openfile.c (CMP_FILENAME): Ditto. @@ -7233,7 +7250,7 @@ 2001-05-01 Werner Koch - * passphrase.c (writen): Replaced ssize_t by int. Thanks to + * passphrase.c (writen): Replaced ssize_t by int. Thanks to to Robert Joop for reporting that SunOS 4.1.4 does not have it. 2001-04-28 Werner Koch @@ -7263,10 +7280,10 @@ 2001-04-23 Werner Koch - * hkp.c (hkp_ask_import): Allow to specify a port number for the + * hkp.c (hkp_ask_import): Allow to specify a port number for the keyserver. Add a kudge to set the no_shutdown flag. (hkp_export): Ditto. - * options.skel: Document the changes + * options.skel: Document the changes 2001-04-20 Werner Koch @@ -7309,7 +7326,7 @@ 2001-04-05 Werner Koch * armor.c (unarmor_pump_new,unarmor_pump_release): New. - (unarmor_pump): New. + (unarmor_pump): New. * pipemode.c (pipemode_filter): Use the unarmor_pump to handle armored or non-armored detached signatures. We can't use the regular armor_filter because this does only check for armored @@ -7412,7 +7429,7 @@ 2001-03-19 Werner Koch * g10.c (main): the default keyring is no always used unless - --no-default-keyring is given. + --no-default-keyring is given. * ringedit.c (add_keyblock_resource): invalidate cache after file creation. @@ -7454,7 +7471,7 @@ function so that we can adjust for the next read. * options.skel: Fixed 3 typos. By Thomas Klausner. Replaced the - keyserver example by a better working server. + keyserver example by a better working server. * parse-packet.c (parse_symkeyenc): Return Invalid_Packet on error. (parse_pubkeyenc): Ditto. @@ -7471,7 +7488,7 @@ * signal.c (do_sigaction): Removed. (init_one_signal): New to replace the above. Needed to support systems without sigactions. Suggested by Dave Dykstra. - (got_fatal_signal,init_signals): Use the above here. + (got_fatal_signal,init_signals): Use the above here. (do_block): Use sigset() if sigprocmask() is not available. * armor.c (parse_hash_header): Test on TIGER192, which is the @@ -7487,7 +7504,7 @@ * getkey.c (merge_selfsigs_main): Set expire date and continue processing even if we found a revoked key. (merge_selfsigs_subkeys): Ditto. - + * packet.h: Add an is_revoked flag to the user_id packet. * getkey.c (fixup_uidnode): Set that flag here. (merge_selfsigs_main): Fix so that the latest signature is used to @@ -7496,9 +7513,9 @@ * mainproc.c (check_sig_and_print): Print the primary user ID according the the node flag and then all other non-revoked user IDs. (is_uid_revoked): Removed; it is now handled by the key selection code. - + Changed the year list of all copyright notices. - + 2001-03-07 Werner Koch * getkey.c (finish_lookup): Print an info message only in verbose mode. @@ -7517,11 +7534,11 @@ (cache_selfsig_result): New. * export.c (do_export_stream): Delete that sig subpkt before exporting. * import.c (remove_bad_stuff): New. - (import): Apply that function to all imported data + (import): Apply that function to all imported data 2001-03-03 Werner Koch - * getkey.c: Introduced a new lookup context flag "exact" and used + * getkey.c: Introduced a new lookup context flag "exact" and used it in all place where we once used primary. (classify_user_id2): Replaced the old function and add an extra argument to return whether an exact keyID has been requested. @@ -7531,7 +7548,7 @@ 2001-03-02 Werner Koch - * keylist.c (list_one): Remove the merge key calls. + * keylist.c (list_one): Remove the merge key calls. 2001-03-01 Werner Koch @@ -7543,7 +7560,7 @@ * import.c (import_one): Take UNU_PUBKEY into account. * mainproc.c (list_node): Ditto. * keylist.c (list_keyblock): Ditto. - * keyedit.c (print_and_check_one_sig): Ditto. + * keyedit.c (print_and_check_one_sig): Ditto. 2001-02-09 Werner Koch @@ -7608,7 +7625,7 @@ 2001-01-09 Werner Koch - * status.c, status.h: New status USERID_HINT. + * status.c, status.h: New status USERID_HINT. (write_status_text): Replace LF and CR int text by C-escape sequence. * passphrase.c (passphrase_to_dek): Fixed the NEED_PASSPHRASE @@ -7636,7 +7653,7 @@ atexit stuff does not work due to the use of raise. Suggested by Peter Fales. * gpgv.c (remove_lockfiles): New stub. - + 2000-12-19 Werner Koch * status.c, status.h (cpr_get_no_help): New. @@ -7726,11 +7743,11 @@ * status.c, status.h: Add 3 status lcodes for notaions and policy. * mainproc.c (print_notation_data): Do status output of notations. - + 2000-11-13 Werner Koch * sign.c (clearsign_file): Use LF macro to print linefeed. - + 2000-11-11 Paul Eggert Clean up the places in the code that incorrectly use "long" or @@ -7755,7 +7772,7 @@ * g10.c (main): New option --enable-special-filenames. 2000-11-07 Werner Koch - + * g10.c (main): New command --pipemode. * pipemode.c: New. @@ -7766,7 +7783,7 @@ * keygen.c (read_parameter_file): Add a cast for isspace(). - * status.c (myread): Use SIGINT instead of SIGHUP for DOS. + * status.c (myread): Use SIGINT instead of SIGHUP for DOS. 2000-10-19 Werner Koch @@ -7775,7 +7792,7 @@ (radix64_read): Act on new option. * openfile.c (try_make_homedir): Klaus Singvogel fixed a stupid - error introduced on Sep 6th. + error introduced on Sep 6th. 2000-10-18 Werner Koch @@ -7787,7 +7804,7 @@ * mainproc.c (do_proc_packets): Hack to fix the problem that signatures are not detected when there is a MDC packet but no compression packet. - + * g10.c (print_hashline): New. (print_mds): Use above func with --with-colons. @@ -7816,7 +7833,7 @@ * armor.c (armor_filter): Replaced the faked 1-pass packet by the new control packet. - * keyedit.c (keyedit_menu): Allow batchmode with a command_fd. + * keyedit.c (keyedit_menu): Allow batchmode with a command_fd. * status.c (my_read): New. (do_get_from_fd): use it. @@ -7861,7 +7878,7 @@ Thu Sep 14 14:20:38 CEST 2000 Werner Koch * g10.c (main): Default S2K algorithms are now SHA1 and CAST5 - this should solve a lot of compatibility problems with other OpenPGP apps because those algorithms are SHOULD and not optional. The old - way to force it was by using the --openpgp option whith the drawback + way to force it was by using the --openpgp option whith the drawback that this would disable a couple of workarounds for PGP. * g10.c (main): Don't set --quite along with --no-tty. By Frank Tobin. @@ -7904,7 +7921,7 @@ Fri Aug 25 16:05:38 CEST 2000 Werner Koch * parse-packet.c (dump_sig_subpkt): Print info about the ARR. * openfile.c (overwrite_filep): Always return okay if the file is - called /dev/null. + called /dev/null. (make_outfile_name): Add ".sign" to the list of know extensions. (open_sigfile): Ditto. diff --git a/g10/Makefile.am b/g10/Makefile.am index 3c85bbe6..8b505e7a 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -81,7 +81,7 @@ gpg2_SOURCES = gpg.c \ seckey-cert.c \ encr-data.c \ cipher.c \ - encode.c \ + encrypt.c \ sign.c \ verify.c \ revoke.c \ diff --git a/g10/encode.c b/g10/encode.c deleted file mode 100644 index 3c4e0a27..00000000 --- a/g10/encode.c +++ /dev/null @@ -1,912 +0,0 @@ -/* encode.c - encode data - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - * 2006, 2009 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include "gpg.h" -#include "options.h" -#include "packet.h" -#include "status.h" -#include "iobuf.h" -#include "keydb.h" -#include "util.h" -#include "main.h" -#include "filter.h" -#include "trustdb.h" -#include "i18n.h" -#include "status.h" -#include "pkglue.h" - - -static int encode_simple( const char *filename, int mode, int use_seskey ); -static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out ); - -/**************** - * Encode FILENAME with only the symmetric cipher. Take input from - * stdin if FILENAME is NULL. - */ -int -encode_symmetric( const char *filename ) -{ - return encode_simple( filename, 1, 0 ); -} - -/**************** - * Encode FILENAME as a literal data packet only. Take input from - * stdin if FILENAME is NULL. - */ -int -encode_store( const char *filename ) -{ - return encode_simple( filename, 0, 0 ); -} - - -static void -encode_seskey( DEK *dek, DEK **seskey, byte *enckey ) -{ - gcry_cipher_hd_t hd; - byte buf[33]; - - assert ( dek->keylen <= 32 ); - if(!*seskey) - { - *seskey=xmalloc_clear(sizeof(DEK)); - (*seskey)->keylen=dek->keylen; - (*seskey)->algo=dek->algo; - make_session_key(*seskey); - /*log_hexdump( "thekey", c->key, c->keylen );*/ - } - - /* The encrypted session key is prefixed with a one-octet algorithm id. */ - buf[0] = (*seskey)->algo; - memcpy( buf + 1, (*seskey)->key, (*seskey)->keylen ); - - /* We only pass already checked values to the following fucntion, - thus we consider any failure as fatal. */ - if (openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1)) - BUG (); - if (gcry_cipher_setkey (hd, dek->key, dek->keylen)) - BUG (); - gcry_cipher_setiv (hd, NULL, 0); - gcry_cipher_encrypt (hd, buf, (*seskey)->keylen + 1, NULL, 0); - gcry_cipher_close (hd); - - memcpy( enckey, buf, (*seskey)->keylen + 1 ); - wipememory( buf, sizeof buf ); /* burn key */ -} - -/* We try very hard to use a MDC */ -static int -use_mdc(PK_LIST pk_list,int algo) -{ - /* RFC-1991 and 2440 don't have MDC */ - if(RFC1991 || RFC2440) - return 0; - - /* --force-mdc overrides --disable-mdc */ - if(opt.force_mdc) - return 1; - - if(opt.disable_mdc) - return 0; - - /* Do the keys really support MDC? */ - - if(select_mdc_from_pklist(pk_list)) - return 1; - - /* The keys don't support MDC, so now we do a bit of a hack - if any - of the AESes or TWOFISH are in the prefs, we assume that the user - can handle a MDC. This is valid for PGP 7, which can handle MDCs - though it will not generate them. 2440bis allows this, by the - way. */ - - if(select_algo_from_prefs(pk_list,PREFTYPE_SYM, - CIPHER_ALGO_AES,NULL)==CIPHER_ALGO_AES) - return 1; - - if(select_algo_from_prefs(pk_list,PREFTYPE_SYM, - CIPHER_ALGO_AES192,NULL)==CIPHER_ALGO_AES192) - return 1; - - if(select_algo_from_prefs(pk_list,PREFTYPE_SYM, - CIPHER_ALGO_AES256,NULL)==CIPHER_ALGO_AES256) - return 1; - - if(select_algo_from_prefs(pk_list,PREFTYPE_SYM, - CIPHER_ALGO_TWOFISH,NULL)==CIPHER_ALGO_TWOFISH) - return 1; - - /* Last try. Use MDC for the modern ciphers. */ - - if (openpgp_cipher_get_algo_blklen (algo) != 8) - return 1; - - if (opt.verbose) - warn_missing_mdc_from_pklist (pk_list); - - return 0; /* No MDC */ -} - -/* We don't want to use use_seskey yet because older gnupg versions - can't handle it, and there isn't really any point unless we're - making a message that can be decrypted by a public key or - passphrase. */ -static int -encode_simple( const char *filename, int mode, int use_seskey ) -{ - IOBUF inp, out; - PACKET pkt; - PKT_plaintext *pt = NULL; - STRING2KEY *s2k = NULL; - byte enckey[33]; - int rc = 0; - int seskeylen = 0; - u32 filesize; - cipher_filter_context_t cfx; - armor_filter_context_t *afx = NULL; - compress_filter_context_t zfx; - text_filter_context_t tfx; - progress_filter_context_t *pfx; - int do_compress = !RFC1991 && default_compress_algo(); - - pfx = new_progress_context (); - memset( &cfx, 0, sizeof cfx); - memset( &zfx, 0, sizeof zfx); - memset( &tfx, 0, sizeof tfx); - init_packet(&pkt); - - /* prepare iobufs */ - inp = iobuf_open(filename); - if (inp) - iobuf_ioctl (inp,3,1,NULL); /* disable fd caching */ - if (inp && is_secured_file (iobuf_get_fd (inp))) - { - iobuf_close (inp); - inp = NULL; - errno = EPERM; - } - if( !inp ) { - rc = gpg_error_from_syserror (); - log_error(_("can't open `%s': %s\n"), filename? filename: "[stdin]", - strerror(errno) ); - release_progress_context (pfx); - return rc; - } - - handle_progress (pfx, inp, filename); - - if( opt.textmode ) - iobuf_push_filter( inp, text_filter, &tfx ); - - /* Due the the fact that we use don't use an IV to encrypt the - session key we can't use the new mode with RFC1991 because - it has no S2K salt. RFC1991 always uses simple S2K. */ - if ( RFC1991 && use_seskey ) - use_seskey = 0; - - cfx.dek = NULL; - if( mode ) { - int canceled; - - s2k = xmalloc_clear( sizeof *s2k ); - s2k->mode = RFC1991? 0:opt.s2k_mode; - s2k->hash_algo=S2K_DIGEST_ALGO; - cfx.dek = passphrase_to_dek( NULL, 0, - default_cipher_algo(), s2k, 4, - NULL, &canceled); - if( !cfx.dek || !cfx.dek->keylen ) { - rc = gpg_error (canceled? GPG_ERR_CANCELED:GPG_ERR_INV_PASSPHRASE); - xfree(cfx.dek); - xfree(s2k); - iobuf_close(inp); - log_error(_("error creating passphrase: %s\n"), gpg_strerror (rc)); - release_progress_context (pfx); - return rc; - } - if (use_seskey && s2k->mode != 1 && s2k->mode != 3) { - use_seskey = 0; - log_info (_("can't use a symmetric ESK packet " - "due to the S2K mode\n")); - } - - if ( use_seskey ) - { - DEK *dek = NULL; - - seskeylen = openpgp_cipher_get_algo_keylen (default_cipher_algo ()); - encode_seskey( cfx.dek, &dek, enckey ); - xfree( cfx.dek ); cfx.dek = dek; - } - - if(opt.verbose) - log_info(_("using cipher %s\n"), - openpgp_cipher_algo_name (cfx.dek->algo)); - - cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo); - } - - if (do_compress && cfx.dek && cfx.dek->use_mdc - && is_file_compressed(filename, &rc)) - { - if (opt.verbose) - log_info(_("`%s' already compressed\n"), filename); - do_compress = 0; - } - - if( rc || (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) { - iobuf_cancel(inp); - xfree(cfx.dek); - xfree(s2k); - release_progress_context (pfx); - return rc; - } - - if ( opt.armor ) - { - afx = new_armor_context (); - push_armor_filter (afx, out); - } - - if( s2k && !RFC1991 ) { - PKT_symkey_enc *enc = xmalloc_clear( sizeof *enc + seskeylen + 1 ); - enc->version = 4; - enc->cipher_algo = cfx.dek->algo; - enc->s2k = *s2k; - if ( use_seskey && seskeylen ) { - enc->seskeylen = seskeylen + 1; /* algo id */ - memcpy( enc->seskey, enckey, seskeylen + 1 ); - } - pkt.pkttype = PKT_SYMKEY_ENC; - pkt.pkt.symkey_enc = enc; - if( (rc = build_packet( out, &pkt )) ) - log_error("build symkey packet failed: %s\n", g10_errstr(rc) ); - xfree(enc); - } - - if (!opt.no_literal) - pt=setup_plaintext_name(filename,inp); - - /* Note that PGP 5 has problems decrypting symmetrically encrypted - data if the file length is in the inner packet. It works when - only partial length headers are use. In the past, we always - used partial body length here, but since PGP 2, PGP 6, and PGP - 7 need the file length, and nobody should be using PGP 5 - nowadays anyway, this is now set to the file length. Note also - that this only applies to the RFC-1991 style symmetric - messages, and not the RFC-2440 style. PGP 6 and 7 work with - either partial length or fixed length with the new style - messages. */ - - if ( !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode ) - { - off_t tmpsize; - int overflow; - - if ( !(tmpsize = iobuf_get_filelength(inp, &overflow)) - && !overflow && opt.verbose) - log_info(_("WARNING: `%s' is an empty file\n"), filename ); - /* We can't encode the length of very large files because - OpenPGP uses only 32 bit for file sizes. So if the the - size of a file is larger than 2^32 minus some bytes for - packet headers, we switch to partial length encoding. */ - if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) ) - filesize = tmpsize; - else - filesize = 0; - } - else - filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ - - if (!opt.no_literal) { - pt->timestamp = make_timestamp(); - pt->mode = opt.textmode? 't' : 'b'; - pt->len = filesize; - pt->new_ctb = !pt->len && !RFC1991; - pt->buf = inp; - pkt.pkttype = PKT_PLAINTEXT; - pkt.pkt.plaintext = pt; - cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0; - } - else - { - cfx.datalen = filesize && !do_compress ? filesize : 0; - pkt.pkttype = 0; - pkt.pkt.generic = NULL; - } - - /* register the cipher filter */ - if( mode ) - iobuf_push_filter( out, cipher_filter, &cfx ); - /* register the compress filter */ - if( do_compress ) - { - if (cfx.dek && cfx.dek->use_mdc) - zfx.new_ctb = 1; - push_compress_filter(out,&zfx,default_compress_algo()); - } - - /* do the work */ - if (!opt.no_literal) { - if( (rc = build_packet( out, &pkt )) ) - log_error("build_packet failed: %s\n", g10_errstr(rc) ); - } - else { - /* user requested not to create a literal packet, - * so we copy the plain data */ - byte copy_buffer[4096]; - int bytes_copied; - while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1) - if ( (rc=iobuf_write(out, copy_buffer, bytes_copied)) ) { - log_error ("copying input to output failed: %s\n", - gpg_strerror (rc) ); - break; - } - wipememory(copy_buffer, 4096); /* burn buffer */ - } - - /* finish the stuff */ - iobuf_close(inp); - if (rc) - iobuf_cancel(out); - else { - iobuf_close(out); /* fixme: check returncode */ - if (mode) - write_status( STATUS_END_ENCRYPTION ); - } - if (pt) - pt->buf = NULL; - free_packet(&pkt); - xfree(cfx.dek); - xfree(s2k); - release_armor_context (afx); - release_progress_context (pfx); - return rc; -} - -int -setup_symkey(STRING2KEY **symkey_s2k,DEK **symkey_dek) -{ - int canceled; - - *symkey_s2k=xmalloc_clear(sizeof(STRING2KEY)); - (*symkey_s2k)->mode = opt.s2k_mode; - (*symkey_s2k)->hash_algo = S2K_DIGEST_ALGO; - - *symkey_dek=passphrase_to_dek(NULL,0,opt.s2k_cipher_algo, - *symkey_s2k, 4, NULL, &canceled); - if(!*symkey_dek || !(*symkey_dek)->keylen) - { - xfree(*symkey_dek); - xfree(*symkey_s2k); - return gpg_error (canceled?GPG_ERR_CANCELED:GPG_ERR_BAD_PASSPHRASE); - } - - return 0; -} - -static int -write_symkey_enc(STRING2KEY *symkey_s2k,DEK *symkey_dek,DEK *dek,IOBUF out) -{ - int rc, seskeylen = openpgp_cipher_get_algo_keylen (dek->algo); - - PKT_symkey_enc *enc; - byte enckey[33]; - PACKET pkt; - - enc=xmalloc_clear(sizeof(PKT_symkey_enc)+seskeylen+1); - encode_seskey(symkey_dek,&dek,enckey); - - enc->version = 4; - enc->cipher_algo = opt.s2k_cipher_algo; - enc->s2k = *symkey_s2k; - enc->seskeylen = seskeylen + 1; /* algo id */ - memcpy( enc->seskey, enckey, seskeylen + 1 ); - - pkt.pkttype = PKT_SYMKEY_ENC; - pkt.pkt.symkey_enc = enc; - - if((rc=build_packet(out,&pkt))) - log_error("build symkey_enc packet failed: %s\n",g10_errstr(rc)); - - xfree(enc); - return rc; -} - -/**************** - * Encrypt the file with the given userids (or ask if none - * is supplied). - */ -int -encode_crypt( const char *filename, strlist_t remusr, int use_symkey ) -{ - IOBUF inp = NULL, out = NULL; - PACKET pkt; - PKT_plaintext *pt = NULL; - DEK *symkey_dek = NULL; - STRING2KEY *symkey_s2k = NULL; - int rc = 0, rc2 = 0; - u32 filesize; - cipher_filter_context_t cfx; - armor_filter_context_t *afx = NULL; - compress_filter_context_t zfx; - text_filter_context_t tfx; - progress_filter_context_t *pfx; - PK_LIST pk_list,work_list; - int do_compress = opt.compress_algo && !RFC1991; - - pfx = new_progress_context (); - memset( &cfx, 0, sizeof cfx); - memset( &zfx, 0, sizeof zfx); - memset( &tfx, 0, sizeof tfx); - init_packet(&pkt); - - if(use_symkey - && (rc=setup_symkey(&symkey_s2k,&symkey_dek))) - { - release_progress_context (pfx); - return rc; - } - - if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) ) - { - release_progress_context (pfx); - return rc; - } - - if(PGP2) { - for(work_list=pk_list; work_list; work_list=work_list->next) - if(!(is_RSA(work_list->pk->pubkey_algo) && - nbits_from_pk(work_list->pk)<=2048)) - { - log_info(_("you can only encrypt to RSA keys of 2048 bits or " - "less in --pgp2 mode\n")); - compliance_failure(); - break; - } - } - - /* prepare iobufs */ - inp = iobuf_open(filename); - if (inp) - iobuf_ioctl (inp,3,1,NULL); /* disable fd caching */ - if (inp && is_secured_file (iobuf_get_fd (inp))) - { - iobuf_close (inp); - inp = NULL; - errno = EPERM; - } - if( !inp ) { - rc = gpg_error_from_syserror (); - log_error(_("can't open `%s': %s\n"), - filename? filename: "[stdin]", - gpg_strerror (rc) ); - goto leave; - } - else if( opt.verbose ) - log_info(_("reading from `%s'\n"), filename? filename: "[stdin]"); - - handle_progress (pfx, inp, filename); - - if( opt.textmode ) - iobuf_push_filter( inp, text_filter, &tfx ); - - if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) - goto leave; - - if ( opt.armor ) - { - afx = new_armor_context (); - push_armor_filter (afx, out); - } - - /* create a session key */ - cfx.dek = xmalloc_secure_clear (sizeof *cfx.dek); - if( !opt.def_cipher_algo ) { /* try to get it from the prefs */ - cfx.dek->algo = select_algo_from_prefs(pk_list,PREFTYPE_SYM,-1,NULL); - /* The only way select_algo_from_prefs can fail here is when - mixing v3 and v4 keys, as v4 keys have an implicit - preference entry for 3DES, and the pk_list cannot be empty. - In this case, use 3DES anyway as it's the safest choice - - perhaps the v3 key is being used in an OpenPGP - implementation and we know that the implementation behind - any v4 key can handle 3DES. */ - if( cfx.dek->algo == -1 ) { - cfx.dek->algo = CIPHER_ALGO_3DES; - - if( PGP2 ) { - log_info(_("unable to use the IDEA cipher for all of the keys " - "you are encrypting to.\n")); - compliance_failure(); - } - } - - /* In case 3DES has been selected, print a warning if - any key does not have a preference for AES. This - should help to indentify why encrypting to several - recipients falls back to 3DES. */ - if (opt.verbose - && cfx.dek->algo == CIPHER_ALGO_3DES) - warn_missing_aes_from_pklist (pk_list); - } - else { - if(!opt.expert && - select_algo_from_prefs(pk_list,PREFTYPE_SYM, - opt.def_cipher_algo,NULL)!=opt.def_cipher_algo) - log_info(_("WARNING: forcing symmetric cipher %s (%d)" - " violates recipient preferences\n"), - openpgp_cipher_algo_name (opt.def_cipher_algo), - opt.def_cipher_algo); - - cfx.dek->algo = opt.def_cipher_algo; - } - - cfx.dek->use_mdc=use_mdc(pk_list,cfx.dek->algo); - - /* Only do the is-file-already-compressed check if we are using a - MDC. This forces compressed files to be re-compressed if we do - not have a MDC to give some protection against chosen - ciphertext attacks. */ - - if (do_compress && cfx.dek->use_mdc && is_file_compressed(filename, &rc2) ) - { - if (opt.verbose) - log_info(_("`%s' already compressed\n"), filename); - do_compress = 0; - } - if (rc2) - { - rc = rc2; - goto leave; - } - - make_session_key( cfx.dek ); - if( DBG_CIPHER ) - log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen ); - - rc = write_pubkey_enc_from_list( pk_list, cfx.dek, out ); - if( rc ) - goto leave; - - /* We put the passphrase (if any) after any public keys as this - seems to be the most useful on the recipient side - there is no - point in prompting a user for a passphrase if they have the - secret key needed to decrypt. */ - if(use_symkey && (rc=write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out))) - goto leave; - - if (!opt.no_literal) - pt=setup_plaintext_name(filename,inp); - - if (!iobuf_is_pipe_filename (filename) && *filename && !opt.textmode ) - { - off_t tmpsize; - int overflow; - - if ( !(tmpsize = iobuf_get_filelength(inp, &overflow)) - && !overflow && opt.verbose) - log_info(_("WARNING: `%s' is an empty file\n"), filename ); - /* We can't encode the length of very large files because - OpenPGP uses only 32 bit for file sizes. So if the the - size of a file is larger than 2^32 minus some bytes for - packet headers, we switch to partial length encoding. */ - if (tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) ) - filesize = tmpsize; - else - filesize = 0; - } - else - filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ - - if (!opt.no_literal) { - pt->timestamp = make_timestamp(); - pt->mode = opt.textmode ? 't' : 'b'; - pt->len = filesize; - pt->new_ctb = !pt->len && !RFC1991; - pt->buf = inp; - pkt.pkttype = PKT_PLAINTEXT; - pkt.pkt.plaintext = pt; - cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0; - } - else - cfx.datalen = filesize && !do_compress ? filesize : 0; - - /* register the cipher filter */ - iobuf_push_filter( out, cipher_filter, &cfx ); - - /* register the compress filter */ - if( do_compress ) { - int compr_algo = opt.compress_algo; - - if(compr_algo==-1) - { - if((compr_algo= - select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1) - compr_algo=DEFAULT_COMPRESS_ALGO; - /* Theoretically impossible to get here since uncompressed - is implicit. */ - } - else if(!opt.expert && - select_algo_from_prefs(pk_list,PREFTYPE_ZIP, - compr_algo,NULL)!=compr_algo) - log_info(_("WARNING: forcing compression algorithm %s (%d)" - " violates recipient preferences\n"), - compress_algo_to_string(compr_algo),compr_algo); - - /* algo 0 means no compression */ - if( compr_algo ) - { - if (cfx.dek && cfx.dek->use_mdc) - zfx.new_ctb = 1; - push_compress_filter(out,&zfx,compr_algo); - } - } - - /* do the work */ - if (!opt.no_literal) { - if( (rc = build_packet( out, &pkt )) ) - log_error("build_packet failed: %s\n", g10_errstr(rc) ); - } - else { - /* user requested not to create a literal packet, so we copy - the plain data */ - byte copy_buffer[4096]; - int bytes_copied; - while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1) - if ( (rc=iobuf_write(out, copy_buffer, bytes_copied)) ) { - log_error ("copying input to output failed: %s\n", - gpg_strerror (rc)); - break; - } - wipememory(copy_buffer, 4096); /* burn buffer */ - } - - /* finish the stuff */ - leave: - iobuf_close(inp); - if( rc ) - iobuf_cancel(out); - else { - iobuf_close(out); /* fixme: check returncode */ - write_status( STATUS_END_ENCRYPTION ); - } - if( pt ) - pt->buf = NULL; - free_packet(&pkt); - xfree(cfx.dek); - xfree(symkey_dek); - xfree(symkey_s2k); - release_pk_list( pk_list ); - release_armor_context (afx); - release_progress_context (pfx); - return rc; -} - - - - -/**************** - * Filter to do a complete public key encryption. - */ -int -encrypt_filter( void *opaque, int control, - IOBUF a, byte *buf, size_t *ret_len) -{ - size_t size = *ret_len; - encrypt_filter_context_t *efx = opaque; - int rc=0; - - if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */ - BUG(); /* not used */ - } - else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */ - if( !efx->header_okay ) { - efx->cfx.dek = xmalloc_secure_clear( sizeof *efx->cfx.dek ); - - if( !opt.def_cipher_algo ) { /* try to get it from the prefs */ - efx->cfx.dek->algo = - select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,-1,NULL); - if( efx->cfx.dek->algo == -1 ) { - /* because 3DES is implicitly in the prefs, this can only - * happen if we do not have any public keys in the list */ - efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO; - } - - /* In case 3DES has been selected, print a warning if - any key does not have a preference for AES. This - should help to indentify why encrypting to several - recipients falls back to 3DES. */ - if (opt.verbose - && efx->cfx.dek->algo == CIPHER_ALGO_3DES) - warn_missing_aes_from_pklist (efx->pk_list); - } - else { - if(!opt.expert && - select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM, - opt.def_cipher_algo, - NULL)!=opt.def_cipher_algo) - log_info(_("forcing symmetric cipher %s (%d) " - "violates recipient preferences\n"), - openpgp_cipher_algo_name (opt.def_cipher_algo), - opt.def_cipher_algo); - - efx->cfx.dek->algo = opt.def_cipher_algo; - } - - efx->cfx.dek->use_mdc = use_mdc(efx->pk_list,efx->cfx.dek->algo); - - make_session_key( efx->cfx.dek ); - if( DBG_CIPHER ) - log_printhex ("DEK is: ", - efx->cfx.dek->key, efx->cfx.dek->keylen ); - - rc = write_pubkey_enc_from_list( efx->pk_list, efx->cfx.dek, a ); - if( rc ) - return rc; - - if(efx->symkey_s2k && efx->symkey_dek) - { - rc=write_symkey_enc(efx->symkey_s2k,efx->symkey_dek, - efx->cfx.dek,a); - if(rc) - return rc; - } - - iobuf_push_filter( a, cipher_filter, &efx->cfx ); - - efx->header_okay = 1; - } - rc = iobuf_write( a, buf, size ); - - } - else if( control == IOBUFCTRL_FREE ) - { - xfree(efx->symkey_dek); - xfree(efx->symkey_s2k); - } - else if( control == IOBUFCTRL_DESC ) { - *(char**)buf = "encrypt_filter"; - } - return rc; -} - - -/**************** - * Write pubkey-enc packets from the list of PKs to OUT. - */ -static int -write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out ) -{ - PACKET pkt; - PKT_public_key *pk; - PKT_pubkey_enc *enc; - int rc; - - for( ; pk_list; pk_list = pk_list->next ) { - gcry_mpi_t frame; - - pk = pk_list->pk; - - print_pubkey_algo_note( pk->pubkey_algo ); - enc = xmalloc_clear( sizeof *enc ); - enc->pubkey_algo = pk->pubkey_algo; - keyid_from_pk( pk, enc->keyid ); - enc->throw_keyid = (opt.throw_keyid || (pk_list->flags&1)); - - if(opt.throw_keyid && (PGP2 || PGP6 || PGP7 || PGP8)) - { - log_info(_("you may not use %s while in %s mode\n"), - "--throw-keyid",compliance_option_string()); - compliance_failure(); - } - - /* Okay, what's going on: We have the session key somewhere in - * the structure DEK and want to encode this session key in - * an integer value of n bits. pubkey_nbits gives us the - * number of bits we have to use. We then encode the session - * key in some way and we get it back in the big intger value - * FRAME. Then we use FRAME, the public key PK->PKEY and the - * algorithm number PK->PUBKEY_ALGO and pass it to pubkey_encrypt - * which returns the encrypted value in the array ENC->DATA. - * This array has a size which depends on the used algorithm - * (e.g. 2 for Elgamal). We don't need frame anymore because we - * have everything now in enc->data which is the passed to - * build_packet() - */ - frame = encode_session_key (dek, pubkey_nbits (pk->pubkey_algo, - pk->pkey) ); - rc = pk_encrypt (pk->pubkey_algo, enc->data, frame, pk->pkey); - gcry_mpi_release (frame); - if( rc ) - log_error ("pubkey_encrypt failed: %s\n", gpg_strerror (rc) ); - else { - if( opt.verbose ) { - char *ustr = get_user_id_string_native (enc->keyid); - log_info(_("%s/%s encrypted for: \"%s\"\n"), - gcry_pk_algo_name (enc->pubkey_algo), - openpgp_cipher_algo_name (dek->algo), - ustr ); - xfree(ustr); - } - /* and write it */ - init_packet(&pkt); - pkt.pkttype = PKT_PUBKEY_ENC; - pkt.pkt.pubkey_enc = enc; - rc = build_packet( out, &pkt ); - if( rc ) - log_error("build_packet(pubkey_enc) failed: %s\n", g10_errstr(rc)); - } - free_pubkey_enc(enc); - if( rc ) - return rc; - } - return 0; -} - -void -encode_crypt_files(int nfiles, char **files, strlist_t remusr) -{ - int rc = 0; - - if (opt.outfile) - { - log_error(_("--output doesn't work for this command\n")); - return; - } - - if (!nfiles) - { - char line[2048]; - unsigned int lno = 0; - while ( fgets(line, DIM(line), stdin) ) - { - lno++; - if (!*line || line[strlen(line)-1] != '\n') - { - log_error("input line %u too long or missing LF\n", lno); - return; - } - line[strlen(line)-1] = '\0'; - print_file_status(STATUS_FILE_START, line, 2); - if ( (rc = encode_crypt(line, remusr, 0)) ) - log_error("encryption of `%s' failed: %s\n", - print_fname_stdin(line), g10_errstr(rc) ); - write_status( STATUS_FILE_DONE ); - } - } - else - { - while (nfiles--) - { - print_file_status(STATUS_FILE_START, *files, 2); - if ( (rc = encode_crypt(*files, remusr, 0)) ) - log_error("encryption of `%s' failed: %s\n", - print_fname_stdin(*files), g10_errstr(rc) ); - write_status( STATUS_FILE_DONE ); - files++; - } - } -} diff --git a/g10/encrypt.c b/g10/encrypt.c new file mode 100644 index 00000000..90a20652 --- /dev/null +++ b/g10/encrypt.c @@ -0,0 +1,957 @@ +/* encrypt.c - Main encryption driver + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + * 2006, 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "gpg.h" +#include "options.h" +#include "packet.h" +#include "status.h" +#include "iobuf.h" +#include "keydb.h" +#include "util.h" +#include "main.h" +#include "filter.h" +#include "trustdb.h" +#include "i18n.h" +#include "status.h" +#include "pkglue.h" + + +static int encrypt_simple( const char *filename, int mode, int use_seskey ); +static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out ); + +/**************** + * Encrypt FILENAME with only the symmetric cipher. Take input from + * stdin if FILENAME is NULL. + */ +int +encrypt_symmetric (const char *filename) +{ + return encrypt_simple( filename, 1, 0 ); +} + + +/**************** + * Encrypt FILENAME as a literal data packet only. Take input from + * stdin if FILENAME is NULL. + */ +int +encrypt_store (const char *filename) +{ + return encrypt_simple( filename, 0, 0 ); +} + + +static void +encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey) +{ + gcry_cipher_hd_t hd; + byte buf[33]; + + assert ( dek->keylen <= 32 ); + if (!*seskey) + { + *seskey=xmalloc_clear(sizeof(DEK)); + (*seskey)->keylen=dek->keylen; + (*seskey)->algo=dek->algo; + make_session_key(*seskey); + /*log_hexdump( "thekey", c->key, c->keylen );*/ + } + + /* The encrypted session key is prefixed with a one-octet algorithm id. */ + buf[0] = (*seskey)->algo; + memcpy( buf + 1, (*seskey)->key, (*seskey)->keylen ); + + /* We only pass already checked values to the following fucntion, + thus we consider any failure as fatal. */ + if (openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1)) + BUG (); + if (gcry_cipher_setkey (hd, dek->key, dek->keylen)) + BUG (); + gcry_cipher_setiv (hd, NULL, 0); + gcry_cipher_encrypt (hd, buf, (*seskey)->keylen + 1, NULL, 0); + gcry_cipher_close (hd); + + memcpy( enckey, buf, (*seskey)->keylen + 1 ); + wipememory( buf, sizeof buf ); /* burn key */ +} + + +/* We try very hard to use a MDC */ +static int +use_mdc(PK_LIST pk_list,int algo) +{ + /* RFC-1991 and 2440 don't have MDC */ + if(RFC1991 || RFC2440) + return 0; + + /* --force-mdc overrides --disable-mdc */ + if(opt.force_mdc) + return 1; + + if(opt.disable_mdc) + return 0; + + /* Do the keys really support MDC? */ + + if(select_mdc_from_pklist(pk_list)) + return 1; + + /* The keys don't support MDC, so now we do a bit of a hack - if any + of the AESes or TWOFISH are in the prefs, we assume that the user + can handle a MDC. This is valid for PGP 7, which can handle MDCs + though it will not generate them. 2440bis allows this, by the + way. */ + + if(select_algo_from_prefs(pk_list,PREFTYPE_SYM, + CIPHER_ALGO_AES,NULL)==CIPHER_ALGO_AES) + return 1; + + if(select_algo_from_prefs(pk_list,PREFTYPE_SYM, + CIPHER_ALGO_AES192,NULL)==CIPHER_ALGO_AES192) + return 1; + + if(select_algo_from_prefs(pk_list,PREFTYPE_SYM, + CIPHER_ALGO_AES256,NULL)==CIPHER_ALGO_AES256) + return 1; + + if(select_algo_from_prefs(pk_list,PREFTYPE_SYM, + CIPHER_ALGO_TWOFISH,NULL)==CIPHER_ALGO_TWOFISH) + return 1; + + /* Last try. Use MDC for the modern ciphers. */ + + if (openpgp_cipher_get_algo_blklen (algo) != 8) + return 1; + + if (opt.verbose) + warn_missing_mdc_from_pklist (pk_list); + + return 0; /* No MDC */ +} + + +/* We don't want to use use_seskey yet because older gnupg versions + can't handle it, and there isn't really any point unless we're + making a message that can be decrypted by a public key or + passphrase. */ +static int +encrypt_simple (const char *filename, int mode, int use_seskey) +{ + iobuf_t inp, out; + PACKET pkt; + PKT_plaintext *pt = NULL; + STRING2KEY *s2k = NULL; + byte enckey[33]; + int rc = 0; + int seskeylen = 0; + u32 filesize; + cipher_filter_context_t cfx; + armor_filter_context_t *afx = NULL; + compress_filter_context_t zfx; + text_filter_context_t tfx; + progress_filter_context_t *pfx; + int do_compress = !RFC1991 && default_compress_algo(); + + pfx = new_progress_context (); + memset( &cfx, 0, sizeof cfx); + memset( &zfx, 0, sizeof zfx); + memset( &tfx, 0, sizeof tfx); + init_packet(&pkt); + + /* Prepare iobufs. */ + inp = iobuf_open(filename); + if (inp) + iobuf_ioctl (inp,3,1,NULL); /* disable fd caching */ + if (inp && is_secured_file (iobuf_get_fd (inp))) + { + iobuf_close (inp); + inp = NULL; + errno = EPERM; + } + if (!inp) + { + rc = gpg_error_from_syserror (); + log_error(_("can't open `%s': %s\n"), filename? filename: "[stdin]", + strerror(errno) ); + release_progress_context (pfx); + return rc; + } + + handle_progress (pfx, inp, filename); + + if (opt.textmode) + iobuf_push_filter( inp, text_filter, &tfx ); + + /* Due the the fact that we use don't use an IV to encrypt the + session key we can't use the new mode with RFC1991 because it has + no S2K salt. RFC1991 always uses simple S2K. */ + if ( RFC1991 && use_seskey ) + use_seskey = 0; + + cfx.dek = NULL; + if ( mode ) + { + int canceled; + + s2k = xmalloc_clear( sizeof *s2k ); + s2k->mode = RFC1991? 0:opt.s2k_mode; + s2k->hash_algo = S2K_DIGEST_ALGO; + cfx.dek = passphrase_to_dek (NULL, 0, + default_cipher_algo(), s2k, 4, + NULL, &canceled); + if ( !cfx.dek || !cfx.dek->keylen ) + { + rc = gpg_error (canceled? GPG_ERR_CANCELED:GPG_ERR_INV_PASSPHRASE); + xfree (cfx.dek); + xfree (s2k); + iobuf_close (inp); + log_error (_("error creating passphrase: %s\n"), gpg_strerror (rc)); + release_progress_context (pfx); + return rc; + } + if (use_seskey && s2k->mode != 1 && s2k->mode != 3) + { + use_seskey = 0; + log_info (_("can't use a symmetric ESK packet " + "due to the S2K mode\n")); + } + + if ( use_seskey ) + { + DEK *dek = NULL; + + seskeylen = openpgp_cipher_get_algo_keylen (default_cipher_algo ()); + encrypt_seskey( cfx.dek, &dek, enckey ); + xfree( cfx.dek ); cfx.dek = dek; + } + + if (opt.verbose) + log_info(_("using cipher %s\n"), + openpgp_cipher_algo_name (cfx.dek->algo)); + + cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo); + } + + if (do_compress && cfx.dek && cfx.dek->use_mdc + && is_file_compressed(filename, &rc)) + { + if (opt.verbose) + log_info(_("`%s' already compressed\n"), filename); + do_compress = 0; + } + + if ( rc || (rc = open_outfile( filename, opt.armor? 1:0, &out ))) + { + iobuf_cancel (inp); + xfree (cfx.dek); + xfree (s2k); + release_progress_context (pfx); + return rc; + } + + if ( opt.armor ) + { + afx = new_armor_context (); + push_armor_filter (afx, out); + } + + if ( s2k && !RFC1991 ) + { + PKT_symkey_enc *enc = xmalloc_clear( sizeof *enc + seskeylen + 1 ); + enc->version = 4; + enc->cipher_algo = cfx.dek->algo; + enc->s2k = *s2k; + if ( use_seskey && seskeylen ) + { + enc->seskeylen = seskeylen + 1; /* algo id */ + memcpy (enc->seskey, enckey, seskeylen + 1 ); + } + pkt.pkttype = PKT_SYMKEY_ENC; + pkt.pkt.symkey_enc = enc; + if ((rc = build_packet( out, &pkt ))) + log_error("build symkey packet failed: %s\n", g10_errstr(rc) ); + xfree (enc); + } + + if (!opt.no_literal) + pt = setup_plaintext_name (filename, inp); + + /* Note that PGP 5 has problems decrypting symmetrically encrypted + data if the file length is in the inner packet. It works when + only partial length headers are use. In the past, we always used + partial body length here, but since PGP 2, PGP 6, and PGP 7 need + the file length, and nobody should be using PGP 5 nowadays + anyway, this is now set to the file length. Note also that this + only applies to the RFC-1991 style symmetric messages, and not + the RFC-2440 style. PGP 6 and 7 work with either partial length + or fixed length with the new style messages. */ + + if ( !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode ) + { + off_t tmpsize; + int overflow; + + if ( !(tmpsize = iobuf_get_filelength(inp, &overflow)) + && !overflow && opt.verbose) + log_info(_("WARNING: `%s' is an empty file\n"), filename ); + /* We can't encode the length of very large files because + OpenPGP uses only 32 bit for file sizes. So if the the + size of a file is larger than 2^32 minus some bytes for + packet headers, we switch to partial length encoding. */ + if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) ) + filesize = tmpsize; + else + filesize = 0; + } + else + filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ + + if (!opt.no_literal) + { + pt->timestamp = make_timestamp(); + pt->mode = opt.textmode? 't' : 'b'; + pt->len = filesize; + pt->new_ctb = !pt->len && !RFC1991; + pt->buf = inp; + pkt.pkttype = PKT_PLAINTEXT; + pkt.pkt.plaintext = pt; + cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0; + } + else + { + cfx.datalen = filesize && !do_compress ? filesize : 0; + pkt.pkttype = 0; + pkt.pkt.generic = NULL; + } + + /* Register the cipher filter. */ + if (mode) + iobuf_push_filter ( out, cipher_filter, &cfx ); + + /* Register the compress filter. */ + if ( do_compress ) + { + if (cfx.dek && cfx.dek->use_mdc) + zfx.new_ctb = 1; + push_compress_filter (out, &zfx, default_compress_algo()); + } + + /* Do the work. */ + if (!opt.no_literal) + { + if ( (rc = build_packet( out, &pkt )) ) + log_error("build_packet failed: %s\n", g10_errstr(rc) ); + } + else + { + /* User requested not to create a literal packet, so we copy the + plain data. */ + byte copy_buffer[4096]; + int bytes_copied; + while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1) + if ( (rc=iobuf_write(out, copy_buffer, bytes_copied)) ) { + log_error ("copying input to output failed: %s\n", + gpg_strerror (rc) ); + break; + } + wipememory (copy_buffer, 4096); /* burn buffer */ + } + + /* Finish the stuff. */ + iobuf_close (inp); + if (rc) + iobuf_cancel(out); + else + { + iobuf_close (out); /* fixme: check returncode */ + if (mode) + write_status ( STATUS_END_ENCRYPTION ); + } + if (pt) + pt->buf = NULL; + free_packet (&pkt); + xfree (cfx.dek); + xfree (s2k); + release_armor_context (afx); + release_progress_context (pfx); + return rc; +} + + +int +setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek) +{ + int canceled; + + *symkey_s2k=xmalloc_clear(sizeof(STRING2KEY)); + (*symkey_s2k)->mode = opt.s2k_mode; + (*symkey_s2k)->hash_algo = S2K_DIGEST_ALGO; + + *symkey_dek=passphrase_to_dek(NULL,0,opt.s2k_cipher_algo, + *symkey_s2k, 4, NULL, &canceled); + if(!*symkey_dek || !(*symkey_dek)->keylen) + { + xfree(*symkey_dek); + xfree(*symkey_s2k); + return gpg_error (canceled?GPG_ERR_CANCELED:GPG_ERR_BAD_PASSPHRASE); + } + + return 0; +} + + +static int +write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek, + iobuf_t out) +{ + int rc, seskeylen = openpgp_cipher_get_algo_keylen (dek->algo); + + PKT_symkey_enc *enc; + byte enckey[33]; + PACKET pkt; + + enc=xmalloc_clear(sizeof(PKT_symkey_enc)+seskeylen+1); + encrypt_seskey(symkey_dek,&dek,enckey); + + enc->version = 4; + enc->cipher_algo = opt.s2k_cipher_algo; + enc->s2k = *symkey_s2k; + enc->seskeylen = seskeylen + 1; /* algo id */ + memcpy( enc->seskey, enckey, seskeylen + 1 ); + + pkt.pkttype = PKT_SYMKEY_ENC; + pkt.pkt.symkey_enc = enc; + + if ((rc=build_packet(out,&pkt))) + log_error("build symkey_enc packet failed: %s\n",g10_errstr(rc)); + + xfree(enc); + return rc; +} + + +/* + * Encrypt the file with the given userids (or ask if none + * is supplied). + */ +int +encrypt_crypt (const char *filename, strlist_t remusr, int use_symkey) +{ + iobuf_t inp = NULL; + iobuf_t out = NULL; + PACKET pkt; + PKT_plaintext *pt = NULL; + DEK *symkey_dek = NULL; + STRING2KEY *symkey_s2k = NULL; + int rc = 0, rc2 = 0; + u32 filesize; + cipher_filter_context_t cfx; + armor_filter_context_t *afx = NULL; + compress_filter_context_t zfx; + text_filter_context_t tfx; + progress_filter_context_t *pfx; + PK_LIST pk_list, work_list; + int do_compress; + + do_compress = opt.compress_algo && !RFC1991; + + pfx = new_progress_context (); + memset( &cfx, 0, sizeof cfx); + memset( &zfx, 0, sizeof zfx); + memset( &tfx, 0, sizeof tfx); + init_packet(&pkt); + + if (use_symkey + && (rc=setup_symkey(&symkey_s2k,&symkey_dek))) + { + release_progress_context (pfx); + return rc; + } + + if ((rc = build_pk_list (remusr, &pk_list, PUBKEY_USAGE_ENC))) + { + release_progress_context (pfx); + return rc; + } + + if(PGP2) + { + for (work_list=pk_list; work_list; work_list=work_list->next) + if (!(is_RSA (work_list->pk->pubkey_algo) + && nbits_from_pk (work_list->pk) <= 2048)) + { + log_info(_("you can only encrypt to RSA keys of 2048 bits or " + "less in --pgp2 mode\n")); + compliance_failure(); + break; + } + } + + /* Prepare iobufs. */ + inp = iobuf_open(filename); + if (inp) + iobuf_ioctl (inp, 3, 1, NULL); /* Disable fd caching. */ + if (inp && is_secured_file (iobuf_get_fd (inp))) + { + iobuf_close (inp); + inp = NULL; + errno = EPERM; + } + if (!inp) + { + rc = gpg_error_from_syserror (); + log_error (_("can't open `%s': %s\n"), + filename? filename: "[stdin]", gpg_strerror (rc) ); + goto leave; + } + else if (opt.verbose) + log_info (_("reading from `%s'\n"), filename? filename: "[stdin]"); + + handle_progress (pfx, inp, filename); + + if (opt.textmode) + iobuf_push_filter (inp, text_filter, &tfx); + + if ((rc = open_outfile( filename, opt.armor? 1:0, &out ))) + goto leave; + + if (opt.armor) + { + afx = new_armor_context (); + push_armor_filter (afx, out); + } + + /* Create a session key. */ + cfx.dek = xmalloc_secure_clear (sizeof *cfx.dek); + if (!opt.def_cipher_algo) + { + /* Try to get it from the prefs. */ + cfx.dek->algo = select_algo_from_prefs (pk_list, PREFTYPE_SYM, -1, NULL); + /* The only way select_algo_from_prefs can fail here is when + mixing v3 and v4 keys, as v4 keys have an implicit preference + entry for 3DES, and the pk_list cannot be empty. In this + case, use 3DES anyway as it's the safest choice - perhaps the + v3 key is being used in an OpenPGP implementation and we know + that the implementation behind any v4 key can handle 3DES. */ + if (cfx.dek->algo == -1) + { + cfx.dek->algo = CIPHER_ALGO_3DES; + + if (PGP2) + { + log_info(_("unable to use the IDEA cipher for all of the keys " + "you are encrypting to.\n")); + compliance_failure(); + } + } + + /* In case 3DES has been selected, print a warning if any key + does not have a preference for AES. This should help to + indentify why encrypting to several recipients falls back to + 3DES. */ + if (opt.verbose && cfx.dek->algo == CIPHER_ALGO_3DES) + warn_missing_aes_from_pklist (pk_list); + } + else + { + if (!opt.expert + && (select_algo_from_prefs (pk_list, PREFTYPE_SYM, + opt.def_cipher_algo, NULL) + != opt.def_cipher_algo)) + { + log_info(_("WARNING: forcing symmetric cipher %s (%d)" + " violates recipient preferences\n"), + openpgp_cipher_algo_name (opt.def_cipher_algo), + opt.def_cipher_algo); + } + + cfx.dek->algo = opt.def_cipher_algo; + } + + cfx.dek->use_mdc = use_mdc (pk_list,cfx.dek->algo); + + /* Only do the is-file-already-compressed check if we are using a + MDC. This forces compressed files to be re-compressed if we do + not have a MDC to give some protection against chosen ciphertext + attacks. */ + + if (do_compress && cfx.dek->use_mdc && is_file_compressed(filename, &rc2)) + { + if (opt.verbose) + log_info(_("`%s' already compressed\n"), filename); + do_compress = 0; + } + if (rc2) + { + rc = rc2; + goto leave; + } + + make_session_key (cfx.dek); + if (DBG_CIPHER) + log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen ); + + rc = write_pubkey_enc_from_list (pk_list, cfx.dek, out); + if (rc) + goto leave; + + /* We put the passphrase (if any) after any public keys as this + seems to be the most useful on the recipient side - there is no + point in prompting a user for a passphrase if they have the + secret key needed to decrypt. */ + if(use_symkey && (rc = write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out))) + goto leave; + + if (!opt.no_literal) + pt = setup_plaintext_name (filename, inp); + + if (!iobuf_is_pipe_filename (filename) && *filename && !opt.textmode ) + { + off_t tmpsize; + int overflow; + + if ( !(tmpsize = iobuf_get_filelength(inp, &overflow)) + && !overflow && opt.verbose) + log_info(_("WARNING: `%s' is an empty file\n"), filename ); + /* We can't encode the length of very large files because + OpenPGP uses only 32 bit for file sizes. So if the the size + of a file is larger than 2^32 minus some bytes for packet + headers, we switch to partial length encoding. */ + if (tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) ) + filesize = tmpsize; + else + filesize = 0; + } + else + filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ + + if (!opt.no_literal) + { + pt->timestamp = make_timestamp(); + pt->mode = opt.textmode ? 't' : 'b'; + pt->len = filesize; + pt->new_ctb = !pt->len && !RFC1991; + pt->buf = inp; + pkt.pkttype = PKT_PLAINTEXT; + pkt.pkt.plaintext = pt; + cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0; + } + else + cfx.datalen = filesize && !do_compress ? filesize : 0; + + /* Register the cipher filter. */ + iobuf_push_filter (out, cipher_filter, &cfx); + + /* Register the compress filter. */ + if (do_compress) + { + int compr_algo = opt.compress_algo; + + if (compr_algo == -1) + { + compr_algo = select_algo_from_prefs (pk_list, PREFTYPE_ZIP, -1, NULL); + if (compr_algo == -1) + compr_algo = DEFAULT_COMPRESS_ALGO; + /* Theoretically impossible to get here since uncompressed + is implicit. */ + } + else if (!opt.expert + && select_algo_from_prefs(pk_list, PREFTYPE_ZIP, + compr_algo, NULL) != compr_algo) + { + log_info (_("WARNING: forcing compression algorithm %s (%d)" + " violates recipient preferences\n"), + compress_algo_to_string(compr_algo), compr_algo); + } + + /* Algo 0 means no compression. */ + if (compr_algo) + { + if (cfx.dek && cfx.dek->use_mdc) + zfx.new_ctb = 1; + push_compress_filter (out,&zfx,compr_algo); + } + } + + /* Do the work. */ + if (!opt.no_literal) + { + if ((rc = build_packet( out, &pkt ))) + log_error ("build_packet failed: %s\n", g10_errstr(rc)); + } + else + { + /* User requested not to create a literal packet, so we copy the + plain data. */ + byte copy_buffer[4096]; + int bytes_copied; + while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1) + if ((rc=iobuf_write(out, copy_buffer, bytes_copied))) + { + log_error ("copying input to output failed: %s\n", + gpg_strerror (rc)); + break; + } + wipememory (copy_buffer, 4096); /* Burn the buffer. */ + } + + /* Finish the stuff. */ + leave: + iobuf_close (inp); + if (rc) + iobuf_cancel (out); + else + { + iobuf_close (out); /* fixme: check returncode */ + write_status (STATUS_END_ENCRYPTION); + } + if (pt) + pt->buf = NULL; + free_packet (&pkt); + xfree (cfx.dek); + xfree (symkey_dek); + xfree (symkey_s2k); + release_pk_list (pk_list); + release_armor_context (afx); + release_progress_context (pfx); + return rc; +} + + +/* + * Filter to do a complete public key encryption. + */ +int +encrypt_filter (void *opaque, int control, + iobuf_t a, byte *buf, size_t *ret_len) +{ + size_t size = *ret_len; + encrypt_filter_context_t *efx = opaque; + int rc = 0; + + if (control == IOBUFCTRL_UNDERFLOW) /* decrypt */ + { + BUG(); /* not used */ + } + else if ( control == IOBUFCTRL_FLUSH ) /* encrypt */ + { + if ( !efx->header_okay ) + { + efx->cfx.dek = xmalloc_secure_clear ( sizeof *efx->cfx.dek ); + if ( !opt.def_cipher_algo ) + { + /* Try to get it from the prefs. */ + efx->cfx.dek->algo = + select_algo_from_prefs (efx->pk_list, PREFTYPE_SYM, -1, NULL); + if (efx->cfx.dek->algo == -1 ) + { + /* Because 3DES is implicitly in the prefs, this can + only happen if we do not have any public keys in + the list. */ + efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO; + } + + /* In case 3DES has been selected, print a warning if + any key does not have a preference for AES. This + should help to indentify why encrypting to several + recipients falls back to 3DES. */ + if (opt.verbose + && efx->cfx.dek->algo == CIPHER_ALGO_3DES) + warn_missing_aes_from_pklist (efx->pk_list); + } + else + { + if (!opt.expert + && select_algo_from_prefs (efx->pk_list,PREFTYPE_SYM, + opt.def_cipher_algo, + NULL) != opt.def_cipher_algo) + log_info(_("forcing symmetric cipher %s (%d) " + "violates recipient preferences\n"), + openpgp_cipher_algo_name (opt.def_cipher_algo), + opt.def_cipher_algo); + + efx->cfx.dek->algo = opt.def_cipher_algo; + } + + efx->cfx.dek->use_mdc = use_mdc (efx->pk_list,efx->cfx.dek->algo); + + make_session_key ( efx->cfx.dek ); + if (DBG_CIPHER) + log_printhex ("DEK is: ", efx->cfx.dek->key, efx->cfx.dek->keylen); + + rc = write_pubkey_enc_from_list (efx->pk_list, efx->cfx.dek, a); + if (rc) + return rc; + + if(efx->symkey_s2k && efx->symkey_dek) + { + rc=write_symkey_enc(efx->symkey_s2k,efx->symkey_dek, + efx->cfx.dek,a); + if(rc) + return rc; + } + + iobuf_push_filter (a, cipher_filter, &efx->cfx); + + efx->header_okay = 1; + } + rc = iobuf_write (a, buf, size); + + } + else if (control == IOBUFCTRL_FREE) + { + xfree (efx->symkey_dek); + xfree (efx->symkey_s2k); + } + else if ( control == IOBUFCTRL_DESC ) + { + *(char**)buf = "encrypt_filter"; + } + return rc; +} + + +/* + * Write pubkey-enc packets from the list of PKs to OUT. + */ +static int +write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out) +{ + PACKET pkt; + PKT_public_key *pk; + PKT_pubkey_enc *enc; + int rc; + + for ( ; pk_list; pk_list = pk_list->next ) + { + gcry_mpi_t frame; + + pk = pk_list->pk; + + print_pubkey_algo_note ( pk->pubkey_algo ); + enc = xmalloc_clear ( sizeof *enc ); + enc->pubkey_algo = pk->pubkey_algo; + keyid_from_pk( pk, enc->keyid ); + enc->throw_keyid = (opt.throw_keyid || (pk_list->flags&1)); + + if (opt.throw_keyid && (PGP2 || PGP6 || PGP7 || PGP8)) + { + log_info(_("you may not use %s while in %s mode\n"), + "--throw-keyid",compliance_option_string()); + compliance_failure(); + } + + /* Okay, what's going on: We have the session key somewhere in + * the structure DEK and want to encode this session key in an + * integer value of n bits. pubkey_nbits gives us the number of + * bits we have to use. We then encode the session key in some + * way and we get it back in the big intger value FRAME. Then + * we use FRAME, the public key PK->PKEY and the algorithm + * number PK->PUBKEY_ALGO and pass it to pubkey_encrypt which + * returns the encrypted value in the array ENC->DATA. This + * array has a size which depends on the used algorithm (e.g. 2 + * for Elgamal). We don't need frame anymore because we have + * everything now in enc->data which is the passed to + * build_packet(). */ + frame = encode_session_key (dek, + pubkey_nbits (pk->pubkey_algo, pk->pkey)); + rc = pk_encrypt (pk->pubkey_algo, enc->data, frame, pk->pkey); + gcry_mpi_release (frame); + if (rc) + log_error ("pubkey_encrypt failed: %s\n", gpg_strerror (rc) ); + else + { + if ( opt.verbose ) + { + char *ustr = get_user_id_string_native (enc->keyid); + log_info (_("%s/%s encrypted for: \"%s\"\n"), + gcry_pk_algo_name (enc->pubkey_algo), + openpgp_cipher_algo_name (dek->algo), + ustr ); + xfree (ustr); + } + /* And write it. */ + init_packet (&pkt); + pkt.pkttype = PKT_PUBKEY_ENC; + pkt.pkt.pubkey_enc = enc; + rc = build_packet (out, &pkt); + if (rc) + log_error ("build_packet(pubkey_enc) failed: %s\n", + g10_errstr (rc)); + } + free_pubkey_enc(enc); + if (rc) + return rc; + } + return 0; +} + + +void +encrypt_crypt_files (int nfiles, char **files, strlist_t remusr) +{ + int rc = 0; + + if (opt.outfile) + { + log_error(_("--output doesn't work for this command\n")); + return; + } + + if (!nfiles) + { + char line[2048]; + unsigned int lno = 0; + while ( fgets(line, DIM(line), stdin) ) + { + lno++; + if (!*line || line[strlen(line)-1] != '\n') + { + log_error("input line %u too long or missing LF\n", lno); + return; + } + line[strlen(line)-1] = '\0'; + print_file_status(STATUS_FILE_START, line, 2); + if ( (rc = encrypt_crypt(line, remusr, 0)) ) + log_error("encryption of `%s' failed: %s\n", + print_fname_stdin(line), g10_errstr(rc) ); + write_status( STATUS_FILE_DONE ); + } + } + else + { + while (nfiles--) + { + print_file_status(STATUS_FILE_START, *files, 2); + if ( (rc = encrypt_crypt(*files, remusr, 0)) ) + log_error("encryption of `%s' failed: %s\n", + print_fname_stdin(*files), g10_errstr(rc) ); + write_status( STATUS_FILE_DONE ); + files++; + } + } +} diff --git a/g10/gpg.c b/g10/gpg.c index 80072fae..6771986d 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2059,9 +2059,9 @@ main (int argc, char **argv) malloc_hooks.realloc = gcry_realloc; malloc_hooks.free = gcry_free; assuan_set_malloc_hooks (&malloc_hooks); + assuan_set_assuan_log_prefix (log_get_prefix (NULL)); assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); - /* Try for a version specific config file first */ default_configname = get_default_configname (); if (default_config) @@ -3418,26 +3418,26 @@ main (int argc, char **argv) case aStore: /* only store the file */ if( argc > 1 ) wrong_args(_("--store [filename]")); - if( (rc = encode_store(fname)) ) + if( (rc = encrypt_store(fname)) ) log_error ("storing `%s' failed: %s\n", print_fname_stdin(fname),g10_errstr(rc) ); break; case aSym: /* encrypt the given file only with the symmetric cipher */ if( argc > 1 ) wrong_args(_("--symmetric [filename]")); - if( (rc = encode_symmetric(fname)) ) + if( (rc = encrypt_symmetric(fname)) ) log_error (_("symmetric encryption of `%s' failed: %s\n"), print_fname_stdin(fname),g10_errstr(rc) ); break; case aEncr: /* encrypt the given file */ if(multifile) - encode_crypt_files(argc, argv, remusr); + encrypt_crypt_files(argc, argv, remusr); else { if( argc > 1 ) wrong_args(_("--encrypt [filename]")); - if( (rc = encode_crypt(fname,remusr,0)) ) + if( (rc = encrypt_crypt(fname,remusr,0)) ) log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) ); } @@ -3458,7 +3458,7 @@ main (int argc, char **argv) " while in %s mode\n"),compliance_option_string()); else { - if( (rc = encode_crypt(fname,remusr,1)) ) + if( (rc = encrypt_crypt(fname,remusr,1)) ) log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) ); } diff --git a/g10/main.h b/g10/main.h index d46c0ff9..4ed878d6 100644 --- a/g10/main.h +++ b/g10/main.h @@ -182,12 +182,12 @@ int cpr_get_answer_okay_cancel (const char *keyword, void display_online_help( const char *keyword ); /*-- encode.c --*/ -int setup_symkey(STRING2KEY **symkey_s2k,DEK **symkey_dek); -int encode_symmetric( const char *filename ); -int encode_store( const char *filename ); -int encode_crypt( const char *filename, strlist_t remusr, int use_symkey ); -void encode_crypt_files(int nfiles, char **files, strlist_t remusr); -int encrypt_filter( void *opaque, int control, +int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek); +int encrypt_symmetric (const char *filename ); +int encrypt_store (const char *filename ); +int encrypt_crypt (const char *filename, strlist_t remusr, int use_symkey ); +void encrypt_crypt_files (int nfiles, char **files, strlist_t remusr); +int encrypt_filter (void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len); diff --git a/g10/pkglue.c b/g10/pkglue.c index 90f8f248..cbfe21ea 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -61,7 +61,7 @@ pk_sign (int algo, gcry_mpi_t * data, gcry_mpi_t hash, gcry_mpi_t * skey) "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", skey[0], skey[1], skey[2], skey[3], skey[4]); } - else if (algo == GCRY_PK_RSA) + else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S) { rc = gcry_sexp_build (&s_skey, NULL, "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", @@ -90,7 +90,7 @@ pk_sign (int algo, gcry_mpi_t * data, gcry_mpi_t hash, gcry_mpi_t * skey) if (rc) ; - else if (algo == GCRY_PK_RSA) + else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S) data[0] = mpi_from_sexp (s_sig, "s"); else { @@ -125,7 +125,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey) "(public-key(elg(p%m)(g%m)(y%m)))", pkey[0], pkey[1], pkey[2]); } - else if (algo == GCRY_PK_RSA) + else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S) { rc = gcry_sexp_build (&s_pkey, NULL, "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]); @@ -158,7 +158,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey) rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(elg(r%m)(s%m)))", data[0], data[1]); } - else if (algo == GCRY_PK_RSA) + else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S) { if (!data[0]) rc = gpg_error (GPG_ERR_BAD_MPI); @@ -197,7 +197,7 @@ pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, gcry_mpi_t * pkey) "(public-key(elg(p%m)(g%m)(y%m)))", pkey[0], pkey[1], pkey[2]); } - else if (algo == GCRY_PK_RSA) + else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_E) { rc = gcry_sexp_build (&s_pkey, NULL, "(public-key(rsa(n%m)(e%m)))", @@ -223,7 +223,7 @@ pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, gcry_mpi_t * pkey) else { /* add better error handling or make gnupg use S-Exp directly */ resarr[0] = mpi_from_sexp (s_ciph, "a"); - if (algo != GCRY_PK_RSA) + if (algo != GCRY_PK_RSA && algo != GCRY_PK_RSA_E) resarr[1] = mpi_from_sexp (s_ciph, "b"); } @@ -252,7 +252,7 @@ pk_decrypt (int algo, gcry_mpi_t * result, gcry_mpi_t * data, "(private-key(elg(p%m)(g%m)(y%m)(x%m)))", skey[0], skey[1], skey[2], skey[3]); } - else if (algo == GCRY_PK_RSA) + else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_E) { rc = gcry_sexp_build (&s_skey, NULL, "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", @@ -274,7 +274,7 @@ pk_decrypt (int algo, gcry_mpi_t * result, gcry_mpi_t * data, rc = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))", data[0], data[1]); } - else if (algo == GCRY_PK_RSA) + else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_E) { if (!data[0]) rc = gpg_error (GPG_ERR_BAD_MPI); @@ -321,7 +321,8 @@ pk_check_secret_key (int algo, gcry_mpi_t *skey) "(private-key(elg(p%m)(g%m)(y%m)(x%m)))", skey[0], skey[1], skey[2], skey[3]); } - else if (algo == GCRY_PK_RSA) + else if (algo == GCRY_PK_RSA + || algo == GCRY_PK_RSA_S || algo == GCRY_PK_RSA_E) { rc = gcry_sexp_build (&s_skey, NULL, "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", diff --git a/g10/server.c b/g10/server.c index cc502e8e..b2285955 100644 --- a/g10/server.c +++ b/g10/server.c @@ -540,18 +540,18 @@ gpg_server (ctrl_t ctrl) char *tmp = NULL; const char *s1 = getenv ("GPG_AGENT_INFO"); - if (asprintf (&tmp, - "Home: %s\n" - "Config: %s\n" - "AgentInfo: %s\n" - "%s", - opt.homedir, - "fixme: need config filename", - s1?s1:"[not set]", - hello) > 0) + tmp = xtryasprintf ("Home: %s\n" + "Config: %s\n" + "AgentInfo: %s\n" + "%s", + opt.homedir, + "fixme: need config filename", + s1?s1:"[not set]", + hello); + if (tmp) { assuan_set_hello_line (ctx, tmp); - free (tmp); + xfree (tmp); } } else diff --git a/g10/trustdb.c b/g10/trustdb.c index 1d083a73..2db97152 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1176,12 +1176,15 @@ get_validity (PKT_public_key *pk, PKT_user_id *uid) int get_validity_info (PKT_public_key *pk, PKT_user_id *uid) { - int trustlevel; - - trustlevel = get_validity (pk, uid); - if( trustlevel & TRUST_FLAG_REVOKED ) - return 'r'; - return trust_letter ( trustlevel ); + int trustlevel; + + if (!pk) + return '?'; /* Just in case a NULL PK is passed. */ + + trustlevel = get_validity (pk, uid); + if ( (trustlevel & TRUST_FLAG_REVOKED) ) + return 'r'; + return trust_letter (trustlevel); } const char * @@ -1189,6 +1192,9 @@ get_validity_string (PKT_public_key *pk, PKT_user_id *uid) { int trustlevel; + if (!pk) + return "err"; /* Just in case a NULL PK is passed. */ + trustlevel = get_validity (pk, uid); if( trustlevel & TRUST_FLAG_REVOKED ) return _("revoked"); -- 2.11.4.GIT