aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/ChangeLog8948
-rw-r--r--g10/Makefile.am121
-rw-r--r--g10/OPTIONS24
-rw-r--r--g10/armor.c1334
-rw-r--r--g10/build-packet.c1203
-rw-r--r--g10/call-agent.c893
-rw-r--r--g10/call-agent.h94
-rw-r--r--g10/card-util.c884
-rw-r--r--g10/cipher.c165
-rw-r--r--g10/comment.c112
-rw-r--r--g10/compress.c329
-rw-r--r--g10/dearmor.c123
-rw-r--r--g10/decrypt.c142
-rw-r--r--g10/delkey.c209
-rw-r--r--g10/encode.c821
-rw-r--r--g10/encr-data.c269
-rw-r--r--g10/exec.c619
-rw-r--r--g10/exec.h43
-rw-r--r--g10/export.c546
-rw-r--r--g10/filter.h155
-rw-r--r--g10/free-packet.c542
-rw-r--r--g10/g10.c3367
-rw-r--r--g10/getkey.c2618
-rw-r--r--g10/global.h31
-rw-r--r--g10/gpg.h38
-rw-r--r--g10/gpgv.c389
-rw-r--r--g10/helptext.c316
-rw-r--r--g10/import.c1906
-rw-r--r--g10/kbnode.c401
-rw-r--r--g10/keydb.c725
-rw-r--r--g10/keydb.h283
-rw-r--r--g10/keyedit.c3856
-rw-r--r--g10/keygen.c2916
-rw-r--r--g10/keyid.c609
-rw-r--r--g10/keylist.c1466
-rw-r--r--g10/keyring.c1588
-rw-r--r--g10/keyring.h46
-rw-r--r--g10/keyserver-internal.h21
-rw-r--r--g10/keyserver.c1381
-rw-r--r--g10/main.h272
-rw-r--r--g10/mainproc.c1758
-rw-r--r--g10/mdfilter.c76
-rw-r--r--g10/misc.c1000
-rw-r--r--g10/mkdtemp.c98
-rw-r--r--g10/openfile.c391
-rw-r--r--g10/options.h255
-rw-r--r--g10/options.skel212
-rw-r--r--g10/packet.h514
-rw-r--r--g10/parse-packet.c2332
-rw-r--r--g10/passphrase.c1237
-rw-r--r--g10/photoid.c333
-rw-r--r--g10/photoid.h34
-rw-r--r--g10/pipemode.c317
-rw-r--r--g10/pkclist.c1372
-rw-r--r--g10/pkglue.c342
-rw-r--r--g10/pkglue.h35
-rw-r--r--g10/plaintext.c458
-rw-r--r--g10/progress.c118
-rw-r--r--g10/pubkey-enc.c345
-rw-r--r--g10/pubring.asc458
-rw-r--r--g10/revoke.c690
-rw-r--r--g10/seckey-cert.c452
-rw-r--r--g10/seskey.c244
-rw-r--r--g10/sig-check.c575
-rw-r--r--g10/sign.c1412
-rw-r--r--g10/signal.c226
-rw-r--r--g10/skclist.c176
-rw-r--r--g10/status.c472
-rw-r--r--g10/status.h124
-rw-r--r--g10/tdbdump.c223
-rw-r--r--g10/tdbio.c1636
-rw-r--r--g10/tdbio.h117
-rw-r--r--g10/textfilter.c235
-rw-r--r--g10/trustdb.c2158
-rw-r--r--g10/trustdb.h86
-rw-r--r--g10/verify.c197
76 files changed, 0 insertions, 60513 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
deleted file mode 100644
index 0e87c2f46..000000000
--- a/g10/ChangeLog
+++ /dev/null
@@ -1,8948 +0,0 @@
-2004-04-30 Werner Koch <[email protected]>
-
- * g10.c (main) <gpgconf>: Use gpg.conf and not /dev/null as
- default filename.
-
-2004-04-28 Werner Koch <[email protected]>
-
- * card-util.c (card_edit): Remove PIN verification.
- (generate_card_keys): New arg SERIALNO. Do PIN verification here
- after resetting forced_chv1.
-
-2004-04-26 Werner Koch <[email protected]>
-
- * card-util.c (change_name): Check that the NAME is not too long.
- (change_url): Likewise.
- (change_login): Likewise.
-
-2004-03-23 Werner Koch <[email protected]>
-
- * g10.c: New options --gpgconf-list, --debug-level and --log-file
- (set_debug): Add arg DEBUG_LEVEL.
- (main): Look at less and less version specific config files. From
- gnupg 1.3.
-
-2004-02-17 Werner Koch <[email protected]>
-
- * call-agent.c (start_agent): Ignore an empty GPG_AGENT_INFO.
- * passphrase.c (agent_open): Ditto.
-
-2004-02-12 Werner Koch <[email protected]>
-
- * gpgv.c: Removed g10defs.h.
-
- * Makefile.am: Include cmacros.am for common flags.
-
-2004-02-11 Werner Koch <[email protected]>
-
- * openfile.c (try_make_homedir): Use GNUPG_DEFAULT_HOMEDIR.
- * gpgv.c (main): Ditto.
- * g10.c (main): Ditto.
-
-2004-01-19 Moritz Schulte <[email protected]>
-
- * keygen.c (do_generate_keypair): Print member fname, instead of
- newfname, again.
- (do_generate_keypair): Don't try to execute certain pieces of code
- in case an error occured.
- (gen_card_key): Don't print out a message, which is already
- printed by do_generate_keypair().
-
-2004-01-18 Moritz Schulte <[email protected]>
-
- * keygen.c (do_generate_keypair): Print member fname, instead of
- newfname.
-
-2003-12-17 Werner Koch <[email protected]>
-
- * card-util.c (print_name): Fixed bad format string usage.
- (print_isoname): Ditto.
-
- * trustdb.c (check_regexp): s/exp/expr/.
-
- * 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.
-
- * tdbio.c (upd_hashtable, drop_from_hashtable, lookup_hashtable):
- Fixed log_error format string bugs. Kudos to the now working
- gcc-3.3 -Wformat-nonliteral and Florian Weimer's investigations in
- gnupg 1.2.3.
-
-2003-12-15 Werner Koch <[email protected]>
-
- * seckey-cert.c (protect_secret_key): Use gry_create_nonce for the
- IV; there is not need for real strong random here and it even
- better protect the random bits used for the key.
-
-2003-11-16 Moritz Schulte <[email protected]>
-
- * signal.c: Removed unused file.
-
-2003-11-10 Moritz Schulte <[email protected]>
-
- * Makefile.am (INCLUDES): Added: @LIBGCRYPT_CFLAGS@.
-
-2003-10-25 Werner Koch <[email protected]>
-
- * call-agent.c (learn_status_cb, scd_genkey_cb): Fixed faulty use
- of !spacep().
-
-2003-10-20 Werner Koch <[email protected]>
-
- * card-util.c (card_edit): New command "passwd". Add logic to
- check the PIN in advance.
- (card_status): Add new args to return the serial number. Changed
- all callers.
- * call-agent.c (agent_scd_checkpin): New.
-
-2003-10-08 Werner Koch <[email protected]>
-
- * call-agent.c (agent_scd_getattr): Don't clear the passed info
- structure, so that it can indeed be updated.
-
- * card-util.c (fpr_is_zero): New.
- (generate_card_keys): New.
- (card_edit): New command "generate".
- * keygen.c (generate_keypair): New arg CARD_SERIALNO, removed call
- to check_smartcard.
- (check_smartcard,show_smartcard): Removed.
- (show_sha1_fpr,fpr_is_zero): Removed.
-
-2003-10-01 Werner Koch <[email protected]>
-
- * card-util.c: Tweaked to use this source also under 1.3.
-
-2003-09-30 Werner Koch <[email protected]>
-
- * keylist.c (print_card_serialno): New.
- (list_keyblock_print): Use it here.
-
- * 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.
-
-2003-09-27 Werner Koch <[email protected]>
-
- * sign.c (do_sign): Removed disabled testcode.
-
-2003-09-26 Timo Schulz <[email protected]>
-
- * card_status (card_status): Do not use fputs since the fp
- parameter can be NULL. This fixes a segv.
-
-2003-09-24 Werner Koch <[email protected]>
-
- * card-util.c (print_isoname,card_status): Handle opt.with_colons.
- (print_sha1_fpr_colon): New.
-
-2003-09-23 Werner Koch <[email protected]>
-
- 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.
- * g10.c (print_hex,print_mds): Ditto.
- * pkclist.c (algo_available): Ditto.
-
- * armor.c (armor_filter): Allow using --comment multiple times to
- get multiple Comment header lines. --no-comments resets list.
- * options.h, g10.c (main): Ditto. Deprecate --default-comment in
- favor of --no-comments.
-
- * g10.c (main): Trim --help to commonly used options. Remove -f.
-
- * g10.c (main): Add --multifile as an alias to turn --encrypt into
- --encrypt-files (plus --verify-files, --decrypt-files). Error out
- if --multifile is used with the commands that don't support it yet.
-
- * 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.
-
- * main.h, keygen.c (keygen_add_keyserver_url): Signature callback
- for adding a keyserver URL.
- * keyedit.c (keyedit_menu, menu_set_keyserver_url): New command to
- set preferred keyserver to specified (or all) user IDs.
- * build-packet.c (build_sig_subpkt): Set preferred keyserver flag
- while building a preferred keyserver subpacket.
-
- * keylist.c (show_policy_url, show_keyserver_url): URLs might be
- UTF8.
-
- * keyedit.c (menu_addrevoker): Fix leaking a few bytes.
-
- * keyedit.c (show_key_with_all_names): Use list-option
- show-long-keyid in main --edit-key display.
-
- * keyedit.c (print_and_check_one_sig): Use list-option
- show-long-keyid in --edit-key "check" function.
-
- * passphrase.c (agent_send_all_options): Make use of $GPG_TTY.
-
- * g10.c (main): Disable use-agent if passphrase-fd is given
- later. Suggested by Kurt Garloff.
-
- * exec.c, g10.c, gpgv.c, passphrase.c, photoid.c:
- s/__MINGW32__/_WIN32/ to help building on native Windows
- compilers. Requested by Brian Gladman. From Werner on stable
- branch.
-
- * options.h, g10.c (main): Add list-option
- list-preferred-keyserver.
-
- * keyedit.c (change_passphrase): When responding 'no' to the blank
- passphrase question, re-prompt for a new passphrase. This is bug
- #202.
-
- * mainproc.c (check_sig_and_print): Use two different preferred
- keyserver displays - one if the key is not present (to tell the
- user where to get the key), the other if it is present (to tell
- the user where the key can be refreshed).
-
- * packet.h, parse-packet.c (parse_signature): Set flag if a
- preferred keyserver is present.
-
- * keylist.c (list_keyblock_print): Show keyserver url in listings
- with list-option show-keyserver-url.
-
- * mainproc.c (check_sig_and_print): Get the uid validity before
- printing any sig results to avoid munging the output with trustdb
- warnings.
-
- * g10.c (main): Don't include --show-keyring in --help as it is
- deprecated.
-
- * options.skel: Note that keyserver.pgp.com isn't synchronized,
- and explain the roundrobin a bit better.
-
- * sig-check.c (check_key_signature2), import.c (import_one,
- import_revoke_cert, chk_self_sigs, delete_inv_parts,
- collapse_uids, merge_blocks): Make much quieter during import of
- slightly munged, but recoverable, keys. Use log_error for
- unrecoverable import failures.
-
- * keyring.c (keyring_rebuild_cache): Comment.
-
- * sign.c (mk_notation_and_policy): Making a v3 signature with
- notations or policy urls is an error, not an info (i.e. increment
- the errorcount). Don't print the notation or policy url to stdout
- since it can be mixed into the output stream when piping and munge
- the stream.
-
- * packet.h, sig-check.c (signature_check2, do_check,
- do_check_messages): Provide a signing-key-is-revoked flag. Change
- all callers.
-
- * status.h, status.c (get_status_string): New REVKEYSIG status tag
- for a good signature from a revoked key.
-
- * mainproc.c (do_check_sig, check_sig_and_print): Use it here.
-
- * import.c (import_revoke_cert, merge_blocks, merge_sigs): Compare
- actual signatures on import rather than using keyid or class
- matching. This does not change actual behavior with a key, but
- does mean that all sigs are imported whether they will be used or
- not.
-
- * parse-packet.c (parse_signature): Don't give "signature packet
- without xxxx" warnings for experimental pk algorithms. An
- experimental algorithm may not have a notion of (for example) a
- keyid (i.e. PGP's x.509 stuff).
-
- * options.h, g10.c (main), keylist.c (list_keyblock_print),
- keyedit.c (print_and_check_one_sig): New "show-sig-expire"
- list-option to show signature expiration dates (if any).
-
- * options.h, g10.c (main, add_keyserver_url): Add
- --sig-preferred-keyserver to implant a "where to get my key"
- subpacket into a signature.
-
- * sign.c (mk_notation_and_policy): Rename to
- mk_notation_policy_etc and add preferred keyserver support for
- signatures.
-
- * keygen.c (do_add_key_flags): Don't set the certify flag for
- subkeys.
- (ask_algo): Provide key flags for DSA, Elgamal_e, and Elgamal
- subkeys.
- (generate_keypair): Provide key flags for the default DSA/Elgamal
- keys.
-
- * sig-check.c (signature_check, signature_check2,
- check_key_signature, check_key_signature2): Allow passing NULLs
- for unused parameters in the x2 form of each function to avoid the
- need for dummy variables. getkey.c, mainproc.c: Change all
- callers.
-
- * trustdb.h, trustdb.c (read_trust_options): New. Returns items
- from the trustdb version record.
- * keylist.c (public_key_list): Use it here for the new "tru"
- record.
- * gpgv.c (read_trust_options): Stub.
-
- * keyedit.c (show_key_with_all_names): Use list-option
- show-validity in --edit-key interface as well.
-
- * options.h, g10.c (main), mainproc.c (check_sig_and_print): Add
- verify-options "show-validity" and "show-long-keyid" to show
- trustdb validity and long keyids during (file) signature
- verification.
-
- * packet.h, main.h, sig-check.c (signature_check2)
- (check_key_signature2, do_check): If ret_pk is set, fill in the pk
- used to verify the signature. Change all callers in getkey.c,
- mainproc.c, and sig-check.c.
-
- * keylist.c (list_keyblock_colon): Use the ret_pk from above to
- put the fingerprint of the signing key in "sig" records during a
- --with-colons --check-sigs. This requires --no-sig-cache as well
- since we don't cache fingerprints.
-
- * parse-packet.c (parse_signature): No need to reserve 8 bytes for
- the unhashed signature cache any longer.
-
- * misc.c (pct_expando): Add two new expandos - signer's
- fingerprint (%g), and signer's primary fingerprint (%p).
-
- * g10.c (main): Add --rfc2440 alias for --openpgp since in a few
- months, they won't be the same thing.
-
- * keyserver.c (parse_keyserver_uri): Accept "http" as an alias for
- "hkp", since it is occasionally written that way.
- (keyserver_spawn): Use ascii_isspace to avoid locale issues.
-
- * keygen.c (ask_user_id): Make --allow-freeform-uid apply to the
- email field as well as the name field, and allow mixing fields
- when it is set.
-
- * trustdb.c (validate_one_keyblock): Certifications on revoked or
- expired uids do not count in the web of trust.
-
- * signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
- sigprocmask() if we have sigset_t, and only use sigaction() if we
- have struct sigaction. This is for Forte c89 on Solaris which
- seems to define only the function call half of the two pairs by
- default.
- (pause_on_sigusr): Typo.
- (do_block): If we can't use sigprocmask() and sigset_t, try to get
- the number of signals from NSIG as well as MAXSIG, and if we
- can't, fail with an explanation.
-
- * signal.c, tdbio.c: Comment out the transaction code. It was not
- used in this version, and was causing some build problems on
- quasi-posix platforms (Solaris and Forte c89).
-
- * keylist.c (list_keyblock_colon): Don't include validity values
- when listing secret keys since they can be incorrect and/or
- misleading. This is a temporary kludge, and will be handled
- properly in 1.9/2.0.
-
- * mainproc.c (check_sig_and_print): Only show the "key available
- from" preferred keyserver line if the key is not currently
- present.
-
- * keyedit.c (sign_uids): Do not sign expired uids without --expert
- (same behavior as revoked uids). Do not allow signing a user ID
- without a self-signature. --expert overrides. Add additional
- prompt to the signature level question.
- (menu_expire): When changing expiration dates, don't replace
- selfsigs on revoked uids since this would effectively unrevoke
- them. There is also no point in replacing expired selfsigs. This
- is bug #181
-
- * g10.c (add_notation_data): Make sure that only ascii is passed
- to iscntrl. Noted by Christian Biere.
- * getkey.c (classify_user_id2): Replaced isspace by spacep
- * keygen.c (ask_user_id): Ditto.
- (get_parameter_algo): Ditto.
- * keyedit.c (keyedit_menu): Ditto.
- * tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
- * revoke.c (ask_revocation_reason):
- * keyserver.c (keyserver_spawn): Dito.
-
- * parse-packet.c (parse): Disallow old style partial length for
- all key material packets to avoid possible corruption of keyrings.
-
- * import.c (import_keys_internal): Invalidate the cache so that
- the file descriptor gets closed. Fixes bug reported by Juan
- F. Codagnone.
-
- * options.h, g10.c (main), main.h, keylist.c (show_keyserver_url),
- mainproc.c (check_sig_and_print), parse-packet.c (dump_sig_subpkt,
- parse_one_sig_subpkt, can_handle_critical): Add read-only support
- for preferred keyserver subpackets. They're basically policy URLs
- with a different name. Add a verify-option
- "show-preferred-keyserver" to turn them on and off (on by default,
- as per stable branch).
-
- * g10.c (main): Add "--set-notation" as alias to "--notation-data"
- this is to make things consistent with --set-policy-url meaning
- both sigs and certs.
-
- * options.h, g10.c (main), keylist.c (list_keyblock_print): Add
- "show-validity" and "show-long-keyid" list-options.
-
- * gpgv.c (get_validity, trust_value_to_string): Stubs.
-
- * g10.c (main): Use SAFE_VERSION instead of VERSION in the
- version-specific gpg.conf file so it can be overridden on RISCOS.
-
- * keyedit.c (show_key_with_all_names): Fix assertion failure when
- using toggle to see a secret key. Reported by Maxim Britov.
-
-
-2003-09-22 Timo Schulz <[email protected]>
-
- * 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 <[email protected]>
-
- * g10.c: New command --card-edit.
- * card-util.c (card_status): Use tty_fprintf for all output.
- (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)
- (smartcard_change_lang, smartcard_change_sex): Removed.
- (check_smartcard): Removed most menu items.
-
-2003-09-06 Werner Koch <[email protected]>
-
- * misc.c (openpgp_pk_algo_usage): Allow AUTH where SIGN is allowed.
-
- * keygen.c (ask_passphrase): No need to allocated S2K in secure
- memory.
-
-2003-09-04 Werner Koch <[email protected]>
-
- * 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)
- (merge_selfsigs_subkey, premerge_public_with_secret): Ditto.
- * keylist.c (print_capabilities): Ditto.
-
-2003-08-25 Timo Schulz <[email protected]>
-
- * pkglue.c (mpi_from_sexp): New. Used to factor out
- some common code.
-
-2003-08-24 Werner Koch <[email protected]>
-
- * keygen.c (do_generate_keypair): Print a reminder to use --gen-revoke.
-
-2003-08-18 Timo Schulz <[email protected]>
-
- * encode.c (encode_sesskey): Checked the code and removed
- the warning since all compatibility checks with PGP succeeded.
- * 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 <[email protected]>
-
- * pkglue.c (pk_sign): Fix last change.
- (pk_verify): Check for valid DATA array so that we don't segv in
- Libgcrypt.
- (pk_verify): Ditto.
-
-2003-08-06 Werner Koch <[email protected]>
-
- * pkglue.c (pk_sign): Allow signing using RSA.
-
-2003-08-05 Werner Koch <[email protected]>
-
- * Makefile.am (install-data-local): Dropped check for the ancient
- gpgm tool.
- (bin_PROGRAMS): Renamed gpg to gpg2 and gpgv to gpgv2. This is so
- that it won't conflict with the current stable version of gpg.
-
- * pkglue.c (pk_check_secret_key): New.
- * seckey-cert.c (do_check): Reenable this test here again.
-
- * g10.c (main): Add command -K as an alias for
- --list-secret-keys. Command "-k" is now an alias to --list-keys.
- Remove special treatment of -kv and -kvv.
- (set_cmd): Ditto.
- (main): Strip a "-cvs" suffix when testing for a version specific
- config file.
-
- * status.h, status.c, g10.c [USE_SHM_COPROCESSING]: Removed. This
- is not any longer available.
-
-2003-07-29 Werner Koch <[email protected]>
-
- * g10.c (main): Add secmem features and set the random seed file.
- (g10_exit): Update the random seed file.
-
- * parse-packet.c (parse_signature,read_protected_v3_mpi)
- (parse_key): Fixed use of mpi_set_opaque.
- * keygen.c (gen_card_key): Ditto.
-
-2003-07-28 Werner Koch <[email protected]>
-
- * status.c (progress_cb): Adjusted for use with Libcgrypt.
- (set_status_fd): Register that callback.
-
- * keygen.c (smartcard_change_login_data): New.
- (smartcard_change_lang): New.
- (smartcard_change_sex): New.
- (check_smartcard): Add menu entries to edit the above.
- (gen_elg,gen_dsa,gen_rsa): Reimplemented in terms of Libgcrypt.
- (genhelp_protect, genhelp_factors, key_from_sexp): New.
- * comment.c (make_comment_node_from_buffer): New.
- (make_comment_node): Reimplemented in terms of above.
-
-2003-07-27 Werner Koch <[email protected]>
-
- Adjusted for gcry_mpi_print and gcry_mpi_scan API change.
-
-2003-07-24 Werner Koch <[email protected]>
-
- * g10.c: New command --card-status.
- * card-util.c (card_status): New.
- * call-agent.c (learn_status_cb): Parse more information.
-
- * keylist.c (print_pubkey_info): Add FP arg for optional printing
- to a stream. Changed all callers.
-
-2003-07-23 Werner Koch <[email protected]>
-
- * keygen.c (generate_keypair): Create an AUTHKEYTYPE entry for cards.
- (do_generate_keypair): Abd generate the authkey.
- (check_smartcard): Changed menu accordingly.
-
-2003-07-22 Werner Koch <[email protected]>
-
- * g10.c: New command --change-pin.
- * card-util.c: New.
- * call-agent.c (agent_scd_change_pin): New.
- (agent_release_card_info): New.
- * keygen.c (check_smartcard): Use it here.
-
-2003-07-16 Werner Koch <[email protected]>
-
- * export.c (parse_export_options): New option sexp-format.
- (export_seckeys,export_secsubkeys): Check sexp-format option.
- (do_export): Ignore armor for sexp format.
- (do_export_stream): Handle sexp-format.
- (write_sexp_line,write_sexp_keyparm, build_sexp_seckey): New.
- (build_sexp): New.
-
-2003-07-03 Werner Koch <[email protected]>
-
- * 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.
- * call-agent.c (agent_scd_pkdecrypt): New.
- * pkglue.c (pk_encrypt): Add RSA support.
-
- * g10.c (main): Default to --use-agent.
-
- * keygen.c (show_smartcard): Print info about the public key.
- (check_smartcard): Check for existing key here.
- (gen_card_key): And not anymore here.
- (fpr_is_zero): New.
- (generate_keypair): Generate both keys for a card.
- (smartcard_change_url): Nw.
-
-2003-07-02 Werner Koch <[email protected]>
-
- * seckey-cert.c (is_secret_key_protected): Let it handle mode 1002.
-
-2003-07-01 Werner Koch <[email protected]>
-
- * keygen.c (gen_card_key): Obviously we should use the creation
- date received from SCDAEMON, so that the fingerprints will match.
- * sign.c (do_sign): Pass the serialno to the sign code.
- * keyid.c (serialno_and_fpr_from_sk): New.
-
-2003-06-30 Werner Koch <[email protected]>
-
- * call-agent.h (agent_card_info_s): Add field serialno.
- * call-agent.c (store_serialno): New.
- (learn_status_cb): Store the serial number.
- * keygen.c (gen_card_key): Store the serial number
- (check_smartcard): New argument to return the serial number.
- (generate_keypair): Get the serial number from check_smartcard and
- store it as a parameter.
- * parse-packet.c (parse_key): Use the protect.iv field to store the
- serial number.
- * build-packet.c (do_secret_key): Write the serial number.
-
-2003-06-27 Werner Koch <[email protected]>
-
- * seckey-cert.c (check_secret_key): Bypass the unprotection for
- mode 1002.
- * sign.c (do_sign): Handle card case (i.e. mode 1002).
-
-2003-06-26 Werner Koch <[email protected]>
-
- * build-packet.c (do_secret_key): Implement special protection
- mode 1002.
- * parse-packet.c (parse_key): Likewise.
-
- * keygen.c (smartcard_gen_key): New.
- * call-agent.c (agent_scd_setattr): New.
-
-2003-06-24 Werner Koch <[email protected]>
-
- * Makefile.am: Removed signal.c
-
- * g10.c (emergency_cleanup): New.
- (main): Use gnupg_init_signals and register malloc for assuan.
-
-2003-06-23 Werner Koch <[email protected]>
-
- * keyid.c (do_fingerprint_md): Made it work again.
-
-2003-06-19 Werner Koch <[email protected]>
-
- Fixed all "==" comparisons against error code constants to use
- gpg_err_code().
-
- * 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.
- (pubkey_get_npkey): Adjusted for changed gcrypt API.
- (pubkey_get_nskey): Ditto.
- (pubkey_get_nsig): Ditto.
- (pubkey_get_nenc): Ditto.
-
-2003-06-18 Werner Koch <[email protected]>
-
- Finished the bulk of changes for gnupg 1.9. This included
- switching to libgcrypt functions, using shared error codes from
- libgpg-error, replacing the old functions we used to have in
- ../util by those in ../jnlib and ../common, renaming the malloc
- functions and a couple of types. Note, that not all changes are
- 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.
- * pkglue.h: New.
-
- * misc.c (pull_in_libs): Removed.
-
- * keygen.c (count_chr): New.
- (ask_user_id): Removed faked RNG support.
-
- * misc.c (openpgp_md_map_name,openpgp_cipher_map_name)
- (openpgp_pk_map_name): New.
-
- * skclist.c (build_sk_list): Removed faked RNG support.
- (is_insecure): Removed.
-
- * comment.c (make_mpi_comment_node): Use gcry MPI print function.
-
- * keyid.c (v3_keyid): New.
-
- * misc.c (mpi_write,mpi_write_opaque,mpi_read,mpi_read_opaque)
- (mpi_print): New. Taken from gnupg 1.1.2.
- (checksum_mpi): Replaced by implementation from 1.1.2.
-
- * g10.c (my_strusage): Renamed from strusage and return NULL
- instead calling a default function.
- (add_to_strlist2): New. Taken from ../util/strgutil.c of gnupg 1.2.
-
- * plaintext.c (handle_plaintext): New arg CREATE_FILE to cope with
- the fact that gpg-error does not have this error code anymore.
-
- * mainproc.c (symkey_decrypt_sesskey): Ditto.
-
- * seskey.c (make_session_key): Adjusted for use with libgcrypt.
- (encode_session_key): Ditto.
- (do_encode_md): Ditto.
- (encode_md_value): Ditto.
-
- * keyring.c: Use libgpg-error instead of READ_ERROR etc.
-
- * g10.c: Adjusted all algorithm name/id mapping functions.
- (set_debug): Pass MPI and CRYPTO debug values to libgcrypt.
-
- * Makefile.am (INCLUDES): Define LOCALEDIR and the default error
- source.
-
- * g10.c (i18n_init): s/G10_LOCALEDIR/LOCALEDIR/.
-
- Renamed m_alloc et al to xmalloc et al.
- 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.
- (do_public_key): Ditto.
-
- * Makefile.am: Add new files, link gpg with libgpg-error.
- * g10.c, options.h: New option --agent-program.
- * call-agent.c: New.
- * gpg.h, call-agent.h: New.
-
-2003-06-03 David Shaw <[email protected]>
-
- * options.h, g10.c (main), keylist.c (list_keyblock_print): Add
- "show-validity" and "show-long-keyid" list-options.
-
- * gpgv.c (get_validity, trust_value_to_string): Stubs.
-
- * g10.c (main): Use SAFE_VERSION instead of VERSION in the
- version-specific gpg.conf file so it can be overridden on RISCOS.
-
-2003-06-01 David Shaw <[email protected]>
-
- * g10.c (main), keylist.c (show_policy_url, show_notation),
- mainproc.c (check_sig_and_print): Emulate the old policy and
- notation behavior (display by default). Send to status-fd whether
- it is displayed on the screen or not.
-
- * g10.c (main): Since we now have some options in devel that won't
- work in a stable branch gpg.conf file, try for a version-specific
- gpg.conf-VERSION file before falling back to gpg.conf.
-
- * main.h, options.h: Move various option flags to options.h.
-
-2003-05-31 David Shaw <[email protected]>
-
- * mainproc.c (check_sig_and_print), main.h, keylist.c
- (show_policy, show_notation): Collapse the old print_notation_data
- into show_policy() and show_notation() so there is only one
- function to print notations and policy URLs.
-
- * options.h, main.h, g10.c (main), keyedit.c
- (print_and_check_one_sig), keylist.c (list_one,
- list_keyblock_print), pkclist.c (do_edit_ownertrust), sign.c
- (mk_notation_and_policy): New "list-options" and "verify-options"
- commands. These replace the existing
- --show-photos/--no-show-photos,
- --show-notation/--no-show-notation,
- --show-policy-url/--no-show-policy-url, and --show-keyring
- options. The new method is more flexible since a user can specify
- (for example) showing photos during sig verification, but not in
- key listings. The old options are emulated.
-
- * main.h, misc.c (parse_options): New general option line
- parser. Fix the bug in the old version that did not handle report
- syntax errors after a valid entry.
-
- * import.c (parse_import_options), export.c
- (parse_export_options): Call it here instead of duplicating the
- code.
-
-2003-05-30 David Shaw <[email protected]>
-
- * keylist.c (list_one): Don't show the keyring filename when in
- --with-colons mode. Actually translate "Keyring" string.
-
- * mainproc.c (proc_tree): We can't currently handle multiple
- signatures of different classes or digests (we'd pretty much have
- to run a different hash context for each), but if they are all the
- same, make an exception. This is Debian bug #194292.
-
- * sig-check.c (check_key_signature2): Make string translatable.
-
- * packet.h, getkey.c (fixup_uidnode): Mark real primary uids
- differently than assumed primaries.
-
- * keyedit.c (no_primary_warning): Use the differently marked
- primaries here in a new function to warn when an --edit-key
- command might rearrange the self-sig dates enough to change which
- uid is primary.
- (menu_expire, menu_set_preferences): Use no_primary_warning()
- here.
-
- * Makefile.am: Use @DLLIBS@ for -ldl.
-
-2003-05-26 David Shaw <[email protected]>
-
- * getkey.c (premerge_public_with_secret): Made "no secret subkey
- for" warning a verbose item and translatable. (From wk on stable
- branch)
-
- * sig-check.c (check_key_signature2): Made "no subkey for subkey
- binding packet" a verbose item instead of a !quiet one. There are
- too many garbled keys out in the wild. (From wk on stable branch)
-
- * filter.h: Remove const from WHAT. (From wk on stable branch)
-
- * progress.c (handle_progress): Store a copy of
- NAME. (progress_filter): Release WHAT, make sure not to print a
- NULL WHAT. (From wk on stable branch)
-
- * openfile.c (open_sigfile): Adjust free for new progress
- semantics. (From wk on stable branch)
-
- * plaintext.c (ask_for_detached_datafile): Don't dealloc
- pfx->WHAT. (From wk on stable branch)
-
- * 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 <[email protected]>
-
- * armor.c, g10.c, kbnode.c, misc.c, pkclist.c, sign.c,
- build-packet.c, getkey.c, keydb.c, openfile.c, plaintext.c,
- status.c, gpgv.c, keygen.c, options.h, sig-check.c, tdbio.h,
- encode.c, mainproc.c, parse-packet.c, signal.c, textfilter.c: Edit
- all preprocessor instructions to remove whitespace before the '#'.
- This is not required by C89, but there are some compilers out
- there that don't like it.
-
-2003-05-21 David Shaw <[email protected]>
-
- * trustdb.h, trustdb.c (is_disabled), gpgv.c (is_disabled): Rename
- is_disabled to cache_disabled_value, which now takes a pk and not
- just the keyid. This is for speed since there is no need to
- 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
- cache_disabled_value if not available.
-
- * trustdb.c (get_validity): Cache the disabled value since we have
- it handy and it might be useful later.
-
- * parse-packet.c (parse_key): Clear disabled flag when parsing a
- new key. Just in case someone forgets to clear the whole key.
-
- * getkey.c (merge_selfsigs_main): Add an "if all else fails" path
- for setting a single user ID primary when there are multiple set
- primaries all at the same second, or no primaries set and the most
- recent user IDs are at the same second, or no signed user IDs at
- all. This is arbitrary, but deterministic.
-
- * exec.h, photoid.h: Add copyright message.
-
- * keylist.c (list_keyblock_print): Don't dump attribs for
- revoked/expired/etc uids for non-colon key listings. This is for
- consistency with --show-photos.
-
- * 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.
-
- * revoke.c (ask_revocation_reason): Clear old reason if user
- elects to repeat question. This is bug 153.
-
- * keyedit.c (sign_uids): Show keyid of the key making the
- signature.
-
-2003-05-21 Werner Koch <[email protected]>
-
- * progress.c (handle_progress)
- * sign.c (write_plaintext_packet)
- * encode.c (encode_simple,encode_crypt): Make sure that a filename
- of "-" is considered to be stdin so that iobuf_get_filelength
- won't get called. This fixes bug 156 reported by Gregery Barton.
-
-2003-05-02 David Shaw <[email protected]>
-
- * packet.h, build-packet.c (build_sig_subpkt), export.c
- (do_export_stream), import.c (remove_bad_stuff, import),
- parse-packet.c (dump_sig_subpkt, parse_one_sig_subpkt): Remove
- vestigal code for the old sig cache subpacket. This wasn't
- completely harmless as it caused subpacket 101 to disappear on
- import and export.
-
- * options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c,
- sign.c, encode.c, getkey.c, revoke.c: The current flags for
- different levels of PGP-ness are massively complex. This is step
- one in simplifying them. No functional change yet, just use a
- macro to check for compliance level.
-
- * sign.c (sign_file): Fix bug that causes spurious compression
- preference warning.
-
- * sign.c (clearsign_file): Fix bug that prevents proper warning
- message from appearing when clearsigning in --pgp2 mode with a
- non-v3 RSA key.
-
- * main.h, misc.c (compliance_option_string, compliance_string,
- compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
- clearsign_file), encode.c (encode_crypt,
- write_pubkey_enc_from_list): New functions to put the "this
- message may not be usable...." warning in one place.
-
- * options.h, g10.c (main): Part two of the simplification. Use a
- single enum to indicate what we are compliant to (1991, 2440,
- PGPx, etc.)
-
- * g10.c (main): Show errors for failure in export, send-keys,
- recv-keys, and refresh-keys.
-
- * options.h, g10.c (main): Give algorithm warnings for algorithms
- chosen against the --pgpX and --openpgp rules.
-
- * keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in
- --openpgp mode.
-
- * sign.c (sign_file), pkclist.c (algo_available): Allow passing a
- hint of 0.
-
-2003-05-01 David Shaw <[email protected]>
-
- * tdbio.c (create_version_record): Only create new trustdbs with
- TM_CLASSIC or TM_PGP.
-
- * trustdb.h, trustdb.c (trust_string, get_ownertrust_string,
- get_validity_string, ask_ownertrust, validate_keys), pkclist.c
- (do_edit_ownertrust): Rename trust_string to trust_value_to_string
- for naming consistency.
-
- * trustdb.h, trustdb.c (string_to_trust_value): New function to
- translate a string to a trust value.
-
- * 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
- since there is no official OpenPGP trust model. Use "PGP"
- instead.
-
-2003-04-30 David Shaw <[email protected]>
-
- * build-packet.c (build_sig_subpkt): Comments.
-
- * exec.c (exec_write): Cast NULL to void* to properly terminate
- varargs list.
-
- * keyedit.c (show_key_with_all_names): Just for safety, catch an
- invalid pk algorithm.
-
- * sign.c (make_keysig_packet): Crucial that the call to mksubpkt
- comes LAST before the calls to finalize the sig as that makes it
- possible for the mksubpkt function to get a reliable pointer to
- the subpacket area.
-
- * pkclist.c (do_we_trust_pre): If an untrusted key was chosen by a
- particular user ID, use that ID as the one to ask about when
- prompting whether to use the key anyway.
- (build_pk_list): Similar change here when adding keys to the
- recipient list.
-
- * trustdb.c (update_validity): Fix bug that prevented more than
- one validity record per trust record.
- (get_validity): When retrieving validity for a (user) supplied
- user ID, return the validity for that user ID only, and do not
- fall back to the general key validity.
- (validate_one_keyblock): Some commentary on whether
- non-self-signed user IDs belong in the web of trust (arguably,
- they do).
-
-2003-04-27 David Shaw <[email protected]>
-
- * g10.c (main): Add --no-textmode.
-
- * export.c (do_export_stream), keyedit.c (show_key_with_all_names,
- menu_addrevoker), mainproc.c (check_sig_and_print), photoid.c
- (show_photos), sign.c (mk_notation_and_policy), trustdb.c
- (get_validity, reset_trust_records, validate_keys): Make some
- strings translatable.
-
- * 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
- signature).
-
- * trustdb.c (init_trustdb): Check the trustdb options even with
- TM_AUTO since the auto may become TM_CLASSIC or TM_OPENPGP.
-
-2003-04-26 David Shaw <[email protected]>
-
- * sign.c (do_sign): Show the hash used when making a signature in
- verbose mode.
-
- * tdbio.h, tdbio.c (tdbio_read_model): New function to return the
- trust model used in a given trustdb.
-
- * options.h, g10.c (main), trustdb.c (init_trustdb, check_trustdb,
- update_trustdb): Use tdbio_read_model to implement an "auto" trust
- model which is set via the trustdb.
-
-2003-04-23 David Shaw <[email protected]>
-
- * import.c (import_revoke_cert): Remove ultimate trust when
- revoking an ultimately trusted key.
-
- * keyedit.c (sign_uids): Allow replacing expired signatures.
- Allow duplicate signatures with --expert.
-
- * pkclist.c (check_signatures_trust): Don't display a null
- fingerprint when checking a signature with --always-trust enabled.
-
- * filter.h (progress_filter_context_t), progress.c
- (handle_progress), plaintext.c (ask_for_detached_datafile,
- hash_datafiles): Fix compiler warnings. Make "what" constant.
-
- * build-packet.c (do_plaintext): Do not create invalid literal
- packets with >255-byte names.
-
-2003-04-15 Werner Koch <[email protected]>
-
- * Makefile.am (AM_CFLAGS): Make use of AM_CFLAGS and AM_LDFLAGS.
-
- * g10.c, options.h: New option --enable-progress-filter.
- * progress.c (handle_progress): Make use of it.
-
-2003-04-15 Marcus Brinkmann <[email protected]>
-
- * progress.c: New file.
- * Makefile.am (common_source): Add progress.c.
- * filter.h (progress_filter_context_t): New type.
- (progress_filter, handle_progress): New prototypes.
- * main.h (open_sigfile): New argument for prototype.
- * openfile.c (open_sigfile): New argument to install progress
- filter.
- * encode.c (encode_simple): New variable PFX. Register
- progress filter. Install text_filter after that.
- (encode_crypt): Likewise.
- * sign.c (sign_file): Likewise.
- (clearsign_file): Likewise.
- * decrypt.c (decrypt_message): Likewise.
- (decrypt_messages): Likewise.
- * verify.c (verify_signatures): Likewise.
- (verify_one_file): Likewise.
- * plaintext.c (hash_datafiles): Likewise.
- (ask_for_detached_datafile): Likewise.
-
-2003-04-10 Werner Koch <[email protected]>
-
- * passphrase.c (read_passphrase_from_fd): Do a dummy read if the
- agent is to be used. Noted by Ingo Kl�cker.
- (agent_get_passphrase): Inhibit caching when we have no
- fingerprint. This is required for key generation as well as for
- symmetric only encryption.
-
- * passphrase .c (agent_get_passphrase): New arg CANCELED.
- (passphrase_to_dek): Ditto. Passed to above. Changed all
- callers to pass NULL.
- * seckey-cert.c (do_check): New arg CANCELED.
- (check_secret_key): Terminate loop when canceled.
-
- * keyedit.c (change_passphrase): Pass ERRTEXT untranslated to
- passphrase_to_dek and translate where appropriate.
- * seckey-cert.c (check_secret_key): Ditto.
- * keygen.c (ask_passphrase): Ditto.
- * passphrase.c (agent_get_passphrase): Translate the TRYAGAIN_TEXT.
- Switch the codeset to utf-8.
-
-2003-04-09 Werner Koch <[email protected]>
-
- * decrypt.c (decrypt_messages): Fixed error handling; the function
- used to re-loop with same file after an error. Reported by Joseph
- Walton.
-
-2003-04-08 David Shaw <[email protected]>
-
- * main.h, g10.c (main), import.c (parse_import_options,
- fix_pks_corruption): It's really PKS corruption, not HKP
- corruption. Keep the old repair-hkp-subkey-bug command as an
- alias.
-
- * g10.c (main): Rename --no-version to --no-emit-version for
- consistency. Keep --no-version as an alias.
-
-2003-04-04 David Shaw <[email protected]>
-
- * pkclist.c (algo_available): PGP 8 can use the SHA-256 hash.
-
- * sign.c (sign_file, clearsign_file, sign_symencrypt_file): Remove
- unused code.
-
-2003-04-01 Werner Koch <[email protected]>
-
- * mainproc.c (check_sig_and_print): Add primary key fpr to VALIDSIG
- status.
-
-2003-03-24 David Shaw <[email protected]>
-
- * keydb.h: Err on the side of making an unknown signature a SIG
- rather than a CERT.
-
- * import.c (delete_inv_parts): Discard any key signatures that
- aren't key types (i.e. 0x00, 0x01, etc.)
-
- * g10.c (main): Add deprecated option warning for
- --list-ownertrust. Add --compression-algo alias for
- --compress-algo. Change --version output strings to match
- "showpref" strings, and make translatable.
-
- * status.c (do_get_from_fd): Accept 'y' as well as 'Y' for
- --command-fd boolean input.
-
- * trustdb.c: Fix typo (DISABLE_REGEXP -> DISABLE_REGEX)
-
- * keyedit.c (show_key_with_all_names_colon): Show no-ks-modify
- flag.
-
-2003-03-11 David Shaw <[email protected]>
-
- * options.h, g10.c (main), keyserver.c (kopts): Add "try-dns-srv"
- keyserver option. Defaults to on.
-
- * passphrase.c (agent_get_passphrase): Fix memory leak with
- symmetric messages. Fix segfault with symmetric messages. Fix
- incorrect prompt with symmetric messages.
-
-2003-03-10 Werner Koch <[email protected]>
-
- * compress.c (init_uncompress): Use a 15 bit window size so that
- the output of implementations which don't run for PGP 2
- compatibility won't get garbled.
-
-2003-03-04 David Shaw <[email protected]>
-
- * trustdb.c (validate_keys): Mask the ownertrust when building the
- list of fully valid keys so that disabled keys are still counted
- in the web of trust.
- (get_ownertrust_with_min): Do the same for the minimum ownertrust
- calculation.
-
- * parse-packet.c (dump_sig_subpkt): Show the notation names for
- not-human-readable notations. Fix cosmetic off-by-one length
- counter.
-
- * options.skel: Add explantion and commented-out
- "no-mangle-dos-filenames".
-
- * mainproc.c (proc_encrypted): Make string translatable.
-
- * keyserver.c (keyserver_spawn): Quote ':', '%', and any 8-bit
- characters in the uid strings sent to the keyserver helper.
-
- * keyring.c (keyring_rebuild_cache): Lock the keyring while
- rebuilding the signature caches to prevent another gpg from
- tampering with the temporary copy.
-
- * keygen.c (keygen_set_std_prefs): Include AES192 and AES256 in
- default prefs.
-
- * keyedit.c (show_prefs): Make strings translatable.
-
- * keydb.c: Double the maximum number of keyrings to 40.
-
- * gpgv.c (main): Fix bug #113 - gpgv should accept the
- --ignore-time-conflict option.
-
- * g10.c (main): --openpgp disables --pgpX. Double the amount of
- secure memory to 32k (keys are getting bigger these days).
-
- * Makefile.am: Makefile.am: Use @CAPLIBS@ to link in -lcap if we
- are using capabilities.
-
-2003-02-26 David Shaw <[email protected]>
-
- * keyserver.c (keyserver_spawn): Include various pieces of
- information about the key in the data sent to the keyserver
- helper. This allows the helper to use it in instructing a remote
- server which may not have any actual OpenPGP smarts in parsing
- keys.
-
- * main.h, export.c (export_pubkeys_stream, do_export_stream): Add
- ability to return only the first match in an exported keyblock for
- keyserver usage. This should be replaced at some point with a
- more flexible solution where each key can be armored seperately.
-
-2003-02-22 David Shaw <[email protected]>
-
- * sign.c (sign_file): Do not push textmode filter onto an unopened
- IOBUF (segfault). Noted by Marcus Brinkmann. Push and
- reinitialize textmode filter for each file in a multiple file
- list.
-
- * packet.h, getkey.c (fixup_uidnode), keyedit.c (show_prefs): Set
- and show the keyserver no-modify flag.
-
- * keygen.c (add_keyserver_modify): New.
- (keygen_upd_std_prefs): Call it here.
- (keygen_set_std_prefs): Accept "ks-modify" and "no-ks-modify" as
- prefs to set and unset keyserver modify flag.
-
- * g10.c (main): Accept "s1" in addition to "idea" to match the
- other ciphers.
-
- * main.h, misc.c (idea_cipher_warn): We don't need this if IDEA
- has been disabled.
-
-2003-02-21 David Shaw <[email protected]>
-
- * keygen.c (keygen_set_std_prefs): Don't put AES or CAST5 in
- default prefs if they are disabled.
-
- * g10.c (main): Use 3DES instead of CAST5 if we don't have CAST5
- support. Use 3DES for the s2k cipher in --openpgp mode.
- (print_mds): #ifdef all of the optional digest algorithms.
-
-2003-02-12 David Shaw <[email protected]>
-
- * keydb.h, getkey.c (classify_user_id, classify_user_id2): Make
- 'exact' a per-desc item. Merge into one function since
- 'force_exact' is no longer needed.
- (key_byname): Use new classify_user_id function, and new exact
- flag in KEYDB_SEARCH_DESC.
-
- * keyring.h, keyring.c (keyring_search): Return an optional index
- to show which KEYDB_SEARCH_DESC was the matching one.
-
- * keydb.h, keydb.c (keydb_search): Rename to keydb_search2, and
- pass the optional index to keyring_search. Add a macro version of
- keydb_search that calls this new function.
-
- * export.c (do_export_stream): If the keyid! syntax is used,
- export only that specified key. If the key in question is a
- subkey, export the primary plus that subkey only.
-
-2003-02-11 David Shaw <[email protected]>
-
- * exec.c (set_exec_path): Add debugging line.
-
- * g10.c (print_hex, print_mds): Print long hash strings a lot
- neater. This assumes at least an 80-character display, as there
- are a few other similar assumptions here and there. Users who
- need unformatted hashes can still use with-colons. Check that
- SHA384 and 512 are available before using them as they are no
- longer always available.
-
- * Makefile.am: Use a local copy of libexecdir along with @PACKAGE@
- as GNUPG_LIBEXECDIR so it can be easily overridden at make time.
-
-2003-02-04 David Shaw <[email protected]>
-
- * armor.c (parse_hash_header, armor_filter): Accept the new SHAs
- in the armor Hash: header.
-
- * g10.c (print_hex): Print long hash strings a little neater.
- (print_mds): Add the new SHAs to the hash list.
-
-2003-02-02 David Shaw <[email protected]>
-
- * keyedit.c (menu_revuid): Properly handle a nonselfsigned uid on
- a v4 key (treat as a v4 revocation).
-
- * import.c (print_import_check): Do not re-utf8 convert user IDs.
-
-2003-01-27 David Shaw <[email protected]>
-
- * mainproc.c (list_node): Show signature expiration date in
- with-colons sig records.
-
- * keylist.c (list_keyblock_colon), mainproc.c (list_node): Show
- trust sig information in with-colons sig records.
-
-2003-01-16 David Shaw <[email protected]>
-
- * g10.c (add_group): Trim whitespace after a group name so it does
- not matter where the user puts the = sign.
-
- * options.skel: Comment out the first three lines in case someone
- manually copies the skel file to their homedir.
-
- * sign.c (clearsign_file): Only use pgp2mode with v3 keys and
- MD5. This matches what we do when decoding such messages and
- prevents creating a message (v3+RIPEMD/160) that we can't verify.
-
- * sig-check.c (signature_check2): Use G10ERR_GENERAL as the error
- for signature digest conflict. BAD_SIGN implies that a signature
- was checked and we may try and print out a user ID for a key that
- doesn't exist.
-
-2003-01-15 David Shaw <[email protected]>
-
- * trustdb.c (init_trustdb, get_validity): Don't use a changed
- trust model to indicate a dirty trustdb, and never auto-rebuild a
- dirty trustdb with the "always" trust model.
-
- * g10.c (add_group): Last commit missed the \t ;)
-
-2003-01-14 David Shaw <[email protected]>
-
- * packet.h, parse-packet.c (setup_user_id), free-packet.c
- (free_user_id), keydb.h, keyid.c (namehash_from_uid): New function
- to rmd160-hash the contents of a user ID packet and cache it in
- the uid object.
-
- * keylist.c (list_keyblock_colon): Use namehash in field 8 of
- uids. Show dates for creation (selfsig date), and expiration in
- fields 6 and 7.
-
- * trustdb.c (get_validity, get_validity_counts, update_validity):
- Use new namehash function rather than hashing it locally.
-
-2003-01-14 Werner Koch <[email protected]>
-
- * g10.c (add_group): Fixed group parsing to allow more than one
- delimiter in a row and also allow tab as delimiter.
-
-2003-01-12 David Shaw <[email protected]>
-
- * tdbio.c (tdbio_set_dbname): Fix assertion failure with
- non-fully-qualified trustdb names.
-
-2003-01-11 David Shaw <[email protected]>
-
- * trustdb.c (get_validity_info, get_ownertrust_info,
- trust_letter): Simplify by returning a ? for error directly.
-
- * keyedit.c (show_key_with_all_names): Use get_validity_string and
- get_ownertrust_string to show full word versions of trust
- (i.e. "full" instead of 'f').
-
- * trustdb.h, trustdb.c (get_ownertrust_string,
- get_validity_string): Same as get_ownertrust_info, and
- get_validity_info, except returns a full string.
-
- * trustdb.c (get_ownertrust_with_min): New. Same as
- 'get_ownertrust' but takes the min_ownertrust value into account.
-
-2003-01-10 David Shaw <[email protected]>
-
- * armor.c (armor_filter): Comment about PGP's end of line tab
- problem.
-
- * trustdb.h, trustdb.c (trust_letter): Make
- static. (get_ownertrust_info, get_validity_info): Don't mask the
- trust level twice.
-
- * trustdb.h, gpgv.c, trustdb.c (get_validity, get_validity_info),
- keylist.c (list_keyblock_colon), keyedit.c
- (show_key_with_all_names_colon, menu_revuid): Pass a user ID in
- rather than a namehash, so we only have to do the hashing in one
- place.
-
- * packet.h, pkclist.c (build_pk_list), free-packet.c
- (release_public_key_parts): Remove unused namehash element for
- public keys.
-
-2003-01-07 David Shaw <[email protected]>
-
- * keygen.c (keygen_set_std_prefs): Warn when setting an IDEA
- preference when IDEA is not available.
-
-2003-01-06 David Shaw <[email protected]>
-
- * trustdb.c (get_validity_info): 'd' for disabled is not a
- validity value any more.
-
- * packet.h, tdbio.h, tdbio.c (tdbio_read_record,
- tdbio_write_record), trustdb.c (update_validity): Store temporary
- full & marginal counts in the trustdb.
- (clear_validity, get_validity_counts): Return and clear temp
- counts.
- (store_validation_status): Keep track of which keyids have been
- stored.
- (validate_one_keyblock, validate_key_list): Use per-uid copies of
- the full & marginal counts so they can be recalled for multiple
- levels.
- (validate_keys): Only use unused keys for each new round.
- (reset_unconnected_keys): Rename to reset_trust_records, and only
- skip specifically excluded records.
-
- * keylist.c (print_capabilities): Show 'D' for disabled keys in
- capabilities section.
-
- * trustdb.c (is_disabled): Remove incorrect comment.
-
-2003-01-03 David Shaw <[email protected]>
-
- * import.c (import_one): Only do the work to create the status
- display for interactive import if status is enabled.
-
- * keyring.c (keyring_search): skipfnc didn't work properly with
- non-keyid searches. Noted by Stefan Bellon.
-
- * getkey.c (merge_selfsigs_main): Remove some unused code and make
- sure that the pk selfsigversion member accounts for 1F direct
- sigs.
-
-2003-01-02 Werner Koch <[email protected]>
-
- * keydb.c (keydb_add_resource): Don't assume that try_make_homedir
- terminates but check again for the existence of the directory and
- continue then.
- * openfile.c (copy_options_file): Print a warning if the skeleton
- file has active options.
-
-2002-12-29 David Shaw <[email protected]>
-
- * getkey.c (merge_selfsigs_main), main.h, sig-check.c
- (check_key_signature2): Pass the ultimately trusted pk directly to
- check_key_signature2 to avoid going through the key selection
- mechanism. This prevents a deadly embrace when two keys without
- selfsigs each sign the other.
-
-2002-12-27 David Shaw <[email protected]>
-
- * keyserver.c (keyserver_refresh): Don't print the "refreshing..."
- line if there are no keys to refresh or if there is no keyserver
- set.
-
- * getkey.c (merge_selfsigs_main): Any valid user ID should make a
- key valid, not just the last one. This also fixes Debian bug
- #174276.
-
-2002-12-27 Stefan Bellon <[email protected]>
-
- * import.c (print_import_check): Changed int to size_t.
-
-2002-12-27 David Shaw <[email protected]>
-
- * keyedit.c (keyedit_menu, menu_revuid): Add "revuid" feature to
- revoke a user ID. This is the same as issuing a revocation for
- the self-signature, but a much simpler interface to do it.
-
-2002-12-26 David Shaw <[email protected]>
-
- * keydb.h, getkey.c (key_byname): Flag to enable or disable
- including disabled keys. Keys specified via keyid (i.e. 0x...)
- are always included.
-
- * getkey.c (get_pubkey_byname, get_seckey_byname2,
- get_seckey_bynames), keyedit.c (keyedit_menu, menu_addrevoker):
- Include disabled keys in these functions.
-
- * pkclist.c (build_pk_list): Do not include disabled keys for -r
- or the key prompt. Do include disabled keys for the default key
- and --encrypt-to.
-
- * trustdb.h, trustdb.c (is_disabled): New skipfnc for skipping
- disabled keys.
-
- * gpgv.c (is_disabled): Stub.
-
- * keygen.c (keygen_add_key_expire): Properly handle updating a key
- expiration to a no-expiration value.
-
- * keyedit.c (enable_disable_key): Comment.
-
- * import.c (import_one): When in interactive mode and --verbose,
- don't repeat some key information twice.
-
-2002-12-22 Timo Schulz <[email protected]>
-
- * 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 <[email protected]>
-
- * pkclist.c (do_we_trust): Tweak language to refer to the "named
- user" rather than "owner". Noted by Stefan Bellon.
-
- * trustdb.h, trustdb.c (trustdb_pending_check): New function to
- check if the trustdb needs a check.
-
- * import.c (import_keys_internal): Used here so we don't rebuild
- the trustdb if it is still clean.
- (import_one, chk_self_sigs): Only mark trustdb dirty if the key
- that is being imported has any sigs other than self-sigs.
- Suggested by Adrian von Bidder.
-
- * options.skel: Include the required '=' sign in the sample
- 'group' option. Noted by Stefan Bellon.
-
- * import.c (chk_self_sigs): Don't try and check a subkey as if it
- was a signature.
-
-2002-12-11 David Shaw <[email protected]>
-
- * tdbio.c (tdbio_read_record, tdbio_write_record): Compact the
- RECTYPE_TRUST records a bit.
-
- * g10.c (main): Comment out --list-trust-path until it can be
- implemented.
-
- * import.c (import_one): Warn when importing an Elgamal primary
- that this may take some time (to verify self-sigs).
- (chk_self_sigs): Try and cache all self-sigs so the keyblock is
- written to the keyring with a good rich cache.
-
- * keygen.c (ask_algo): Make the Elgamal sign+encrypt warning
- stronger, and remove the RSA sign+encrypt warning.
-
-2002-12-06 Stefan Bellon <[email protected]>
-
- * options.h: Fixed typo (mangle_dos_names instead of
- mangle_dos_filenames).
-
-2002-12-05 Werner Koch <[email protected]>
-
- * g10.c: New options --[no-]mangle-dos-filenames.
- * options.h (opt): Added mangle-dos-filenames.
- * openfile.c (open_outfile) [USE_ONLY_8DOT3]: Truncate the
- filename only when this option is set; this is the default.
-
-2002-12-04 David Shaw <[email protected]>
-
- * main.h, keyedit.c, keygen.c: Back out previous (2002-12-01)
- change. Minimal isn't always best.
-
- * sign.c (update_keysig_packet): Use the current time rather then
- a modification of the original signature time. Make sure that
- this doesn't cause a time warp.
-
- * keygen.c (keygen_add_key_expire): Properly handle a key
- expiration date in the past (use a duration of 0).
-
- * keyedit.c (menu_expire): Use update_keysig_packet so any sig
- subpackets are maintained during the update.
-
- * build-packet.c (build_sig_subpkt): Mark sig expired or unexpired
- when the sig expiration subpacket is added.
- (build_sig_subpkt_from_sig): Handle making an expiration subpacket
- from a sig that has already expired (use a duration of 0).
-
- * packet.h, sign.c (update_keysig_packet), keyedit.c
- (menu_set_primary_uid, menu_set_preferences): Add ability to issue
- 0x18 subkey binding sigs to update_keysig_packet and change all
- callers.
-
- * trustdb.c (validate_keys): Show trust parameters when building
- the trustdb, and make sure that the version record update was
- successful.
- (init_trustdb): If the current parameters aren't what was used for
- building the trustdb, the trustdb is invalid.
-
- * tbio.c (tdbio_db_matches_options): Update to work with new
- trustdbs.
-
-2002-12-03 David Shaw <[email protected]>
-
- * tdbio.h, tdbio.c (tdbio_read_record, tdbio_write_record): Store
- trust model in the trustdb version record.
- (tdbio_update_version_record): New function to update version
- record values during a trustdb check or update.
- (tdbio_dump_record): Show trust model in dump.
-
- * trustdb.c (validate_keys): Call tdbio_update_version_record on
- success so that the correct options are stored in the trustdb.
-
- * options.h: rearrange trust models so that CLASSIC is 0 and
- OPENPGP is 1.
-
- * options.h, g10.c (main), encode.c (write_pubkey_enc_from_list),
- pkclist.c (algo_available), revoke.c (gen_revoke): Add --pgp8
- mode. This is basically identical to --pgp7 in all ways except
- that signing subkeys, v4 data sigs (including expiration), and SK
- comments are allowed.
-
- * getkey.c (finish_lookup): Comment.
-
- * main.h, keylist.c (reorder_keyblock), keyedit.c (keyedit_menu):
- Reorder user ID display in the --edit-key menu to match that of
- the --list-keys display.
-
- * g10.c (add_notation_data): Fix initialization.
-
-2002-12-01 David Shaw <[email protected]>
-
- * keyedit.c (menu_expire): Don't lose key flags when changing the
- expiration date of a subkey. This is not the most optimal
- solution, but it is minimal change on the stable branch.
-
- * main.h, keygen.c (do_copy_key_flags): New function to copy key
- flags, if any, from one sig to another.
- (do_add_key_expire): New function to add key expiration to a sig.
- (keygen_copy_flags_add_expire): New version of
- keygen_add_key_expire that also copies key flags.
- (keygen_add_key_flags_and_expire): Use do_add_key_expire.
-
- * import.c (fix_hkp_corruption): Comment.
-
-2002-11-25 Stefan Bellon <[email protected]>
-
- * plaintext.c (handle_plaintext) [__riscos__]: If nooutput is set,
- no filetype is needed obviously.
-
-2002-11-24 David Shaw <[email protected]>
-
- * main.h, misc.c (default_cipher_algo, default_compress_algo):
- New. Return the default algorithm by trying
- --cipher-algo/--compress-algo, then the first item in the pref
- list, then s2k-cipher-algo or ZIP.
-
- * sign.c (sign_file, sign_symencrypt_file), encode.c
- (encode_simple, encode_crypt): Call default_cipher_algo and
- default_compress_algo to get algorithms.
-
- * g10.c (main): Allow pref selection for compress algo with
- --openpgp.
-
- * mainproc.c (proc_encrypted): Use --s2k-digest-algo for
- passphrase mangling rather than --digest-algo.
-
- * sign.c (hash_for): If --digest-algo is not set, but
- --personal-digest-preferences is, then use the first hash
- algorithm in the personal list. If the signing algorithm is DSA,
- then use the first 160-bit hash algorithm in the personal list.
- If --pgp2 is set and it's a v3 RSA key, use MD5.
-
- * g10.c (main), keydb.c (keydb_add_resource,
- keydb_locate_writable): Rename --default-keyring as
- --primary-keyring. Stefan wins the naming contest.
-
-2002-11-23 David Shaw <[email protected]>
-
- * g10.c (add_notation_data): Disallow notation names that do not
- contain a '@', unless --expert is set. This is to help prevent
- people from polluting the (as yet unused) IETF namespace.
-
- * main.h: Comments about default algorithms.
-
- * photoid.c (image_type_to_string): Comments about 3-letter file
- extensions.
-
- * encode.c (encode_simple), passphrase.c (passphrase_to_dek),
- sign.c (sign_symencrypt_file): Use --s2k-digest-algo for
- passphrase mangling rather than --digest-algo.
-
-2002-11-21 David Shaw <[email protected]>
-
- * keygen.c (keygen_set_std_prefs): Properly handle an empty
- preference string.
-
- * misc.c (string_to_compress_algo): "none" is a bad choice since
- it conflicts with the "none" in setpref.
-
-2002-11-14 David Shaw <[email protected]>
-
- * g10.c (main): Allow compression algorithm names as the argument
- to --compress-algo. The old algorithm names still work for
- backwards compatibility.
-
- * misc.c (string_to_compress_algo): Allow "none" as an alias for
- "uncompressed".
-
-2002-11-13 Stefan Bellon <[email protected]>
-
- * getkey.c (get_pubkey_byfprint_fast): Fixed type incompatibility,
- was unsigned char instead of byte.
-
-2002-11-13 David Shaw <[email protected]>
-
- * encode.c (encode_simple): Make sure that files larger than about
- 4G use partial length encoding. This is required because OpenPGP
- allows only for 32 bit length fields. From Werner on stable
- branch.
-
- * getkey.c (get_pubkey_direct): Renamed to...
- (get_pubkey_fast): this and made extern.
- (get_pubkey_byfprint_fast): New. From Werner on stable branch.
-
- * keydb.h, import.c (import_one): Use get_pubkey_fast instead of
- get_pubkey. We don't need a merged key and actually this might
- lead to recursions.
- (revocation_present): Likewise for search by fingerprint. From
- Werner on stable branch.
-
- * g10.c (main): Try to create the trustdb even for non-colon-mode
- 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.
-
- * passphrase.c (agent_get_passphrase): Ditto. From Werner on
- stable branch.
-
- * tdbio.c (MY_O_BINARY): Need binary mode with Cygwin. From
- Werner on stable branch.
-
- * 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.
-
- * passphrase.c (agent_send_all_options): Fix compile warning.
-
- * keylist.c (list_keyblock_colon): Validity for subkeys should
- match that of the primary key, and not that of the last user ID.
-
- * getkey.c (merge_selfsigs): Revoked/expired/invalid primary keys
- carry these facts onto all their subkeys, but only after the
- subkey has a chance to be marked valid. This is to fix an
- incorrect "invalid public key" error verifying a signature made by
- a revoked signing subkey, with a valid unrevoked primary key.
-
-2002-11-09 Werner Koch <[email protected]>
-
- * passphrase.c (agent_send_all_options): Use tty_get_ttyname to
- get the default ttyname.
-
-2002-11-07 David Shaw <[email protected]>
-
- * keyring.h, keyring.c (keyring_register_filename): Return the
- pointer if a given keyring is registered twice.
-
- * keydb.h, keydb.c (keydb_add_resource): Use flags to indicate a
- default keyring.
- (keydb_locate_writable): Prefer the default keyring if possible.
-
- * g10.c (main): Add --default-keyring option.
-
-2002-11-06 David Shaw <[email protected]>
-
- * options.h, g10.c (main), trustdb.c (ask_ownertrust): Add
- --force-ownertrust option for debugging purposes. This allows
- setting a whole keyring to a given trust during an
- --update-trustdb. Not for normal use - it's just easier than
- hitting "4" all the time to test a large trustdb.
-
- * pubkey-enc.c (get_session_key): With hidden recipients or try a
- given passphrase against all secret keys rather than trying all
- secret keys in turn. Don't if --try-all-secrets or --status-fd is
- enabled.
-
- * passphrase.c (passphrase_to_dek): Mode 1 means do a regular
- passphrase query, but don't prompt with the key info.
-
- * seckey-cert.c (do_check, check_secret_key): A negative ask count
- means to enable passphrase mode 1.
-
- * keydb.h, getkey.c (enum_secret_keys): Add flag to include
- secret-parts-missing keys (or not) in the list.
-
-2002-11-05 David Shaw <[email protected]>
-
- * keyserver.c (keyserver_search_prompt): When --with-colons is
- enabled, don't try and fit the search output to the screen size -
- just dump the whole list.
-
-2002-11-04 David Shaw <[email protected]>
-
- * keyserver.c (keyserver_search_prompt): When --with-colons is
- enabled, just dump the raw keyserver protocol to stdout and don't
- print the menu.
-
- * keyserver.c (show_prompt): Don't show a prompt when command-fd
- is being used.
-
- * trustdb.c (trust_model_string, check_trustdb, update_trustdb,
- validate_one_keyblock): It's not clear what a trustdb rebuild or
- check means with a trust model other than "classic" or "openpgp",
- so disallow this.
-
-2002-11-03 David Shaw <[email protected]>
-
- * options.h, g10.c (main): Add --trust-model option. Current
- models are "openpgp" which is classic+trustsigs, "classic" which
- is classic only, and "always" which is the same as the current
- option --always-trust (which still works). Default is "openpgp".
-
- * trustdb.c (validate_one_keyblock): Use "openpgp" trust model to
- enable trust sigs.
-
- * gpgv.c (main), mainproc.c (check_sig_and_print), pkclist.c
- (do_we_trust, do_we_trust_pre, check_signatures_trust): Use new
- --trust-model option in place of --always-trust.
-
- * keyedit.c (sign_mk_attrib, trustsig_prompt, sign_uids,
- keyedit_menu): Prompt for and create a trust signature with
- "tsign". This is functional, but needs better UI text.
-
- * build-packet.c (build_sig_subpkt): Able to build trust and
- regexp subpackets.
-
- * pkclist.c (do_edit_ownertrust): Comment.
-
-2002-11-02 David Shaw <[email protected]>
-
- * keygen.c (set_one_pref, keygen_set_std_prefs): Allow using the
- full algorithm name (CAST5, SHA1) rather than the short form (S3,
- H2).
-
- * main.h, keygen.c (keygen_get_std_prefs), keyedit.c
- (keyedit_menu): Return and use a fake uid packet rather than a
- string since we already have a nice parser/printer in
- keyedit.c:show_prefs.
-
- * main.h, misc.c (string_to_compress_algo): New.
-
-2002-11-01 David Shaw <[email protected]>
-
- * g10.c (main): Add --no-throw-keyid.
-
- * keydb.h, encode.c (write_pubkey_enc_from_list), g10.c (main),
- pkclist.c (build_pk_list): Add --hidden-recipient (-R) and
- --hidden-encrypt-to, which do a single-user variation on
- --throw-keyid. The "hide this key" flag is carried in bit 0 of
- the pk_list flags field.
-
- * keyserver.c (parse_keyrec): Fix shadowing warning.
-
-2002-10-31 Stefan Bellon <[email protected]>
-
- * compress.c (init_compress) [__riscos__]: Use
- riscos_load_module() to load ZLib module.
-
- * g10.c (main) [__riscos__]: Renames due to changes in riscos.c
- (e.g. prefixes all RISC OS specific functions with riscos_*).
- * photoid.c (show_photos) [__riscos__]: Likewise.
- * signal.c (got_fatal_signal) [__riscos__]: Likewise.
-
- * trustdb.c (check_regexp) [__riscos__]: Branch to RISC OS RegEx
- handling.
-
-2002-10-31 David Shaw <[email protected]>
-
- * build-packet.c (do_plaintext), encode.c (encode_sesskey,
- encode_simple, encode_crypt), sign.c (write_plaintext_packet): Use
- wipememory() instead of memset() to wipe sensitive memory as the
- memset() might be optimized away.
-
-2002-10-30 David Shaw <[email protected]>
-
- * trustdb.c (check_regexp): Modern regexps require REG_EXTENDED.
-
-2002-10-29 David Shaw <[email protected]>
-
- * packet.h, trustdb.h, trustdb.c (trust_string): New. Return a
- string like "fully trusted", "marginally trusted", etc.
- (get_min_ownertrust): New. Return minimum ownertrust.
- (update_min_ownertrust): New. Set minimum ownertrust.
- (check_regexp): New. Check a regular epression against a user ID.
- (ask_ownertrust): Allow specifying a minimum value.
- (get_ownertrust_info): Follow the minimum ownertrust when
- returning a letter.
- (clear_validity): Remove minimum ownertrust when a key becomes
- invalid.
- (release_key_items): Release regexp along with the rest of the
- info.
- (validate_one_keyblock, validate_keys): Build a trust sig chain
- while validating. Call check_regexp for regexps. Use the minimum
- ownertrust if the user does not specify a genuine ownertrust.
-
- * pkclist.c (do_edit_ownertrust): Only allow user to select a
- trust level greater than the minimum value.
-
- * parse-packet.c (can_handle_critical): Can handle critical trust
- and regexp subpackets.
-
- * trustdb.h, trustdb.c (clear_ownertrusts), delkey.c
- (do_delete_key), import.c (import_one): Rename clear_ownertrust to
- clear_ownertrusts and have it clear the min_ownertrust value as
- well.
-
- * keylist.c (list_keyblock_print): Indent uid to match pub and
- sig.
-
- * keyedit.c (print_and_check_one_sig, show_key_and_fingerprint,
- menu_addrevoker), keylist.c (list_keyblock_print,
- print_fingerprint): Show "T" or the trust depth for trust
- signatures, and add spaces to some strings to make room for it.
-
- * packet.h, parse-packet.c (dump_sig_subpkt, parse_one_sig_subpkt,
- parse_signature): Parse trust signature values.
-
- * tdbio.h, tdbio.c (tdbio_read_record, tdbio_write_record):
- Reserve a byte for the minimum ownertrust value (for use with
- trust signatures).
-
-2002-10-29 Stefan Bellon <[email protected]>
-
- * build-packet.c (calc_plaintext, do_plaintext): Removed RISC OS
- specific filetype parts (it's now done in make_basename()).
-
- * plaintext.c (handle_plaintext): Tidied up RISC OS specific
- filetype parts.
-
- * encode.c (encode_simple, encode_crypt): Added argument to
- make_basename() call.
-
- * sign.c (write_plaintext_packet): Added argument to
- make_basename() call.
-
-2002-10-28 Stefan Bellon <[email protected]>
-
- * build-packet.c (calc_plaintext, do_plaintext): Added filetype
- handling for RISC OS' file types.
-
- * plaintext.c (handle_plaintext) [__riscos__]: Added filetype
- handling for RISC OS' file types.
-
-2002-10-23 David Shaw <[email protected]>
-
- * main.h, import.c (sec_to_pub_keyblock, import_secret_one,
- parse_import_options), g10.c (main): New import-option
- "convert-sk-to-pk" to convert a secret key into a public key
- during import. It is on by default.
-
-2002-10-23 Werner Koch <[email protected]>
-
- * pubkey-enc.c (get_it): Fix segv, test for revoked only when PK
- has been assigned.
-
-2002-10-18 Timo Schulz <[email protected]>
-
- * keylist.c: (print_pubkey_info): New.
- (print_seckey_info): New.
- * 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 <[email protected]>
-
- * pkclist.c (do_edit_ownertrust): Show all user IDs. This should
- be enhanced to also show the current trust level. Suggested by
- Florian Weimer.
-
-2002-10-17 David Shaw <[email protected]>
-
- * g10.c (main): Handle --strict and --no-strict from the command
- line before the options file is loaded.
-
-2002-10-15 David Shaw <[email protected]>
-
- * g10.c (main): Disable --textmode when encrypting (symmetric or
- pk) in --pgp2 mode as PGP 2 can't handle the unknown length
- literal packet. Reported by Michael Richardson.
-
-2002-10-14 David Shaw <[email protected]>
-
- * keyserver-internal.h, keyserver.c (print_keyrec, parse_keyrec,
- show_prompt, keyserver_search_prompt, keyserver_spawn): Go to
- version 1 of the keyserver protocol. This is a better design,
- similar to --with-colons, that allows for keys with multiple user
- IDs rather than using multiple keys. It also matches the machine
- readable pksd format. Also use a prettier --search-keys listing
- format that can fill different size windows (currently set at 24
- lines).
-
-2002-10-12 Werner Koch <[email protected]>
-
- * keygen.c (print_status_key_created): New.
- (do_generate_keypair): Use it to print the fingerprint.
- (generate_subkeypair): Likewise.
-
-2002-10-11 David Shaw <[email protected]>
-
- * keyedit.c (menu_addrevoker): Properly back out if the signature
- fails. Also, do not allow appointing the same revoker twice, and
- report ALREADY_SIGNED if the user tries it.
-
-2002-10-07 David Shaw <[email protected]>
-
- * import.c (import_keys_internal): Missed one s/inp/inp2/.
-
- * keylist.c (print_capabilities): Properly indicate per-key
- capabilities of sign&encrypt primary keys that have
- secret-parts-missing (i.e. no capabilities at all)
-
- * mainproc.c (symkey_decrypt_sesskey): Fix compiler warning.
-
-2002-10-04 David Shaw <[email protected]>
-
- * getkey.c (get_pubkey_direct): Don't cache keys retrieved via
- this function as they may not have all their fields filled in.
-
- * sig-check.c (signature_check2): Use new is_primary flag to check
- rather than comparing main_keyid with keyid as this still works in
- the case of a not fully filled in pk.
-
-2002-10-04 Werner Koch <[email protected]>
-
- * import.c (import_keys_internal): s/inp/inp2/ to avoid shadowing
- warning.
-
- * passphrase.c (agent_get_passphrase): Fixed signed/unsigned char
- problem in %-escaping. Noted by Ingo Kl�cker.
-
-2002-10-03 David Shaw <[email protected]>
-
- * options.h, g10.c (main): Add --strict and --no-strict to switch
- the log_warning severity level from info to error.
-
- * keylist.c (print_capabilities): Secret-parts-missing keys should
- show that fact in the capabilities, and only primary signing keys
- can certify other keys.
-
- * packet.h, parse_packet.c (parse_key): Add is_primary flag for
- public keys (it already exists for secret keys).
-
-2002-10-02 David Shaw <[email protected]>
-
- * import.c (import_secret_one): Check for an illegal (>110)
- protection cipher when importing a secret key.
-
- * keylist.c (list_keyblock_print): Show a '#' for a
- secret-parts-missing key.
-
- * parse_packet.c (parse_key): Some comments.
-
- * revoke.c (gen_revoke): Remove some debugging code.
-
- * trustdb.c (verify_own_keys): Make trusted-key a non-deprecated
- option again.
-
- * seckey-cert.c (do_check): Don't give the IDEA warning unless the
- cipher in question is in fact IDEA.
-
-2002-10-01 David Shaw <[email protected]>
-
- * import.c (import_one): Make sure that a newly imported key
- starts with a clean ownertrust.
-
-2002-10-01 Werner Koch <[email protected]>
-
- * getkey.c (get_pubkey_direct): New.
- (merge_selfsigs_main): Use it here to look for an ultimately
- trusted key. Using the full get_pubkey might lead to an
- infinitive recursion.
-
-2002-09-29 David Shaw <[email protected]>
-
- * keyserver.c (parse_keyserver_uri): Force the keyserver URI
- scheme to lowercase to be case-insensitive.
-
-2002-09-28 David Shaw <[email protected]>
-
- * export.c (do_export_stream): Comment.
-
- * sig-check.c (check_key_signature2): Properly handle a
- non-designated revocation import.
-
-2002-09-26 Werner Koch <[email protected]>
-
- * g10.c (set_homedir): New. Changed all direct assignments to use
- this.
- * gpgv.c (set_homedir): Ditto.
-
-2002-09-25 David Shaw <[email protected]>
-
- * Makefile.am: Link gpg with EGDLIBS (i.e. NETLIBS) as EGD uses
- sockets. Remove the old NETLIBS variable since the keyserver
- stuff is no longer internal.
-
-2002-09-24 David Shaw <[email protected]>
-
- * import.c (import_keys_stream): Fix compiler type warning.
-
- * keyring.c (keyring_rebuild_cache), sig-check.c
- (check_key_signature2), import.c (import, chk_self_sigs): Minor
- language cleanups.
-
-2002-09-23 Stefan Bellon <[email protected]>
-
- * main.h: Introduced fast-import as import option. Removed
- fast as separate option from prototypes.
- * import.c (parse_import_options): Added fast-import option.
- (import_*): Removed fast as separate option.
- * g10.c (main): Added option fast-import, removed old fast
- as separate argument.
- * keyserver.c (keyserver_spawn): Removed old fast as separate
- argument.
-
-2002-09-22 Stefan Bellon <[email protected]>
-
- * import.c (import_keys, import_keys_stream,
- import_keys_internal): Added trustdb update/check to key import if
- not fast-import and interactive set/no-auto-check-trustdb unset.
- Avoided function clone by introducing import_keys_internal.
-
-2002-09-19 David Shaw <[email protected]>
-
- * keyserver.c (keyserver_spawn): Properly handle line truncation.
- Don't leak memory (~10-20 bytes) on searches.
- (keyserver_search_prompt): Cleanup.
-
- * keylist.c (list_keyblock_colon): Show 1F direct key signatures
- in --with-colons listing.
-
-2002-09-16 David Shaw <[email protected]>
-
- * keyedit.c (menu_addrevoker): The direct key signature for
- revocation keys must be at least v4 to carry the revocation key
- subpacket. Add a PGP 2.x warning for revocation keys.
-
-2002-09-14 David Shaw <[email protected]>
-
- * g10.c (check_permissions): Rearrange strings to make translating
- easier (don't incorporate string parts).
-
- * keyedit.c (sign_uids): Make strings translatable.
-
- * sig-check.c (check_key_signature2): Make string translatable.
-
-2002-09-13 David Shaw <[email protected]>
-
- * getkey.c (check_revocation_keys): Move....
- * main.h, sig-check.c (check_revocation_keys): to here. Also
- return the signature_check error code rather than 0/1 and cache
- the sig result.
-
- * sig-check.c (check_key_signature2): Divert to
- check_revocation_keys if a revocation sig is made by someone other
- than the pk owner.
-
- * getkey.c (merge_selfsigs_main): Tidy.
-
-2002-09-13 Werner Koch <[email protected]>
-
- * g10.c (main) [__MINGW32__]: Activate oLoadExtension.
-
-2002-09-12 David Shaw <[email protected]>
-
- * Makefile.am, hkp.c, hkp.h, keyserver.c (keyserver_work): Remove
- internal HKP support.
-
- * keyserver.c (keyserver_spawn): Remove whitespace after keyserver
- commands.
-
-2002-09-10 David Shaw <[email protected]>
-
- * exec.c (expand_args): Remove loop left over from earlier
- implementation.
- (exec_write): Missed one tick.
-
-2002-09-10 Werner Koch <[email protected]>
-
- * g10.c, options.h: Removed option --emulate-checksum-bug.
- * misc.c (checksum_u16_nobug): Removed.
- (checksum_u16): Removed the bug emulation.
- (checksum_mpi): Ditto.
- (checksum_mpi_counted_nbits): Removed and replaced all calls
- with checksum_mpi.
-
- * parse-packet.c (read_protected_v3_mpi): New.
- (parse_key): Use it here to store it as an opaque MPI.
- * seckey-cert.c (do_check): Changed the v3 unprotection to the new
- why to store these keys.
- (protect_secret_key): Likewise.
- * build-packet.c (do_secret_key): And changed the writing.
-
- * tdbio.c (tdbio_set_dbname, open_db): Use new macro MY_O_BINARY
- to avoid silly ifdefs.
- (open_db): Fallback to RDONLY so that gpg may be used from a
- RO-medium.
-
- * encode.c (encode_simple): Make sure we don't use an ESK packet
- when we don't have a salt in the S2K.
-
- * misc.c (pct_expando) <case f>: Make sure that LEN is initialized.
-
- * exec.c (exec_finish): Use ticks to denote filenames in messages.
- (make_tempdir, exec_write): Changed format of messages.
-
- * keyserver.c (print_keyinfo): Release USERID in on error.
- (keyserver_work) [!DISABLE_KEYSERVER_HELPERS]: Exclude the unused
- code.
-
-2002-09-09 Werner Koch <[email protected]>
-
- * parse-packet.c (make_attribute_uidname): Add new ar MAX_NAMELEN
- for sanity checks. Changed both callers. Limit the size of an %s.
-
- * options.skel: Comment lock-once out, so that this file does not
- change anything when copied to a new home directory.
- * openfile.c (try_make_homedir): Don't exit after copying the
- option skeleton.
-
- * options.h: Don't use a comma when declaring variables over more
- than one line.
-
- * mainproc.c (symkey_decrypt_sesskey): Check length of the session
- key.
-
- * hkp.c (dehtmlize): Use ascii_tolower to protect against weird
- locales. Cast the argument for isspace for the sake of broken
- HP/UXes.
- (parse_hkp_index): s/ascii_memcasecmp/ascii_strncasecmp/.
-
- * g10.c: Removed option --emulate-3des-s2k-bug.
-
- * passphrase.c (hash_passphrase): Was used here.
-
- * export.c (parse_export_options)
- * keyserver.c (parse_keyserver_options)
- * import.c (parse_import_options)
- * g10.c (check_permissions): s/ascii_memcasecmp/ascii_strncasecmp/.
-
-2002-09-09 David Shaw <[email protected]>
-
- * g10.c (add_group): Use '=' to separate group name from group
- members. Use a better error message for when no = is found.
-
- * hkp.c (hkp_export): Use CRLF in headers.
-
-2002-09-03 David Shaw <[email protected]>
-
- * mainproc.c (print_pkenc_list): Don't increment the error counter
- when printing the list of keys a message was encrypted to. This
- would make gpg give a non-zero exit code even for completely valid
- messages if the message was encrypted to more than one key that
- the user owned.
-
-2002-09-02 Werner Koch <[email protected]>
-
- * g10.c (main): Try to set a default character set. Print the
- used one in verbosity level 3.
- * gpgv.c (main): Try to set a default character set.
-
- * status.c, status.h (STATUS_IMPORT_OK): New.
- * import.c (import_one,import_secret_one): Print new status.
-
-2002-08-30 David Shaw <[email protected]>
-
- * pkclist.c (build_pk_list): Add new status code to indicate an
- untrusted user. This (or a disabled key) fail with "unavailable
- pubkey" (G10ERR_UNU_PUBKEY).
-
- * pkclist.c (build_pk_list): Fail if any recipient keys are
- unusable.
-
- * options.skel: The PGP LDAP keyserver is back. Use MIT keyserver
- as a sample rather than cryptnet as cryptnet does not support
- searching yet.
-
- * keyedit.c (show_key_with_all_names): Fix error message
- (preferences are userid/selfsig and not key specific).
-
-2002-08-30 Werner Koch <[email protected]>
-
- * pkclist.c (do_we_trust_pre): Changed the wording of a warning.
-
- * encode.c (encode_simple,encode_crypt): Use new style CTB for
- compressssed packets when using MDC. We need to do this so that
- concatenated messages are properly decrypted. Old style
- compression assumes that it is the last packet; given that we
- can't determine the length in advance, the uncompressor does not
- know where to start. Actually we should use the new CTB always
- but this would break PGP 2 compatibility.
-
- * parse-packet.c (parse): Special treatment for new style CTB
- compressed packets.
-
- * build-packet.c (do_mdc): Removed. Was not used.
- (do_encrypted_mdc): Count in the version number and the MDC packet.
-
-2002-08-28 David Shaw <[email protected]>
-
- * sig-check.c (do_check_messages, do_check): Show keyid in error
- messages.
-
- * keyserver.c (print_keyinfo): More readable key listings for
- --search-keys responses.
-
-2002-08-26 David Shaw <[email protected]>
-
- * hkp.c (parse_hkp_index, dehtmlize): Move HTML functionality into
- new "dehtmlize" function. Remove HTML before trying to parse each
- line from the keyserver. If the keyserver provides key type
- information in the listing, use it.
-
-2002-08-23 David Shaw <[email protected]>
-
- * sig-check.c (do_check, do_check_messages): Emit the usual sig
- warnings even for cached sigs. This also serves to protect
- against missing a sig expiring while cached.
-
- * getkey.c (merge_selfsigs_main): Don't check UID self-sigs twice.
-
-2002-08-22 David Shaw <[email protected]>
-
- * import.c (clean_subkeys, chk_self_sigs): Merge clean_subkeys
- into chk_self_sigs. This improves efficiency as the same
- signatures are not checked multiple times. Clarify when a subkey
- is revoked (any revocation signature, even if it is dated before
- the binding signature).
-
- * getkey.c (merge_selfsigs_subkey): Subkey revocation comments.
-
- * keylist.c (list_one): Stats are only for public key listings.
-
- * g10.c (main), options.skel: Default should be include-revoked
- for keyserver operations.
-
-2002-08-21 Werner Koch <[email protected]>
-
- * import.c (import_print_stats): Print new non_imported counter
- which is currently not used because we terminate on errors.
-
-2002-08-20 David Shaw <[email protected]>
-
- * options.skel: Document no-include-attributes for
- keyserver-options.
-
- * keylist.c, keyedit.c, keyserver.c, sign.c: Some TODOs and
- comments.
-
- * export.c (do_export_stream): Fix noop bug in exporting sensitive
- revocation keys.
-
- * pkclist.c (do_edit_ownertrust): Comment out the option for
- showing trust paths until it can be implemented.
-
-2002-08-19 Werner Koch <[email protected]>
-
- * getkey.c (get_user_id_native): Renamed to ..
- (get_user_id_printable): this. Filter out all dangerous
- characters. Checked all usages.
- (get_user_id_string_native): Renamed to..
- (get_user_id_string_printable): this. Filter out all dangerous
- characters. Checked all usages.
- * keyedit.c (show_basic_key_info): New.
- * keylist.c (print_fingerprint): New mode 3.
- * import.c (import_one): Use new function to display the user ID.
-
-2002-08-16 Timo Schulz <[email protected]>
-
- * g10.c (main): Enable opt.interactive.
-
- * 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 <[email protected]>
-
- * seckey-cert.c: Workaround to allow decryption of v3 keys created
- with a bug in the mpi_get_secure_buffer.
-
-2002-08-14 David Shaw <[email protected]>
-
- * hkp.c (parse_hkp_index): Properly handle really large keys
- (5 digit key length) in HKP searches.
-
-2002-08-13 David Shaw <[email protected]>
-
- * encode.c (encode_simple): Fix problem with using compression
- algo 2 and symmetric compressed files.
-
- * encode.c (encode_simple, encode_crypt): If we are not using a
- MDC, compress even if a file is already compressed. This is to
- help against the chosen ciphertext attack.
-
- * pkclist.c (select_algo_from_prefs): Fix requested algorithm bug
- so the request succeeds even if the requested algorithm is not the
- first found.
-
- * cipher.c (write_header), encode.c (use_mdc, encode_simple,
- encode_crypt, encrypt_filter), g10.c (main): Be more eager to use
- a MDC. We use a MDC if the keys directly support it, if the keys
- list AES (any) or TWOFISH anywhere in the prefs, or if the cipher
- chosen does not have a 64 bit blocksize.
-
-2002-08-08 David Shaw <[email protected]>
-
- * options.skel: Some language tweaks, and remove the
- load-extension section for random gatherers.
-
- * keyring.c (create_tmp_file, rename_tmp_file): Create tmp files
- with user-only permissions, but restore the original permissions
- if the user has something special set.
-
- * openfile.c (copy_options_file): Create new options file
- (gpg.conf) with user-only permissions.
-
- * keydb.c (keydb_add_resource): Create new keyrings with user-only
- permissions.
-
- * tdbio.c (tdbio_set_dbname): Create new trustdbs with user-only
- permissions.
-
-2002-08-07 David Shaw <[email protected]>
-
- * sig-check.c (signature_check2): Sanity check that the md has a
- context for the hash that the sig is expecting. This can happen
- if a onepass sig header does not match the actual sig, and also if
- the clearsign "Hash:" header is missing or does not match the
- actual sig.
-
- * keyedit.c (menu_revsig): Properly show a uid is revoked without
- restarting gpg. This is Debian bug 124219, though their supplied
- patch will not do the right thing.
-
- * main.h, tdbio.c (tdbio_set_dbname), misc.c (removed
- check_permissions), keydb.c (keydb_add_resource), g10.c (main,
- check_permissions): Significant reworking of the permission check
- mechanism. The new behavior is to check everything in the homedir
- by checking the homedir itself. If the user wants to put
- (possibly shared) keyrings outside the homedir, they are not
- 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 <[email protected]>
-
- * g10.c (main): Use of EXTSEP_S in new gpg.conf string.
- * openfile.c (copy_options_file): Ditto.
-
-2002-08-06 David Shaw <[email protected]>
-
- * options.h, g10.c (main), mainproc.c (proc_encrypted):
- --ignore-mdc-error option to turn a MDC check error into a
- warning.
-
- * encode.c (encode_crypt), g10.c (main), sign.c (sign_file,
- clearsign_file): Use the same --pgpX warning string everywhere to
- ease translations.
-
- * encode.c (write_pubkey_enc_from_list): Warn when using
- --throw-keyid with --pgpX. Noted by Vedaal Nistar.
-
- * revoke.c (export_minimal_pk, gen_desig_revoke, gen_revoke):
- Export a minimal pk along with the revocation cert when in --pgpX
- mode so that PGP can import it.
-
-2002-08-06 Werner Koch <[email protected]>
-
- * options.skel: Changed comments.
-
- * g10.c (main): Try to use "gpg.conf" as default option file.
- * openfile.c (copy_options_file): Changed name of created file.
-
-2002-08-02 Werner Koch <[email protected]>
-
- * Makefile.am (LDFLAGS): Removed DYNLINK_LDFLAGS.
-
-2002-07-30 David Shaw <[email protected]>
-
- * options.h, g10.c (main), mainproc.c (proc_encrypted): Return a
- decryption failed error if a MDC does not verify. Warn if a MDC
- is not present (can disable via --no-mdc-warning).
-
- * exec.c (exec_write), g10.c (main), keyserver.c
- (keyserver_spawn): Use new DISABLE_KEYSERVER_PATH rather than
- FIXED_EXEC_PATH.
-
-2002-07-28 David Shaw <[email protected]>
-
- * sig-check.c (do_check): Properly validate v4 sigs with no hashed
- section at all.
-
-2002-07-25 Werner Koch <[email protected]>
-
- * delkey.c (do_delete_key): Always allow to delete a key in batch mode
- when specified by fingerprint. Suggested by Enzo Michelangeli.
-
-2002-07-25 David Shaw <[email protected]>
-
- * keyedit.c (menu_revsig): Change "revsig" to honor selected uids
- so the user can revoke sigs from particular uids only.
-
- * keylist.c (list_keyblock_print): Don't display expired uids in
- --list-keys unless -v and not --list-sigs (just like revoked
- uids).
-
- * exec.c, export.c, import.c, keyedit.c, keyserver.c, misc.c:
- "Warning" -> "WARNING"
-
-2002-07-24 David Shaw <[email protected]>
-
- * main.h, import.c (parse_import_options, fix_hkp_corruption,
- import_one, delete_inv_parts), g10.c (main): New import-option
- "repair-hkp-subkey-bug", which repairs as much as possible the HKP
- mangling multiple subkeys bug. It is on by default for keyserver
- receives, and off by default for regular --import.
-
- * main.h, import.c (import, import_one, delete_inv_parts), hkp.c
- (hkp_ask_import), keyserver.c (keyserver_spawn): Use keyserver
- import options when doing keyserver receives.
-
- * options.h, exec.h, exec.c (set_exec_path, exec_write), g10.c
- (main), keyserver.c (keyserver_spawn): If the user does not use
- "exec-path", completely replace $PATH with GNUPG_LIBEXECDIR before
- calling the keyserver helper. If the user does use "exec-path",
- append GNUPG_LIBEXECDIR after the specified path.
-
-2002-07-23 David Shaw <[email protected]>
-
- * import.c (parse_import_options), export.c
- (parse_export_options): Fix offset problem with reversed ("no-")
- meanings.
-
- * import.c (delete_inv_parts): Discard subkey signatures (0x18 and
- 0x28) if found in the userid section of the key.
-
- * sig-check.c (signature_check2): Signatures made by invalid
- subkeys (bad/missing binding sig) are also invalid.
-
- * keylist.c (print_fingerprint): Show the primary as well as the
- secondary key fingerprint in modes 1 & 2.
-
-2002-07-22 David Shaw <[email protected]>
-
- * options.h, main.h, g10.c (main), import.c
- (parse_import_options, delete_inv_parts), keyserver.c
- (parse_keyserver_options): add new --import-options option. The
- only current flag is "allow-local-sigs".
-
- * g10.c (main): Don't disable MDC in pgp7 mode.
-
- * options.h, g10.c (main), keyserver.c (parse_keyserver_options):
- Remove old keyserver-option include-attributes now that there is
- an export-option for the same thing.
-
- * options.h, main.h, export.c (parse_export_options,
- do_export_stream), g10.c (main): add new --export-options option.
- Current flags are "include-non-rfc", "include-local-sigs",
- "include-attributes", and "include-sensitive-revkeys".
-
- * options.h, hkp.c (hkp_export), keyserver.c
- (parse_keyserver_options, keyserver_spawn): try passing unknown
- keyserver options to export options, and if successful, use them
- when doing a keyserver --send-key.
-
- * build-packet.c (build_sig_subpkt): We do not generate
- SIGSUBPKT_PRIV_VERIFY_CACHE anymore.
-
- * revoke.c (gen_desig_revoke): Lots more comments about including
- sensitive revkeys along with the revocation sig itself.
-
- * keyserver.c (parse_keyserver_options): Simpler implementation
- that can skip one pass over the options.
-
-2002-07-18 David Shaw <[email protected]>
-
- * keyedit.c (keyedit_menu, menu_addrevoker): Allow specifying
- "sensitive" as an argument to an addrevoker command. This sets
- the 0x40 sensitive revoker flag.
-
- * revoke.c (gen_desig_revoke): When generating a designated
- revocation, include the direct key sig that contains the
- designated revoker subpacket. This allows sensitive designated
- revocation subpackets to be exported. Also indicate which
- revokers are sensitive in the first place.
-
-2002-07-17 David Shaw <[email protected]>
-
- * keyedit.c (show_key_with_all_names_colon): The 0x40 class bit in
- a designated revoker means "sensitive", not "local". It's
- exportable under the right circumstances.
-
- * main.h, options.h, export.c (do_export_stream), g10.c (main),
- hkp.c (hkp_export), keyserver.c (keyserver_spawn: Add a flag to
- skip attribute packets and their signatures while exporting. This
- is to accomodate keyservers (pksd again) that choke on attributes.
- Use keyserver-option "include-attributes" to control it. This
- defaults to ON (i.e. don't skip).
-
-2002-07-09 David Shaw <[email protected]>
-
- * options.h, keyserver.c (parse_keyserver_uri, keyserver_spawn,
- keyserver_work), hkp.c (hkp_ask_import, hkp_export, hkp_search):
- Use a much more strict reading of RFC-2396 for the keyserver URIs.
- Specifically, don't try and be smart about checking the value of
- ":port" so long as it is all digits, and properly handle opaque
- data (those scheme specific parts that do not start with "//").
-
-2002-07-04 David Shaw <[email protected]>
-
- * photoid.c (get_default_photo_command, show_photos): Honor
- FIXED_PHOTO_VIEWER and DISABLE_PHOTO_VIEWER.
-
- * mainproc.c (check_sig_and_print): Use --show-photos to show
- photos when verifying a sig made by a key with a photo.
-
- * keyserver.c (parse_keyserver_uri): Properly parse a URI with no
- :port section and an empty file path, but with a terminating '/'.
- (keyserver_work): Honor DISABLE_KEYSERVER_HELPERS.
-
- * hkp.c (hkp_ask_import): Display keyserver URI as a URI, but only
- if verbose.
-
- * exec.c, g10.c: USE_EXEC_PATH -> FIXED_EXEC_PATH
-
-2002-07-03 David Shaw <[email protected]>
-
- * exec.h, exec.c (set_exec_path, exec_write), g10.c (main): If
- USE_EXEC_PATH is defined at compile time, use it to lock the
- exec-path and not allow the user to change it.
-
-2002-07-02 David Shaw <[email protected]>
-
- * options.h, g10.c (main), keyserver.c (keyserver_refresh):
- Maintain and use the original keyserver URI for cosmetics rather
- than trying to recreate it when needed.
-
- * mainproc.c (check_sig_and_print): Properly disregard expired
- uids. Make sure that the first uid listed is a real uid and not
- an attribute (attributes should only be listed in the "aka"
- section). When there are no valid textual userids, try for an
- invalid textual userid before using any attribute uid.
-
-2002-07-01 David Shaw <[email protected]>
-
- * options.skel: Fix a few typos, clarify "group", and remove
- sample photo viewers for Win32 since they are the defaults now.
-
- * parse-packet.c (make_attribute_uidname), keylist.c
- (dump_attribs): Fix two typecast warnings.
-
- * packet.h, build-packet.c (build_attribute_subpkt), exec.c
- (expand_args), mkdtemp.c (mkdtemp), photoid.c
- (parse_image_header): Fix some signedness compiler warnings.
-
-2002-07-01 Werner Koch <[email protected]>
-
- * photoid.c (get_default_photo_command): Also use __MINGW32__
- instead of HAVE_DOSISH_SYSTEM.
-
- * encode.c (encode_symmetric): Do not use the new encryption code.
-
-2002-06-30 Werner Koch <[email protected]>
-
- * 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.
-
-2002-06-21 Stefan Bellon <[email protected]>
-
- * g10.c [__riscos__]: Moved RISC OS specific stuff to util/riscos.c
- and include/util.h.
-
- * gpgv.c [__riscos__]: Likewise.
-
-2002-06-20 David Shaw <[email protected]>
-
- * keydb.h, pkclist.c (select_algo_from_prefs): Allow passing a
- suggested algorithm which will be used if available.
-
- * encode.c (encode_crypt, encrypt_filter), sign.c (sign_file): Use
- new select_algo_from_prefs feature to check if forcing an
- algorithm would violate the recipient preferences.
-
- * photoid.c (get_default_photo_command, show_photos): Use
- different default viewers on different platforms. Currently we
- have Win 9x, Win NT (2k, xp), Mac OSX, RISC OS, and "everybody
- else". These are #ifdefs as much as possible to avoid clutter.
-
- * g10.c (strusage, build_list), keyedit.c (show_prefs), main.h,
- misc.c (compress_algo_to_string, check_compress_algo), pkclist.c
- (algo_available), keygen.c (keygen_set_std_prefs): New
- algo_to_string and check functions for compress algorithms.
-
-2002-06-20 Werner Koch <[email protected]>
-
- * misc.c (setsysinfo): Removed a #warning for Alpha's uniligedn
- trap disabling - it is quite possible that this is a debug relict.
-
-2002-06-20 Stefan Bellon <[email protected]>
-
- * g10.c [__riscos__]: Added image file system feature.
-
- * gpgv.c [__riscos__]: Added image file system feature.
-
- * photoid.c (show_photos) [__riscos__]: Set RISC OS filetype of
- photo id according to MIME type.
-
-2002-06-19 David Shaw <[email protected]>
-
- * hkp.c (parse_hkp_index): Don't leak memory when failing out of a
- bad HKP keyserver.
-
- * g10.c (add_notation_data): Relax slightly the rules as to what
- can go into a notation name - 2440 allows "@", for example.
-
-2002-06-17 David Shaw <[email protected]>
-
- * import.c (clean_subkeys, import_one): Only allow at most 1
- binding sig and at most 1 revocation sig on a subkey, as per
- 2440:11.1.
-
- * hkp.c (parse_hkp_index, hkp_search): Error if the keyserver
- returns an unparseable HKP response.
-
-2002-06-15 David Shaw <[email protected]>
-
- * keyedit.c (show_key_with_all_names), keylist.c
- (list_keyblock_print): Show "[expired]" before expired uids.
-
- * keyedit.c (show_key_with_all_names_colon), mainproc.c
- (list_node), keylist.c (list_keyblock_colon): Show flag 'e' for
- expired user ids. Use "uat" for user attribute packets instead of
- "uid". Also use '<count> <length>' rather than the fake user id
- string on attributes.
-
- * keygen.c (keygen_add_revkey): Remove unused code.
-
- * misc.c (check_permissions): Check directory permissions
- properly - they are not special files.
-
- * pkclist.c (expand_id, expand_group, build_pk_list): When
- expanding groups before building a pk list, inherit flags from the
- original pre-expanded string.
-
- * pubkey-enc.c (is_algo_in_prefs): Don't use prefs from expired
- uids.
-
-2002-06-14 David Shaw <[email protected]>
-
- * free-packet.c (copy_signature): Properly copy a signature that
- carries a revocation key on it.
-
- * pkclist.c (expand_id, expand_group, build_pk_list): Groups now
- work properly when used in the "Enter the user ID" prompt.
-
-2002-06-14 David Shaw <[email protected]>
-
- * keyedit.c (show_key_with_all_names): Display warning if a user
- tries to show prefs on a v3 key with a v3 selfsig.
-
- * kbnode.c (dump_kbnode): Show if a uid is expired.
-
- * import.c (merge_blocks, import_revoke_cert): Show user ID
- receiving a revocation certificate.
-
- * free-packet.c (cmp_user_ids): Properly compare attribute ids.
-
- * pkclist.c (expand_groups): Maintain the strlist flags while
- expanding. Members of an expansion inherit their flags from the
- expansion key.
-
- * options.h, cipher.c (write_header), g10.c (main), keygen.c
- (keygen_set_std_prefs): remove the personal_mdc flag. It no
- longer serves a purpose now that the personal preference lists are
- split into cipher/digest/zip.
-
-2002-06-14 Timo Schulz <[email protected]>
-
- * skclist.c (is_insecure): Implemented.
-
-2002-06-12 David Shaw <[email protected]>
-
- * keyserver.c (keyserver_spawn): Properly handle PROGRAM responses
- when they have a CRLF ending. Noted by Keith Ray.
-
- * keyserver.c (keyserver_spawn): Handle CRLF endings from
- keyserver helpers. Also don't leak the last line worth of memory
- from the keyserver response.
-
- * main.h, misc.c (deprecated_warning): New function to warn about
- deprecated options and commands.
-
- * g10.c (main), keyserver-internal.h, keyserver.c
- (parse_keyserver_uri): Use new deprecated function to warn about
- honor-http-proxy, auto-key-retrieve, and x-broken-hkp.
-
-2002-06-11 David Shaw <[email protected]>
-
- * Makefile.am: link gpg with NETLIBS for the built-in HKP access.
-
-2002-06-10 David Shaw <[email protected]>
-
- * options.h, keyserver.c (keyserver_opts), g10.c (main): New
- keyserver option "include-subkeys". This feature already existed,
- but now can be turned off. It defaults to on.
-
- * options.h, keyserver.c (parse_keyserver_options,
- keyserver_spawn): There are now enough options to justify making a
- structure for the keyserver options rather than a page of
- if-then-else-if-then-etc.
-
- * getkey.c (merge_keys_and_selfsig, merge_selfsigs_main): Fix bug
- in calculating key expiration dates.
-
-2002-06-09 David Shaw <[email protected]>
-
- * keydb.h, getkey.c (get_user_id_native), import.c (import_one):
- Display user ID while importing a key. Note this applies to both
- --import and keyserver --recv-keys.
-
- * exec.c (exec_finish): Log unnatural exit (core dump, killed
- manually, etc) for fork/exec/pipe child processes.
-
-2002-06-08 Timo Schulz <[email protected]>
-
- * encode.c (encode_symmetric): Disable the compat flag
- when the expert mode is enabled.
-
-2002-06-07 David Shaw <[email protected]>
-
- * options.skel, options.h, main.h, keydb.h, pkclist.c
- (build_pk_list, expand_groups), g10.c (main, add_group): Add new
- "group" command to allow one name to expand into multiple keys.
- For simplicity, and to avoid potential loops, we only expand once
- - you can't make an alias that points to an alias.
-
- * main.h, g10.c (main), keygen.c (build_personal_digest_list):
- Simplify the default digest list - there is really no need for the
- other hashes since they will never be used after SHA-1 in the
- list.
-
- * options.skel, options.h, g10.c (main), hkp.c (hkp_ask_import,
- hkp_export, hkp_search), keyserver.c (parse_keyserver_options,
- parse_keyserver_uri, keyserver_work, keyserver_refresh): Make the
- "x-broken-hkp" keyserver scheme into keyserver-option
- "broken-http-proxy". Move honor_http_proxy into
- keyserver_options. Canonicalize the three variations of "hkp",
- "x-hkp", and "x-broken-hkp" into "hkp".
-
-2002-06-07 Stefan Bellon <[email protected]>
-
- * g10.c [__riscos__]: Added --attribute-file to do the same as
- --attribute-fd, but with a filename not a fd as argument.
- Added magic symbol for RISC OS to use different memory management.
-
- * gpgv.c [__riscos__]: Added magic symbol for RISC OS to use
- different memory management.
-
-2002-06-06 David Shaw <[email protected]>
-
- * main.h, g10.c (main), keygen.c (build_personal_digest_list): Put
- in a default digest preference list consisting of SHA-1, followed
- by every other installed digest except MD5. Note this is the same
- as having no digest preference at all except for SHA-1 being
- favored.
-
- * options.h, g10.c (main), keygen.c (keygen_set_std_prefs),
- pkclist.c (select_algo_from_prefs): Split
- --personal-preference-list into three:
- --personal-{cipher|digest|compress}-preferences. This allows a
- user to set one without affecting another (i.e. setting only a
- digest pref doesn't imply an empty cipher pref).
-
- * exec.c (exec_read): This is a safer way of guessing the return
- value of system(). Noted by Stefan Bellon.
-
-2002-06-05 David Shaw <[email protected]>
-
- * hkp.c (parse_hkp_index): Be more robust with keyservers
- returning very unparseable responses.
-
- * exec.c (exec_read): Catch and display an error when the remote
- process exits unnaturally (i.e. segfault) so the user knows what
- happened. Also fix exec_write stub which has a different number
- of arguments now.
-
-2002-06-05 Timo Schulz <[email protected]>
-
- * 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 <[email protected]>
-
- * 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 <[email protected]>
-
- * mainproc.c (symkey_decrypt_sesskey): New.
- (proc_symkey_enc): Support for encrypted session keys.
-
-2002-06-04 David Shaw <[email protected]>
-
- * sign.c (hash_for, sign_file): When encrypting and signing at the
- same time, consult the various hash prefs to pick a hash algorithm
- to use. Pass in a 160-bit hint if any of the signing keys are
- DSA.
-
- * keydb.h, pkclist.c (select_algo_from_prefs, algo_available):
- Pass a "hints" opaque pointer in to let the caller give hints as
- to what algorithms would be acceptable. The only current hint is
- for PREFTYPE_HASH to require a 160-bit hash for DSA. Change all
- callers in encode.c (encode_crypt, encrypt_filter) and sign.c
- (sign_file). If we settle on MD5 as the best algorithm based
- solely on recepient keys and SHA1 is also a possibility, use SHA1
- unless the user intentionally chose MD5. This is as per 2440:13.
-
- * exec.c (make_tempdir): Fix duplicated filename problem.
-
-2002-06-03 David Shaw <[email protected]>
-
- * packet.h, parse-packet.c (enum_sig_subpkt): Report back from
- enum_sig_subpkt when a subpacket is critical and change all
- callers in keylist.c (show_policy_url, show_notation), mainproc.c
- (print_notation_data), and pkclist.c (do_show_revocation_reason).
-
- * keylist.c (show_policy_url, show_notation): Display if the
- policy or notation is critical.
-
-2002-06-03 David Shaw <[email protected]>
-
- * main.h, g10.c (main), keylist.c (dump_attribs, set_attrib_fd,
- list_keyblock_print, list_keyblock_colon), status.h, status.c
- (get_status_string): New --attribute-fd feature to dump the
- contents of attribute subpackets for frontends. If --status-fd is
- also used, then a new status tag ATTRIBUTE is provided for each
- subpacket.
-
- * packet.h, getkey.c (fixup_uidnode, merge_selfsigs_main,
- merge_selfsigs_subkey), parse-packet.c (setup_user_id): Keep track
- of the expiration time of a user ID, and while we're at it, use
- the expired flag from the selfsig rather than reparsing the
- SIG_EXPIRE subpacket.
-
- * photoid.c (generate_photo_id): When adding a new photo ID,
- 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 <[email protected]>
-
- * options.skel: Sample photo viewers for Win32.
-
- * misc.c (pct_expando): Use the seckey for %k/%K if the pubkey is
- not available.
-
- * photoid.h, photoid.c (show_photos): Include the seckey in case a
- user tries to view a photo on a secret key, and change all callers
- in keyedit.c (menu_showphoto), keylist.c (list_keyblock_print),
- and photoid.c (generate_photo_id).
-
-2002-06-02 David Shaw <[email protected]>
-
- * photoid.c (show_photos): Work properly when not called with a
- public key.
-
-2002-05-31 David Shaw <[email protected]>
-
- * sign.c (mk_notation_and_policy): Free unneeded buffer.
-
- * hkp.c (parse_hkp_index): Properly handle the '&' character
- (i.e. "&amp;") in HKP responses.
-
- * getkey.c (merge_selfsigs_main): Fix reversed expiration time
- check with self-sigs.
-
- * keyedit.c (sign_uids): When making a new self-sig on a v3 key,
- make a v3 self-sig unless it is currently a v3 self-sig being
- promoted to v4.
-
-2002-05-31 Timo Schulz <[email protected]>
-
- * pkclist.c (do_show_revocation_reason): Don't use capital
- 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 <[email protected]>
-
- * sign.c (write_signature_packets, sign_file, clearsign_file,
- sign_symencrypt_file): Make a v4 signature if a policy URL or
- notation is set, unless v3 sigs are forced via rfc1991 or
- force-v3-sigs. Also remove some doubled code and clarify an error
- message (we don't sign in PGP2 mode - just detach-sign).
-
- * parse-packet.c (parse_one_sig_subpkt): Add KS_FLAGS to the "any
- size" section.
-
-2002-05-29 David Shaw <[email protected]>
-
- * keygen.c (keygen_set_std_prefs, add_feature_mdc): Use "mdc" and
- "no-mdc" in the prefs string to allow switching on and off the MDC
- feature. This is needed to properly export a key from GnuPG for
- use on PGP which does not support MDC - without this, MDC-capable
- implementations will still try and generate MDCs which will break
- PGP.
-
- * keygen.c (keygen_get_std_prefs): Show "[mdc]" in prefs string if
- it is enabled.
-
- * options.h, g10.c (main), cipher.c (write_header), keygen.c
- (keygen_set_std_prefs): For consistency, allow the user to specify
- mdc/no-mdc in the --personal-preference-list. If disabled, it
- acts just like --disable-mdc.
-
-2002-05-29 David Shaw <[email protected]>
-
- * options.h, exec.c: Add some debugging info, using the 1024 debug
- flag.
-
- * exec.c (win_system): New system()-like function for win32 that
- does not return until the child process terminates. Of course,
- this doesn't help if the process itself exits before it is
- finished.
-
-2002-05-29 Werner Koch <[email protected]>
-
- * encode.c (encode_simple): Intialize PKT when --no-literal is used.
-
- * keyedit.c (show_key_with_all_names_colon): Renamed the record
- for revocation keys to "rvk".
-
-2002-05-27 Werner Koch <[email protected]>
-
- * keyedit.c (show_key_with_all_names_colon): New.
- (show_key_with_all_names): Divert to new function when required.
- Sanitize printing of revoker name.
-
-2002-05-27 David Shaw <[email protected]>
-
- * build-packet.c (build_sig_subpkt): Handle setting sig flags for
- certain subpacket types (notation, policy url, exportable,
- revocable). keyedit.c (sign_mk_attrib): Flags no longer need to
- be set here.
-
- * packet.h, parse-packet.c (parse_one_sig_subpkt), build-packet.c
- (build_sig_subpkt): Call parse_one_sig_subpkt to sanity check
- buffer lengths before building a sig subpacket.
-
-2002-05-26 David Shaw <[email protected]>
-
- * sign.c (mk_notation_and_policy): Include secret key to enable %s
- expandos, and pass notations through pct_expando as well.
-
- * main.h, misc.c (pct_expando): Add %s and %S expandos for
- signer's keyid.
-
-2002-05-25 David Shaw <[email protected]>
-
- * g10.c (strusage, build_list): Add compress algorithms to
- --version list. Show algorithm numbers when --verbose --version
- is done.
-
-2002-05-22 David Shaw <[email protected]>
-
- * options.h, main.h, keygen.c (keygen_set_set_prefs,
- keygen_get_std_prefs, keygen_upd_std_prefs), keyedit.c
- (keyedit_menu), g10.c (main), pkclist.c (select_algo_from_prefs):
- Add --personal-preference-list which allows the user to factor in
- their own preferred algorithms when the preference lists are
- consulted. Obviously, this does not let the user violate a
- recepient's preferences (and the RFC) - this only influences the
- ranking of the agreed-on (and available) algorithms from the
- recepients. Suggested by David Hollenberg.
-
- * options.h, keygen.c (keygen_set_std_prefs), g10.c (main): Rename
- --preference-list to --default-preference-list (as that is what it
- really is), and make it a true default in that if the user selects
- "default" they get this list and not the compiled-in list.
-
-2002-05-22 Werner Koch <[email protected]>
-
- * g10.c (main): Add missing LF in a info printout and made it
- translatable. Noted by Michael Tokarev.
-
-2002-05-21 Werner Koch <[email protected]>
-
- * g10.c (main): Removed the undef of USE_SHM_COPROCESSING which
- was erroneously introduced on 2002-01-09.
-
- * signal.c (got_fatal_signal): Don't write the Nul to stderr.
- Reported by David Hollenberg.
-
-2002-05-18 David Shaw <[email protected]>
-
- * main.h, g10.c (main), revoke.c (gen_desig_revoke): Generate a
- designated revocation via --desig-revoke
-
- * keyedit.c (keyedit_menu, menu_addrevoker): New "addrevoker"
- command to add a designated revoker to a key.
-
-2002-05-17 David Shaw <[email protected]>
-
- * gpgv.c: Add stub for get_ownertrust().
-
- * g10.c (main): --allow-freeform-uid should be implied by
- OpenPGP. Add --no-allow-freeform-uid.
-
- * keyedit.c (sign_uids): Issue a warning when signing a
- non-selfsigned uid.
-
- * getkey.c (merge_selfsigs_main): If a key has no selfsigs, and
- allow-non-selfsigned-uid is not set, still try and make the key
- valid by checking all uids for a signature from an ultimately
- trusted key.
-
-2002-05-16 David Shaw <[email protected]>
-
- * main.h, keygen.c (keygen_add_revkey): Add revocation key
- subpackets to a signature (callable by
- make_keysig_packet). (write_direct_sig): Write a 1F direct key
- signature. (parse_revocation_key): Parse a string in
- algo:fpr:sensitive format into a revocation
- key. (get_parameter_revkey, do_generate_keypair): Call above
- functions when prompted from a batch key generation file.
-
- * build-packet.c (build_sig_subpkt): Allow multiple revocation key
- subpackets in a single sig.
-
- * keydb.h, getkey.c (get_seckey_byfprint): Same as
- get_pubkey_byfprint, except for secret keys. We only know the
- fingerprint of a revocation key, so this is needed to retrieve the
- secret key needed to issue a revokation.
-
- * packet.h, parse-packet.c (parse_signature, parse_revkeys): Split
- revkey parsing off into a new function that can be used to reparse
- after manipulating the revkey list.
-
- * sign.c (make_keysig_packet): Ability to make 1F direct key
- signatures.
-
-2002-05-15 David Shaw <[email protected]>
-
- * options.skel: keyserver.pgp.com is gone, so list pgp.surfnet.nl
- as a sample LDAP server instead.
-
- * getkey.c (merge_selfsigs_main): Properly handle multiple
- revocation keys in a single packet. Properly handle revocation
- keys that are in out-of-order packets. Remove duplicates in
- revocation key list.
-
-2002-05-14 Timo Schulz <[email protected]>
-
- * exec.c (make_tempdir) [MINGW32]: Added missing '\'.
-
-2002-05-14 Stefan Bellon <[email protected]>
-
- * exec.c (make_tempdir): Make use of EXTSEP_S instead of hardcoded
- dot as extension separator.
-
-2002-05-13 David Shaw <[email protected]>
-
- * photoid.c (show_photos): Use the long keyid as the filename for
- the photo. Use the short keyid as the filename on 8.3 systems.
-
- * exec.h, exec.c (make_tempdir, exec_write, exec_finish): Allow
- caller to specify filename. This should make things easier on
- windows and macs where the file extension is required, but a whole
- filename is even better.
-
- * keyedit.c (show_key_with_all_names, show_prefs): Show proper
- prefs for a v4 key uid with no selfsig at all.
-
- * misc.c (check_permissions): Don't check permissions on
- non-normal files (pipes, character devices, etc.)
-
-2002-05-11 Werner Koch <[email protected]>
-
- * mainproc.c (proc_symkey_enc): Avoid segv in case the parser
- encountered an invalid packet.
-
- * keyserver.c (keyserver_export): Get confirmation before sending
- all keys.
-
-2002-05-10 Stefan Bellon <[email protected]>
-
- * g10.c, hkp.c, keyedit.c, keyserver.c: Replaced all occurrances
- of strcasecmp with ascii_strcasecmp and all occurrances of
- strncasecmp with ascii_memcasecmp.
-
-2002-05-10 David Shaw <[email protected]>
-
- * packet.h, getkey.c (fixup_uidnode), keyedit.c (show_prefs): Show
- assumed prefs for hash and compression as well as the cipher pref.
- Show assumed prefs if there are no prefs at all on a v4
- self-signed key.
-
- * options.h, g10.c (main), sign.c (make_keysig_packet): New
- --cert-digest-algo function to override the default key signing
- hash algorithm.
-
-2002-05-09 David Shaw <[email protected]>
-
- * getkey.c (merge_selfsigs_main): Make sure the revocation key
- list starts clean as this function may be called more than once
- (e.g. from functions in --edit).
-
- * g10.c, encode.c (encode_crypt), sign.c (sign_file,
- sign_symencrypt_file): Make --compress-algo work like the
- documentation says. It should be like --cipher-algo and
- --digest-algo in that it can override the preferences calculation
- and impose the setting the user wants. No --compress-algo setting
- allows the usual preferences calculation to take place.
-
- * main.h, compress.c (compress_filter): use new
- DEFAULT_COMPRESS_ALGO define, and add a sanity check for compress
- algo value.
-
-2002-05-08 David Shaw <[email protected]>
-
- * pkclist.c (select_algo_from_prefs): There is an assumed
- compression preference for uncompressed data.
-
-2002-05-07 David Shaw <[email protected]>
-
- * options.h, g10.c (main), getkey.c (finish_lookup), pkclist.c
- (algo_available): --pgp7, identical to --pgp6 except that it
- permits a few algorithms that PGP 7 added: AES128, AES192, AES256,
- and TWOFISH. Any more of these --pgpX flags, and it'll be time to
- start looking at a generic --emulate-pgp X option.
-
- * export.c (do_export_stream): Warn the user when exporting a
- secret key if it or any of its secret subkeys are protected with
- SHA1 while simple_sk_checksum is set.
-
- * parse-packet.c (parse_key): Show when the SHA1 protection is
- used in --list-packets.
-
- * options.h, build-packet.c (do_comment), g10.c (main): Rename
- --no-comment as --sk-comments/--no-sk-comments (--no-comment still
- works) and make the default be --no-sk-comments.
-
-2002-05-07 Werner Koch <[email protected]>
-
- * keygen.c (get_parameter_algo): Never allow generation of the
- deprecated RSA-E or RSA-S flavors of PGP RSA.
- (ask_algo): Allow generation of RSA sign and encrypt in expert
- mode. Don't allow ElGamal S+E unless in expert mode.
- * helptext.c: Added entry keygen.algo.rsa_se.
-
-2002-05-07 David Shaw <[email protected]>
-
- * keyedit.c (sign_uids): If --expert is set, allow re-signing a
- uid to promote a v3 self-sig to a v4 one. This essentially
- deletes the old v3 self-sig and replaces it with a v4 one.
-
- * packet.h, parse-packet.c (parse_key), getkey.c
- (merge_keys_and_selfsig, merge_selfsigs_main): a v3 key with a v4
- self-sig must never let the v4 self-sig express a key expiration
- time that extends beyond the original v3 expiration time.
-
-2002-05-06 David Shaw <[email protected]>
-
- * keyedit.c (sign_uids): When making a self-signature via "sign"
- don't ask about sig level or expiration, and include the usual
- preferences and such for v4 self-sigs. (menu_set_preferences):
- Convert uids from UTF8 to native before printing.
-
- * keyedit.c (sign_uids): Convert uids from UTF8 to native before
- printing. (menu_set_primary_uid): Show error if the user tries to
- make a uid with a v3 self-sig primary.
-
-2002-05-05 David Shaw <[email protected]>
-
- * import.c (import_one): When merging with a key we already have,
- don't let a key conflict (same keyid but different key) stop the
- import: just skip the bad key and continue.
-
- * exec.c (make_tempdir): Under Win32, don't try environment
- variables for temp directories - GetTempDir tries environment
- variables internally, and it's better not to second-guess it in
- case MS adds some sort of temp dir handling to Windows at some
- point.
-
-2002-05-05 Timo Schulz <[email protected]>
-
- * mainproc.c (proc_symkey_enc): Don't ask for a passphrase
- in the list only mode.
-
-2002-05-05 David Shaw <[email protected]>
-
- * keyserver.c (keyserver_refresh): --refresh-keys implies
- --merge-only so as not to import keys with keyids that match the
- ones being refreshed. Noted by Florian Weimer.
-
-2002-05-04 Stefan Bellon <[email protected]>
-
- * free-packet.c (copy_public_key): Don't call m_alloc(0), therefore
- added consistency check for revkey and numrefkeys.
-
- * getkey.c (check_revocation_keys): Added consistency check for
- revkey and numrefkeys.
-
- * keyedit.c (show_key_with_all_names): Likewise.
-
-2002-05-03 David Shaw <[email protected]>
-
- * photoid.c: Provide default image viewer for Win32.
-
- * misc.c (pct_expando): %t means extension, not name ("jpg", not
- "jpeg").
-
- * keyserver.c (keyserver_spawn), photoid.c (show_photos), exec.h,
- exec.c: Allow the caller to determine the temp file extension when
- starting an exec_write and change all callers.
-
- * keyedit.c (sign_uids): Nonrevocable key signatures cause an
- automatic promotion to v4.
-
- * exec.c: Provide stubs for exec_ functions when NO_EXEC is
- defined.
-
-2002-05-02 David Shaw <[email protected]>
-
- * photoid.h, photoid.c (parse_image_header, image_type_to_string):
- Useful functions to return data about an image.
-
- * packet.h, parse-packet.c (make_attribute_uidname,
- parse_attribute_subpkts, parse_attribute), photoid.h, photoid.c
- (show_photos): Handle multiple images in a single attribute
- packet.
-
- * main.h, misc.c (pct_expando), sign.c (mk_notation_and_policy),
- photoid.c (show_photos): Simpler expando code that does not
- require using compile-time string sizes. Call
- image_type_to_string to get image strings (i.e. "jpg",
- "image/jpeg"). Change all callers.
-
- * keyedit.c (menu_showphoto), keylist.c (list_keyblock_print):
- Allow viewing multiple images within a single attribute packet.
-
- * gpgv.c: Various stubs for link happiness.
-
-2002-05-02 David Shaw <[email protected]>
-
- * build-packet.c (build_sig_subpkt), keyedit.c (sign_uids),
- options.h, sign.c (mk_notation_and_policy), g10.c (main,
- add_notation_data, add_policy_url (new), check_policy_url
- (removed)): Allow multiple policy URLs on a given signature.
- Split "--notation-data" into "--cert-notation" and
- "--sig-notation" so the user can set different policies for key
- and data signing. For backwards compatibility, "--notation-data"
- sets both, as before.
-
-2002-05-02 Werner Koch <[email protected]>
-
- * options.skel: Removed the comment on trusted-keys because this
- option is now deprecated.
-
-2002-05-01 David Shaw <[email protected]>
-
- * keyedit.c (menu_adduid): 2440bis04 says that multiple attribute
- packets on a given key are legal.
-
- * keyserver.c (keyserver_refresh): the fake v3 keyid hack applies
- to "mailto" URLs as well since they are also served by pksd.
-
-2002-04-29 Werner Koch <[email protected]>
-
- Added a copyright year for files changed this year.
-
-2002-04-25 Werner Koch <[email protected]>
-
- * g10.c, options.h: New options --display, --ttyname, --ttytype,
- --lc-ctype, --lc-messages to be used with future versions of the
- gpg-agent.
- * passphrase.c (agent_send_option,agent_send_all_options): New.
- (agent_open): Send options to the agent.
-
- * trustdb.c (update_ownertrust, clear_ownertrust): Do an explicit
- do_sync because revalidation_mark does it only if when the
- timestamp actually changes.
-
-2002-04-23 David Shaw <[email protected]>
-
- * main.h, keygen.c (do_generate_keypair), keylist.c
- (print_signature_stats, list_all, list_one, list_keyblock,
- list_keyblock_print, list_keyblock_colon): After generating a new
- key, show the key information (name, keyid, fingerprint, etc.)
- Also do not print uncheckable signatures (missing key..) in
- --check-sigs. Print statistics (N missing keys, etc.) after
- --check-sigs.
-
- * keyedit.c (sign_uids): When signing a key with an expiration
- date on it, the "Do you want your signature to expire at the same
- time?" question should default to YES.
-
-2002-04-22 David Shaw <[email protected]>
-
- * parse-packet.c (parse_plaintext), packet.h, plaintext.c
- (handle_plaintext): Fix bug in handling literal packets with
- zero-length data (no data was being confused with partial body
- length).
-
- * misc.c (pct_expando), options.skel: %t means extension ("jpg").
- %T means MIME type ("image/jpeg").
-
- * import.c (import_one): Only trigger trust update if the keyring
- is actually changed.
-
- * export.c (do_export_stream): Missing a m_free.
-
-2002-04-22 Stefan Bellon <[email protected]>
-
- * keyid.c (expirestr_from_sk, expirestr_from_sig): Added _() to
- string constant.
-
- * exec.c (make_tempdir) [__riscos__]: Better placement of
- temporary file.
-
-2002-04-20 David Shaw <[email protected]>
-
- * keygen.c (generate_subkeypair): 2440bis04 adds that creating
- subkeys on v3 keys is a MUST NOT.
-
- * getkey.c (finish_lookup): The --pgp6 "use the primary key"
- behavior should only apply while data signing and not encryption.
- Noted by Roger Sondermann.
-
-2002-04-19 Werner Koch <[email protected]>
-
- * keygen.c (keygen_set_std_prefs): Put back 3DES because the RFC
- says it is good form to do so.
-
-2002-04-19 David Shaw <[email protected]>
-
- * keyedit.c (menu_deluid): Only cause a trust update if we delete
- a non-revoked user id.
-
- * hkp.c (hkp_ask_import), keyserver.c (parse_keyserver_options,
- keyserver_spawn), options.h: Remove fast-import keyserver option
- (no longer meaningful).
-
- * g10.c (main), keyedit.c (sign_uids), options.h: Change
- --default-check-level to --default-cert-check-level as it makes
- clear what it operates on.
-
- * g10.c (main): --pgp6 also implies --no-ask-sig-expire.
-
- * delkey.c (do_delete_key): Comment.
-
- * keyedit.c (sign_uids, keyedit_menu, menu_deluid, menu_delsig,
- menu_expire, menu_revsig, menu_revkey): Only force a trustdb check
- if we did something that changes it.
-
- * g10.c: add "--auto-check-trustdb" to override a
- "--no-auto-check-trustdb"
-
-2002-04-19 Werner Koch <[email protected]>
-
- * tdbio.c (tdbio_write_nextcheck): Return a status whether the
- stamp was actually changed.
- * trustdb.c (revalidation_mark): Sync the changes. Removed the
- 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".
- (show_key_with_all_names): Print a warning on the wrong listed key
- validity.
-
- * delkey.c (do_delete_key): Clear the owenertrust information when
- deleting a public key.
-
-2002-04-18 Werner Koch <[email protected]>
-
- * seskey.c (encode_md_value): Print an error message if a wrong
- digest algorithm is used with DSA. Changed all callers to cope
- with a NULL return. Problem noted by Imad R. Faiad.
-
-2002-04-18 David Shaw <[email protected]>
-
- * trustdb.c (mark_usable_uid_certs): Properly handle nonrevocable
- signatures that can expire. In short, the only thing that can
- override an unexpired nonrevocable signature is another unexpired
- nonrevocable signature.
-
- * getkey.c (finish_lookup): Always use primary signing key for
- signatures when --pgp6 is on since pgp6 and 7 do not understand
- signatures made by signing subkeys.
-
-2002-04-18 Werner Koch <[email protected]>
-
- * trustdb.c (validate_keys): Never schedule a nextcheck into the
- past.
- (validate_key_list): New arg curtime use it to set next_expire.
- (validate_one_keyblock): Take the current time from the caller.
- (clear_validity, reset_unconnected_keys): New.
- (validate_keys): Reset all unconnected keys.
-
- * getkey.c (premerge_public_with_secret): Fixed 0x12345678! syntax
- for use with secret keys.
- (lookup): Advance the searchmode after a search FIRST.
-
- * seckey-cert.c (do_check): Always calculate the old checksum for
- use after unprotection.
-
- * g10.c, options.skel: New option --no-escape-from. Made
- --escape-from and --force-v3-sigs the default and removed them
- from the options skeleton.
-
-2002-04-16 Werner Koch <[email protected]>
-
- * parse-packet.c (parse_key): Support a SHA1 checksum as per
- draft-rfc2440-bis04.
- * packet.h (PKT_secret_key): Add field sha1chk.
- * seckey-cert.c (do_check): Check the SHA1 checksum
- (protect_secret_key): And create it.
- * build-packet.c (do_secret_key): Mark it as sha-1 protected.
- * g10.c, options.h: New option --simple-sk-checksum.
-
-2002-04-13 David Shaw <[email protected]>
-
- * parse-packet.c (parse_signature): Minor fix - signatures should
- expire at their expiration time and not one second later.
-
- * keygen.c (proc_parameter_file): Allow specifying preferences
- string (i.e. "s5 s2 z1 z2", etc) in a batchmode key generation
- file.
-
- * keyedit.c (keyedit_menu): Print standard error message when
- signing a revoked key (no new translation).
-
- * getkey.c (merge_selfsigs): Get the default set of key prefs from
- the real (not attribute) primary uid.
-
-2002-04-12 David Shaw <[email protected]>
-
- * pkclist.c (build_pk_list): Fix bug that allowed a key to be
- selected twice in batch mode if one instance was the default
- recipient and the other was an encrypt-to. Noted by Stefan
- Bellon.
-
- * parse-packet.c (dump_sig_subpkt): Show data in trust and regexp
- sig subpackets.
-
- * keyedit.c (keyedit_menu): Use new function real_uids_left to
- prevent deleting the last real (i.e. non-attribute) uid. Again,
- according to the attribute draft. (menu_showphoto): Make another
- string translatable.
-
-2002-04-11 David Shaw <[email protected]>
-
- * build-packet.c (build_sig_subpkt): Delete subpackets from both
- hashed and unhashed area on update. (find_subpkt): No longer
- needed.
-
- * keyedit.c (sign_uids): With --pgp2 on, refuse to sign a v3 key
- with a v4 signature. As usual, --expert overrides. Try to tweak
- some strings to a closer match so they can all be translated in
- one place. Use different helptext keys to allow different help
- text for different questions.
-
- * keygen.c (keygen_upd_std_prefs): Remove preferences from both
- hashed and unhashed areas if they are not going to be used.
-
-2002-04-10 David Shaw <[email protected]>
-
- * misc.c (pct_expando), options.skel: Use %t to indicate type of a
- photo ID (in this version, it's always "jpeg"). Also tweak string
- expansion loop to minimize reallocs.
-
- * mainproc.c (do_check_sig): Variable type fix.
-
- * keyedit.c (menu_set_primary_uid): Differentiate between true
- user IDs and attribute user IDs when making one of them primary.
- That is, if we are making a user ID primary, we alter user IDs.
- If we are making an attribute packet primary, we alter attribute
- packets. This matches the language in the latest attribute packet
- draft.
-
- * keyedit.c (sign_uids): No need for the empty string hack.
-
- * getkey.c (fixup_uidnode): Only accept preferences from the
- hashed segment of the self-sig.
-
-2002-04-10 Werner Koch <[email protected]>
-
- * tdbio.c (migrate_from_v2): Fixed the offset to read the old
- ownertrust value and only add entries to the table if we really
- have a value.
-
-2002-04-08 David Shaw <[email protected]>
-
- * status.h, status.c (get_status_string): Add KEYEXPIRED, EXPSIG,
- and EXPKEYSIG. Add "deprecated-use-keyexpired-instead" to
- SIGEXPIRED.
-
- * sig-check.c (do_check): Start transition from SIGEXPIRED to
- KEYEXPIRED, since the actual event is signature verification by an
- expired key and not an expired signature. (do_signature_check,
- packet.h): Rename as signature_check2, make public, and change all
- callers.
-
- * mainproc.c (check_sig_and_print, do_check_sig): Use status
- EXPSIG for an expired, but good, signature. Add the expiration
- time (or 0) to the VALIDSIG status line. Use status KEYEXPSIG for
- a good signature from an expired key.
-
- * g10.c (main): remove checks for no arguments now that argparse
- does it.
-
-2002-04-06 Werner Koch <[email protected]>
-
- * keyring.c (keyring_get_keyblock): Disable the keylist mode here.
-
- * encode.c (encode_simple, encode_crypt): Only test on compressed
- files if a compress level was not explicity set.
-
- * keygen.c (keygen_set_std_prefs): Removed Blowfish and Twofish
- from the list of default preferences, swapped the preferences of
- RMD160 and SHA1. Don't include a preference to 3DES unless the
- IDEA kludge gets used.
-
- * free-packet.c (free_packet): call free_encrypted also for
- PKT_ENCRYPTED_MDC.
-
- * compress.c (release_context): New.
- (handle_compressed): Allocate the context and setup a closure to
- release the context. This is required because there is no
- guarabntee that the filter gets popped from the chain at the end
- of the function. Problem noted by Timo and probably also the
- cause for a couple of other reports.
- (compress_filter): Use the release function if set.
-
- * tdbio.c [__CYGWIN32__]: Don't rename ftruncate. Noted by
- Disastry.
-
- * parse-packet.c (parse_signature): Put parens around a bit test.
-
- * exec.c (make_tempdir): Double backslash for TMP directory
- creation under Windows. Better strlen the DIRSEP_S constants for
- allocation measurements.
-
- * decrypt.c (decrypt_messages): Release the passphrase aquired
- by get_last_passphrase.
-
-2002-04-02 Werner Koch <[email protected]>
-
- * Makefile.am (EXTRA_DIST): Removed OPTIONS an pubring.asc - they
- are no longer of any use.
-
-2002-04-03 David Shaw <[email protected]>
-
- * keyserver.c (parse_keyserver_options): fix auto-key-retrieve to
- actually work as a keyserver-option (noted by Roger Sondermann).
-
- * keylist.c (reorder_keyblock): do not reorder the primary
- attribute packet - the first user ID must be a genuine one.
-
-2002-03-31 David Shaw <[email protected]>
-
- * keylist.c (list_keyblock_colon): Fix ownertrust display with
- --with-colons.
-
- * keygen.c (generate_user_id), photoid.c (generate_photo_id):
- Properly initialize the user ID refcount. A few more "y/n" ->
- "y/N" in photoid.c.
-
- * keyedit.c (ask_revoke_sig): Warn the user if they are about to
- revoke an expired sig (not a problem, but they should know). Also
- tweak a few prompts to change "y/n" to "y/N", which is how most
- other prompts are written.
-
- * keyserver.c (keyserver_search_prompt): Control-d escapes the
- keyserver search prompt.
-
- * pkclist.c (show_revocation_reason & callers): If a subkey is
- considered revoked solely because the parent key is revoked, print
- the revocation reason from the parent key.
-
- * trustdb.c (get_validity): Allow revocation/expiration to apply
- to a uid/key with no entry in the trustdb.
-
-2002-03-29 David Shaw <[email protected]>
-
- * keyserver.c (printunquoted): unquote backslashes from keyserver
- searches
-
- * hkp.c (write_quoted): quote backslashes from keyserver searches
-
-2002-03-26 Werner Koch <[email protected]>
-
- * keygen.c (ask_keysize): Removed the warning for key sizes > 1536.
-
-2002-03-25 Werner Koch <[email protected]>
-
- * keyedit.c (sign_uids): Use 2 strings and not a %s so that
- translations can be done the right way.
- * helptext.c: Fixed small typo.
-
-2002-03-23 David Shaw <[email protected]>
-
- * import.c (append_uid, merge_sigs): it is okay to import
- completely non-signed uids now (with --allow-non-selfsigned-uid).
-
- * getkey.c (get_primary_uid, merge_selfsigs_main): do not choose
- an attribute packet (i.e. photo) as primary uid. This prevents
- oddities like "Good signature from [image of size 2671]". This is
- still not perfect (one can still select an attribute packet as
- primary in --edit), but is closer to the way the draft is going.
-
- * g10.c (build_list): algorithms should include 110.
-
- * g10.c (main): --pgp2 implies --no-ask-sig-expire and
- --no-ask-cert-expire as those would cause a v4 sig/cert.
-
- * armor.c (is_armor_header): be more lenient in what constitutes a
- valid armor header (i.e. -----BEGIN blah blah-----) as some
- Windows programs seem to add spaces at the end. --openpgp makes
- it strict again.
-
-2002-03-18 David Shaw <[email protected]>
-
- * keyserver.c (keyserver_search_prompt): Properly handle a "no
- keys found" case from the internal HKP code (external HKP is ok).
- Also, make a COUNT -1 (i.e. streamed) keyserver response a little
- more efficient.
-
- * g10.c (main): Add --no-allow-non-selfsigned-uid
-
-2002-03-17 David Shaw <[email protected]>
-
- * g10.c (main): --openpgp implies --allow-non-selfsigned-uid.
-
- * getkey.c (merge_selfsigs_main): If none of the uids are primary
- (because none are valid) then pick the first to be primary (but
- still invalid). This is for cosmetics in case some display needs
- to print a user ID from a non-selfsigned key. Also use
- --allow-non-selfsigned-uid to make such a key valid and not
- --always-trust. The key is *not* automatically trusted via
- --allow-non-selfsigned-uid.
-
- * mainproc.c (check_sig_and_print): Make sure non-selfsigned uids
- print [uncertain] on verification even though one is primary now.
-
- * getkey.c (merge_selfsigs): If the main key is not valid, then
- neither are the subkeys.
-
- * import.c (import_one): Allow --allow-non-selfsigned-uid to work
- on completely unsigned keys. Print the uids in UTF8. Remove
- mark_non_selfsigned_uids_valid().
-
- * keyedit.c (show_key_with_all_names): Show revocation key as
- UTF8.
-
- * sign.c (clearsign_file): Allow --not-dash-escaped to work with
- v3 keys.
-
-2002-03-14 Werner Koch <[email protected]>
-
- * main.h: Changed the default algorithms to CAST5 and SHA1.
-
-2002-03-13 David Shaw <[email protected]>
-
- * import.c (chk_self_sigs): Show which user ID a bad self-sig
- (invald sig or unsupported public key algorithm) resides on.
-
- * import.c (chk_self_sigs): any valid self-sig should mark a user
- ID or subkey as valid - otherwise, an attacker could DoS the user
- by inventing a bogus invalid self-signature.
-
-2002-03-07 David Shaw <[email protected]>
-
- * g10.c (main): make a few more strings translatable.
-
- * options.h, options.skel, g10.c (main), gpgv.c, mainproc.c
- (check_sig_and_print), keyserver.c (parse_keyserver_options):
- --auto-key-retrieve should really be a keyserver-option variable.
-
- * import.c (revocation_present): new function to print a warning
- if a key is imported that has been revoked by designated revoker,
- but the designated revoker is not present to verify the
- revocation. If keyserver-options auto-key-retrieve is set, try
- and fetch the designated revoker from the keyserver.
-
- * 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).
-
- * keyserver.c (keyserver_import_keyid): much simpler
- implementation now that we're using KEYDB_SEARCH_DESC internally.
-
-2002-03-04 David Shaw <[email protected]>
-
- * revoke.c (gen_revoke): do not prompt for revocation reason for
- v3 revocations (unless force-v4-certs is on) since they wouldn't
- be used anyway.
-
- * keyedit.c (menu_revsig): show the status of the sigs
- (exportable? revocable?) to the user before prompting for which
- sig to revoke. Also, make sure that local signatures get local
- revocations.
-
- * keyedit.c (ask_revoke_sig): remind the user which sigs are
- local.
-
- * g10.c (main): Add "exec-path" variable to override PATH for
- execing programs.
-
- * export.c (do_export_stream): properly check return code from
- classify_user_id to catch unclassifiable keys.
-
-2002-03-03 David Shaw <[email protected]>
-
- * parse-packet.c (parse_signature): variable type tweak for RISC
- OS (from Stefan)
-
-2002-02-28 David Shaw <[email protected]>
-
- * getkey.c (check_revocation_keys): New function to check a
- revocation against a list of potential revocation keys. Note the
- loop-breaking code here. This is to prevent blowing up if A is
- B's revocation key, while B is also A's. Note also that this is
- written so that a revoked revoker can still issue revocations:
- i.e. If A revokes B, but A is revoked, B is still revoked. I'm
- not completely convinced this is the proper behavior, but it
- matches how PGP does it. It does at least have the advantage of
- much simpler code - my first version of this had lots of loop
- maintaining code so you could chain revokers many levels deep and
- if D was revoked, C was not, which meant that B was, and so on.
- It was sort of scary, actually.
-
- * getkey.c (merge_selfsigs_main): Add any revocation keys onto the
- pk. This is particularly interesting since we normally only get
- data from the most recent 1F signature, but you need multiple 1F
- sigs to properly handle revocation keys (PGP does it this way, and
- a revocation key could be marked "sensitive" and hence in a
- different signature). Also, if a pk has a revocation key set,
- check for revocation sigs that were not made by us - if made by a
- valid revocation key, mark the pk revoked.
-
- * packet.h, getkey.c (cache_public_key): do not cache key if
- "dont_cache" is set. This allows the revocation key code to look
- up a key and return information that may be inaccurate to prevent
- loops without caching the fake data.
-
- * packet.h, sig-check.c (do_signature_check): Record if a
- signature was made by a revoked pk.
-
- * 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
- verify it or if verification failed. Also, 0x1F should get listed
- as "sig", and not "unexpected signature class".
-
- * keyedit.c (show_key_with_all_names): Add a flag for printing
- revoker information and change all callers.
-
- * import.c (merge_blocks): merge in any new direct key (0x1F)
- sigs.
-
- * 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
- checked before we trust it.
-
- * free-packet.c (copy_public_key): Include a new copy of the
- revocation keys when duping a pk.
-
- * free-packet.c (free_seckey_enc, release_public_key_parts): Free
- any revocation keys that are attached to a sig or pk.
-
- * export.c (do_export_stream): Do not export signatures with
- "sensitive" revocation keys in them.
-
-2002-02-27 David Shaw <[email protected]>
-
- * export.c (do_export_stream): Do not include v3 keys in a
- --export-secret-subkeys export.
-
- * getkey.c (merge_selfsigs_main): If a key isn't valid (say,
- because of no self-signature), allow --always-trust to force it
- valid so it can be trusted.
-
-2002-02-25 David Shaw <[email protected]>
-
- * hkp.c (hkp_ask_import), hkp.h, keyserver.c (all): treat key
- lists internally as fingerprints when possible. All this is via
- KEYDB_SEARCH_DESC - no point in reinventing the wheel. This allows
- the helper program to search the keyserver by fingerprint if
- desired (and the keyserver supports it). Note that automatic
- fingerprint promotion during refresh only applies to v4 keys as a
- v4 fingerprint can be easily changed into a long or short key id,
- and a v3 cannot.
-
- * pubkey-enc.c, getkey.c, misc.c, main.h: Take two copies of
- hextobyte() from pubkey-enc.c and getkey.c and make them into one
- copy in misc.c.
-
-2002-02-22 David Shaw <[email protected]>
-
- * keyserver.c (keyserver_search_prompt): Detect a "no keys found"
- case even if the helper program does not explicitly say how many
- keys were found.
-
- * hkp.c (parse_hkp_index): Bug fix - don't report non-revoked keys
- as revoked in HKP key searches.
-
-2002-02-19 Werner Koch <[email protected]>
-
- * parse-packet.c (parse_trust): Made parsing more robust.
-
-2002-02-19 David Shaw <[email protected]>
-
- * hkp.c (parse_hkp_index): Catch corruption in HKP index lines
- (can be caused by broken or malicious keyservers).
-
- * keyserver.c (keyserver_work): Add KEYSERVER_NOT_SUPPORTED for
- unsupported actions (say, a keyserver that has no way to search,
- or a readonly keyserver that has no way to add). Also add a
- USE_EXTERNAL_HKP define to disable the internal HKP keyserver
- code.
-
-2002-02-14 Werner Koch <[email protected]>
-
- * 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
- by Janusz A. Urbanowicz.
-
-2002-02-11 David Shaw <[email protected]>
-
- * hkp.c (parse_hkp_index): Bug fix - properly handle user IDs with
- colons (":") in them while HKP searching.
-
-2002-02-09 David Shaw <[email protected]>
-
- * misc.c (pct_expando): More comments.
-
- * keydb.h, sign.c (mk_notation_and_policy): Clarify what is a sig
- and what is a cert. A sig has sigclass 0x00, 0x01, 0x02, or 0x40,
- and everything else is a cert.
-
- * g10.c (main), keyedit.c (keyedit_menu): Add a "nrlsign" for
- nonrevocable and local key signatures.
-
- * g10.c (main): Add a --no-force-mdc to undo --force-mdc.
-
- * 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.
-
- * 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.
-
-2002-02-04 David Shaw <[email protected]>
-
- * main.h, misc.c (pct_expando): New function to generalize
- %-expando processing in any arbitrary string.
-
- * 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
- policy URLs of the form "http://notary.jabberwocky.com/keysign/%K"
- which will generate a per-signature policy URL.
-
- * main.h, keylist.c (show_policy_url, show_notation): Add amount
- to indent so the same function can be used in key listings as well
- as during sig generation. Change all callers.
-
-2002-02-04 David Shaw <[email protected]>
-
- * keyserver.c, options.h (parse_keyserver_options, keyidlist):
- Workaround for the pksd and OKS keyserver bug that calculates v4
- RSA keyids as if they were v3. The workaround/hack is to fetch
- both the v4 (e.g. 99242560) and v3 (e.g. 68FDDBC7) keyids. This
- only happens for key refresh while using the HKP scheme and the
- refresh-add-fake-v3-keyids keyserver option must be set. This
- should stay off by default.
-
-2002-02-03 David Shaw <[email protected]>
-
- * keyserver.c (keyserver_spawn): Bug fix - do not append keys to
- each other when --sending more than one.
-
-2002-02-02 David Shaw <[email protected]>
-
- * options.h, g10.c (main), keyedit.c (sign_uids), sign.c
- (mk_notation_and_policy): Split "--set-policy-url" into
- "--cert-policy-url" and "--sig-policy-url" so the user can set
- different policies for key and data signing. For backwards
- compatibility, "--set-policy-url" sets both, as before.
-
-2002-01-30 Werner Koch <[email protected]>
-
- * g10.c (main): --gen-random --armor does now output a base64
- encoded string.
-
-2002-01-28 David Shaw <[email protected]>
-
- * g10.c (main), options.h, pkclist.c (algo_available): --pgp6
- flag. This is not nearly as involved as --pgp2. In short, it
- turns off force_mdc, turns on no_comment, escape_from, and
- force_v3_sigs, and sets compression to 1. It also restricts the
- user to IDEA (if present), 3DES, CAST5, MD5, SHA1, and RIPEMD160.
- See the comments above algo_available() for lots of discussion on
- why you would want to do this.
-
-2002-01-27 David Shaw <[email protected]>
-
- * keygen.c (keygen_set_std_prefs): Comment
-
- * keyedit.c (sign_uids): Bug fix - when signing with multiple
- secret keys at the same time, make sure each key gets the sigclass
- prompt.
-
- * exec.c (exec_finish): Close the iobuf and FILE before trying to
- waitpid, so the remote process will get a SIGPIPE and exit. This
- is only a factor when using a pipe to communicate.
-
- * exec.c (exec_write): Disable cache-on-close of the fd iobuf (is
- this right? Why is a fd iobuf cached at all?)
-
-2002-01-26 Werner Koch <[email protected]>
-
- * g10.c, options.h: New option --gpg-agent-info
- * passphrase.c (agent_open): Let it override the environment info.
- * seckey-cert.c (check_secret_key): Always try 3 times when the
- agent is enabled.
- * options.skel: Describe --use-agent.
-
-2002-01-24 David Shaw <[email protected]>
-
- * pubkey-enc.c (is_algo_in_prefs, get_it): Only check preferences
- against keys with v4 self sigs - there is really little point in
- warning for every single non-IDEA message encrypted to an old key.
-
- * pkclist.c (select_algo_from_prefs): Only put in the fake IDEA
- preference if --pgp2 is on.
-
- * mainproc.c (check_sig_and_print): Print "Expired" for expired
- but good signatures (this still prints "BAD" for expired but bad
- signatures).
-
-2002-01-23 David Shaw <[email protected]>
-
- * keygen.c (ask_keysize): Cosmetic: don't present a RSA signing
- key as a "keypair" which can be 768 bits long (as RSA minimum is
- 1024).
-
- * pubkey-enc.c (is_algo_in_prefs): Allow IDEA as a fake preference
- for v3 keys with v3 selfsigs.
-
-2002-01-22 David Shaw <[email protected]>
-
- * packet.h, getkey.c (merge_selfsigs_main), pkclist.c
- (select_algo_from_prefs): Implement the fake IDEA preference as
- per RFC2440:12.1. This doesn't mean that IDEA will be used (the
- plugin may not be present), but it does mean that a v3 key with a
- v3 selfsig has an implicit IDEA preference instead of 3DES. v3
- keys with v4 selfsigs use preferences as normal.
-
- * encode.c (encode_crypt): if select_algo_from_prefs fails, this
- means that we could not find a cipher that both keys like. Since
- all v4 keys have an implicit 3DES preference, this means there is
- a v3 key with a v3 selfsig in the list. Use 3DES in this case as
- it is the safest option (we know the v4 key can handle it, and
- we'll just hope the v3 key is being used in an implementation that
- can handle it). If --pgp2 is on, warn the user what we're doing
- since it'll probably break PGP2 compatibility.
-
- * g10.c (main): Do not force using IDEA for encrypted files in
- --pgp2 mode - let the fake IDEA preference choose this for us for
- better compatibility when encrypting to multiple keys, only some
- of which are v3.
-
- * keygen.c (keygen_set_std_prefs): Put 3DES on the end of the
- default cipher pref list (RFC2440: "...it is good form to place it
- there explicitly."). If the user has the IDEA plugin installed,
- put a preference for IDEA *after* 3DES to effectively disable its
- use for everything except encrypting along with v3 keys.
-
- * encode.c, g10.c, sign.c: Change the PGP2 warning line from
- "... will not be usable ..." to "... may not be usable ..." as the
- user could be using one of the enhanced PGP2 variations.
-
- * helptext.c: Revise the sign_uid.class help text as suggested by
- Stefan.
-
-2002-01-20 Werner Koch <[email protected]>
-
- * passphrase.c (passphrase_to_dek): Add tryagain_text arg to be
- used with the agent. Changed all callers.
- (agent_get_passphrase): Likewise and send it to the agent
- * seckey-cert.c (do_check): New arg tryagain_text.
- (check_secret_key): Pass the string to do_check.
- * keygen.c (ask_passphrase): Set the error text is required.
- * keyedit.c (change_passphrase): Ditto.
-
- * passphrase.c (agent_open): Disable opt.use_agent in case of a
- problem with the agent.
- (agent_get_passphrase): Ditto.
- (passphrase_clear_cache): Ditto.
-
-2002-01-19 Werner Koch <[email protected]>
-
- * passphrase.c (agent_open): Add support for the new Assuan based
- gpg-agent. New arg to return the used protocol version.
- (agent_get_passphrase): Implemented new protocol here.
- (passphrase_clear_cache): Ditto.
- (readline): New.
-
-2002-01-15 Timo Schulz <[email protected]>
-
- * 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 <[email protected]>
-
- * g10.c, misc.c, gpgv.c: move idea_cipher_warn to misc.c so gpgv.c
- doesn't need a stub for it any longer.
-
- * g10.c (get_temp_dir), main.h: no longer used (it's in exec.c now)
-
- * g10.c (main), delkey.c (delete_keys), main.h : Allow
- --delete-key (now --delete-keys, though --delete-key still works,
- of course) to delete multiple keys in one go. This applies to
- --delete-secret-key(s) and --delete-secret-and-public-key(s) as
- well.
-
-2002-01-09 Timo Schulz <[email protected]>
-
- * 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.
-
-2002-01-09 Timo Schulz <[email protected]>
-
- * exec.c: Include windows.h for dosish systems.
-
-2002-01-08 Timo Schulz <[email protected]>
-
- * g10.c (main): New description for --encrypt-files.
-
-2002-01-08 Werner Koch <[email protected]>
-
- * g10.c (main): Must register the secring for encryption because
- it is needed to figure out the default recipient. Reported by
- Roger Sondermann.
-
-2002-01-05 David Shaw <[email protected]>
-
- * keyedit.c (menu_adduid): Require --expert before adding a photo
- ID to a v3 key, and before adding a second photo ID to any key.
-
- * keyedit.c (keyedit_menu): Don't allow adding photo IDs in
- rfc1991 or pgp2 mode.
-
- * getkey.c (merge_selfsigs_subkey): Permit v3 subkeys. Believe it
- or not, this is allowed by rfc 2440, and both PGP 6 and PGP 7 work
- fine with them.
-
- * g10.c, options.h, keyedit.c, sign.c: Move the "ask for
- expiration" switch off of --expert, which was getting quite
- overloaded, and onto ask-sig-expire and ask-cert-expire. Both
- default to off.
-
- * g10.c (main): Change the default compression algo to 1, to be
- more OpenPGP compliant (PGP also uses this, so it'll help with
- interoperability problems as well).
-
- * encode.c (encode_crypt): Handle compression algo 2, since the
- default is now 1.
-
- * build-packet.c (build_attribute_subpkt): Fix off-by-one error.
-
-2002-01-05 Werner Koch <[email protected]>
-
- * g10.c (main): Do not register the secret keyrings for certain
- commands.
-
- * keydb.c (keydb_add_resource): Use access to test for keyring
- existence. This avoids cached opened files which are bad under
- RISC OS.
-
-2002-01-04 David Shaw <[email protected]>
-
- * sign.c (sign_file, sign_symencrypt_file): always use one-pass
- packets unless rfc1991 is enabled. This allows a signature made
- with a v3 key to work in PGP 6 and 7. Signatures made with v4
- keys are unchanged.
-
- * g10.c (main): Disallow non-detached signatures in PGP2 mode.
- Move the "you must use files and not pipes" PGP2 warning up so all
- the PGP2 stuff is together.
-
- * encode.c (encode_simple): Use the actual filesize instead of
- partial length packets in the internal literal packet from a
- symmetric message. This breaks PGP5(?), but fixes PGP2, 6, and 7.
- It's a decent tradeoff. Note there was only an issue with
- old-style RFC1991 symmetric messages. 2440-style messages in 6
- and 7 work with or without partial length packets.
-
-2002-01-03 David Shaw <[email protected]>
-
- * g10.c (main): Removed --no-default-check-level option, as it is
- not consistent with other "default" options. Plus, it is the same
- as saying --default-check-level 0.
-
- * exec.c (exec_read): Disallow caching tempfile from child
- process, as this keeps the file handle open and can cause unlink
- problems on some platforms.
-
- * keyserver.c (keyserver_search_prompt): Minor tweak - don't
- bother to transform keyids into textual form if they're just going
- to be transformed back to numbers.
-
-2002-01-03 Timo Schulz <[email protected]>
-
- * g10.c: New command --encrypt-files.
-
- * verify.c (print_file_status): Removed the static because
- encode_crypt_files also uses this function.
-
- * main.h (print_files_status): New.
- (encode_crypt_files): New.
-
- * encode.c (encode_crypt_files): New.
-
-2002-01-02 Stefan Bellon <[email protected]>
-
- * keyserver.c: Moved util.h include down in order to avoid
- redefinition problems on RISC OS.
-
- * keyring.c (keyring_lock): Only lock keyrings that are writable.
-
- * keyring.c (keyring_update_keyblock): Close unused iobuf.
-
- * hkp.c (parse_hkp_index, hkp_search) [__riscos__]: Changed
- unsigned char* to char* because of compiler issues.
-
- * exec.c (exec_finish) [__riscos__]: Invalidate close cache so
- that file can be unlinked.
-
-2001-12-28 David Shaw <[email protected]>
-
- * g10.c (main): Use a different strlist to check extensions since
- they need to be handled seperately now.
-
- * misc.c,main.h (check_permissions): Properly handle permission
- and ownership checks on files in the lib directory
- (e.g. /usr/local/lib/gnupg), which are owned by root and are
- world-readable, and change all callers to specify extension or
- per-user file.
-
- * photoid.c (show_photo), keyserver.c (keyserver_spawn): Bug fix -
- don't call exec_finish if exec_write fails.
-
- * keyserver.c (keyserver_spawn): Look for OPTIONS from the
- keyserver helper - specifically, a "OUTOFBAND" option for the
- email keyserver.
-
- * mainproc.c (list_node), keylist.c (list_keyblock_colon),
- import.c (delete_inv_parts), export.c (do_export_stream): Use
- signature flags for exportability check rather than re-parsing the
- subpacket.
-
- * keyid.c, keydb.h (get_lsign_letter): No longer needed.
-
-2001-12-27 David Shaw <[email protected]>
-
- * exec.c (exec_finish): Show errors when temp files cannot be
- deleted for whatever reason.
-
- * exec.c (exec_read): Don't rely on WEXITSTATUS being present.
-
- * exec.c (make_tempdir): Add temp file creator for win32. Don't
- create an incoming temp file if the exec is write-only.
-
- * keyserver.c (keyserver_spawn): Clean up error handling, for when
- the spawn fails.
-
- * photoid.c (show_photo): Clean up error handling.
-
- * misc.c (check_permissions): Neaten.
-
-2001-12-25 David Shaw <[email protected]>
-
- * mkdtemp.c (mkdtemp): Add copyleft info and tweak the 'X' counter
- to be a bit simpler.
-
- * keyserver.c, photoid.c: Remove unused headers left over from
- when the exec functions lived there.
-
-2001-12-23 Timo Schulz <[email protected]>
-
- * misc.c (check_permissions): Do not use it for W32 systems.
-
- * tdbio.c (migrate_from_v2): Define ftruncate as chsize() for W32.
-
- * mkdtemp.c: W32 support.
-
- * photoid.c: Ditto.
-
- * exec.c: Ditto.
-
-2001-12-22 David Shaw <[email protected]>
-
- * exec.c (make_tempdir): avoid compiler warning with const
-
- * mkdtemp.c (mkdtemp): catch the empty ("") string case in case
- someone repurposes mkdtemp at some point.
-
- * photoid.c (generate_photo_id, show_photo): some type changes
- from Stefan Bellon.
-
- * exec.c (make_tempdir): handle Win32 systems, suggested by Timo
- Schulz.
-
-2001-12-22 Werner Koch <[email protected]>
-
- * encode.c (encode_simple, encode_crypt): i18n 2 strings.
-
-2001-12-22 Timo Schulz <[email protected]>
-
- * encode.c (encode_simple, encode_crypt): Use is_file_compressed
- to avoid to compress compressed files.
-
-2001-12-22 Werner Koch <[email protected]>
-
- * keyserver.c (keyserver_spawn): Removed some variables
- declaration due to shadowing warnings.
-
- * build-packet.c (build_attribute_subpkt): s/index/idx/ to avoid
- compiler warnig due to index(3).
-
- * getkey.c (get_ctx_handle): Use KEYDB_HANDLE as return value.
- * keylist.c (list_one): Made resname const.
-
- * keyedit.c (keyedit_menu): Allow "addphoto" only when --openpgp is
- not used.
-
- * options.skel: Changed one example photo viewer to qiv.
-
-2001-12-21 David Shaw <[email protected]>
-
- * Makefile.am: add exec.c, exec.h, photoid.c, and photoid.h
-
- * build-packet.c (build_attribute_subpkt): new function to build
- the raw attribute subpacket. Note that attribute subpackets have
- the same format as signature subpackets.
-
- * exec.c: new file with generic exec-a-program functionality.
- Used by both photo IDs and keyserver helpers. This is pretty much
- the same code that used to be keyserver specific, with some
- changes to be usable generically.
-
- * 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",
- and "delphoto" (same as "deluid").
-
- * 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.
-
- * g10.c, options.h: three new options - --{no-}show-photos, and
- --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.
-
- * parse-packet.c (make_attribute_uidname (new)): constructs a fake
- "name" for attribute packets (e.g. "[image of size ...]")
-
- * parse-packet.c (parse_attribute (replaces parse_photo_id),
- parse_attribute_subpkts): Builds an array of individual
- attributes. Currently only handles attribute image / type jpeg
- subpackets.
-
- * sign.c (hash_uid): Fix bug in signing attribute (formerly
- photo_id) packets.
-
- * packet.h, and callers: globally change "photo_id" to "attribute"
- and add structures for attributes. The packet format is generic
- attributes, even though the only attribute type thus far defined
- is jpeg.
-
-2001-12-21 David Shaw <[email protected]>
-
- * parse-packet.c (can_handle_critical): Can handle critical
- revocation subpackets now.
-
- * trustdb.c (mark_usable_uid_certs): Disregard revocations for
- nonrevocable sigs. Note that this allows a newer revocable
- signature to override an older nonrevocable signature.
-
- * sign.c (make_keysig_packet): add a duration field and change all
- callers. This makes make_keysig_packet closer to
- write_signature_packets and removes some duplicated expiration
- code.
-
- * keyedit.c (keyedit_menu, menu_revsig, sign_uids,
- sign_mk_attrib): Add nrsign command, don't allow revoking a
- nonrevocable signature,
-
- * g10.c (main): Add --nrsign option to nonrevocably sign a key
- from the command line.
-
- * build-packet.c (build_sig_subpkt_from_sig): Comment to explain
- the use of CRITICAL.
-
-2001-12-21 Werner Koch <[email protected]>
-
- * g10.c. options.h : New option --show-keyring
- * getkey.c (get_ctx_handle): New.
- * keylist.c (list_one): Implement option here. By David Champion.
-
-2001-12-20 David Shaw <[email protected]>
-
- * keyserver.c (keyserver_spawn): Use mkdtemp() to make temp
- directory.
-
- * mkdtemp.c: replacement function for those platforms that don't
- have mkdtemp (make a temp directory securely).
-
-2001-12-19 David Shaw <[email protected]>
-
- * misc.c (check_permissions): New function to stat() and ensure
- the permissions of GNUPGHOME and the files have safe permissions.
-
- * keydb.c (keydb_add_resource): Check keyring permissions.
-
- * tdbio.c (tdbio_set_dbname): Check permissions of trustdb.gpg
-
- * keyserver.c (keyserver_spawn): Disable keyserver schemes that
- involve running external programs if the options file has unsafe
- permissions or ownership.
-
- * g10.c, options.h: New option --no-permission-warning to disable
- 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
- based on get_random_bits() instead. Also try a few times to get
- the temp dir before giving up.
-
-2001-12-19 Werner Koch <[email protected]>
-
- * g10.c, passphrase.c [CYGWIN32]: Allow this as an alias for MINGW32.
-
-2001-12-18 David Shaw <[email protected]>
-
- * g10.c (idea_cipher_warn): Add a flag to show the warning always
- or once per session and change all callers (show always except for
- the secret key protection and unknown cipher from an encrypted
- message errors). Also make the strings translatable.
-
- * pubkey-enc.c (get_it): Add the IDEA cipher warning if the user
- tries to decrypt an IDEA encrypted message without the IDEA
- plugin.
-
- * keyserver.c (parse_keyserver_uri): More strict checking of the
- keyserver URI. Specifically, fail if the ":port" section is
- anything except a number between 1 and 65535.
-
-2001-12-17 David Shaw <[email protected]>
-
- * keyserver.c (print_keyinfo): No need to check for
- control/illegal characters, as utf8_to_native does this for us.
-
- * mainproc.c (proc_encrypted): Use generic IDEA warning.
-
- * gpgv.c: add stub for idea_cipher_warn
-
- * g10.c, hkp.c, keyserver.c: Fix capitalization and plural issues.
-
- * encode.c (encode_crypt), sign.c (sign_file, clearsign_file):
- disable pgp2 mode after the message is no longer pgp2 compatible.
-
- * g10.c (main): Tweak the PGP2.x IDEA warning to use the generic
- warning, and not merely fail if the IDEA plugin isn't there.
-
- * g10.c (main, idea_cipher_warn), keygen.c (set_one_pref),
- seckey-cert.c (do_check): Add a generic IDEA warning for when the
- IDEA plugin is not present. This pops up when the user uses
- "--cipher-algo idea", when setpref is used to set a "S1"
- preference, and when a secret key protected with IDEA is used.
-
-2001-12-15 Werner Koch <[email protected]>
-
- * keyserver.c (keyserver_spawn): Assert that we have dropped privs.
-
-2001-12-13 Werner Koch <[email protected]>
-
- * pubkey-enc.c (get_session_key): Check that the public key
- algorithm is indeed usable for en/decryption. This avoid a
- strange error message from pubkey_decrypt if for some reasons a
- bad algorithm indentifier is passed.
-
-2001-12-12 David Shaw <[email protected]>
-
- * Fixed some types for portability. Noted by Stefan Bellon.
-
-2001-12-11 Werner Koch <[email protected]>
-
- * hkp.c (hkp_export): Do not print possible control characters
- from a keyserver response.
- (parse_hkp_index): Made uid an unsigned char* because it is passed to
- isspace().
- (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
- check.
-
-2001-12-07 David Shaw <[email protected]>
-
- * g10.c, options.h: New option --pgp2. This is identical to
- "--rfc1991 --cipher-algo idea --compress-algo 1 --digest-algo md5
- --force_v3_sigs" with the addition of an warning to advise the
- user not to use a pipe (which would break pgp2 compatibility).
-
- * encode.c (encode_crypt): warn if the user tries to encrypt to
- any key that is not RSA and <= 2048 bits when the --pgp2 option is
- used.
-
- * sign.c (sign_file, clearsign_file): When using --pgp2, make a v3
- sig, and warn if the signature is made with a non-v3 key.
-
-2001-12-05 David Shaw <[email protected]>
-
- * sign.c (sign_file, clearsign_file, sign_symencrypt_file): Prompt
- for sig expiration if --expert is set and --force-v3-sigs is not
- set (v3 sigs cannot expire).
-
- * mainproc.c (check_sig_and_print): After checking a sig, print
- expiration status. This causes a error return if the sig is
- expired.
-
- * build-packet.c (build_sig_subpkt_from_sig): Include a critical
- sig expiration subpacket if the sig is to expire.
-
- * keyedit.c (sign_uids): Do not sign an expired key unless
- --expert is set, in which case prompt. Also, offer to expire a
- signature when the key the user is signing expires.
-
- * keygen.c (ask_expire_interval): Add a value to determine whether
- to prompt for a key or sig expiration and change all callers.
-
- * keyid.c: New functions: expirestr_from_sig and
- colon_expirestr_from_sig.
-
- * keylist.c (list_keyblock_colon): Show sig expiration date in the
- --with-colons listing.
-
- * sign.c (make_keysig_packet, write_signature_packets): Pass in an
- optional timestamp for the signature packet, and change all
- callers.
-
- * keyedit.c (sign_mk_attrib): Include a critical expiration
- subpacket in the signature if an expiration date is given.
-
-2001-12-04 David Shaw <[email protected]>
-
- * keyedit.c (sign_uids): If the user tries to sign a
- locally-signed key, allow the cert to be promoted to a full
- exportable signature. This essentially deletes the old
- non-exportable sig, and replaces it with a new exportable one.
-
-2001-12-04 David Shaw <[email protected]>
-
- * keyedit.c (keyedit_menu): Do not allow signing a revoked key
- unless --expert is set, and ask even then.
-
- * keyedit.c (sign_uids): Do not allow signing a revoked UID unless
- --expert is set, and ask even then.
-
- * g10.c, options.h : New option --expert
-
-2001-11-16 David Shaw <[email protected]>
-
- * Allow the user to select no compression via "--compress-algo 0"
- on the command line.
-
- * keyedit.c (show_prefs): Show compression preferences in the
- long-form "showpref" style.
-
- * keygen.c (set_one_pref): Permit setting a no-compression ("Z0")
- preference.
-
- * getkey.c (fixup_uidnode): Fix compression preference corruption
- bug.
-
-2001-12-02 David Shaw <[email protected]>
-
- * g10.c: Add advisory --for-your-eyes-only option as per section
- 5.9 of 2440.
-
-2001-12-05 David Shaw <[email protected]>
-
- * Force a V4 sig if the user has a notation or policy URL set.
-
-2001-12-04 David Shaw <[email protected]>
-
- * g10.c: Add options --keyserver-options, --temp-directory, and
- auto-key-retrieve (the opposite of no-auto-key-retrieve).
-
- * hkp.c (hkp_search): New function to handle searching a HKP
- keyserver for a key
-
- * hkp.c (hkp_ask_import, hkp_export): Pretty large changes to make
- them communicate via the generic functions in keyserver.c
-
- * keyserver.c: new file with generic keyserver routines for
- getting keys from a keyserver, sending keys to a keyserver, and
- searching for keys on a keyserver. Calls the internal HKP stuff
- in hkp.c for HKP keyserver functions. Other calls are handled by
- an external program which is spawned and written to and read from
- via pipes. Platforms that don't have pipes use temp files.
-
-2001-11-20 David Shaw <[email protected]>
-
- * options.h, g10.c: New options show-notation, no-show-notation,
- default-check-level, no-default-check-level, show-policy-url,
- no-show-policy-url.
-
- * packet.h, sign.c (make_keysig_packet), parse-packet.c
- (parse_signature), free-packet.c (free_seckey_enc): Fill in
- structures for notation, policy, sig class, exportability, etc.
-
- * keyedit.c, keylist.c (print_and_check_one_sig,
- list_keyblock_print): Show flags in signature display for cert
- details (class, local, notation, policy, revocable). If selected,
- show the notation and policy url.
-
- * keyedit.c (sign_uids): Prompt for and use different key sig
- classes.
-
- * helptext.c (helptexts): Add help text to explain different
- key signature classes
-
-2001-11-26 David Shaw <[email protected]>
-
- * trustdb.c (mark_usable_uid_certs): Fix segfault from bad
- initialization and fix reversed key signature expiration check.
-
-2001-11-09 Werner Koch <[email protected]>
-
- * export.c (do_export_stream): Put all given names into a search
- description and change the loop so that all matching names are
- returned.
-
-2001-11-08 Werner Koch <[email protected]>
-
- * pubkey-enc.c (get_it): To reduce the number of questions on the
- MLs print the the name of cipher algorithm 1 with the error message.
-
- * mainproc.c: Changed the way old rfc1991 encryption cipher is
- 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"
- * 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.
-
- * g10.c, options.h : New option --[no-]froce-v4-certs.
- * sign.c (make_keysig_packet): Create v4 sigs on v4 keys even with
- a v3 key. Use that new option. By David Shaw
-
- * revoke.c (ask_revocation_reason): Allow to select "no reason".
- By David Shaw.
-
- * keyid.c (fingerprint_from_sk): Calculation of an v3 fpr was
- plain wrong - nearly the same code in fingerprint_from_pk is correct.
-
- * build-packet.c (do_secret_key): Added a few comments to the code.
-
-2001-11-07 Werner Koch <[email protected]>
-
- * g10.c (main): Print a warning when -r is used w/o encryption.
- Suggested by Pascal Scheffers.
-
-2001-10-23 Werner Koch <[email protected]>
-
- * keyedit.c (keyedit_menu): Changed helptext for showpref
- command. Suggested by Reinhard Wobst.
-
- * keyring.c (keyring_search): When marking the offtbl ready, take
- into account that we may have more than one keyring.
-
-2001-10-22 Werner Koch <[email protected]>
-
- * Makefile.am: Do not use OMIT_DEPENDENCIES
-
- * build-packet.c (build_sig_subpkt): Default is now to put all
- types of subpackets into the hashed area and only list those which
- should go into the unhashed area.
-
-2001-10-18 Werner Koch <[email protected]>
-
- * keydb.c (keydb_add_resource): Rearranged the way we keep track
- of the resource. There will now be an entry for each keyring here
- and not in keyring.c itself. Store a token to allow creation of a
- keyring handle. Changed all functions to utilize this new design.
- (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_rebuild_cache): Add an arg to pass the token from keydb.
-
-2001-10-17 Werner Koch <[email protected]>
-
- * keyring.c (keyring_search): Enabled word search mode but print a
- warning that it is buggy.
-
-2001-10-11 Werner Koch <[email protected]>
-
- * hkp.c (hkp_ask_import): No more need to set the port number for
- the x-hkp scheme.
- (hkp_export): Ditto.
-
-2001-10-06 Stefan Bellon <[email protected]>
-
- * passphrase.c [__riscos__]: Disabled agent specific stuff.
- * g10.c: New option --no-force-v3-sigs.
-
-2001-10-04 Werner Koch <[email protected]>
-
- * 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.
-
-2001-09-28 Werner Koch <[email protected]>
-
- * keyedit.c (sign_uids): Always use the primary key to sign keys.
- * getkey.c (finish_lookup): Hack to return only the primary key if
- a certification key has been requested.
-
- * trustdb.c (cmp_kid_for_make_key_array): Renamed to
- (validate_one_keyblock): this and changed arg for direct calling.
- (make_key_array): Renamed to
- (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.
- (validate_keys): Ditto for UTKs and write the stamp.
-
- * tdbio.c (migrate_from_v2): Check return code of tbdio_sync.
-
- * tdbdump.c (import_ownertrust): Do a tdbio_sync().
-
- * keyring.c: Made the offtbl an global object.
-
-2001-09-27 Werner Koch <[email protected]>
-
- * pkclist.c (do_edit_ownertrust): Allow settin of ultimate trust.
-
- * trustdb.c (mark_keyblock_seen): New.
- (make_key_array): Use it to mark the subkeys too.
- (validate_keys): Store validity for ultimatly trusted keys.
-
-2001-09-26 Werner Koch <[email protected]>
-
- * pkclist.c (check_signatures_trust, do_we_trust): Removed the
- invocation of add_ownertrust. Minor changes to the wording.
- (add_ownertrust, add_ownertrust_cb): Removed.
-
- * trustdb.c (get_validity): Allow to lookup the validity using a
- subkey.
-
- * trustdb.c (new_key_hash_table): Increased the table size to 1024
- and changed the masks accordingly.
- (validate): Changed stats printing.
- (mark_usable_uid_certs): New.
- (cmp_kid_for_make_key_array): Does now check the signatures and
- figures out a usable one.
-
-2001-09-25 Werner Koch <[email protected]>
-
- * keyring.c (new_offset_item,release_offset_items)
- (new_offset_hash_table, lookup_offset_hash_table)
- (update_offset_hash_table, update_offset_hash_table_from_kb): New.
- (keyring_search): Use a offset table to optimize search for
- unknown keys.
- (keyring_update_keyblock, keyring_insert_keyblock): Insert new
- offsets.
- * getkey.c (MAX_UNK_CACHE_ENTRIES): Removed the unknown keys
- caching code.
-
- * g10.c, options.h, import.c: Removed the entire
- allow-secret-key-import stuff because the validity is now
- controlled by other means.
-
- * g10.c: New command --rebuild-keydb-caches.
- * keydb.c (keydb_rebuild_caches): New.
- * keyring.c (do_copy): Moved some code to
- (create_tmp_file, rename_tmp_file, write_keyblock): new functions.
- (keyring_rebuild_cache): New.
-
- * packet.h (PKT_ring_trust): Add sigcache field.
- * parse-packet.c (parse_trust): Parse sigcache.
- * keyring.c (do_copy): Always insert a sigcache packet.
- (keyring_get_keyblock): Copy the sigcache packet to the signature.
- * sig-check.c (cache_sig_result): Renamed from
- cache_selfsig_result. Changed implementation to use the flag bits
- and changed all callers.
- (mdc_kludge_check): Removed this unused code.
- (do_check): Do not set the sig flags here.
-
- * import.c (read_block): Make sure that ring_trust packets are
- never imported.
- * export.c (do_export_stream): and never export them.
-
- * trustdb.c (make_key_array): Skip revoked and expired keys.
-
-2001-09-24 Werner Koch <[email protected]>
-
- * g10.c, options.h: New option --no-auto-check-trustdb.
-
- * keygen.c (do_generate_keypair): Set newly created keys to
- ultimately trusted.
-
- * tdbio.h, tdbio.c: Removed all support for records DIR, KEY, UID,
- PREF, SIG, SDIR and CACH. Changed migration function to work
- direct on the file.
- (tdbio_read_nextcheck): New.
- (tdbio_write_nextcheck): New.
-
-2001-09-21 Werner Koch <[email protected]>
-
- 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
- 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.
- * keydb.h: Removed the TDBIDX mode add a skipfnc to the
- descriptor.
- * keyring.c (keyring_search): Implemented skipfnc.
-
- * passphrase.c (agent_open): Add missing bracket. Include windows.h.
-
-2001-09-19 Werner Koch <[email protected]>
-
- * keylist.c (print_fingerprint): Renamed from fingerprint, made
- global available. Added new arg to control the print style.
- * mainproc.c (print_fingerprint): Removed.
- * pkclist.c (print_fpr, fpr_info): Removed and changed callers to
- use print_fingerprint.
- * keyedit.c (show_fingerprint): Ditto.
-
- * passphrase.c (writen, readn)
- (agent_open, agent_close)
- (agent_get_passphrase)
- (passphrase_clear_cache): Support for W32. Contributed by Timo.
-
- * import.c (import_one): Release keydb handles at 2 more places.
-
- * 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_release_stats_handle): New.
- (import_print_stats): Renamed from static fnc print_stats.
- (import_keys, import_keys_stream): Add an optional status handle
- arg and changed all callers.
- * hkp.c (hkp_ask_import): Add an stats_handle arg and changed all
- callers.
-
- * mainproc.c (print_pkenc_list): Use print_utf8_string2().
-
-2001-09-18 Werner Koch <[email protected]>
-
- * g10.c: New command --refresh-keys.
- * hkp.c (hkp_refresh_keys): New. Contributed by Timo Schulz.
-
- * parse-packet.c (parse): Stop on impossible packet lengths.
-
-2001-09-17 Werner Koch <[email protected]>
-
- * mainproc.c (print_notation_data): Wrap notation data status lines
- after 50 chars.
-
- * mainproc.c (proc_pubkey_enc): Make option try-all-secrets work.
-
-2001-09-14 Werner Koch <[email protected]>
-
- * parse-packet.c (dump_sig_subpkt): List key server preferences
- and show the revocable flag correctly. Contributed by David Shaw.
-
-2001-09-09 Werner Koch <[email protected]>
-
- * keyedit.c (keyedit_menu): No need to define another p.
-
- * keylist.c (print_capabilities): s/used/use/ so that it
- does not shadow a global.
- * sign.c (sign_file): Renamed arg encrypt to encryptflag
- * keygen.c: Replaced all "usage" by "use".
- * misc.c (openpgp_pk_algo_usage): Ditto.
-
- * pubkey-enc.c (get_it): Renamed arg k to enc so that the later
- defined k does not shadow it.
-
- * parse-packet.c (parse_gpg_control): No need to define another i.
-
- * getkey.c (get_pubkey_byfprint): Must use the enum values and not
- the fprint_len.
- * keyring.c (keyring_search): Removed a non-sense break. Both
- bugs pointed out by Stefan.
-
-2001-09-07 Werner Koch <[email protected]>
-
- * status.c, status.h: Added NO_RECP and ALREADY_SIGNED.
- * pkclist.c (build_pk_list): Issue NO_RECP.
- * keyedit.c (sign_uids): Added experimental ALREADY_SIGNED
-
- * hkp.c (hkp_import): Use log_error. Bug reported by Neal H
- 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
- union to this function. Changed all callers.
- (classify_user_id): Ditto and allow to pass NULL as the description.
-
-2001-09-06 Werner Koch <[email protected]>
-
- * getkey.c (fixup_uidnode): Features flag is now a bit vector.
- * keygen.c (add_feature_mdc): Ditto.
-
- Revamped the entire key I/O code to be prepared for other ways of
- key storages and to get rid of the existing shit. GDBM support has
- gone.
- * keydb.c: New
- * 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.
- (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
- arg. Changed all callers.
- (key_byname): Use get_pubkey_end to release the context and take
- new ret_kbdhd arg. Changed all callers.
- (classify_user_id2): Fill the 16 byte fingerprint up with 4 null
- bytes not with zero bytes of value 4, tsss.
- * 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.
- * keyedit.c (keyedit_menu): Ditto.
- (get_keyblock_byname): Removed.
- * 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.
- * 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 <[email protected]>
-
- * passphrase.c (agent_get_passphrase): Changed nread to size_t.
- (passphrase_clear_cache): Ditto.
-
- * keyid.c (mk_datestr): Avoid trigraphs.
- (fingerprint_from_pk): Cache the keyid in the pk.
-
- * options.h: Add opt.with_fingerprint so that we know whether the
- corresponding options was used.
- * g10.c (main): Set it here.
- * pkclist.c (check_signatures_trust): Always print fingerprint
- when this option is used. Mixed a minor memory leak.
-
- * status.c, status.h: New status INV_RECP.
- * pkclist.c (build_pk_list): Issue this status.
-
-2001-08-31 Werner Koch <[email protected]>
-
- * 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
- * status.c (write_status_text_and_buffer): New.
-
-2001-08-30 Werner Koch <[email protected]>
-
- * packet.h (sigsubpkttype_t): Add SIGSUBPKT_FEATURES.
- (PKT_public_key, PKT_user_id): Add a flag for it.
- * parse-packet.c, build-packet.c: Add support for them.
- * getkey.c (fixup_uidnode, merge_selfsigs): Set the MDC flags.
- * keygen.c (add_feature_mdc): New.
- (keygen_upd_std_prefs): Always set the MDC feature.
- * keyedit.c (show_prefs): List the MDC flag
- * pkclist.c (select_mdc_from_pklist): New.
- * encode.c (encode_crypt, encrypt_filter): Test whether MDC
- should be used.
- * cipher.c (write_header): Set MDC use depending on the above test.
- Print more status info.
-
- * delkey.c (do_delete_key): Kludge to delete a secret key with no
- public key available.
-
- * ringedit.c (find_secret_keyblock_direct): New.
- * getkey.c (seckey_available): Simplified.
-
- * ringedit.c (cmp_seckey): Now compares the secret key against the
- public key while ignoring all secret parts.
- (keyring_search): Use a public key packet as arg. Allow to search
- for subnkeys
- (search): Likewise. Changed all callers.
- (find_secret_keyblock_bypk): New.
- (find_secret_keyblock_byname): First locate the pubkey and then
- find the correponding secret key.
- * parse-packet.c (parse): Renamed pkttype arg to onlykeypkts and
- changed code accordingly. Changed all callers.
- (search_packet): Removed pkttype arg.
- * keyedit.c (keyedit_menu): First locate the public key and then
- try to locate a secret key.
-
- * ringedit.c (locate_keyblock_by_fpr): Removed.
- (locate_keyblock_by_keyid): Removed.
- (find_keyblock_bysk): Removed.
-
- * sig-check.c (check_key_signature2): Print the keyid along with
- the wrong sig class errors.
-
-2001-08-24 Werner Koch <[email protected]>
-
- * sign.c (sign_file): Stripped the disabled comment packet code.
- (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
- (write_signature_packets): this new function.
- (write_signature_packets, make_keysig_packet)
- (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
- (write_plaintext_packet): this new function.
-
-2001-08-21 Stefan Bellon <[email protected]>
-
- * trustdb.c (query_trust_info): Changed trustlevel to signed int.
- * g10.c [__riscos__]: Fixed handling of --use-agent --lock-multiple.
-
-2001-08-20 Werner Koch <[email protected]>
-
- * encr-data.c (decrypt_data): Keep track on whether we already
- printed information about the used algorithm.
- * mainproc.c (proc_encrypted): Removed the non-working IDEA hack
- and print a message about the assumed algorithm.
- * passphrase.c (passphrase_to_dek): Use the same algorithm as above.
- (proc_symkey_enc): Print the algorithm, so that the user knows it
- before entering the passphrase.
- (proc_pubkey_enc, proc_pubkey_enc): Zero the DEK out.
- * encode.c (encode_crypt, encrypt_filter): Ditto.
-
- * g10.c: Allow for --sign --symmetric.
- * sign.c (sign_and_symencrypt): New.
-
- Applied patches from Stefan Bellon <[email protected]> to support
- RISC OS. Nearly all of these patches are identified by the
- __riscos__ macro.
- * compress.c: Added a couple of casts.
- * 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.
- * passprase.c [__riscos__]: Disabled agent stuff
- * trustdb.c (check_trust): Changed r_trustlevel to signed int to
- avoid mismatch problems in pkclist.c
- * pkclist.c (add_ownertrust): Ditto.
- * plaintext.c (handle_plaintext) [__riscos__]: Print a note when
- file can't be created.
- * 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 <[email protected]>
-
- * keygen.c (ask_algo): New arg r_usage. Allow for RSA keys.
- (gen_rsa): Enabled the code.
- (do_create): Enabled RSA branch.
- (parse_parameter_usage): New.
- (proc_parameter_file): Handle usage parameter.
- (read_parameter_file): Ditto.
- (generate_keypair): Ditto.
- (generate_subkeypair): Ditto.
- (do_generate_keypair): Ditto.
- (do_add_key_flags): New.
- (keygen_add_std_prefs): Use the new function.
- (keygen_add_key_flags_and_expire): New.
- (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
- preferences. Added calls to merge keblock.
-
- * kbnode.c (dump_kbnode): Print some more flags.
-
-2001-08-10 Werner Koch <[email protected]>
-
- Revamped the preference handling.
-
- * packet.h (prefitem_t, preftype_t): New.
- (PKT_public_key): Added a uid field.
- (PKT_user_id): Added field to store preferences and a reference
- counter.
- * 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.
- (cmp_user_ids): Optimized for identical pointers.
- (release_public_key_parts): Release the uid.
- (copy_public_key_with_new_namehash): Removed.
- (copy_prefs): New.
- * keyedit.c (menu_adduid): Use the new shallow copy user id.
- (show_prefs): Adjusted implementation.
- (keyedit_menu): No more need to update the trustdb after changing
- preferences.
- * getkey.c (fixup_uidnode): Store preferences.
- (find_by_name): Return a user id packet and remove namehash stuff.
- (lookup): Removed the unused namehash stuff.
- (finish_lookup): Added foundu arg.
- (pk_from_block): Removed the namehash arg and changed all callers.
- (merge_selfsigs): Copy prefs to all keys.
- * trustdb.c (get_pref_data): Removed.
- (is_algo_in_prefs): Removed.
- (make_pref_record): Deleted and removed all class.
- * 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.
-
-2001-08-09 Werner Koch <[email protected]>
-
- * build-packet.c (build_sig_subpkt): Fixed calculation of
- newarea->size.
-
- * g10.c (main): New option "--preference-list"
- * keyedit.c (keyedit_menu): New commands "setpref" and "updpref".
- (menu_set_preferences): New.
- * keygen.c (keygen_set_std_prefs): New.
- (set_one_pref): New.
- (check_zip_algo): New.
- (keygen_get_std_prefs): New.
- (keygen_upd_std_prefs): New
- (keygen_add_std_prefs): Move the pref setting code into the above fnc.
- * build-packet.c (build_sig_subpkt): Updated the list of allowed
- to update subpackets.
-
-2001-08-08 Werner Koch <[email protected]>
-
- * packet.h (subpktarea_t): New.
- (PKT_signature): Use that type for hashed_data and unhashed_data and
- removed the _data prefix from those fields. Changed all users.
- * parse-packet.c (parse_signature): Changed allocation for that.
- (parse_sig_subpkt): Changed declaration
- (enum_sig_subpkt): Ditto and changed implementation accordingly.
- * free-packet.c (cp_subpktarea): Renamed from cp_data_block and
- adjusted implementation. Changed caller.
- * sig-check.c (mdc_kludge_check): Adjusted the hashing.
- (do_check): Ditto.
- * sign.c (sign_file, clearsign_file, make_keysig_packet,
- update_keysig_packet): Ditto.
- * build-packet.c (build_sig_subpkt): Partial rewrite.
- (find_subpkt): Adjusted and made static.
- (delete_sig_subpkt): Adjusted.
- (do_signature): Ditto.
-
- * keygen.c (ask_keysize): Do not print the notes about suggested
- key sizes if just a DSA key is generated.
-
- * trustdb.c (add_ultimate_key): s/log_error/log_info/ for
- duplicated inserted trusted keys.
-
-2001-08-07 Werner Koch <[email protected]>
-
- * sign.c (sleep): Redefine for W32.
-
- * g10.c, options.h: Set new flag opt.no_homedir_creation when
- --no-options is given.
- * openfile.c (try_make_homedir): Don't create the homedir in that case.
-
-2001-08-03 Werner Koch <[email protected]>
-
- * armor.c (armor_filter): Removed the default comment string
- because it could get us in trouble due to translations using non
- ascii characters.
-
-2001-08-01 Werner Koch <[email protected]>
-
- * keylist.c (list_keyblock_print): Do not list revoked UIDs unless
- in verbose mode and we do no signature listing.
-
- * getkey.c (finish_lookup): Skip subkeys which are not yet valid.
- * g10.c, options.h: New option --ignore-valid-from.
-
- * sign.c (make_keysig_packet): Added new sigversion argument to
- allow the caller to force generation of required signature
- version. Changed all callers. Suggested by Thomas Roessler.
-
- * keyedit.c (sign_uids): Force v4 signature generation for local
- sigs. Removed the check for local signature and pre-v4 keys.
-
-2001-07-27 Werner Koch <[email protected]>
-
- * keyedit.c (sign_uids): Check that we are not trying to to a
- lsign with a pre-v4 key. Bug noticed by Thomas Roessler.
-
-2001-07-26 Werner Koch <[email protected]>
-
- * parse-packet.c (parse_photo_id): Reset all variables.
- * getkey.c (merge_selfsigs_main): Removed checks on PHOTO_ID
- because this is handled identically to a user ID.
-
-2001-07-06 Werner Koch <[email protected]>
-
- * cipher.c (write_header): Don't use MDC with --rfc1991. Suggested
-
-2001-07-05 Werner Koch <[email protected]>
-
- * g10.c, options.h: New option --preserve-permissions.
- * ringedit.c (add_keyblock_resource): Use it here
- (keyring_copy): and here.
-
- * trustdb.c (verify_own_keys): Be more silent on --quiet.
- Suggested by Thomas Roessler.
- * sig-check.c (check_key_signature2): Ditto.
- * mainproc.c (proc_encrypted, proc_tree): Ditto
- * getkey.c (lookup): Ditto.
-
-2001-07-04 Werner Koch <[email protected]>
-
- * ringedit.c (add_keyblock_resource): Restore filename in case of error.
-
-2001-06-25 Werner Koch <[email protected]>
-
- * kbnode.c (dump_kbnode): Print the signature timestamp.
-
- * keyedit.c (keyedit_menu): New menu point "primary".
- (change_primary_uid_cb): New.
- (menu_set_primary_uid): New.
- * sign.c (update_keysig_packet): New.
- * build-packet.c (build_sig_subpkt): Put the primary UID flag into
- the hashed area. Allow update of some more packets.
-
-2001-06-15 Werner Koch <[email protected]>
-
- * 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 <[email protected]>
-
- * getkey.c (compare_name): Use ascii_memistr(), ascii_memcasecmp()
- * keyedit.c (keyedit_menu): Use ascii_strcasecmp().
- * armor.c (radix64_read): Use ascii_toupper().
- * ringedit.c (do_bm_search): Ditto.
- * keygen.c (read_parameter_file): Ditto.
- * openfile.c (CMP_FILENAME): Ditto.
- * g10.c (i18n_init): We can now use just LC_ALL.
-
-2001-05-29 Werner Koch <[email protected]>
-
- * keygen.c (generate_subkeypair): Print a warning if a subkey is
- created on a v3 key. Suggested by Brian M. Carlson.
-
-2001-05-27 Werner Koch <[email protected]>
-
- * keyid.c (get_lsign_letter): New.
- * keylist.c (list_keyblock_colon): Use it here.
- * mainproc.c (list_node): and here.
-
- * getkey.c, packet.h, free-packet.c: Removed that useless key
- created field; I dunno why I introducded this at all - the
- creation time is always bound to the key packet and subject to
- fingerprint calculation etc.
-
- * getkey.c (fixup_uidnode): Add keycreated arg and use this
- instead of the signature timestamp to calculate the
- help_key_expire. Bug reported by David R. Bergstein.
- (merge_selfsigs_main): Correct key expiration time calculation.
- (merge_selfsigs_subkey): Ditto.
-
-2001-05-25 Werner Koch <[email protected]>
-
- * revoke.c (gen_revoke): Add a cast to a tty_printf arg.
- * delkey.c (do_delete_key): Ditto.
- * keyedit.c (print_and_check_one_sig): Ditto.
- (ask_revoke_sig): Ditto.
- (menu_revsig): Ditto.
- (check_all_keysigs): Removed unused arg.
-
-2001-05-23 Werner Koch <[email protected]>
-
- * g10.c (opts): Typo fix by Robert C. Ames.
-
-2001-05-06 Werner Koch <[email protected]>
-
- * revoke.c: Small typo fix
-
-2001-05-04 Werner Koch <[email protected]>
-
- * passphrase.c (passphrase_clear_cache): Shortcut if agent usage
- is not enabled.
-
-2001-05-01 Werner Koch <[email protected]>
-
- * 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 <[email protected]>
-
- * getkey.c (merge_public_with_secret): pkttype was not set to subkey.
-
-2001-04-27 Werner Koch <[email protected]>
-
- * skclist.c (build_sk_list): Changed one log_debug to log_info.
-
-2001-04-25 Werner Koch <[email protected]>
-
- * keyedit.c (show_prefs): Add a verbose mode.
- (show_key_with_all_names): Pass verbose flag for special value of
- with_pref.
- (keyedit_menu): New command "showpref"
- (show_key_with_all_names): Mark revoked uids and the primary key.
-
-2001-04-24 Werner Koch <[email protected]>
-
- * getkey.c (get_primary_uid): Return a different string in case of
- error and made it translatable.
-
- * build-packet.c (do_secret_key): Ugly, we wrote a zero
- instead of the computed ndays. Thanks to M Taylor for complaining
- about a secret key import problem.
-
-2001-04-23 Werner Koch <[email protected]>
-
- * 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
-
-2001-04-20 Werner Koch <[email protected]>
-
- * options.skel: Add some more comments.
-
-2001-04-19 Werner Koch <[email protected]>
-
- * keyid.c (mk_datestr): New. Handles negative times. We must do
- this because Windoze segvs on negative times passed to gmtime().
- Changed all datestr_from function to use this one.
-
- * keyid.c, keyid.h (colon_strtime): New. To implement the
- fixed-list-mode.
- (colon_datestr_from_pk): New.
- (colon_datestr_from_sk): New.
- (colon_datestr_from_sig): New.
- * keylist.c (list_keyblock_colon): Use these functions here.
- * mainproc.c (list_node): Ditto.
-
-2001-04-18 Werner Koch <[email protected]>
-
- * openfile.c (open_sigfile): Fixed the handling of ".sign".
- * mainproc.c (proc_tree): Use iobuf_get_real_fname.
- Both are by Vincent Broman.
-
-2001-04-14 Werner Koch <[email protected]>
-
- * getkey.c (fixup_uidnode): Removed check for !sig which is
- pointless here. Thanks to Jan Niehusmann.
-
-2001-04-10 Werner Koch <[email protected]>
-
- * sig-check.c (check_key_signature2): Use log_info instead of
- log_error so that messed up keys do not let gpg return an error.
- Suggested by Christian Kurz.
-
- * getkey.c (merge_selfsigs_main): Do a fixup_uidnode only if we
- have both, uid and sig. Thanks to M Taylor.
-
-2001-04-05 Werner Koch <[email protected]>
-
- * armor.c (unarmor_pump_new,unarmor_pump_release): 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 becuase this does only chack for armored
- signatures the very first time. In pipemode we may have a mix of
- armored and binary detached signatures.
- * mainproc.c (proc_tree): Do not print the "old style" notice when
- this is a pipemode processes detached signature.
- (proc_plaintext): Special handling of pipemode detached sigs.
-
- * packet.h (CTRLPKT_PLAINTEXT_MARK): New.
- * parse-packet.c (create_gpg_control): New.
- * kbnode.c (dump_kbnode): Support it here.
- * mainproc.c (check_sig_and_print): Fixed the check for bad
- sequences of multiple signatures.
- (proc_plaintext): Add the marker packet.
- (proc_tree): We can now check multiple detached signatures.
-
-2001-04-02 Werner Koch <[email protected]>
-
- The length of encrypted packets for blocksizes != 8 was not
- correct encoded. I think this is a minor problem, because we
- usually use partial length packets. Kudos to Kahil D. Jallad for
- pointing this out.
- * packet.h: Add extralen to PKT_encrypted.
- * cipher.c (write_header): Set extralen.
- * build-packet.c (do_encrypted): Use extralen instead of const 10.
- (do_encrypted_mdc): Ditto.
- * parse-packet.c (parse_encrypted): Set extralen to 0 because we
- don't know it here.
-
-2001-03-30 Werner Koch <[email protected]>
-
- * getkey.c (premerge_public_with_secret): Changed wording an add
- the keyID to the info message.
-
-2001-03-29 Werner Koch <[email protected]>
-
- * getkey.c (premerge_public_with_secret): Use log_info instead of
- log_error when no secret key was found for a public one.
- Fix the usage if the secret parts of a key are not available.
-
- * openfile.c (ask_outfile_name): Trim spaces.
- (open_outfile): Allow to enter an alternate filename. Thanks to
- Stefan Bellon.
- * plaintext.c (handle_plaintext): Ditto.
-
-2001-03-28 Werner Koch <[email protected]>
-
- * mainproc.c (do_check_sig): Allow direct key and subkey
- revocation signature.
- * sig-check.c (check_key_signature2): Check direct key signatures.
- Print the signature class along with an error.
-
-2001-03-27 Werner Koch <[email protected]>
-
- * packet.h: Add a missing typedef to an enum. Thanks to Stefan Bellon.
-
- * g10.c: New option --no-sig-create-check.
- * sign.c (do_sign): Implement it here.
- * g10.c: New option --no-sig-cache.
- * sig-check.c (check_key_signature2): Implement it here.
- (cache_selfsig_result): and here.
-
- * keylist.c (list_keyblock): Removed debugging stuff.
-
- * getkey.c (cache_public_key): Made global.
- * keygen.c (write_selfsig, write_keybinding): Cache the new key.
-
- * getkey.c (key_byname): Add new arg secmode and changed all
- callers to request explicitly the mode. Deriving this information
- from the other supplied parameters does not work if neither pk nor
- sk are supplied.
-
-2001-03-25 Werner Koch <[email protected]>
-
- * packet.h (ctrlpkttype_t): New.
- * mainproc.c (add_gpg_control,proc_plaintext,proc_tree): Use the
- new enum values.
- * pipemode.c (make_control): Ditto.
- * armor.c (armor_filter): Ditto.
-
-2001-03-24 Werner Koch <[email protected]>
-
- * sign.c (do_sign): Verify the signature right after creation.
-
-2001-03-23 Werner Koch <[email protected]>
-
- * status.c, status.h (STATUS_UNEXPECTED): New.
- * mainproc.c (do_proc_packets): And emit it here.
-
-2001-03-21 Werner Koch <[email protected]>
-
- * status.c: Add sys/types.h so that it runs on Ultrix. Reported
- by Georg Schwarz.x
-
- * build-packet.c (build_sig_subpkt): Fixed generaton of packet
- length header in case where 2 bytes headers are needed. Thanks to
- Piotr Krukowiecki.
-
-2001-03-19 Werner Koch <[email protected]>
-
- * g10.c (main): the default keyring is no always used unless
- --no-default-keyring is given.
-
- * ringedit.c (add_keyblock_resource): invalidate cache after file
- creation.
-
-2001-03-15 Werner Koch <[email protected]>
-
- * keygen.c (ask_algo): Changed the warning of the ElGamal S+E Algo.
-
- * keylist.c (print_capabilities): New.
- (list_keyblock_colon): and use it here.
-
-2001-03-13 Werner Koch <[email protected]>
-
- * main.c, options.h: New option --fixed_list_mode.
- * keylist.c (list_keyblock_colon): use it here.
-
- * getkey.c (merge_keys_and_selfsig): Divert merging of public keys
- to the function used in key selection..
- * keylist.c (is_uid_valid): Removed.
- (list_keyblock): Splitted into ..
- (list_keyblock_print, list_keyblock_colon): .. these.
- functions. Changed them to use the flags set in the key lookup code.
- (reorder_keyblock): New, so that primary user IDs are listed first.
-
- * ringedit.c (keyring_copy): flush the new iobuf chaces before
- rename or remove operations. This is mainly needed for W32.
-
- * hkp.c [HAVE_DOSISH_SYSTEM]: Removed the disabled code because we
- have now W32 socket support in ../util/http.c
-
- * skclist.c (key_present_in_sk_list): New.
- (is_duplicated_entry): New.
- (build_sk_list): Check for duplicates and do that before unlocking.
-
-2001-03-12 Werner Koch <[email protected]>
-
- * armor.c (parse_header_line): Removed double empty line check.
- (parse_header_line): Replaced trim_trailing_ws with a counting
- 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.
-
- * parse-packet.c (parse_symkeyenc): Return Invalid_Packet on error.
- (parse_pubkeyenc): Ditto.
- (parse_onepass_sig): Ditto.
- (parse_plaintext): Ditto.
- (parse_encrypted): Ditto.
- (parse_signature): Return error at other places too.
- (parse_key): Ditto.
- * g10.c (main): Set opt.list_packets to another value when invoked
- with the --list-packets command.
- * mainproc.c (do_proc_packets): Don's stop processing when running
- under --list-packets command.
-
- * 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.
- (do_block): Use sigset() if sigprocmask() is not available.
-
- * armor.c (parse_hash_header): Test on TIGER192, which is the
- correct value as per rfc2440. By Edwin Woudt.
-
-2001-03-08 Werner Koch <[email protected]>
-
- * misc.c: Include time.h. By James Troup.
-
- * getkey.c: Re-enabled the unknown user Id and PK caches and
- increased their sizes.
-
- * 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
- find the self-signature for an UID.
- * parse-packet.c (parse_user_id): Zero out all fields.
- * 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 <[email protected]>
-
- * getkey.c (finish_lookup): Print an info message only in verbose mode.
-
-2001-03-05 Werner Koch <[email protected]>
-
- * packet.h: Replaced sigsubpkt_t value 101 by PRIV_VERIFY_CACHE.
- We have never used the old value, so we can do this without any harm.
- * parse-packet.c (dump_sig_subpkt): Ditto.
- (parse_one_sig_subpkt): Parse that new sub packet.
- * build-packet.c (build_sig_subpkt): Removed the old one from the
- hashed area.
- (delete_sig_subpkt): New.
- (build_sig_subpkt): Allow an update of that new subpkt.
- * sig-check.c (check_key_signature2): Add verification caching
- (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
-
-2001-03-03 Werner Koch <[email protected]>
-
- * 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.
- (key_byname): Removed the unused ctx.primary flag
- (get_seckey_byname2): Ditto.
- (finish_lookup): Changed debugging output.
-
-2001-03-02 Werner Koch <[email protected]>
-
- * keylist.c (list_one): Remove the merge key calls.
-
-2001-03-01 Werner Koch <[email protected]>
-
- * getkey.c (finish_lookup): Don't use it if we no specific usage
- has been requested.
- (merge_selfsigs_main): fix UID only if we have an signature.
- (lookup): Return UNU_PUBKEY etc. instead of NO_PUBKEY if we found
- a key but the requested usage does not allow this key.
- * 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.
-
-2001-02-09 Werner Koch <[email protected]>
-
- * delkey.c (delete_key): Removed that silly assert which rendered
- the whole new stuff meaningless.
-
-2001-02-08 Werner Koch <[email protected]>
-
- * getkey.c (key_byname): It can happen that we have both, sk and pk
- NULL, fix for that.
-
- * parse-packet.c (parse_one_sig_subpkt): Add support for
- primary_uid and key_flags.
- (can_handle_critical): Ditto
-
- * parse-packet.c (parse_encrypted): Fixed listing of pktlen for
- MDC packets.
-
- * getkey.c: Backported the version of this file from gpg 1.1. this
- involved some changes in other files too.
- * parse-packet.c (parse_key): Clear req_usage.
- * skclist.c (build_sk_list): Use req_usage to pass the usage
- information to the lookup function.
- * pkclist.c (build_pk_list): Ditto.
- * free-packet.c (copy_public_parts_to_secret_key): New.
- * keydb.h: Add IS_* macros to check the sig_class.
- * misc.c (openpgp_cipher_test_algo): New.
- (openpgp_pk_test_algo): New.
- (openpgp_pk_algo_usage): New.
- (openpgp_md_test_algo): New.
- * packet.h: Add a few fields to PKT_{public,secret}_key and
- PKT_user_id.
- * seckey-cert.c (do_check): Use the new main_keyid field.
-
-2001-02-04 Werner Koch <[email protected]>
-
- * encr-data.c (decrypt_data): Catch error when we had problems to
- parse the encrypted packet. By Timo.
-
-2001-01-29 Werner Koch <[email protected]>
-
- * g10.c (main): --batch does now set nogreeting.
-
- * delkey.c (do_delete_key): Fixed delete-both functionality.
-
-2001-01-22 Werner Koch <[email protected]>
-
- * g10.c: New command --delete-secret-and-public-key.
- * delkey.c (delete_key): Add new arg allow_both.
- (do_delete_key): Move most stuff from above to this new function.
-
-2001-01-12 Werner Koch <[email protected]>
-
- * passphrase.c (passphrase_to_dek): Use MD5 when IDEA is installed
- and we have no S2K.
- * mainproc.c (proc_encrypted): Likewise
-
-2001-01-11 Werner Koch <[email protected]>
-
- * sig-check.c (do_check): Print the signature key expire message
- only in verbose mode and added the keyID.
-
-2001-01-09 Werner Koch <[email protected]>
-
- * 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
- output. It does now always print 2 keyIDs. Emit the new
- USERID_HINT.
-
-2001-01-08 Werner Koch <[email protected]>
-
- * g10.c, options.h: New option --no-expensive-trust-checks.
- * keylist.c (list_keyblock): Act on this option.
-
-2001-01-04 Werner Koch <[email protected]>
-
- * g10.c (main): Set homedir only in the pre-parsing phase and
- replace backslashes in the W32 version.
-
-2001-01-03 Werner Koch <[email protected]>
-
- * status.c, status.h : New status KEY_CREATED
- * keygen.c (do_generate_keypair,generate_subkeypair): Emit it.
-
-2000-12-28 Werner Koch <[email protected]>
-
- * signal.c (got_fatal_signal): Remove lockfiles here because the
- 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 <[email protected]>
-
- * status.c, status.h (cpr_get_no_help): New.
- * keyedit.c (keyedit_menu): Use it here because we have our own
- help list here.
-
-2000-12-18 Werner Koch <[email protected]>
-
- * mainproc.c (print_failed_pkenc): Don't print the sometimes
- confusing message about unavailabe secret key. Renamed ...
- (print_pkenc_list): ... to this and introduced failed arg.
- (proc_encrypted): Print the failed encryption keys and then
- the one to be used.
- (proc_pubkey_enc): Store also the key we are going to use.
-
- * mainproc.c (check_sig_and_print): Don't list revoked user IDs.
- (is_uid_revoked): New.
-
-2000-12-08 Werner Koch <[email protected]>
-
- * pipemode.c: Made the command work. Currently only for
- non-armored detached signatures.
- * mainproc.c (release_list): Reset the new pipemode vars.
- (add_gpg_control): Handle the control packets for pipemode
- * status.c, status.h: New stati {BEGIN,END}_STREAM.
-
-2000-12-07 Werner Koch <[email protected]>
-
- * g10.c: New option --allow-secret-key-import.
- * import.c (import_keys,import_keys_stream): Honor this option.
- (import): New arg allow_secret and pass that arg down to ...
- (import_secret_one): to this and print a warning if secret key
- importing is not allowed.
-
-2000-12-05 Werner Koch <[email protected]>
-
- * cipher.c (cipher_filter): Moved the end_encryption status ...
- * encode.c (encode_simple,encode_crypt): to here
- * sign.c (sign_file): and here.
-
- * status.c (mywrite): Removed.
- (get_status_string): Removed the LFs from the strings.
- (set_status_fd,is_status_enabed,write_status_text,
- write_status_buffer): Replaced all mywrite by stdio calls and use
- fdopen to create a strem. This is needed to make things smoother
- in the W32 version.
-
-2000-12-04 Werner Koch <[email protected]>
-
- * import.c (merge_blocks): Increment n_sigs for revocations.
-
-2000-11-30 Werner Koch <[email protected]>
-
- * g10.c (main): Use iobuf_translate_file_handle for all options
- with filehandles as arguments. This is function does some magic
- for the W32 API.
-
- * verify.c (verify_signatures): Add a comment rant about the
- detached signature problem.
- * mainproc.c (proc_tree): Issue an error if a detached signature
- is assumed but a standard one was found.
- * plaintext.c (hash_datafiles): Don't fall back to read signature
- from stdin.
- * openfile.c (open_sigfile): Print verbose message only if the
- file could be accessed.
-
-2000-11-24 Werner Koch <[email protected]>
-
- * passphrase.c [HAVE_DOSISH_SYSTEM]: Disabled all the agent stuff.
-
-2000-11-16 Werner Koch <[email protected]>
-
- * g10.c: New option --use-agent
- * passphrase.c (agent_open,agent_close): New.
- (agent_get_passphrase,agent_clear_passphrase): New.
- (passphrase_clear_cache): New.
- (passphrase_to_dek): Use the agent here.
- * seckey-cert.c (do_check): Clear cached passphrases.
-
-2000-11-15 Werner Koch <[email protected]>
-
- * status.c (write_status_text): Moved the big switch to ...
- (get_status_string): ... new function.
- (write_status_buffer): New.
-
- * status.c (mywrite): New and replaced all write() by this.
-
- * 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 <[email protected]>
-
- * sign.c (clearsign_file): Use LF macro to print linefeed.
-
-2000-11-11 Paul Eggert <[email protected]>
-
- Clean up the places in the code that incorrectly use "long" or
- "unsigned long" for file offsets. The correct type to use is
- "off_t". The difference is important on large-file hosts,
- where "off_t" is longer than "long".
-
- * keydb.h (struct keyblock_pos_struct.offset):
- Use off_t, not ulong, for file offsets.
- * packet.h (dbg_search_packet, dbg_copy_some_packets,
- search_packet, copy_some_packets): Likewise.
- * parse-packet.c (parse, dbg_search_packet, search_packet,
- dbg_copy_some_packets, copy_some_packets): Likewise.
- * ringedit.c (keyring_search): Likewise.
-
- * parse-packet.c (parse): Do not use %lu to report file
- offsets in error diagnostics; it's not portable.
- * ringedit.c (keyring_search): Likewise.
-
-2000-11-09 Werner Koch <[email protected]>
-
- * g10.c (main): New option --enable-special-filenames.
-
-2000-11-07 Werner Koch <[email protected]>
-
- * g10.c (main): New command --pipemode.
- * pipemode.c: New.
-
-2000-10-23 Werner Koch <[email protected]>
-
- * armor.c (armor_filter): Changed output of hdrlines, so that a CR
- is emitted for DOS systems.
-
- * keygen.c (read_parameter_file): Add a cast for isspace().
-
- * status.c (myread): Use SIGINT instead of SIGHUP for DOS.
-
-2000-10-19 Werner Koch <[email protected]>
-
- * g10.c: New option --ignore-crc-error
- * armor.c (invalid_crc): New.
- (radix64_read): Act on new option.
-
- * openfile.c (try_make_homedir): Klaus Singvogel fixed a stupid
- error introduced on Sep 6th.
-
-2000-10-18 Werner Koch <[email protected]>
-
- * misc.c (print_cipher_algo_note): Don't print the note for AES.
- Changed wording.
-
-2000-10-16 Werner Koch <[email protected]>
-
- * 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.
-
- * mainproc.c (check_sig_and_print): Detect multiple signatures
- and don't verify them.
-
-2000-10-14 Werner Koch <[email protected]>
-
- * mainproc.c (add_onepass_sig): There is an easier solution to the
- error fixed yesterday; just check that we only have onepass
- packets. However, the other solution provides an cleaner
- interface and opens the path to get access to other information
- from the armore headers.
- (release_list): Reset some more variables.
-
-2000-10-13 Werner Koch <[email protected]>
-
- * mainproc.c (add_gpg_control): New.
- (do_proc_packets): use it.
- (proc_plaintext): Changed logic to detect clearsigns.
- (proc_tree): Check the cleartext sig with some new code.
-
- * packet.h: New packet PKT_GPG_CONTROL.
- * parse-packet.c (parse_gpg_control): New.
- * misc.c (get_session_marker): New.
- * 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.
- * status.c (my_read): New.
- (do_get_from_fd): use it.
-
-2000-10-12 Werner Koch <[email protected]>
-
- * keygen.c (keygen_add_std_prefs): Add Rijndael to the prefs.
-
-2000-10-07 Werner Koch <[email protected]>
-
- * gpgv.c: Add more stubs for ununsed code to make the binary smaller.
-
-Wed Oct 4 15:50:18 CEST 2000 Werner Koch <[email protected]>
-
- * sign.c (hash_for): New arg to take packet version in account, changed
- call callers.
-
- * gpgv.c: New.
- * Makefile.am: Rearranged source files so that gpgv can be build with
- at least files as possible.
-
-Mon Sep 18 12:13:52 CEST 2000 Werner Koch <[email protected]>
-
- * hkp.c (not_implemented): Print a notice for W32
-
-Fri Sep 15 18:40:36 CEST 2000 Werner Koch <[email protected]>
-
- * keygen.c (keygen_add_std_prefs): Changed order of preferences to
- twofish, cast5, blowfish.
-
- * pkclist.c (algo_available): Removed hack to disable Twofish.
-
-Thu Sep 14 17:45:11 CEST 2000 Werner Koch <[email protected]>
-
- * parse-packet.c (dump_sig_subpkt): Dump key flags. Print special
- warning in case of faked ARRs.
-
- * getkey.c (finsih_lookup): Hack so that for v4 RSA keys the subkey
- is used for encryption.
-
-Thu Sep 14 14:20:38 CEST 2000 Werner Koch <[email protected]>
-
- * 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
- that this would disable a couple of workarounds for PGP.
-
- * g10.c (main): Don't set --quite along with --no-tty. By Frank Tobin.
-
- * misc.c (disable_core_dump): Don't display a warning here but a return
- a status value and ...
- * g10.c (main): ...print warnining here. Suggested by Sam Roberts.
-
-Wed Sep 13 18:12:34 CEST 2000 Werner Koch <[email protected]>
-
- * keyedit.c (keyedit_menu): Allow to use "debug" on the secret key.
-
- * ringedit.c (cmp_seckey): Fix for v4 RSA keys.
- * seckey-cert.c (do_check): Workaround for PGP 7 bug.
-
-Wed Sep 6 17:55:47 CEST 2000 Werner Koch <[email protected]>
-
- * misc.c (print_pubkey_algo_note): Do not print the RSA notice.
- * sig-check.c (do_signature_check): Do not emit the RSA status message.
- * pubkey-enc.c (get_session_key): Ditto.
-
- * encode.c (encode_simple, encode_crypt): Fix for large files.
- * sign.c (sign_file): Ditto.
-
-Wed Sep 6 14:59:09 CEST 2000 Werner Koch <[email protected]>
-
- * passphrase.c (hash_passphrase): Removed funny assert. Reported by
- David Mathog.
-
- * openfile.c (try_make_homedir): Changes for non-Posix systems.
- * g10.c (main): Take the default homedir from macro.
-
- * g10.c: The --trusted-key option is back.
- * trustdb.c (verify_own_key): Handle this option.
- (add_ultimate_key): Moved stuff from verify_own_key to this new func.
- (register_trusted_key): New.
-
-Fri Aug 25 16:05:38 CEST 2000 Werner Koch <[email protected]>
-
- * 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.
- (make_outfile_name): Add ".sign" to the list of know extensions.
- (open_sigfile): Ditto.
-
-Wed Aug 23 19:52:51 CEST 2000 Werner Koch <[email protected]>
-
- * g10.c: New option --allow-freeform-uid. By Jeroen C. van Gelderen.
- * keygen.c (ask_user_id): Implemented here.
-
-Fri Aug 4 14:23:05 CEST 2000 Werner Koch <[email protected]>
-
- * status.c (do_get_from_fd): Ooops, we used fd instead of opt.command_fd.
- Thanks to Michael Tokarev.
-
-Tue Aug 1 20:06:23 CEST 2000 Werner Koch <[email protected]>
-
- * g10.c: New opttion --try-all-secrets on suggestion from Matthias Urlichs.
- * pubkey-enc.c (get_session_key): Quite easy to implement here.
-
-Thu Jul 27 17:33:04 CEST 2000 Werner Koch <[email protected]>
-
- * g10.c: New option --merge-only. Suggested by Brendan O'Dea.
- * import.c (import_one): Implemented it here
- (import_secret_one): Ditto.
- (print_stats): and give some stats.
-
-Thu Jul 27 12:01:00 CEST 2000 Werner Koch <[email protected]>
-
- * g10.c: New options --show-session-key and --override-session-key
- * pubkey-enc.c (hextobyte): New.
- (get_override_session_key): New.
- * mainproc.c (proc_pubkey_enc): Add session-key stuff.
- * status.h, status.c (STATUS_SESSION_KEY): New.
-
-Thu Jul 27 10:02:38 CEST 2000 Werner Koch <[email protected]>
-
- * g10.c (main): Use setmode(O_BINARY) for MSDOS while generating random bytes
- (print_mds): Likewise for stdin.
- * plaintext.c (handle_plaintext): Likewise for stdout.
-
-Mon Jul 24 10:30:17 CEST 2000 Werner Koch <[email protected]>
-
- * keyedit.c (menu_expire): expire date for primary key can be set again.
-
-Wed Jul 19 11:26:43 CEST 2000 Werner Koch <[email protected]>
-
- * keylist.c (is_uid_valid): New.
- (list_keyblock): Print validity information for all user IDs. Note, this
- has to be done at other places too; for now we have only minimal support.
-
-Wed Jul 12 13:32:06 CEST 2000 Werner Koch <[email protected]>
-
- * helptext.c, pkclist.c: s/superseeded/superseded/
-
-Mon Jul 10 16:08:57 CEST 2000 Werner Koch <[email protected]>
-
- * parse-packet.c (enum_sig_subpkt): Fixed testing on crtitical bit in case
- of a NULL buffer. Reported by Peter Marschall.
-
-Wed Jul 5 13:28:45 CEST 2000 Werner Koch <[email protected]>
-
- * keyedit.c, keyid.c: Add some _()
-
- * argparse.c: Changed the flag to suppress --version handling to also
- suppress --help.
-
-Wed Jun 28 11:54:44 CEST 2000 Werner Koch <[email protected]>
-
- * armor.c (armor_filter): Set sigclass to 0 in case of non-dash-escaped
- clearsig. This makes this mode work again.
-
- * mainproc.c (proc_tree): Fixed handling of one-pass-sig packets in textmode.
- Disabled the ugly workaround for PGP 5 - let's see whether thi breaks less
- cases. Found by Ted Cabeen.
-
- * options.h (DBG_HASHING): New. All commented md_start_debug are now
- controlled by this debug option.
-
- * sign.c (print_status_sig_created): New and called from 2 places.
-
- * keygen.c (gen_rsa): New, but commented.
- (ask_algo): Commented support for RSA.
-
- * seckey-cert.c (protect_secret_key): Started to fix the code for v4 RSA
- keys - it is not solved yet. However, we have time until, Sep 20th ;)
-
-Wed Jun 14 12:27:09 CEST 2000 Werner Koch <[email protected]>
-
- * status.c (init_shm_coprocessing): Changed the sequence of the get,attach
- to cope with the changes in newer Linux kernels. This bug has been found
- by <[email protected]> who also proposed this solution. Hopefully
- this does not break gpg on to many systems.
-
- * cipher.c (write_header): Protect the IV with the MDC too.
- * encr-data.c (decrypt_data): Likewise.
-
-Fri Jun 9 10:09:52 CEST 2000 Werner Koch <[email protected]>
-
- * g10.c: New options --no-auto-key-retrieve
- * options.h (auto_key_retrieve): New.
- * mainproc.c (check_sig_and_print): Implemented that.
-
-Wed Jun 7 19:19:09 CEST 2000 Werner Koch <[email protected]>
-
- * sig-check.c (do_check): Use EMULATE_MDENCODE also on v4 packets.
-
-Wed Jun 7 17:25:38 CEST 2000 Werner Koch <[email protected]>
-
- * cipher.c (write_header): Use plain CFB mode for MDC encrypted packets.
- * encr-data.c (decrypt_data): Ditto.
-
-Mon Jun 5 23:41:54 CEST 2000 Werner Koch <[email protected]>
-
- * seskey.c (do_encode_md, encode_md_value): Add new arg v3compathack to work
- around a bug in old versions.
- * sig-check.c (do_check): use the aboved workaround when enabled.
- * g10.c: New option --emulate-md-decode-bug
-
-Mon Jun 5 12:37:43 CEST 2000 Werner Koch <[email protected]>
-
- * build-packet.c (do_mdc): New.
- (do_encrypted_mdc): Changed for the new proposal.
- * parse-packet.c (parse_mdc): New.
- (parse_encrypted): Fixed for the new proposal.
- * packet.h (PKT_MDC): New.
- * cipher.c (cipher_filter): Build the MDC packet here.
- * g10.c (main): Enable --force-mdc.
- * encr-data.c (mdc_decode_filter): Fixed for new MDC method
-
- * options.h(rfc2440): New.
- * g10.c (main): Changed the selected values for --openpgp to not include
- optional algorithms.
-
-Thu May 18 11:38:54 CEST 2000 Werner Koch <[email protected]>
-
- * keyedit.c (keyedit_menu): Add a keyword arg to the prompt.
-
- * status.c, status.h: Added 3 new status tokens.
- * status.c (do_get_from_fd): New.
- (cpr_enabled,cpr_get,cpr_get_hidden,cpr_kill_prompt,
- cpr_get_answer_is_yes,cpr_get_answer_yes_no_quit): Modified to work
- with the new function.
- * g10.c: Add new option --command-fd.
-
- * status.c (progress_cb): New.
- (set_status_fd): Register progress functions
-
-Fri May 12 14:01:20 CEST 2000 Werner Koch <[email protected]>
-
- * delkey.c (delete_key): Add 2 new status messages
- * status.c, status.h (STATUS_DELETE_PROBLEM): New.
-
- Fixed years of copyright in all source files.
-
-Mon May 1 17:08:14 CEST 2000 Werner Koch <[email protected]>
-
- * trustdb.c (propagate_validity): Fixed the bug that only one uid
- gets fully trusted even when all are signed by an ultimate key.
-
-Mon May 1 15:38:04 CEST 2000 Werner Koch <[email protected]>
-
- * getkey.c (key_byname): Always returned a defined context. Fixed
- a segv for invalid user id specifications. Reported by Walter Koch.
-
- * getkey.c (get_user_id): I18ned "no user id" string. By Walter.
-
- * pkclist.c (do_show_revocation_reason): Typo fixes.
- * helptext.c: Ditto.
-
- * armor.c (armor_filter): Fixed some CRLF issues. By Mike McEwan.
-
-Fri Apr 14 19:37:08 CEST 2000 Werner Koch <[email protected]>
-
- * pkclist.c (do_show_revocation_reason): New.
- (show_revocation_reason): New and called at various places.
-
- * g10.c (main): Fixed small typo.
-
- * pkclist.c (do_we_trust): Act on always_trust but not for revoked
- keys. Suggested by Chip Salzenberg.
-
- * g10.c: New option --lock-never.
-
- * ringedit.c (get_writable_keyblock_file): New.
- * keygen.c (do_generate_keypair): Use this instead of the hardwired one.
-
- * keygen.c (ask_user_id): Check that the email address is in the
- correct field. Suggested by Christian Kurz.
-
-Mon Apr 10 13:34:19 CEST 2000 Werner Koch <[email protected]>
-
- * keyedit.c (show_key_with_all_names): s/sbb/ssb/
-
-Tue Mar 28 14:26:58 CEST 2000 Werner Koch <[email protected]>
-
- * trustdb.c (verify_own_keys): Do not print warning about unprotected
- key when in quiet mode.
-
-Wed Mar 22 13:50:24 CET 2000 Werner Koch <[email protected]>
-
- * mainproc.c (print_userid): Do UTF8 conversion before printing.
- * import.c (import_one): Ditto.
- (import_secret_one): Ditto.
- (delete_inv_parts): Ditto.
-
-Thu Mar 16 16:20:23 CET 2000 Werner Koch <[email protected]>
-
- * keylist.c (print_key_data): Handle a NULL pk gracefully.
-
- * getkey.c (merge_one_pk_and_selfsig): Fixed silly code for
- getting the primary keys keyID but kept using the one from the
- subkey.
- * pubkey-enc.c (get_it): Print a note for expired subkeys.
-
- * getkey.c (has_expired): New.
- (subkeys_expiretime): New.
- (finish_lookup): Check for expired subkeys needed for encryption.
- (merge_keys_and_selfsig): Fixed expiration date merging for subkeys.
-
- * keylist.c (list_keyblock): Print expiration time for "sub".
- (list_one): Add missing merging for public keys.
- * mainproc.c (list_node): Ditto.
-
-2000-03-14 13:49:38 Werner Koch ([email protected])
-
- * keygen.c (keyedit_menu): Do not allow to use certain commands
- while the secret key is selected.
-
-2000-03-09 12:53:09 Werner Koch ([email protected])
-
- * keygen.c (ask_expire_interval): Movede parsig to ...
- (parse_expire_string): ... this new function. And some new control
- commands.
- (proc_parameter_file): Add expire date parsing.
- (do_generate_keypair): Allow the use of specified output files.
-
-2000-03-08 10:38:38 Werner Koch ([email protected])
-
- * keygen.c (ask_algo): Removed is_v4 return value and the commented
- code to create Elg keys in a v3 packet. Removed the rounding
- of key sizes here.
- (do_create): Likewise removed arg v4_packet.
- (gen_elg): Likewise removed arg version. Now rounding keysizes here.
- (gen_dsa): Rounding keysize now here.
- (release_parameter_list): New
- (get_parameter*): New.
- (proc_parameter_file): New.
- (read_parameter_file): New.
- (generate_keypair): Splitted. Now uses read_parameter_file when in
- batch mode. Additional argument to specify a parameter file.
- (do_generate_keypair): Main bulk of above fucntion and uses the
- parameter list.
- (do_create): Don't print long notice in batch mode.
- * g10.c (main): Allow batched key generation.
-
-Thu Mar 2 15:37:46 CET 2000 Werner Koch <[email protected]>
-
- * pubkey-enc.c (get_it): Print a note about unknown cipher algos.
-
- * g10.c (opts): Add a note to the help listing about the man page
- and removed some options from the help listing.
-
- * keyedit.c (print_and_check_one_sig): Use a new function to truncate
- the output of the user ID. Suggested by Jan-Benedict Glaw.
-
-Wed Feb 23 10:07:57 CET 2000 Werner Koch <[email protected]>
-
- * helptext.c: typo fix.
-
-Thu Feb 17 13:39:32 CET 2000 Werner Koch <[email protected]>
-
- * revoke.c: Removed a bunch of commented code.
-
- * packet.h (SIGSUBPKT_REVOC_REASON): New.
- * build-packet.c (build_sig_subpkt): Support new sub packet.
- * parse-packet.c (parse_one_sig_subpkt): Ditto.
- (dump_sig_subpkt): Ditto.
- * revoke.c (ask_revocation_reason): New.
- (release_revocation_reason_info): New.
- (revocation_reason_build_cb): New.
- (gen_revoke): Ask for reason.
- * main.h (struct revocation_reason_info): Add declaration.
- * keyedit.c (menu_revsig): Add support for revocation reason.
- (menu_revkey): Ditto.
- (sign_uid_mk_attrib): Renamed to ...
- (sign_mk_attrib): ... this, made static and add support for reasons.
-
-Tue Feb 15 08:48:13 CET 2000 Werner Koch <[email protected]>
-
- * build-packet.c (build_packet): Fixed fixing of old comment packets.
-
- * import.c (import_keys): Fixed importing from stdin when called with
- nnames set to zero as it normally happens.
-
-Mon Feb 14 14:30:20 CET 2000 Werner Koch <[email protected]>
-
- * sig-check.c (check_key_signature2): Add new arg r_expired.
- (do_signature_check): New arg to pass it down to ...
- (do_check): New arg r-expire which is set when the signature
- has expired.
- * trustdb.c (check_sig_record): Set SIGF_EXPIRED flag and set
- the expiretime to zero so that thi signature will not be checked
- anymore.
-
-Fri Feb 11 17:44:40 CET 2000 Werner Koch <[email protected]>
-
- * g10.c (g10_exit): Update the random seed_file.
- (main): Set the random seed file. New option --no-random-seed-file.
-
-Thu Feb 10 17:39:44 CET 2000 Werner Koch <[email protected]>
-
- * keyedit.c (menu_expire): Fixed segv due to unitialized sub_pk.
- By R�mi.
-
-Thu Feb 10 11:39:41 CET 2000 Werner Koch <[email protected]>
-
- * keylist.c (list_keyblock): Don't print warnings in the middle of
- regulat output lines. By R�mi.
-
- * sig-check.c: Include options.h
-
-Wed Feb 9 15:33:44 CET 2000 Werner Koch <[email protected]>
-
- * gpg.c: New option --ignore-time-conflict
- * sig-check.c (do_check): Implemented this option.
- * trustdb.c (check_trust): Ditto.
- * sign.c (do_sign): Ditto.
- * keygen.c (generate_subkeypair): Ditto.
-
- * encode.c (encode_simple): use iobuf_cancel after open failure.
- Reported by Huy Le.
-
-Fri Jan 14 18:32:01 CET 2000 Werner Koch <[email protected]>
-
- * packet.h (STRING2KEY): Changed mode from byte to int.
- * parse-packet.c (parse_key): Add the special GNU protection stuff
- * build-packet.c (so_secret_key): Ditto.
- * seckey-cert.c (do_check): Ditto.
- * keyedit.c (change_passphrase): Ditto.
- * export.c (export_secsubkeys): New.
- (do_export_stream): Hack to export the primary key using mode 1001.
- * g10.c: New command --export-secret-subkeys
-
-Thu Jan 13 19:31:58 CET 2000 Werner Koch <[email protected]>
-
- * armor.c (is_armored): Check for 1-pass-sig packets. Reported by
- David Hallinan <[email protected]>.
- (armor_filter): Replaced one LF by the LF macro. Reported by
- Wolfgang Redtenbacher.
-
-Wed Jan 5 11:51:17 CET 2000 Werner Koch <[email protected]>
-
- * g10.c (main): Reset new global flag opt.pgp2_workarounds
- when --openpgp is used.
- * mainproc.c (proc_plaintext): Do the PGP2,5 workarounds only
- when the global flag is set.
- (proc_tree): Ditto.
- * textfilter.c (copy_clearsig_text): Ditto.
- * armor.c (armor_filter): Ditto.
-
- * g10.c: New option --list-only
- * mainproc.c (proc_tree): Don't do it if opt.list_only is active.
- (proc_pubkey_enc): Implement option.
-
- * status.h, status.c ({BEGIN,END}_{EN,DE}CRYPTION): New.
- * cipher.c (cipher_filter): New status outputs.
- * mainproc.c (proc_encrypted): New status outputs.
-
-Fri Dec 31 14:08:15 CET 1999 Werner Koch <[email protected]>
-
- * armor.c (armor_filter): Made the "Comment:" header translatable.
-
- * hkp.c (hkp_import): Make sure that the program does not return
- success when there is a connection problem. Reported by Phillip Jones.
-
-Sun Dec 19 15:22:26 CET 1999 Werner Koch <[email protected]>
-
- * armor.c (LF): Use this new macro at all places where a line LF
- is needed. This way DOSish textfiles should be created when the
- input data is also in dos mode.
- * sign.c (LF): Ditto.
- * textfilter.c (LF): Ditto.
- (copy_clearsig_text): Disabled the forcing of CR,LF sequences
- for DOS systems.
-
- * plaintext.c (handle_plaintext): Fixes for line endings on DOS.
- and react on a LF in cleartext.
- * armor.c (fake_packet): Restore the original line ending after
- removing trailing spaces.
-
- * signal.c (got_fatal_signal): DOS fix.
-
-Thu Dec 16 10:07:58 CET 1999 Werner Koch <[email protected]>
-
- * mainproc.c (print_failed_pkenc): Fix for unknown algorithm.
- Found by [email protected].
-
-Thu Dec 9 10:31:05 CET 1999 Werner Koch <[email protected]>
-
- * hkp.c: i18n the strings.
-
-Sat Dec 4 15:32:20 CET 1999 Werner Koch <[email protected]>
-
- * trustdb.c (verify_key): Shortcut for ultimately trusted keys.
-
-Sat Dec 4 12:30:28 CET 1999 Werner Koch <[email protected]>
-
- * pkclist.c (build_pk_list): Validate the trust using the namehash
- if this one has been set by the key lookup.
-
- * g10.c: Add --delete-secret-key to the help page.
-
- * openfile.c (copy_options_file): Made static.
- (try_make_homedir): New.
- * ringedit.c (add_keyblock_resource): Use the try_make_hoemdir logic.
- * tdbio.c (tdbio_set_dbname): Likewise.
-
- * keygen.c (generate_user_id): Use m_alloc_clear() here. We should
- better use an allocation function specific to the user_id packet.
-
- * keygen.c (keygen_add_std_prefs): Changed symmetric preferences
- to include Blowfish again. This is due to it's better speed compared
- to CAST5.
-
- * g10.c (strusage): Print the home directory.
-
- * armor.c (armor_filter): Take action on the cancel control msg.
- * filter.h (armor_filter_context_t): Add cancel flag.
-
-Mon Nov 29 21:52:11 CET 1999 Werner Koch <[email protected]>
-
- * g10.c: New option --fast-list-mode ..
- * keylist.c (list_keyblock): .. and implemented.
- * mainproc.c (list_node): Ditto.
-
- * import.c (mark_non_selfsigned_uids_valid): Fixed the case that there
- is a uid without any packet following.
-
-Mon Nov 22 11:14:53 CET 1999 Werner Koch <[email protected]>
-
- * mainproc.c (proc_plaintext): Never enable the hash processing
- when skip_verify is active.
-
- * armor.c (parse_header_line): Stop parsing on a WS line too.
- Suggested by Aric Cyr.
-
- * tdbdump.c (HEXTOBIN): Changed the name of the argument, so that
- traditional cpp don't mess up the macros. Suggested by Jos Backus.
-
- * mainproc.c (list_node): Print the PK algo in the --with-colon mode.
- * keylist.c (list_keyblock): Ditto.
-
- * signal.c (got_fatal_signal): Found the reason why exit(8) did not
- work - it is better to set the disposition back to default before
- raising the signal. Print the notice on stderr always.
-
-Fri Nov 12 20:33:19 CET 1999 Werner Koch <[email protected]>
-
- * g10.c (make_username): Swapped the logic.
- * keylist.c (public_key_list): Now takes a STRLIST as arg and moved
- the creation ot this list to the caller, so that he can copy with
- UTF-conversion of user IDs. Changed all callers.
- (secret_key_list): Likewise.
-
- * getkey.c (get_user_id_string_native): New and ...
- * encode.c (write_pubkey_enc_from_list): ... use it here.
-
- * pubring.asc: Updated.
-
- * packet.h (PKT_PHOTO_ID): New.
- * parse-packet.c (parse_photo_id): New.
- * build-packet.c (do_user_id: Handle photo IDs.
- (build_packet): Change CTB for photo IDs
- * free-packet.c (free_user_id): Release memory used for photo IDs
- * sig-check.c (hash_uid_node): Handle photo IDs too.
- * trustdb.c (print_uid_from_keyblock): Hash photo ID.
- (make_uid_records): Ditto.
- * getkey.c (find_by_name): Ditto.
- * keyedit.c (show_prefs): Ditto.
- * keylist.c (list_keyblock): Ditto.
-
-Thu Oct 28 16:08:20 CEST 1999 Werner Koch <[email protected]>
-
- * keygen.c (ask_expire_interval): Print a warning for systems
- with a signed 32 time_t if the exiration time is beyoind 2038.
-
-Fri Oct 8 20:40:50 CEST 1999 Werner Koch <[email protected]>
-
- * ringedit.c (enum_keyblocks): The last fix way really stupid;
- reverted and set rt to Unknown.
-
-Fri Oct 8 20:32:01 CEST 1999 Werner Koch <[email protected]>
-
- * ringedit.c (enum_keyblocks): Zero the entire kbpos out on open.
-
- * g10.c (oEntropyDLL): Removed option.
- (main): Made the warning on development versions more verbose.
-
- * g10.c (oHonorHttpProxy): New option.
- * hkp.c (hkp_ask_import,hkp_export): Implement this option.
- * options.skel: Enable this option for new installations
-
-Mon Oct 4 21:23:04 CEST 1999 Werner Koch <[email protected]>
-
- * import.c (import_keys): Changed calling interface, adjusted caller.
- (import): Moved printing of stats out ...
- (print_stats): New. ... to here.
- (import_keys_stream): Call stats print here.
- (import_keys): Print stats as totals for all files.
-
- * tdbio.h (DIRF_NEWKEYS): New
- * tdbio.c (tdbio_dump_record): Print the new flag.
- * trustdb.c (check_trust_record): New arg sigs_only. Adapted all
- callers.
- (do_update_trust_record): Removed recheck arg and add a new sigs_only
- do we can later improve on the performance. Changed all callers too.
- (check_trustdb): Evalutate the new flag and add a status output.
- Do a check when the dir record has not been checked.
- (build_cert_tree): Evaluate the new flag.
- (check_trust): Ditto. Do a trust_record check, when the dir record
- is not marked as checked.
- (mark_fresh_keys): New.
- (clear_lid_table): New.
- (sync_trustdb): New.
- * import.c (import_keys): Call sync_trustdb() after processing.
- (import_keys_stream): Ditto.
- * tdbdump.c (import_ownertrust): Ditto.
-
- * import.c (import_revoke_cert): Notify the trust DB.
- (do_update_trust_record): Use |= to set the REVOKED bit and not &=;
- shame on me for this bad copy+paste introduced bug.
- (do_we_trust): Add trustmask to allow revoked key override to work.
- Chnaged are to allow return of a mofified trustlevel. Adapted the
- one caller.
-
- * g10.c: New options --emulate-3des-s2k-bug
- * passphrase.c (hash_passphrase): Implemented above.
-
- * mainproc.c (proc_tree): Check for standalone signatures.
- (do_check_sig): Print a notice for a standalone revocation
- (check_sig_and_print): Do not print an error for unchecked standalone
- revocations.
-
-Tue Sep 28 20:54:37 CEST 1999 Werner Koch <[email protected]>
-
- * encode.c (encode_simple): Use new CTB when we don't have the
- length of the file. This is somewhat strange as the comment above
- indicates that this part is actually fixed for PGP 5 - maybe I simply
- lost the source line, tsss.
-
- * armor.c (armor_filter): Set a flag if no OpenPGP data has been found.
- * verify.c (verify_signatures): Add an error helptext.
-
-Thu Sep 23 19:24:30 CEST 1999 Werner Koch <[email protected]>
-
- * openfile.c (open_outfile): Fixed the 8dot3 handling.
-
- * passphrase.c (passphrase_to_dek): Print uid using utf8 func.
- * delkey.c (delete_key): Ditto.
- * pkclist.c (show_paths,do_edit_ownertrust,do_we_trust): Ditto
- (do_we_trust_pre): Ditto.
- * trustdb.c (print_user_id,check_uidsigs): Ditto.
- * revoke.c (gen_revoke,ask_revoke_sig): Ditto.
-
-Thu Sep 23 09:52:58 CEST 1999 Werner Koch <[email protected]>
-
- * verify.c (print_file_status): New.
- (verify_one_file): Moved status print to th new fnc. Add error status.
- * status.c, status.h (STATUS_FILE_ERROR): New
-
-Wed Sep 22 10:14:17 CEST 1999 Werner Koch <[email protected]>
-
- * openfile.c (make_outfile_name): Use case-insenstive compare for
- DOS systems. Add ".pgp" to the list of know extensions.
- (open_outfile): For DOS systems try to replace the suffiy instead of
- appending it.
-
- * status.c, status.h: Add STATUS_FILE_{START,DONE}.
- * verify.c (verify_one_file): Emit these new stati.
-
- * sign.c (clearsign_file): Avoid duplicated Entries in the "Hash:"
- line. Those headers are now only _not_ printed when there are
- only old-style keys _and_ all hashs are MD5.
-
-Mon Sep 20 12:24:41 CEST 1999 Werner Koch <[email protected]>
-
-
- * verify.c (verify_files, ferify_one_file): New.
- * g10.c: New command --verify-files
-
-Fri Sep 17 12:56:42 CEST 1999 Werner Koch <[email protected]>
-
- * g10.c: Add UK spelling as alias for armor options ;-)
-
- * import.c (append_uid): Fixed a SEGV when there is no selfsig and
- no subkey.
- (merge_sigs): Ditto. Removed the assertion.
-
-Wed Sep 15 16:22:17 CEST 1999 Werner Koch <[email protected]>
-
- * g10.c: New option --entropy-dll-name
-
-Mon Sep 13 10:51:29 CEST 1999 Werner Koch <[email protected]>
-
- * signal.c (got_fatal_signal): Print message using write(2) and
- only for development versions.
-
-Mon Sep 6 19:59:08 CEST 1999 Werner Koch <[email protected]>
-
- * tdbio.c (tdbio_set_dbname): Use mkdir macro
- * ringedit.c (add_keyblock_resource): Ditto.
-
-Fri Sep 3 10:04:45 CEST 1999 Werner Koch <[email protected]>
-
- * pkclist.c (build_pk_list): Skip keys set with --encrypt-to also
- when asking for a key.
-
- * plaintext.c (handle_plaintext): Make sure that we don't read a
- second EOF in the read loop for partial length packets.
-
- * mainproc.c (check_sig_and_print): print user ID as utf-8.
-
-Thu Sep 2 16:40:55 CEST 1999 Werner Koch <[email protected]>
-
- * import.c (merge_blocks): First add new subkeys, then merge subkey
- certificates.
- (merge_sigs): Don't merge subkey signatures here.
-
-Wed Sep 1 15:30:44 CEST 1999 Werner Koch <[email protected]>
-
- * keygen.c (ask_expire_interval): Fixed bug related to cpr_xx (tnx
- Francis J. Lacoste).
-
-Tue Aug 31 17:20:44 CEST 1999 Werner Koch <[email protected]>
-
- * plaintext.c (do_hash): Hash CR,LF for a single CR.
- (ask_for_detached_datafile): Changed arguments to be closer to
- those of hash_datafiles and cleanup the code a bit.
- * mainproc.c (proc_tree): Workaround for pgp5 textmode detached
- signatures. Changed behavior of asking for data file to be the same
- as with provided data files.
-
- * keylist.c (list_keyblock): Use UTF8 print functions.
-
-Mon Aug 30 20:38:33 CEST 1999 Werner Koch <[email protected]>
-
- * import.c (chk_self_sigs): some s/log_error/log_info/ so that gpg
- does not return an error if a key has some invalid packets.
-
- * helptext.c: Fixed some typos and changed the way the
- translation works. The english text is now the keyword for gettext
- and not anymore the keyword supplied to the function. Done after
- some discussion with Walter who thinks this is much easier for the
- translators.
-
- * misc.c (disable_core_dumps): Don't do it for DOSish systems.
-
- * signal.c (signal_name): Bounds check on signum.
-
-Wed Aug 4 10:34:18 CEST 1999 Werner Koch <[email protected]>
-
- * pubring.asc: Updated.
-
- * pkclist.c (do_we_trust_pre,check_signatures_trust): Do not print
- the warning about --always_trust when --quiet is used.
-
- * pkclist.c (fpr_info): New and called at several places.
-
- * parse-packet.c (dump_sig_subpkt): List revocation key contents.
-
-Mon Jul 26 09:34:46 CEST 1999 Werner Koch <[email protected]>
-
- * pkclist.c (build_pk_list): Fixed typo in format string.
-
- * trustdb.c (create_shadow_dir): Don't translate the error string.
-
- * g10.c (main): Fixed spelling of user-id.
- * getkey.c (find_by_name_pk,find_by_name_sk,
- find_by_keyid,find_by_keyid_sk): Ditto and translate it.
- * import.c (mark_non_selfsigned_uids_valid,delete_inv_parts): Ditto.
-
-
-Mon Jul 26 01:01:39 CEST 1999 Michael Roth <[email protected]>
-
- * g10.c, options.h: New options --no-literal and --set-filesize
-
- * encode.c (encode_simple, encode_crypt): Support for the options
- --no-literal and --set-filesize.
-
- * sign.c (sign_file): ditto.
-
-Fri Jul 23 13:53:03 CEST 1999 Werner Koch <[email protected]>
-
-
- * ringedit.c (enum_keyblocks): Removed annoying error message in cases
- when we have no keyring at all to enum.
-
- * getkey.c (classify_user_id): Rewrote to relax the recognition of
- keyIDs and fingerprints (Michael).
-
- * mainproc.c (check_sig_and_print): Print status NO_PUBKEY.
- (print_failed_pkenc): Print status NO_SECKEY.
-
- * import.c (mark_non_selfsigned_uids_valid): New.
- * g10.c: New option --allow-non-selfsigned-uid.
-
- * pkclist.c (print_fpr): New.
- (do_we_trust_pre): Print the fpr before asking whether to use the key
- anyway.
- (do_edit_ownertrust): Likewise.
-
-Thu Jul 22 20:03:03 CEST 1999 Werner Koch <[email protected]>
-
-
- * ringedit.c (enum_keyblocks): Removed annoying error message in cases
- when we have no keyring at all to enum.
-
- * getkey.c (classify_user_id): Rewrote to relax the recognition of
- keyIDs and fingerprints (Michael).
-
- * mainproc.c (check_sig_and_print): Print status NO_PUBKEY.
- (print_failed_pkenc): Print status NO_SECKEY.
-
- * import.c (mark_non_selfsigned_uids_valid): New.
- * g10.c: New option --allow-non-selfsigned-uid.
-
-Thu Jul 15 10:15:35 CEST 1999 Werner Koch <[email protected]>
-
- * g10.c: New options --disable-{cipher,pubkey}-algo.
-
-Wed Jul 14 19:42:08 CEST 1999 Werner Koch <[email protected]>
-
- * status.h (STATUS_IMPORTED): New.
- * import.c (import): Print some status information (Holger Schurig).
-
- * g10.c (main): Make --no-greeting work again. Add a warning when
- --force-mds is used.
-
-Tue Jul 13 17:39:25 CEST 1999 Werner Koch <[email protected]>
-
- * pkclist.c (do_edit_ownertrust): Changed the way help works.
- (build_pk_list): Implemented default recipient stuff.
- * g10.c: New options --default-recipient[-self]
- (main): Suppress greeting in most cases, entering a passphrase or
- a missing value is not considered to be interactive use.
- Merged --print-md and --print-mds; the latter is now obsolete.
- Changed the way --gen-random works and documented it.
- Changed the way --gen-prime works and add a man entry.
- * g10.c (MAINTAINER_OPTIONS): Removed.
-
-Mon Jul 12 18:45:57 CEST 1999 Werner Koch <[email protected]>
-
- * keyedit.c (keyedit_menu): Add arg sign_mode and changed callers
- * g10.c (main): New command --lsign-key.
-
-Mon Jul 12 14:55:34 CEST 1999 Werner Koch <[email protected]>
-
- * mainproc.c (kidlist_item): New.
- (release_list): Release failed pk-enc-list.
- (print_failed_pkenc): New
- (proc_encrypted): Print info about failed PK enc.
-
- * openfile.c (make_outfile_name): s/error/info/
-
- * passphrase.c (passphrase_to_dek): Return an empty passphrase when
- in batch mode and don't make the warning message fatal
- * seckey-cert.c (check_secret_key): Try only once when in batch mode.
-
- * g10.c (make_username): New.
-
-Thu Jul 8 16:21:27 CEST 1999 Werner Koch <[email protected]>
-
-
- * packet.h (PKT_ring_trust): New
- * parse-packet.c (parse_trust): Store trust value
- * build-packet (build_packet): Ignore ring trust packets.
- * mainproc.c (add_ring_trust): New.
- (list_node): Print "rtv" records.
- * g10.c: New option --with-fingerprint.
-
- * trustdb.c (verify_own_keys): Don't insert if we are dry running
- (check_trust): Ditto.
-
-Wed Jul 7 13:08:40 CEST 1999 Werner Koch <[email protected]>
-
- * Makefile.am: Support for libtool.
-
- * keygen.c (ask_expire_interval): Hack to allow for an expire date.
-
- * trustdb.c (do_update_trust_record,update_trust_record): Splitted.
- (check_trust_record): New.
- (check_trust,build_cert_tree): Check the dir record as needed.
- (upd_pref_record): Removed.
- (make_pref_record): New.
- (propagate_validity): Stop as soon as we have enough validity.
-
- * tbdio.c (MAX_CACHE_ENTRIES_HARD): Increased the limit.
-
-
-Fri Jul 2 11:45:54 CEST 1999 Werner Koch <[email protected]>
-
- * g10.c (g10_exit): Dump random stats.
-
- * sig-check.c (check_key_signature,check_key_signature2): Enhanced
- version and wrapper for old function.
- (do_signature_check,signature_check): Ditto.
-
-Thu Jul 1 12:47:31 CEST 1999 Werner Koch <[email protected]>
-
-
- * keyedit.c (show_key_with_all_names): Print a notice for disabled keys.
- (enable_disable_keys): Add functionality
- * pkclist.c (edit_ownertrust): preserve disabled state.
- (build_pk_list): Skip disabled keys.
- * trustdb.c (upd_one_ownertrust): Ditto.
- (build_cert_tree): Mask the ownertrust.
- (trust_letter): Mask the value.
- (do_check): Take disabled flag into account.
-
- * passphrase.c (passphrase_to_dek): Add a pubkey_algo arg and changed
- all callers.
-
- * g10.c (utf8_strings): 2 new options.
-
- * trustdb.c (insert_trust_record_by_pk): New, replaces the next one.
- (insert_trust_record): Now takes a keyblock as arg. Changed all
- callers to use the appropritae function.
-
- * openfile.c (ask_outfile_name): New.
- * plaintext.c (handle_plaintext): Ask for filename if there is
- no valid syntax. Don't use fname varbatim but filter it.
-
-Tue Jun 29 21:44:25 CEST 1999 Werner Koch <[email protected]>
-
-
- * trustdb.h (TRUST_FLAG_DISABLED): New.
-
- * status.c (USE_CAPABILITIES): Capabilities support (Remi).
-
- * tdbio.c : Added new fields to the DIR record.
- (tdbio_write_record): Fixed the update of the hash tables.
- (tdbio_delete_record): Drop the record from the hash tables.
- (drop_from_hashtbl): New.
-
- * status.c (cpr_get): Special online help mode.
- * helptext.c ("keyedit.cmd"): Removed.
- * keyedit.c (keyedit_menu): Use only help system.
- (enable_disable_key): New bit doies not yet work.
-
-Sat Jun 26 12:15:59 CEST 1999 Werner Koch <[email protected]>
-
-
- * dearmor.c (enarmor_file): Fixed comment string.
- * tdbdump.c (export_ownertrust): Text fix.
- * tbio.c (tdbio_invalid): Ditto.
-
- * parse-packet.c (parse_key): Made temp buffer larger.
-
- * Makefile.am (install-data-local): Add missing backslashes
-
-Tue Jun 15 12:21:08 CEST 1999 Werner Koch <[email protected]>
-
- * g10.c (main): Made iterated+salted the default S2K method.
-
- * Makefile.am (install-data-local): Use DESTDIR.
-
- * passphrase.c (passphrase_to_dek): Emit missing-passphrase while in
- batchmode.
-
- * parse-packet.c (parse_pubkeyenc): Fixed a SEGV.
-
-Mon Jun 14 21:18:54 CEST 1999 Michael Roth <[email protected]>
-
- * g10.c: New options --openpgp, --no-tty, --emit-version,
- --default-comment and --lock-multiple
-
-Thu Jun 10 14:18:23 CEST 1999 Werner Koch <[email protected]>
-
- * free-packet.c (free_encrypted): Fixed EOF case (Remi).
- (free_plaintext): Ditto.
-
- * helptext.c (keyedit.delsig.unknown): New (Remi).
- * keyedit.c (print_and_check_one_sig): Add arg print_without_key and
- changed all callers to make use of it (Remi):
-
-Tue Jun 8 13:36:25 CEST 1999 Werner Koch <[email protected]>
-
- * keylist.c (print_key_data): New and called elsewhere.
- * g10.c: New option --with-key-data
-
-Wed Jun 2 14:17:19 CEST 1999 Werner Koch <[email protected]>
-
- * mainproc.c (proc_tree): Yet another bad hack to cope with
- broken pgp2 created detached messages in textmode.
-
-Tue Jun 1 16:01:46 CEST 1999 Werner Koch <[email protected]>
-
- * openfile.c (make_outfile_name): New.
- * plaintext.c (handle_plaintext): Outputfile is now the inputfile
- without the suffix.
- * g10.c: New option --use-embedded-filename
-
-Mon May 31 19:41:10 CEST 1999 Werner Koch <[email protected]>
-
- * g10.c (main): Fix for SHM init (Michael).
-
- * compress.c, encr-data.c, mdfilter.c,
- plaintext.c, free-packet.c: Speed patches (R�mi).
-
-Thu May 27 09:40:55 CEST 1999 Werner Koch <[email protected]>
-
- * status.c (cpr_get_answer_yes_no_quit): New.
- * keyedit.c (menu_delsig): New.
- (check_all_keysigs): Splitted.
- (print_and_check_one_sig): New.
-
-Wed May 26 14:36:29 CEST 1999 Werner Koch <[email protected]>
-
- * build-packet.c (build_sig_subpkt): Support large packets.
- * parse-packet.c (enum_sig_subpkt): Replaces parse_sig_subpkt.
- * mainproc.c (print_notation_data): Print all notation packets.
- * g10.c (add_notation_data): Add a way to specify the critical flag.
- (main): Add option --set-policy-url.
- (check_policy_url): Basic checks.
- * sign.c (mk_notation_and_policy): Replaces mk_notation.
-
- * parse-packet.c (can_handle_critical): Moved decision whether we can
- handle critical subpacket to an extra function.
-
-Tue May 25 19:50:32 CEST 1999 Werner Koch <[email protected]>
-
- * sign.c (sign_file): Always use compression algo 1 for signed
- onyl file becuase we can� be sure the the verifier supports other
- algorithms.
-
- * build-packet.c (build_sig_subpkt): Support for notation data.
- * sign.c (sign_file,clearsign_file,make_keysig_packet): Ditto.
- (mk_notation): New.
- * g10.c (add_notation_data): New and add option -N
- * mainproc.c (print_notation_data): New.
- (check_sig_and_print): Print any notation data of the signed text.
-
-Sun May 23 14:20:22 CEST 1999 Werner Koch <[email protected]>
-
- * pkclist.c (check_signatures_trust): Print a warning and return
- immediateley if opt.always_trust is true.
-
- * g10.c (main): Corrected handling of no-default-keyring
-
- * pkclist.c (algo_available): Disable Twofish until we have settled
- how to do the MDC.
-
- * hkp.c: Disable everything for mingw32
-
-Sat May 22 22:47:26 CEST 1999 Werner Koch <[email protected]>
-
- * mainproc.c (check_sig_and_print): Add sig creation time to the
- VALIDSIG status output. Add more info to the ERRSIG output.
- * sig-check.c (signature_check): Add sig time after epoch to SIG_ID.
-
- * import.c (import_one): Merge duplicate user IDs.
- (collapse_uids): New.
- * kbnode.c (move_kbnode): New.
- (remove_kbnode): New.
- * keyedit.c (keyedit_menu): Call collapse_uids.
-
- * g10.c: new option --logger-fd.
-
- * import.c: s/log_*_f/log_*/
-
-Thu May 20 14:04:08 CEST 1999 Werner Koch <[email protected]>
-
- * misc.c (pull_in_libs): do the volatile only for gcc
-
- * sig-check (signature_check): Emit SIG_iD only for classes 0 and 1.
-
- * armor.c (armor_filter): Add detection of PGP2 created clearsigs.
- (fake_packet): A tab is not a WS for pgp2 - handle this.
- * textfilter.c (len_without_trailing_chars): New.
- (copy_clearsig_text): Add pgp2mode arg.
- * sign.c (clearsign_file): pass old_style to the above fnc.
-
-
-Wed May 19 16:04:30 CEST 1999 Werner Koch <[email protected]>
-
- * g10.c: New option --interactive.
-
- * mainproc.c (proc_plaintext): Add workaround for pgp2 bug
- (do_check_sig): Ditto.
- (proc_tree): Ditto.
- * plaintext.c (do_hash): Ditto.
- (hash_datafiles): Ditto, add an arg, changed all callers.
- * mdfilter.c (md_filter): Add support for the alternate hash context.
-
-Mon May 17 21:54:43 CEST 1999 Werner Koch <[email protected]>
-
- * parse-packet.c (parse_encrypted): Support for PKT_ENCRYPTED_MDC.
- * build-packet.c (do_encrypted_mdc): Ditto.
- * cipher.c (write_header): Add mdc hashing.
- (cipher_filter): write out the hash.
- * mainproc.c (do_proc_packets): Add PKT_ENCRYPTED_MDC.
- * encr-data.c (decrypt_data): Add mdc hashing.
- (mdc_decode_filter): New.
-
- * parse-packet.c (parse_sig_subpkt): Fixed stupid bug for subpkt
- length calculation
- (parse_signature): Fixed even more stupid bug.
-
-Sat May 8 19:28:08 CEST 1999 Werner Koch <[email protected]>
-
- * build-packet.c (do_signature): Removed MDC hack.
- * encode.c (encode_crypt_mdc): Removed.
- * mainproc.c (do_check_sig): Removed MDC hack.
- (check_sig_and_print): Ditto.
- * parse-packet.c (parse_signature): Ditto.
- * sig-check.c (mdc_kludge_check): Ditto.
- * free-packte.c (copy_signature, free_seckey_enc): Ditto.
-
- * parse-packet.c (parse_signature,parse_key): Store data of
- unknown algorithms with mpi_set_opaque inseatd of the old
- faked data stuff.
- (read_rest): Removed.
- (read_rest2): Renamed to read_rest
- * build-packet.c (write_fake_data): Use mpi_get_opaque.
- * free-packet.c (cp_fake_data): Removed and cahnged all callers
- to use mpi_copy.
- (free_pubkey_enc,free_seckey_enc,release_public_key_parts,
- release_secret_key_parts): Use mpi_free for opaque data.
-
-Thu May 6 14:18:17 CEST 1999 Werner Koch <[email protected]>
-
- * trustdb.c (check_trust): Check for revoked subkeys.
- * pkclist.c (do_we_trust): Handled revoked subkeys.
- (do_we_trust_pre): Ditto.
- (check_signatures_trust): Ditto.
-
- * build-packet.c (hash_public_key): Fix for ancient g10 keys.
-
- * mainproc.c (do_proc_packets): Return EOF if no data has been read.
- * g10.c (main): Catch errors for default operation.
-
-Thu Apr 29 12:29:22 CEST 1999 Werner Koch <[email protected]>
-
- * sign.c (sign_file): Fixed hashing in case of no subpackets.
- (clearsign_file): Ditto.
- (make_keysig_packet): Ditto.
-
-Wed Apr 28 13:03:03 CEST 1999 Werner Koch <[email protected]>
-
- * keyedit.c (keyedit_menu): Add new command revkey.
- * (menu_revkey): New.
-
-
-Mon Apr 26 17:48:15 CEST 1999 Werner Koch <[email protected]>
-
- * parse-packet.c (parse_signature): Add the MDC hack.
- * build-packet.c (do_signature): Ditto.
- * free-packet.c (free_seckey_enc,copy_signature,cmp_signatures): Ditto.
- * mainproc.c (do_check_sig): Ditto.
- * sig-check.c (mdc_kludge_check): New.
- * encode.c (encrypt_mdc_file): New.
-
- * keyedit.c (check_all_keysigs): List revocations.
- * (menu_revsig): New.
- * sign (make_keysig_packet): Support for class 0x30.
-
-Sun Apr 18 20:48:15 CEST 1999 Werner Koch <[email protected]>
-
- * pkclist.c (select_algo_from_prefs): Fixed the case that one key
- has no preferences (Remi Guyomarch).
-
- keylist.c (list_keyblock): ulti_hack to propagate trust to all uids.
-
-Sun Apr 18 10:11:28 CEST 1999 Werner Koch <[email protected]>
-
- * seckey-cert.c (do_check): Use real IV instead of a 0 one, so that
- it works even if the length of the IV doesn't match the blocksize.
- Removed the save_iv stuff.
- (protect_secret_key): Likewise. Create the IV here.
- * packet.h (PKT_secret_key): Increased size of IV field and add a
- ivlen field.
- * parse-packet.c (parse_key): Use the len protect.ivlen.
- * build-packet.c (do_secret_key). Ditto.
-
- * getkey.c (key_byname): Close keyblocks.
-
- * Makefile.am (gpgm): Removed this
- * g10.c: Merged gpg and gpgm
-
- * import.c (import): Utilize option quiet.
- * tdbio.c (tdbio_set_dbname): Ditto.
- * ringedit.c (add_keyblock_resource,keyring_copy): Ditto.
-
- * keyedit.c (sign_uids): Add some batch support.
-
- * g10.c (main): add call to tty_batchmode.
-
-Fri Apr 9 12:26:25 CEST 1999 Werner Koch <[email protected]>
-
- * status.c (write_status_text): Some more status codes.
- * passphrase_to_dek (passphrase_to_dek): add a status code.
- * seckey_cert.c (check_secret_key): Likewise.
-
- * encr-data.c (decrypt_data): Reverse the last changes
- * cipher.c (write_header): Ditto.
-
- * parse-packet.c (parse_key): Dropped kludge for ancient blowfish mode.
-
-Thu Apr 8 09:35:53 CEST 1999 Werner Koch <[email protected]>
-
- * mainproc.c (proc_encrypted): Add a new status output
- * passphrase.c (passphrase_to_dek): Ditto.
- * status.h status.c: Add new status tokens.
-
-Wed Apr 7 20:51:39 CEST 1999 Werner Koch <[email protected]>
-
- * encr-data.c (decrypt_data): Fixes for 128 bit blocksize
- * cipher.c (write_header): Ditto.
- * seckey-cert.c (do_check): Ditto.
- (protect_secret_key). Ditto.
- * misc.c (print_cipher_algo_note): Twofish is now a standard algo.
-
- * keygen.c (do_create): Fixed spelling (Ga�l Qu�ri)
- (ask_keysize): Only allow keysizes up to 4096
-
- * ringedit.c (add_keyblock_resource): chmod newly created secrings.
-
- * import.c (delete_inv_parts): Fixed accidently deleted subkeys.
-
-Tue Apr 6 19:58:12 CEST 1999 Werner Koch <[email protected]>
-
- * armor.c: Removed duped include (John Bley)
- * mainproc.c: Ditto.
-
- * build-packet.c (hash_public_key): Fixed hashing of the header.
-
- * import.c (delete_inv_parts): Allow import of own non-exportable sigs.
-
-Sat Mar 20 13:59:47 CET 1999 Werner Koch <[email protected]>
-
- * armor.c (fake_packet): Fix for not not-dash-escaped
-
-Sat Mar 20 11:44:21 CET 1999 Werner Koch <[email protected]>
-
- * g10.c (main): Added command --recv-keys
- * hkp.c (hkp_import): New.
-
-Wed Mar 17 13:09:03 CET 1999 Werner Koch <[email protected]>
-
- * trustdb.c (check_trust): add new arg add_fnc and changed all callers.
- (do_check): Ditto.
- (verify_key): Ditto.
- (propagate_validity): Use the new add_fnc arg.
- (print_user_id): Add the FILE arg.
- (propagate_ownertrust): New.
- * pkclist.c (add_ownertrust_cb): New and changed the add_ownertrust
- logic.
-
- * getkey.c (get_keyblock_bylid): New.
- * trustdb.c (print_uid_from_keyblock): New.
- (dump_tn_tree_with_colons): New.
- (list_trust_path): Add colon print mode.
-
- * trustdb.c (insert_trust_record): Always use the primary key.
-
- * encode.c (encode_simple): Added text_mode filter (R�mi Guyomarch)
- (encode_crypt): Ditto.
-
- * mainproc.c (proc_pubkey_enc): Added status ENC_TO.
- * armor.c (armor_filter): Added status NODATA.
- * passphrase.c (passphrase_to_dek): Always print NEED_PASSPHRASE
- * seckey_cert.c (check_secret_key): Added BAD_PASS status.
-
- * g10.c (main): Set g10_opt_homedir.
-
-Sun Mar 14 19:34:36 CET 1999 Werner Koch <[email protected]>
-
- * keygen.c (do_create): Changed wording of the note (Hugh Daniel)
-
-Thu Mar 11 16:39:46 CET 1999 Werner Koch <[email protected]>
-
- * tdbdump.c: New
-
- * trustdb.c (walk_sigrecs,do_list_sigs,list_sigs,
- list_records,list_trustdb,export_ownertrust,import_ownertrust): Moved
- to tdbdump.c
- (init_trustdb): renamed to setup_trustdb. Changed all callers.
- (do_init_trustdb): renamed to init_trustdb().
- * trustdb.c (die_invalid_db): replaced by tdbio_invalid.
- * tdbio.c (tdbio_invalid): New.
-
- * import.c (delete_inv_parts): Skip non exportable signatures.
- * keyedit.c (sign_uid_mk_attrib): New.
- (sign_uids): Add the local argument.
- (keyedit_menu): New "lsign" command.
- * trustdb.c (register_trusted_key): Removed this and all related stuff.
- * g10.c (oTrustedKey): Removed option.
-
- * tdbio.h (dir.valcheck): New trustdb field.
- * tdbio.c: Add support for this field
- (tdbio_read_modify_stamp): New.
- (tdbio_write_modify_stamp): New.
- * trustdb.c (do_check): Check against this field. Removed cache update.
- (verify_key): Add cache update.
- (upd_uid_record): Some functional changes.
- (upd_cert_record): Ditto
-
-Wed Mar 10 11:26:18 CET 1999 Werner Koch <[email protected]>
-
- * keylist.c (list_keyblock): Fixed segv in uid. Print 'u' as
- validity of sks.
-
-Mon Mar 8 20:47:17 CET 1999 Werner Koch <[email protected]>
-
- * getkey.c (classify_user_id): Add new mode 12 (#<lid>).
-
- * seckey-cert.c (check_secret_key): replaced error by info.
-
- * trustdb.c (query_trust_info): Add another arg, changed all callers.
- (check_trust): Ditto.
- (do_check): Ditto.
- (verify_key): Handle namehash.
- * keylist.c (list_keyblock): print trust info for user ids.
-
- * sig-check.c (signature_check): Add sig-created to status output.
-
-Tue Mar 2 16:44:57 CET 1999 Werner Koch <[email protected]>
-
- * textfilter.c (copy_clearsig_text): New.
- (clearsign): Removed.
- * sign.c (clearsign_file): does not use textfiler anymore.
-
- * keygen.c (ask_user_id): print a note about the used charset.
-
-Tue Mar 2 10:38:42 CET 1999 Werner Koch <[email protected]>
-
- * sig-check.c (signature_check): sig-id now works for all algos.
-
- * armor.c (armor_filter): Fixed armor bypassing.
-
-Sun Feb 28 19:11:00 CET 1999 Werner Koch <[email protected]>
-
- * keygen.c (ask_user_id): Don't change the case of email addresses.
- (has_invalid_email_chars): Adjusted.
-
- * keylist.c (list_one): Really list serect keys (Remi Guyomarch)
-
- * keyedit.c (menu_select_uid): Add some braces to make egcs happy.
- (menu_select_key): Ditto.
-
- * mainproc.c (do_proc_packets): List sym-enc packets (Remi Guyomarch)
-
-Fri Feb 26 17:55:41 CET 1999 Werner Koch <[email protected]>
-
- * pkclist.c (build_pk_list): Return error if there are no recipients.
-
- * sig-check.c (signature_check): New signature id feature.
- * armor.c (make_radic64_string): New.
-
- * mainproc.c (proc_pubkey_enc): early check for seckey availability.
-
- * pkclist.c (do_we_trust_pre): print user id before asking.
-
- * ringedit.c (add_keyblock_resource,get_keyblock_handle): Cleaner
- handling of default resource.
-
-
-Thu Feb 25 18:47:39 CET 1999 Werner Koch <[email protected]>
-
- * pkclist.c (algo_available): New.
- (select_algo_from_prefs): Check whether algo is available.
-
- * ringedit.c (keyring_copy): Take care of opt.dry_run.
- (do_gdbm_store): Ditto.
- * openfile.c (open_outfile). Ditto.
- (copy_options_file): Ditto.
- * trustdb.c (update_trustdb): Ditto.
- (clear_trust_checked_flag): Ditto.
- (update_trust_record): Ditto.
- (insert_trust_record): Ditto.
-
-Wed Feb 24 11:07:27 CET 1999 Werner Koch <[email protected]>
-
- * keylist.c (secret_key_list): Now really list the secret key.
-
- * trustdb.c (do_init_trustdb): New. Init is now deferred.
-
-Mon Feb 22 20:04:00 CET 1999 Werner Koch <[email protected]>
-
- * getkey.c (lookup_sk): Return G10ERR_NO_SECKEY and not x_PUBKEY.
-
-Fri Feb 19 15:49:15 CET 1999 Werner Koch <[email protected]>
-
- * pkclist.c (select_algo_from_prefs): retrieve LID if not there.
-
- * armor.c (fake_packet): Replaced ugly lineending handling.
-
- * g10.c (oNoEncryptTo): New.
- * pkclist.c (build_pk_list): Implemented this option.
-
- * g10.c (main): Greeting is now printed to stderr and not to tty.
- Use add_to_strlist() instead of direct coding.
-
- * import.c (import): Use iobuf_push_filter2.
-
- * mainproc.c (check_sig_and_print): Print all user ids
- for good signatures.
- * getkey.c (get_pubkeyblock): New.
-
- * import.c (chk_self_sigs): Fixed SEGV for unbounded class 0x18 keys.
- (delete_inv_parts): Delete special marked packets.
-
-Tue Feb 16 14:10:02 CET 1999 Werner Koch <[email protected]>
-
- * g10.c (main): New option --encrypt-to
-
- * pkclist.c (build_pk_list): Implemented encrypt-to.
-
- * parse-packet.c (parse_user_id): Removed the hack to work with
- utf-8 strings.
-
- * g10.c (main): Install lockfile cleanup handler.
- * tdbio.c (cleanup): Removed: this is now handled by dotlock.
-
-Sat Feb 13 14:13:04 CET 1999 Werner Koch <[email protected]>
-
- * tdbio.c (tdbio_set_dbname): Init lockhandle for a new trustdb
-
-Wed Feb 10 17:15:39 CET 1999 Werner Koch <[email protected]>
-
- * g10.c (main): check for development version now in configure
-
- * tdbio.c (tdbio_write_record): Add uid.validity
- (tdbio_read_record) : Ditto.
- (tdbio_dump_record) : Ditto.
-
- * keygen.c (keygen_add_std_prefs): Replaced Blowfish by Twofish,
- removed MD5 and Tiger.
- * pubkey-enc.c (get_it): Suppress warning about missing Blowfish
- in preferences in certain cases.
-
- * ringedit.c (lock_rentry,unlock_rentry): New.
-
- * getkey.c (key_byname): Pass ret_kb down to lookup_xx.
-
- * armor.c (armor_filter): No output of of empty comment lines.
- Add option --no-version to suppress the output of the version string.
-
- * getkey.c: Release the getkey context for auto context variables.
-
-Sun Jan 24 18:16:26 CET 1999 Werner Koch <[email protected]>
-
- * getkey.c: Changed the internal design to allow simultaneous
- lookup of multible user ids
- (get_pubkey_bynames): New.
- (get_seckey_bynames): New.
- (get_seckey_next): New.
- (get_seckey_end): New.
- * keylist.c (list_one): Use the new functions.
-
- * keylist.c (list_keyblock): add a newline for normal listings.
-
- * g10.c (--recipient): New option name to replace --remote-user
-
-
-Wed Jan 20 18:59:49 CET 1999 Werner Koch <[email protected]>
-
- * textfilter.c: Mostly rewritten
- * plaintext.c (handle_plaintext): Use now text_filter semantics.
-
-Tue Jan 19 19:34:58 CET 1999 Werner Koch <[email protected]>
-
- * export.c (export_pubkeys_stream): New.
- (do_export_stream): New.
- * g10.c (aSendKeys): New command.
- * hkp.c (hkp_export): New.
-
- * compress.c (do_uncompress): Hack for algo 1 and 1.1.3
-
-Sun Jan 17 11:04:33 CET 1999 Werner Koch <[email protected]>
-
- * textfilter.c (text_filter): Now uses iobuf_read_line().
- (read_line): Removed.
-
- * armor.c (trim_trailing_spaces): Removed and replaced
- by trim_trailing_ws from libutil
-
-Sat Jan 16 12:03:27 CET 1999 Werner Koch <[email protected]>
-
- * hkp.c (hkp_ask_import): Use only the short keyid
-
-Sat Jan 16 09:27:30 CET 1999 Werner Koch <[email protected]>
-
- * import.c (import_key_stream): New
- (import): New, moved most of import_keys here.
- * g10.c: New option --keyserver
- * mainproc.c (check_sig_and_print): Hook to import a pubkey.
-
- * pref.c pref.h : Removed
-
- * hkp.c hkp.h: New
-
-Wed Jan 13 14:10:15 CET 1999 Werner Koch <[email protected]>
-
- * armor.c (radix64_read): Print an error if a bad armor was detected.
-
-Wed Jan 13 12:49:36 CET 1999 Werner Koch <[email protected]>
-
- * armor.c (radix64_read): Now handles malformed armors produced
- by some buggy MUAs.
-
-Tue Jan 12 11:17:18 CET 1999 Werner Koch <[email protected]>
-
- * ringedit.c (find_keyblock_bysk): New.
-
- * skc_list.c (is_insecure): New.
- (build_sk_list): usage check for insecure keys.
-
- * import.c (chk_self_sigs): Add handling for subkeys.
- (delete_inv_parts): Skip unsigned subkeys
-
- * sig-check.c (do_check): Print info if the signature is older
- than the key.
- * keygen.c (generate_subkeypair): Fail on time warp.
- * sign.c (do_sign): Ditto.
-
-Sun Jan 10 15:10:02 CET 1999 Werner Koch <[email protected]>
-
- * armor.c (fake_packet): Fixed not-dash-escaped bug.
-
-Sat Jan 9 16:02:23 CET 1999 Werner Koch <[email protected]>
-
- * sig-check.c (do_check): Output time diff on error
-
- * status.c (STATUS_VALIDSIG): New.
- (is_status_enabled): New.
- * mainproc.c (check_sig_and_print): Issue that status message.
-
- * plaintext.c (special_md_putc): Removed
-
- * armor.c (armor_filter): print error for truncated lines.
-
- * free-packet.c (free_encrypted): Revomed call to set_block_mode.
- (free_plaintext): Ditto.
-
-Thu Jan 7 18:00:58 CET 1999 Werner Koch <[email protected]>
-
- * pkclist.c (add_ownertrust): Fixed return value.
-
- * encr-data.c (decrypt_data): Disabled iobuf_set_limit and
- iobuf_pop_filter stuff.
- * compress.c (handle_compressed): Disabled iobuf_pop_filter.
-
- * packet.h (PKT_secret_key): Add is_primary flag.
- * parse-packet.c (parse_key): Set this flag.
- * passphrase.c (passphrase_to_dek): Kludge to print the primary
- keyid - changed the API: keyid must now hold 2 keyids.
- * getkey.c (get_primary_seckey): New.
- * seckey-cert.c (do_check): pass primary keyid to passphrase query
-
- * tbdio.c (open_db): removed the atexit
- (tdbio_set_dbname): and moved it to here.
-
- * armor.c: Rewrote large parts.
-
-Tue Dec 29 19:55:38 CET 1998 Werner Koch <[email protected]>
-
- * revoke.c (gen_revoke): Removed compression.
-
- * pkclist.c (do_we_trust_pre): special check for revoked keys
-
- * trustdb.c (update_trust_record): Fixed revoke flag.
-
-Tue Dec 29 14:41:47 CET 1998 Werner Koch <[email protected]>
-
- * misc.c (disable_core_dumps): Check for EINVAL (Atari)
-
- * getkey (merge_one_pk_and_selfsig): Fixed search of expiredate.
- (merge_keys_and_selfsig): Ditto.
-
- * free-packet.c (cmp_public_keys): cmp expire only for v3 packets
- (cmp_secret_keys): Ditto.
- (cmp_public_secret_key): Ditto.
-
-Wed Dec 23 17:12:24 CET 1998 Werner Koch <[email protected]>
-
- * armor.c (find_header): Reset not_dashed at every header
-
-Wed Dec 23 13:18:14 CET 1998 Werner Koch <[email protected]>
-
- * pkclist.c (add_ownertrust): Refresh validity values.
-
- * trustdb.c (enum_cert_paths_print): New arg refresh.
-
- * ringedit.c: Fixed problems fix keyrings
- * parse-packet.c (dbg_parse_packet): New debug functions.
-
- * getkey.c (getkey_disable_caches): New.
- * import.c (import_keys): Disable caches.
-
-Thu Dec 17 18:31:15 CET 1998 Werner Koch <[email protected]>
-
- * misc.c (trap_unaligned): Only for glibc 1
-
- * sign.c (write_dash_escaped): Now escapes "From " lines
- * g10.c: New option --escape-from-lines
-
- * trustdb.c (sort_tsl_list): New
- (list_trust_path): Now prints sorted list.
- (enum_cert_paths): Likewise.
- (enum_cert_paths_print): New.
- (print_paths): New printing format.
- * pkclist.c (add_ownertrust): New arg quit.
- (edit_ownertrust): New quit selection and does not query
- the recipients ownertrust anymore.
- (add_ownertrust): Print the ceritficate path.
-
-
-Mon Dec 14 21:18:49 CET 1998 Werner Koch <[email protected]>
-
- * parse-packet.c (parse_signature): Now checks for critical bit
- (parse_sig_subpkt): Splitted.
- (parse_one_sig_subpkt): New.
- * sig-check.c (do_check): handle critical bit.
-
-Sun Dec 13 14:10:56 CET 1998 Werner Koch <[email protected]>
-
- * pcklist.c (select_algo_from_prefs): Preferences should
- now work (lost the != ? )
-
-Thu Dec 10 20:15:36 CET 1998 Werner Koch <[email protected]>
-
- * ringedit.c (gdbm_store): Fix for inserts
-
- * g10.c (main): New option --export-all
- * export.c (export_pubkeys): New arg.
- (do_export): Now may skip old keys.
-
- * status.c: Minor patches for Sun's cc
-
- * keygen.c (ask_algo): Disabled v3 ElGamal choice, rearranged
- the numbers. Add a warning question when a sign+encrypt key
- is selected.
-
- * g10.c (do_not_use_RSA): Removed.
- * misc.c (print_pubkey_algo_note): New as replacement for the
- do_not_use_RSA() and chnaged all callers.
- (print_cipher_algo_note): New.
- (print_hash_algo_note): New.
-
- * cipher.c (write_header): Add a call to print_cipher_algo_note.
- * seckey-cert.c (protect_secret_key): Ditto
- * sign.c (do_sign): Add a call to print_digest_algo_note.
-
- * getkey.c (get_long_user_id_string): New.
- * mainproc.c (check_sig_and_print): Changed the format of the
- status output.
-
- * encrypt.c (write_pubkey_enc_from_list): print used symmetric cipher.
-
- * pkclist.c (do_we_trust): Changed a message.
-
-Wed Dec 9 13:41:06 CET 1998 Werner Koch <[email protected]>
-
- * misc.c (trap_unaligned) [ALPHA]: Only if UAC_SIGBUS is defined.
-
- * sign.c (write_dash_escaped): Add the forgotten patch by Brian Moore.
-
- * compress.c (do_uncompress): Fixed the inflating bug.
-
-
-Tue Dec 8 13:15:16 CET 1998 Werner Koch <[email protected]>
-
- * trustdb.c (upd_uid_record): Now uses the newest self-signature
- (insert_trust_record): Now calls update with recheck set to true.
- (register_trusted_key): New.
- (verify_own_keys): Enhanced by list of trusted keys.
-
- * g10.c (main): Print a warning when a devel version is used.
- (main): New option --trusted-key
-
- * import.c (merge_blocks): Fixed merging of new user ids and
- added merging of subkeys.
- (append_uid): Ditto.
- (merge_keysig): New.
- (append_key): New.
- * getkey.c (merge_one_pk_and_selfsig): Get the expiration time
- from the newest self-signature.
- (merge_keys_and_selfsig): Ditto.
-
- * free-packet.c (cmp_secret_key): New.
-
-
-Fri Nov 27 21:37:41 CET 1998 Werner Koch <[email protected]>
-
- * g10.c: New option --lock-once
- * tdbio.c (open_db): Add an atexit
- (cleanup): New.
- (tdbio_sync): Add locking.
- (tdbio_end_transaction): Ditto.
- (put_record_into_cache): Ditto.
- * ringedit.c (keyring_copy): Ditto.
- (cleanup): New.
- (add_keyblock_resource): Add an atexit.
-
-Fri Nov 27 15:30:24 CET 1998 Werner Koch <[email protected]>
-
- * armor.c (find_header): Another fix for clearsigs.
-
-Fri Nov 27 12:39:29 CET 1998 Werner Koch <[email protected]>
-
-
- * status.c (display_help): Removed.
- * helptext.c: New and removed the N_() from all cpr_gets.
-
-
-Fri Nov 20 16:54:52 1998 Werner Koch ([email protected])
-
- * g10.c (main): New option --not-dash-escaped
- * sign.c (write_dashed_escaped): Ditto.
- * armor.c (find_header): Support for NotDashEscaped header.
-
- * getkey.c: print "disabled cache.." only if verbose is used.
-
-Thu Nov 19 07:17:31 1998 Werner Koch <[email protected]>
-
- * parse-packet.c (dump_sig_subpkt): Fixed expire listing
- * getkey.c (merge_keys_and_selfsig): Fixed expire calculation.
- (merge_one_pk_and_selfsig): Ditto.
- * keyedit.c (menu_expire). Ditto.
- * keygen.c (keygen_add_key_expire): Ditto.
- (ask_expire_interval): New and changed all local function to use
- this instead.
- (keygen_add_key_expire): Opaque should now be a public key;
- changed all callers.
-
- * parse.packet.c (parse): use skip_rest to skip packets.
-
- * keyedit.c (keyedit_menu): New arg for cmdline cmds.
-
-Wed Nov 18 20:33:50 1998 Werner Koch ([email protected])
-
- * trustdb.c (check_trustdb): Now rechecks all gived userids.
- (collect_paths): Some fixes.
- (upd_pref_records): Skips empty items, evaluate all items.
-
- * parse-packet.c (dump_sig_subpkt): Better listing of prefs.
- (skip_packet): Now knows about marker packet
-
- * g10.c: removed cmd "--edit-sig".
-
- * pubring.asc: Updated.
-
-Sat Nov 14 14:01:29 1998 Werner Koch ([email protected])
-
- * g10.c (main): Changed syntax of --list-trust-path
- * trustdb.c (list_trust_path): Replaced max_depth by
- opt.max_cert_depth
-
-Fri Nov 13 07:39:58 1998 Werner Koch <[email protected]>
-
- * trustdb.c (collect_paths): Removed a warning message.
- (enum_trust_web): Removed.
- (enum_cert_paths): New.
- * pkclist.c (add_ownertrust): Changed to use enum_cert_paths.
- (edit_ownertrust): Now list ceritficates on request.
- (show_paths): New.
-
-Wed Nov 11 18:05:44 1998 Werner Koch <[email protected]>
-
- * g10.c (main): New option --max-cert-depth
- * tdbio.h: add new fields to ver and dir record.
- * tdbio.c: read/write/dump of these fields.
- (tdbio_db_matches_options): New.
- * trustdb.c: replaced MAC_CERT_DEPTH by opt.max_cert_depth.
- (do_check): cache validity and changed other functions
- to reset the cached value.
-
- * keylist.c (list_one): Now lists the ownertrust.
- * mainproc.c (list_node): Ditto.
-
-Tue Nov 10 10:08:59 1998 Werner Koch ([email protected])
-
- * g10.c (g10_exit): Now looks at the new g10_errors_seen.
- * mainproc.c (check_sig_and_print): Sets g10_errors_seen.
-
- * *.c : i18n many more strings.
-
- * ringedit.c (locate_keyblock_by_keyid): Add HAVE_LIBGDBM
- (locate_keyblock_by_fpr): Ditto.
-
- * g10.c (main): removed unsused "int errors".
- (main): Add new option --charset.
-
- * g10.c (main): special message for the unix newbie.
-
-Mon Nov 9 07:17:42 1998 Werner Koch <[email protected]>
-
- * getkey.c (finish_lookup): Kludge to prefere algo 16.
-
- * trustdb.c (new_lid_table): Clear cached item.
-
- * status.c (cpr_get_utf8): New.
- * pkclist.c (build_pk_list): Uses this.
-
-Sun Nov 8 17:20:39 1998 Werner Koch ([email protected])
-
- * mainproc.c (check_sig_and_print): Why did I use strlen()-1
- in the printf? - This truncated the TZ.
-
-Sat Nov 7 15:57:28 1998 me,,, (wk@tobold)
-
- * getkey.c (lookup): Changes to support a read_next.
- (get_pubkey): Fixed a memory leak.
-
- * keylist.c (list_one): Now lists all matching user IDs.
-
-Tue Nov 3 16:19:21 1998 Werner Koch ([email protected])
-
- * keygen.c (ask_user_id): Now converted to UTF-8
-
- * g10.c (main): Kludge for pgp clearsigs and textmode.
-
-Fri Oct 30 16:40:39 1998 me,,, (wk@tobold)
-
- * signal.c (block_all_signals): New.
- (unblock_all_signals): New
- * tdbio.c (tdbio_end_transaction): Now blocks all signals.
-
- * trustdb.c (new_lid_table): Changed the representation of the
- former local_lid_info stuff.
-
- * trustdb.c (update_trust_record): Reorganized the whole thing.
- * sig-check.c (check_key_signature): Now handles class 0x28
-
-
-Wed Oct 28 18:56:33 1998 me,,, (wk@tobold)
-
- * export.c (do_export): Takes care of the exportable sig flag.
-
-Tue Oct 27 14:53:04 1998 Werner Koch ([email protected])
-
- * trustdb.c (update_trust_record): New "fast" parameter.
-
-Sun Oct 25 19:32:05 1998 Werner Koch ([email protected])
-
- * openfile.c (copy_options_File): New.
- * ringedit.c (add_keyblock_resource): Creates options file
- * tdbio.c (tdbio_set_dbname): Ditto.
-
-Sat Oct 24 14:10:53 1998 brian moore <[email protected]>
-
- * mainproc.c (proc_pubkey_enc): Don't release the DEK
- (do_proc_packets): Ditto.
-
-Fri Oct 23 06:49:38 1998 me,,, (wk@tobold)
-
- * keyedit.c (keyedit_menu): Comments are now allowed
-
- * trustdb.c: Rewrote large parts.
-
-
-Thu Oct 22 15:56:45 1998 Michael Roth ([email protected])
-
- * encode.c: (encode_simple): Only the plain filename without
- a given directory is stored in generated packets.
- (encode_crypt): Ditto.
-
- * sign.c: (sign_file) Ditto.
-
-
-Thu Oct 22 10:53:41 1998 Werner Koch ([email protected])
-
- * trustdb.c (update_trust_record): Add new optional arg.
-
- * import.c (import_keys): Add statistics output
- * trustdb.c (update_trustdb): Ditto.
- (insert_trustdb): Ditto.
-
- * tdbio.c (tdbio_begin_transaction): New.
- (tdbio_end_transaction): New.
- (tdbio_cancel_transaction): New.
-
- * g10.c (main): New option --quit.
-
- * trustdb.c (check_hint_sig): No tests for user-id w/o sig.
- This caused an assert while checking the sigs.
-
- * trustdb.c (upd_sig_record): Splitted into several functions.
-
- * import.c (import_keys): New arg "fast".
- * g10.c (main): New command --fast-import.
-
-Wed Oct 21 18:19:36 1998 Michael Roth <[email protected]>
-
- * ringedit.c (add_keyblock_resource): Directory is now created.
- * tdbio.c (tdbio_set_dbname): New info message.
-
-Wed Oct 21 11:52:04 1998 Werner Koch ([email protected])
-
- * trustdb.c (update_trustdb): released keyblock in loop.
-
- * keylist.c (list_block): New.
- (list_all): Changed to use list_block.
-
- * trustdb.c: Completed support for GDBM
-
- * sign.c (only_old_style): Changed the way force_v3 is handled
- (sign_file): Ditto.
- (clearsign_file): Ditto.
-
- * keygen.c (has_invalid_email_chars): Splitted into mailbox and
- host part.
-
- * keylist.c (list_one): Add a merge_keys_and_selfsig.
- * mainproc.c (proc_tree): Ditto.
-
-Sun Oct 18 11:49:03 1998 Werner Koch ([email protected])
-
- * sign.c (only_old_style): Add option force_v3_sigs
- (sign_file): Fixed a bug in sig->version
- (clearsign_file): Ditto.
-
- * parse-packet.c (dump_sig_subpkt): New
-
- * keyedit.c (menu_expire): New.
- * free-packet.c (cmp_signatures): New
-
-
-Sat Oct 17 10:22:39 1998 Werner Koch ([email protected])
-
- * armor.c: changed output line length from 72 to 64.
-
- * keyedit.c (fix_keyblock): New.
-
-Fri Oct 16 10:24:47 1998 Werner Koch ([email protected])
-
- * trustdb.c: Rewrote most.
- * tdbio.c: Add cache and generalized hash tables.
-
- * options.h (ENABLE_COMMENT_PACKETS): New but undef'ed.
- * encode.c, sign.c, keygen.c: Disabled comment packets.
- * export.c (do_export): Comment packets are never exported,
- except for those in the secret keyring.
-
- * g10.c (main): Removed option do-no-export-rsa; should be
- be replaced by a secpial tool.
- * export.c (do_export): Removed the code for the above option.
-
- * armor.c (find_header): Support for new only_keyblocks.
- * import.c (import_keys): Only looks for keyblock armors.
-
- * packet.h: replaced valid_days by expiredate and changed all users.
- * build-packet.c (do_public_key): calculates valid-days
- (do_secret_key): Ditto.
- * parse-packet.c (parse_key): expiredate is calucated from the
- valid_period in v3 packets.
- * keyid.c (do_fingerprint_md): calculates valid_dates.
-
- * keygen.c (add_key_expire): fixed key expiration time for v4 packets.
-
- * armor.c (find_header): A LF in the first 28 bytes
- was skipped for non-armored data.
-
-Thu Oct 8 11:35:51 1998 Werner Koch ([email protected])
-
- * armor.c (is_armored): Add test on old comment packets.
-
- * tdbio.c (tdbio_search_dir_bypk): fixed memory leak.
-
- * getkey.c: Changed the caching algorithms.
-
-Wed Oct 7 19:33:28 1998 Werner Koch ([email protected])
-
- * kbnodes.c (unused_nodes): New.
-
-Wed Oct 7 11:15:36 1998 Werner Koch ([email protected])
-
- * keyedit.c (sign_uids): Fixed a problem with SK which could caused
- a save of an unprotected key.
- (menu_adduid): Ditto.
-
- * keyedit.c (keyedit_menu): Prefs are now correctly listed for
- new user ids.
-
- * trustdb.c (update_trust_record): New.
- (insert_trust_record): Now makes use of update_trust_record.
-
-Tue Oct 6 16:18:03 1998 Werner Koch ([email protected])
-
- * trustdb.c (read_record): replaces most of the tdbio_read_records.
- (write_record): Ditto.
-
-Sat Oct 3 11:01:21 1998 Werner Koch ([email protected])
-
- * keygen.c (ask_alogo): enable ElGamal enc-only only for addmode.
-
-Wed Sep 30 10:15:33 1998 Werner Koch ([email protected])
-
- * import.c (import_one): Fixed update of wrong keyblock.
-
-Tue Sep 29 08:32:08 1998 me,,, (wk@tobold)
-
- * mainproc.c (proc_plaintext): Display note for special filename.
- * plaintext.c (handle_plaintext): Suppress output of special file.
-
-Mon Sep 28 12:57:12 1998 Werner Koch ([email protected])
-
- * g10.c (verify_own_keys): Add warning if a key is not protected.
-
- * passphrase (hash_passphrase): Fixed iterated+salted mode and
- setup for keysizes > hashsize.
-
- * g10.c (main): New options: --s2k-{cipher,digest,mode}.
-
-Fri Sep 25 09:34:23 1998 Werner Koch ([email protected])
-
- * g10.c: Chnaged some help texts.
-
-Tue Sep 22 19:34:39 1998 Werner Koch ([email protected])
-
- * passphrase.c (read_passphrase_from_fd): fixed bug for long
- passphrases.
-
-Mon Sep 21 11:28:05 1998 Werner Koch (wk@(none))
-
- * getkey.c (lookup): Add code to use the sub key if the primary one
- does not match the usage.
-
- * armor.c (armor_filter): New error message: no valid data found.
- (radix64_read): Changes to support multiple messages.
- (i18n.h): New.
- * mainproc.c (add_onepass_sig): bug fix.
-
-Mon Sep 21 08:03:16 1998 Werner Koch ([email protected])
-
- * pkclist.c (do_we_trust): Add keyid to most messages.
-
- * passphrase.c (read_passphrase_from_fd): New.
- (have_static_passphrase): New
- (get_passphrase_fd): Removed.
- (set_passphrase_fd): Removed.
- * g10.c (main): passphrase is now read here.
-
- * keyedit.c (keyedit_menu): "help" texts should now translate fine.
-
-Mon Sep 21 06:40:02 1998 Werner Koch ([email protected])
-
- * encode.c (encode_simple): Now disables compression
- when --rfc1991 is used.
- (encode_crypt): Ditto.
-
-Fri Sep 18 16:50:32 1998 Werner Koch ([email protected])
-
- * getkey.c (merge_key_and_selfsig): New.
-
-Fri Sep 18 10:20:11 1998 Werner Koch ([email protected])
-
- * pkclist.c (select_algo_from_prefs): Removed 3DES kludge.
-
- * seskey.c (make_session_key): Fixed SERIOUS bug introduced
- by adding the weak key detection code.
-
- * sign.c (sign_file): Changed aremor header in certain cases.
-
-Tue Sep 15 17:52:55 1998 Werner Koch ([email protected])
-
- * mainproc.c (check_sig_and_print): Replaced ascime by asctimestamp.
-
-Mon Sep 14 11:40:52 1998 Werner Koch ([email protected])
-
- * seskey.c (make_session_key): Now detects weak keys.
-
- * trustdb (clear_trust_checked_flag): New.
-
- * plaintext.c (handle_plaintext): Does no anymore suppress CR from
- cleartext signed messages.
-
-Sun Sep 13 12:54:29 1998 Werner Koch ([email protected])
-
- * trustdb.c (insert_trust_record): Fixed a stupid bug in the free
- liunked list loops.
-
-Sat Sep 12 15:49:16 1998 Werner Koch ([email protected])
-
- * status.c (remove_shmid): New.
- (init_shm_comprocess): Now sets permission to the real uid.
-
-Wed Sep 9 11:15:03 1998 Werner Koch ([email protected])
-
- * packet.h (PKT_pubkey_enc): New flah throw_keyid, and add logic to
- implement it.
- * g10.c (main): New Option --throw-keyid
-
- * getkey.c (enum_secret_keys): Add new ar and changed all callers.
-
-Tue Sep 8 20:04:09 1998 Werner Koch ([email protected])
-
- * delkey.c (delete_key): Moved from keyedit.c.
-
-Mon Sep 7 16:37:52 1998 Werner Koch ([email protected])
-
- * build-packet.c (calc_length_header): New arg new_ctb to correctly
- calculate the length of new style packets.
-
- * armor.c (is_armored): Checks for symkey_enc packets.
-
- * pkclist.c (select_algo_from_prefs): 3DEs substitute is now CAST5.
-
-Tue Aug 11 17:54:50 1998 Werner Koch ([email protected])
-
- * build-packet.c (do_secret_key): Fixed handling of old keys.
-
- * getkey.c (compare_name): Fixed exact and email matching
-
- * openfile.c (open_outfile): Changed arguments and all callers.
-
-Tue Aug 11 09:14:35 1998 Werner Koch ([email protected])
-
- * encode.c (encode_simple): Applied option set-filename and comment.
- (encode_crypt): Ditto.
- * sign.c (sign_file): Ditto.
- * armor.c (armor_filter): Applied option comment.
-
- * encode.c (encode_crypt): Moved init_packet to the begin.
- (encode_simple): add an init_packet().
-
- * comment (write_comment): Now enforces a hash sign as the 1st byte.
-
- * import.c (import_one): Add explanation for "no user ids".
-
- * compress.c (do_uncompress): Applied Brian Warner's patch to support
- zlib 1.1.3 etc.
-
- * trustdb.c (check_trust): Fixed a problem after inserting new keys.
-
- * getkey (lookup): do not return the primary key if usage is given
- (lookup_sk): Ditto and take usage into account.
-
- * status.c (cpr_get_answer_is_yes): add display_help.
-
-Mon Aug 10 10:11:28 1998 Werner Koch ([email protected])
-
- * getkey.c (lookup_sk): Now always returns the primary if arg
- primary is true.
- (lookup): Likewise.
- (get_pubkey_byname): Now returns the primary key
- (get_seckey_byname): Ditto.
-
-
-Mon Aug 10 08:34:03 1998 Werner Koch ([email protected])
-
- * keyid.c (pubkey_letter): ELG_E is now a small g.
-
-Sat Aug 8 17:26:12 1998 Werner Koch ([email protected])
-
- * openfile (overwrite_filep): Changed semantics and all callers.
-
-Sat Aug 8 12:17:07 1998 Werner Koch ([email protected])
-
- * status.c (display_help): New.
-
-Thu Aug 6 16:30:41 1998 Werner Koch,mobil,,, (wk@tobold)
-
- * seskey.c (encode_session_key): Now uses get_random_bits().
-
-Thu Aug 6 07:34:56 1998 Werner Koch,mobil,,, (wk@tobold)
-
- * ringedit.c (keyring_copy): No more backupfiles for
- secret keyrings and add additional warning in case of
- a failed secret keyring operation.
-
-Wed Aug 5 11:54:37 1998 Werner Koch ([email protected])
-
- * g10.c (check_opts): Moved to main. Changed def_cipher_algo
- semantics and chnaged all users.
-
- * pubkey-enc.c (get_sssion_key): New informational output
- about preferences.
-
- * parse-packet.c (parse_symkeyenc): Fixed salted+iterated S2K
- (parse_key): Ditto.
- * build-packet.c (do_secret_key): Ditto.
- (do_symkey_enc): Ditto.
-
-Tue Aug 4 08:59:10 1998 Werner Koch ([email protected])
-
- * getkey.c (enum_secret_keys): Now returns only primary keys.
-
- * getkey (lookup): Now sets the new namehash field.
-
- * parse-packet.c (parse_sig_subpkt2): New.
-
- * sign.c (sign_file): one-pass sigs are now emiited reverse.
- Preference data is considered when selecting the compress algo.
-
-Wed Jul 29 12:53:03 1998 Werner Koch ([email protected])
-
- * free-packet.c (copy_signature): New.
-
- * keygen.c (generate_subkeypair): rewritten
- * g10.c (aKeyadd): Removed option --add-key
-
-Mon Jul 27 10:37:28 1998 Werner Koch ([email protected])
-
- * seckey-cert.c (do_check): Additional check on cipher blocksize.
- (protect_secret_key): Ditto.
- * encr-data.c: Support for other blocksizes.
- * cipher.c (write_header): Ditto.
-
-Fri Jul 24 16:47:59 1998 Werner Koch ([email protected])
-
- * kbnode.c (insert_kbnode): Changed semantics and all callers.
- * keyedit.c : More or less a complete rewrite
-
-Wed Jul 22 17:10:04 1998 Werner Koch ([email protected])
-
- * build-packet.c (write_sign_packet_header): New.
-
-Tue Jul 21 14:37:09 1998 Werner Koch ([email protected])
-
- * import.c (import_one): Now creates a trustdb record.
-
- * g10.c (main): New command --check-trustdb
-
-Mon Jul 20 11:15:07 1998 Werner Koch ([email protected])
-
- * genkey.c (generate_keypair): Default key is now DSA with
- encryption only ElGamal subkey.
-
-Thu Jul 16 10:58:33 1998 Werner Koch ([email protected])
-
- * keyid.c (keyid_from_fingerprint): New.
- * getkey.c (get_pubkey_byfprint): New.
-
-Tue Jul 14 18:09:51 1998 Werner Koch ([email protected])
-
- * keyid.c (fingerprint_from_pk): Add argument and changed all callers.
- (fingerprint_from_sk): Ditto.
-
-Tue Jul 14 10:10:03 1998 Werner Koch ([email protected])
-
- * plaintext.c (handle_plaintext): Now returns create error if
- the file could not be created or the user responded not to overwrite
- the file.
- * mainproc.c (proc_plaintext): Tries again if the file could not
- be created to check the signature without output.
-
- * misc.c (disable_core_dumps): New.
- * g10.c (main): disable coredumps for gpg
-
- * g10.c (MAINTAINER_OPTIONS): New to disable some options
-
-Mon Jul 13 16:47:54 1998 Werner Koch ([email protected])
-
- * plaintext.c (hash_datafiles): New arg for better support of
- detached sigs. Changed all callers.
- * mainproc.c (proc_signature_packets): Ditto.
-
- * g10.c (main): New option "compress-sigs"
- * sig.c (sign_file): detached signatures are not anymore compressed
- unless the option --compress-sigs is used.
-
-Thu Jul 9 19:54:54 1998 Werner Koch ([email protected])
-
- * armor.c: Fixes to allow zero length cleartext signatures
-
-Thu Jul 9 14:52:47 1998 Werner Koch ([email protected])
-
- * g10.c (build_list): Now drops setuid.
- (main): Changed the way keyrings and algorithms are registered .
-
-Wed Jul 8 14:17:30 1998 Werner Koch ([email protected])
-
- * packet.h (PKT_public_key): Add field keyid.
- * parse-packet.c (parse_key): Reset the above field.
- * keyid.c (keyid_from_pk): Use above field as cache.
-
- * tdbio.c, tdbio.h: New
- * trustdb.c: Moved some functions to tdbio.c.
- (print_keyid): New.
-
- * pkclist.c (check_signatures_trust): New.
-
-Wed Jul 8 10:45:28 1998 Werner Koch ([email protected])
-
- * plaintext.c (special_md_putc): New.
- (handle_plaintext): add clearsig argument
- * mainproc.c (proc_plaintext): detection of clearsig
- * sign.c (write_dased_escaped): Changed clearsig format
-
-Tue Jul 7 18:56:19 1998 Werner Koch ([email protected])
-
- * armor.c (find_header): Now makes sure that there is only one
- empty line for clearsigs, as this is what OP now says.
-
-Mon Jul 6 13:09:07 1998 Werner Koch ([email protected])
-
- * g10.c (main): New option default-secret-key
- * getkey.c (get_seckey_byname): support for this option.
-
-Mon Jul 6 09:03:49 1998 Werner Koch ([email protected])
-
- * getkey.c (add_keyring): Keyrings are now added to end of the
- list of keyrings. The first added keyringwill be created.
- (add_secret_keyring): Likewise.
-
- * ringedit.c (add_keyblock_resource): Files are created here.
-
- * g10.c (aNOP): Removed
-
- * getkey.c (lookup): Add checking of usage for name lookups
- * packet.h (pubkey_usage): Add a field which may be used to store
- usage capabilities.
- * pkclist.c (build_pk_list): getkey now called with usage arg.
- * skclist.c (build_sk_list): Ditto.
-
- * sign.c (clearsign_file): Fixed "Hash:" headers
-
-Sat Jul 4 13:33:31 1998 Werner Koch ([email protected])
-
- * trustdb.c (list_ownertrust): New.
- * g10.c (aListOwnerTrust): New.
-
- * g10.c (def_pubkey_algo): Removed.
-
- * trustdb.c (verify_private_data): Removed and also the call to it.
- (sign_private_data): Removed.
-
-Fri Jul 3 13:26:10 1998 Werner Koch ([email protected])
-
- * g10.c (aEditKey): was aEditSig. Changed usage msg.
-
- * keyedit.c: Done some i18n stuff.
-
- * g10.c (do_not_use_RSA): New.
- * sign.c (do_sign): Add call to above function.
- * encode.c (write_pubkey_enc_from_list): Ditto.
-
-Thu Jul 2 21:01:25 1998 Werner Koch ([email protected])
-
- * parse-packet.c: Now is able sto store data of unknown
- algorithms.
- * free-packet.c: Support for this.
- * build-packet.c: Can write data of packet with unknown algos.
-
-Thu Jul 2 11:46:36 1998 Werner Koch ([email protected])
-
- * parse-packet.c (parse): fixed 4 byte length header
-
-Wed Jul 1 12:36:55 1998 Werner Koch ([email protected])
-
- * packet.h (new_ctb): New field for some packets
- * build-packet.c (build_packet): Support for new_ctb
- * parse-packet.c (parse): Ditto.
-
-Mon Jun 29 12:54:45 1998 Werner Koch ([email protected])
-
- * packet.h: changed all "_cert" to "_key", "subcert" to "subkey".
-
- * free-packet.c (free_packet): Removed memory leak for subkeys.
-
-Sun Jun 28 18:32:27 1998 Werner Koch ([email protected])
-
- * import.c (import_keys): Renamed from import_pubkeys.
- (import_secret_one): New.
-
- * g10.c (aExportSecret): New.
-
- * export.c (export_seckeys): New.
-
- * parse-packet.c (parse_certificate): Cleaned up.
- (parse_packet): Trust packets are now considered as unknown.
- (parse_pubkey_warning): New.
-
-Fri Jun 26 10:37:35 1998 Werner Koch ([email protected])
-
- * keygen.c (has_invalid_email_chars): New.
-
-Wed Jun 24 16:40:22 1998 Werner Koch ([email protected])
-
- * armor.c (armor_filter): Now creates valid onepass_sig packets
- with all detected hash algorithms.
- * mainproc.c (proc_plaintext): Now uses the hash algos as specified
- in the onepass_sig packets (if there are any)
-
-Mon Jun 22 11:54:08 1998 Werner Koch ([email protected])
-
- * plaintext.c (handle_plaintext): add arg to disable outout
- * mainproc.c (proc_plaintext): disable output when in sigs_only mode.
-
-Thu Jun 18 13:17:27 1998 Werner Koch ([email protected])
-
- * keygen.c: Removed all rsa packet stuff, chnaged defaults
- for key generation.
-
-Sun Jun 14 21:28:31 1998 Werner Koch ([email protected])
-
- * misc.c (checksum_u16): Fixed a stupid bug which caused a
- wrong checksum calculation for the secret key protection and
- add a backward compatibility option.
- * g10.c (main): Add option --emulate-checksum-bug.
-
-Thu Jun 11 13:26:44 1998 Werner Koch ([email protected])
-
- * packet.h: Major changes to the structure of public key material
- which is now stored in an array and not anaymore in a union of
- algorithm specific structures. These is needed to make the system
- more extendable and makes a lot of stuff much simpler. Changed
- all over the system.
-
- * dsa.c, rsa.c, elg.c: Removed.
-
-Wed Jun 10 07:22:02 1998 Werner Koch,mobil,,, (wk@tobold)
-
- * g10.c ("load-extension"): New option.
-
-Mon Jun 8 22:23:37 1998 Werner Koch ([email protected])
-
- * seckey-cert.c (do_check): Removed cipher constants
- (protect_secret_key): Ditto.
-
-Fri May 29 10:00:28 1998 Werner Koch ([email protected])
-
- * trustdb.c (query_trust_info): New.
- * keylist.c (list_one): Add output of trust info
- * mainproc (list_node): ditto.
- * g10.c (main): full trustdb init if -with-colons and any of the
- key list modes.
-
-Thu May 28 10:34:42 1998 Werner Koch ([email protected])
-
- * status.c (STATUS_RSA_OR_IDEA): New.
- * sig-check.c (check_signature): Output special status message.
- * pubkey-enc.c (get_session_key): Ditto.
-
- * mainproc.c (check_sig_and_print): Changed format of output.
- * passpharse.c (passphrase_to_dek): Likewise.
-
-Wed May 27 13:46:48 1998 Werner Koch ([email protected])
-
- * g10.c (aListSecretKeys): New option --list-secret-keys
- * keylist.c (std_key_list): Renamed to public_key_list.
- (secret_key_list): New
- (list_one, list_all): Add support for secret keys.
- * getkey.c (get_secret_keyring): New.
- * mainproc.c (list_node): Add option --with-colons for secret keys
-
- * sig-check.c (check_key_signature): detection of selfsigs
- * mainproc.c (list_node): fixed listing.
-
- * g10.c (aListSecretKeys): New option --always-trust
- * pkclist.c (do_we_trust): Override per option added
-
- * status.c (write_status_text): Add a prefix to every output line.
-
-Wed May 27 07:49:21 1998 Werner Koch ([email protected])
-
- * g10 (--compress-keys): New.
- * options.h (compress_keys): New.
- * export.c (export_pubkeys): Only compresses with the new option.
-
-Tue May 26 11:24:33 1998 Werner Koch ([email protected])
-
- * passphrase.c (get_last_passphrase): New
- (set_next_passphrase): New.
- (passphrase_to_dek): add support for the above functions.
- * keyedit.c (make_keysig_packet): Add sigclass 0x18,
- changed all callers due to a new argument.
- * keygen.c (write_keybinding): New
- (generate_subkeypair): Add functionality
- (ask_algo, ask_keysize, ask_valid_days): Broke out of generate_keypair
- (ask_user_id, ask_passphrase): Ditto.
-
-Thu May 21 11:26:13 1998 Werner Koch ([email protected])
-
- * g10.c,gpgd.c (main): Does now return an int, so that egcs does
- not complain.
-
- * armor.c (fake_packet): Removed erro message and add a noticed
- that this part should be fixed.
-
- * sign.c (sign_file): Compression now comes in front of encryption.
- * encode.c (encode_simple): Ditto.
- (encode_crypt): Ditto.
-
-Tue May 19 16:18:19 1998 Werner Koch ([email protected])
-
- * armor.c (fake_packet): Changed assertion to log_error
-
-Sat May 16 16:02:06 1998 Werner Koch ([email protected])
-
- * build-packet.c (build_packet): Add SUBKEY packets.
-
-Fri May 15 17:57:23 1998 Werner Koch ([email protected])
-
- * sign.c (hash_for): New and used in all places here.
- * main.h (DEFAULT_): new macros.
- * g10.c (opt.def_digest_algo): Now set to 0
-
- * compress.c (init_compress): Add support for algo 1
- * options.h (def_compress_algo): New
- * g10.c (main): New option --compress-algo
-
-Fri May 15 13:23:59 1998 Werner Koch ([email protected])
-
- * g10.c (print_mds): New feature to print only one hash,
- chnaged formatting.
-
-Thu May 14 15:36:24 1998 Werner Koch ([email protected])
-
- * misc.c (trap_unaligned) [__alpha__]: New
- * g10.c (trap_unaligned): Add call to this to track down SIGBUS
- on Alphas (to avoid the slow emulation code).
-
-Wed May 13 11:48:27 1998 Werner Koch ([email protected])
-
- * build-packet.c (do_signature): Support for v4 pakets.
- * keyedit.c (make_keysig_packet): Ditto.
- * build-packet.c (build_sig_subpkt_from_sig): New.
- (build_sig_subpkt): New.
-
- * elg.c (g10_elg_sign): removed keyid_from_skc.
- * dsa.c (g10_dsa_sign): Ditto.
- * rsa.c (g10_rsa_sign): Ditto.
- * keyedit.c (make_keysig_packet): Add call to keyid_from_skc
-
- * sign.c (clearsign_file): Support for v4 signatures.
- (sign_file): Ditto.
-
-Wed May 6 09:31:24 1998 Werner Koch ([email protected])
-
- * parse-packet.c (do_parse): add support for 5 byte length leader.
- (parse_subpkt): Ditto.
- * build-packet.c (write_new_header): Ditto.
-
- * packet.h (SIGSUBPKT_): New constants.
- * parse-packet.c (parse_sig_subpkt): Changed name, made global,
- and arg to return packet length, chnaged all callers
-
-
-Tue May 5 22:11:59 1998 Werner Koch ([email protected])
-
- * keygen.c (gen_dsa): New.
- * build_packet.c (do_secret_cert): Support for DSA
-
-Mon May 4 19:01:25 1998 Werner Koch ([email protected])
-
- * compress.c: doubled buffer sizes
- * parse-packet.c (do_plaintext): now uses iobuf_read/write.
-
-Mon May 4 09:35:53 1998 Werner Koch ([email protected])
-
- * seskey.c (encode_md_value): Add optional argument hash_algo,
- changed all callers.
-
- * passphrase.c (make_dek_from_passphrase): Removed
- * (get_passhrase_hash): Changed name to passphrase_to_dek, add arg,
- changed all callers.
-
- * all: Introduced the new ELG identifier and added support for the
- encryption only one (which is okay to use by GNUPG for signatures).
-
-Sun May 3 17:50:26 1998 Werner Koch ([email protected])
-
- * packet.h (PKT_OLD_COMMENT): New name for type 16.
- * parse-packet.c (parse_comment): Now uses type 61
-
-Fri May 1 12:44:39 1998 Werner Koch,mobil,,, (wk@tobold)
-
- * packet.h (count): Chnaged s2k count from byte to u32.
- * seckey-cert.c (do_check): Changed s2k algo 3 to 4, changed
- reading of count.
- * build-packet.c (do_secret_cert): ditto.
- * parse-packet.c (parse_certificate): ditto.
-
- * parse-packet.c (parse_symkeyenc): New.
- * build-packet.c (do_symkey_enc): New.
-
-Thu Apr 30 16:33:34 1998 Werner Koch ([email protected])
-
- * sign.c (clearsign_file): Fixed "Hash: " armor line.
-
-Tue Apr 28 14:27:42 1998 Werner Koch ([email protected])
-
- * parse-packet.c (parse_subpkt): Some new types.
-
-Mon Apr 27 12:53:59 1998 Werner Koch ([email protected])
-
- * g10.c (main): Add option --skip-verify.
- * mainproc.c (check_sig_and_print): Ditto.
-
- * g10.c (print_mds): Add output for Tiger.
-
- * sign.c (sign_file): Now uses partial length headers if used
- in canonical textmode (kludge to fix a bug).
-
- * parse-packet.c (parse_certificate): Changed BLOWFISH id.
- * pubkey-enc.c (get_session_key): Ditto.
- * seskey.c (make_session_key): Ditto.
- * seckey-cert.c (protect_secret_key,do_check): Add BLOWFISH160.
-
-Fri Apr 24 17:38:48 1998 Werner Koch,mobil,,, (wk@tobold)
-
- * sig-check.c (check_key_signature): Add sig-class 0x14..0x17
- * keyedit.c (sign-key): Some changes to start with support of
- the above new sig-classes.
-
-Wed Apr 22 09:01:57 1998 Werner Koch,mobil,,, (wk@tobold)
-
- * getkey.c (compare_name): add email matching
-
-Tue Apr 21 16:17:12 1998 Werner Koch,mobil,,, (wk@tobold)
-
- * armor.c (armor_filter): fixed missing last LF before CSUM.
-
-Thu Apr 9 11:35:22 1998 Werner Koch ([email protected])
-
- * seckey-cert.c (do_check): New; combines all the check functions
- into one.
-
- * sign.c: removed all key management functions
- * keyedit.c: New.
-
-Thu Apr 9 09:49:36 1998 Werner Koch ([email protected])
-
- * import.c (chk_self_sigs): Changed an error message.
-
-Wed Apr 8 16:19:39 1998 Werner Koch ([email protected])
-
- * packet.h: packet structs now uses structs from the pubkey,
- removed all copy operations from packet to pubkey structs.
-
-Wed Apr 8 13:40:33 1998 Werner Koch ([email protected])
-
- * trustdb.c (verify_own_certs): Fixed "public key not found".
-
- * getkey.c (key_byname): New, combines public and secret key search.
-
- * pkclist.c (build_pkc_list): Add new arg usage, changed all callers.
- * skclist.c (build_skc_list): Likewise.
-
- * ringedit.c (find_keyblock, keyring_search2): Removed.
-
-Wed Apr 8 09:47:21 1998 Werner Koch ([email protected])
-
- * sig-check.c (do_check): Applied small fix from Ulf M�ller.
-
-Tue Apr 7 19:28:07 1998 Werner Koch ([email protected])
-
- * cipher.c, encr-data.c, seckey-cert.c: Now uses cipher_xxxx
- functions instead of blowfish_xxx or cast_xxx
-
-Tue Apr 7 11:04:02 1998 Werner Koch ([email protected])
-
- * Makefile.am (g10maint.o): Changed the way it is created.
-
-Mon Apr 6 11:17:08 1998 Werner Koch ([email protected])
-
- * misc.c: New.
- * keygen.c (checksum,checksum_u16,checksum_mpi): Moved to misc.c
- * seckey-cert.c: Kludge for wrong ELG checksum implementation.
-
-Sat Apr 4 20:07:01 1998 Werner Koch ([email protected])
-
- * cipher.c (cipher_filter): Support for CAST5
- * encr-data.c (decode_filter): Ditto.
- (decrypt_data): Ditto.
- * seskey.c (make_session_key): Ditto.
- * seckey-cert.c (check_elg, check_dsa): Ditto,
- (protect_secret_key): Ditto.
- * pubkey-enc.c (get_session_key): Ditto.
- * passphrase.c (hash_passphrase): Ditto.
-
-Thu Apr 2 20:22:35 1998 Werner Koch ([email protected])
-
- * gpgd.c: New
-
-Thu Apr 2 10:38:16 1998 Werner Koch ([email protected])
-
- * keygen.c (generate_keypair): Add valid_days stuff.
- * trustdb.c (check_trust): Add check for valid_days.
-
-Wed Apr 1 16:15:58 1998 Werner Koch ([email protected])
-
- * keygen.c (generate_keypair): Addional question whether the
- selected large keysize is really needed.
-
-Wed Apr 1 15:56:33 1998 Werner Koch ([email protected])
-
- * seckey-cert.c (protect_secret_key): merged protect_xxx to here.
-
-Wed Apr 1 10:34:46 1998 Werner Koch ([email protected])
-
- * Makefile.am (g10maint.c): Changed creation rule, so that it works
- on FreeBSD (missing CFLAGS).
-
- * parse-packet.c (parse_subkey): Removed.
-
-Thu Mar 19 15:22:36 1998 Werner Koch ([email protected])
-
- * ringedit.c (keyring_enum): Fixed problem with reading too
- many packets. Add support to read secret keyrings.
-
- * getkey.c (scan_keyring): Removed
- (lookup): New to replace scan_keyring.
- (scan_secret_keyring): Removed.
- (lookup_skc): New.
-
-Wed Mar 18 11:47:34 1998 Werner Koch ([email protected])
-
- * ringedit.c (enum_keyblocks): New read mode 11.
-
- * keyid.c (elg_fingerprint_md): New and changed all other functions
- to call this if the packet version is 4 or above.
-
-Tue Mar 17 20:46:16 1998 Werner Koch ([email protected])
-
- * parse-packet.c (parse_certificate): Add listing support for subkeys.
-
-Tue Mar 17 20:32:22 1998 Werner Koch ([email protected])
-
- * armor.c (is_armored): Allow marker packet.
-
-Thu Mar 12 13:36:49 1998 Werner Koch ([email protected])
-
- * trustdb.c (check_trust): Checks timestamp of pubkey.
- * sig-check. (do_check): Compares timestamps.
-
-Tue Mar 10 17:01:56 1998 Werner Koch ([email protected])
-
- * g10.c (main): Add call to init_signals.
- * signal.c: New.
-
-Mon Mar 9 12:43:42 1998 Werner Koch ([email protected])
-
- * dsa.c: New
- * packet.h, free-packet.c, parse-packet.c : Add support for DSA
- * sig-check.c, getkey.c, keyid.c, ringedit.c: Ditto.
- * seckey-cert.c: Ditto.
-
- * packet.h : Moved .digest_algo of signature packets to outer
- structure. Changed all references
-
-Sun Mar 8 13:06:42 1998 Werner Koch ([email protected])
-
- * openfile.c : Support for stdout filename "-".
-
- * mainproc.c (check_sig_and_print): Enhanced status output:
- * status.c (write_status_text): New.
-
-Fri Mar 6 16:10:54 1998 Werner Koch ([email protected])
-
- * kbnode.c (clone_kbnode): Fixed private_flag.
-
- * mainproc.c (list_node): Output of string "Revoked" as user-id.
-
-Fri Mar 6 14:26:39 1998 Werner Koch ([email protected])
-
- * g10.c (main): Add userids to "-kv" and cleaned up this stuff.
-
-Fri Mar 6 12:45:58 1998 Werner Koch ([email protected])
-
- * g10.c (main): Changed semantics of the list-... commands
- and added a new one. Removed option "-d"
-
- * decrypt.c: New.
-
- * trustdb.c (init_trustdb): Autocreate directory only if it ends
- in "/.gnupg".
-
-Thu Mar 5 12:12:11 1998 Werner Koch ([email protected])
-
- * mainproc.c (do_proc_packets): New. Common part of proc_packet.
- (proc_signature_packets): special version to handle signature data.
- * verify.c: New.
- * g10.c (aVerify): New.
- * plaintext.c (hash_datafiles): New.
- * compress.c (handle_compressed): Add callback arg, changed caller.
-
-Thu Mar 5 10:20:06 1998 Werner Koch ([email protected])
-
- * g10.c: Is nom the common source for gpg and gpgm
- * g10maint.c: Removed
- * Makefile.am: Add rule to build g10maint.c
-
-Thu Mar 5 08:43:59 1998 Werner Koch ([email protected])
-
- * g10.c (main): Changed the way clear text sigs are faked.
-
-Wed Mar 4 19:47:37 1998 Werner Koch ([email protected])
-
- * g10maint.c (aMuttKeyList): New
- * keylist.c: New.
-
-Wed Mar 4 17:20:33 1998 Werner Koch ([email protected])
-
- * getkey.c (get_pubkey_byname): Kludge to allow 0x prefix.
-
-Tue Mar 3 13:46:55 1998 Werner Koch ([email protected])
-
- * g10maint.c (main): New option --gen-random.
-
-Tue Mar 3 09:50:08 1998 Werner Koch ([email protected])
-
- * g10.c (aDeleteSecretKey): New.
- (aEditSig): Add option "--edit-key" as synonym for "--edit-sig".
- (aDeleteSecretKey): New.
- * getkey.c (seckey_available): New.
- * sign.c (delete_key): Enhanced to delete secret keys, changed all
- callers.
-
-Mon Mar 2 21:23:48 1998 Werner Koch ([email protected])
-
- * pkc_list.c (build_pkc_list): Add interactive input of user ID.
-
-Mon Mar 2 20:54:05 1998 Werner Koch ([email protected])
-
- * pkclist.c (do_we_trust_pre): New.
- (add_ownertrust): Add message.
- * trustdb.c (enum_trust_web): Quick fix.
-
-Mon Mar 2 13:50:53 1998 Werner Koch ([email protected])
-
- * g10.c (main): New action aDeleteKey
- * sign.c (delete_key): New.
-
-Sun Mar 1 16:38:58 1998 Werner Koch ([email protected])
-
- * trustdb.c (do_check): No returns TRUST_UNDEFINED instead of
- eof error.
-
-Fri Feb 27 18:14:03 1998 Werner Koch ([email protected])
-
- * armor.c (find_header): Removed trailing CR on headers.
-
-Fri Feb 27 18:02:48 1998 Werner Koch ([email protected])
-
- * ringedit.c (keyring_search) [MINGW32]: Open and close file here
- because rename does not work on open files. Chnaged callers.
-
-Fri Feb 27 16:43:11 1998 Werner Koch ([email protected])
-
- * sig-check.c (do_check): Add an md_enable.
- * mainproc.c (do_check_sig): Use md_open in case of detached sig
- (proc_tree): Take detached sigs into account.
-
-Fri Feb 27 15:22:46 1998 Werner Koch ([email protected])
-
- * g10.c (main): Make use of GNUPGHOME envvar.
- * g10main.c (main): Ditto.
-
-Wed Feb 25 11:40:04 1998 Werner Koch ([email protected])
-
- * plaintext.c (ask_for_detached_datafile): add opt.verbose to
- info output.
-
- * openfile.c (open_sigfile): Try also name ending in ".asc"
-
-Wed Feb 25 08:41:00 1998 Werner Koch ([email protected])
-
- * keygen.c (generate_keypair): Fixed memory overflow.
-
-Tue Feb 24 15:51:55 1998 Werner Koch ([email protected])
-
- * parse-packet.c (parse_certificate): Support for S2K.
- * build-packet.c (do_secret_cert): Ditto.
- * keygen.c (gen_elg): Ditto.
- * seckey-cert.c (check_elg): Ditto
- (protect_elg): Ditto.
- * sign.c (chnage_passphrase): Ditto.
- * passphrase.c (get_passphrase_hash): Support for a salt and
- changed all callers.
- (make_dek_from_passphrase): Ditto.
-
-Tue Feb 24 12:30:56 1998 Werner Koch ([email protected])
-
- * build-packet.c (hash_public_cert): Disabled debug output.
-
-Fri Feb 20 17:22:28 1998 Werner Koch ([email protected])
-
- * trustdb.c (init_trustdb) [MINGW32]: Removed 2nd mkdir arg.
- (keyring_copy) [MINGW32]: Add a remove prior to the renames.
-
-Wed Feb 18 18:39:02 1998 Werner Koch ([email protected])
-
- * Makefile.am (OMIT_DEPENDENCIES): New.
-
- * rsa.c: Replaced log_bug by BUG.
-
-Wed Feb 18 13:35:58 1998 Werner Koch ([email protected])
-
- * mainproc.c (do_check_sig): Now uses hash_public_cert.
- * parse-packet.c (parse_certificate): Removed hashing.
- * packet.h (public_cert): Removed hash variable.
- * free-packet.c (copy_public_cert, free_public_cert): Likewise.
-
- * sig-check.c (check_key_signatures): Changed semantics.
-
-Wed Feb 18 12:11:28 1998 Werner Koch ([email protected])
-
- * trustdb.c (do_check): Add handling for revocation certificates.
- (build_sigrecs): Ditto.
- (check_sigs): Ditto.
-
-Wed Feb 18 09:31:04 1998 Werner Koch ([email protected])
-
- * armor.c (armor_filter): Add afx->hdrlines.
- * revoke.c (gen_revoke): Add comment line.
- * dearmor.c (enarmor_file): Ditto.
-
- * sig-check.c (check_key_signature): Add handling for class 0x20.
- * mainproc.c : Ditto.
-
-Tue Feb 17 21:24:17 1998 Werner Koch ([email protected])
-
- * armor.c : Add header lines "...ARMORED FILE .."
- * dearmor.c (enarmor_file): New.
- * g10maint.c (main): New option "--enarmor"
-
-Tue Feb 17 19:03:33 1998 Werner Koch ([email protected])
-
- * mainproc.c : Changed a lot, because the packets are now stored
- a simple linlked list and not anymore in a complicatd tree structure.
-
-Tue Feb 17 10:14:48 1998 Werner Koch ([email protected])
-
- * free_packet.c (cmp_public_certs): New.
- (cmp_user_ids): New.
-
- * kbnode.c (clone_kbnode): New.
- (release_kbnode): Add clone support.
-
- * ringedit.c (find_keyblock_bypkc): New.
-
- * sign.c (remove_keysigs): Self signatures are now skipped,
- changed arguments and all callers.
-
- * import.c : Add functionality.
-
-Tue Feb 17 09:31:40 1998 Werner Koch ([email protected])
-
- * options.h (homedir): New option.
- * g10.c, g10maint.c, getkey.c, keygen.c, trustdb.c (opt.homedir): New.
-
- * trustdb.c (init_trustdb): mkdir for hoem directory
- (sign_private_data): Renamed "sig" to "g10.sig"
-
-Mon Feb 16 20:02:03 1998 Werner Koch ([email protected])
-
- * kbnode.c (commit_kbnode): New.
- (delete_kbnode): removed unused first arg. Changed all Callers.
-
- * ringedit.c (keyblock_resource_name): New.
- (get_keyblock_handle): NULL for filename returns default resource.
-
-Mon Feb 16 19:38:48 1998 Werner Koch ([email protected])
-
- * sig-check.s (check_key_signature): Now uses the supplied
- public key to check the signature and not any more the one
- from the getkey.c
- (do_check): New.
- (check_signature): Most work moved to do_check.
-
-Mon Feb 16 14:48:57 1998 Werner Koch ([email protected])
-
- * armor.c (find_header): Fixed another bug.
-
-Mon Feb 16 12:18:34 1998 Werner Koch ([email protected])
-
- * getkey.c (scan_keyring): Add handling of compressed keyrings.
-
-Mon Feb 16 10:44:51 1998 Werner Koch ([email protected])
-
- * g10.c, g10maint.c (strusage): Rewrote.
- (build_list): New
-
-Mon Feb 16 08:58:41 1998 Werner Koch ([email protected])
-
- * armor.c (use_armor): New.
-
-Sat Feb 14 14:30:57 1998 Werner Koch ([email protected])
-
- * mainproc.c (proc_tree): Sigclass fix.
-
-Sat Feb 14 14:16:33 1998 Werner Koch ([email protected])
-
- * armor.c (armor_filter): Changed version and comment string.
- * encode.c, sign.c, keygen.c: Changed all comment packet strings.
-
-Sat Feb 14 12:39:24 1998 Werner Koch ([email protected])
-
- * g10.c (aGenRevoke): New command.
- * revoke.c: New.
- * sign.c (make_keysig_packet): Add support for sigclass 0x20.
-
-Fri Feb 13 20:18:14 1998 Werner Koch ([email protected])
-
- * ringedit.c (enum_keyblocks, keyring_enum): New.
-
-Fri Feb 13 19:33:40 1998 Werner Koch ([email protected])
-
- * export.c: Add functionality.
-
- * keygen.c (generate_keypair): Moved the leading comment behind the
- key packet.
- * kbnode.c (walk_kbnode): Fixed.
-
- * g10.c (main): listing armored keys now work.
-
-Fri Feb 13 16:17:43 1998 Werner Koch ([email protected])
-
- * parse-packet.c (parse_publickey, parse_signature): Fixed calls
- to mpi_read used for ELG b.
-
-Fri Feb 13 15:13:23 1998 Werner Koch ([email protected])
-
- * g10.c (main): changed formatting of help output.
-
-Thu Feb 12 22:24:42 1998 Werner Koch (wk@frodo)
-
- * pubkey-enc.c (get_session_key): rewritten
-
-
- Copyright 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
-
- This file is free software; as a special exception the author gives
- unlimited permission to copy and/or distribute it, with or without
- modifications, as long as this notice is preserved.
-
- This file is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/g10/Makefile.am b/g10/Makefile.am
deleted file mode 100644
index fc33acf73..000000000
--- a/g10/Makefile.am
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright (C) 1998, 1999, 2000, 2001, 2002,
-# 2003 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 2 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-## Process this file with automake to produce Makefile.in
-
-EXTRA_DIST = options.skel
-
-AM_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/include \
- -I$(top_srcdir)/intl
-
-include $(top_srcdir)/am/cmacros.am
-
-AM_CFLAGS = $(LIBGCRYPT_CFLAGS)
-
-needed_libs = ../common/libcommon.a ../jnlib/libjnlib.a
-
-bin_PROGRAMS = gpg2 gpgv2
-
-common_source = \
- global.h gpg.h \
- build-packet.c \
- compress.c \
- filter.h \
- free-packet.c \
- getkey.c \
- keydb.c keydb.h \
- keyring.c keyring.h \
- seskey.c \
- kbnode.c \
- main.h \
- mainproc.c \
- armor.c \
- mdfilter.c \
- textfilter.c \
- progress.c \
- misc.c \
- options.h \
- openfile.c \
- keyid.c \
- packet.h \
- parse-packet.c \
- comment.c \
- status.c \
- status.h \
- plaintext.c \
- sig-check.c \
- keylist.c \
- pkglue.c pkglue.h
-
-gpg2_SOURCES = g10.c \
- $(common_source) \
- pkclist.c \
- skclist.c \
- pubkey-enc.c \
- passphrase.c \
- seckey-cert.c \
- encr-data.c \
- cipher.c \
- encode.c \
- sign.c \
- verify.c \
- revoke.c \
- decrypt.c \
- keyedit.c \
- dearmor.c \
- import.c \
- export.c \
- trustdb.c \
- trustdb.h \
- tdbdump.c \
- tdbio.c \
- tdbio.h \
- delkey.c \
- keygen.c \
- pipemode.c \
- helptext.c \
- keyserver.c \
- keyserver-internal.h \
- photoid.c photoid.h \
- call-agent.c call-agent.h \
- card-util.c \
- exec.c exec.h
-
-gpgv2_SOURCES = gpgv.c \
- $(common_source) \
- verify.c
-
-#gpgd_SOURCES = gpgd.c \
-# ks-proto.h \
-# ks-proto.c \
-# ks-db.c \
-# ks-db.h \
-# $(common_source)
-
-LDADD = $(needed_libs) @INTLLIBS@ @CAPLIBS@ @ZLIBS@ @W32LIBS@
-gpg2_LDADD = $(LIBGCRYPT_LIBS) $(LDADD) -lassuan -lgpg-error
-gpgv2_LDADD = $(LIBGCRYPT_LIBS) $(LDADD) -lassuan -lgpg-error
-
-$(PROGRAMS): $(needed_libs)
-
-install-data-local:
- $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
- $(INSTALL_DATA) $(srcdir)/options.skel \
- $(DESTDIR)$(pkgdatadir)/options.skel
-
diff --git a/g10/OPTIONS b/g10/OPTIONS
deleted file mode 100644
index b1a49e254..000000000
--- a/g10/OPTIONS
+++ /dev/null
@@ -1,24 +0,0 @@
-# Some notes used by the maintainers
-
-
-store
-# simply packs the input data into a rfc1991 packet format
-
-check-trustdb
-
-
-compress-keys
-# compress exported key, compress level is still set with "-z" and
-# algorithm with --compress-algo" - Default is to not compress keys, as
-# this is better for interoperability.
-
-compress-sigs
-# Normally, compressing of signatures does not make sense; so this
-# is disabled for detached signatures unless this option is used.
-
-run-as-shm-coprocess [request-locked-shm-size]
-# very special :-)
-# You will have to use "--status-fd" too
-# Note: This option does only work if given on the command line.
-
-
diff --git a/g10/armor.c b/g10/armor.c
deleted file mode 100644
index 121ec3a09..000000000
--- a/g10/armor.c
+++ /dev/null
@@ -1,1334 +0,0 @@
-/* armor.c - Armor flter
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
- * 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <ctype.h>
-
-#include "gpg.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "memory.h"
-#include "util.h"
-#include "filter.h"
-#include "packet.h"
-#include "options.h"
-#include "main.h"
-#include "status.h"
-#include "i18n.h"
-
-#ifdef HAVE_DOSISH_SYSTEM
-#define LF "\r\n"
-#else
-#define LF "\n"
-#endif
-
-#define MAX_LINELEN 20000
-
-#define CRCINIT 0xB704CE
-#define CRCPOLY 0X864CFB
-#define CRCUPDATE(a,c) do { \
- a = ((a) << 8) ^ crc_table[((a)&0xff >> 16) ^ (c)]; \
- a &= 0x00ffffff; \
- } while(0)
-static u32 crc_table[256];
-static byte bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789+/";
-static byte asctobin[256]; /* runtime initialized */
-static int is_initialized;
-
-
-typedef enum {
- fhdrHASArmor = 0,
- fhdrNOArmor,
- fhdrINIT,
- fhdrINITCont,
- fhdrINITSkip,
- fhdrCHECKBegin,
- fhdrWAITHeader,
- fhdrWAITClearsig,
- fhdrSKIPHeader,
- fhdrCLEARSIG,
- fhdrREADClearsig,
- fhdrNullClearsig,
- fhdrEMPTYClearsig,
- fhdrCHECKClearsig,
- fhdrCHECKClearsig2,
- fhdrCHECKDashEscaped,
- fhdrCHECKDashEscaped2,
- fhdrCHECKDashEscaped3,
- fhdrREADClearsigNext,
- fhdrENDClearsig,
- fhdrENDClearsigHelp,
- fhdrTESTSpaces,
- fhdrCLEARSIGSimple,
- fhdrCLEARSIGSimpleNext,
- fhdrTEXT,
- fhdrTEXTSimple,
- fhdrERROR,
- fhdrERRORShow,
- fhdrEOF
-} fhdr_state_t;
-
-
-/* if we encounter this armor string with this index, go
- * into a mode which fakes packets and wait for the next armor */
-#define BEGIN_SIGNATURE 2
-#define BEGIN_SIGNED_MSG_IDX 3
-static char *head_strings[] = {
- "BEGIN PGP MESSAGE",
- "BEGIN PGP PUBLIC KEY BLOCK",
- "BEGIN PGP SIGNATURE",
- "BEGIN PGP SIGNED MESSAGE",
- "BEGIN PGP ARMORED FILE", /* gnupg extension */
- "BEGIN PGP PRIVATE KEY BLOCK",
- "BEGIN PGP SECRET KEY BLOCK", /* only used by pgp2 */
- NULL
-};
-static char *tail_strings[] = {
- "END PGP MESSAGE",
- "END PGP PUBLIC KEY BLOCK",
- "END PGP SIGNATURE",
- "END dummy",
- "END PGP ARMORED FILE",
- "END PGP PRIVATE KEY BLOCK",
- "END PGP SECRET KEY BLOCK",
- NULL
-};
-
-
-
-static void
-initialize(void)
-{
- int i, j;
- u32 t;
- byte *s;
-
- /* init the crc lookup table */
- crc_table[0] = 0;
- for(i=j=0; j < 128; j++ ) {
- t = crc_table[j];
- if( t & 0x00800000 ) {
- t <<= 1;
- crc_table[i++] = t ^ CRCPOLY;
- crc_table[i++] = t;
- }
- else {
- t <<= 1;
- crc_table[i++] = t;
- crc_table[i++] = t ^ CRCPOLY;
- }
- }
- /* build the helptable for radix64 to bin conversion */
- for(i=0; i < 256; i++ )
- asctobin[i] = 255; /* used to detect invalid characters */
- for(s=bintoasc,i=0; *s; s++,i++ )
- asctobin[*s] = i;
-
- is_initialized=1;
-}
-
-/****************
- * Check whether this is an armored file or not See also
- * parse-packet.c for details on this code For unknown historic
- * reasons we use a string here but only the first byte will be used.
- * Returns: True if it seems to be armored
- */
-static int
-is_armored( const byte *buf )
-{
- int ctb, pkttype;
-
- ctb = *buf;
- if( !(ctb & 0x80) )
- return 1; /* invalid packet: assume it is armored */
- pkttype = ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf);
- switch( pkttype ) {
- case PKT_MARKER:
- case PKT_SYMKEY_ENC:
- case PKT_ONEPASS_SIG:
- case PKT_PUBLIC_KEY:
- case PKT_SECRET_KEY:
- case PKT_PUBKEY_ENC:
- case PKT_SIGNATURE:
- case PKT_COMMENT:
- case PKT_OLD_COMMENT:
- case PKT_PLAINTEXT:
- case PKT_COMPRESSED:
- case PKT_ENCRYPTED:
- return 0; /* seems to be a regular packet: not armored */
- }
-
- return 1;
-}
-
-
-/****************
- * Try to check whether the iobuf is armored
- * Returns true if this may be the case; the caller should use the
- * filter to do further processing.
- */
-int
-use_armor_filter( iobuf_t a )
-{
- byte buf[1];
- int n;
-
- /* fixme: there might be a problem with iobuf_peek */
- n = iobuf_peek(a, buf, 1 );
- if( n == -1 )
- return 0; /* EOF, doesn't matter whether armored or not */
- if( !n )
- return 1; /* can't check it: try armored */
- return is_armored(buf);
-}
-
-
-
-
-static void
-invalid_armor(void)
-{
- write_status(STATUS_BADARMOR);
- g10_exit(1); /* stop here */
-}
-
-
-/****************
- * check whether the armor header is valid on a signed message.
- * this is for security reasons: the header lines are not included in the
- * hash and by using some creative formatting rules, Mallory could fake
- * any text at the beginning of a document; assuming it is read with
- * a simple viewer. We only allow the Hash Header.
- */
-static int
-parse_hash_header( const char *line )
-{
- const char *s, *s2;
- unsigned found = 0;
-
- if( strlen(line) < 6 || strlen(line) > 60 )
- return 0; /* too short or too long */
- if( memcmp( line, "Hash:", 5 ) )
- return 0; /* invalid header */
- s = line+5;
- for(s=line+5;;s=s2) {
- for(; *s && (*s==' ' || *s == '\t'); s++ )
- ;
- if( !*s )
- break;
- for(s2=s+1; *s2 && *s2!=' ' && *s2 != '\t' && *s2 != ','; s2++ )
- ;
- if( !strncmp( s, "RIPEMD160", s2-s ) )
- found |= 1;
- else if( !strncmp( s, "SHA1", s2-s ) )
- found |= 2;
- else if( !strncmp( s, "MD5", s2-s ) )
- found |= 4;
- else if( !strncmp( s, "SHA256", s2-s ) )
- found |= 8;
- else if( !strncmp( s, "SHA384", s2-s ) )
- found |= 16;
- else if( !strncmp( s, "SHA512", s2-s ) )
- found |= 32;
- else
- return 0;
- for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
- ;
- if( *s2 && *s2 != ',' )
- return 0;
- if( *s2 )
- s2++;
- }
- return found;
-}
-
-
-
-/****************
- * Check whether this is a armor line.
- * returns: -1 if it is not a armor header or the index number of the
- * armor header.
- */
-static int
-is_armor_header( byte *line, unsigned len )
-{
- const char *s;
- byte *save_p, *p;
- int save_c;
- int i;
-
- if( len < 15 )
- return -1; /* too short */
- if( memcmp( line, "-----", 5 ) )
- return -1; /* no */
- p = strstr( line+5, "-----");
- if( !p )
- return -1;
- save_p = p;
- p += 5;
-
- /* Some mail programs on Windows seem to add spaces to the end of
- the line. This becomes strict if --openpgp is set. */
-
- if(!RFC2440)
- while(*p==' ')
- p++;
-
- if( *p == '\r' )
- p++;
- if( *p == '\n' )
- p++;
- if( *p )
- return -1; /* garbage after dashes */
- save_c = *save_p; *save_p = 0;
- p = line+5;
- for(i=0; (s=head_strings[i]); i++ )
- if( !strcmp(s, p) )
- break;
- *save_p = save_c;
- if( !s )
- return -1; /* unknown armor line */
-
- if( opt.verbose > 1 )
- log_info(_("armor: %s\n"), head_strings[i]);
- return i;
-}
-
-
-
-/****************
- * Parse a header lines
- * Return 0: Empty line (end of header lines)
- * -1: invalid header line
- * >0: Good header line
- */
-static int
-parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len )
-{
- byte *p;
- int hashes=0;
- unsigned int len2;
-
- len2 = length_sans_trailing_ws( line, len );
- if( !len2 ) {
- afx->buffer_pos = len2; /* (it is not the fine way to do it here) */
- return 0; /* WS only: same as empty line */
- }
- len = len2;
- line[len2] = 0;
-
- p = strchr( line, ':');
- if( !p || !p[1] ) {
- log_error(_("invalid armor header: "));
- print_string( stderr, line, len, 0 );
- putc('\n', stderr);
- return -1;
- }
-
- if( opt.verbose ) {
- log_info(_("armor header: "));
- print_string( stderr, line, len, 0 );
- putc('\n', stderr);
- }
-
- if( afx->in_cleartext ) {
- if( (hashes=parse_hash_header( line )) )
- afx->hashes |= hashes;
- else if( strlen(line) > 15 && !memcmp( line, "NotDashEscaped:", 15 ) )
- afx->not_dash_escaped = 1;
- else {
- log_error(_("invalid clearsig header\n"));
- return -1;
- }
- }
- return 1;
-}
-
-
-
-/* figure out whether the data is armored or not */
-static int
-check_input( armor_filter_context_t *afx, iobuf_t a )
-{
- int rc = 0;
- int i;
- byte *line;
- unsigned len;
- unsigned maxlen;
- int hdr_line = -1;
-
- /* read the first line to see whether this is armored data */
- maxlen = MAX_LINELEN;
- len = afx->buffer_len = iobuf_read_line( a, &afx->buffer,
- &afx->buffer_size, &maxlen );
- line = afx->buffer;
- if( !maxlen ) {
- /* line has been truncated: assume not armored */
- afx->inp_checked = 1;
- afx->inp_bypass = 1;
- return 0;
- }
-
- if( !len ) {
- return -1; /* eof */
- }
-
- /* (the line is always a C string but maybe longer) */
- if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
- ;
- else if( !is_armored( line ) ) {
- afx->inp_checked = 1;
- afx->inp_bypass = 1;
- return 0;
- }
-
- /* find the armor header */
- while(len) {
- i = is_armor_header( line, len );
- if( i >= 0 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) {
- hdr_line = i;
- if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
- if( afx->in_cleartext ) {
- log_error(_("nested clear text signatures\n"));
- rc = GPG_ERR_INV_ARMOR;
- }
- afx->in_cleartext = 1;
- }
- break;
- }
- /* read the next line (skip all truncated lines) */
- do {
- maxlen = MAX_LINELEN;
- afx->buffer_len = iobuf_read_line( a, &afx->buffer,
- &afx->buffer_size, &maxlen );
- line = afx->buffer;
- len = afx->buffer_len;
- } while( !maxlen );
- }
-
- /* parse the header lines */
- while(len) {
- /* read the next line (skip all truncated lines) */
- do {
- maxlen = MAX_LINELEN;
- afx->buffer_len = iobuf_read_line( a, &afx->buffer,
- &afx->buffer_size, &maxlen );
- line = afx->buffer;
- len = afx->buffer_len;
- } while( !maxlen );
-
- i = parse_header_line( afx, line, len );
- if( i <= 0 ) {
- if( i )
- rc = GPG_ERR_INV_ARMOR;
- break;
- }
- }
-
-
- if( rc )
- invalid_armor();
- else if( afx->in_cleartext )
- afx->faked = 1;
- else {
- afx->inp_checked = 1;
- afx->crc = CRCINIT;
- afx->idx = 0;
- afx->radbuf[0] = 0;
- }
-
- return rc;
-}
-
-
-
-/****************
- * Fake a literal data packet and wait for the next armor line
- * fixme: empty line handling and null length clear text signature are
- * not implemented/checked.
- */
-static int
-fake_packet( armor_filter_context_t *afx, iobuf_t a,
- size_t *retn, byte *buf, size_t size )
-{
- int rc = 0;
- size_t len = 0;
- int lastline = 0;
- unsigned maxlen, n;
- byte *p;
-
- len = 2; /* reserve 2 bytes for the length header */
- size -= 2; /* and 2 for the terminating header */
- while( !rc && len < size ) {
- /* copy what we have in the line buffer */
- if( afx->faked == 1 )
- afx->faked++; /* skip the first (empty) line */
- else {
- while( len < size && afx->buffer_pos < afx->buffer_len )
- buf[len++] = afx->buffer[afx->buffer_pos++];
- if( len >= size )
- continue;
- }
-
- /* read the next line */
- maxlen = MAX_LINELEN;
- afx->buffer_pos = 0;
- afx->buffer_len = iobuf_read_line( a, &afx->buffer,
- &afx->buffer_size, &maxlen );
- if( !afx->buffer_len ) {
- rc = -1; /* eof (should not happen) */
- continue;
- }
- if( !maxlen )
- afx->truncated++;
- if( !afx->not_dash_escaped ) {
- int crlf;
- p = afx->buffer;
- n = afx->buffer_len;
- crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
-
- /* PGP2 does not treat a tab as white space character */
- afx->buffer_len = trim_trailing_chars( p, n,
- afx->pgp2mode ? " \r\n" : " \t\r\n");
- /* the buffer is always allocated with enough space to append
- * the removed [CR], LF and a Nul
- * The reason for this complicated procedure is to keep at least
- * the original type of lineending - handling of the removed
- * trailing spaces seems to be impossible in our method
- * of faking a packet; either we have to use a temporary file
- * or calculate the hash here in this module and somehow find
- * a way to send the hash down the processing line (well, a special
- * faked packet could do the job).
- */
- if( crlf )
- afx->buffer[afx->buffer_len++] = '\r';
- afx->buffer[afx->buffer_len++] = '\n';
- afx->buffer[afx->buffer_len] = 0;
- }
- p = afx->buffer;
- n = afx->buffer_len;
-
- if( n > 2 && *p == '-' ) {
- /* check for dash escaped or armor header */
- if( p[1] == ' ' && !afx->not_dash_escaped ) {
- /* issue a warning if it is not regular encoded */
- if( p[2] != '-' && !( n > 6 && !memcmp(p+2, "From ", 5))) {
- log_info(_("invalid dash escaped line: "));
- print_string( stderr, p, n, 0 );
- putc('\n', stderr);
- }
- afx->buffer_pos = 2; /* skip */
- }
- else if( n >= 15 && p[1] == '-' && p[2] == '-' && p[3] == '-' ) {
- int type = is_armor_header( p, n );
- if( afx->not_dash_escaped && type != BEGIN_SIGNATURE )
- ; /* this is okay */
- else {
- if( type != BEGIN_SIGNATURE ) {
- log_info(_("unexpected armor:"));
- print_string( stderr, p, n, 0 );
- putc('\n', stderr);
- }
- lastline = 1;
- rc = -1;
- }
- }
- }
- }
-
- buf[0] = (len-2) >> 8;
- buf[1] = (len-2);
- if( lastline ) { /* write last (ending) length header */
- if( buf[0] || buf[1] ) { /* only if we have some text */
- buf[len++] = 0;
- buf[len++] = 0;
- }
- rc = 0;
- afx->faked = 0;
- afx->in_cleartext = 0;
- /* and now read the header lines */
- afx->buffer_pos = 0;
- for(;;) {
- int i;
-
- /* read the next line (skip all truncated lines) */
- do {
- maxlen = MAX_LINELEN;
- afx->buffer_len = iobuf_read_line( a, &afx->buffer,
- &afx->buffer_size, &maxlen );
- } while( !maxlen );
- p = afx->buffer;
- n = afx->buffer_len;
- if( !n ) {
- rc = -1;
- break; /* eof */
- }
- i = parse_header_line( afx, p , n );
- if( i <= 0 ) {
- if( i )
- invalid_armor();
- break;
- }
- }
- afx->inp_checked = 1;
- afx->crc = CRCINIT;
- afx->idx = 0;
- afx->radbuf[0] = 0;
- }
-
- *retn = len;
- return rc;
-}
-
-
-static int
-invalid_crc(void)
-{
- if ( opt.ignore_crc_error )
- return 0;
- log_inc_errorcount();
- return GPG_ERR_INV_ARMOR;
-}
-
-
-static int
-radix64_read( armor_filter_context_t *afx, iobuf_t a, size_t *retn,
- byte *buf, size_t size )
-{
- byte val;
- int c=0, c2; /*init c because gcc is not clever enough for the continue*/
- int checkcrc=0;
- int rc = 0;
- size_t n = 0;
- int idx, i;
- u32 crc;
-
- crc = afx->crc;
- idx = afx->idx;
- val = afx->radbuf[0];
- for( n=0; n < size; ) {
-
- if( afx->buffer_pos < afx->buffer_len )
- c = afx->buffer[afx->buffer_pos++];
- else { /* read the next line */
- unsigned maxlen = MAX_LINELEN;
- afx->buffer_pos = 0;
- afx->buffer_len = iobuf_read_line( a, &afx->buffer,
- &afx->buffer_size, &maxlen );
- if( !maxlen )
- afx->truncated++;
- if( !afx->buffer_len )
- break; /* eof */
- continue;
- }
-
- again:
- if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
- continue;
- else if( c == '=' ) { /* pad character: stop */
- /* some mailers leave quoted-printable encoded characters
- * so we try to workaround this */
- if( afx->buffer_pos+2 < afx->buffer_len ) {
- int cc1, cc2, cc3;
- cc1 = afx->buffer[afx->buffer_pos];
- cc2 = afx->buffer[afx->buffer_pos+1];
- cc3 = afx->buffer[afx->buffer_pos+2];
- if( isxdigit(cc1) && isxdigit(cc2)
- && strchr( "=\n\r\t ", cc3 )) {
- /* well it seems to be the case - adjust */
- c = isdigit(cc1)? (cc1 - '0'): (ascii_toupper(cc1)-'A'+10);
- c <<= 4;
- c |= isdigit(cc2)? (cc2 - '0'): (ascii_toupper(cc2)-'A'+10);
- afx->buffer_pos += 2;
- afx->qp_detected = 1;
- goto again;
- }
- }
-
- if( idx == 1 )
- buf[n++] = val;
- checkcrc++;
- break;
- }
- else if( (c = asctobin[(c2=c)]) == 255 ) {
- log_error(_("invalid radix64 character %02x skipped\n"), c2);
- continue;
- }
- switch(idx) {
- case 0: val = c << 2; break;
- case 1: val |= (c>>4)&3; buf[n++]=val;val=(c<<4)&0xf0;break;
- case 2: val |= (c>>2)&15; buf[n++]=val;val=(c<<6)&0xc0;break;
- case 3: val |= c&0x3f; buf[n++] = val; break;
- }
- idx = (idx+1) % 4;
- }
-
- for(i=0; i < n; i++ )
- crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
- crc &= 0x00ffffff;
- afx->crc = crc;
- afx->idx = idx;
- afx->radbuf[0] = val;
-
- if( checkcrc ) {
- afx->any_data = 1;
- afx->inp_checked=0;
- afx->faked = 0;
- for(;;) { /* skip lf and pad characters */
- if( afx->buffer_pos < afx->buffer_len )
- c = afx->buffer[afx->buffer_pos++];
- else { /* read the next line */
- unsigned maxlen = MAX_LINELEN;
- afx->buffer_pos = 0;
- afx->buffer_len = iobuf_read_line( a, &afx->buffer,
- &afx->buffer_size, &maxlen );
- if( !maxlen )
- afx->truncated++;
- if( !afx->buffer_len )
- break; /* eof */
- continue;
- }
- if( c == '\n' || c == ' ' || c == '\r'
- || c == '\t' || c == '=' )
- continue;
- break;
- }
- if( c == -1 )
- log_error(_("premature eof (no CRC)\n"));
- else {
- u32 mycrc = 0;
- idx = 0;
- do {
- if( (c = asctobin[c]) == 255 )
- break;
- switch(idx) {
- case 0: val = c << 2; break;
- case 1: val |= (c>>4)&3; mycrc |= val << 16;val=(c<<4)&0xf0;break;
- case 2: val |= (c>>2)&15; mycrc |= val << 8;val=(c<<6)&0xc0;break;
- case 3: val |= c&0x3f; mycrc |= val; break;
- }
- for(;;) {
- if( afx->buffer_pos < afx->buffer_len )
- c = afx->buffer[afx->buffer_pos++];
- else { /* read the next line */
- unsigned maxlen = MAX_LINELEN;
- afx->buffer_pos = 0;
- afx->buffer_len = iobuf_read_line( a, &afx->buffer,
- &afx->buffer_size,
- &maxlen );
- if( !maxlen )
- afx->truncated++;
- if( !afx->buffer_len )
- break; /* eof */
- continue;
- }
- break;
- }
- if( !afx->buffer_len )
- break; /* eof */
- } while( ++idx < 4 );
- if( c == -1 ) {
- log_info(_("premature eof (in CRC)\n"));
- rc = invalid_crc();
- }
- else if( idx != 4 ) {
- log_info(_("malformed CRC\n"));
- rc = invalid_crc();
- }
- else if( mycrc != afx->crc ) {
- log_info (_("CRC error; %06lx - %06lx\n"),
- (ulong)afx->crc, (ulong)mycrc);
- rc = invalid_crc();
- }
- else {
- rc = 0;
- /* FIXME: Here we should emit another control packet,
- * so that we know in mainproc that we are processing
- * a clearsign message */
-#if 0
- for(rc=0;!rc;) {
- rc = 0 /*check_trailer( &fhdr, c )*/;
- if( !rc ) {
- if( (c=iobuf_get(a)) == -1 )
- rc = 2;
- }
- }
- if( rc == -1 )
- rc = 0;
- else if( rc == 2 ) {
- log_error(_("premature eof (in Trailer)\n"));
- rc = GPG_ERR_INV_ARMOR;
- }
- else {
- log_error(_("error in trailer line\n"));
- rc = GPG_ERR_INV_ARMOR;
- }
-#endif
- }
- }
- }
-
- if( !n )
- rc = -1;
-
- *retn = n;
- return rc;
-}
-
-/****************
- * This filter is used to handle the armor stuff
- */
-int
-armor_filter( void *opaque, int control,
- iobuf_t a, byte *buf, size_t *ret_len)
-{
- size_t size = *ret_len;
- armor_filter_context_t *afx = opaque;
- int rc=0, i, c;
- byte radbuf[3];
- int idx, idx2;
- size_t n=0;
- u32 crc;
-#if 0
- static FILE *fp ;
-
- if( !fp ) {
- fp = fopen("armor.out", "w");
- assert(fp);
- }
-#endif
-
- if( DBG_FILTER )
- log_debug("armor-filter: control: %d\n", control );
- if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) {
- n = 0;
- if( afx->buffer_len ) {
- for(; n < size && afx->buffer_pos < afx->buffer_len; n++ )
- buf[n++] = afx->buffer[afx->buffer_pos++];
- if( afx->buffer_pos >= afx->buffer_len )
- afx->buffer_len = 0;
- }
- for(; n < size; n++ ) {
- if( (c=iobuf_get(a)) == -1 )
- break;
- buf[n] = c & 0xff;
- }
- if( !n )
- rc = -1;
- *ret_len = n;
- }
- else if( control == IOBUFCTRL_UNDERFLOW ) {
- /* We need some space for the faked packet. The minmum required
- * size is ~18 + length of the session marker */
- if( size < 50 )
- BUG(); /* supplied buffer too short */
-
- if( afx->faked )
- rc = fake_packet( afx, a, &n, buf, size );
- else if( !afx->inp_checked ) {
- rc = check_input( afx, a );
- if( afx->inp_bypass ) {
- for(n=0; n < size && afx->buffer_pos < afx->buffer_len; )
- buf[n++] = afx->buffer[afx->buffer_pos++];
- if( afx->buffer_pos >= afx->buffer_len )
- afx->buffer_len = 0;
- if( !n )
- rc = -1;
- }
- else if( afx->faked ) {
- unsigned int hashes = afx->hashes;
- const byte *sesmark;
- size_t sesmarklen;
-
- sesmark = get_session_marker( &sesmarklen );
- if ( sesmarklen > 20 )
- BUG();
-
- /* the buffer is at least 15+n*15 bytes long, so it
- * is easy to construct the packets */
-
- hashes &= 1|2|4|8|16|32|64;
- if( !hashes ) {
- hashes |= 4; /* default to MD 5 */
- /* This is non-ideal since PGP 5-8 have the same
- end-of-line bugs as PGP 2. However, we only
- enable pgp2mode if there is no Hash: header. */
- if( opt.pgp2_workarounds )
- afx->pgp2mode = 1;
- }
- n=0;
- /* first a gpg control packet */
- buf[n++] = 0xff; /* new format, type 63, 1 length byte */
- n++; /* see below */
- memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
- buf[n++] = CTRLPKT_CLEARSIGN_START;
- buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
- if( hashes & 1 )
- buf[n++] = DIGEST_ALGO_RMD160;
- if( hashes & 2 )
- buf[n++] = DIGEST_ALGO_SHA1;
- if( hashes & 4 )
- buf[n++] = DIGEST_ALGO_MD5;
- if( hashes & 8 )
- buf[n++] = DIGEST_ALGO_SHA256;
- if( hashes & 16 )
- buf[n++] = DIGEST_ALGO_SHA384;
- if( hashes & 32 )
- buf[n++] = DIGEST_ALGO_SHA512;
- buf[1] = n - 2;
-
- /* followed by a plaintext packet */
- buf[n++] = 0xaf; /* old packet format, type 11, var length */
- buf[n++] = 0; /* set the length header */
- buf[n++] = 6;
- buf[n++] = 't'; /* canonical text mode */
- buf[n++] = 0; /* namelength */
- memset(buf+n, 0, 4); /* timestamp */
- n += 4;
- }
- else if( !rc )
- rc = radix64_read( afx, a, &n, buf, size );
- }
- else
- rc = radix64_read( afx, a, &n, buf, size );
-#if 0
- if( n )
- if( fwrite(buf, n, 1, fp ) != 1 )
- BUG();
-#endif
- *ret_len = n;
- }
- else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
- if( !afx->status ) { /* write the header line */
- const char *s;
- STRLIST comment = opt.comments;
-
- if( afx->what >= DIM(head_strings) )
- log_bug("afx->what=%d", afx->what);
- iobuf_writestr(a, "-----");
- iobuf_writestr(a, head_strings[afx->what] );
- iobuf_writestr(a, "-----" LF );
- if( !opt.no_version )
- iobuf_writestr(a, "Version: GnuPG v" VERSION " ("
- PRINTABLE_OS_NAME ")" LF );
-
- /* Write the comment string. */
- for(s=comment? comment->d:NULL; comment;
- comment=comment->next,s=comment->d)
- {
- iobuf_writestr(a, "Comment: " );
- for ( ; *s; s++ )
- {
- if( *s == '\n' )
- iobuf_writestr(a, "\\n" );
- else if( *s == '\r' )
- iobuf_writestr(a, "\\r" );
- else if( *s == '\v' )
- iobuf_writestr(a, "\\v" );
- else
- iobuf_put(a, *s );
- }
- iobuf_writestr(a, LF );
- }
-
- if ( afx->hdrlines ) {
- for ( s = afx->hdrlines; *s; s++ ) {
-#ifdef HAVE_DOSISH_SYSTEM
- if ( *s == '\n' )
- iobuf_put( a, '\r');
-#endif
- iobuf_put(a, *s );
- }
- }
- iobuf_writestr(a, LF );
- afx->status++;
- afx->idx = 0;
- afx->idx2 = 0;
- afx->crc = CRCINIT;
-
- }
- crc = afx->crc;
- idx = afx->idx;
- idx2 = afx->idx2;
- for(i=0; i < idx; i++ )
- radbuf[i] = afx->radbuf[i];
-
- for(i=0; i < size; i++ )
- crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
- crc &= 0x00ffffff;
-
- for( ; size; buf++, size-- ) {
- radbuf[idx++] = *buf;
- if( idx > 2 ) {
- idx = 0;
- c = bintoasc[(*radbuf >> 2) & 077];
- iobuf_put(a, c);
- c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
- iobuf_put(a, c);
- c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
- iobuf_put(a, c);
- c = bintoasc[radbuf[2]&077];
- iobuf_put(a, c);
- if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */
- iobuf_writestr(a, LF );
- idx2=0;
- }
- }
- }
- for(i=0; i < idx; i++ )
- afx->radbuf[i] = radbuf[i];
- afx->idx = idx;
- afx->idx2 = idx2;
- afx->crc = crc;
- }
- else if( control == IOBUFCTRL_INIT ) {
- if( !is_initialized )
- initialize();
- }
- else if( control == IOBUFCTRL_CANCEL ) {
- afx->cancel = 1;
- }
- else if( control == IOBUFCTRL_FREE ) {
- if( afx->cancel )
- ;
- else if( afx->status ) { /* pad, write cecksum, and bottom line */
- crc = afx->crc;
- idx = afx->idx;
- idx2 = afx->idx2;
- for(i=0; i < idx; i++ )
- radbuf[i] = afx->radbuf[i];
- if( idx ) {
- c = bintoasc[(*radbuf>>2)&077];
- iobuf_put(a, c);
- if( idx == 1 ) {
- c = bintoasc[((*radbuf << 4) & 060) & 077];
- iobuf_put(a, c);
- iobuf_put(a, '=');
- iobuf_put(a, '=');
- }
- else { /* 2 */
- c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
- iobuf_put(a, c);
- c = bintoasc[((radbuf[1] << 2) & 074) & 077];
- iobuf_put(a, c);
- iobuf_put(a, '=');
- }
- if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */
- iobuf_writestr(a, LF );
- idx2=0;
- }
- }
- /* may need a linefeed */
- if( idx2 )
- iobuf_writestr(a, LF );
- /* write the CRC */
- iobuf_put(a, '=');
- radbuf[0] = crc >>16;
- radbuf[1] = crc >> 8;
- radbuf[2] = crc;
- c = bintoasc[(*radbuf >> 2) & 077];
- iobuf_put(a, c);
- c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
- iobuf_put(a, c);
- c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
- iobuf_put(a, c);
- c = bintoasc[radbuf[2]&077];
- iobuf_put(a, c);
- iobuf_writestr(a, LF );
- /* and the the trailer */
- if( afx->what >= DIM(tail_strings) )
- log_bug("afx->what=%d", afx->what);
- iobuf_writestr(a, "-----");
- iobuf_writestr(a, tail_strings[afx->what] );
- iobuf_writestr(a, "-----" LF );
- }
- else if( !afx->any_data && !afx->inp_bypass ) {
- log_error(_("no valid OpenPGP data found.\n"));
- afx->no_openpgp_data = 1;
- write_status_text( STATUS_NODATA, "1" );
- }
- if( afx->truncated )
- log_info(_("invalid armor: line longer than %d characters\n"),
- MAX_LINELEN );
- /* issue an error to enforce dissemination of correct software */
- if( afx->qp_detected )
- log_error(_("quoted printable character in armor - "
- "probably a buggy MTA has been used\n") );
- xfree ( afx->buffer );
- afx->buffer = NULL;
- }
- else if( control == IOBUFCTRL_DESC )
- *(char**)buf = "armor_filter";
- return rc;
-}
-
-
-/****************
- * create a radix64 encoded string.
- */
-char *
-make_radix64_string( const byte *data, size_t len )
-{
- char *buffer, *p;
-
- buffer = p = xmalloc ( (len+2)/3*4 + 1 );
- for( ; len >= 3 ; len -= 3, data += 3 ) {
- *p++ = bintoasc[(data[0] >> 2) & 077];
- *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
- *p++ = bintoasc[(((data[1]<<2)&074)|((data[2]>>6)&03))&077];
- *p++ = bintoasc[data[2]&077];
- }
- if( len == 2 ) {
- *p++ = bintoasc[(data[0] >> 2) & 077];
- *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
- *p++ = bintoasc[((data[1]<<2)&074)];
- }
- else if( len == 1 ) {
- *p++ = bintoasc[(data[0] >> 2) & 077];
- *p++ = bintoasc[(data[0] <<4)&060];
- }
- *p = 0;
- return buffer;
-}
-
-
-/***********************************************
- * For the pipemode command we can't use the armor filter for various
- * reasons, so we use this new unarmor_pump stuff to remove the armor
- */
-
-enum unarmor_state_e {
- STA_init = 0,
- STA_bypass,
- STA_wait_newline,
- STA_wait_dash,
- STA_first_dash,
- STA_compare_header,
- STA_found_header_wait_newline,
- STA_skip_header_lines,
- STA_skip_header_lines_non_ws,
- STA_read_data,
- STA_wait_crc,
- STA_read_crc,
- STA_ready
-};
-
-struct unarmor_pump_s {
- enum unarmor_state_e state;
- byte val;
- int checkcrc;
- int pos; /* counts from 0..3 */
- u32 crc;
- u32 mycrc; /* the one store in the data */
-};
-
-
-
-UnarmorPump
-unarmor_pump_new (void)
-{
- UnarmorPump x;
-
- if( !is_initialized )
- initialize();
- x = xcalloc (1,sizeof *x);
- return x;
-}
-
-void
-unarmor_pump_release (UnarmorPump x)
-{
- xfree (x);
-}
-
-/*
- * Get the next character from the ascii armor taken from the IOBUF
- * created earlier by unarmor_pump_new().
- * Return: c = Character
- * 256 = ignore this value
- * -1 = End of current armor
- * -2 = Premature EOF (not used)
- * -3 = Invalid armor
- */
-int
-unarmor_pump (UnarmorPump x, int c)
-{
- int rval = 256; /* default is to ignore the return value */
-
- switch (x->state) {
- case STA_init:
- {
- byte tmp[1];
- tmp[0] = c;
- if ( is_armored (tmp) )
- x->state = c == '-'? STA_first_dash : STA_wait_newline;
- else {
- x->state = STA_bypass;
- return c;
- }
- }
- break;
- case STA_bypass:
- return c; /* return here to avoid crc calculation */
- case STA_wait_newline:
- if (c == '\n')
- x->state = STA_wait_dash;
- break;
- case STA_wait_dash:
- x->state = c == '-'? STA_first_dash : STA_wait_newline;
- break;
- case STA_first_dash: /* just need for initalization */
- x->pos = 0;
- x->state = STA_compare_header;
- case STA_compare_header:
- if ( "-----BEGIN PGP SIGNATURE-----"[++x->pos] == c ) {
- if ( x->pos == 28 )
- x->state = STA_found_header_wait_newline;
- }
- else
- x->state = c == '\n'? STA_wait_dash : STA_wait_newline;
- break;
- case STA_found_header_wait_newline:
- /* to make CR,LF issues easier we simply allow for white space
- behind the 5 dashes */
- if ( c == '\n' )
- x->state = STA_skip_header_lines;
- else if ( c != '\r' && c != ' ' && c != '\t' )
- x->state = STA_wait_dash; /* garbage after the header line */
- break;
- case STA_skip_header_lines:
- /* i.e. wait for one empty line */
- if ( c == '\n' ) {
- x->state = STA_read_data;
- x->crc = CRCINIT;
- x->val = 0;
- x->pos = 0;
- }
- else if ( c != '\r' && c != ' ' && c != '\t' )
- x->state = STA_skip_header_lines_non_ws;
- break;
- case STA_skip_header_lines_non_ws:
- /* like above but we already encountered non white space */
- if ( c == '\n' )
- x->state = STA_skip_header_lines;
- break;
- case STA_read_data:
- /* fixme: we don't check for the trailing dash lines but rely
- * on the armor stop characters */
- if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
- break; /* skip all kind of white space */
-
- if( c == '=' ) { /* pad character: stop */
- if( x->pos == 1 ) /* in this case val has some value */
- rval = x->val;
- x->state = STA_wait_crc;
- break;
- }
-
- {
- int c2;
- if( (c = asctobin[(c2=c)]) == 255 ) {
- log_error(_("invalid radix64 character %02x skipped\n"), c2);
- break;
- }
- }
-
- switch(x->pos) {
- case 0:
- x->val = c << 2;
- break;
- case 1:
- x->val |= (c>>4)&3;
- rval = x->val;
- x->val = (c<<4)&0xf0;
- break;
- case 2:
- x->val |= (c>>2)&15;
- rval = x->val;
- x->val = (c<<6)&0xc0;
- break;
- case 3:
- x->val |= c&0x3f;
- rval = x->val;
- break;
- }
- x->pos = (x->pos+1) % 4;
- break;
- case STA_wait_crc:
- if( c == '\n' || c == ' ' || c == '\r' || c == '\t' || c == '=' )
- break; /* skip ws and pad characters */
- /* assume that we are at the next line */
- x->state = STA_read_crc;
- x->pos = 0;
- x->mycrc = 0;
- case STA_read_crc:
- if( (c = asctobin[c]) == 255 ) {
- rval = -1; /* ready */
- if( x->crc != x->mycrc ) {
- log_info (_("CRC error; %06lx - %06lx\n"),
- (ulong)x->crc, (ulong)x->mycrc);
- if ( invalid_crc() )
- rval = -3;
- }
- x->state = STA_ready; /* not sure whether this is correct */
- break;
- }
-
- switch(x->pos) {
- case 0:
- x->val = c << 2;
- break;
- case 1:
- x->val |= (c>>4)&3;
- x->mycrc |= x->val << 16;
- x->val = (c<<4)&0xf0;
- break;
- case 2:
- x->val |= (c>>2)&15;
- x->mycrc |= x->val << 8;
- x->val = (c<<6)&0xc0;
- break;
- case 3:
- x->val |= c&0x3f;
- x->mycrc |= x->val;
- break;
- }
- x->pos = (x->pos+1) % 4;
- break;
- case STA_ready:
- rval = -1;
- break;
- }
-
- if ( !(rval & ~255) ) { /* compute the CRC */
- x->crc = (x->crc << 8) ^ crc_table[((x->crc >> 16)&0xff) ^ rval];
- x->crc &= 0x00ffffff;
- }
-
- return rval;
-}
diff --git a/g10/build-packet.c b/g10/build-packet.c
deleted file mode 100644
index d2c538477..000000000
--- a/g10/build-packet.c
+++ /dev/null
@@ -1,1203 +0,0 @@
-/* build-packet.c - assemble packets and write them
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "packet.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "mpi.h"
-#include "util.h"
-#include "cipher.h"
-#include "memory.h"
-#include "options.h"
-
-
-static int do_comment( iobuf_t out, int ctb, PKT_comment *rem );
-static int do_user_id( iobuf_t out, int ctb, PKT_user_id *uid );
-static int do_public_key( iobuf_t out, int ctb, PKT_public_key *pk );
-static int do_secret_key( iobuf_t out, int ctb, PKT_secret_key *pk );
-static int do_symkey_enc( iobuf_t out, int ctb, PKT_symkey_enc *enc );
-static int do_pubkey_enc( iobuf_t out, int ctb, PKT_pubkey_enc *enc );
-static u32 calc_plaintext( PKT_plaintext *pt );
-static int do_plaintext( iobuf_t out, int ctb, PKT_plaintext *pt );
-static int do_encrypted( iobuf_t out, int ctb, PKT_encrypted *ed );
-static int do_encrypted_mdc( iobuf_t out, int ctb, PKT_encrypted *ed );
-static int do_compressed( iobuf_t out, int ctb, PKT_compressed *cd );
-static int do_signature( iobuf_t out, int ctb, PKT_signature *sig );
-static int do_onepass_sig( iobuf_t out, int ctb, PKT_onepass_sig *ops );
-
-static int calc_header_length( u32 len, int new_ctb );
-static int write_16(iobuf_t inp, u16 a);
-static int write_32(iobuf_t inp, u32 a);
-static int write_header( iobuf_t out, int ctb, u32 len );
-static int write_sign_packet_header( iobuf_t out, int ctb, u32 len );
-static int write_header2( iobuf_t out, int ctb, u32 len, int hdrlen, int blkmode );
-static int write_new_header( iobuf_t out, int ctb, u32 len, int hdrlen );
-static int write_version( iobuf_t out, int ctb );
-
-/****************
- * Build a packet and write it to INP
- * Returns: 0 := okay
- * >0 := error
- * Note: Caller must free the packet
- */
-int
-build_packet( iobuf_t out, PACKET *pkt )
-{
- int new_ctb=0, rc=0, ctb;
- int pkttype;
-
- if( DBG_PACKET )
- log_debug("build_packet() type=%d\n", pkt->pkttype );
- assert( pkt->pkt.generic );
-
- switch( (pkttype = pkt->pkttype) ) {
- case PKT_OLD_COMMENT: pkttype = pkt->pkttype = PKT_COMMENT; break;
- case PKT_PLAINTEXT: new_ctb = pkt->pkt.plaintext->new_ctb; break;
- case PKT_ENCRYPTED:
- case PKT_ENCRYPTED_MDC: new_ctb = pkt->pkt.encrypted->new_ctb; break;
- case PKT_COMPRESSED:new_ctb = pkt->pkt.compressed->new_ctb; break;
- case PKT_USER_ID:
- if( pkt->pkt.user_id->attrib_data )
- pkttype = PKT_ATTRIBUTE;
- break;
- default: break;
- }
-
- if( new_ctb || pkttype > 15 ) /* new format */
- ctb = 0xc0 | (pkttype & 0x3f);
- else
- ctb = 0x80 | ((pkttype & 15)<<2);
- switch( pkttype ) {
- case PKT_ATTRIBUTE:
- case PKT_USER_ID:
- rc = do_user_id( out, ctb, pkt->pkt.user_id );
- break;
- case PKT_COMMENT:
- rc = do_comment( out, ctb, pkt->pkt.comment );
- break;
- case PKT_PUBLIC_SUBKEY:
- case PKT_PUBLIC_KEY:
- rc = do_public_key( out, ctb, pkt->pkt.public_key );
- break;
- case PKT_SECRET_SUBKEY:
- case PKT_SECRET_KEY:
- rc = do_secret_key( out, ctb, pkt->pkt.secret_key );
- break;
- case PKT_SYMKEY_ENC:
- rc = do_symkey_enc( out, ctb, pkt->pkt.symkey_enc );
- break;
- case PKT_PUBKEY_ENC:
- rc = do_pubkey_enc( out, ctb, pkt->pkt.pubkey_enc );
- break;
- case PKT_PLAINTEXT:
- rc = do_plaintext( out, ctb, pkt->pkt.plaintext );
- break;
- case PKT_ENCRYPTED:
- rc = do_encrypted( out, ctb, pkt->pkt.encrypted );
- break;
- case PKT_ENCRYPTED_MDC:
- rc = do_encrypted_mdc( out, ctb, pkt->pkt.encrypted );
- break;
- case PKT_COMPRESSED:
- rc = do_compressed( out, ctb, pkt->pkt.compressed );
- break;
- case PKT_SIGNATURE:
- rc = do_signature( out, ctb, pkt->pkt.signature );
- break;
- case PKT_ONEPASS_SIG:
- rc = do_onepass_sig( out, ctb, pkt->pkt.onepass_sig );
- break;
- case PKT_RING_TRUST:
- break; /* ignore it (keyring.c does write it directly)*/
- case PKT_MDC: /* we write it directly, so we should never see it here. */
- default:
- log_bug("invalid packet type in build_packet()\n");
- break;
- }
-
- return rc;
-}
-
-/****************
- * calculate the length of a packet described by PKT
- */
-u32
-calc_packet_length( PACKET *pkt )
-{
- u32 n=0;
- int new_ctb = 0;
-
- assert( pkt->pkt.generic );
- switch( pkt->pkttype ) {
- case PKT_PLAINTEXT:
- n = calc_plaintext( pkt->pkt.plaintext );
- new_ctb = pkt->pkt.plaintext->new_ctb;
- break;
- case PKT_ATTRIBUTE:
- case PKT_USER_ID:
- case PKT_COMMENT:
- case PKT_PUBLIC_KEY:
- case PKT_SECRET_KEY:
- case PKT_SYMKEY_ENC:
- case PKT_PUBKEY_ENC:
- case PKT_ENCRYPTED:
- case PKT_SIGNATURE:
- case PKT_ONEPASS_SIG:
- case PKT_RING_TRUST:
- case PKT_COMPRESSED:
- default:
- log_bug("invalid packet type in calc_packet_length()");
- break;
- }
-
- n += calc_header_length(n, new_ctb);
- return n;
-}
-
-static void
-write_fake_data( iobuf_t out, gcry_mpi_t a )
-{
- if( a ) {
- unsigned int n;
- void *p;
-
- assert( gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE));
- p = gcry_mpi_get_opaque (a, &n);
- iobuf_write (out, p, (n+7)/8);
- }
-}
-
-
-static int
-do_comment (iobuf_t out, int ctb, PKT_comment *rem)
-{
- int rc = 0;
-
- if (opt.sk_comments)
- {
- write_header(out, ctb, rem->len);
- rc = iobuf_write( out, rem->data, rem->len );
- }
- return rc;
-}
-
-static int
-do_user_id( iobuf_t out, int ctb, PKT_user_id *uid )
-{
- int rc;
-
- if (uid->attrib_data)
- {
- write_header (out, ctb, uid->attrib_len);
- rc = iobuf_write (out, uid->attrib_data, uid->attrib_len );
- }
- else
- {
- write_header (out, ctb, uid->len);
- rc = iobuf_write (out, uid->name, uid->len );
- }
- return rc;
-}
-
-static int
-do_public_key( iobuf_t out, int ctb, PKT_public_key *pk )
-{
- int rc = 0;
- int n, i;
- iobuf_t a = iobuf_temp();
-
- if( !pk->version )
- iobuf_put( a, 3 );
- else
- iobuf_put( a, pk->version );
- write_32(a, pk->timestamp );
- if( pk->version < 4 ) {
- u16 ndays;
- if( pk->expiredate )
- ndays = (u16)((pk->expiredate - pk->timestamp) / 86400L);
- else
- ndays = 0;
- write_16(a, ndays );
- }
- iobuf_put(a, pk->pubkey_algo );
- n = pubkey_get_npkey( pk->pubkey_algo );
- if( !n )
- write_fake_data( a, pk->pkey[0] );
- for(i=0; i < n; i++ )
- mpi_write(a, pk->pkey[i] );
-
- write_header2(out, ctb, iobuf_get_temp_length(a), pk->hdrbytes, 1 );
- rc = iobuf_write_temp (out, a);
-
- iobuf_close(a);
- return rc;
-}
-
-
-/****************
- * Make a hash value from the public key certificate
- */
-void
-hash_public_key( MD_HANDLE md, PKT_public_key *pk )
-{
- PACKET pkt;
- int rc = 0;
- int ctb;
- ulong pktlen;
- int c;
- iobuf_t a = iobuf_temp();
-#if 0
- FILE *fp = fopen("dump.pk", "a");
- int i=0;
-
- fprintf(fp, "\nHashing PK (v%d):\n", pk->version);
-#endif
-
- /* build the packet */
- init_packet(&pkt);
- pkt.pkttype = PKT_PUBLIC_KEY;
- pkt.pkt.public_key = pk;
- if( (rc = build_packet( a, &pkt )) )
- log_fatal("build public_key for hashing failed: %s\n", gpg_strerror (rc));
-
- if( !(pk->version == 3 && pk->pubkey_algo == 16) ) {
- /* skip the constructed header but don't do this for our very old
- * v3 ElG keys */
- ctb = iobuf_get_noeof(a);
- pktlen = 0;
- if( (ctb & 0x40) ) {
- c = iobuf_get_noeof(a);
- if( c < 192 )
- pktlen = c;
- else if( c < 224 ) {
- pktlen = (c - 192) * 256;
- c = iobuf_get_noeof(a);
- pktlen += c + 192;
- }
- else if( c == 255 ) {
- pktlen = iobuf_get_noeof(a) << 24;
- pktlen |= iobuf_get_noeof(a) << 16;
- pktlen |= iobuf_get_noeof(a) << 8;
- pktlen |= iobuf_get_noeof(a);
- }
- }
- else {
- int lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
- for( ; lenbytes; lenbytes-- ) {
- pktlen <<= 8;
- pktlen |= iobuf_get_noeof(a);
- }
- }
- /* hash a header */
- gcry_md_putc ( md, 0x99 );
- pktlen &= 0xffff; /* can't handle longer packets */
- gcry_md_putc ( md, pktlen >> 8 );
- gcry_md_putc ( md, pktlen & 0xff );
- }
- /* hash the packet body */
- while( (c=iobuf_get(a)) != -1 ) {
-#if 0
- fprintf( fp," %02x", c );
- if( (++i == 24) ) {
- putc('\n', fp);
- i=0;
- }
-#endif
- gcry_md_putc ( md, c );
- }
-#if 0
- putc('\n', fp);
- fclose(fp);
-#endif
- iobuf_cancel(a);
-}
-
-
-static int
-do_secret_key( iobuf_t out, int ctb, PKT_secret_key *sk )
-{
- int rc = 0;
- int i, nskey, npkey;
- iobuf_t a = iobuf_temp(); /* build in a self-enlarging buffer */
-
- /* Write the version number - if none is specified, use 3 */
- if( !sk->version )
- iobuf_put( a, 3 );
- else
- iobuf_put( a, sk->version );
- write_32(a, sk->timestamp );
-
- /* v3 needs the expiration time */
- if( sk->version < 4 ) {
- u16 ndays;
- if( sk->expiredate )
- ndays = (u16)((sk->expiredate - sk->timestamp) / 86400L);
- else
- ndays = 0;
- write_16(a, ndays);
- }
-
- iobuf_put(a, sk->pubkey_algo );
-
- /* get number of secret and public parameters. They are held in
- one array first the public ones, then the secret ones */
- nskey = pubkey_get_nskey( sk->pubkey_algo );
- npkey = pubkey_get_npkey( sk->pubkey_algo );
-
- /* If we don't have any public parameters - which is the case if
- we don't know the algorithm used - the parameters are stored as
- one blob in a faked (opaque) gcry_mpi_t */
- if( !npkey ) {
- write_fake_data( a, sk->skey[0] );
- goto leave;
- }
- assert( npkey < nskey );
-
- /* Writing the public parameters is easy */
- for(i=0; i < npkey; i++ )
- mpi_write(a, sk->skey[i] );
-
- /* build the header for protected (encrypted) secret parameters */
- if( sk->is_protected ) {
- if( is_RSA(sk->pubkey_algo) && sk->version < 4
- && !sk->protect.s2k.mode ) {
- /* the simple rfc1991 (v3) way */
- iobuf_put(a, sk->protect.algo );
- iobuf_write(a, sk->protect.iv, sk->protect.ivlen );
- }
- else {
- /* OpenPGP protection according to rfc2440 */
- iobuf_put(a, sk->protect.sha1chk? 0xfe : 0xff );
- iobuf_put(a, sk->protect.algo );
- if( sk->protect.s2k.mode >= 1000 ) {
- /* These modes are not possible in OpenPGP, we use them
- to implement our extensions, 101 can be seen as a
- private/experimental extension (this is not
- specified in rfc2440 but the same scheme is used
- for all other algorithm identifiers) */
- iobuf_put(a, 101 );
- iobuf_put(a, sk->protect.s2k.hash_algo );
- iobuf_write(a, "GNU", 3 );
- iobuf_put(a, sk->protect.s2k.mode - 1000 );
- }
- else {
- iobuf_put(a, sk->protect.s2k.mode );
- iobuf_put(a, sk->protect.s2k.hash_algo );
- }
- if( sk->protect.s2k.mode == 1
- || sk->protect.s2k.mode == 3 )
- iobuf_write(a, sk->protect.s2k.salt, 8 );
- if( sk->protect.s2k.mode == 3 )
- iobuf_put(a, sk->protect.s2k.count );
-
- /* For our special modes 1001 and 1002 we do not need an IV */
- if( sk->protect.s2k.mode != 1001
- && sk->protect.s2k.mode != 1002 )
- iobuf_write(a, sk->protect.iv, sk->protect.ivlen );
- }
- }
- else
- iobuf_put(a, 0 );
-
- if( sk->protect.s2k.mode == 1001 )
- ; /* GnuPG extension - don't write a secret key at all */
- else if( sk->protect.s2k.mode == 1002 )
- { /* GnuPG extension - divert to OpenPGP smartcard. */
- iobuf_put(a, sk->protect.ivlen ); /* length of the serial
- number or 0 for no serial
- number. */
- /* The serial number gets stored in the IV field. */
- iobuf_write(a, sk->protect.iv, sk->protect.ivlen);
- }
- else if( sk->is_protected && sk->version >= 4 ) {
- /* The secret key is protected - write it out as it is */
- byte *p;
- assert( gcry_mpi_get_flag( sk->skey[npkey], GCRYMPI_FLAG_OPAQUE ) );
- p = gcry_mpi_get_opaque( sk->skey[npkey], &i );
- iobuf_write(a, p, (i+7)/8 );
- }
- else if( sk->is_protected ) {
- /* The secret key is protected the old v4 way. */
- for( ; i < nskey; i++ ) {
- byte *p;
- size_t n;
-
- assert( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
- p = gcry_mpi_get_opaque( sk->skey[i], &n );
- iobuf_write (a, p, (n+7)/8);
- }
- write_16(a, sk->csum );
- }
- else {
- /* non-protected key */
- for( ; i < nskey; i++ )
- mpi_write(a, sk->skey[i] );
- write_16(a, sk->csum );
- }
-
- leave:
- /* Build the header of the packet - which we must do after writing all
- the other stuff, so that we know the length of the packet */
- write_header2(out, ctb, iobuf_get_temp_length(a), sk->hdrbytes, 1 );
- /* And finally write it out the real stream */
- rc = iobuf_write_temp (out, a );
-
- iobuf_close(a); /* close the remporary buffer */
- return rc;
-}
-
-static int
-do_symkey_enc( iobuf_t out, int ctb, PKT_symkey_enc *enc )
-{
- int rc = 0;
- iobuf_t a = iobuf_temp();
-
- assert( enc->version == 4 );
- switch( enc->s2k.mode ) {
- case 0: case 1: case 3: break;
- default: log_bug("do_symkey_enc: s2k=%d\n", enc->s2k.mode );
- }
- iobuf_put( a, enc->version );
- iobuf_put( a, enc->cipher_algo );
- iobuf_put( a, enc->s2k.mode );
- iobuf_put( a, enc->s2k.hash_algo );
- if( enc->s2k.mode == 1 || enc->s2k.mode == 3 ) {
- iobuf_write(a, enc->s2k.salt, 8 );
- if( enc->s2k.mode == 3 )
- iobuf_put(a, enc->s2k.count);
- }
- if( enc->seskeylen )
- iobuf_write(a, enc->seskey, enc->seskeylen );
-
- write_header(out, ctb, iobuf_get_temp_length(a) );
- rc = iobuf_write_temp (out, a);
-
- iobuf_close(a);
- return rc;
-}
-
-
-
-
-static int
-do_pubkey_enc( iobuf_t out, int ctb, PKT_pubkey_enc *enc )
-{
- int rc = 0;
- int n, i;
- iobuf_t a = iobuf_temp();
-
- write_version( a, ctb );
- if( enc->throw_keyid ) {
- write_32(a, 0 ); /* don't tell Eve who can decrypt the message */
- write_32(a, 0 );
- }
- else {
- write_32(a, enc->keyid[0] );
- write_32(a, enc->keyid[1] );
- }
- iobuf_put(a,enc->pubkey_algo );
- n = pubkey_get_nenc( enc->pubkey_algo );
- if( !n )
- write_fake_data( a, enc->data[0] );
- for(i=0; i < n; i++ )
- mpi_write(a, enc->data[i] );
-
- write_header(out, ctb, iobuf_get_temp_length(a) );
- rc = iobuf_write_temp (out, a);
-
- iobuf_close(a);
- return rc;
-}
-
-
-
-
-static u32
-calc_plaintext( PKT_plaintext *pt )
-{
- return pt->len? (1 + 1 + pt->namelen + 4 + pt->len) : 0;
-}
-
-static int
-do_plaintext( iobuf_t out, int ctb, PKT_plaintext *pt )
-{
- int i, rc = 0;
- u32 n;
- byte buf[1000]; /* this buffer has the plaintext! */
- int nbytes;
-
- /* Truncate namelen to the maximum 255 characters. This does mean
- that a function that calls build_packet with an illegal literal
- packet will get it back legalized. */
- if(pt->namelen>255)
- pt->namelen=255;
-
- write_header(out, ctb, calc_plaintext( pt ) );
- iobuf_put(out, pt->mode );
- iobuf_put(out, pt->namelen );
- for(i=0; i < pt->namelen; i++ )
- iobuf_put(out, pt->name[i] );
- rc = write_32 (out, pt->timestamp);
-
- n = 0;
- while( (nbytes=iobuf_read(pt->buf, buf, 1000)) != -1 ) {
- rc = iobuf_write(out, buf, nbytes);
- if (rc)
- break;
- n += nbytes;
- }
- wipememory(buf,1000); /* burn the buffer */
- if( !pt->len )
- iobuf_set_block_mode(out, 0 ); /* write end marker */
- else if( n != pt->len )
- log_error("do_plaintext(): wrote %lu bytes but expected %lu bytes\n",
- (ulong)n, (ulong)pt->len );
-
- return rc;
-}
-
-
-
-static int
-do_encrypted( iobuf_t out, int ctb, PKT_encrypted *ed )
-{
- int rc = 0;
- u32 n;
-
- n = ed->len ? (ed->len + ed->extralen) : 0;
- write_header(out, ctb, n );
-
- /* This is all. The caller has to write the real data */
-
- return rc;
-}
-
-static int
-do_encrypted_mdc( iobuf_t out, int ctb, PKT_encrypted *ed )
-{
- int rc = 0;
- u32 n;
-
- assert( ed->mdc_method );
-
- /* Take version number and the following MDC packet in account. */
- n = ed->len ? (ed->len + ed->extralen + 1 + 22) : 0;
- write_header(out, ctb, n );
- iobuf_put(out, 1 ); /* version */
-
- /* This is all. The caller has to write the real data */
-
- return rc;
-}
-
-
-static int
-do_compressed( iobuf_t out, int ctb, PKT_compressed *cd )
-{
- int rc = 0;
-
- /* We must use the old convention and don't use blockmode for tyhe
- sake of PGP 2 compatibility. However if the new_ctb flag was
- set, CTB is already formatted as new style and write_header2
- does create a partial length encoding using new the new
- style. */
- write_header2(out, ctb, 0, 0, 0 );
- iobuf_put(out, cd->algorithm );
-
- /* This is all. The caller has to write the real data */
-
- return rc;
-}
-
-
-/****************
- * Delete all subpackets of type REQTYPE and return a bool whether a packet
- * was deleted.
- */
-int
-delete_sig_subpkt (subpktarea_t *area, sigsubpkttype_t reqtype )
-{
- int buflen;
- sigsubpkttype_t type;
- byte *buffer, *bufstart;
- size_t n;
- size_t unused = 0;
- int okay = 0;
-
- if( !area )
- return 0;
- buflen = area->len;
- buffer = area->data;
- for(;;) {
- if( !buflen ) {
- okay = 1;
- break;
- }
- bufstart = buffer;
- n = *buffer++; buflen--;
- if( n == 255 ) {
- if( buflen < 4 )
- break;
- n = (buffer[0] << 24) | (buffer[1] << 16)
- | (buffer[2] << 8) | buffer[3];
- buffer += 4;
- buflen -= 4;
- }
- else if( n >= 192 ) {
- if( buflen < 2 )
- break;
- n = (( n - 192 ) << 8) + *buffer + 192;
- buffer++;
- buflen--;
- }
- if( buflen < n )
- break;
-
- type = *buffer & 0x7f;
- if( type == reqtype ) {
- buffer++;
- buflen--;
- n--;
- if( n > buflen )
- break;
- buffer += n; /* point to next subpkt */
- buflen -= n;
- memmove (bufstart, buffer, buflen); /* shift */
- unused += buffer - bufstart;
- buffer = bufstart;
- }
- else {
- buffer += n; buflen -=n;
- }
- }
-
- if (!okay)
- log_error ("delete_subpkt: buffer shorter than subpacket\n");
- assert (unused <= area->len);
- area->len -= unused;
- return !!unused;
-}
-
-
-/****************
- * Create or update a signature subpacket for SIG of TYPE. This
- * functions knows where to put the data (hashed or unhashed). The
- * function may move data from the unhashed part to the hashed one.
- * Note: All pointers into sig->[un]hashed (e.g. returned by
- * parse_sig_subpkt) are not valid after a call to this function. The
- * data to put into the subpaket should be in a buffer with a length
- * of buflen.
- */
-void
-build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
- const byte *buffer, size_t buflen )
-{
- byte *p;
- int critical, hashed;
- subpktarea_t *oldarea, *newarea;
- size_t nlen, n, n0;
-
- critical = (type & SIGSUBPKT_FLAG_CRITICAL);
- type &= ~SIGSUBPKT_FLAG_CRITICAL;
-
- /* Sanity check buffer sizes */
- if(parse_one_sig_subpkt(buffer,buflen,type)<0)
- BUG();
-
- switch(type)
- {
- case SIGSUBPKT_NOTATION:
- case SIGSUBPKT_POLICY:
- case SIGSUBPKT_REV_KEY:
- /* we do allow multiple subpackets */
- break;
-
- default:
- /* we don't allow multiple subpackets */
- delete_sig_subpkt(sig->hashed,type);
- delete_sig_subpkt(sig->unhashed,type);
- break;
- }
-
- /* Any special magic that needs to be done for this type so the
- packet doesn't need to be reparsed? */
- switch(type)
- {
- case SIGSUBPKT_NOTATION:
- sig->flags.notation=1;
- break;
-
- case SIGSUBPKT_POLICY:
- sig->flags.policy_url=1;
- break;
-
- case SIGSUBPKT_PREF_KS:
- sig->flags.pref_ks=1;
- break;
-
- case SIGSUBPKT_EXPORTABLE:
- if(buffer[0])
- sig->flags.exportable=1;
- else
- sig->flags.exportable=0;
- break;
-
- case SIGSUBPKT_REVOCABLE:
- if(buffer[0])
- sig->flags.revocable=1;
- else
- sig->flags.revocable=0;
- break;
-
- case SIGSUBPKT_TRUST:
- sig->trust_depth=buffer[0];
- sig->trust_value=buffer[1];
- break;
-
- case SIGSUBPKT_REGEXP:
- sig->trust_regexp=buffer;
- break;
-
- /* This should never happen since we don't currently allow
- creating such a subpacket, but just in case... */
- case SIGSUBPKT_SIG_EXPIRE:
- if(buffer_to_u32(buffer)+sig->timestamp<=make_timestamp())
- sig->flags.expired=1;
- else
- sig->flags.expired=0;
- break;
-
- default:
- break;
- }
-
- if( (buflen+1) >= 8384 )
- nlen = 5; /* write 5 byte length header */
- else if( (buflen+1) >= 192 )
- nlen = 2; /* write 2 byte length header */
- else
- nlen = 1; /* just a 1 byte length header */
-
- switch( type ) {
- /* The issuer being unhashed is a historical oddity. It
- should work equally as well hashed. Of course, if even an
- unhashed issuer is tampered with, it makes it awfully hard
- to verify the sig... */
- case SIGSUBPKT_ISSUER:
- hashed = 0;
- break;
- default:
- hashed = 1;
- break;
- }
-
- if( critical )
- type |= SIGSUBPKT_FLAG_CRITICAL;
-
- oldarea = hashed? sig->hashed : sig->unhashed;
-
- /* Calculate new size of the area and allocate */
- n0 = oldarea? oldarea->len : 0;
- n = n0 + nlen + 1 + buflen; /* length, type, buffer */
- if (oldarea && n <= oldarea->size) { /* fits into the unused space */
- newarea = oldarea;
- /*log_debug ("updating area for type %d\n", type );*/
- }
- else if (oldarea) {
- newarea = xrealloc (oldarea, sizeof (*newarea) + n - 1);
- newarea->size = n;
- /*log_debug ("reallocating area for type %d\n", type );*/
- }
- else {
- newarea = xmalloc (sizeof (*newarea) + n - 1);
- newarea->size = n;
- /*log_debug ("allocating area for type %d\n", type );*/
- }
- newarea->len = n;
-
- p = newarea->data + n0;
- if (nlen == 5) {
- *p++ = 255;
- *p++ = (buflen+1) >> 24;
- *p++ = (buflen+1) >> 16;
- *p++ = (buflen+1) >> 8;
- *p++ = (buflen+1);
- *p++ = type;
- memcpy (p, buffer, buflen);
- }
- else if (nlen == 2) {
- *p++ = (buflen+1-192) / 256 + 192;
- *p++ = (buflen+1-192) % 256;
- *p++ = type;
- memcpy (p, buffer, buflen);
- }
- else {
- *p++ = buflen+1;
- *p++ = type;
- memcpy (p, buffer, buflen);
- }
-
- if (hashed)
- sig->hashed = newarea;
- else
- sig->unhashed = newarea;
-}
-
-/****************
- * Put all the required stuff from SIG into subpackets of sig.
- * Hmmm, should we delete those subpackets which are in a wrong area?
- */
-void
-build_sig_subpkt_from_sig( PKT_signature *sig )
-{
- u32 u;
- byte buf[8];
-
- u = sig->keyid[0];
- buf[0] = (u >> 24) & 0xff;
- buf[1] = (u >> 16) & 0xff;
- buf[2] = (u >> 8) & 0xff;
- buf[3] = u & 0xff;
- u = sig->keyid[1];
- buf[4] = (u >> 24) & 0xff;
- buf[5] = (u >> 16) & 0xff;
- buf[6] = (u >> 8) & 0xff;
- buf[7] = u & 0xff;
- build_sig_subpkt( sig, SIGSUBPKT_ISSUER, buf, 8 );
-
- u = sig->timestamp;
- buf[0] = (u >> 24) & 0xff;
- buf[1] = (u >> 16) & 0xff;
- buf[2] = (u >> 8) & 0xff;
- buf[3] = u & 0xff;
- build_sig_subpkt( sig, SIGSUBPKT_SIG_CREATED, buf, 4 );
-
- if(sig->expiredate)
- {
- if(sig->expiredate>sig->timestamp)
- u=sig->expiredate-sig->timestamp;
- else
- u=0;
-
- buf[0] = (u >> 24) & 0xff;
- buf[1] = (u >> 16) & 0xff;
- buf[2] = (u >> 8) & 0xff;
- buf[3] = u & 0xff;
-
- /* Mark this CRITICAL, so if any implementation doesn't
- understand sigs that can expire, it'll just disregard this
- sig altogether. */
-
- build_sig_subpkt( sig, SIGSUBPKT_SIG_EXPIRE | SIGSUBPKT_FLAG_CRITICAL,
- buf, 4 );
- }
-}
-
-void
-build_attribute_subpkt(PKT_user_id *uid,byte type,
- const void *buf,u32 buflen,
- const void *header,u32 headerlen)
-{
- byte *attrib;
- int idx;
-
- if(1+headerlen+buflen>8383)
- idx=5;
- else if(1+headerlen+buflen>191)
- idx=2;
- else
- idx=1;
-
- /* realloc uid->attrib_data to the right size */
-
- uid->attrib_data=xrealloc(uid->attrib_data,
- uid->attrib_len+idx+1+headerlen+buflen);
-
- attrib=&uid->attrib_data[uid->attrib_len];
-
- if(idx==5)
- {
- attrib[0]=255;
- attrib[1]=(1+headerlen+buflen) >> 24;
- attrib[2]=(1+headerlen+buflen) >> 16;
- attrib[3]=(1+headerlen+buflen) >> 8;
- attrib[4]=1+headerlen+buflen;
- }
- else if(idx==2)
- {
- attrib[0]=(1+headerlen+buflen-192) / 256 + 192;
- attrib[1]=(1+headerlen+buflen-192) % 256;
- }
- else
- attrib[0]=1+headerlen+buflen; /* Good luck finding a JPEG this small! */
-
- attrib[idx++]=type;
-
- /* Tack on our data at the end */
-
- if(headerlen>0)
- memcpy(&attrib[idx],header,headerlen);
- memcpy(&attrib[idx+headerlen],buf,buflen);
- uid->attrib_len+=idx+headerlen+buflen;
-}
-
-static int
-do_signature( iobuf_t out, int ctb, PKT_signature *sig )
-{
- int rc = 0;
- int n, i;
- iobuf_t a = iobuf_temp();
-
- if( !sig->version )
- iobuf_put( a, 3 );
- else
- iobuf_put( a, sig->version );
- if( sig->version < 4 )
- iobuf_put(a, 5 ); /* constant */
- iobuf_put(a, sig->sig_class );
- if( sig->version < 4 ) {
- write_32(a, sig->timestamp );
- write_32(a, sig->keyid[0] );
- write_32(a, sig->keyid[1] );
- }
- iobuf_put(a, sig->pubkey_algo );
- iobuf_put(a, sig->digest_algo );
- if( sig->version >= 4 ) {
- size_t nn;
- /* timestamp and keyid must have been packed into the
- * subpackets prior to the call of this function, because
- * these subpackets are hashed */
- nn = sig->hashed? sig->hashed->len : 0;
- write_16(a, nn);
- if( nn )
- iobuf_write( a, sig->hashed->data, nn );
- nn = sig->unhashed? sig->unhashed->len : 0;
- write_16(a, nn);
- if( nn )
- iobuf_write( a, sig->unhashed->data, nn );
- }
- iobuf_put(a, sig->digest_start[0] );
- iobuf_put(a, sig->digest_start[1] );
- n = pubkey_get_nsig( sig->pubkey_algo );
- if( !n )
- write_fake_data( a, sig->data[0] );
- for(i=0; i < n; i++ )
- mpi_write(a, sig->data[i] );
-
- if( is_RSA(sig->pubkey_algo) && sig->version < 4 )
- write_sign_packet_header(out, ctb, iobuf_get_temp_length(a) );
- else
- write_header(out, ctb, iobuf_get_temp_length(a) );
- rc = iobuf_write_temp (out, a);
-
- iobuf_close(a);
- return rc;
-}
-
-
-static int
-do_onepass_sig( iobuf_t out, int ctb, PKT_onepass_sig *ops )
-{
- int rc = 0;
- iobuf_t a = iobuf_temp();
-
- write_version( a, ctb );
- iobuf_put(a, ops->sig_class );
- iobuf_put(a, ops->digest_algo );
- iobuf_put(a, ops->pubkey_algo );
- write_32(a, ops->keyid[0] );
- write_32(a, ops->keyid[1] );
- iobuf_put(a, ops->last );
-
- write_header(out, ctb, iobuf_get_temp_length(a) );
- rc = iobuf_write_temp (out, a);
-
- iobuf_close(a);
- return rc;
-}
-
-
-static int
-write_16(iobuf_t out, u16 a)
-{
- iobuf_put(out, a>>8);
- return iobuf_put(out,a);
-}
-
-static int
-write_32(iobuf_t out, u32 a)
-{
- iobuf_put(out, a>> 24);
- iobuf_put(out, a>> 16);
- iobuf_put(out, a>> 8);
- return iobuf_put (out, a);
-}
-
-
-/****************
- * calculate the length of a header
- */
-static int
-calc_header_length( u32 len, int new_ctb )
-{
- if( !len )
- return 1; /* only the ctb */
-
- if( new_ctb ) {
- if( len < 192 )
- return 2;
- if( len < 8384 )
- return 3;
- else
- return 6;
- }
- if( len < 256 )
- return 2;
- if( len < 65536 )
- return 3;
-
- return 5;
-}
-
-/****************
- * Write the CTB and the packet length
- */
-static int
-write_header( iobuf_t out, int ctb, u32 len )
-{
- return write_header2( out, ctb, len, 0, 1 );
-}
-
-
-static int
-write_sign_packet_header( iobuf_t out, int ctb, u32 len )
-{
- /* work around a bug in the pgp read function for signature packets,
- * which are not correctly coded and silently assume at some
- * point 2 byte length headers.*/
- iobuf_put(out, 0x89 );
- iobuf_put(out, len >> 8 );
- return iobuf_put(out, len ) == -1 ? -1:0;
-}
-
-/****************
- * if HDRLEN is > 0, try to build a header of this length.
- * we need this, so that we can hash packets without reading them again.
- */
-static int
-write_header2( iobuf_t out, int ctb, u32 len, int hdrlen, int blkmode )
-{
- if( ctb & 0x40 )
- return write_new_header( out, ctb, len, hdrlen );
-
- if( hdrlen ) {
- if( !len )
- ctb |= 3;
- else if( hdrlen == 2 && len < 256 )
- ;
- else if( hdrlen == 3 && len < 65536 )
- ctb |= 1;
- else
- ctb |= 2;
- }
- else {
- if( !len )
- ctb |= 3;
- else if( len < 256 )
- ;
- else if( len < 65536 )
- ctb |= 1;
- else
- ctb |= 2;
- }
- if( iobuf_put(out, ctb ) )
- return -1;
- if( !len ) {
- if( blkmode )
- iobuf_set_block_mode(out, 8196 );
- }
- else {
- if( ctb & 2 ) {
- iobuf_put(out, len >> 24 );
- iobuf_put(out, len >> 16 );
- }
- if( ctb & 3 )
- iobuf_put(out, len >> 8 );
- if( iobuf_put(out, len ) )
- return -1;
- }
- return 0;
-}
-
-
-static int
-write_new_header( iobuf_t out, int ctb, u32 len, int hdrlen )
-{
- if( hdrlen )
- log_bug("can't cope with hdrlen yet\n");
-
- if( iobuf_put(out, ctb ) )
- return -1;
- if( !len ) {
- iobuf_set_partial_block_mode(out, 512 );
- }
- else {
- if( len < 192 ) {
- if( iobuf_put(out, len ) )
- return -1;
- }
- else if( len < 8384 ) {
- len -= 192;
- if( iobuf_put( out, (len / 256) + 192) )
- return -1;
- if( iobuf_put( out, (len % 256) ) )
- return -1;
- }
- else {
- if( iobuf_put( out, 0xff ) )
- return -1;
- if( iobuf_put( out, (len >> 24)&0xff ) )
- return -1;
- if( iobuf_put( out, (len >> 16)&0xff ) )
- return -1;
- if( iobuf_put( out, (len >> 8)&0xff ) )
- return -1;
- if( iobuf_put( out, len & 0xff ) )
- return -1;
- }
- }
- return 0;
-}
-
-static int
-write_version( iobuf_t out, int ctb )
-{
- if( iobuf_put( out, 3 ) )
- return -1;
- return 0;
-}
diff --git a/g10/call-agent.c b/g10/call-agent.c
deleted file mode 100644
index de157d491..000000000
--- a/g10/call-agent.c
+++ /dev/null
@@ -1,893 +0,0 @@
-/* call-agent.c - divert operations to the agent
- * Copyright (C) 2001, 2002, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#if 0 /* lety Emacs display a red warning */
-#error fixme: this shares a lof of code with the file in ../sm
-#endif
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-#ifdef HAVE_LOCALE_H
-#include <locale.h>
-#endif
-#include <assuan.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "membuf.h"
-#include "options.h"
-#include "i18n.h"
-#include "call-agent.h"
-
-#ifndef DBG_ASSUAN
-# define DBG_ASSUAN 1
-#endif
-
-static ASSUAN_CONTEXT agent_ctx = NULL;
-static int force_pipe_server = 1; /* FIXME: set this back to 0. */
-
-struct cipher_parm_s {
- ASSUAN_CONTEXT ctx;
- const char *ciphertext;
- size_t ciphertextlen;
-};
-
-struct genkey_parm_s {
- ASSUAN_CONTEXT ctx;
- const char *sexp;
- size_t sexplen;
-};
-
-
-
-/* Try to connect to the agent via socket or fork it off and work by
- pipes. Handle the server's initial greeting */
-static int
-start_agent (void)
-{
- int rc = 0;
- char *infostr, *p;
- ASSUAN_CONTEXT ctx;
- char *dft_display = NULL;
- char *dft_ttyname = NULL;
- char *dft_ttytype = NULL;
- char *old_lc = NULL;
- char *dft_lc = NULL;
-
- if (agent_ctx)
- return 0; /* fixme: We need a context for each thread or serialize
- the access to the agent. */
-
- infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO");
- if (!infostr || !*infostr)
- {
- const char *pgmname;
- const char *argv[3];
- int no_close_list[3];
- int i;
-
- if (opt.verbose)
- log_info (_("no running gpg-agent - starting one\n"));
-
- if (fflush (NULL))
- {
- gpg_error_t tmperr = gpg_error_from_errno (errno);
- log_error ("error flushing pending output: %s\n", strerror (errno));
- return tmperr;
- }
-
- if (!opt.agent_program || !*opt.agent_program)
- opt.agent_program = GNUPG_DEFAULT_AGENT;
- if ( !(pgmname = strrchr (opt.agent_program, '/')))
- pgmname = opt.agent_program;
- else
- pgmname++;
-
- argv[0] = pgmname;
- argv[1] = "--server";
- argv[2] = NULL;
-
- i=0;
- if (log_get_fd () != -1)
- no_close_list[i++] = log_get_fd ();
- no_close_list[i++] = fileno (stderr);
- no_close_list[i] = -1;
-
- /* connect to the agent and perform initial handshaking */
- rc = assuan_pipe_connect (&ctx, opt.agent_program, (char**)argv,
- no_close_list);
- }
- else
- {
- int prot;
- int pid;
-
- infostr = xstrdup (infostr);
- if ( !(p = strchr (infostr, ':')) || p == infostr)
- {
- log_error (_("malformed GPG_AGENT_INFO environment variable\n"));
- xfree (infostr);
- force_pipe_server = 1;
- return start_agent ();
- }
- *p++ = 0;
- pid = atoi (p);
- while (*p && *p != ':')
- p++;
- prot = *p? atoi (p+1) : 0;
- if (prot != 1)
- {
- log_error (_("gpg-agent protocol version %d is not supported\n"),
- prot);
- xfree (infostr);
- force_pipe_server = 1;
- return start_agent ();
- }
-
- rc = assuan_socket_connect (&ctx, infostr, pid);
- xfree (infostr);
- if (rc == ASSUAN_Connect_Failed)
- {
- log_error (_("can't connect to the agent - trying fall back\n"));
- force_pipe_server = 1;
- return start_agent ();
- }
- }
-
- if (rc)
- {
- log_error ("can't connect to the agent: %s\n", assuan_strerror (rc));
- return gpg_error (GPG_ERR_NO_AGENT);
- }
- agent_ctx = ctx;
-
- if (DBG_ASSUAN)
- log_debug ("connection to agent established\n");
-
- rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL);
- if (rc)
- return map_assuan_err (rc);
-
- dft_display = getenv ("DISPLAY");
- if (opt.display || dft_display)
- {
- char *optstr;
- if (asprintf (&optstr, "OPTION display=%s",
- opt.display ? opt.display : dft_display) < 0)
- return gpg_error_from_errno (errno);
- rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
- NULL);
- free (optstr);
- if (rc)
- return map_assuan_err (rc);
- }
- if (!opt.ttyname)
- {
- dft_ttyname = getenv ("GPG_TTY");
- if ((!dft_ttyname || !*dft_ttyname) && ttyname (0))
- dft_ttyname = ttyname (0);
- }
- if (opt.ttyname || dft_ttyname)
- {
- char *optstr;
- if (asprintf (&optstr, "OPTION ttyname=%s",
- opt.ttyname ? opt.ttyname : dft_ttyname) < 0)
- return gpg_error_from_errno (errno);
- rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
- NULL);
- free (optstr);
- if (rc)
- return map_assuan_err (rc);
- }
- dft_ttytype = getenv ("TERM");
- if (opt.ttytype || (dft_ttyname && dft_ttytype))
- {
- char *optstr;
- if (asprintf (&optstr, "OPTION ttytype=%s",
- opt.ttyname ? opt.ttytype : dft_ttytype) < 0)
- return gpg_error_from_errno (errno);
- rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
- NULL);
- free (optstr);
- if (rc)
- return map_assuan_err (rc);
- }
-#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE)
- old_lc = setlocale (LC_CTYPE, NULL);
- if (old_lc)
- {
- old_lc = strdup (old_lc);
- if (!old_lc)
- return gpg_error_from_errno (errno);
-
- }
- dft_lc = setlocale (LC_CTYPE, "");
-#endif
- if (opt.lc_ctype || (dft_ttyname && dft_lc))
- {
- char *optstr;
- if (asprintf (&optstr, "OPTION lc-ctype=%s",
- opt.lc_ctype ? opt.lc_ctype : dft_lc) < 0)
- rc = gpg_error_from_errno (errno);
- else
- {
- rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
- NULL);
- free (optstr);
- if (rc)
- rc = map_assuan_err (rc);
- }
- }
-#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE)
- if (old_lc)
- {
- setlocale (LC_CTYPE, old_lc);
- free (old_lc);
- }
-#endif
- if (rc)
- return rc;
-#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)
- old_lc = setlocale (LC_MESSAGES, NULL);
- if (old_lc)
- {
- old_lc = strdup (old_lc);
- if (!old_lc)
- return gpg_error_from_errno (errno);
- }
- dft_lc = setlocale (LC_MESSAGES, "");
-#endif
- if (opt.lc_messages || (dft_ttyname && dft_lc))
- {
- char *optstr;
- if (asprintf (&optstr, "OPTION lc-messages=%s",
- opt.lc_messages ? opt.lc_messages : dft_lc) < 0)
- rc = gpg_error_from_errno (errno);
- else
- {
- rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
- NULL);
- free (optstr);
- if (rc)
- rc = map_assuan_err (rc);
- }
- }
-#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)
- if (old_lc)
- {
- setlocale (LC_MESSAGES, old_lc);
- free (old_lc);
- }
-#endif
-
- return rc;
-}
-
-
-/* Return a new malloced string by unescaping the string S. Escaping
- is percent escaping and '+'/space mapping. A binary nul will
- silently be replaced by a 0xFF. Function returns NULL to indicate
- an out of memory status. */
-static char *
-unescape_status_string (const unsigned char *s)
-{
- char *buffer, *d;
-
- buffer = d = xtrymalloc (strlen (s)+1);
- if (!buffer)
- return NULL;
- while (*s)
- {
- if (*s == '%' && s[1] && s[2])
- {
- s++;
- *d = xtoi_2 (s);
- if (!*d)
- *d = '\xff';
- d++;
- s += 2;
- }
- else if (*s == '+')
- {
- *d++ = ' ';
- s++;
- }
- else
- *d++ = *s++;
- }
- *d = 0;
- return buffer;
-}
-
-/* Take a 20 byte hexencoded string and put it into the the provided
- 20 byte buffer FPR in binary format. */
-static int
-unhexify_fpr (const char *hexstr, unsigned char *fpr)
-{
- const char *s;
- int n;
-
- for (s=hexstr, n=0; hexdigitp (s); s++, n++)
- ;
- if (*s || (n != 40))
- return 0; /* no fingerprint (invalid or wrong length). */
- n /= 2;
- for (s=hexstr, n=0; *s; s += 2, n++)
- fpr[n] = xtoi_2 (s);
- return 1; /* okay */
-}
-
-/* Take the serial number from LINE and return it verbatim in a newly
- allocated string. We make sure that only hex characters are
- returned. */
-static char *
-store_serialno (const char *line)
-{
- const char *s;
- char *p;
-
- for (s=line; hexdigitp (s); s++)
- ;
- p = xtrymalloc (s + 1 - line);
- if (p)
- {
- memcpy (p, line, s-line);
- p[s-line] = 0;
- }
- return p;
-}
-
-
-
-#if 0
-/* Handle a KEYPARMS inquiry. Note, we only send the data,
- assuan_transact takes care of flushing and writing the end */
-static AssuanError
-inq_genkey_parms (void *opaque, const char *keyword)
-{
- struct genkey_parm_s *parm = opaque;
- AssuanError rc;
-
- rc = assuan_send_data (parm->ctx, parm->sexp, parm->sexplen);
- return rc;
-}
-
-
-
-/* Call the agent to generate a new key */
-int
-agent_genkey (KsbaConstSexp keyparms, KsbaSexp *r_pubkey)
-{
- int rc;
- struct genkey_parm_s gk_parm;
- membuf_t data;
- size_t len;
- char *buf;
-
- *r_pubkey = NULL;
- rc = start_agent ();
- if (rc)
- return rc;
-
- rc = assuan_transact (agent_ctx, "RESET", NULL, NULL,
- NULL, NULL, NULL, NULL);
- if (rc)
- return map_assuan_err (rc);
-
- init_membuf (&data, 1024);
- gk_parm.ctx = agent_ctx;
- gk_parm.sexp = keyparms;
- gk_parm.sexplen = gcry_sexp_canon_len (keyparms, 0, NULL, NULL);
- if (!gk_parm.sexplen)
- return gpg_error (GPG_ERR_INV_VALUE);
- rc = assuan_transact (agent_ctx, "GENKEY",
- membuf_data_cb, &data,
- inq_genkey_parms, &gk_parm, NULL, NULL);
- if (rc)
- {
- xfree (get_membuf (&data, &len));
- return map_assuan_err (rc);
- }
- buf = get_membuf (&data, &len);
- if (!buf)
- return gpg_error (GPG_ERR_ENOMEM);
- if (!gcry_sexp_canon_len (buf, len, NULL, NULL))
- {
- xfree (buf);
- return gpg_error (GPG_ERR_INV_SEXP);
- }
- *r_pubkey = buf;
- return 0;
-}
-#endif /*0*/
-
-
-
-/* Ask the agent whether the corresponding secret key is available for
- the given keygrip. */
-int
-agent_havekey (const char *hexkeygrip)
-{
- int rc;
- char line[ASSUAN_LINELENGTH];
-
- rc = start_agent ();
- if (rc)
- return rc;
-
- if (!hexkeygrip || strlen (hexkeygrip) != 40)
- return gpg_error (GPG_ERR_INV_VALUE);
-
- snprintf (line, DIM(line)-1, "HAVEKEY %s", hexkeygrip);
- line[DIM(line)-1] = 0;
-
- rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
- return map_assuan_err (rc);
-}
-
-
-/* Release the card info structure INFO. */
-void
-agent_release_card_info (struct agent_card_info_s *info)
-{
- if (!info)
- return;
-
- xfree (info->serialno); info->serialno = NULL;
- xfree (info->disp_name); info->disp_name = NULL;
- xfree (info->disp_lang); info->disp_lang = NULL;
- xfree (info->pubkey_url); info->pubkey_url = NULL;
- xfree (info->login_data); info->login_data = NULL;
- info->fpr1valid = info->fpr2valid = info->fpr3valid = 0;
-}
-
-static AssuanError
-learn_status_cb (void *opaque, const char *line)
-{
- struct agent_card_info_s *parm = opaque;
- const char *keyword = line;
- int keywordlen;
- int i;
-
- for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
- ;
- while (spacep (line))
- line++;
-
- if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
- {
- xfree (parm->serialno);
- parm->serialno = store_serialno (line);
- }
- else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
- {
- xfree (parm->disp_name);
- parm->disp_name = unescape_status_string (line);
- }
- else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
- {
- xfree (parm->disp_lang);
- parm->disp_lang = unescape_status_string (line);
- }
- else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
- {
- parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0;
- }
- else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
- {
- xfree (parm->pubkey_url);
- parm->pubkey_url = unescape_status_string (line);
- }
- else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
- {
- xfree (parm->login_data);
- parm->login_data = unescape_status_string (line);
- }
- else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
- {
- parm->sig_counter = strtoul (line, NULL, 0);
- }
- else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen))
- {
- char *p, *buf;
-
- buf = p = unescape_status_string (line);
- if (buf)
- {
- while (spacep (p))
- p++;
- parm->chv1_cached = atoi (p);
- while (*p && !spacep (p))
- p++;
- while (spacep (p))
- p++;
- for (i=0; *p && i < 3; i++)
- {
- parm->chvmaxlen[i] = atoi (p);
- while (*p && !spacep (p))
- p++;
- while (spacep (p))
- p++;
- }
- for (i=0; *p && i < 3; i++)
- {
- parm->chvretry[i] = atoi (p);
- while (*p && !spacep (p))
- p++;
- while (spacep (p))
- p++;
- }
- xfree (buf);
- }
- }
- else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
- {
- int no = atoi (line);
- while (*line && !spacep (line))
- line++;
- while (spacep (line))
- line++;
- if (no == 1)
- parm->fpr1valid = unhexify_fpr (line, parm->fpr1);
- else if (no == 2)
- parm->fpr2valid = unhexify_fpr (line, parm->fpr2);
- else if (no == 3)
- parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
- }
-
- return 0;
-}
-
-/* Call the agent to learn about a smartcard */
-int
-agent_learn (struct agent_card_info_s *info)
-{
- int rc;
-
- rc = start_agent ();
- if (rc)
- return rc;
-
- memset (info, 0, sizeof *info);
- rc = assuan_transact (agent_ctx, "LEARN --send",
- NULL, NULL, NULL, NULL,
- learn_status_cb, info);
-
- return map_assuan_err (rc);
-}
-
-/* Call the agent to retrieve a data object. This function returns
- the data in the same structure as used by the learn command. It is
- allowed to update such a structure using this commmand. */
-int
-agent_scd_getattr (const char *name, struct agent_card_info_s *info)
-{
- int rc;
- char line[ASSUAN_LINELENGTH];
-
- if (!*name)
- return gpg_error (GPG_ERR_INV_VALUE);
-
- /* We assume that NAME does not need escaping. */
- if (12 + strlen (name) > DIM(line)-1)
- return gpg_error (GPG_ERR_TOO_LARGE);
- stpcpy (stpcpy (line, "SCD GETATTR "), name);
-
- rc = start_agent ();
- if (rc)
- return rc;
-
- rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL,
- learn_status_cb, info);
-
- return map_assuan_err (rc);
-}
-
-
-/* Send an setattr command to the SCdaemon. */
-int
-agent_scd_setattr (const char *name,
- const unsigned char *value, size_t valuelen)
-{
- int rc;
- char line[ASSUAN_LINELENGTH];
- char *p;
-
- if (!*name || !valuelen)
- return gpg_error (GPG_ERR_INV_VALUE);
-
- /* We assume that NAME does not need escaping. */
- if (12 + strlen (name) > DIM(line)-1)
- return gpg_error (GPG_ERR_TOO_LARGE);
-
- p = stpcpy (stpcpy (line, "SCD SETATTR "), name);
- *p++ = ' ';
- for (; valuelen; value++, valuelen--)
- {
- if (p >= line + DIM(line)-5 )
- return gpg_error (GPG_ERR_TOO_LARGE);
- if (*value < ' ' || *value == '+' || *value == '%')
- {
- sprintf (p, "%%%02X", *value);
- p += 3;
- }
- else if (*value == ' ')
- *p++ = '+';
- else
- *p++ = *value;
- }
- *p = 0;
-
- rc = start_agent ();
- if (rc)
- return rc;
-
- rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
- return map_assuan_err (rc);
-}
-
-
-/* Status callback for the SCD GENKEY command. */
-static AssuanError
-scd_genkey_cb (void *opaque, const char *line)
-{
- struct agent_card_genkey_s *parm = opaque;
- const char *keyword = line;
- int keywordlen;
- gpg_error_t rc;
-
- log_debug ("got status line `%s'\n", line);
- for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
- ;
- while (spacep (line))
- line++;
-
- if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
- {
- parm->fprvalid = unhexify_fpr (line, parm->fpr);
- }
- if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
- {
- gcry_mpi_t a;
- const char *name = line;
-
- while (*line && !spacep (line))
- line++;
- while (spacep (line))
- line++;
-
- rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
- if (rc)
- log_error ("error parsing received key data: %s\n", gpg_strerror (rc));
- else if (*name == 'n' && spacep (name+1))
- parm->n = a;
- else if (*name == 'e' && spacep (name+1))
- parm->e = a;
- else
- {
- log_info ("unknown parameter name in received key data\n");
- gcry_mpi_release (a);
- }
- }
- else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
- {
- parm->created_at = (u32)strtoul (line, NULL, 10);
- }
-
- return 0;
-}
-
-/* Send a GENKEY command to the SCdaemon. */
-int
-agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force)
-{
- int rc;
- char line[ASSUAN_LINELENGTH];
-
- rc = start_agent ();
- if (rc)
- return rc;
-
- memset (info, 0, sizeof *info);
- snprintf (line, DIM(line)-1, "SCD GENKEY %s%d",
- force? "--force ":"", keyno);
- line[DIM(line)-1] = 0;
-
- memset (info, 0, sizeof *info);
- rc = assuan_transact (agent_ctx, line,
- NULL, NULL, NULL, NULL,
- scd_genkey_cb, info);
-
- return map_assuan_err (rc);
-}
-
-
-static AssuanError
-membuf_data_cb (void *opaque, const void *buffer, size_t length)
-{
- membuf_t *data = opaque;
-
- if (buffer)
- put_membuf (data, buffer, length);
- return 0;
-}
-
-/* Send a sign command to the scdaemon via gpg-agent's pass thru
- mechanism. */
-int
-agent_scd_pksign (const char *serialno, int hashalgo,
- const unsigned char *indata, size_t indatalen,
- char **r_buf, size_t *r_buflen)
-{
- int rc, i;
- char *p, line[ASSUAN_LINELENGTH];
- membuf_t data;
- size_t len;
-
- /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
-
- *r_buf = NULL;
- *r_buflen = 0;
-
- rc = start_agent ();
- if (rc)
- return rc;
-
- if (indatalen*2 + 50 > DIM(line))
- return gpg_error (GPG_ERR_GENERAL);
-
- sprintf (line, "SCD SETDATA ");
- p = line + strlen (line);
- for (i=0; i < indatalen ; i++, p += 2 )
- sprintf (p, "%02X", indata[i]);
- rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
- if (rc)
- return map_assuan_err (rc);
-
- init_membuf (&data, 1024);
-#if 0
- if (!hashalgo) /* Temporary test hack. */
- snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno);
- else
-#endif
- snprintf (line, DIM(line)-1, "SCD PKSIGN %s", serialno);
- line[DIM(line)-1] = 0;
- rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data,
- NULL, NULL, NULL, NULL);
- if (rc)
- {
- xfree (get_membuf (&data, &len));
- return map_assuan_err (rc);
- }
- *r_buf = get_membuf (&data, r_buflen);
-
- return 0;
-}
-
-
-/* Decrypt INDATA of length INDATALEN using the card identified by
- SERIALNO. Return the plaintext in a nwly allocated buffer stored
- at the address of R_BUF.
-
- Note, we currently support only RSA or more exactly algorithms
- taking one input data element. */
-int
-agent_scd_pkdecrypt (const char *serialno,
- const unsigned char *indata, size_t indatalen,
- char **r_buf, size_t *r_buflen)
-{
- int rc, i;
- char *p, line[ASSUAN_LINELENGTH];
- membuf_t data;
- size_t len;
-
- *r_buf = NULL;
- rc = start_agent ();
- if (rc)
- return rc;
-
- /* FIXME: use secure memory where appropriate */
- if (indatalen*2 + 50 > DIM(line))
- return gpg_error (GPG_ERR_GENERAL);
-
- sprintf (line, "SCD SETDATA ");
- p = line + strlen (line);
- for (i=0; i < indatalen ; i++, p += 2 )
- sprintf (p, "%02X", indata[i]);
- rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
- if (rc)
- return map_assuan_err (rc);
-
- init_membuf (&data, 1024);
- snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno);
- line[DIM(line)-1] = 0;
- rc = assuan_transact (agent_ctx, line,
- membuf_data_cb, &data,
- NULL, NULL, NULL, NULL);
- if (rc)
- {
- xfree (get_membuf (&data, &len));
- return map_assuan_err (rc);
- }
- *r_buf = get_membuf (&data, r_buflen);
- if (!*r_buf)
- return gpg_error (GPG_ERR_ENOMEM);
-
- return 0;
-}
-
-
-/* Change the PIN of an OpenPGP card or reset the retry counter.
- CHVNO 1: Change the PIN
- 2: Same as 1
- 3: Change the admin PIN
- 101: Set a new PIN and reset the retry counter
- 102: Same as 101
- */
-int
-agent_scd_change_pin (int chvno)
-{
- int rc;
- char line[ASSUAN_LINELENGTH];
- const char *reset = "";
-
- if (chvno >= 100)
- reset = "--reset";
- chvno %= 100;
-
- rc = start_agent ();
- if (rc)
- return rc;
-
- snprintf (line, DIM(line)-1, "SCD PASSWD %s %d", reset, chvno);
- line[DIM(line)-1] = 0;
- rc = assuan_transact (agent_ctx, line, NULL, NULL,
- NULL, NULL, NULL, NULL);
- return map_assuan_err (rc);
-}
-
-
-/* Perform a CHECKPIN operation. SERIALNO should be the serial
- number of the card - optioanlly followed by the fingerprint;
- however the fingerprint is ignored here. */
-int
-agent_scd_checkpin (const char *serialno)
-{
- int rc;
- char line[ASSUAN_LINELENGTH];
-
- rc = start_agent ();
- if (rc)
- return rc;
-
- snprintf (line, DIM(line)-1, "SCD CHECKPIN %s", serialno);
- line[DIM(line)-1] = 0;
- return assuan_transact (agent_ctx, line,
- NULL, NULL,
- NULL, NULL, NULL, NULL);
-}
-
-
diff --git a/g10/call-agent.h b/g10/call-agent.h
deleted file mode 100644
index 875110118..000000000
--- a/g10/call-agent.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* call-agent.h - Divert operations to the agent
- * Copyright (C) 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef GNUPG_G10_CALL_AGENT_H
-#define GNUPG_G10_CALL_AGENT_H
-
-
-struct agent_card_info_s {
- int error; /* private. */
- char *serialno; /* malloced hex string. */
- char *disp_name; /* malloced. */
- char *disp_lang; /* malloced. */
- int disp_sex; /* 0 = unspecified, 1 = male, 2 = female */
- char *pubkey_url; /* malloced. */
- char *login_data; /* malloced. */
- char fpr1valid;
- char fpr2valid;
- char fpr3valid;
- char fpr1[20];
- char fpr2[20];
- char fpr3[20];
- unsigned long sig_counter;
- int chv1_cached; /* True if a PIN is not required for each
- signing. Note that the gpg-agent might cache
- it anyway. */
- int chvmaxlen[3]; /* Maximum allowed length of a CHV. */
- int chvretry[3]; /* Allowed retries for the CHV; 0 = blocked. */
-};
-
-struct agent_card_genkey_s {
- char fprvalid;
- char fpr[20];
- u32 created_at;
- gcry_mpi_t n;
- gcry_mpi_t e;
-};
-
-
-/* Release the card info structure. */
-void agent_release_card_info (struct agent_card_info_s *info);
-
-/* Return card info. */
-int agent_learn (struct agent_card_info_s *info);
-
-/* Update INFO with the attribute NAME. */
-int agent_scd_getattr (const char *name, struct agent_card_info_s *info);
-
-/* Check whether the secret key for the key identified by HEXKEYGRIP
- is available. Return 0 for yes or an error code. */
-int agent_havekey (const char *hexkeygrip);
-
-/* Send a SETATTR command to the SCdaemon. */
-int agent_scd_setattr (const char *name,
- const unsigned char *value, size_t valuelen);
-
-/* Send a GENKEY command to the SCdaemon. */
-int agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force);
-
-/* Send a PKSIGN command to the SCdaemon. */
-int agent_scd_pksign (const char *keyid, int hashalgo,
- const unsigned char *indata, size_t indatalen,
- char **r_buf, size_t *r_buflen);
-
-/* Send a PKDECRYPT command to the SCdaemon. */
-int agent_scd_pkdecrypt (const char *serialno,
- const unsigned char *indata, size_t indatalen,
- char **r_buf, size_t *r_buflen);
-
-/* Change the PIN of an OpenPGP card or reset the retry counter. */
-int agent_scd_change_pin (int chvno);
-
-/* Send the CHECKPIN command to the SCdaemon. */
-int agent_scd_checkpin (const char *serialno);
-
-
-
-#endif /*GNUPG_G10_CALL_AGENT_H*/
-
diff --git a/g10/card-util.c b/g10/card-util.c
deleted file mode 100644
index c93d028bd..000000000
--- a/g10/card-util.c
+++ /dev/null
@@ -1,884 +0,0 @@
-/* card-util.c - Utility functions for the OpenPGP card.
- * Copyright (C) 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#if GNUPG_MAJOR_VERSION != 1
-#include "gpg.h"
-#endif
-#include "util.h"
-#include "i18n.h"
-#include "ttyio.h"
-#include "status.h"
-#include "options.h"
-#include "main.h"
-#if GNUPG_MAJOR_VERSION == 1
-#include "cardglue.h"
-#else
-#include "call-agent.h"
-#endif
-
-#define CONTROL_D ('D' - 'A' + 1)
-
-
-/* Change the PIN of a an OpenPGP card. This is an interactive
- function. */
-void
-change_pin (int chvno)
-{
- struct agent_card_info_s info;
- int rc;
-
- rc = agent_learn (&info);
- if (rc)
- {
- log_error (_("OpenPGP card not available: %s\n"),
- gpg_strerror (rc));
- return;
- }
-
- log_info (_("OpenPGP card no. %s detected\n"),
- info.serialno? info.serialno : "[none]");
-
- agent_release_card_info (&info);
-
- if (opt.batch)
- {
- log_error (_("sorry, can't do this in batch mode\n"));
- return;
- }
-
- for (;;)
- {
- char *answer;
-
- tty_printf ("\n");
- tty_printf ("1 - change PIN\n"
- "2 - unblock PIN\n"
- "3 - change Admin PIN\n"
- "Q - quit\n");
- tty_printf ("\n");
-
- answer = cpr_get("cardutil.change_pin.menu",_("Your selection? "));
- cpr_kill_prompt();
- if (strlen (answer) != 1)
- continue;
-
- rc = 0;
- if (*answer == '1')
- {
- rc = agent_scd_change_pin (1);
- if (rc)
- tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
- else
- tty_printf ("PIN changed.\n");
- }
- else if (*answer == '2')
- {
- rc = agent_scd_change_pin (101);
- if (rc)
- tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc));
- else
- tty_printf ("PIN unblocked and new PIN set.\n");
- }
- else if (*answer == '3')
- {
- rc = agent_scd_change_pin (3);
- if (rc)
- tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
- else
- tty_printf ("PIN changed.\n");
- }
- else if (*answer == 'q' || *answer == 'Q')
- {
- break;
- }
- }
-}
-
-static const char *
-get_manufacturer (unsigned int no)
-{
- /* Note: Make sure that there is no colon or linefeed in the string. */
- switch (no)
- {
- case 0:
- case 0xffff: return "test card";
- case 0x0001: return "PPC Card Systems";
- default: return "unknown";
- }
-}
-
-
-static void
-print_sha1_fpr (FILE *fp, const unsigned char *fpr)
-{
- int i;
-
- if (fpr)
- {
- for (i=0; i < 20 ; i+=2, fpr += 2 )
- {
- if (i == 10 )
- tty_fprintf (fp, " ");
- tty_fprintf (fp, " %02X%02X", *fpr, fpr[1]);
- }
- }
- else
- tty_fprintf (fp, " [none]");
- tty_fprintf (fp, "\n");
-}
-
-
-static void
-print_sha1_fpr_colon (FILE *fp, const unsigned char *fpr)
-{
- int i;
-
- if (fpr)
- {
- for (i=0; i < 20 ; i++, fpr++)
- fprintf (fp, "%02X", *fpr);
- }
- putc (':', fp);
-}
-
-
-static void
-print_name (FILE *fp, const char *text, const char *name)
-{
- tty_fprintf (fp, "%s", text);
-
- /* FIXME: tty_printf_utf8_string2 eats everything after and
- including an @ - e.g. when printing an url. */
- if (name && *name)
- {
- if (fp)
- print_utf8_string2 (fp, name, strlen (name), '\n');
- else
- tty_print_utf8_string2 (name, strlen (name), 0);
- }
- else
- tty_fprintf (fp, _("[not set]"));
- tty_fprintf (fp, "\n");
-}
-
-static void
-print_isoname (FILE *fp, const char *text, const char *tag, const char *name)
-{
- if (opt.with_colons)
- fprintf (fp, "%s:", tag);
- else
- tty_fprintf (fp, "%s", text);
-
- if (name && *name)
- {
- char *p, *given, *buf = xstrdup (name);
-
- given = strstr (buf, "<<");
- for (p=buf; *p; p++)
- if (*p == '<')
- *p = ' ';
- if (given && given[2])
- {
- *given = 0;
- given += 2;
- if (opt.with_colons)
- print_string (fp, given, strlen (given), ':');
- else if (fp)
- print_utf8_string2 (fp, given, strlen (given), '\n');
- else
- tty_print_utf8_string2 (given, strlen (given), 0);
-
- if (opt.with_colons)
- putc (':', fp);
- else if (*buf)
- tty_fprintf (fp, " ");
- }
-
- if (opt.with_colons)
- print_string (fp, buf, strlen (buf), ':');
- else if (fp)
- print_utf8_string2 (fp, buf, strlen (buf), '\n');
- else
- tty_print_utf8_string2 (buf, strlen (buf), 0);
- xfree (buf);
- }
- else
- {
- if (opt.with_colons)
- putc (':', fp);
- else
- tty_fprintf (fp, _("[not set]"));
- }
-
- if (opt.with_colons)
- fputs (":\n", fp);
- else
- tty_fprintf (fp, "\n");
-}
-
-/* Return true if the SHA1 fingerprint FPR consists only of zeroes. */
-static int
-fpr_is_zero (const char *fpr)
-{
- int i;
-
- for (i=0; i < 20 && !fpr[i]; i++)
- ;
- return (i == 20);
-}
-
-
-/* Print all available information about the current card. */
-void
-card_status (FILE *fp, char *serialno, size_t serialnobuflen)
-{
- struct agent_card_info_s info;
- PKT_public_key *pk = xcalloc (1, sizeof *pk);
- int rc;
- unsigned int uval;
-
- if (serialno && serialnobuflen)
- *serialno = 0;
-
- rc = agent_learn (&info);
- if (rc)
- {
- if (opt.with_colons)
- fputs ("AID:::\n", fp);
- log_error (_("OpenPGP card not available: %s\n"),
- gpg_strerror (rc));
- xfree (pk);
- return;
- }
-
- if (opt.with_colons)
- fprintf (fp, "AID:%s:", info.serialno? info.serialno : "");
- else
- tty_fprintf (fp, "Application ID ...: %s\n",
- info.serialno? info.serialno : "[none]");
- if (!info.serialno || strncmp (info.serialno, "D27600012401", 12)
- || strlen (info.serialno) != 32 )
- {
- if (opt.with_colons)
- fputs ("unknown:\n", fp);
- log_info ("not an OpenPGP card\n");
- agent_release_card_info (&info);
- xfree (pk);
- return;
- }
-
- if (!serialno)
- ;
- else if (strlen (serialno)+1 > serialnobuflen)
- log_error ("serial number longer than expected\n");
- else
- strcpy (serialno, info.serialno);
-
- if (opt.with_colons)
- fputs ("openpgp-card:\n", fp);
-
-
- if (opt.with_colons)
- {
- fprintf (fp, "version:%.4s:\n", info.serialno+12);
- uval = xtoi_2(info.serialno+16)*256 + xtoi_2 (info.serialno+18);
- fprintf (fp, "vendor:%04x:%s:\n", uval, get_manufacturer (uval));
- fprintf (fp, "serial:%.8s:\n", info.serialno+20);
-
- print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
-
- fputs ("lang:", fp);
- if (info.disp_lang)
- print_string (fp, info.disp_lang, strlen (info.disp_lang), ':');
- fputs (":\n", fp);
-
- fprintf (fp, "sex:%c:\n", (info.disp_sex == 1? 'm':
- info.disp_sex == 2? 'f' : 'u'));
-
- fputs ("url:", fp);
- if (info.pubkey_url)
- print_string (fp, info.pubkey_url, strlen (info.pubkey_url), ':');
- fputs (":\n", fp);
-
- fputs ("login:", fp);
- if (info.login_data)
- print_string (fp, info.login_data, strlen (info.login_data), ':');
- fputs (":\n", fp);
-
- fprintf (fp, "forcepin:%d:::\n", !info.chv1_cached);
- fprintf (fp, "maxpinlen:%d:%d:%d:\n",
- info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
- fprintf (fp, "pinretry:%d:%d:%d:\n",
- info.chvretry[0], info.chvretry[1], info.chvretry[2]);
- fprintf (fp, "sigcount:%lu:::\n", info.sig_counter);
-
- fputs ("fpr:", fp);
- print_sha1_fpr_colon (fp, info.fpr1valid? info.fpr1:NULL);
- print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2:NULL);
- print_sha1_fpr_colon (fp, info.fpr3valid? info.fpr3:NULL);
- putc ('\n', fp);
-
- }
- else
- {
- tty_fprintf (fp, "Version ..........: %.1s%c.%.1s%c\n",
- info.serialno[12] == '0'?"":info.serialno+12,
- info.serialno[13],
- info.serialno[14] == '0'?"":info.serialno+14,
- info.serialno[15]);
- tty_fprintf (fp, "Manufacturer .....: %s\n",
- get_manufacturer (xtoi_2(info.serialno+16)*256
- + xtoi_2 (info.serialno+18)));
- tty_fprintf (fp, "Serial number ....: %.8s\n", info.serialno+20);
-
- print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
- print_name (fp, "Language prefs ...: ", info.disp_lang);
- tty_fprintf (fp, "Sex ..............: %s\n",
- info.disp_sex == 1? _("male"):
- info.disp_sex == 2? _("female") : _("unspecified"));
- print_name (fp, "URL of public key : ", info.pubkey_url);
- print_name (fp, "Login data .......: ", info.login_data);
- tty_fprintf (fp, "Signature PIN ....: %s\n",
- info.chv1_cached? _("not forced"): _("forced"));
- tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n",
- info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
- tty_fprintf (fp, "PIN retry counter : %d %d %d\n",
- info.chvretry[0], info.chvretry[1], info.chvretry[2]);
- tty_fprintf (fp, "Signature counter : %lu\n", info.sig_counter);
- tty_fprintf (fp, "Signature key ....:");
- print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL);
- tty_fprintf (fp, "Encryption key....:");
- print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL);
- tty_fprintf (fp, "Authentication key:");
- print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL);
- tty_fprintf (fp, "General key info..: ");
- if (info.fpr1valid && !get_pubkey_byfprint (pk, info.fpr1, 20))
- print_pubkey_info (fp, pk);
- else
- tty_fprintf (fp, "[none]\n");
- }
-
- free_public_key (pk);
- agent_release_card_info (&info);
-}
-
-
-static char *
-get_one_name (const char *prompt1, const char *prompt2)
-{
- char *name;
- int i;
-
- for (;;)
- {
- name = cpr_get (prompt1, prompt2);
- if (!name)
- return NULL;
- trim_spaces (name);
- cpr_kill_prompt ();
- for (i=0; name[i] && name[i] >= ' ' && name[i] <= 126; i++)
- ;
-
- /* The name must be in Latin-1 and not UTF-8 - lacking the code
- to ensure this we restrict it to ASCII. */
- if (name[i])
- tty_printf (_("Error: Only plain ASCII is currently allowed.\n"));
- else if (strchr (name, '<'))
- tty_printf (_("Error: The \"<\" character may not be used.\n"));
- else if (strstr (name, " "))
- tty_printf (_("Error: Double spaces are not allowed.\n"));
- else
- return name;
- xfree (name);
- }
-}
-
-
-
-static int
-change_name (void)
-{
- char *surname = NULL, *givenname = NULL;
- char *isoname, *p;
- int rc;
-
- surname = get_one_name ("keygen.smartcard.surname",
- _("Cardholder's surname: "));
- givenname = get_one_name ("keygen.smartcard.givenname",
- _("Cardholder's given name: "));
- if (!surname || !givenname || (!*surname && !*givenname))
- {
- xfree (surname);
- xfree (givenname);
- return -1; /*canceled*/
- }
-
- isoname = xmalloc ( strlen (surname) + 2 + strlen (givenname) + 1);
- strcpy (stpcpy (stpcpy (isoname, surname), "<<"), givenname);
- xfree (surname);
- xfree (givenname);
- for (p=isoname; *p; p++)
- if (*p == ' ')
- *p = '<';
-
- if (strlen (isoname) > 39 )
- {
- tty_printf (_("Error: Combined name too long "
- "(limit is %d characters).\n"), 39);
- xfree (isoname);
- return -1;
- }
-
- log_debug ("setting Name to `%s'\n", isoname);
- rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname) );
- if (rc)
- log_error ("error setting Name: %s\n", gpg_strerror (rc));
-
- xfree (isoname);
- return rc;
-}
-
-
-static int
-change_url (void)
-{
- char *url;
- int rc;
-
- url = cpr_get ("cardedit.change_url", _("URL to retrieve public key: "));
- if (!url)
- return -1;
- trim_spaces (url);
- cpr_kill_prompt ();
-
- if (strlen (url) > 254 )
- {
- tty_printf (_("Error: URL too long "
- "(limit is %d characters).\n"), 254);
- xfree (url);
- return -1;
- }
-
- rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url) );
- if (rc)
- log_error ("error setting URL: %s\n", gpg_strerror (rc));
- xfree (url);
- return rc;
-}
-
-static int
-change_login (void)
-{
- char *data;
- int rc;
-
- data = cpr_get ("cardedit.change_login",
- _("Login data (account name): "));
- if (!data)
- return -1;
- trim_spaces (data);
- cpr_kill_prompt ();
-
- if (strlen (data) > 254 )
- {
- tty_printf (_("Error: Login data too long "
- "(limit is %d characters).\n"), 254);
- xfree (data);
- return -1;
- }
-
- rc = agent_scd_setattr ("LOGIN-DATA", data, strlen (data) );
- if (rc)
- log_error ("error setting login data: %s\n", gpg_strerror (rc));
- xfree (data);
- return rc;
-}
-
-static int
-change_lang (void)
-{
- char *data, *p;
- int rc;
-
- data = cpr_get ("cardedit.change_lang",
- _("Language preferences: "));
- if (!data)
- return -1;
- trim_spaces (data);
- cpr_kill_prompt ();
-
- if (strlen (data) > 8 || (strlen (data) & 1))
- {
- tty_printf (_("Error: invalid length of preference string.\n"));
- xfree (data);
- return -1;
- }
-
- for (p=data; *p && *p >= 'a' && *p <= 'z'; p++)
- ;
- if (*p)
- {
- tty_printf (_("Error: invalid characters in preference string.\n"));
- xfree (data);
- return -1;
- }
-
- rc = agent_scd_setattr ("DISP-LANG", data, strlen (data) );
- if (rc)
- log_error ("error setting lang: %s\n", gpg_strerror (rc));
- xfree (data);
- return rc;
-}
-
-
-static int
-change_sex (void)
-{
- char *data;
- const char *str;
- int rc;
-
- data = cpr_get ("cardedit.change_sex",
- _("Sex ((M)ale, (F)emale or space): "));
- if (!data)
- return -1;
- trim_spaces (data);
- cpr_kill_prompt ();
-
- if (!*data)
- str = "9";
- else if ((*data == 'M' || *data == 'm') && !data[1])
- str = "1";
- else if ((*data == 'F' || *data == 'f') && !data[1])
- str = "2";
- else
- {
- tty_printf (_("Error: invalid response.\n"));
- xfree (data);
- return -1;
- }
-
- rc = agent_scd_setattr ("DISP-SEX", str, 1 );
- if (rc)
- log_error ("error setting sex: %s\n", gpg_strerror (rc));
- xfree (data);
- return rc;
-}
-
-
-static void
-toggle_forcesig (void)
-{
- struct agent_card_info_s info;
- int rc;
- int newstate;
-
- memset (&info, 0, sizeof info);
- rc = agent_scd_getattr ("CHV-STATUS", &info);
- if (rc)
- {
- log_error ("error getting current status: %s\n", gpg_strerror (rc));
- return;
- }
- newstate = !info.chv1_cached;
- agent_release_card_info (&info);
-
- rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1);
- if (rc)
- log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (rc));
-}
-
-
-static void
-generate_card_keys (const char *serialno)
-{
- struct agent_card_info_s info;
- int rc;
- int forced_chv1;
-
- memset (&info, 0, sizeof info);
- rc = agent_scd_getattr ("KEY-FPR", &info);
- if (!rc)
- rc = agent_scd_getattr ("SERIALNO", &info);
- if (!rc)
- rc = agent_scd_getattr ("CHV-STATUS", &info);
- if (!rc)
- rc = agent_scd_getattr ("DISP-NAME", &info);
- if (rc)
- {
- log_error ("error getting current key info: %s\n", gpg_strerror (rc));
- return;
- }
- if ( (info.fpr1valid && !fpr_is_zero (info.fpr1))
- || (info.fpr2valid && !fpr_is_zero (info.fpr2))
- || (info.fpr3valid && !fpr_is_zero (info.fpr3)))
- {
- tty_printf ("\n");
- log_info ("NOTE: keys are already stored on the card!\n");
- tty_printf ("\n");
- if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_keys",
- _("Replace existing keys? ")))
- {
- agent_release_card_info (&info);
- return;
- }
- }
- else if (!info.disp_name || !*info.disp_name)
- {
- tty_printf ("\n");
- tty_printf (_("Please note that the factory settings of the PINs are\n"
- " PIN = \"%s\" Admin PIN = \"%s\"\n"
- "You should change them using the command --change-pin\n"),
- "123456", "12345678");
- tty_printf ("\n");
- }
-
- forced_chv1 = !info.chv1_cached;
- if (forced_chv1)
- { /* Switch of the forced mode so that during key generation we
- don't get bothered with PIN queries for each
- self-signature. */
- rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1);
- if (rc)
- {
- log_error ("error clearing forced signature PIN flag: %s\n",
- gpg_strerror (rc));
- return;
- }
- }
-
- /* Check the PIN now, so that we won't get asked later for each
- binding signature. */
- rc = agent_scd_checkpin (serialno);
- if (rc)
- log_error ("error checking the PIN: %s\n", gpg_strerror (rc));
- else
- generate_keypair (NULL, info.serialno);
-
- agent_release_card_info (&info);
- if (forced_chv1)
- { /* Switch back to forced state. */
- rc = agent_scd_setattr ("CHV-STATUS-1", "", 1);
- if (rc)
- {
- log_error ("error setting forced signature PIN flag: %s\n",
- gpg_strerror (rc));
- return;
- }
- }
-}
-
-/* Menu to edit all user changeable values on an OpenPGP card. Only
- Key creation is not handled here. */
-void
-card_edit (STRLIST commands)
-{
- enum cmdids {
- cmdNOP = 0,
- cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG,
- cmdNAME, cmdURL, cmdLOGIN, cmdLANG, cmdSEX,
- cmdFORCESIG, cmdGENERATE, cmdPASSWD,
- cmdINVCMD
- };
-
- static struct {
- const char *name;
- enum cmdids id;
- const char *desc;
- } cmds[] = {
- { N_("quit") , cmdQUIT , N_("quit this menu") },
- { N_("q") , cmdQUIT , NULL },
- { N_("help") , cmdHELP , N_("show this help") },
- { "?" , cmdHELP , NULL },
- { N_("list") , cmdLIST , N_("list all available data") },
- { N_("l") , cmdLIST , NULL },
- { N_("debug") , cmdDEBUG , NULL },
- { N_("name") , cmdNAME , N_("change card holder's name") },
- { N_("url") , cmdURL , N_("change URL to retrieve key") },
- { N_("login") , cmdLOGIN , N_("change the login name") },
- { N_("lang") , cmdLANG , N_("change the language preferences") },
- { N_("sex") , cmdSEX , N_("change card holder's sex") },
- { N_("forcesig"),
- cmdFORCESIG, N_("toggle the signature force PIN flag") },
- { N_("generate"),
- cmdGENERATE, N_("generate new keys") },
- { N_("passwd"), cmdPASSWD, N_("menu to change or unblock the PIN") },
- { NULL, cmdINVCMD }
- };
-
- enum cmdids cmd = cmdNOP;
- int have_commands = !!commands;
- int redisplay = 1;
- char *answer = NULL;
- int did_checkpin = 0;
- char serialnobuf[50];
-
-
- if (opt.command_fd != -1)
- ;
- else if (opt.batch && !have_commands)
- {
- log_error(_("can't do that in batchmode\n"));
- goto leave;
- }
-
- for (;;)
- {
- int arg_number;
- const char *arg_string = "";
- char *p;
- int i;
-
- tty_printf("\n");
- if (redisplay )
- {
- if (opt.with_colons)
- {
- card_status (stdout, serialnobuf, DIM (serialnobuf));
- fflush (stdout);
- }
- else
- {
- card_status (NULL, serialnobuf, DIM (serialnobuf));
- tty_printf("\n");
- }
- redisplay = 0;
- }
-
- do
- {
- xfree (answer);
- if (have_commands)
- {
- if (commands)
- {
- answer = xstrdup (commands->d);
- commands = commands->next;
- }
- else if (opt.batch)
- {
- answer = xstrdup ("quit");
- }
- else
- have_commands = 0;
- }
-
- if (!have_commands)
- {
- answer = cpr_get_no_help("cardedit.prompt", _("Command> "));
- cpr_kill_prompt();
- }
- trim_spaces(answer);
- }
- while( *answer == '#' );
-
- arg_number = 0; /* Yes, here is the init which egcc complains about */
- if (!*answer)
- cmd = cmdLIST; /* Default to the list command */
- else if (*answer == CONTROL_D)
- cmd = cmdQUIT;
- else {
- if ((p=strchr (answer,' ')))
- {
- *p++ = 0;
- trim_spaces (answer);
- trim_spaces (p);
- arg_number = atoi(p);
- arg_string = p;
- }
-
- for (i=0; cmds[i].name; i++ )
- if (!ascii_strcasecmp (answer, cmds[i].name ))
- break;
-
- cmd = cmds[i].id;
- }
-
-
- switch (cmd)
- {
- case cmdHELP:
- for (i=0; cmds[i].name; i++ )
- if (cmds[i].desc)
- tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
- break;
-
- case cmdLIST:
- redisplay = 1;
- break;
-
- case cmdNAME:
- change_name ();
- break;
-
- case cmdURL:
- change_url ();
- break;
-
- case cmdLOGIN:
- change_login ();
- break;
-
- case cmdLANG:
- change_lang ();
- break;
-
- case cmdSEX:
- change_sex ();
- break;
-
- case cmdFORCESIG:
- toggle_forcesig ();
- break;
-
- case cmdGENERATE:
- generate_card_keys (serialnobuf);
- break;
-
- case cmdPASSWD:
- change_pin (0);
- did_checkpin = 0; /* Need to reset it of course. */
- break;
-
- case cmdQUIT:
- goto leave;
-
- case cmdNOP:
- break;
-
- case cmdINVCMD:
- default:
- tty_printf ("\n");
- tty_printf (_("Invalid command (try \"help\")\n"));
- break;
- } /* End command switch. */
- } /* End of main menu loop. */
-
- leave:
- xfree (answer);
-}
-
diff --git a/g10/cipher.c b/g10/cipher.c
deleted file mode 100644
index 3d51a874a..000000000
--- a/g10/cipher.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/* cipher.c - En-/De-ciphering filter
- * Copyright (C) 1998, 1999, 2000, 2001, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "memory.h"
-#include "util.h"
-#include "filter.h"
-#include "packet.h"
-#include "options.h"
-#include "main.h"
-#include "status.h"
-
-
-#define MIN_PARTIAL_SIZE 512
-
-
-static void
-write_header( cipher_filter_context_t *cfx, iobuf_t a )
-{
- PACKET pkt;
- PKT_encrypted ed;
- byte temp[18];
- unsigned int blocksize;
- unsigned int nprefix;
- gpg_error_t rc;
-
- blocksize = gcry_cipher_get_algo_blklen ( cfx->dek->algo );
- if( blocksize < 8 || blocksize > 16 )
- log_fatal("unsupported blocksize %u\n", blocksize );
-
- memset( &ed, 0, sizeof ed );
- ed.len = cfx->datalen;
- ed.extralen = blocksize+2;
- ed.new_ctb = !ed.len && !RFC1991;
- if( cfx->dek->use_mdc ) {
- ed.mdc_method = DIGEST_ALGO_SHA1;
- gcry_md_open (&cfx->mdc_hash, GCRY_MD_SHA1, 0 );
- if ( DBG_HASHING )
- gcry_md_start_debug ( cfx->mdc_hash, "creatmdc" );
- }
-
- {
- char buf[20];
-
- sprintf (buf, "%d %d", ed.mdc_method, cfx->dek->algo);
- write_status_text (STATUS_BEGIN_ENCRYPTION, buf);
- }
-
- init_packet( &pkt );
- pkt.pkttype = cfx->dek->use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED;
- pkt.pkt.encrypted = &ed;
- if( build_packet( a, &pkt ))
- log_bug("build_packet(ENCR_DATA) failed\n");
- nprefix = blocksize;
- gcry_randomize ( temp, nprefix, GCRY_STRONG_RANDOM);
- temp[nprefix] = temp[nprefix-2];
- temp[nprefix+1] = temp[nprefix-1];
- print_cipher_algo_note( cfx->dek->algo );
- rc = gcry_cipher_open (&cfx->cipher_hd, cfx->dek->algo,
- GCRY_CIPHER_MODE_CFB,
- GCRY_CIPHER_SECURE
- | ((cfx->dek->use_mdc || cfx->dek->algo >= 100) ?
- 0 : GCRY_CIPHER_ENABLE_SYNC));
- if (rc) {
- /* we should never get an error here cause we already checked, that
- * the algorithm is available. */
- BUG();
- }
-/* log_hexdump( "thekey", cfx->dek->key, cfx->dek->keylen );*/
- gcry_cipher_setkey( cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen );
- gcry_cipher_setiv( cfx->cipher_hd, NULL, 0 );
-/* log_hexdump( "prefix", temp, nprefix+2 ); */
- if( cfx->mdc_hash ) /* hash the "IV" */
- gcry_md_write( cfx->mdc_hash, temp, nprefix+2 );
- gcry_cipher_encrypt( cfx->cipher_hd, temp, nprefix+2, NULL, 0);
- gcry_cipher_sync( cfx->cipher_hd );
- iobuf_write(a, temp, nprefix+2);
- cfx->header=1;
-}
-
-
-
-/****************
- * This filter is used to en/de-cipher data with a conventional algorithm
- */
-int
-cipher_filter( void *opaque, int control,
- iobuf_t a, byte *buf, size_t *ret_len)
-{
- size_t size = *ret_len;
- cipher_filter_context_t *cfx = opaque;
- int rc=0;
-
- if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */
- rc = -1; /* not yet used */
- }
- else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
- assert(a);
- if( !cfx->header ) {
- write_header( cfx, a );
- }
- if( cfx->mdc_hash )
- gcry_md_write( cfx->mdc_hash, buf, size );
- gcry_cipher_encrypt( cfx->cipher_hd, buf, size, NULL, 0);
- rc = iobuf_write( a, buf, size );
- }
- else if( control == IOBUFCTRL_FREE ) {
- if( cfx->mdc_hash ) {
- byte *hash;
- int hashlen = gcry_md_get_algo_dlen (gcry_md_get_algo (
- cfx->mdc_hash));
- byte temp[22];
-
- assert( hashlen == 20 );
- /* we must hash the prefix of the MDC packet here */
- temp[0] = 0xd3;
- temp[1] = 0x14;
- gcry_md_putc ( cfx->mdc_hash, temp[0] );
- gcry_md_putc ( cfx->mdc_hash, temp[1] );
-
- gcry_md_final ( cfx->mdc_hash );
- hash = gcry_md_read ( cfx->mdc_hash, 0 );
- memcpy(temp+2, hash, 20);
- gcry_cipher_encrypt( cfx->cipher_hd, temp, 22, NULL, 0 );
- gcry_md_close ( cfx->mdc_hash ); cfx->mdc_hash = NULL;
- rc = iobuf_write( a, temp, 22 );
- if (rc)
- log_error("writing MDC packet failed\n" );
- }
- gcry_cipher_close (cfx->cipher_hd);
- }
- else if( control == IOBUFCTRL_DESC ) {
- *(char**)buf = "cipher_filter";
- }
- return rc;
-}
-
-
-
diff --git a/g10/comment.c b/g10/comment.c
deleted file mode 100644
index b52104cd7..000000000
--- a/g10/comment.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/* comment.c - write comment stuff
- * Copyright (C) 1998, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "options.h"
-#include "packet.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "memory.h"
-#include "util.h"
-#include "main.h"
-#include "keydb.h"
-
-
-
-int
-write_comment( iobuf_t out, const char *s )
-{
- PACKET pkt;
- size_t n = strlen(s);
- int rc=0;
-
- pkt.pkttype = PKT_COMMENT;
- if( *s != '#' ) {
- pkt.pkt.comment = xmalloc ( sizeof *pkt.pkt.comment + n );
- pkt.pkt.comment->len = n+1;
- *pkt.pkt.comment->data = '#';
- strcpy(pkt.pkt.comment->data+1, s);
- }
- else {
- pkt.pkt.comment = xmalloc ( sizeof *pkt.pkt.comment + n - 1 );
- pkt.pkt.comment->len = n;
- strcpy(pkt.pkt.comment->data, s);
- }
- if( (rc = build_packet( out, &pkt )) )
- log_error("build_packet(comment) failed: %s\n", gpg_strerror (rc) );
- free_packet( &pkt );
- return rc;
-}
-
-
-KBNODE
-make_comment_node_from_buffer (const char *s, size_t n)
-{
- PACKET *pkt;
-
- pkt = gcry_xcalloc( 1, sizeof *pkt );
- pkt->pkttype = PKT_COMMENT;
- pkt->pkt.comment = gcry_xmalloc( sizeof *pkt->pkt.comment + n - 1 );
- pkt->pkt.comment->len = n;
- strcpy(pkt->pkt.comment->data, s);
- return new_kbnode( pkt );
-}
-
-KBNODE
-make_comment_node( const char *s )
-{
- return make_comment_node_from_buffer (s, strlen (s));
-}
-
-
-KBNODE
-make_mpi_comment_node( const char *s, gcry_mpi_t a )
-{
- PACKET *pkt;
- byte *buf, *pp;
- size_t n1, nb1;
- size_t n = strlen(s);
-
- nb1 = mpi_get_nbits( a );
- if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &n1, a))
- BUG ();
- /* fixme: allocate it on the stack */
- buf = xmalloc (n1);
- if (gcry_mpi_print (GCRYMPI_FMT_PGP, buf, n1, &n1, a))
- BUG ();
-
- pkt = xcalloc (1, sizeof *pkt );
- pkt->pkttype = PKT_COMMENT;
- pkt->pkt.comment = xmalloc ( sizeof *pkt->pkt.comment + n + 2 + n1 );
- pkt->pkt.comment->len = n+1+2+n1;
- pp = pkt->pkt.comment->data;
- memcpy(pp, s, n+1);
- memcpy(pp+n+1, buf, n1 );
- xfree (buf);
- return new_kbnode( pkt );
-}
-
-
diff --git a/g10/compress.c b/g10/compress.c
deleted file mode 100644
index 7dce1790a..000000000
--- a/g10/compress.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/* compress.c - compress filter
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <assert.h>
-#include <errno.h>
-#include <zlib.h>
-#ifdef __riscos__
-# include "zlib-riscos.h"
-#endif
-
-#include "gpg.h"
-#include "util.h"
-#include "memory.h"
-#include "packet.h"
-#include "filter.h"
-#include "main.h"
-#include "options.h"
-
-static void
-init_compress( compress_filter_context_t *zfx, z_stream *zs )
-{
- int rc;
- int level;
-
-#ifdef __riscos__
- static int zlib_initialized = 0;
-
- if (!zlib_initialized)
- zlib_initialized = riscos_load_module("ZLib", zlib_path, 1);
-#endif
-
- if( opt.compress >= 0 && opt.compress <= 9 )
- level = opt.compress;
- else if( opt.compress == -1 )
- level = Z_DEFAULT_COMPRESSION;
- else if( opt.compress == 10 ) /* remove this ! */
- level = 0;
- else {
- log_error("invalid compression level; using default level\n");
- level = Z_DEFAULT_COMPRESSION;
- }
-
-
- if( (rc = zfx->algo == 1? deflateInit2( zs, level, Z_DEFLATED,
- -13, 8, Z_DEFAULT_STRATEGY)
- : deflateInit( zs, level )
- ) != Z_OK ) {
- log_fatal("zlib problem: %s\n", zs->msg? zs->msg :
- rc == Z_MEM_ERROR ? "out of core" :
- rc == Z_VERSION_ERROR ? "invalid lib version" :
- "unknown error" );
- }
-
- zfx->outbufsize = 8192;
- zfx->outbuf = xmalloc ( zfx->outbufsize );
-}
-
-static int
-do_compress( compress_filter_context_t *zfx, z_stream *zs, int flush, iobuf_t a )
-{
- gpg_error_t rc;
- int zrc;
- unsigned n;
-
- do {
-#ifndef __riscos__
- zs->next_out = zfx->outbuf;
-#else /* __riscos__ */
- zs->next_out = (Bytef *) zfx->outbuf;
-#endif /* __riscos__ */
- zs->avail_out = zfx->outbufsize;
- if( DBG_FILTER )
- log_debug("enter deflate: avail_in=%u, avail_out=%u, flush=%d\n",
- (unsigned)zs->avail_in, (unsigned)zs->avail_out, flush );
- zrc = deflate( zs, flush );
- if( zrc == Z_STREAM_END && flush == Z_FINISH )
- ;
- else if( zrc != Z_OK ) {
- if( zs->msg )
- log_fatal("zlib deflate problem: %s\n", zs->msg );
- else
- log_fatal("zlib deflate problem: rc=%d\n", zrc );
- }
- n = zfx->outbufsize - zs->avail_out;
- if( DBG_FILTER )
- log_debug("leave deflate: "
- "avail_in=%u, avail_out=%u, n=%u, zrc=%d\n",
- (unsigned)zs->avail_in, (unsigned)zs->avail_out,
- (unsigned)n, zrc );
-
- rc = iobuf_write (a, zfx->outbuf, n);
- if (rc)
- {
- log_debug("deflate: iobuf_write failed\n");
- return rc;
- }
- } while( zs->avail_in || (flush == Z_FINISH && zrc != Z_STREAM_END) );
- return 0;
-}
-
-static void
-init_uncompress( compress_filter_context_t *zfx, z_stream *zs )
-{
- int rc;
-
- /****************
- * PGP uses a windowsize of 13 bits. Using a negative value for
- * it forces zlib not to expect a zlib header. This is a
- * undocumented feature Peter Gutmann told me about.
- *
- * We must use 15 bits for the inflator because CryptoEx uses 15
- * bits thus the output would get scrambled w/o error indication
- * if we would use 13 bits. For the uncompressing this does not
- * matter at all.
- */
- if( (rc = zfx->algo == 1? inflateInit2( zs, -15)
- : inflateInit( zs )) != Z_OK ) {
- log_fatal("zlib problem: %s\n", zs->msg? zs->msg :
- rc == Z_MEM_ERROR ? "out of core" :
- rc == Z_VERSION_ERROR ? "invalid lib version" :
- "unknown error" );
- }
-
- zfx->inbufsize = 2048;
- zfx->inbuf = xmalloc ( zfx->inbufsize );
- zs->avail_in = 0;
-}
-
-static int
-do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
- iobuf_t a, size_t *ret_len )
-{
- int zrc;
- int rc=0;
- size_t n;
- int nread, count;
- int refill = !zs->avail_in;
-
- if( DBG_FILTER )
- log_debug("begin inflate: avail_in=%u, avail_out=%u, inbuf=%u\n",
- (unsigned)zs->avail_in, (unsigned)zs->avail_out,
- (unsigned)zfx->inbufsize );
- do {
- if( zs->avail_in < zfx->inbufsize && refill ) {
- n = zs->avail_in;
- if( !n )
-#ifndef __riscos__
- zs->next_in = zfx->inbuf;
-#else /* __riscos__ */
- zs->next_in = (Bytef *) zfx->inbuf;
-#endif /* __riscos__ */
- count = zfx->inbufsize - n;
- nread = iobuf_read( a, zfx->inbuf + n, count );
- if( nread == -1 ) nread = 0;
- n += nread;
- /* If we use the undocumented feature to suppress
- * the zlib header, we have to give inflate an
- * extra dummy byte to read */
- if( nread < count && zfx->algo == 1 ) {
- *(zfx->inbuf + n) = 0xFF; /* is it really needed ? */
- zfx->algo1hack = 1;
- n++;
- }
- zs->avail_in = n;
- }
- refill = 1;
- if( DBG_FILTER )
- log_debug("enter inflate: avail_in=%u, avail_out=%u\n",
- (unsigned)zs->avail_in, (unsigned)zs->avail_out);
-#ifdef Z_SYNC_FLUSH
- zrc = inflate( zs, Z_SYNC_FLUSH );
-#else
- zrc = inflate( zs, Z_PARTIAL_FLUSH );
-#endif
- if( DBG_FILTER )
- log_debug("leave inflate: avail_in=%u, avail_out=%u, zrc=%d\n",
- (unsigned)zs->avail_in, (unsigned)zs->avail_out, zrc);
- if( zrc == Z_STREAM_END )
- rc = -1; /* eof */
- else if( zrc != Z_OK && zrc != Z_BUF_ERROR ) {
- if( zs->msg )
- log_fatal("zlib inflate problem: %s\n", zs->msg );
- else
- log_fatal("zlib inflate problem: rc=%d\n", zrc );
- }
- } while( zs->avail_out && zrc != Z_STREAM_END && zrc != Z_BUF_ERROR );
- *ret_len = zfx->outbufsize - zs->avail_out;
- if( DBG_FILTER )
- log_debug("do_uncompress: returning %u bytes\n", (unsigned)*ret_len );
- return rc;
-}
-
-int
-compress_filter( void *opaque, int control,
- iobuf_t a, byte *buf, size_t *ret_len)
-{
- size_t size = *ret_len;
- compress_filter_context_t *zfx = opaque;
- z_stream *zs = zfx->opaque;
- int rc=0;
-
- if( control == IOBUFCTRL_UNDERFLOW ) {
- if( !zfx->status ) {
- zs = zfx->opaque = xcalloc (1, sizeof *zs );
- init_uncompress( zfx, zs );
- zfx->status = 1;
- }
-
-#ifndef __riscos__
- zs->next_out = buf;
-#else /* __riscos__ */
- zs->next_out = (Bytef *) buf;
-#endif /* __riscos__ */
- zs->avail_out = size;
- zfx->outbufsize = size; /* needed only for calculation */
- rc = do_uncompress( zfx, zs, a, ret_len );
- }
- else if( control == IOBUFCTRL_FLUSH ) {
- if( !zfx->status ) {
- PACKET pkt;
- PKT_compressed cd;
-
- if( !zfx->algo )
- zfx->algo = DEFAULT_COMPRESS_ALGO;
- if( zfx->algo != 1 && zfx->algo != 2 )
- BUG();
- memset( &cd, 0, sizeof cd );
- cd.len = 0;
- cd.algorithm = zfx->algo;
- init_packet( &pkt );
- pkt.pkttype = PKT_COMPRESSED;
- pkt.pkt.compressed = &cd;
- if( build_packet( a, &pkt ))
- log_bug("build_packet(PKT_COMPRESSED) failed\n");
- zs = zfx->opaque = xcalloc (1, sizeof *zs );
- init_compress( zfx, zs );
- zfx->status = 2;
- }
-
-#ifndef __riscos__
- zs->next_in = buf;
-#else /* __riscos__ */
- zs->next_in = (Bytef *) buf;
-#endif /* __riscos__ */
- zs->avail_in = size;
- rc = do_compress( zfx, zs, Z_NO_FLUSH, a );
- }
- else if( control == IOBUFCTRL_FREE ) {
- if( zfx->status == 1 ) {
- inflateEnd(zs);
- xfree (zs);
- zfx->opaque = NULL;
- xfree (zfx->outbuf); zfx->outbuf = NULL;
- }
- else if( zfx->status == 2 ) {
-#ifndef __riscos__
- zs->next_in = buf;
-#else /* __riscos__ */
- zs->next_in = (Bytef *) buf;
-#endif /* __riscos__ */
- zs->avail_in = 0;
- do_compress( zfx, zs, Z_FINISH, a );
- deflateEnd(zs);
- xfree (zs);
- zfx->opaque = NULL;
- xfree (zfx->outbuf); zfx->outbuf = NULL;
- }
- if (zfx->release)
- zfx->release (zfx);
- }
- else if( control == IOBUFCTRL_DESC )
- *(char**)buf = "compress_filter";
- return rc;
-}
-
-
-static void
-release_context (compress_filter_context_t *ctx)
-{
- xfree (ctx);
-}
-
-/****************
- * Handle a compressed packet
- */
-int
-handle_compressed( void *procctx, PKT_compressed *cd,
- int (*callback)(iobuf_t, void *), void *passthru )
-{
- compress_filter_context_t *cfx;
- int rc;
-
- if( cd->algorithm < 1 || cd->algorithm > 2 )
- return GPG_ERR_COMPR_ALGO;
- cfx = xcalloc (1,sizeof *cfx);
- cfx->algo = cd->algorithm;
- cfx->release = release_context;
- iobuf_push_filter( cd->buf, compress_filter, cfx );
- if( callback )
- rc = callback(cd->buf, passthru );
- else
- rc = proc_packets(procctx, cd->buf);
- cd->buf = NULL;
- return rc;
-}
-
diff --git a/g10/dearmor.c b/g10/dearmor.c
deleted file mode 100644
index 4f9fa2db7..000000000
--- a/g10/dearmor.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* dearmor.c - Armor utility
- * Copyright (C) 1998, 1999, 2000, 2001, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "memory.h"
-#include "util.h"
-#include "filter.h"
-#include "packet.h"
-#include "options.h"
-#include "main.h"
-
-
-/****************
- * Take an armor file and write it out without armor
- */
-int
-dearmor_file( const char *fname )
-{
- armor_filter_context_t afx;
- iobuf_t inp = NULL, out = NULL;
- int rc = 0;
- int c;
-
- memset( &afx, 0, sizeof afx);
-
- /* prepare iobufs */
- if( !(inp = iobuf_open(fname)) ) {
- rc = gpg_error_from_errno (errno);
- log_error("can't open %s: %s\n", fname? fname: "[stdin]",
- strerror(errno) );
- goto leave;
- }
-
- iobuf_push_filter( inp, armor_filter, &afx );
-
- if( (rc = open_outfile( fname, 0, &out )) )
- goto leave;
-
-
-
- while( (c = iobuf_get(inp)) != -1 )
- iobuf_put( out, c );
-
-
- leave:
- if( rc )
- iobuf_cancel(out);
- else
- iobuf_close(out);
- iobuf_close(inp);
- return rc;
-}
-
-
-/****************
- * Take file and write it out with armor
- */
-int
-enarmor_file( const char *fname )
-{
- armor_filter_context_t afx;
- iobuf_t inp = NULL, out = NULL;
- int rc = 0;
- int c;
-
- memset( &afx, 0, sizeof afx);
-
- /* prepare iobufs */
- if( !(inp = iobuf_open(fname)) ) {
- rc = gpg_error_from_errno (errno);
- log_error("can't open %s: %s\n", fname? fname: "[stdin]",
- strerror(errno) );
- goto leave;
- }
-
-
- if( (rc = open_outfile( fname, 1, &out )) )
- goto leave;
-
- afx.what = 4;
- afx.hdrlines = "Comment: Use \"gpg --dearmor\" for unpacking\n";
- iobuf_push_filter( out, armor_filter, &afx );
-
- while( (c = iobuf_get(inp)) != -1 )
- iobuf_put( out, c );
-
-
- leave:
- if( rc )
- iobuf_cancel(out);
- else
- iobuf_close(out);
- iobuf_close(inp);
- return rc;
-}
-
-
diff --git a/g10/decrypt.c b/g10/decrypt.c
deleted file mode 100644
index 98a270cfb..000000000
--- a/g10/decrypt.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/* decrypt.c - verify signed data
- * Copyright (C) 1998,1999,2000,2001,2002,2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "options.h"
-#include "packet.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "keydb.h"
-#include "memory.h"
-#include "util.h"
-#include "main.h"
-#include "status.h"
-#include "i18n.h"
-
-
-
-/****************
- * Assume that the input is an encrypted message and decrypt
- * (and if signed, verify the signature on) it.
- * This command differs from the default operation, as it never
- * writes to the filename which is included in the file and it
- * rejects files which don't begin with an encrypted message.
- */
-
-int
-decrypt_message( const char *filename )
-{
- iobuf_t fp;
- armor_filter_context_t afx;
- progress_filter_context_t pfx;
- int rc;
- int no_out=0;
-
- /* open the message file */
- fp = iobuf_open(filename);
- if( !fp ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("can't open `%s'\n"), print_fname_stdin(filename));
- return rc;
- }
-
- handle_progress (&pfx, fp, filename);
-
- if( !opt.no_armor ) {
- if( use_armor_filter( fp ) ) {
- memset( &afx, 0, sizeof afx);
- iobuf_push_filter( fp, armor_filter, &afx );
- }
- }
-
- if( !opt.outfile ) {
- no_out = 1;
- opt.outfile = "-";
- }
- rc = proc_encryption_packets( NULL, fp );
- if( no_out )
- opt.outfile = NULL;
- iobuf_close(fp);
- return rc;
-}
-
-void
-decrypt_messages(int nfiles, char **files)
-{
- iobuf_t fp;
- armor_filter_context_t afx;
- progress_filter_context_t pfx;
- char *p, *output = NULL;
- int rc = 0;
-
- if (opt.outfile)
- {
- log_error(_("--output doesn't work for this command\n"));
- return;
-
- }
-
- while (nfiles--)
- {
- print_file_status(STATUS_FILE_START, *files, 3);
- output = make_outfile_name(*files);
- if (!output)
- goto next_file;
- fp = iobuf_open(*files);
- if (!fp)
- {
- log_error(_("can't open `%s'\n"), print_fname_stdin(*files));
- goto next_file;
- }
-
- handle_progress (&pfx, fp, *files);
-
- if (!opt.no_armor)
- {
- if (use_armor_filter(fp))
- {
- memset(&afx, 0, sizeof afx);
- iobuf_push_filter(fp, armor_filter, &afx);
- }
- }
- rc = proc_packets(NULL, fp);
- iobuf_close(fp);
- if (rc)
- log_error("%s: decryption failed: %s\n", print_fname_stdin(*files),
- gpg_strerror (rc));
- p = get_last_passphrase();
- set_next_passphrase(p);
- xfree (p);
-
- next_file:
- /* Note that we emit file_done even after an error. */
- write_status( STATUS_FILE_DONE );
- xfree (output);
- files++;
- }
- set_next_passphrase(NULL);
-}
-
diff --git a/g10/delkey.c b/g10/delkey.c
deleted file mode 100644
index 6263dec47..000000000
--- a/g10/delkey.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* delkey.c - delete keys
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <ctype.h>
-
-#include "options.h"
-#include "packet.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "keydb.h"
-#include "memory.h"
-#include "util.h"
-#include "main.h"
-#include "trustdb.h"
-#include "filter.h"
-#include "ttyio.h"
-#include "status.h"
-#include "i18n.h"
-
-
-/****************
- * Delete a public or secret key from a keyring.
- * r_sec_avail will be set if a secret key is available and the public
- * key can't be deleted for that reason.
- */
-static int
-do_delete_key( const char *username, int secret, int *r_sec_avail )
-{
- int rc = 0;
- KBNODE keyblock = NULL;
- KBNODE node;
- KEYDB_HANDLE hd = keydb_new (secret);
- PKT_public_key *pk = NULL;
- PKT_secret_key *sk = NULL;
- u32 keyid[2];
- int okay=0;
- int yes;
- KEYDB_SEARCH_DESC desc;
- int exactmatch;
-
- *r_sec_avail = 0;
-
- /* search the userid */
- classify_user_id (username, &desc);
- exactmatch = (desc.mode == KEYDB_SEARCH_MODE_FPR
- || desc.mode == KEYDB_SEARCH_MODE_FPR16
- || desc.mode == KEYDB_SEARCH_MODE_FPR20);
- rc = desc.mode? keydb_search (hd, &desc, 1):GPG_ERR_INV_USER_ID;
- if (rc) {
- log_error (_("key `%s' not found: %s\n"), username, gpg_strerror (rc));
- write_status_text( STATUS_DELETE_PROBLEM, "1" );
- goto leave;
- }
-
- /* read the keyblock */
- rc = keydb_get_keyblock (hd, &keyblock );
- if (rc) {
- log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) );
- goto leave;
- }
-
- /* get the keyid from the keyblock */
- node = find_kbnode( keyblock, secret? PKT_SECRET_KEY:PKT_PUBLIC_KEY );
- if( !node ) {
- log_error("Oops; key not found anymore!\n");
- rc = GPG_ERR_GENERAL;
- goto leave;
- }
-
- if( secret ) {
- sk = node->pkt->pkt.secret_key;
- keyid_from_sk( sk, keyid );
- }
- else {
- pk = node->pkt->pkt.public_key;
- keyid_from_pk( pk, keyid );
- rc = seckey_available( keyid );
- if( !rc ) {
- *r_sec_avail = 1;
- rc = -1;
- goto leave;
- }
- else if( rc != GPG_ERR_NO_SECKEY ) {
- log_error("%s: get secret key: %s\n", username, gpg_strerror (rc) );
- }
- else
- rc = 0;
- }
-
- if( rc )
- rc = 0;
- else if (opt.batch && exactmatch)
- okay++;
- else if( opt.batch && secret )
- {
- log_error(_("can't do that in batchmode\n"));
- log_info (_("(unless you specify the key by fingerprint)\n"));
- }
- else if( opt.batch && opt.answer_yes )
- okay++;
- else if( opt.batch )
- {
- log_error(_("can't do that in batchmode without \"--yes\"\n"));
- log_info (_("(unless you specify the key by fingerprint)\n"));
- }
- else {
- if( secret )
- print_seckey_info( sk );
- else
- print_pubkey_info (NULL, pk );
- tty_printf( "\n" );
-
- yes = cpr_get_answer_is_yes( secret? "delete_key.secret.okay"
- : "delete_key.okay",
- _("Delete this key from the keyring? "));
- if( !cpr_enabled() && secret && yes ) {
- /* I think it is not required to check a passphrase; if
- * the user is so stupid as to let others access his secret keyring
- * (and has no backup) - it is up him to read some very
- * basic texts about security.
- */
- yes = cpr_get_answer_is_yes("delete_key.secret.okay",
- _("This is a secret key! - really delete? "));
- }
- if( yes )
- okay++;
- }
-
-
- if( okay ) {
- rc = keydb_delete_keyblock (hd);
- if (rc) {
- log_error (_("deleting keyblock failed: %s\n"), gpg_strerror (rc) );
- goto leave;
- }
-
- /* Note that the ownertrust being cleared will trigger a
- revalidation_mark(). This makes sense - only deleting keys
- that have ownertrust set should trigger this. */
-
- if (!secret && pk && clear_ownertrusts (pk)) {
- if (opt.verbose)
- log_info (_("ownertrust information cleared\n"));
- }
- }
-
- leave:
- keydb_release (hd);
- release_kbnode (keyblock);
- return rc;
-}
-
-/****************
- * Delete a public or secret key from a keyring.
- */
-int
-delete_keys( STRLIST names, int secret, int allow_both )
-{
- int rc, avail;
-
- for(;names;names=names->next) {
- rc = do_delete_key (names->d, secret, &avail );
- if ( rc && avail ) {
- if ( allow_both ) {
- rc = do_delete_key (names->d, 1, &avail );
- if ( !rc )
- rc = do_delete_key (names->d, 0, &avail );
- }
- else {
- log_error(_(
- "there is a secret key for public key \"%s\"!\n"),names->d);
- log_info(_(
- "use option \"--delete-secret-keys\" to delete it first.\n"));
- write_status_text( STATUS_DELETE_PROBLEM, "2" );
- return rc;
- }
- }
-
- if(rc) {
- log_error("%s: delete key failed: %s\n", names->d, gpg_strerror (rc) );
- return rc;
- }
- }
-
- return 0;
-}
diff --git a/g10/encode.c b/g10/encode.c
deleted file mode 100644
index 7794bdb7c..000000000
--- a/g10/encode.c
+++ /dev/null
@@ -1,821 +0,0 @@
-/* encode.c - encode data
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "options.h"
-#include "packet.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "keydb.h"
-#include "memory.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 compat );
-static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out );
-
-
-
-/****************
- * Encode FILENAME with only the symmetric cipher. Take input from
- * stdin if FILENAME is NULL.
- */
-int
-encode_symmetric( const char *filename )
-{
- int compat = 1;
-
-#if 0
- /* We don't want to use it because older gnupg version can't
- handle it and we can presume that a lot of scripts are running
- with the expert mode set. Some time in the future we might
- want to allow for it. */
- if ( opt.expert )
- compat = 0; /* PGP knows how to handle this mode. */
-#endif
- return encode_simple( filename, 1, compat );
-}
-
-/****************
- * 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, 1 );
-}
-
-static void
-encode_sesskey (DEK * dek, DEK ** ret_dek, byte * enckey)
-{
- CIPHER_HANDLE hd;
- DEK * c;
- byte buf[33];
-
- assert (dek->keylen < 32);
-
- c = xcalloc (1, sizeof *c);
- c->keylen = dek->keylen;
- c->algo = dek->algo;
- make_session_key (c);
- /*log_hexdump ("thekey", c->key, c->keylen);*/
-
- /* the encrypted session key is prefixed with a one-octet algorithm id */
- buf[0] = c->algo;
- memcpy (buf + 1, c->key, c->keylen);
-
- /* due to the fact that we use only checked values, consider each
- failure as fatal. */
- if (gcry_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, c->keylen + 1, NULL, 0);
- gcry_cipher_close (hd);
-
- memcpy (enckey, buf, c->keylen + 1);
- wipememory (buf, sizeof buf); /* burn key */
- *ret_dek = c;
-}
-
-/* We try very hard to use a MDC */
-static int
-use_mdc (PK_LIST pk_list,int algo)
-{
- byte cipher_algid[4] = {
- CIPHER_ALGO_AES,
- CIPHER_ALGO_AES192,
- CIPHER_ALGO_AES256,
- CIPHER_ALGO_TWOFISH
- };
- int i;
-
- /* 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. */
- for (i=0; i < DIM (cipher_algid); i++)
- {
- if (select_algo_from_prefs (pk_list, PREFTYPE_SYM, cipher_algid[i],
- NULL) == cipher_algid[i])
- return 1;
- }
-
- /* Last try. Use MDC for the modern ciphers. */
- if (gcry_cipher_get_algo_blklen (algo) != 8)
- return 1;
-
- return 0; /* No MDC */
-}
-
-static int
-encode_simple( const char *filename, int mode, int compat )
-{
- iobuf_t inp, out;
- PACKET pkt;
- DEK *dek = NULL;
- 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;
- compress_filter_context_t zfx;
- text_filter_context_t tfx;
- progress_filter_context_t pfx;
- int do_compress = opt.compress && !RFC1991;
-
- memset( &cfx, 0, sizeof cfx);
- memset( &afx, 0, sizeof afx);
- memset( &zfx, 0, sizeof zfx);
- memset( &tfx, 0, sizeof tfx);
- init_packet(&pkt);
-
- /* prepare iobufs */
- if( !(inp = iobuf_open(filename)) ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("%s: can't open: %s\n"), filename? filename: "[stdin]",
- strerror(errno) );
- 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 && !compat )
- compat = 1;
-
- cfx.dek = NULL;
- if( mode ) {
- s2k = xcalloc (1, sizeof *s2k );
- s2k->mode = RFC1991? 0:opt.s2k_mode;
- s2k->hash_algo = opt.s2k_digest_algo;
- cfx.dek = passphrase_to_dek( NULL, 0,
- default_cipher_algo(), s2k, 2,
- NULL, NULL);
- if( !cfx.dek || !cfx.dek->keylen ) {
- rc = gpg_error (GPG_ERR_INV_PASSPHRASE);
- xfree (cfx.dek);
- xfree (s2k);
- iobuf_close(inp);
- log_error(_("error creating passphrase: %s\n"), gpg_strerror (rc) );
- return rc;
- }
- if (!compat && s2k->mode != 1 && s2k->mode != 3) {
- compat = 1;
- log_info (_("can't use a symmetric ESK packet "
- "due to the S2K mode\n"));
- }
-
- if ( !compat ) {
- seskeylen = gcry_cipher_get_algo_keylen (default_cipher_algo());
- encode_sesskey( cfx.dek, &dek, enckey );
- xfree (cfx.dek); cfx.dek = dek;
- }
-
- cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo);
- }
-
- if (opt.compress == -1 && 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);
- return rc;
- }
-
- if( opt.armor )
- iobuf_push_filter( out, armor_filter, &afx );
-#ifdef ENABLE_COMMENT_PACKETS
- else {
- write_comment( out, "#created by GNUPG v" VERSION " ("
- PRINTABLE_OS_NAME ")");
- if( opt.comment_string )
- write_comment( out, opt.comment_string );
- }
-#endif
- if( s2k && !RFC1991 ) {
- PKT_symkey_enc *enc = xcalloc (1, sizeof *enc + seskeylen + 1 );
- enc->version = 4;
- enc->cipher_algo = cfx.dek->algo;
- enc->s2k = *s2k;
- if ( !compat && 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", gpg_strerror (rc) );
- xfree (enc);
- }
-
- if (!opt.no_literal) {
- /* setup the inner packet */
- if( filename || opt.set_filename ) {
- char *s = make_basename ( opt.set_filename ? opt.set_filename
- : filename
- /* for riscos?
- .iobuf_get_real_fname( inp ) */
- );
- pt = xmalloc ( sizeof *pt + strlen(s) - 1 );
- pt->namelen = strlen(s);
- memcpy(pt->name, s, pt->namelen );
- xfree (s);
- }
- else { /* no filename */
- pt = xmalloc ( sizeof *pt - 1 );
- pt->namelen = 0;
- }
- }
-
- /* 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 (filename && *filename && !(*filename == '-' && !filename[1])
- && !opt.textmode ) {
- off_t tmpsize;
-
- if ( !(tmpsize = iobuf_get_filelength(inp)) )
- log_info(_("%s: WARNING: 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;
- zfx.algo=default_compress_algo();
- iobuf_push_filter( out, compress_filter, &zfx );
- }
-
- /* do the work */
- if (!opt.no_literal) {
- if( (rc = build_packet( out, &pkt )) )
- log_error("build_packet failed: %s\n", gpg_strerror (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);
- return rc;
-}
-
-/****************
- * Encrypt the file with the given userids (or ask if none
- * is supplied).
- */
-int
-encode_crypt( const char *filename, STRLIST remusr )
-{
- iobuf_t inp = NULL, out = NULL;
- PACKET pkt;
- PKT_plaintext *pt = NULL;
- int rc = 0, rc2 = 0;
- u32 filesize;
- cipher_filter_context_t cfx;
- armor_filter_context_t afx;
- 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 && !RFC1991;
-
-
- memset( &cfx, 0, sizeof cfx);
- memset( &afx, 0, sizeof afx);
- memset( &zfx, 0, sizeof zfx);
- memset( &tfx, 0, sizeof tfx);
- init_packet(&pkt);
-
- if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) )
- 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 */
- if( !(inp = iobuf_open(filename)) ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("can't open %s: %s\n"), filename? filename: "[stdin]",
- strerror(errno) );
- 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 )
- iobuf_push_filter( out, armor_filter, &afx );
-#ifdef ENABLE_COMMENT_PACKETS
- else {
- write_comment( out, "#created by GNUPG v" VERSION " ("
- PRINTABLE_OS_NAME ")");
- if( opt.comment_string )
- write_comment( out, opt.comment_string );
- }
-#endif
- /* create a session key */
- cfx.dek = xcalloc_secure (1, 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();
- }
- }
- }
- else {
- if(!opt.expert &&
- select_algo_from_prefs(pk_list,PREFTYPE_SYM,
- opt.def_cipher_algo,NULL)!=opt.def_cipher_algo)
- log_info(_("forcing symmetric cipher %s (%d) "
- "violates recipient preferences\n"),
- gcry_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 (opt.compress == -1 && 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;
-
- if (!opt.no_literal) {
- /* setup the inner packet */
- if( filename || opt.set_filename ) {
- char *s = make_basename( opt.set_filename ? opt.set_filename
- : filename
- /* ,iobuf_get_real_fname( inp )*/ );
- pt = xmalloc ( sizeof *pt + strlen(s) - 1 );
- pt->namelen = strlen(s);
- memcpy(pt->name, s, pt->namelen );
- xfree (s);
- }
- else { /* no filename */
- pt = xmalloc ( sizeof *pt - 1 );
- pt->namelen = 0;
- }
- }
-
- if (filename && *filename && !(*filename == '-' && !filename[1])
- && !opt.textmode ) {
- off_t tmpsize;
-
- if ( !(tmpsize = iobuf_get_filelength(inp)) )
- log_info(_("%s: WARNING: 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.def_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(_("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;
- zfx.algo = compr_algo;
- iobuf_push_filter( out, compress_filter, &zfx );
- }
- }
-
- /* do the work */
- if (!opt.no_literal) {
- if( (rc = build_packet( out, &pkt )) )
- log_error("build_packet failed: %s\n", gpg_strerror (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);
- release_pk_list( pk_list );
- 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 = xcalloc_secure (1, 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;
- }
- }
- 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"),
- gcry_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;
-
- iobuf_push_filter( a, cipher_filter, &efx->cfx );
-
- efx->header_okay = 1;
- }
- rc = iobuf_write( a, buf, size );
-
- }
- else if( control == IOBUFCTRL_FREE ) {
- }
- 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 = xcalloc (1, 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_printable (enc->keyid);
- log_info(_("%s/%s encrypted for: \"%s\"\n"),
- gcry_pk_algo_name (enc->pubkey_algo),
- gcry_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", gpg_strerror (rc));
- }
- free_pubkey_enc(enc);
- if( rc )
- return rc;
- }
- return 0;
-}
-
-void
-encode_crypt_files(int nfiles, char **files, STRLIST 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)) )
- log_error("%s: encryption failed: %s\n",
- print_fname_stdin(line), gpg_strerror (rc) );
- write_status( STATUS_FILE_DONE );
- }
- }
- else
- {
- while (nfiles--)
- {
- print_file_status(STATUS_FILE_START, *files, 2);
- if ( (rc = encode_crypt(*files, remusr)) )
- log_error("%s: encryption failed: %s\n",
- print_fname_stdin(*files), gpg_strerror (rc) );
- write_status( STATUS_FILE_DONE );
- files++;
- }
- }
-}
diff --git a/g10/encr-data.c b/g10/encr-data.c
deleted file mode 100644
index 074408404..000000000
--- a/g10/encr-data.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/* encr-data.c - process an encrypted data packet
- * Copyright (C) 1998, 1999, 2000, 2001, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "memory.h"
-#include "packet.h"
-#include "mpi.h"
-#include "cipher.h"
-#include "options.h"
-#include "i18n.h"
-
-
-static int mdc_decode_filter( void *opaque, int control, iobuf_t a,
- byte *buf, size_t *ret_len);
-static int decode_filter( void *opaque, int control, iobuf_t a,
- byte *buf, size_t *ret_len);
-
-typedef struct {
- CIPHER_HANDLE cipher_hd;
- MD_HANDLE mdc_hash;
- char defer[20];
- int defer_filled;
- int eof_seen;
-} decode_filter_ctx_t;
-
-
-/****************
- * Decrypt the data, specified by ED with the key DEK.
- */
-int
-decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
-{
- decode_filter_ctx_t dfx;
- byte *p;
- int rc=0, c, i;
- byte temp[32];
- unsigned blocksize;
- unsigned nprefix;
-
- memset( &dfx, 0, sizeof dfx );
- if( opt.verbose && !dek->algo_info_printed ) {
- const char *s = gcry_cipher_algo_name (dek->algo);
- if (s && *s)
- log_info(_("%s encrypted data\n"), s );
- else
- log_info(_("encrypted with unknown algorithm %d\n"), dek->algo );
- dek->algo_info_printed = 1;
- }
- if( (rc=openpgp_cipher_test_algo(dek->algo)) )
- goto leave;
- blocksize = gcry_cipher_get_algo_blklen (dek->algo);
- if( !blocksize || blocksize > 16 )
- log_fatal("unsupported blocksize %u\n", blocksize );
- nprefix = blocksize;
- if( ed->len && ed->len < (nprefix+2) )
- BUG();
-
- if( ed->mdc_method ) {
- gcry_md_open (&dfx.mdc_hash, ed->mdc_method, 0 );
- if ( DBG_HASHING )
- gcry_md_start_debug (dfx.mdc_hash, "checkmdc");
- }
- rc = gcry_cipher_open (&dfx.cipher_hd, dek->algo,
- GCRY_CIPHER_MODE_CFB,
- GCRY_CIPHER_SECURE
- | ((ed->mdc_method || dek->algo >= 100)?
- 0 : GCRY_CIPHER_ENABLE_SYNC) );
- if (rc)
- {
- /* we should never get an error here cause we already
- * checked, that the algorithm is available. What about a
- * flag to let the function die in this case? */
- BUG();
- }
- /* log_hexdump( "thekey", dek->key, dek->keylen );*/
- rc = gcry_cipher_setkey (dfx.cipher_hd, dek->key, dek->keylen);
- if( gpg_err_code (rc) == GPG_ERR_WEAK_KEY )
- log_info(_("WARNING: message was encrypted with "
- "a weak key in the symmetric cipher.\n"));
- else if( rc ) {
- log_error("key setup failed: %s\n", gpg_strerror (rc) );
- goto leave;
- }
- if (!ed->buf) {
- log_error(_("problem handling encrypted packet\n"));
- goto leave;
- }
-
- gcry_cipher_setiv (dfx.cipher_hd, NULL, 0);
-
- if (ed->len) {
- for(i=0; i < (nprefix+2) && ed->len; i++, ed->len-- ) {
- if( (c=iobuf_get(ed->buf)) == -1 )
- break;
- else
- temp[i] = c;
- }
- }
- else {
- for(i=0; i < (nprefix+2); i++ )
- if( (c=iobuf_get(ed->buf)) == -1 )
- break;
- else
- temp[i] = c;
- }
- gcry_cipher_decrypt( dfx.cipher_hd, temp, nprefix+2, NULL, 0);
- gcry_cipher_sync( dfx.cipher_hd );
- p = temp;
-/* log_hexdump( "prefix", temp, nprefix+2 ); */
- if( p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1] ) {
- rc = GPG_ERR_BAD_KEY;
- goto leave;
- }
-
- if( dfx.mdc_hash )
- gcry_md_write( dfx.mdc_hash, temp, nprefix+2 );
-
- if( ed->mdc_method )
- iobuf_push_filter( ed->buf, mdc_decode_filter, &dfx );
- else
- iobuf_push_filter( ed->buf, decode_filter, &dfx );
-
- proc_packets( procctx, ed->buf );
- ed->buf = NULL;
- if( ed->mdc_method && dfx.eof_seen == 2 )
- rc = gpg_error (GPG_ERR_INV_PACKET);
- else if( ed->mdc_method ) { /* check the mdc */
- int datalen = gcry_md_get_algo_dlen (ed->mdc_method);
-
- gcry_cipher_decrypt (dfx.cipher_hd, dfx.defer, 20, NULL, 0);
- gcry_md_final ( dfx.mdc_hash );
- if( datalen != 20
- || memcmp(gcry_md_read ( dfx.mdc_hash, 0 ), dfx.defer, datalen) )
- rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
- /*log_hexdump("MDC calculated:", gcry_md_read ( dfx.mdc_hash, 0), datalen);*/
- /*log_hexdump("MDC message :", dfx.defer, 20);*/
- }
-
-
- leave:
- gcry_cipher_close(dfx.cipher_hd);
- gcry_md_close ( dfx.mdc_hash );
- return rc;
-}
-
-
-
-/* I think we should merge this with cipher_filter */
-static int
-mdc_decode_filter( void *opaque, int control, iobuf_t a,
- byte *buf, size_t *ret_len)
-{
- decode_filter_ctx_t *dfx = opaque;
- size_t n, size = *ret_len;
- int rc = 0;
- int c;
-
- if( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen ) {
- *ret_len = 0;
- rc = -1;
- }
- else if( control == IOBUFCTRL_UNDERFLOW ) {
- assert(a);
- assert( size > 40 );
-
- /* get at least 20 bytes and put it somewhere ahead in the buffer */
- for(n=20; n < 40 ; n++ ) {
- if( (c = iobuf_get(a)) == -1 )
- break;
- buf[n] = c;
- }
- if( n == 40 ) {
- /* we have enough stuff - flush the deferred stuff */
- /* (we have asserted that the buffer is large enough) */
- if( !dfx->defer_filled ) { /* the first time */
- memcpy(buf, buf+20, 20 );
- n = 20;
- }
- else {
- memcpy(buf, dfx->defer, 20 );
- }
- /* now fill up */
- for(; n < size; n++ ) {
- if( (c = iobuf_get(a)) == -1 )
- break;
- buf[n] = c;
- }
- /* move the last 20 bytes back to the defer buffer */
- /* (okay, we are wasting 20 bytes of supplied buffer) */
- n -= 20;
- memcpy( dfx->defer, buf+n, 20 );
- dfx->defer_filled = 1;
- }
- else if( !dfx->defer_filled ) { /* eof seen buf empty defer */
- /* this is bad because there is an incomplete hash */
- n -= 20;
- memcpy(buf, buf+20, n );
- dfx->eof_seen = 2; /* eof with incomplete hash */
- }
- else { /* eof seen */
- memcpy(buf, dfx->defer, 20 );
- n -= 20;
- memcpy( dfx->defer, buf+n, 20 );
- dfx->eof_seen = 1; /* normal eof */
- }
-
- if( n ) {
- gcry_cipher_decrypt( dfx->cipher_hd, buf, n, NULL, 0);
- gcry_md_write( dfx->mdc_hash, buf, n );
- }
- else {
- assert( dfx->eof_seen );
- rc = -1; /* eof */
- }
- *ret_len = n;
- }
- else if( control == IOBUFCTRL_DESC ) {
- *(char**)buf = "mdc_decode_filter";
- }
- return rc;
-}
-
-static int
-decode_filter( void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len)
-{
- decode_filter_ctx_t *fc = opaque;
- size_t n, size = *ret_len;
- int rc = 0;
-
- if( control == IOBUFCTRL_UNDERFLOW ) {
- assert(a);
- n = iobuf_read( a, buf, size );
- if( n == -1 ) n = 0;
- if( n )
- gcry_cipher_decrypt( fc->cipher_hd, buf, n, NULL, 0);
- else
- rc = -1; /* eof */
- *ret_len = n;
- }
- else if( control == IOBUFCTRL_DESC ) {
- *(char**)buf = "decode_filter";
- }
- return rc;
-}
-
diff --git a/g10/exec.c b/g10/exec.c
deleted file mode 100644
index a49fe15d2..000000000
--- a/g10/exec.c
+++ /dev/null
@@ -1,619 +0,0 @@
-/* exec.c - generic call-a-program code
- * Copyright (C) 2001, 2002, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#ifndef EXEC_TEMPFILE_ONLY
-#include <sys/wait.h>
-#endif
-#ifdef HAVE_DOSISH_SYSTEM
-#include <windows.h>
-#endif
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include "options.h"
-#include "memory.h"
-#include "i18n.h"
-#include "iobuf.h"
-#include "util.h"
-#include "exec.h"
-
-#ifdef NO_EXEC
-int exec_write(struct exec_info **info,const char *program,
- const char *args_in,const char *name,int writeonly,int binary)
-{
- log_error(_("no remote program execution supported\n"));
- return GPG_ERR_GENERAL;
-}
-
-int exec_read(struct exec_info *info) { return GPG_ERR_GENERAL; }
-int exec_finish(struct exec_info *info) { return GPG_ERR_GENERAL; }
-int set_exec_path(const char *path,int method) { return GPG_ERR_GENERAL; }
-
-#else /* ! NO_EXEC */
-
-#ifndef HAVE_MKDTEMP
-char *mkdtemp(char *template);
-#endif
-
-#if defined (_WIN32)
-/* This is a nicer system() for windows that waits for programs to
- return before returning control to the caller. I hate helpful
- computers. */
-static int win_system(const char *command)
-{
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- char *string;
-
- /* We must use a copy of the command as CreateProcess modifies this
- argument. */
- string=xstrdup (command);
-
- memset(&pi,0,sizeof(pi));
- memset(&si,0,sizeof(si));
- si.cb=sizeof(si);
-
- if(!CreateProcess(NULL,string,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
- return -1;
-
- /* Wait for the child to exit */
- WaitForSingleObject(pi.hProcess,INFINITE);
-
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- xfree (string);
-
- return 0;
-}
-#endif
-
-/* method==0 to replace current $PATH, and 1 to append to current
- $PATH. */
-int set_exec_path(const char *path,int method)
-{
- char *p,*curpath=NULL;
- size_t curlen=0;
-
- if(method==1 && (curpath=getenv("PATH")))
- curlen=strlen(curpath)+1;
-
- p=xmalloc (5+curlen+strlen(path)+1);
- strcpy(p,"PATH=");
-
- if(curpath)
- {
- strcat(p,curpath);
- strcat(p,":");
- }
-
- strcat(p,path);
-
- if(DBG_EXTPROG)
- log_debug("set_exec_path method %d: %s\n",method,p);
-
- /* Notice that path is never freed. That is intentional due to the
- way putenv() works. This leaks a few bytes if we call
- set_exec_path multiple times. */
-
- if(putenv(p)!=0)
- return GPG_ERR_GENERAL;
- else
- return 0;
-}
-
-/* Makes a temp directory and filenames */
-static int make_tempdir(struct exec_info *info)
-{
- char *tmp=opt.temp_dir,*namein=info->name,*nameout;
-
- if(!namein)
- namein=info->binary?"tempin" EXTSEP_S "bin":"tempin" EXTSEP_S "txt";
-
- nameout=info->binary?"tempout" EXTSEP_S "bin":"tempout" EXTSEP_S "txt";
-
- /* Make up the temp dir and files in case we need them */
-
- if(tmp==NULL)
- {
-#if defined (_WIN32)
- tmp=xmalloc (256);
- if(GetTempPath(256,tmp)==0)
- strcpy(tmp,"c:\\windows\\temp");
- else
- {
- int len=strlen(tmp);
-
- /* GetTempPath may return with \ on the end */
- while(len>0 && tmp[len-1]=='\\')
- {
- tmp[len-1]='\0';
- len--;
- }
- }
-#else /* More unixish systems */
- tmp=getenv("TMPDIR");
- if(tmp==NULL)
- {
- tmp=getenv("TMP");
- if(tmp==NULL)
- {
-#ifdef __riscos__
- tmp="<Wimp$ScrapDir>.GnuPG";
- mkdir(tmp,0700); /* Error checks occur later on */
-#else
- tmp="/tmp";
-#endif
- }
- }
-#endif
- }
-
- info->tempdir=xmalloc (strlen(tmp)+strlen(DIRSEP_S)+10+1);
-
- sprintf(info->tempdir,"%s" DIRSEP_S "gpg-XXXXXX",tmp);
-
-#if defined (_WIN32)
- xfree (tmp);
-#endif
-
- if(mkdtemp(info->tempdir)==NULL)
- log_error(_("can't create directory `%s': %s\n"),
- info->tempdir,strerror(errno));
- else
- {
- info->madedir=1;
-
- info->tempfile_in=xmalloc (strlen(info->tempdir)+
- strlen(DIRSEP_S)+strlen(namein)+1);
- sprintf(info->tempfile_in,"%s" DIRSEP_S "%s",info->tempdir,namein);
-
- if(!info->writeonly)
- {
- info->tempfile_out=xmalloc (strlen(info->tempdir)+
- strlen(DIRSEP_S)+strlen(nameout)+1);
- sprintf(info->tempfile_out,"%s" DIRSEP_S "%s",info->tempdir,nameout);
- }
- }
-
- return info->madedir?0:GPG_ERR_GENERAL;
-}
-
-/* Expands %i and %o in the args to the full temp files within the
- temp directory. */
-static int expand_args(struct exec_info *info,const char *args_in)
-{
- const char *ch=args_in;
- unsigned int size,len;
-
- info->use_temp_files=0;
- info->keep_temp_files=0;
-
- if(DBG_EXTPROG)
- log_debug("expanding string \"%s\"\n",args_in);
-
- size=100;
- info->command=xmalloc (size);
- len=0;
- info->command[0]='\0';
-
- while(*ch!='\0')
- {
- if(*ch=='%')
- {
- char *append=NULL;
-
- ch++;
-
- switch(*ch)
- {
- case 'O':
- info->keep_temp_files=1;
- /* fall through */
-
- case 'o': /* out */
- if(!info->madedir)
- {
- if(make_tempdir(info))
- goto fail;
- }
- append=info->tempfile_out;
- info->use_temp_files=1;
- break;
-
- case 'I':
- info->keep_temp_files=1;
- /* fall through */
-
- case 'i': /* in */
- if(!info->madedir)
- {
- if(make_tempdir(info))
- goto fail;
- }
- append=info->tempfile_in;
- info->use_temp_files=1;
- break;
-
- case '%':
- append="%";
- break;
- }
-
- if(append)
- {
- size_t applen=strlen(append);
-
- if(applen+len>size-1)
- {
- if(applen<100)
- applen=100;
-
- size+=applen;
- info->command=xrealloc(info->command,size);
- }
-
- strcat(info->command,append);
- len+=strlen(append);
- }
- }
- else
- {
- if(len==size-1) /* leave room for the \0 */
- {
- size+=100;
- info->command=xrealloc(info->command,size);
- }
-
- info->command[len++]=*ch;
- info->command[len]='\0';
- }
-
- ch++;
- }
-
- if(DBG_EXTPROG)
- log_debug("args expanded to \"%s\", use %d, keep %d\n",
- info->command,info->use_temp_files,info->keep_temp_files);
-
- return 0;
-
- fail:
-
- xfree (info->command);
- info->command=NULL;
-
- return GPG_ERR_GENERAL;
-}
-
-/* Either handles the tempfile creation, or the fork/exec. If it
- returns ok, then info->tochild is a FILE * that can be written to.
- The rules are: if there are no args, then it's a fork/exec/pipe.
- If there are args, but no tempfiles, then it's a fork/exec/pipe via
- shell -c. If there are tempfiles, then it's a system. */
-
-int exec_write(struct exec_info **info,const char *program,
- const char *args_in,const char *name,int writeonly,int binary)
-{
- int ret=GPG_ERR_GENERAL;
-
- if(opt.exec_disable && !opt.no_perm_warn)
- {
- log_info(_("external program calls are disabled due to unsafe "
- "options file permissions\n"));
-
- return ret;
- }
-
-#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
- /* There should be no way to get to this spot while still carrying
- setuid privs. Just in case, bomb out if we are. */
- if(getuid()!=geteuid())
- BUG();
-#endif
-
- if(program==NULL && args_in==NULL)
- BUG();
-
- *info=xcalloc (1,sizeof(struct exec_info));
-
- if(name)
- (*info)->name=xstrdup (name);
- (*info)->binary=binary;
- (*info)->writeonly=writeonly;
-
- /* Expand the args, if any */
- if(args_in && expand_args(*info,args_in))
- goto fail;
-
-#ifdef EXEC_TEMPFILE_ONLY
- if(!(*info)->use_temp_files)
- {
- log_error(_("this platform requires temp files when calling external "
- "programs\n"));
- goto fail;
- }
-
-#else /* !EXEC_TEMPFILE_ONLY */
-
- /* If there are no args, or there are args, but no temp files, we
- can use fork/exec/pipe */
- if(args_in==NULL || (*info)->use_temp_files==0)
- {
- int to[2],from[2];
-
- if(pipe(to)==-1)
- goto fail;
-
- if(pipe(from)==-1)
- {
- close(to[0]);
- close(to[1]);
- goto fail;
- }
-
- if(((*info)->child=fork())==-1)
- {
- close(to[0]);
- close(to[1]);
- close(from[0]);
- close(from[1]);
- goto fail;
- }
-
- if((*info)->child==0)
- {
- char *shell=getenv("SHELL");
-
- if(shell==NULL)
- shell="/bin/sh";
-
- /* I'm the child */
-
- /* If the program isn't going to respond back, they get to
- keep their stdout/stderr */
- if(!(*info)->writeonly)
- {
- /* implied close of STDERR */
- if(dup2(STDOUT_FILENO,STDERR_FILENO)==-1)
- _exit(1);
-
- /* implied close of STDOUT */
- close(from[0]);
- if(dup2(from[1],STDOUT_FILENO)==-1)
- _exit(1);
- }
-
- /* implied close of STDIN */
- close(to[1]);
- if(dup2(to[0],STDIN_FILENO)==-1)
- _exit(1);
-
- if(args_in==NULL)
- {
- if(DBG_EXTPROG)
- log_debug("execlp: %s\n",program);
-
- execlp(program,program,(void *)NULL);
- }
- else
- {
- if(DBG_EXTPROG)
- log_debug("execlp: %s -c %s\n",shell,(*info)->command);
-
- execlp(shell,shell,"-c",(*info)->command,(void *)NULL);
- }
-
- /* If we get this far the exec failed. Clean up and return. */
-
- log_error(_("unable to execute %s \"%s\": %s\n"),
- args_in==NULL?"program":"shell",
- args_in==NULL?program:shell,
- strerror(errno));
-
- /* This mimics the POSIX sh behavior - 127 means "not found"
- from the shell. */
- if(errno==ENOENT)
- _exit(127);
-
- _exit(1);
- }
-
- /* I'm the parent */
-
- close(to[0]);
-
- (*info)->tochild=fdopen(to[1],binary?"wb":"w");
- if((*info)->tochild==NULL)
- {
- ret = gpg_error_from_errno (errno);
- close(to[1]);
- goto fail;
- }
-
- close(from[1]);
-
- (*info)->fromchild=iobuf_fdopen(from[0],"r");
- if((*info)->fromchild==NULL)
- {
- ret = gpg_error_from_errno (errno);
- close(from[0]);
- goto fail;
- }
-
- /* fd iobufs are cached?! */
- iobuf_ioctl((*info)->fromchild,3,1,NULL);
-
- return 0;
- }
-#endif /* !EXEC_TEMPFILE_ONLY */
-
- if(DBG_EXTPROG)
- log_debug("using temp file `%s'\n",(*info)->tempfile_in);
-
- /* It's not fork/exec/pipe, so create a temp file */
- (*info)->tochild=fopen((*info)->tempfile_in,binary?"wb":"w");
- if((*info)->tochild==NULL)
- {
- ret = gpg_error_from_errno (errno);
- log_error(_("can't create `%s': %s\n"),
- (*info)->tempfile_in,strerror(errno));
- goto fail;
- }
-
- ret=0;
-
- fail:
- return ret;
-}
-
-int exec_read(struct exec_info *info)
-{
- int ret=GPG_ERR_GENERAL;
-
- fclose(info->tochild);
- info->tochild=NULL;
-
- if(info->use_temp_files)
- {
- if(DBG_EXTPROG)
- log_debug("system() command is %s\n",info->command);
-
-#if defined (_WIN32)
- info->progreturn=win_system(info->command);
-#else
- info->progreturn=system(info->command);
-#endif
-
- if(info->progreturn==-1)
- {
- log_error(_("system error while calling external program: %s\n"),
- strerror(errno));
- info->progreturn=127;
- goto fail;
- }
-
-#if defined(WIFEXITED) && defined(WEXITSTATUS)
- if(WIFEXITED(info->progreturn))
- info->progreturn=WEXITSTATUS(info->progreturn);
- else
- {
- log_error(_("unnatural exit of external program\n"));
- info->progreturn=127;
- goto fail;
- }
-#else
- /* If we don't have the macros, do the best we can. */
- info->progreturn = (info->progreturn & 0xff00) >> 8;
-#endif
-
- /* 127 is the magic value returned from system() to indicate
- that the shell could not be executed, or from /bin/sh to
- indicate that the program could not be executed. */
-
- if(info->progreturn==127)
- {
- log_error(_("unable to execute external program\n"));
- goto fail;
- }
-
- if(!info->writeonly)
- {
- info->fromchild=iobuf_open(info->tempfile_out);
- if(info->fromchild==NULL)
- {
- ret = gpg_error_from_errno (errno);
- log_error(_("unable to read external program response: %s\n"),
- strerror(errno));
- goto fail;
- }
-
- /* Do not cache this iobuf on close */
- iobuf_ioctl(info->fromchild,3,1,NULL);
- }
- }
-
- ret=0;
-
- fail:
- return ret;
-}
-
-int exec_finish(struct exec_info *info)
-{
- int ret=info->progreturn;
-
- if(info->fromchild)
- iobuf_close(info->fromchild);
-
- if(info->tochild)
- fclose(info->tochild);
-
-#ifndef EXEC_TEMPFILE_ONLY
- if(info->child>0)
- {
- if(waitpid(info->child,&info->progreturn,0)!=0 &&
- WIFEXITED(info->progreturn))
- ret=WEXITSTATUS(info->progreturn);
- else
- {
- log_error(_("unnatural exit of external program\n"));
- ret=127;
- }
- }
-#endif
-
- if(info->madedir && !info->keep_temp_files)
- {
- if(info->tempfile_in)
- {
- if(unlink(info->tempfile_in)==-1)
- log_info(_("WARNING: unable to remove tempfile (%s) `%s': %s\n"),
- "in",info->tempfile_in,strerror(errno));
- }
-
- if(info->tempfile_out)
- {
- if(unlink(info->tempfile_out)==-1)
- log_info(_("WARNING: unable to remove tempfile (%s) `%s': %s\n"),
- "out",info->tempfile_out,strerror(errno));
- }
-
- if(rmdir(info->tempdir)==-1)
- log_info(_("WARNING: unable to remove temp directory `%s': %s\n"),
- info->tempdir,strerror(errno));
- }
-
- xfree (info->command);
- xfree (info->name);
- xfree (info->tempdir);
- xfree (info->tempfile_in);
- xfree (info->tempfile_out);
- xfree (info);
-
- return ret;
-}
-#endif /* ! NO_EXEC */
diff --git a/g10/exec.h b/g10/exec.h
deleted file mode 100644
index eda406894..000000000
--- a/g10/exec.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* exec.h
- * Copyright (C) 2001, 2002, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef _EXEC_H_
-#define _EXEC_H_
-
-#include <unistd.h>
-#include <stdio.h>
-#include "../common/iobuf.h"
-
-struct exec_info
-{
- int progreturn,binary,writeonly,madedir,use_temp_files,keep_temp_files;
- pid_t child;
- FILE *tochild;
- iobuf_t fromchild;
- char *command,*name,*tempdir,*tempfile_in,*tempfile_out;
-};
-
-int exec_write(struct exec_info **info,const char *program,
- const char *args_in,const char *name,int writeonly,int binary);
-int exec_read(struct exec_info *info);
-int exec_finish(struct exec_info *info);
-int set_exec_path(const char *path,int method);
-
-#endif /* !_EXEC_H_ */
diff --git a/g10/export.c b/g10/export.c
deleted file mode 100644
index 43d1b21ed..000000000
--- a/g10/export.c
+++ /dev/null
@@ -1,546 +0,0 @@
-/* export.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "options.h"
-#include "packet.h"
-#include "errors.h"
-#include "keydb.h"
-#include "memory.h"
-#include "util.h"
-#include "main.h"
-#include "i18n.h"
-
-static int do_export( STRLIST users, int secret, unsigned int options );
-static int do_export_stream( iobuf_t out, STRLIST users, int secret,
- KBNODE *keyblock_out, unsigned int options,
- int *any );
-static int build_sexp (iobuf_t out, PACKET *pkt, int *indent);
-
-int
-parse_export_options(char *str,unsigned int *options)
-{
- struct parse_options export_opts[]=
- {
- {"include-non-rfc",EXPORT_INCLUDE_NON_RFC},
- {"include-local-sigs",EXPORT_INCLUDE_LOCAL_SIGS},
- {"include-attributes",EXPORT_INCLUDE_ATTRIBUTES},
- {"include-sensitive-revkeys",EXPORT_INCLUDE_SENSITIVE_REVKEYS},
- {"sexp-format",EXPORT_SEXP_FORMAT},
- {NULL,0}
- /* add tags for include revoked and disabled? */
- };
-
- return parse_options(str,options,export_opts);
-}
-
-/****************
- * Export the public keys (to standard out or --output).
- * Depending on opt.armor the output is armored.
- * options are defined in main.h.
- * If USERS is NULL, the complete ring will be exported. */
-int
-export_pubkeys( STRLIST users, unsigned int options )
-{
- return do_export( users, 0, options );
-}
-
-/****************
- * Export to an already opened stream; return -1 if no keys have
- * been exported
- */
-int
-export_pubkeys_stream( iobuf_t out, STRLIST users,
- KBNODE *keyblock_out, unsigned int options )
-{
- int any, rc;
-
- rc = do_export_stream( out, users, 0, keyblock_out, options, &any );
- if( !rc && !any )
- rc = -1;
- return rc;
-}
-
-int
-export_seckeys( STRLIST users )
-{
- /* Use only relevant options for the secret key. */
- unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT);
- return do_export (users, 1, options);
-}
-
-int
-export_secsubkeys( STRLIST users )
-{
- /* Use only relevant options for the secret key. */
- unsigned int options = (opt.export_options & EXPORT_SEXP_FORMAT);
- return do_export( users, 2, options);
-}
-
-static int
-do_export (STRLIST users, int secret, unsigned int options)
-{
- iobuf_t out = NULL;
- int any, rc;
- armor_filter_context_t afx;
- compress_filter_context_t zfx;
-
- memset (&afx, 0, sizeof afx);
- memset (&zfx, 0, sizeof zfx);
-
- rc = open_outfile (NULL, 0, &out);
- if (rc)
- return rc;
-
- if (!(options & EXPORT_SEXP_FORMAT))
- {
- if (opt.armor)
- {
- afx.what = secret?5:1;
- iobuf_push_filter( out, armor_filter, &afx );
- }
- if (opt.compress_keys && opt.compress)
- iobuf_push_filter( out, compress_filter, &zfx );
- }
- rc = do_export_stream (out, users, secret, NULL, options, &any );
-
- if (rc || !any)
- iobuf_cancel (out);
- else
- iobuf_close (out);
- return rc;
-}
-
-
-/* If keyblock_out is non-NULL, AND the exit code is zero, then it
- contains a pointer to the first keyblock found and exported. No
- other keyblocks are exported. The caller must free it. */
-static int
-do_export_stream( iobuf_t out, STRLIST users, int secret,
- KBNODE *keyblock_out, unsigned int options, int *any )
-{
- int rc = 0;
- PACKET pkt;
- KBNODE keyblock = NULL;
- KBNODE kbctx, node;
- size_t ndesc, descindex;
- KEYDB_SEARCH_DESC *desc = NULL;
- KEYDB_HANDLE kdbhd;
- STRLIST sl;
- int indent = 0;
-
- *any = 0;
- init_packet( &pkt );
- kdbhd = keydb_new (secret);
-
- if (!users) {
- ndesc = 1;
- desc = xcalloc (1, ndesc * sizeof *desc);
- desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
- }
- else {
- for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++)
- ;
- desc = xmalloc ( ndesc * sizeof *desc);
-
- for (ndesc=0, sl=users; sl; sl = sl->next) {
- if (classify_user_id (sl->d, desc+ndesc))
- ndesc++;
- else
- log_error (_("key `%s' not found: %s\n"),
- sl->d, gpg_strerror (GPG_ERR_INV_USER_ID));
- }
-
- /* it would be nice to see which of the given users did
- actually match one in the keyring. To implement this we
- need to have a found flag for each entry in desc and to set
- this we must check all those entries after a match to mark
- all matched one - currently we stop at the first match. To
- do this we need an extra flag to enable this feature so */
- }
-
- while (!(rc = keydb_search2 (kdbhd, desc, ndesc, &descindex))) {
- int sha1_warned=0,skip_until_subkey=0;
- u32 sk_keyid[2];
-
- if (!users)
- desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
-
- /* read the keyblock */
- rc = keydb_get_keyblock (kdbhd, &keyblock );
- if( rc ) {
- log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) );
- goto leave;
- }
-
- /* do not export keys which are incompatible with rfc2440 */
- if( !(options&EXPORT_INCLUDE_NON_RFC) &&
- (node = find_kbnode( keyblock, PKT_PUBLIC_KEY )) ) {
- PKT_public_key *pk = node->pkt->pkt.public_key;
- if( pk->version == 3 && pk->pubkey_algo > 3 ) {
- log_info(_("key %08lX: not a rfc2440 key - skipped\n"),
- (ulong)keyid_from_pk( pk, NULL) );
- continue;
- }
- }
-
- node=find_kbnode( keyblock, PKT_SECRET_KEY );
- if(node)
- {
- PKT_secret_key *sk=node->pkt->pkt.secret_key;
-
- keyid_from_sk(sk,sk_keyid);
-
- /* we can't apply GNU mode 1001 on an unprotected key */
- if( secret == 2 && !sk->is_protected )
- {
- log_info(_("key %08lX: not protected - skipped\n"),
- (ulong)sk_keyid[1]);
- continue;
- }
-
- /* no v3 keys with GNU mode 1001 */
- if( secret == 2 && sk->version == 3 )
- {
- log_info(_("key %08lX: PGP 2.x style key - skipped\n"),
- (ulong)sk_keyid[1]);
- continue;
- }
- }
-
- /* and write it */
- for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) {
- if( skip_until_subkey )
- {
- if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY
- || node->pkt->pkttype==PKT_SECRET_SUBKEY)
- skip_until_subkey=0;
- else
- continue;
- }
-
- /* don't export any comment packets but those in the
- * secret keyring */
- if( !secret && node->pkt->pkttype == PKT_COMMENT )
- continue;
-
- /* make sure that ring_trust packets never get exported */
- if (node->pkt->pkttype == PKT_RING_TRUST)
- continue;
-
- /* If exact is set, then we only export what was requested
- (plus the primary key, if the user didn't specifically
- request it) */
- if(desc[descindex].exact
- && (node->pkt->pkttype==PKT_PUBLIC_SUBKEY
- || node->pkt->pkttype==PKT_SECRET_SUBKEY))
- {
- u32 kid[2];
- byte fpr[MAX_FINGERPRINT_LEN];
- size_t fprlen;
-
- switch(desc[descindex].mode)
- {
- case KEYDB_SEARCH_MODE_SHORT_KID:
- case KEYDB_SEARCH_MODE_LONG_KID:
- if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
- keyid_from_pk(node->pkt->pkt.public_key,kid);
- else
- keyid_from_sk(node->pkt->pkt.secret_key,kid);
- break;
-
- case KEYDB_SEARCH_MODE_FPR16:
- case KEYDB_SEARCH_MODE_FPR20:
- case KEYDB_SEARCH_MODE_FPR:
- if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
- fingerprint_from_pk(node->pkt->pkt.public_key,
- fpr,&fprlen);
- else
- fingerprint_from_sk(node->pkt->pkt.secret_key,
- fpr,&fprlen);
- break;
-
- default:
- break;
- }
-
- switch(desc[descindex].mode)
- {
- case KEYDB_SEARCH_MODE_SHORT_KID:
- if (desc[descindex].u.kid[1] != kid[1])
- skip_until_subkey=1;
- break;
- case KEYDB_SEARCH_MODE_LONG_KID:
- if (desc[descindex].u.kid[0] != kid[0]
- || desc[descindex].u.kid[1] != kid[1])
- skip_until_subkey=1;
- break;
- case KEYDB_SEARCH_MODE_FPR16:
- if (memcmp (desc[descindex].u.fpr, fpr, 16))
- skip_until_subkey=1;
- break;
- case KEYDB_SEARCH_MODE_FPR20:
- case KEYDB_SEARCH_MODE_FPR:
- if (memcmp (desc[descindex].u.fpr, fpr, 20))
- skip_until_subkey=1;
- break;
- default:
- break;
- }
-
- if(skip_until_subkey)
- continue;
- }
-
- if( node->pkt->pkttype == PKT_SIGNATURE ) {
- /* do not export packets which are marked as not exportable */
- if( !(options&EXPORT_INCLUDE_LOCAL_SIGS) &&
- !node->pkt->pkt.signature->flags.exportable )
- continue; /* not exportable */
-
- /* Do not export packets with a "sensitive" revocation
- key unless the user wants us to. Note that we do
- export these when issuing the actual revocation (see
- revoke.c). */
- if( !(options&EXPORT_INCLUDE_SENSITIVE_REVKEYS) &&
- node->pkt->pkt.signature->revkey ) {
- int i;
-
- for(i=0;i<node->pkt->pkt.signature->numrevkeys;i++)
- if(node->pkt->pkt.signature->revkey[i]->class & 0x40)
- break;
-
- if(i<node->pkt->pkt.signature->numrevkeys)
- continue;
- }
- }
-
- /* Don't export attribs? */
- if( !(options&EXPORT_INCLUDE_ATTRIBUTES) &&
- node->pkt->pkttype == PKT_USER_ID &&
- node->pkt->pkt.user_id->attrib_data ) {
- /* Skip until we get to something that is not an attrib
- or a signature on an attrib */
- while(kbctx->next && kbctx->next->pkt->pkttype==PKT_SIGNATURE) {
- kbctx=kbctx->next;
- }
-
- continue;
- }
-
- if( secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY ) {
- /* we don't want to export the secret parts of the
- * primary key, this is done by using GNU protection mode 1001
- */
- int save_mode = node->pkt->pkt.secret_key->protect.s2k.mode;
- node->pkt->pkt.secret_key->protect.s2k.mode = 1001;
- if ((options&EXPORT_SEXP_FORMAT))
- rc = build_sexp (out, node->pkt, &indent);
- else
- rc = build_packet (out, node->pkt);
- node->pkt->pkt.secret_key->protect.s2k.mode = save_mode;
- }
- else {
- /* Warn the user if the secret key or any of the secret
- subkeys are protected with SHA1 and we have
- simple_sk_checksum set. */
- if(!sha1_warned && opt.simple_sk_checksum &&
- (node->pkt->pkttype==PKT_SECRET_KEY ||
- node->pkt->pkttype==PKT_SECRET_SUBKEY) &&
- node->pkt->pkt.secret_key->protect.sha1chk)
- {
- /* I hope this warning doesn't confuse people. */
- log_info(_("WARNING: secret key %08lX does not have a "
- "simple SK checksum\n"),(ulong)sk_keyid[1]);
-
- sha1_warned=1;
- }
-
- if ((options&EXPORT_SEXP_FORMAT))
- rc = build_sexp (out, node->pkt, &indent);
- else
- rc = build_packet (out, node->pkt);
- }
-
- if( rc ) {
- log_error("build_packet(%d) failed: %s\n",
- node->pkt->pkttype, gpg_strerror (rc) );
- goto leave;
- }
- }
- if ((options&EXPORT_SEXP_FORMAT) && indent)
- {
- for (; indent; indent--)
- iobuf_put (out, ')');
- iobuf_put (out, '\n');
- }
-
- ++*any;
- if(keyblock_out)
- {
- *keyblock_out=keyblock;
- break;
- }
- }
- if ((options&EXPORT_SEXP_FORMAT) && indent)
- {
- for (; indent; indent--)
- iobuf_put (out, ')');
- iobuf_put (out, '\n');
- }
- if( rc == -1 )
- rc = 0;
-
- leave:
- xfree (desc);
- keydb_release (kdbhd);
- if(rc || keyblock_out==NULL)
- release_kbnode( keyblock );
- if( !*any )
- log_info(_("WARNING: nothing exported\n"));
- return rc;
-}
-
-
-static int
-write_sexp_line (iobuf_t out, int *indent, const char *text)
-{
- int i;
-
- for (i=0; i < *indent; i++)
- iobuf_put (out, ' ');
- iobuf_writestr (out, text);
- return 0;
-}
-
-static int
-write_sexp_keyparm (iobuf_t out, int *indent, const char *name, gcry_mpi_t a)
-{
- int rc;
- unsigned char *buffer;
-
- write_sexp_line (out, indent, "(");
- iobuf_writestr (out, name);
- iobuf_writestr (out, " #");
-
- rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a);
- assert (!rc);
- iobuf_writestr (out, buffer);
- iobuf_writestr (out, "#)");
- gcry_free (buffer);
- return 0;
-}
-
-static int
-build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent)
-{
- PKT_secret_key *sk = pkt->pkt.secret_key;
- char tmpbuf[100];
-
- if (pkt->pkttype == PKT_SECRET_KEY)
- {
- iobuf_writestr (out, "(openpgp-key\n");
- (*indent)++;
- }
- else
- {
- iobuf_writestr (out, " (subkey\n");
- (*indent)++;
- }
- (*indent)++;
- write_sexp_line (out, indent, "(private-key\n");
- (*indent)++;
- if (is_RSA (sk->pubkey_algo) && !sk->is_protected)
- {
- write_sexp_line (out, indent, "(rsa\n");
- (*indent)++;
- write_sexp_keyparm (out, indent, "n", sk->skey[0]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "e", sk->skey[1]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "d", sk->skey[2]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "p", sk->skey[3]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "q", sk->skey[4]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "u", sk->skey[5]);
- iobuf_put (out,')'); iobuf_put (out,'\n');
- (*indent)--;
- }
- else if (sk->pubkey_algo == PUBKEY_ALGO_DSA && !sk->is_protected)
- {
- write_sexp_line (out, indent, "(dsa\n");
- (*indent)++;
- write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "q", sk->skey[1]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "x", sk->skey[4]);
- iobuf_put (out,')'); iobuf_put (out,'\n');
- (*indent)--;
- }
- else if (is_ELGAMAL (sk->pubkey_algo) && !sk->is_protected)
- {
- write_sexp_line (out, indent, "(elg\n");
- (*indent)++;
- write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n');
- write_sexp_keyparm (out, indent, "x", sk->skey[4]);
- iobuf_put (out,')'); iobuf_put (out,'\n');
- (*indent)--;
- }
- write_sexp_line (out, indent, "(attrib\n"); (*indent)++;
- sprintf (tmpbuf, "(created \"%lu\"", (unsigned long)sk->timestamp);
- write_sexp_line (out, indent, tmpbuf);
- iobuf_put (out,')'); (*indent)--; /* close created */
- iobuf_put (out,')'); (*indent)--; /* close attrib */
- iobuf_put (out,')'); (*indent)--; /* close private-key */
- if (pkt->pkttype != PKT_SECRET_KEY)
- iobuf_put (out,')'), (*indent)--; /* close subkey */
- iobuf_put (out,'\n');
-
- return 0;
-}
-
-
-/* For some packet types we write them in a S-Exp like format. This is
- still EXPERIMENTAL and subject to change. */
-static int
-build_sexp (iobuf_t out, PACKET *pkt, int *indent)
-{
- int rc;
-
- switch (pkt->pkttype)
- {
- case PKT_SECRET_KEY:
- case PKT_SECRET_SUBKEY:
- rc = build_sexp_seckey (out, pkt, indent);
- break;
- default:
- rc = 0;
- break;
- }
- return rc;
-}
-
diff --git a/g10/filter.h b/g10/filter.h
deleted file mode 100644
index 12c5cebed..000000000
--- a/g10/filter.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/* filter.h
- * Copyright (C) 1998, 1999, 2000, 2001 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef G10_FILTER_H
-#define G10_FILTER_H
-
-#include "types.h"
-#include "cipher.h"
-#include "iobuf.h"
-
-typedef struct {
- MD_HANDLE md; /* catch all */
- MD_HANDLE md2; /* if we want to calculate an alternate hash */
- size_t maxbuf_size;
-} md_filter_context_t;
-
-typedef struct {
- /* these fields may be initialized */
- int what; /* what kind of armor headers to write */
- int only_keyblocks; /* skip all headers but ".... key block" */
- const char *hdrlines; /* write these headerlines */
-
- /* these fileds must be initialized to zero */
- int no_openpgp_data; /* output flag: "No valid OpenPGP data found" */
-
- /* the following fields must be initialized to zero */
- int inp_checked; /* set if the input has been checked */
- int inp_bypass; /* set if the input is not armored */
- int in_cleartext; /* clear text message */
- int not_dash_escaped; /* clear text is not dash escaped */
- int hashes; /* detected hash algorithms */
- int faked; /* we are faking a literal data packet */
- int truncated; /* number of truncated lines */
- int qp_detected;
- int pgp2mode;
-
- byte *buffer; /* malloced buffer */
- unsigned buffer_size; /* and size of this buffer */
- unsigned buffer_len; /* used length of the buffer */
- unsigned buffer_pos; /* read position */
-
- byte radbuf[4];
- int idx, idx2;
- u32 crc;
-
- int status; /* an internal state flag */
- int cancel;
- int any_data; /* any valid armored data seen */
- int pending_lf; /* used together with faked */
-} armor_filter_context_t;
-
-struct unarmor_pump_s;
-typedef struct unarmor_pump_s *UnarmorPump;
-
-
-struct compress_filter_context_s {
- int status;
- void *opaque; /* (used for z_stream) */
- byte *inbuf;
- unsigned inbufsize;
- byte *outbuf;
- unsigned outbufsize;
- int algo; /* compress algo */
- int algo1hack;
- int new_ctb;
- void (*release)(struct compress_filter_context_s*);
-};
-typedef struct compress_filter_context_s compress_filter_context_t;
-
-
-typedef struct {
- DEK *dek;
- u32 datalen;
- CIPHER_HANDLE cipher_hd;
- int header;
- MD_HANDLE mdc_hash;
- byte enchash[20];
- int create_mdc; /* flag will be set by the cipher filter */
-} cipher_filter_context_t;
-
-
-
-typedef struct {
- byte *buffer; /* malloced buffer */
- unsigned buffer_size; /* and size of this buffer */
- unsigned buffer_len; /* used length of the buffer */
- unsigned buffer_pos; /* read position */
- int truncated; /* number of truncated lines */
- int not_dash_escaped;
- int escape_from;
- MD_HANDLE md;
- int pending_lf;
- int pending_esc;
-} text_filter_context_t;
-
-
-typedef struct {
- char *what; /* description */
- u32 last_time; /* last time reported */
- unsigned long last; /* last amount reported */
- unsigned long offset; /* current amount */
- unsigned long total; /* total amount */
-} progress_filter_context_t;
-
-/* encrypt_filter_context_t defined in main.h */
-
-/*-- mdfilter.c --*/
-int md_filter( void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len);
-void free_md_filter_context( md_filter_context_t *mfx );
-
-/*-- armor.c --*/
-int use_armor_filter( iobuf_t a );
-int armor_filter( void *opaque, int control,
- iobuf_t chain, byte *buf, size_t *ret_len);
-UnarmorPump unarmor_pump_new (void);
-void unarmor_pump_release (UnarmorPump x);
-int unarmor_pump (UnarmorPump x, int c);
-
-/*-- compress.c --*/
-int compress_filter( void *opaque, int control,
- iobuf_t chain, byte *buf, size_t *ret_len);
-
-/*-- cipher.c --*/
-int cipher_filter( void *opaque, int control,
- iobuf_t chain, byte *buf, size_t *ret_len);
-
-/*-- textfilter.c --*/
-int text_filter( void *opaque, int control,
- iobuf_t chain, byte *buf, size_t *ret_len);
-int copy_clearsig_text( iobuf_t out, iobuf_t inp, MD_HANDLE md,
- int escape_dash, int escape_from, int pgp2mode );
-
-/*-- progress.c --*/
-int progress_filter (void *opaque, int control,
- iobuf_t a, byte *buf, size_t *ret_len);
-void handle_progress (progress_filter_context_t *pfx,
- iobuf_t inp, const char *name);
-
-#endif /*G10_FILTER_H*/
diff --git a/g10/free-packet.c b/g10/free-packet.c
deleted file mode 100644
index 7ced327f5..000000000
--- a/g10/free-packet.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/* free-packet.c - cleanup stuff for packets
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
- * 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "packet.h"
-#include "iobuf.h"
-#include "mpi.h"
-#include "util.h"
-#include "cipher.h"
-#include "memory.h"
-#include "options.h"
-
-void
-free_symkey_enc( PKT_symkey_enc *enc )
-{
- xfree (enc);
-}
-
-void
-free_pubkey_enc( PKT_pubkey_enc *enc )
-{
- int n, i;
- n = pubkey_get_nenc( enc->pubkey_algo );
- if( !n )
- mpi_release (enc->data[0]);
- for(i=0; i < n; i++ )
- mpi_release ( enc->data[i] );
- xfree (enc);
-}
-
-void
-free_seckey_enc( PKT_signature *sig )
-{
- int n, i;
-
- n = pubkey_get_nsig( sig->pubkey_algo );
- if( !n )
- mpi_release (sig->data[0]);
- for(i=0; i < n; i++ )
- mpi_release ( sig->data[i] );
-
- xfree (sig->revkey);
- xfree (sig->hashed);
- xfree (sig->unhashed);
- xfree (sig);
-}
-
-
-void
-release_public_key_parts( PKT_public_key *pk )
-{
- int n, i;
- n = pubkey_get_npkey( pk->pubkey_algo );
- if( !n )
- mpi_release (pk->pkey[0]);
- for(i=0; i < n; i++ ) {
- mpi_release ( pk->pkey[i] );
- pk->pkey[i] = NULL;
- }
- if (pk->prefs) {
- xfree (pk->prefs);
- pk->prefs = NULL;
- }
- if (pk->user_id) {
- free_user_id (pk->user_id);
- pk->user_id = NULL;
- }
- if (pk->revkey) {
- xfree (pk->revkey);
- pk->revkey=NULL;
- pk->numrevkeys=0;
- }
-}
-
-
-void
-free_public_key( PKT_public_key *pk )
-{
- release_public_key_parts( pk );
- xfree (pk);
-}
-
-
-static subpktarea_t *
-cp_subpktarea (subpktarea_t *s )
-{
- subpktarea_t *d;
-
- if( !s )
- return NULL;
- d = xmalloc (sizeof (*d) + s->size - 1 );
- d->size = s->size;
- d->len = s->len;
- memcpy (d->data, s->data, s->len);
- return d;
-}
-
-/*
- * Return a copy of the preferences
- */
-prefitem_t *
-copy_prefs (const prefitem_t *prefs)
-{
- size_t n;
- prefitem_t *new;
-
- if (!prefs)
- return NULL;
-
- for (n=0; prefs[n].type; n++)
- ;
- new = xmalloc ( sizeof (*new) * (n+1));
- for (n=0; prefs[n].type; n++) {
- new[n].type = prefs[n].type;
- new[n].value = prefs[n].value;
- }
- new[n].type = PREFTYPE_NONE;
- new[n].value = 0;
-
- return new;
-}
-
-
-PKT_public_key *
-copy_public_key ( PKT_public_key *d, PKT_public_key *s)
-{
- int n, i;
-
- if( !d )
- d = xmalloc (sizeof *d);
- memcpy( d, s, sizeof *d );
- d->user_id = scopy_user_id (s->user_id);
- d->prefs = copy_prefs (s->prefs);
- n = pubkey_get_npkey( s->pubkey_algo );
- if( !n )
- d->pkey[0] = mpi_copy(s->pkey[0]);
- else {
- for(i=0; i < n; i++ )
- d->pkey[i] = mpi_copy( s->pkey[i] );
- }
- if( !s->revkey && s->numrevkeys )
- BUG();
- if( s->numrevkeys ) {
- d->revkey = xmalloc (sizeof(struct revocation_key)*s->numrevkeys);
- memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
- }
- else
- d->revkey = NULL;
- return d;
-}
-
-/****************
- * Replace all common parts of a sk by the one from the public key.
- * This is a hack and a better solution will be to just store the real secret
- * parts somewhere and don't duplicate all the other stuff.
- */
-void
-copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
-{
- sk->expiredate = pk->expiredate;
- sk->pubkey_algo = pk->pubkey_algo;
- sk->pubkey_usage= pk->pubkey_usage;
- sk->req_usage = pk->req_usage;
- sk->req_algo = pk->req_algo;
- sk->has_expired = pk->has_expired;
- sk->is_revoked = pk->is_revoked;
- sk->is_valid = pk->is_valid;
- sk->main_keyid[0]= pk->main_keyid[0];
- sk->main_keyid[1]= pk->main_keyid[1];
- sk->keyid[0] = pk->keyid[0];
- sk->keyid[1] = pk->keyid[1];
-}
-
-PKT_signature *
-copy_signature( PKT_signature *d, PKT_signature *s )
-{
- int n, i;
-
- if( !d )
- d = xmalloc (sizeof *d);
- memcpy( d, s, sizeof *d );
- n = pubkey_get_nsig( s->pubkey_algo );
- if( !n )
- d->data[0] = mpi_copy(s->data[0]);
- else {
- for(i=0; i < n; i++ )
- d->data[i] = mpi_copy( s->data[i] );
- }
- d->hashed = cp_subpktarea (s->hashed);
- d->unhashed = cp_subpktarea (s->unhashed);
- if(s->numrevkeys)
- {
- d->revkey=NULL;
- d->numrevkeys=0;
- parse_revkeys(d);
- }
- return d;
-}
-
-
-/*
- * shallow copy of the user ID
- */
-PKT_user_id *
-scopy_user_id (PKT_user_id *s)
-{
- if (s)
- s->ref++;
- return s;
-}
-
-
-
-void
-release_secret_key_parts( PKT_secret_key *sk )
-{
- int n, i;
-
- n = pubkey_get_nskey( sk->pubkey_algo );
- if( !n )
- mpi_release (sk->skey[0]);
- for(i=0; i < n; i++ ) {
- mpi_release ( sk->skey[i] );
- sk->skey[i] = NULL;
- }
-}
-
-void
-free_secret_key( PKT_secret_key *sk )
-{
- release_secret_key_parts( sk );
- xfree (sk);
-}
-
-PKT_secret_key *
-copy_secret_key( PKT_secret_key *d, PKT_secret_key *s )
-{
- int n, i;
-
- if( !d )
- d = xmalloc (sizeof *d);
- memcpy( d, s, sizeof *d );
- n = pubkey_get_nskey( s->pubkey_algo );
- if( !n )
- d->skey[0] = mpi_copy(s->skey[0]);
- else {
- for(i=0; i < n; i++ )
- d->skey[i] = mpi_copy( s->skey[i] );
- }
- return d;
-}
-
-void
-free_comment( PKT_comment *rem )
-{
- xfree (rem);
-}
-
-void
-free_attributes(PKT_user_id *uid)
-{
- xfree (uid->attribs);
- xfree (uid->attrib_data);
-
- uid->attribs=NULL;
- uid->attrib_data=NULL;
- uid->attrib_len=0;
-}
-
-void
-free_user_id (PKT_user_id *uid)
-{
- assert (uid->ref > 0);
- if (--uid->ref)
- return;
-
- free_attributes(uid);
- xfree (uid->prefs);
- xfree (uid->namehash);
- xfree (uid);
-}
-
-void
-free_compressed( PKT_compressed *zd )
-{
- if( zd->buf ) { /* have to skip some bytes */
- /* don't have any information about the length, so
- * we assume this is the last packet */
- while( iobuf_read( zd->buf, NULL, 1<<30 ) != -1 )
- ;
- }
- xfree (zd);
-}
-
-void
-free_encrypted( PKT_encrypted *ed )
-{
- if( ed->buf ) { /* have to skip some bytes */
- if( iobuf_in_block_mode(ed->buf) ) {
- while( iobuf_read( ed->buf, NULL, 1<<30 ) != -1 )
- ;
- }
- else {
- while( ed->len ) { /* skip the packet */
- int n = iobuf_read( ed->buf, NULL, ed->len );
- if( n == -1 )
- ed->len = 0;
- else
- ed->len -= n;
- }
- }
- }
- xfree (ed);
-}
-
-
-void
-free_plaintext( PKT_plaintext *pt )
-{
- if( pt->buf ) { /* have to skip some bytes */
- if( iobuf_in_block_mode(pt->buf) ) {
- while( iobuf_read( pt->buf, NULL, 1<<30 ) != -1 )
- ;
- }
- else {
- while( pt->len ) { /* skip the packet */
- int n = iobuf_read( pt->buf, NULL, pt->len );
- if( n == -1 )
- pt->len = 0;
- else
- pt->len -= n;
- }
- }
- }
- xfree (pt);
-}
-
-/****************
- * Free the packet in pkt.
- */
-void
-free_packet( PACKET *pkt )
-{
- if( !pkt || !pkt->pkt.generic )
- return;
-
- if( DBG_MEMORY )
- log_debug("free_packet() type=%d\n", pkt->pkttype );
-
- switch( pkt->pkttype ) {
- case PKT_SIGNATURE:
- free_seckey_enc( pkt->pkt.signature );
- break;
- case PKT_PUBKEY_ENC:
- free_pubkey_enc( pkt->pkt.pubkey_enc );
- break;
- case PKT_SYMKEY_ENC:
- free_symkey_enc( pkt->pkt.symkey_enc );
- break;
- case PKT_PUBLIC_KEY:
- case PKT_PUBLIC_SUBKEY:
- free_public_key( pkt->pkt.public_key );
- break;
- case PKT_SECRET_KEY:
- case PKT_SECRET_SUBKEY:
- free_secret_key( pkt->pkt.secret_key );
- break;
- case PKT_COMMENT:
- free_comment( pkt->pkt.comment );
- break;
- case PKT_USER_ID:
- free_user_id( pkt->pkt.user_id );
- break;
- case PKT_COMPRESSED:
- free_compressed( pkt->pkt.compressed);
- break;
- case PKT_ENCRYPTED:
- case PKT_ENCRYPTED_MDC:
- free_encrypted( pkt->pkt.encrypted );
- break;
- case PKT_PLAINTEXT:
- free_plaintext( pkt->pkt.plaintext );
- break;
- default:
- xfree ( pkt->pkt.generic );
- break;
- }
- pkt->pkt.generic = NULL;
-}
-
-/****************
- * returns 0 if they match.
- */
-int
-cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
-{
- int n, i;
-
- if( a->timestamp != b->timestamp )
- return -1;
- if( a->version < 4 && a->expiredate != b->expiredate )
- return -1;
- if( a->pubkey_algo != b->pubkey_algo )
- return -1;
-
- n = pubkey_get_npkey( b->pubkey_algo );
- if( !n )
- return -1; /* can't compare due to unknown algorithm */
- for(i=0; i < n; i++ ) {
- if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
- return -1;
- }
-
- return 0;
-}
-
-/****************
- * Returns 0 if they match.
- * We only compare the public parts.
- */
-int
-cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b )
-{
- int n, i;
-
- if( a->timestamp != b->timestamp )
- return -1;
- if( a->version < 4 && a->expiredate != b->expiredate )
- return -1;
- if( a->pubkey_algo != b->pubkey_algo )
- return -1;
-
- n = pubkey_get_npkey( b->pubkey_algo );
- if( !n )
- return -1; /* can't compare due to unknown algorithm */
- for(i=0; i < n; i++ ) {
- if( mpi_cmp( a->skey[i], b->skey[i] ) )
- return -1;
- }
-
- return 0;
-}
-
-/****************
- * Returns 0 if they match.
- */
-int
-cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
-{
- int n, i;
-
- if( pk->timestamp != sk->timestamp )
- return -1;
- if( pk->version < 4 && pk->expiredate != sk->expiredate )
- return -1;
- if( pk->pubkey_algo != sk->pubkey_algo )
- return -1;
-
- n = pubkey_get_npkey( pk->pubkey_algo );
- if( !n )
- return -1; /* can't compare due to unknown algorithm */
- for(i=0; i < n; i++ ) {
- if( mpi_cmp( pk->pkey[i] , sk->skey[i] ) )
- return -1;
- }
- return 0;
-}
-
-
-
-int
-cmp_signatures( PKT_signature *a, PKT_signature *b )
-{
- int n, i;
-
- if( a->keyid[0] != b->keyid[0] )
- return -1;
- if( a->keyid[1] != b->keyid[1] )
- return -1;
- if( a->pubkey_algo != b->pubkey_algo )
- return -1;
-
- n = pubkey_get_nsig( a->pubkey_algo );
- if( !n )
- return -1; /* can't compare due to unknown algorithm */
- for(i=0; i < n; i++ ) {
- if( mpi_cmp( a->data[i] , b->data[i] ) )
- return -1;
- }
- return 0;
-}
-
-
-/****************
- * Returns: true if the user ids do not match
- */
-int
-cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
-{
- int res=1;
-
- if( a == b )
- return 0;
-
- if( a->attrib_data && b->attrib_data )
- {
- res = a->attrib_len - b->attrib_len;
- if( !res )
- res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len );
- }
- else if( !a->attrib_data && !b->attrib_data )
- {
- res = a->len - b->len;
- if( !res )
- res = memcmp( a->name, b->name, a->len );
- }
-
- return res;
-}
diff --git a/g10/g10.c b/g10/g10.c
deleted file mode 100644
index 915011026..000000000
--- a/g10/g10.c
+++ /dev/null
@@ -1,3367 +0,0 @@
-/* g10.c - The GnuPG utility (main for gpg)
- * Copyright (C) 1998,1999,2000,2001,2002,2003
- * 2004 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <assert.h>
-#ifdef HAVE_DOSISH_SYSTEM
-#include <fcntl.h> /* for setmode() */
-#endif
-#ifdef HAVE_STAT
-#include <sys/stat.h> /* for stat() */
-#endif
-#include <assuan.h>
-
-#define INCLUDED_BY_MAIN_MODULE 1
-#include "gpg.h"
-#include "packet.h"
-#include "iobuf.h"
-#include "memory.h"
-#include "util.h"
-#include "main.h"
-#include "options.h"
-#include "keydb.h"
-#include "trustdb.h"
-#include "mpi.h"
-#include "cipher.h"
-#include "filter.h"
-#include "ttyio.h"
-#include "i18n.h"
-#include "status.h"
-#include "keyserver-internal.h"
-#include "exec.h"
-
-enum cmd_and_opt_values { aNull = 0,
- oArmor = 'a',
- aDetachedSign = 'b',
- aSym = 'c',
- aDecrypt = 'd',
- aEncr = 'e',
- oInteractive = 'i',
- aListKeys = 'k',
- aListSecretKeys = 'K',
- oDryRun = 'n',
- oOutput = 'o',
- oQuiet = 'q',
- oRecipient = 'r',
- oHiddenRecipient = 'R',
- aSign = 's',
- oTextmodeShort= 't',
- oUser = 'u',
- oVerbose = 'v',
- oCompress = 'z',
- oSetNotation = 'N',
- oBatch = 500,
- aGPGConfList,
- oSigNotation,
- oCertNotation,
- oShowNotation,
- oNoShowNotation,
- aEncrFiles,
- aDecryptFiles,
- aClearsign,
- aStore,
- aKeygen,
- aSignEncr,
- aSignSym,
- aSignKey,
- aLSignKey,
- aNRSignKey,
- aNRLSignKey,
- aListPackets,
- aEditKey,
- aDeleteKeys,
- aDeleteSecretKeys,
- aDeleteSecretAndPublicKeys,
- aImport,
- aFastImport,
- aVerify,
- aVerifyFiles,
- aListSigs,
- aSendKeys,
- aRecvKeys,
- aSearchKeys,
- aExport,
- aExportAll,
- aExportSecret,
- aExportSecretSub,
- aCheckKeys,
- aGenRevoke,
- aDesigRevoke,
- aPrimegen,
- aPrintMD,
- aPrintMDs,
- aCheckTrustDB,
- aUpdateTrustDB,
- aFixTrustDB,
- aListTrustDB,
- aListTrustPath,
- aExportOwnerTrust,
- aListOwnerTrust,
- aImportOwnerTrust,
- aDeArmor,
- aEnArmor,
- aGenRandom,
- aPipeMode,
- aRebuildKeydbCaches,
- aRefreshKeys,
- aCardStatus,
- aCardEdit,
- aChangePIN,
-
- oTextmode,
- oNoTextmode,
- oExpert,
- oNoExpert,
- oAskSigExpire,
- oNoAskSigExpire,
- oAskCertExpire,
- oNoAskCertExpire,
- oFingerprint,
- oWithFingerprint,
- oAnswerYes,
- oAnswerNo,
- oDefCertCheckLevel,
- oKeyring,
- oPrimaryKeyring,
- oSecretKeyring,
- oShowKeyring,
- oDefaultKey,
- oDefRecipient,
- oDefRecipientSelf,
- oNoDefRecipient,
- oOptions,
- oDebug,
- oDebugLevel,
- oDebugAll,
- oStatusFD,
-#ifdef __riscos__
- oStatusFile,
-#endif /* __riscos__ */
- oAttributeFD,
-#ifdef __riscos__
- oAttributeFile,
-#endif /* __riscos__ */
- oSKComments,
- oNoSKComments,
- oEmitVersion,
- oNoEmitVersion,
- oCompletesNeeded,
- oMarginalsNeeded,
- oMaxCertDepth,
- oLoadExtension,
- oGnuPG,
- oRFC1991,
- oRFC2440,
- oOpenPGP,
- oPGP2,
- oPGP6,
- oPGP7,
- oPGP8,
- oCipherAlgo,
- oDigestAlgo,
- oCertDigestAlgo,
- oCompressAlgo,
- oPasswdFD,
-#ifdef __riscos__
- oPasswdFile,
-#endif /* __riscos__ */
- oCommandFD,
-#ifdef __riscos__
- oCommandFile,
-#endif /* __riscos__ */
- oQuickRandom,
- oNoVerbose,
- oTrustDBName,
- oNoSecmemWarn,
- oNoPermissionWarn,
- oNoMDCWarn,
- oNoArmor,
- oNoDefKeyring,
- oNoGreeting,
- oNoTTY,
- oNoOptions,
- oNoBatch,
- oHomedir,
- oWithColons,
- oWithKeyData,
- oSkipVerify,
- oCompressKeys,
- oCompressSigs,
- oAlwaysTrust,
- oTrustModel,
- oForceOwnertrust,
- oEmuChecksumBug,
- oSetFilename,
- oForYourEyesOnly,
- oNoForYourEyesOnly,
- oSetPolicyURL,
- oSigPolicyURL,
- oCertPolicyURL,
- oShowPolicyURL,
- oNoShowPolicyURL,
- oSigKeyserverURL,
- oUseEmbeddedFilename,
- oComment,
- oDefaultComment,
- oNoComments,
- oThrowKeyid,
- oNoThrowKeyid,
- oShowPhotos,
- oNoShowPhotos,
- oPhotoViewer,
- oForceV3Sigs,
- oNoForceV3Sigs,
- oForceV4Certs,
- oNoForceV4Certs,
- oForceMDC,
- oNoForceMDC,
- oDisableMDC,
- oNoDisableMDC,
- oS2KMode,
- oS2KDigest,
- oS2KCipher,
- oSimpleSKChecksum,
- oCharset,
- oNotDashEscaped,
- oEscapeFrom,
- oNoEscapeFrom,
- oLockOnce,
- oLockMultiple,
- oLockNever,
- oKeyServer,
- oKeyServerOptions,
- oImportOptions,
- oExportOptions,
- oListOptions,
- oVerifyOptions,
- oTempDir,
- oExecPath,
- oEncryptTo,
- oHiddenEncryptTo,
- oNoEncryptTo,
- oLogFile,
- oLoggerFD,
-#ifdef __riscos__
- oLoggerFile,
-#endif /* __riscos__ */
- oUtf8Strings,
- oNoUtf8Strings,
- oDisableCipherAlgo,
- oDisablePubkeyAlgo,
- oAllowNonSelfsignedUID,
- oNoAllowNonSelfsignedUID,
- oAllowFreeformUID,
- oNoAllowFreeformUID,
- oAllowSecretKeyImport,
- oEnableSpecialFilenames,
- oNoLiteral,
- oSetFilesize,
- oHonorHttpProxy,
- oFastListMode,
- oListOnly,
- oIgnoreTimeConflict,
- oIgnoreValidFrom,
- oIgnoreCrcError,
- oIgnoreMDCError,
- oShowSessionKey,
- oOverrideSessionKey,
- oNoRandomSeedFile,
- oAutoKeyRetrieve,
- oNoAutoKeyRetrieve,
- oUseAgent,
- oNoUseAgent,
- oGpgAgentInfo,
- oMergeOnly,
- oTryAllSecrets,
- oTrustedKey,
- oNoExpensiveTrustChecks,
- oFixedListMode,
- oNoSigCache,
- oNoSigCreateCheck,
- oAutoCheckTrustDB,
- oNoAutoCheckTrustDB,
- oPreservePermissions,
- oDefaultPreferenceList,
- oPersonalCipherPreferences,
- oPersonalDigestPreferences,
- oPersonalCompressPreferences,
- oEmuMDEncodeBug,
- oAgentProgram,
- oDisplay,
- oTTYname,
- oTTYtype,
- oLCctype,
- oLCmessages,
- oGroup,
- oStrict,
- oNoStrict,
- oMangleDosFilenames,
- oNoMangleDosFilenames,
- oEnableProgressFilter,
- oMultifile,
-aTest };
-
-
-static ARGPARSE_OPTS opts[] = {
-
- { 300, NULL, 0, N_("@Commands:\n ") },
-
- { aSign, "sign", 256, N_("|[file]|make a signature")},
- { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature") },
- { aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
- { aEncr, "encrypt", 256, N_("encrypt data")},
- { aEncrFiles, "encrypt-files", 256, "@"},
- { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
- { aStore, "store", 256, "@"},
- { aDecrypt, "decrypt", 256, N_("decrypt data (default)")},
- { aDecryptFiles, "decrypt-files", 256, "@"},
- { aVerify, "verify" , 256, N_("verify a signature")},
- { aVerifyFiles, "verify-files" , 256, "@" },
- { aListKeys, "list-keys", 256, N_("list keys")},
- { aListKeys, "list-public-keys", 256, "@" },
- { aListSigs, "list-sigs", 256, N_("list keys and signatures")},
- { aCheckKeys, "check-sigs",256, N_("list and check key signatures")},
- { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
- { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
- { aKeygen, "gen-key", 256, N_("generate a new key pair")},
- { aDeleteKeys,"delete-keys",256,N_("remove keys from the public keyring")},
- { aDeleteSecretKeys, "delete-secret-keys",256,
- N_("remove keys from the secret keyring")},
- { aSignKey, "sign-key" ,256, N_("sign a key")},
- { aLSignKey, "lsign-key" ,256, N_("sign a key locally")},
- { aNRSignKey, "nrsign-key" ,256, "@"},
- { aNRLSignKey, "nrlsign-key" ,256, "@"},
- { aEditKey, "edit-key" ,256, N_("sign or edit a key")},
- { aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")},
- { aDesigRevoke, "desig-revoke",256, "@" },
- { aExport, "export" , 256, N_("export keys") },
- { aSendKeys, "send-keys" , 256, N_("export keys to a key server") },
- { aRecvKeys, "recv-keys" , 256, N_("import keys from a key server") },
- { aSearchKeys, "search-keys" , 256,
- N_("search for keys on a key server") },
- { aRefreshKeys, "refresh-keys", 256,
- N_("update all keys from a keyserver")},
- { aExportAll, "export-all" , 256, "@" },
- { aExportSecret, "export-secret-keys" , 256, "@" },
- { aExportSecretSub, "export-secret-subkeys" , 256, "@" },
- { aImport, "import", 256 , N_("import/merge keys")},
- { aFastImport, "fast-import", 256 , "@"},
- { aCardStatus, "card-status", 256, N_("print the card status")},
- { aCardEdit, "card-edit", 256, N_("change data on a card")},
- { aChangePIN, "change-pin", 256, N_("change a card's PIN")},
-
- { aListPackets, "list-packets",256, "@"},
- { aExportOwnerTrust, "export-ownertrust", 256, "@"},
- { aImportOwnerTrust, "import-ownertrust", 256, "@"},
- { aUpdateTrustDB, "update-trustdb",0 , N_("update the trust database")},
- { aCheckTrustDB, "check-trustdb",0 , "@"},
- { aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")},
- { aDeArmor, "dearmor", 256, "@" },
- { aDeArmor, "dearmour", 256, "@" },
- { aEnArmor, "enarmor", 256, "@" },
- { aEnArmor, "enarmour", 256, "@" },
- { aPrintMD, "print-md" , 256, N_("|algo [files]|print message digests")},
- { aPrimegen, "gen-prime" , 256, "@" },
- { aGenRandom, "gen-random" , 256, "@" },
- { aGPGConfList, "gpgconf-list", 256, "@" },
-
- { 301, NULL, 0, N_("@\nOptions:\n ") },
-
- { oArmor, "armor", 0, N_("create ascii armored output")},
- { oArmor, "armour", 0, "@" },
- { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
- { oHiddenRecipient, "hidden-recipient", 2, "@" },
- { oRecipient, "remote-user", 2, "@"}, /* old option name */
- { oDefRecipient, "default-recipient" ,2, "@" },
- { oDefRecipientSelf, "default-recipient-self" ,0, "@" },
- { oNoDefRecipient, "no-default-recipient", 0, "@" },
- { oTempDir, "temp-directory", 2, "@" },
- { oExecPath, "exec-path", 2, "@" },
- { oEncryptTo, "encrypt-to", 2, "@" },
- { oHiddenEncryptTo, "hidden-encrypt-to", 2, "@" },
- { oNoEncryptTo, "no-encrypt-to", 0, "@" },
- { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
- { oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") },
- { oTextmodeShort, NULL, 0, "@"},
- { oTextmode, "textmode", 0, N_("use canonical text mode")},
- { oNoTextmode, "no-textmode", 0, "@"},
- { oExpert, "expert", 0, "@"},
- { oNoExpert, "no-expert", 0, "@"},
- { oAskSigExpire, "ask-sig-expire", 0, "@"},
- { oNoAskSigExpire, "no-ask-sig-expire", 0, "@"},
- { oAskCertExpire, "ask-cert-expire", 0, "@"},
- { oNoAskCertExpire, "no-ask-cert-expire", 0, "@"},
- { oOutput, "output", 2, N_("use as output file")},
- { oVerbose, "verbose", 0, N_("verbose") },
- { oQuiet, "quiet", 0, "@" },
- { oNoTTY, "no-tty", 0, "@" },
- { oLogFile, "log-file" ,2, "@" },
- { oForceV3Sigs, "force-v3-sigs", 0, "@" },
- { oNoForceV3Sigs, "no-force-v3-sigs", 0, "@" },
- { oForceV4Certs, "force-v4-certs", 0, "@" },
- { oNoForceV4Certs, "no-force-v4-certs", 0, "@" },
- { oForceMDC, "force-mdc", 0, "@" },
- { oNoForceMDC, "no-force-mdc", 0, "@" },
- { oDisableMDC, "disable-mdc", 0, "@" },
- { oNoDisableMDC, "no-disable-mdc", 0, "@" },
- { oDryRun, "dry-run", 0, N_("do not make any changes") },
- { oInteractive, "interactive", 0, N_("prompt before overwriting") },
- { oUseAgent, "use-agent",0, "@"},
- { oNoUseAgent, "no-use-agent",0, "@"},
- { oGpgAgentInfo, "gpg-agent-info",2, "@"},
- { oBatch, "batch", 0, "@"},
- { oAnswerYes, "yes", 0, "@"},
- { oAnswerNo, "no", 0, "@"},
- { oKeyring, "keyring" , 2, "@"},
- { oPrimaryKeyring, "primary-keyring",2, "@" },
- { oSecretKeyring, "secret-keyring" ,2, "@"},
- { oShowKeyring, "show-keyring", 0, "@"},
- { oDefaultKey, "default-key" , 2, "@"},
- { oKeyServer, "keyserver", 2, "@"},
- { oKeyServerOptions, "keyserver-options",2,"@"},
- { oImportOptions, "import-options",2,"@"},
- { oExportOptions, "export-options",2,"@"},
- { oListOptions, "list-options",2,"@"},
- { oVerifyOptions, "verify-options",2,"@"},
- { oCharset, "charset" , 2, "@" },
- { oOptions, "options" , 2, "@"},
-
- { oDebug, "debug" ,4|16, "@"},
- { oDebugLevel, "debug-level" ,2, "@"},
- { oDebugAll, "debug-all" ,0, "@"},
- { oStatusFD, "status-fd" ,1, "@" },
-#ifdef __riscos__
- { oStatusFile, "status-file" ,2, "@" },
-#endif /* __riscos__ */
- { oAttributeFD, "attribute-fd" ,1, "@" },
-#ifdef __riscos__
- { oAttributeFile, "attribute-file" ,2, "@" },
-#endif /* __riscos__ */
- { oNoSKComments, "no-sk-comments", 0, "@"},
- { oSKComments, "sk-comments", 0, "@"},
- { oCompletesNeeded, "completes-needed", 1, "@"},
- { oMarginalsNeeded, "marginals-needed", 1, "@"},
- { oMaxCertDepth, "max-cert-depth", 1, "@" },
- { oTrustedKey, "trusted-key", 2, "@"},
- { oLoadExtension, "load-extension" ,2, "@"},
- { oGnuPG, "gnupg", 0, "@"},
- { oGnuPG, "no-pgp2", 0, "@"},
- { oGnuPG, "no-pgp6", 0, "@"},
- { oGnuPG, "no-pgp7", 0, "@"},
- { oGnuPG, "no-pgp8", 0, "@"},
- { oRFC1991, "rfc1991", 0, "@"},
- { oRFC2440, "rfc2440", 0, "@"},
- { oOpenPGP, "openpgp", 0, N_("use strict OpenPGP behavior")},
- { oPGP2, "pgp2", 0, N_("generate PGP 2.x compatible messages")},
- { oPGP6, "pgp6", 0, "@"},
- { oPGP7, "pgp7", 0, "@"},
- { oPGP8, "pgp8", 0, "@"},
- { oS2KMode, "s2k-mode", 1, "@"},
- { oS2KDigest, "s2k-digest-algo",2, "@"},
- { oS2KCipher, "s2k-cipher-algo",2, "@"},
- { oSimpleSKChecksum, "simple-sk-checksum", 0, "@"},
- { oCipherAlgo, "cipher-algo", 2 , "@"},
- { oDigestAlgo, "digest-algo", 2 , "@"},
- { oCertDigestAlgo, "cert-digest-algo", 2 , "@" },
- { oCompressAlgo,"compress-algo",2, "@"},
- { oThrowKeyid, "throw-keyid", 0, "@"},
- { oNoThrowKeyid, "no-throw-keyid", 0, "@" },
- { oShowPhotos, "show-photos", 0, "@" },
- { oNoShowPhotos, "no-show-photos", 0, "@" },
- { oPhotoViewer, "photo-viewer", 2, "@" },
- { oSetNotation, "set-notation", 2, "@" },
- { oSetNotation, "notation-data", 2, "@" }, /* Alias */
- { oSigNotation, "sig-notation", 2, "@" },
- { oCertNotation, "cert-notation", 2, "@" },
-
- { 302, NULL, 0, N_(
- "@\n(See the man page for a complete listing of all commands and options)\n"
- )},
-
- { 303, NULL, 0, N_("@\nExamples:\n\n"
- " -se -r Bob [file] sign and encrypt for user Bob\n"
- " --clearsign [file] make a clear text signature\n"
- " --detach-sign [file] make a detached signature\n"
- " --list-keys [names] show keys\n"
- " --fingerprint [names] show fingerprints\n" ) },
-
- /* hidden options */
- { aListOwnerTrust, "list-ownertrust", 256, "@"}, /* deprecated */
- { oCompressAlgo, "compression-algo", 1, "@"}, /* alias */
- { aPrintMDs, "print-mds" , 256, "@"}, /* old */
- { aListTrustDB, "list-trustdb",0 , "@"},
- /* Not yet used */
- /* { aListTrustPath, "list-trust-path",0, "@"}, */
- { aPipeMode, "pipemode", 0, "@" },
- { oPasswdFD, "passphrase-fd",1, "@" },
-#ifdef __riscos__
- { oPasswdFile, "passphrase-file",2, "@" },
-#endif /* __riscos__ */
- { oCommandFD, "command-fd",1, "@" },
-#ifdef __riscos__
- { oCommandFile, "command-file",2, "@" },
-#endif /* __riscos__ */
- { oQuickRandom, "quick-random", 0, "@"},
- { oNoVerbose, "no-verbose", 0, "@"},
- { oTrustDBName, "trustdb-name", 2, "@" },
- { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */
- { oNoPermissionWarn, "no-permission-warning", 0, "@" },
- { oNoMDCWarn, "no-mdc-warning", 0, "@" },
- { oNoArmor, "no-armor", 0, "@"},
- { oNoArmor, "no-armour", 0, "@"},
- { oNoDefKeyring, "no-default-keyring", 0, "@" },
- { oNoGreeting, "no-greeting", 0, "@" },
- { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */
- { oHomedir, "homedir", 2, "@" }, /* defaults to "~/.gnupg" */
- { oNoBatch, "no-batch", 0, "@" },
- { oWithColons, "with-colons", 0, "@"},
- { oWithKeyData,"with-key-data", 0, "@"},
- { aListKeys, "list-key", 0, "@" }, /* alias */
- { aListSigs, "list-sig", 0, "@" }, /* alias */
- { aCheckKeys, "check-sig",0, "@" }, /* alias */
- { oSkipVerify, "skip-verify",0, "@" },
- { oCompressKeys, "compress-keys",0, "@"},
- { oCompressSigs, "compress-sigs",0, "@"},
- { oDefCertCheckLevel, "default-cert-check-level", 1, "@"},
- { oAlwaysTrust, "always-trust", 0, "@"},
- { oTrustModel, "trust-model", 2, "@"},
- { oForceOwnertrust, "force-ownertrust", 2, "@"},
- { oEmuChecksumBug, "emulate-checksum-bug", 0, "@"},
- { oSetFilename, "set-filename", 2, "@" },
- { oForYourEyesOnly, "for-your-eyes-only", 0, "@" },
- { oNoForYourEyesOnly, "no-for-your-eyes-only", 0, "@" },
- { oSetPolicyURL, "set-policy-url", 2, "@" },
- { oSigPolicyURL, "sig-policy-url", 2, "@" },
- { oCertPolicyURL, "cert-policy-url", 2, "@" },
- { oShowPolicyURL, "show-policy-url", 0, "@" },
- { oNoShowPolicyURL, "no-show-policy-url", 0, "@" },
- { oShowNotation, "show-notation", 0, "@" },
- { oNoShowNotation, "no-show-notation", 0, "@" },
- { oSigKeyserverURL, "sig-keyserver-url", 2, "@" },
- { oComment, "comment", 2, "@" },
- { oDefaultComment, "default-comment", 0, "@" },
- { oNoComments, "no-comments", 0, "@" },
- { oEmitVersion, "emit-version", 0, "@"},
- { oNoEmitVersion, "no-emit-version", 0, "@"},
- { oNoEmitVersion, "no-version", 0, "@"}, /* alias */
- { oNotDashEscaped, "not-dash-escaped", 0, "@" },
- { oEscapeFrom, "escape-from-lines", 0, "@" },
- { oNoEscapeFrom, "no-escape-from-lines", 0, "@" },
- { oLockOnce, "lock-once", 0, "@" },
- { oLockMultiple, "lock-multiple", 0, "@" },
- { oLockNever, "lock-never", 0, "@" },
- { oLoggerFD, "logger-fd",1, "@" },
-#ifdef __riscos__
- { oLoggerFile, "logger-file",2, "@" },
-#endif /* __riscos__ */
- { oUseEmbeddedFilename, "use-embedded-filename", 0, "@" },
- { oUtf8Strings, "utf8-strings", 0, "@" },
- { oNoUtf8Strings, "no-utf8-strings", 0, "@" },
- { oWithFingerprint, "with-fingerprint", 0, "@" },
- { oDisableCipherAlgo, "disable-cipher-algo", 2, "@" },
- { oDisablePubkeyAlgo, "disable-pubkey-algo", 2, "@" },
- { oAllowNonSelfsignedUID, "allow-non-selfsigned-uid", 0, "@" },
- { oNoAllowNonSelfsignedUID, "no-allow-non-selfsigned-uid", 0, "@" },
- { oAllowFreeformUID, "allow-freeform-uid", 0, "@" },
- { oNoAllowFreeformUID, "no-allow-freeform-uid", 0, "@" },
- { oNoLiteral, "no-literal", 0, "@" },
- { oSetFilesize, "set-filesize", 20, "@" },
- { oHonorHttpProxy,"honor-http-proxy", 0, "@" },
- { oFastListMode,"fast-list-mode", 0, "@" },
- { oFixedListMode,"fixed-list-mode", 0, "@" },
- { oListOnly, "list-only", 0, "@"},
- { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" },
- { oIgnoreValidFrom, "ignore-valid-from", 0, "@" },
- { oIgnoreCrcError, "ignore-crc-error", 0,"@" },
- { oIgnoreMDCError, "ignore-mdc-error", 0,"@" },
- { oShowSessionKey, "show-session-key", 0, "@" },
- { oOverrideSessionKey, "override-session-key", 2, "@" },
- { oNoRandomSeedFile, "no-random-seed-file", 0, "@" },
- { oAutoKeyRetrieve, "auto-key-retrieve", 0, "@" },
- { oNoAutoKeyRetrieve, "no-auto-key-retrieve", 0, "@" },
- { oNoSigCache, "no-sig-cache", 0, "@" },
- { oNoSigCreateCheck, "no-sig-create-check", 0, "@" },
- { oAutoCheckTrustDB, "auto-check-trustdb", 0, "@"},
- { oNoAutoCheckTrustDB, "no-auto-check-trustdb", 0, "@"},
- { oMergeOnly, "merge-only", 0, "@" },
- { oAllowSecretKeyImport, "allow-secret-key-import", 0, "@" },
- { oTryAllSecrets, "try-all-secrets", 0, "@" },
- { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" },
- { oNoExpensiveTrustChecks, "no-expensive-trust-checks", 0, "@" },
- { aDeleteSecretAndPublicKeys, "delete-secret-and-public-keys",256, "@" },
- { aRebuildKeydbCaches, "rebuild-keydb-caches", 256, "@"},
- { oPreservePermissions, "preserve-permissions", 0, "@"},
- { oDefaultPreferenceList, "default-preference-list", 2, "@"},
- { oPersonalCipherPreferences, "personal-cipher-preferences", 2, "@"},
- { oPersonalDigestPreferences, "personal-digest-preferences", 2, "@"},
- { oPersonalCompressPreferences, "personal-compress-preferences", 2, "@"},
- { oEmuMDEncodeBug, "emulate-md-encode-bug", 0, "@"},
- { oAgentProgram, "agent-program", 2 , "@" },
- { oDisplay, "display", 2, "@" },
- { oTTYname, "ttyname", 2, "@" },
- { oTTYtype, "ttytype", 2, "@" },
- { oLCctype, "lc-ctype", 2, "@" },
- { oLCmessages, "lc-messages", 2, "@" },
- { oGroup, "group", 2, "@" },
- { oStrict, "strict", 0, "@" },
- { oNoStrict, "no-strict", 0, "@" },
- { oMangleDosFilenames, "mangle-dos-filenames", 0, "@" },
- { oNoMangleDosFilenames, "no-mangle-dos-filenames", 0, "@" },
- { oEnableProgressFilter, "enable-progress-filter", 0, "@" },
- { oMultifile, "multifile", 0, "@" },
-{0} };
-
-
-
-int g10_errors_seen = 0;
-
-static int utf8_strings = 0;
-static int maybe_setuid = 1;
-
-static char *build_list( const char *text, char letter,
- const char *(*mapf)(int), int (*chkf)(int) );
-static void set_cmd( enum cmd_and_opt_values *ret_cmd,
- enum cmd_and_opt_values new_cmd );
-static void print_mds( const char *fname, int algo );
-static void add_notation_data( const char *string, int which );
-static void add_policy_url( const char *string, int which );
-static void add_keyserver_url( const char *string, int which );
-static void emergency_cleanup (void);
-
-#ifdef __riscos__
-RISCOS_GLOBAL_STATICS("GnuPG Heap")
-#endif /* __riscos__ */
-
-static int
-pk_test_algo (int algo)
-{
- return openpgp_pk_test_algo (algo, 0);
-}
-
-
-static const char *
-my_strusage( int level )
-{
- static char *digests, *pubkeys, *ciphers, *zips;
- const char *p;
- switch( level ) {
- case 11: p = "gpg (GnuPG)";
- break;
- case 13: p = VERSION; break;
- case 17: p = PRINTABLE_OS_NAME; break;
- case 19: p =
- _("Please report bugs to <[email protected]>.\n");
- break;
- case 1:
- case 40: p =
- _("Usage: gpg [options] [files] (-h for help)");
- break;
- case 41: p =
- _("Syntax: gpg [options] [files]\n"
- "sign, check, encrypt or decrypt\n"
- "default operation depends on the input data\n");
- break;
-
- case 31: p = "\nHome: "; break;
-#ifndef __riscos__
- case 32: p = opt.homedir; break;
-#else /* __riscos__ */
- case 32: p = make_filename(opt.homedir, NULL); break;
-#endif /* __riscos__ */
- case 33: p = _("\nSupported algorithms:\n"); break;
- case 34:
- if( !pubkeys )
- pubkeys = build_list(_("Pubkey: "), 0, gcry_pk_algo_name,
- pk_test_algo );
- p = pubkeys;
- break;
- case 35:
- if( !ciphers )
- ciphers = build_list(_("Cipher: "), 'S', gcry_cipher_algo_name,
- openpgp_cipher_test_algo );
- p = ciphers;
- break;
- case 36:
- if( !digests )
- digests = build_list(_("Hash: "), 'H', gcry_md_algo_name,
- openpgp_md_test_algo );
- p = digests;
- break;
- case 37:
- if( !zips )
- zips = build_list(_("Compression: "),'Z',compress_algo_to_string,
- check_compress_algo);
- p = zips;
- break;
-
- default: p = NULL;
- }
- return p;
-}
-
-
-static char *
-build_list( const char *text, char letter,
- const char * (*mapf)(int), int (*chkf)(int) )
-{
- int i;
- const char *s;
- size_t n=strlen(text)+2;
- char *list, *p, *line=NULL;
-
- if( maybe_setuid )
- gcry_control (GCRYCTL_INIT_SECMEM, 0, 0); /* drop setuid */
-
- for(i=0; i <= 110; i++ )
- if( !chkf(i) && (s=mapf(i)) )
- n += strlen(s) + 7 + 2;
- list = xmalloc ( 21 + n ); *list = 0;
- for(p=NULL, i=0; i <= 110; i++ ) {
- if( !chkf(i) && (s=mapf(i)) ) {
- if( !p ) {
- p = stpcpy( list, text );
- line=p;
- }
- else
- p = stpcpy( p, ", ");
-
- if(strlen(line)>60) {
- int spaces=strlen(text);
-
- list = xrealloc(list,n+spaces+1);
- /* realloc could move the block, so find the end again */
- p=list;
- while(*p)
- p++;
-
- p=stpcpy(p, "\n");
- line=p;
- for(;spaces;spaces--)
- p=stpcpy(p, " ");
- }
-
- p = stpcpy(p, s );
- if(opt.verbose && letter)
- {
- char num[8];
- sprintf(num," (%c%d)",letter,i);
- p = stpcpy(p,num);
- }
- }
- }
- if( p )
- p = stpcpy(p, "\n" );
- return list;
-}
-
-
-static void
-i18n_init(void)
-{
-#ifdef USE_SIMPLE_GETTEXT
- set_gettext_file( PACKAGE_GT );
-#else
-#ifdef ENABLE_NLS
- setlocale( LC_ALL, "" );
- bindtextdomain( PACKAGE_GT, LOCALEDIR );
- textdomain( PACKAGE_GT );
-#endif
-#endif
-}
-
-static void
-wrong_args( const char *text)
-{
- fputs(_("usage: gpg [options] "),stderr);
- fputs(text,stderr);
- putc('\n',stderr);
- g10_exit(2);
-}
-
-
-static void
-log_set_strict (int yesno)
-{
- /* FIXME-XXX*/
-}
-
-static char *
-make_username( const char *string )
-{
- char *p;
- if( utf8_strings )
- p = xstrdup (string);
- else
- p = native_to_utf8( string );
- return p;
-}
-
-
-/*
- * same as add_to_strlist() but if is_utf8 is *not* set a conversion
- * to UTF8 is done
- */
-static STRLIST
-add_to_strlist2 ( STRLIST *list, const char *string, int is_utf8)
-{
- STRLIST sl;
-
- if (is_utf8)
- sl = add_to_strlist( list, string );
- else
- {
- char *p = native_to_utf8( string );
- sl = add_to_strlist( list, p );
- xfree( p );
- }
- return sl;
-}
-
-
-/* Setup the debugging. With a LEVEL of NULL only the active debug
- flags are propagated to the subsystems. With LEVEL set, a specific
- set of debug flags is set; thus overriding all flags already
- set. */
-static void
-set_debug (const char *level)
-{
- if (!level)
- ;
- else if (!strcmp (level, "none"))
- opt.debug = 0;
- else if (!strcmp (level, "basic"))
- opt.debug = DBG_MEMSTAT_VALUE;
- else if (!strcmp (level, "advanced"))
- opt.debug = DBG_MEMSTAT_VALUE|DBG_TRUST_VALUE|DBG_EXTPROG_VALUE;
- else if (!strcmp (level, "expert"))
- opt.debug = (DBG_MEMSTAT_VALUE|DBG_TRUST_VALUE|DBG_EXTPROG_VALUE
- |DBG_CACHE_VALUE|DBG_FILTER_VALUE|DBG_PACKET_VALUE);
- else if (!strcmp (level, "guru"))
- opt.debug = ~0;
- else
- {
- log_error (_("invalid debug-level `%s' given\n"), level);
- g10_exit (2);
- }
-
- if (opt.debug & DBG_MEMORY_VALUE )
- memory_debug_mode = 1;
- if (opt.debug & DBG_MEMSTAT_VALUE )
- memory_stat_debug_mode = 1;
- if (opt.debug & DBG_MPI_VALUE)
- gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
- if (opt.debug & DBG_CIPHER_VALUE )
- gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
- if (opt.debug & DBG_IOBUF_VALUE )
- iobuf_debug_mode = 1;
-}
-
-
-/* We need the home directory also in some other directories, so make
- sure that both variables are always in sync. */
-static void
-set_homedir (char *dir)
-{
- if (!dir)
- dir = "";
- g10_opt_homedir = opt.homedir = dir;
-}
-
-
-static void
-set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
-{
- enum cmd_and_opt_values cmd = *ret_cmd;
-
- if( !cmd || cmd == new_cmd )
- cmd = new_cmd;
- else if( cmd == aSign && new_cmd == aEncr )
- cmd = aSignEncr;
- else if( cmd == aEncr && new_cmd == aSign )
- cmd = aSignEncr;
- else if( cmd == aSign && new_cmd == aSym )
- cmd = aSignSym;
- else if( cmd == aSym && new_cmd == aSign )
- cmd = aSignSym;
- else if( ( cmd == aSign && new_cmd == aClearsign )
- || ( cmd == aClearsign && new_cmd == aSign ) )
- cmd = aClearsign;
- else {
- log_error(_("conflicting commands\n"));
- g10_exit(2);
- }
-
- *ret_cmd = cmd;
-}
-
-
-static void add_group(char *string)
-{
- char *name,*value;
- struct groupitem *item;
- STRLIST values=NULL;
-
- /* Break off the group name */
- name=strsep(&string,"=");
- if(string==NULL)
- {
- log_error(_("no = sign found in group definition \"%s\"\n"),name);
- return;
- }
-
- trim_trailing_ws(name,strlen(name));
-
- /* Break apart the values */
- while ((value= strsep(&string," \t")))
- {
- if (*value)
- add_to_strlist2 (&values,value,utf8_strings);
- }
-
- item=xmalloc (sizeof(struct groupitem));
- item->name=name;
- item->values=values;
- item->next=opt.grouplist;
-
- opt.grouplist=item;
-}
-
-/* We need to check three things.
-
- 0) The homedir. It must be x00, a directory, and owned by the
- user.
-
- 1) The options file. Okay unless it or its containing directory is
- group or other writable or not owned by us. disable exec in this
- case.
-
- 2) Extensions. Same as #2.
-
- Returns true if the item is unsafe. */
-static int
-check_permissions(const char *path,int item)
-{
-#if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
- static int homedir_cache=-1;
- char *tmppath,*dir;
- struct stat statbuf,dirbuf;
- int homedir=0,ret=0,checkonly=0;
- int perm=0,own=0,enc_dir_perm=0,enc_dir_own=0;
-
- if(opt.no_perm_warn)
- return 0;
-
- assert(item==0 || item==1 || item==2);
-
- /* extensions may attach a path */
- if(item==2 && path[0]!=DIRSEP_C)
- {
- if(strchr(path,DIRSEP_C))
- tmppath=make_filename(path,NULL);
- else
- tmppath=make_filename(GNUPG_LIBDIR,path,NULL);
- }
- else
- tmppath=xstrdup (path);
-
- /* If the item is located in the homedir, but isn't the homedir,
- don't continue if we already checked the homedir itself. This is
- to avoid user confusion with an extra options file warning which
- could be rectified if the homedir itself had proper
- permissions. */
- if(item!=0 && homedir_cache>-1
- && ascii_strncasecmp(opt.homedir,tmppath,strlen(opt.homedir))==0)
- {
- ret=homedir_cache;
- goto end;
- }
-
- /* It's okay if the file or directory doesn't exist */
- if(stat(tmppath,&statbuf)!=0)
- {
- ret=0;
- goto end;
- }
-
- /* Now check the enclosing directory. Theoretically, we could walk
- this test up to the root directory /, but for the sake of sanity,
- I'm stopping at one level down. */
- dir=make_dirname(tmppath);
-
- if(stat(dir,&dirbuf)!=0 || !S_ISDIR(dirbuf.st_mode))
- {
- /* Weird error */
- ret=1;
- goto end;
- }
-
- xfree (dir);
-
- /* Assume failure */
- ret=1;
-
- if(item==0)
- {
- /* The homedir must be x00, a directory, and owned by the user. */
-
- if(S_ISDIR(statbuf.st_mode))
- {
- if(statbuf.st_uid==getuid())
- {
- if((statbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
- ret=0;
- else
- perm=1;
- }
- else
- own=1;
-
- homedir_cache=ret;
- }
- }
- else if(item==1 || item==2)
- {
- /* The options or extension file. Okay unless it or its
- containing directory is group or other writable or not owned
- by us or root. */
-
- if(S_ISREG(statbuf.st_mode))
- {
- if(statbuf.st_uid==getuid() || statbuf.st_uid==0)
- {
- if((statbuf.st_mode & (S_IWGRP|S_IWOTH))==0)
- {
- /* it's not writable, so make sure the enclosing
- directory is also not writable */
- if(dirbuf.st_uid==getuid() || dirbuf.st_uid==0)
- {
- if((dirbuf.st_mode & (S_IWGRP|S_IWOTH))==0)
- ret=0;
- else
- enc_dir_perm=1;
- }
- else
- enc_dir_own=1;
- }
- else
- {
- /* it's writable, so the enclosing directory had
- better not let people get to it. */
- if(dirbuf.st_uid==getuid() || dirbuf.st_uid==0)
- {
- if((dirbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
- ret=0;
- else
- perm=enc_dir_perm=1; /* unclear which one to fix! */
- }
- else
- enc_dir_own=1;
- }
- }
- else
- own=1;
- }
- }
- else
- BUG();
-
- if(!checkonly)
- {
- if(own)
- {
- if(item==0)
- log_info(_("WARNING: unsafe ownership on "
- "homedir \"%s\"\n"),tmppath);
- else if(item==1)
- log_info(_("WARNING: unsafe ownership on "
- "configuration file \"%s\"\n"),tmppath);
- else
- log_info(_("WARNING: unsafe ownership on "
- "extension \"%s\"\n"),tmppath);
- }
- if(perm)
- {
- if(item==0)
- log_info(_("WARNING: unsafe permissions on "
- "homedir \"%s\"\n"),tmppath);
- else if(item==1)
- log_info(_("WARNING: unsafe permissions on "
- "configuration file \"%s\"\n"),tmppath);
- else
- log_info(_("WARNING: unsafe permissions on "
- "extension \"%s\"\n"),tmppath);
- }
- if(enc_dir_own)
- {
- if(item==0)
- log_info(_("WARNING: unsafe enclosing directory ownership on "
- "homedir \"%s\"\n"),tmppath);
- else if(item==1)
- log_info(_("WARNING: unsafe enclosing directory ownership on "
- "configuration file \"%s\"\n"),tmppath);
- else
- log_info(_("WARNING: unsafe enclosing directory ownership on "
- "extension \"%s\"\n"),tmppath);
- }
- if(enc_dir_perm)
- {
- if(item==0)
- log_info(_("WARNING: unsafe enclosing directory permissions on "
- "homedir \"%s\"\n"),tmppath);
- else if(item==1)
- log_info(_("WARNING: unsafe enclosing directory permissions on "
- "configuration file \"%s\"\n"),tmppath);
- else
- log_info(_("WARNING: unsafe enclosing directory permissions on "
- "extension \"%s\"\n"),tmppath);
- }
- }
-
- end:
- xfree (tmppath);
-
- if(homedir)
- homedir_cache=ret;
-
- return ret;
-
-#endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */
-
- return 0;
-}
-
-int
-main( int argc, char **argv )
-{
- ARGPARSE_ARGS pargs;
- iobuf_t a;
- int rc=0;
- int orig_argc;
- char **orig_argv;
- const char *fname;
- char *username;
- int may_coredump;
- STRLIST sl, remusr= NULL, locusr=NULL;
- STRLIST nrings=NULL, sec_nrings=NULL;
- armor_filter_context_t afx;
- int detached_sig = 0;
- FILE *configfp = NULL;
- char *configname = NULL;
- const char *config_filename = NULL;
- unsigned configlineno;
- int parse_debug = 0;
- int default_config = 1;
- int default_keyring = 1;
- int greeting = 0;
- int nogreeting = 0;
- char *logfile = NULL;
- int use_random_seed = 1;
- enum cmd_and_opt_values cmd = 0;
- const char *debug_level = NULL;
- const char *trustdb_name = NULL;
- char *def_cipher_string = NULL;
- char *def_digest_string = NULL;
- char *def_compress_string = NULL;
- char *cert_digest_string = NULL;
- char *s2k_cipher_string = NULL;
- char *s2k_digest_string = NULL;
- char *pers_cipher_list = NULL;
- char *pers_digest_list = NULL;
- char *pers_compress_list = NULL;
- int eyes_only=0;
- int multifile=0;
- int pwfd = -1;
- int with_fpr = 0; /* make an option out of --fingerprint */
- int any_explicit_recipient = 0;
-
-#ifdef __riscos__
- riscos_global_defaults();
- opt.lock_once = 1;
-#endif /* __riscos__ */
-
- trap_unaligned();
- set_strusage (my_strusage);
- gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
- /* We don't need any locking in libgcrypt unless we use any kind of
- threading. */
- gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING);
- /* Please note that we may running SUID(ROOT), so be very CAREFUL
- * when adding any stuff between here and the call to
- * secmem_init() somewhere after the option parsing
- */
- log_set_prefix ("gpg", 1);
- /* check that the libraries are suitable. Do it here because the
- option parse may need services of the library */
- if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
- {
- log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
- NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
- }
-
- gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
-
- may_coredump = disable_core_dumps();
- gnupg_init_signals (0, emergency_cleanup);
- create_dotlock (NULL); /* register locking cleanup */
- i18n_init();
-
- opt.command_fd = -1; /* no command fd */
- opt.compress = -1; /* defaults to standard compress level */
- /* note: if you change these lines, look at oOpenPGP */
- opt.def_cipher_algo = 0;
- opt.def_digest_algo = 0;
- opt.cert_digest_algo = 0;
- opt.def_compress_algo = -1;
- opt.s2k_mode = 3; /* iterated+salted */
- opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
-#ifdef USE_CAST5
- opt.s2k_cipher_algo = CIPHER_ALGO_CAST5;
-#else
- opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
-#endif
- opt.completes_needed = 1;
- opt.marginals_needed = 3;
- opt.max_cert_depth = 5;
- opt.pgp2_workarounds = 1;
- opt.force_v3_sigs = 1;
- opt.escape_from = 1;
- opt.import_options=IMPORT_SK2PK;
- opt.export_options=
- EXPORT_INCLUDE_NON_RFC|EXPORT_INCLUDE_ATTRIBUTES;
- opt.keyserver_options.import_options=IMPORT_REPAIR_PKS_SUBKEY_BUG;
- opt.keyserver_options.export_options=
- EXPORT_INCLUDE_NON_RFC|EXPORT_INCLUDE_ATTRIBUTES;
- opt.keyserver_options.include_subkeys=1;
- opt.keyserver_options.include_revoked=1;
- opt.keyserver_options.try_dns_srv=1;
- opt.verify_options=
- VERIFY_SHOW_POLICY|VERIFY_SHOW_NOTATION|VERIFY_SHOW_KEYSERVER;
- opt.trust_model=TM_AUTO;
- opt.mangle_dos_filenames = 1;
- opt.use_agent = 1;
-
-#if defined (_WIN32)
- set_homedir ( read_w32_registry_string( NULL,
- "Software\\GNU\\GnuPG", "HomeDir" ));
-#else
- set_homedir ( getenv("GNUPGHOME") );
-#endif
- if( !*opt.homedir )
- set_homedir ( GNUPG_DEFAULT_HOMEDIR );
-
- /* check whether we have a config file on the commandline */
- orig_argc = argc;
- orig_argv = argv;
- pargs.argc = &argc;
- pargs.argv = &argv;
- pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */
- while( arg_parse( &pargs, opts) ) {
- if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll )
- parse_debug++;
- else if( pargs.r_opt == oOptions ) {
- /* yes there is one, so we do not try the default one, but
- * read the option file when it is encountered at the commandline
- */
- default_config = 0;
- }
- else if( pargs.r_opt == oNoOptions )
- default_config = 0; /* --no-options */
- else if( pargs.r_opt == oHomedir )
- set_homedir ( pargs.r.ret_str );
- else if( pargs.r_opt == oNoPermissionWarn )
- opt.no_perm_warn=1;
- else if (pargs.r_opt == oStrict )
- {
- opt.strict=1;
- log_set_strict(1);
- }
- else if (pargs.r_opt == oNoStrict )
- {
- opt.strict=0;
- log_set_strict(0);
- }
- }
-
-#ifdef HAVE_DOSISH_SYSTEM
- if ( strchr (opt.homedir,'\\') ) {
- char *d, *buf = xmalloc (strlen (opt.homedir)+1);
- const char *s = opt.homedir;
- for (d=buf,s=opt.homedir; *s; s++)
- *d++ = *s == '\\'? '/': *s;
- *d = 0;
- set_homedir (buf);
- }
-#endif
-
- /* Initialize the secure memory. */
- gcry_control (GCRYCTL_INIT_SECMEM, 32768, 0);
- maybe_setuid = 0;
- /* Okay, we are now working under our real uid */
-
- /* malloc hooks go here ... */
- assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
-
- set_native_charset (NULL); /* Try to auto set the character set */
-
- /* Try for a version specific config file first */
- if( default_config )
- {
- char *name = xstrdup ("gpg" EXTSEP_S "conf-" SAFE_VERSION);
- char *ver = name + strlen("gpg" EXTSEP_S "conf-");
-
- do
- {
- if(configname)
- {
- char *tok;
-
- xfree (configname);
- configname=NULL;
-
- if((tok=strrchr (ver,SAFE_VERSION_DASH)))
- *tok='\0';
- else if((tok=strrchr (ver,SAFE_VERSION_DOT)))
- *tok='\0';
- else
- break;
- }
-
- configname = make_filename (opt.homedir, name, NULL);
- }
- while ( access(configname,R_OK) );
- xfree(name);
-
- if (!access (configname, R_OK))
- { /* Print a warning when both config files are present. */
- char *p = make_filename(opt.homedir, "options", NULL );
- if (!access (p, R_OK))
- log_info (_("NOTE: old default options file `%s' ignored\n"), p);
- xfree (p);
- }
- else
- { /* Keep on using the old default one. */
- xfree (configname);
- configname = make_filename(opt.homedir, "options", NULL );
- }
- }
- argc = orig_argc;
- argv = orig_argv;
- pargs.argc = &argc;
- pargs.argv = &argv;
- pargs.flags= 1; /* do not remove the args */
-
- /* By this point we have a homedir, and cannot change it. */
- check_permissions(opt.homedir,0);
-
- next_pass:
- if( configname ) {
- if(check_permissions(configname,1))
- {
- /* If any options file is unsafe, then disable any external
- programs for keyserver calls or photo IDs. Since the
- external program to call is set in the options file, a
- unsafe options file can lead to an arbitrary program
- being run. */
-
- opt.exec_disable=1;
- }
-
- configlineno = 0;
- configfp = fopen( configname, "r" );
- if( !configfp ) {
- if( default_config ) {
- if( parse_debug )
- log_info(_("NOTE: no default option file `%s'\n"),
- configname );
- }
- else {
- log_error(_("option file `%s': %s\n"),
- configname, strerror(errno) );
- g10_exit(2);
- }
- xfree (configname); configname = NULL;
- }
- if( parse_debug && configname )
- log_info(_("reading options from `%s'\n"), configname );
- default_config = 0;
- }
-
- while( optfile_parse( configfp, configname, &configlineno,
- &pargs, opts) ) {
- switch( pargs.r_opt ) {
- case aCheckKeys: set_cmd( &cmd, aCheckKeys); break;
- case aListPackets: set_cmd( &cmd, aListPackets); break;
- case aImport: set_cmd( &cmd, aImport); break;
- case aFastImport: set_cmd( &cmd, aFastImport); break;
- case aSendKeys: set_cmd( &cmd, aSendKeys); break;
- case aRecvKeys: set_cmd( &cmd, aRecvKeys); break;
- case aSearchKeys: set_cmd( &cmd, aSearchKeys); break;
- case aRefreshKeys: set_cmd( &cmd, aRefreshKeys); break;
- case aExport: set_cmd( &cmd, aExport); break;
- case aExportAll: set_cmd( &cmd, aExportAll); break;
- case aListKeys: set_cmd( &cmd, aListKeys); break;
- case aListSigs: set_cmd( &cmd, aListSigs); break;
- case aExportSecret: set_cmd( &cmd, aExportSecret); break;
- case aExportSecretSub: set_cmd( &cmd, aExportSecretSub); break;
- case aDeleteSecretKeys: set_cmd( &cmd, aDeleteSecretKeys);
- greeting=1; break;
- case aDeleteSecretAndPublicKeys:
- set_cmd( &cmd, aDeleteSecretAndPublicKeys);
- greeting=1;
- break;
- case aDeleteKeys: set_cmd( &cmd, aDeleteKeys); greeting=1; break;
-
- case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
- case aSym: set_cmd( &cmd, aSym); break;
-
- case aDecryptFiles: multifile=1; /* fall through */
- case aDecrypt: set_cmd( &cmd, aDecrypt); break;
-
- case aEncrFiles: multifile=1; /* fall through */
- case aEncr: set_cmd( &cmd, aEncr); break;
-
- case aVerifyFiles: multifile=1; /* fall through */
- case aVerify: set_cmd( &cmd, aVerify); break;
-
- case aSign: set_cmd( &cmd, aSign ); break;
- case aKeygen: set_cmd( &cmd, aKeygen); greeting=1; break;
- case aSignKey: set_cmd( &cmd, aSignKey); break;
- case aLSignKey: set_cmd( &cmd, aLSignKey); break;
- case aNRSignKey: set_cmd( &cmd, aNRSignKey); break;
- case aNRLSignKey: set_cmd( &cmd, aNRLSignKey); break;
- case aStore: set_cmd( &cmd, aStore); break;
- case aEditKey: set_cmd( &cmd, aEditKey); greeting=1; break;
- case aClearsign: set_cmd( &cmd, aClearsign); break;
- case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
- case aDesigRevoke: set_cmd( &cmd, aDesigRevoke); break;
-
- case aPrimegen: set_cmd( &cmd, aPrimegen); break;
- case aGenRandom: set_cmd( &cmd, aGenRandom); break;
- case aPrintMD: set_cmd( &cmd, aPrintMD); break;
- case aPrintMDs: set_cmd( &cmd, aPrintMDs); break;
- case aListTrustDB: set_cmd( &cmd, aListTrustDB); break;
- case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break;
- case aUpdateTrustDB: set_cmd( &cmd, aUpdateTrustDB); break;
- case aFixTrustDB: set_cmd( &cmd, aFixTrustDB); break;
- case aListTrustPath: set_cmd( &cmd, aListTrustPath); break;
- case aDeArmor: set_cmd( &cmd, aDeArmor); break;
- case aEnArmor: set_cmd( &cmd, aEnArmor); break;
- case aListOwnerTrust:
- deprecated_warning(configname,configlineno,
- "--list-ownertrust","--export-ownertrust","");
- case aExportOwnerTrust: set_cmd( &cmd, aExportOwnerTrust); break;
- case aImportOwnerTrust: set_cmd( &cmd, aImportOwnerTrust); break;
- case aPipeMode: set_cmd( &cmd, aPipeMode); break;
- case aRebuildKeydbCaches: set_cmd( &cmd, aRebuildKeydbCaches); break;
-
- case aCardStatus: set_cmd (&cmd, aCardStatus); break;
- case aCardEdit: set_cmd (&cmd, aCardEdit); break;
- case aChangePIN: set_cmd (&cmd, aChangePIN); break;
- case aGPGConfList:
- set_cmd (&cmd, aGPGConfList);
- nogreeting = 1;
- break;
-
- case oArmor: opt.armor = 1; opt.no_armor=0; break;
- case oOutput: opt.outfile = pargs.r.ret_str; break;
- case oQuiet: opt.quiet = 1; break;
- case oNoTTY: tty_no_terminal(1); break;
- case oDryRun: opt.dry_run = 1; break;
- case oInteractive: opt.interactive = 1; break;
- case oVerbose: g10_opt_verbose++;
- opt.verbose++; opt.list_sigs=1; break;
-
- case oLogFile: logfile = pargs.r.ret_str; break;
-
- case oBatch: opt.batch = 1; nogreeting = 1; break;
- case oUseAgent:
-#ifndef __riscos__
- opt.use_agent = 1;
-#else /* __riscos__ */
- opt.use_agent = 0;
- riscos_not_implemented("use-agent");
-#endif /* __riscos__ */
- break;
- case oNoUseAgent: opt.use_agent = 0; break;
- case oGpgAgentInfo: opt.gpg_agent_info = pargs.r.ret_str; break;
- case oAnswerYes: opt.answer_yes = 1; break;
- case oAnswerNo: opt.answer_no = 1; break;
- case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
- case oPrimaryKeyring:
- sl=append_to_strlist( &nrings, pargs.r.ret_str);
- sl->flags=2;
- break;
- case oShowKeyring: opt.list_options|=LIST_SHOW_KEYRING; break;
- case oDebug: opt.debug |= pargs.r.ret_ulong; break;
- case oDebugAll: opt.debug = ~0; break;
- case oDebugLevel: debug_level = pargs.r.ret_str; break;
- case oStatusFD:
- set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) );
- break;
-#ifdef __riscos__
- case oStatusFile:
- set_status_fd( iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) );
- break;
-#endif /* __riscos__ */
- case oAttributeFD:
- set_attrib_fd(iobuf_translate_file_handle (pargs.r.ret_int, 1));
- break;
-#ifdef __riscos__
- case oAttributeFile:
- set_attrib_fd(iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) );
- break;
-#endif /* __riscos__ */
- case oLoggerFD:
- log_set_fd (iobuf_translate_file_handle (pargs.r.ret_int, 1));
- break;
-#ifdef __riscos__
- case oLoggerFile:
- log_set_logfile( NULL,
- iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) );
- break;
-#endif /* __riscos__ */
- case oWithFingerprint:
- opt.with_fingerprint = 1;
- with_fpr=1; /*fall thru*/
- case oFingerprint: opt.fingerprint++; break;
- case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break;
- case oOptions:
- /* config files may not be nested (silently ignore them) */
- if( !configfp ) {
- xfree (configname);
- configname = xstrdup (pargs.r.ret_str);
- goto next_pass;
- }
- break;
- case oNoArmor: opt.no_armor=1; opt.armor=0; break;
- case oNoDefKeyring: default_keyring = 0; break;
- case oDefCertCheckLevel: opt.def_cert_check_level=pargs.r.ret_int; break;
- case oNoGreeting: nogreeting = 1; break;
- case oNoVerbose: g10_opt_verbose = 0;
- opt.verbose = 0; opt.list_sigs=0; break;
- /* disabled for now:
- case oQuickRandom: quick_random_gen(1); break; */
- case oSKComments: opt.sk_comments=1; break;
- case oNoSKComments: opt.sk_comments=0; break;
- case oEmitVersion: opt.no_version=0; break;
- case oNoEmitVersion: opt.no_version=1; break;
- case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
- case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
- case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
- case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
- case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
- case oDefRecipient:
- if( *pargs.r.ret_str )
- opt.def_recipient = make_username(pargs.r.ret_str);
- break;
- case oDefRecipientSelf:
- xfree (opt.def_recipient); opt.def_recipient = NULL;
- opt.def_recipient_self = 1;
- break;
- case oNoDefRecipient:
- xfree (opt.def_recipient); opt.def_recipient = NULL;
- opt.def_recipient_self = 0;
- break;
- case oNoOptions: opt.no_homedir_creation = 1; break; /* no-options */
- case oHomedir: break;
- case oNoBatch: opt.batch = 0; break;
- case oWithKeyData: opt.with_key_data=1; /* fall thru */
- case oWithColons: opt.with_colons=':'; break;
-
- case oSkipVerify: opt.skip_verify=1; break;
- case oCompressKeys: opt.compress_keys = 1; break;
- case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
- /* There are many programs (like mutt) that call gpg with
- --always-trust so keep this option around for a long
- time. */
- case oAlwaysTrust: opt.trust_model=TM_ALWAYS; break;
- case oTrustModel:
- if(ascii_strcasecmp(pargs.r.ret_str,"pgp")==0)
- opt.trust_model=TM_PGP;
- else if(ascii_strcasecmp(pargs.r.ret_str,"classic")==0)
- opt.trust_model=TM_CLASSIC;
- else if(ascii_strcasecmp(pargs.r.ret_str,"always")==0)
- opt.trust_model=TM_ALWAYS;
- else if(ascii_strcasecmp(pargs.r.ret_str,"auto")==0)
- opt.trust_model=TM_AUTO;
- else
- log_error("unknown trust model \"%s\"\n",pargs.r.ret_str);
- break;
- case oForceOwnertrust:
- log_info(_("NOTE: %s is not for normal use!\n"),
- "--force-ownertrust");
- opt.force_ownertrust=string_to_trust_value(pargs.r.ret_str);
- if(opt.force_ownertrust==-1)
- {
- log_error("invalid ownertrust \"%s\"\n",pargs.r.ret_str);
- opt.force_ownertrust=0;
- }
- break;
- case oLoadExtension:
-#ifndef __riscos__
-#if defined(USE_DYNAMIC_LINKING) || defined(_WIN32)
- if(check_permissions(pargs.r.ret_str,2))
- log_info(_("cipher extension \"%s\" not loaded due to "
- "unsafe permissions\n"),pargs.r.ret_str);
- else
- register_cipher_extension(orig_argc? *orig_argv:NULL,
- pargs.r.ret_str);
-#endif
-#else /* __riscos__ */
- riscos_not_implemented("load-extension");
-#endif /* __riscos__ */
- break;
- case oRFC1991:
- opt.compliance = CO_RFC1991;
- opt.force_v4_certs = 0;
- opt.escape_from = 1;
- break;
- case oRFC2440:
- case oOpenPGP:
- /* TODO: When 2440bis becomes a RFC, these may need
- changing. */
- opt.compliance = CO_RFC2440;
- opt.allow_non_selfsigned_uid = 1;
- opt.allow_freeform_uid = 1;
- opt.pgp2_workarounds = 0;
- opt.escape_from = 0;
- opt.force_v3_sigs = 0;
- opt.compress_keys = 0; /* not mandated but we do it */
- opt.compress_sigs = 0; /* ditto. */
- opt.not_dash_escaped = 0;
- opt.def_cipher_algo = 0;
- opt.def_digest_algo = 0;
- opt.cert_digest_algo = 0;
- opt.def_compress_algo = -1;
- opt.s2k_mode = 3; /* iterated+salted */
- opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
- opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
- break;
- case oPGP2: opt.compliance = CO_PGP2; break;
- case oPGP6: opt.compliance = CO_PGP6; break;
- case oPGP7: opt.compliance = CO_PGP7; break;
- case oPGP8: opt.compliance = CO_PGP8; break;
- case oGnuPG: opt.compliance = CO_GNUPG; break;
- case oEmuMDEncodeBug: opt.emulate_bugs |= EMUBUG_MDENCODE; break;
- case oCompressSigs: opt.compress_sigs = 1; break;
- case oSetFilename: opt.set_filename = pargs.r.ret_str; break;
- case oForYourEyesOnly: eyes_only = 1; break;
- case oNoForYourEyesOnly: eyes_only = 0; break;
- case oSetPolicyURL:
- add_policy_url(pargs.r.ret_str,0);
- add_policy_url(pargs.r.ret_str,1);
- break;
- case oSigPolicyURL: add_policy_url(pargs.r.ret_str,0); break;
- case oCertPolicyURL: add_policy_url(pargs.r.ret_str,1); break;
- case oShowPolicyURL:
- opt.list_options|=LIST_SHOW_POLICY;
- opt.verify_options|=VERIFY_SHOW_POLICY;
- break;
- case oNoShowPolicyURL:
- opt.list_options&=~LIST_SHOW_POLICY;
- opt.verify_options&=~VERIFY_SHOW_POLICY;
- break;
- case oSigKeyserverURL: add_keyserver_url(pargs.r.ret_str,0); break;
- case oUseEmbeddedFilename: opt.use_embedded_filename = 1; break;
-
- case oComment: add_to_strlist(&opt.comments,pargs.r.ret_str); break;
- case oDefaultComment:
- deprecated_warning(configname,configlineno,
- "--default-comment","--no-comments","");
- /* fall through */
- case oNoComments:
- free_strlist(opt.comments);
- opt.comments=NULL;
- break;
-
- case oThrowKeyid: opt.throw_keyid = 1; break;
- case oNoThrowKeyid: opt.throw_keyid = 0; break;
- case oShowPhotos:
- opt.list_options|=LIST_SHOW_PHOTOS;
- opt.verify_options|=VERIFY_SHOW_PHOTOS;
- break;
- case oNoShowPhotos:
- opt.list_options&=~LIST_SHOW_PHOTOS;
- opt.verify_options&=~VERIFY_SHOW_PHOTOS;
- break;
- case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break;
- case oForceV3Sigs: opt.force_v3_sigs = 1; break;
- case oNoForceV3Sigs: opt.force_v3_sigs = 0; break;
- case oForceV4Certs: opt.force_v4_certs = 1; break;
- case oNoForceV4Certs: opt.force_v4_certs = 0; break;
- case oForceMDC: opt.force_mdc = 1; break;
- case oNoForceMDC: opt.force_mdc = 0; break;
- case oDisableMDC: opt.disable_mdc = 1; break;
- case oNoDisableMDC: opt.disable_mdc = 0; break;
- case oS2KMode: opt.s2k_mode = pargs.r.ret_int; break;
- case oS2KDigest: s2k_digest_string = xstrdup (pargs.r.ret_str); break;
- case oS2KCipher: s2k_cipher_string = xstrdup (pargs.r.ret_str); break;
- case oSimpleSKChecksum: opt.simple_sk_checksum = 1; break;
- case oNoEncryptTo: opt.no_encrypt_to = 1; break;
- case oEncryptTo: /* store the recipient in the second list */
- sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
- sl->flags = 1;
- break;
- case oHiddenEncryptTo: /* store the recipient in the second list */
- sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
- sl->flags = 1|2;
- break;
- case oRecipient: /* store the recipient */
- add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
- any_explicit_recipient = 1;
- break;
- case oHiddenRecipient: /* store the recipient with a flag */
- sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
- sl->flags = 2;
- any_explicit_recipient = 1;
- break;
- case oTextmodeShort: opt.textmode = 2; break;
- case oTextmode: opt.textmode=1; break;
- case oNoTextmode: opt.textmode=0; break;
- case oExpert: opt.expert = 1; break;
- case oNoExpert: opt.expert = 0; break;
- case oAskSigExpire: opt.ask_sig_expire = 1; break;
- case oNoAskSigExpire: opt.ask_sig_expire = 0; break;
- case oAskCertExpire: opt.ask_cert_expire = 1; break;
- case oNoAskCertExpire: opt.ask_cert_expire = 0; break;
- case oUser: /* store the local users */
- add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
- break;
- case oCompress: opt.compress = pargs.r.ret_int; break;
- case oPasswdFD:
- pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
- opt.use_agent = 0;
- break;
-#ifdef __riscos__
- case oPasswdFile:
- pwfd = iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 0), 0);
- break;
-#endif /* __riscos__ */
- case oCommandFD:
- opt.command_fd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
- break;
-#ifdef __riscos__
- case oCommandFile:
- opt.command_fd = iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 0), 0);
- break;
-#endif /* __riscos__ */
- case oCipherAlgo: def_cipher_string = xstrdup (pargs.r.ret_str); break;
- case oDigestAlgo: def_digest_string = xstrdup (pargs.r.ret_str); break;
- case oCompressAlgo:
- /* If it is all digits, stick a Z in front of it for
- later. This is for backwards compatibility with
- versions that took the compress algorithm number. */
- {
- char *pt=pargs.r.ret_str;
- while(*pt)
- {
- if(!isdigit(*pt))
- break;
-
- pt++;
- }
-
- if(*pt=='\0')
- {
- def_compress_string=xmalloc (strlen(pargs.r.ret_str)+2);
- strcpy(def_compress_string,"Z");
- strcat(def_compress_string,pargs.r.ret_str);
- }
- else
- def_compress_string = xstrdup (pargs.r.ret_str);
- }
- break;
- case oCertDigestAlgo: cert_digest_string = xstrdup (pargs.r.ret_str); break;
- case oNoSecmemWarn:
- gcry_control (GCRYCTL_DISABLE_SECMEM_WARN);
- break;
- case oNoPermissionWarn: opt.no_perm_warn=1; break;
- case oNoMDCWarn: opt.no_mdc_warn=1; break;
- case oCharset:
- if( set_native_charset( pargs.r.ret_str ) )
- log_error(_("%s is not a valid character set\n"),
- pargs.r.ret_str);
- break;
- case oNotDashEscaped: opt.not_dash_escaped = 1; break;
- case oEscapeFrom: opt.escape_from = 1; break;
- case oNoEscapeFrom: opt.escape_from = 0; break;
- case oLockOnce: opt.lock_once = 1; break;
- case oLockNever: disable_dotlock(); break;
- case oLockMultiple:
-#ifndef __riscos__
- opt.lock_once = 0;
-#else /* __riscos__ */
- riscos_not_implemented("lock-multiple");
-#endif /* __riscos__ */
- break;
- case oKeyServer:
- opt.keyserver_uri=xstrdup (pargs.r.ret_str);
- if(parse_keyserver_uri(pargs.r.ret_str,configname,configlineno))
- log_error(_("could not parse keyserver URI\n"));
- break;
- case oKeyServerOptions:
- parse_keyserver_options(pargs.r.ret_str);
- break;
- case oImportOptions:
- if(!parse_import_options(pargs.r.ret_str,&opt.import_options))
- {
- if(configname)
- log_error(_("%s:%d: invalid import options\n"),
- configname,configlineno);
- else
- log_error(_("invalid import options\n"));
- }
- break;
- case oExportOptions:
- if(!parse_export_options(pargs.r.ret_str,&opt.export_options))
- {
- if(configname)
- log_error(_("%s:%d: invalid export options\n"),
- configname,configlineno);
- else
- log_error(_("invalid export options\n"));
- }
- break;
- case oListOptions:
- {
- struct parse_options lopts[]=
- {
- {"show-photos",LIST_SHOW_PHOTOS},
- {"show-policy-url",LIST_SHOW_POLICY},
- {"show-notation",LIST_SHOW_NOTATION},
- {"show-keyserver-url",LIST_SHOW_KEYSERVER},
- {"show-validity",LIST_SHOW_VALIDITY},
- {"show-long-keyid",LIST_SHOW_LONG_KEYID},
- {"show-keyring",LIST_SHOW_KEYRING},
- {"show-sig-expire",LIST_SHOW_SIG_EXPIRE},
- {NULL,0}
- };
-
- if(!parse_options(pargs.r.ret_str,&opt.list_options,lopts))
- {
- if(configname)
- log_error(_("%s:%d: invalid list options\n"),
- configname,configlineno);
- else
- log_error(_("invalid list options\n"));
- }
- }
- break;
- case oVerifyOptions:
- {
- struct parse_options vopts[]=
- {
- {"show-photos",VERIFY_SHOW_PHOTOS},
- {"show-policy-url",VERIFY_SHOW_POLICY},
- {"show-notation",VERIFY_SHOW_NOTATION},
- {"show-keyserver-url",VERIFY_SHOW_KEYSERVER},
- {"show-validity",VERIFY_SHOW_VALIDITY},
- {"show-long-keyid",VERIFY_SHOW_LONG_KEYID},
- {NULL,0}
- };
-
- if(!parse_options(pargs.r.ret_str,&opt.verify_options,vopts))
- {
- if(configname)
- log_error(_("%s:%d: invalid verify options\n"),
- configname,configlineno);
- else
- log_error(_("invalid verify options\n"));
- }
- }
- break;
- case oTempDir: opt.temp_dir=pargs.r.ret_str; break;
- case oExecPath:
- if(set_exec_path(pargs.r.ret_str,0))
- log_error(_("unable to set exec-path to %s\n"),pargs.r.ret_str);
- else
- opt.exec_path_set=1;
- break;
- case oSetNotation:
- add_notation_data( pargs.r.ret_str, 0 );
- add_notation_data( pargs.r.ret_str, 1 );
- break;
- case oSigNotation: add_notation_data( pargs.r.ret_str, 0 ); break;
- case oCertNotation: add_notation_data( pargs.r.ret_str, 1 ); break;
- case oShowNotation:
- opt.list_options|=LIST_SHOW_NOTATION;
- opt.verify_options|=VERIFY_SHOW_NOTATION;
- break;
- case oNoShowNotation:
- opt.list_options&=~LIST_SHOW_NOTATION;
- opt.verify_options&=~VERIFY_SHOW_NOTATION;
- break;
- case oUtf8Strings: utf8_strings = 1; break;
- case oNoUtf8Strings: utf8_strings = 0; break;
- case oDisableCipherAlgo:
- {
- int algo = gcry_cipher_map_name (pargs.r.ret_str);
- gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO,
- &algo, sizeof algo);
- }
- break;
- case oDisablePubkeyAlgo:
- {
- int algo = gcry_pk_map_name (pargs.r.ret_str);
- gcry_pk_ctl (GCRYCTL_DISABLE_ALGO,
- &algo, sizeof algo );
- }
- break;
- case oNoSigCache: opt.no_sig_cache = 1; break;
- case oNoSigCreateCheck: opt.no_sig_create_check = 1; break;
- case oAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid = 1; break;
- case oNoAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid=0; break;
- case oAllowFreeformUID: opt.allow_freeform_uid = 1; break;
- case oNoAllowFreeformUID: opt.allow_freeform_uid = 0; break;
- case oNoLiteral: opt.no_literal = 1; break;
- case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break;
- case oHonorHttpProxy:
- opt.keyserver_options.honor_http_proxy = 1;
- deprecated_warning(configname,configlineno,
- "--honor-http-proxy",
- "--keyserver-options ",
- "honor-http-proxy");
- break;
- case oFastListMode: opt.fast_list_mode = 1; break;
- case oFixedListMode: opt.fixed_list_mode = 1; break;
- case oListOnly: opt.list_only=1; break;
- case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
- case oIgnoreValidFrom: opt.ignore_valid_from = 1; break;
- case oIgnoreCrcError: opt.ignore_crc_error = 1; break;
- case oIgnoreMDCError: opt.ignore_mdc_error = 1; break;
- case oNoRandomSeedFile: use_random_seed = 0; break;
- case oAutoKeyRetrieve:
- case oNoAutoKeyRetrieve:
- opt.keyserver_options.auto_key_retrieve=
- (pargs.r_opt==oAutoKeyRetrieve);
- deprecated_warning(configname,configlineno,
- pargs.r_opt==oAutoKeyRetrieve?"--auto-key-retrieve":
- "--no-auto-key-retrieve","--keyserver-options ",
- pargs.r_opt==oAutoKeyRetrieve?"auto-key-retrieve":
- "no-auto-key-retrieve");
- break;
- case oShowSessionKey: opt.show_session_key = 1; break;
- case oOverrideSessionKey:
- opt.override_session_key = pargs.r.ret_str;
- break;
- case oMergeOnly: opt.merge_only = 1; break;
- case oAllowSecretKeyImport: /* obsolete */ break;
- case oTryAllSecrets: opt.try_all_secrets = 1; break;
- case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break;
- case oEnableSpecialFilenames:
- iobuf_enable_special_filenames (1);
- break;
- case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break;
- case oAutoCheckTrustDB: opt.no_auto_check_trustdb=0; break;
- case oNoAutoCheckTrustDB: opt.no_auto_check_trustdb=1; break;
- case oPreservePermissions: opt.preserve_permissions=1; break;
- case oDefaultPreferenceList:
- opt.def_preference_list = pargs.r.ret_str;
- break;
- case oPersonalCipherPreferences:
- pers_cipher_list=pargs.r.ret_str;
- break;
- case oPersonalDigestPreferences:
- pers_digest_list=pargs.r.ret_str;
- break;
- case oPersonalCompressPreferences:
- pers_compress_list=pargs.r.ret_str;
- break;
- case oAgentProgram: opt.agent_program = pargs.r.ret_str; break;
- case oDisplay: opt.display = pargs.r.ret_str; break;
- case oTTYname: opt.ttyname = pargs.r.ret_str; break;
- case oTTYtype: opt.ttytype = pargs.r.ret_str; break;
- case oLCctype: opt.lc_ctype = pargs.r.ret_str; break;
- case oLCmessages: opt.lc_messages = pargs.r.ret_str; break;
- case oGroup: add_group(pargs.r.ret_str); break;
- case oStrict: opt.strict=1; log_set_strict(1); break;
- case oNoStrict: opt.strict=0; log_set_strict(0); break;
-
- case oMangleDosFilenames: opt.mangle_dos_filenames = 1; break;
- case oNoMangleDosFilenames: opt.mangle_dos_filenames = 0; break;
-
- case oEnableProgressFilter: opt.enable_progress_filter = 1; break;
- case oMultifile: multifile=1; break;
-
- default : pargs.err = configfp? 1:2; break;
- }
- }
-
- if( configfp ) {
- fclose( configfp );
- configfp = NULL;
- config_filename = configname; /* Keep a copy of the config
- file name. */
- configname = NULL;
- goto next_pass;
- }
- xfree ( configname ); configname = NULL;
- if( log_get_errorcount(0) )
- g10_exit(2);
- if( nogreeting )
- greeting = 0;
-
- if( greeting ) {
- fprintf(stderr, "%s %s; %s\n",
- strusage(11), strusage(13), strusage(14) );
- fprintf(stderr, "%s\n", strusage(15) );
- }
-#ifdef IS_DEVELOPMENT_VERSION
- if( !opt.batch ) {
- log_info("NOTE: THIS IS A DEVELOPMENT VERSION!\n");
- log_info("It is only intended for test purposes and should NOT be\n");
- log_info("used in a production environment or with production keys!\n");
- }
-#endif
-
- /* FIXME: We should use the lggging to a file only in server mode;
- however we have not yet implemetyed that thus we try to get
- away with --batch as indication for logging to file required. */
- if (logfile && opt.batch)
- {
- log_set_file (logfile);
- log_set_prefix (NULL, 1|2|4);
- }
-
- if (opt.verbose > 2)
- log_info ("using character set `%s'\n", get_native_charset ());
-
- if( may_coredump && !opt.quiet )
- log_info(_("WARNING: program may create a core file!\n"));
-
- if (eyes_only) {
- if (opt.set_filename)
- log_info(_("WARNING: %s overrides %s\n"),
- "--for-your-eyes-only","--set-filename");
-
- opt.set_filename="_CONSOLE";
- }
-
- if (opt.no_literal) {
- log_info(_("NOTE: %s is not for normal use!\n"), "--no-literal");
- if (opt.textmode)
- log_error(_("%s not allowed with %s!\n"),
- "--textmode", "--no-literal" );
- if (opt.set_filename)
- log_error(_("%s makes no sense with %s!\n"),
- eyes_only?"--for-your-eyes-only":"--set-filename",
- "--no-literal" );
- }
-
- if (opt.set_filesize)
- log_info(_("NOTE: %s is not for normal use!\n"), "--set-filesize");
- if( opt.batch )
- tty_batchmode( 1 );
-
- gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
- set_debug (debug_level);
-
- /* Do these after the switch(), so they can override settings. */
- if(PGP2)
- {
- int unusable=0;
-
- if(cmd==aSign && !detached_sig)
- {
- log_info(_("you can only make detached or clear signatures "
- "while in --pgp2 mode\n"));
- unusable=1;
- }
- else if(cmd==aSignEncr || cmd==aSignSym)
- {
- log_info(_("you can't sign and encrypt at the "
- "same time while in --pgp2 mode\n"));
- unusable=1;
- }
- else if(argc==0 && (cmd==aSign || cmd==aEncr || cmd==aSym))
- {
- log_info(_("you must use files (and not a pipe) when "
- "working with --pgp2 enabled.\n"));
- unusable=1;
- }
- else if(cmd==aEncr || cmd==aSym)
- {
- /* Everything else should work without IDEA (except using
- a secret key encrypted with IDEA and setting an IDEA
- preference, but those have their own error
- messages). */
-
- if(openpgp_cipher_test_algo (CIPHER_ALGO_IDEA))
- {
- log_info(_("encrypting a message in --pgp2 mode requires "
- "the IDEA cipher\n"));
- idea_cipher_warn(1);
- unusable=1;
- }
- else if(cmd==aSym)
- {
- /* This only sets IDEA for symmetric encryption
- since it is set via select_algo_from_prefs for
- pk encryption. */
- xfree (def_cipher_string);
- def_cipher_string = xstrdup ("idea");
- }
-
- /* PGP2 can't handle the output from the textmode
- filter, so we disable it for anything that could
- create a literal packet (only encryption and
- symmetric encryption, since we disable signing
- above). */
- if(!unusable)
- opt.textmode=0;
- }
-
- if(unusable)
- compliance_failure();
- else
- {
- opt.force_v4_certs = 0;
- opt.sk_comments = 0;
- opt.escape_from = 1;
- opt.force_v3_sigs = 1;
- opt.pgp2_workarounds = 1;
- opt.ask_sig_expire = 0;
- opt.ask_cert_expire = 0;
- xfree (def_digest_string);
- def_digest_string = xstrdup ("md5");
- opt.def_compress_algo = 1;
- }
- }
- else if(PGP6)
- {
- opt.sk_comments=0;
- opt.escape_from=1;
- opt.force_v3_sigs=1;
- opt.ask_sig_expire=0;
- }
- else if(PGP7)
- {
- opt.sk_comments=0;
- opt.escape_from=1;
- opt.force_v3_sigs=1;
- opt.ask_sig_expire=0;
- }
- else if(PGP8)
- {
- opt.escape_from=1;
- }
-
- /* must do this after dropping setuid, because string_to...
- * may try to load an module */
- if( def_cipher_string ) {
- opt.def_cipher_algo = gcry_cipher_map_name (def_cipher_string);
- if(opt.def_cipher_algo==0 &&
- (ascii_strcasecmp(def_cipher_string,"idea")==0
- || ascii_strcasecmp(def_cipher_string,"s1")==0))
- idea_cipher_warn(1);
- xfree (def_cipher_string); def_cipher_string = NULL;
- if( openpgp_cipher_test_algo (opt.def_cipher_algo) )
- log_error(_("selected cipher algorithm is invalid\n"));
- }
- if( def_digest_string ) {
- opt.def_digest_algo = gcry_md_map_name (def_digest_string);
- xfree (def_digest_string); def_digest_string = NULL;
- if( openpgp_md_test_algo (opt.def_digest_algo) )
- log_error(_("selected digest algorithm is invalid\n"));
- }
- if( def_compress_string ) {
- opt.def_compress_algo = string_to_compress_algo(def_compress_string);
- xfree (def_compress_string); def_compress_string = NULL;
- if( check_compress_algo(opt.def_compress_algo) )
- log_error(_("selected compression algorithm is invalid\n"));
- }
- if( cert_digest_string ) {
- opt.cert_digest_algo = gcry_md_map_name (cert_digest_string);
- xfree (cert_digest_string); cert_digest_string = NULL;
- if( openpgp_md_test_algo(opt.cert_digest_algo) )
- log_error(_("selected certification digest algorithm is invalid\n"));
- }
- if( s2k_cipher_string ) {
- opt.s2k_cipher_algo = gcry_cipher_map_name (s2k_cipher_string);
- xfree (s2k_cipher_string); s2k_cipher_string = NULL;
- if( openpgp_cipher_test_algo (opt.s2k_cipher_algo) )
- log_error(_("selected cipher algorithm is invalid\n"));
- }
- if( s2k_digest_string ) {
- opt.s2k_digest_algo = gcry_md_map_name (s2k_digest_string);
- xfree (s2k_digest_string); s2k_digest_string = NULL;
- if( openpgp_md_test_algo (opt.s2k_digest_algo) )
- log_error(_("selected digest algorithm is invalid\n"));
- }
- if( opt.completes_needed < 1 )
- log_error(_("completes-needed must be greater than 0\n"));
- if( opt.marginals_needed < 2 )
- log_error(_("marginals-needed must be greater than 1\n"));
- if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 )
- log_error(_("max-cert-depth must be in range 1 to 255\n"));
- switch( opt.s2k_mode ) {
- case 0:
- log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
- break;
- case 1: case 3: break;
- default:
- log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
- }
-
- if(opt.def_cert_check_level<0 || opt.def_cert_check_level>3)
- log_error(_("invalid default-check-level; must be 0, 1, 2, or 3\n"));
-
- /* This isn't actually needed, but does serve to error out if the
- string is invalid. */
- if(opt.def_preference_list &&
- keygen_set_std_prefs(opt.def_preference_list,0))
- log_error(_("invalid default preferences\n"));
-
- /* We provide defaults for the personal digest list */
- if(!pers_digest_list)
- pers_digest_list="h2";
-
- if(pers_cipher_list &&
- keygen_set_std_prefs(pers_cipher_list,PREFTYPE_SYM))
- log_error(_("invalid personal cipher preferences\n"));
-
- if(pers_digest_list &&
- keygen_set_std_prefs(pers_digest_list,PREFTYPE_HASH))
- log_error(_("invalid personal digest preferences\n"));
-
- if(pers_compress_list &&
- keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP))
- log_error(_("invalid personal compress preferences\n"));
-
- /* We don't support all possible commands with multifile yet */
- if(multifile)
- {
- char *cmdname;
-
- switch(cmd)
- {
- case aSign:
- cmdname="--sign";
- break;
- case aClearsign:
- cmdname="--clearsign";
- break;
- case aDetachedSign:
- cmdname="--detach-sign";
- break;
- case aSym:
- cmdname="--symmetric";
- break;
- case aStore:
- cmdname="--store";
- break;
- default:
- cmdname=NULL;
- break;
- }
-
- if(cmdname)
- log_error(_("%s does not yet work with %s\n"),cmdname,"--multifile");
- }
-
- if( log_get_errorcount(0) )
- g10_exit(2);
-
- /* Check our chosen algorithms against the list of legal
- algorithms. */
-
- if(!GNUPG)
- {
- const char *badalg=NULL;
- preftype_t badtype=PREFTYPE_NONE;
-
- if (opt.def_cipher_algo
- && !algo_available (PREFTYPE_SYM,opt.def_cipher_algo,NULL))
- {
- badalg = gcry_cipher_algo_name (opt.def_cipher_algo);
- badtype = PREFTYPE_SYM;
- }
- else if (opt.def_digest_algo
- && !algo_available (PREFTYPE_HASH,opt.def_digest_algo,NULL))
- {
- badalg = gcry_md_algo_name (opt.def_digest_algo);
- badtype = PREFTYPE_HASH;
- }
- else if (opt.cert_digest_algo
- && !algo_available (PREFTYPE_HASH,opt.cert_digest_algo,NULL))
- {
- badalg = gcry_md_algo_name (opt.cert_digest_algo);
- badtype = PREFTYPE_HASH;
- }
- else if (opt.def_compress_algo!=-1
- && !algo_available (PREFTYPE_ZIP,opt.def_compress_algo,NULL))
- {
- badalg = compress_algo_to_string (opt.def_compress_algo);
- badtype = PREFTYPE_ZIP;
- }
-
- if (badalg)
- {
- switch(badtype)
- {
- case PREFTYPE_SYM:
- log_info(_("you may not use cipher algorithm \"%s\" "
- "while in %s mode\n"),
- badalg,compliance_option_string());
- break;
- case PREFTYPE_HASH:
- log_info(_("you may not use digest algorithm \"%s\" "
- "while in %s mode\n"),
- badalg,compliance_option_string());
- break;
- case PREFTYPE_ZIP:
- log_info(_("you may not use compression algorithm \"%s\" "
- "while in %s mode\n"),
- badalg,compliance_option_string());
- break;
- default:
- BUG();
- }
-
- compliance_failure();
- }
- }
-
- /* set the random seed file */
- if( use_random_seed ) {
- char *p = make_filename(opt.homedir, "random_seed", NULL );
- gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
- xfree (p);
- }
-
- if( !cmd && opt.fingerprint && !with_fpr ) {
- set_cmd( &cmd, aListKeys);
- }
-
- /* Compression algorithm 0 means no compression at all */
- if( opt.def_compress_algo == 0)
- opt.compress = 0;
-
- /* kludge to let -sat generate a clear text signature */
- if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
- cmd = aClearsign;
-
- if( opt.verbose > 1 )
- set_packet_list_mode(1);
-
- /* Add the keyrings, but not for some special commands. Also
- avoid adding the secret keyring for a couple of commands to
- avoid unneeded access in case the secrings are stored on a
- floppy */
- if( cmd != aDeArmor && cmd != aEnArmor && cmd != aGPGConfList )
- {
- if (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys
- && cmd != aVerify && cmd != aSym)
- {
- if (!sec_nrings || default_keyring) /* add default secret rings */
- keydb_add_resource ("secring" EXTSEP_S "gpg", 0, 1);
- for (sl = sec_nrings; sl; sl = sl->next)
- keydb_add_resource ( sl->d, 0, 1 );
- }
- if( !nrings || default_keyring ) /* add default ring */
- keydb_add_resource ("pubring" EXTSEP_S "gpg", 0, 0);
- for(sl = nrings; sl; sl = sl->next )
- keydb_add_resource ( sl->d, sl->flags, 0 );
- }
- FREE_STRLIST(nrings);
- FREE_STRLIST(sec_nrings);
-
-
- if( pwfd != -1 ) /* read the passphrase now. */
- read_passphrase_from_fd( pwfd );
-
- fname = argc? *argv : NULL;
-
- switch( cmd ) {
- case aPrimegen:
- case aPrintMD:
- case aPrintMDs:
- case aGenRandom:
- case aDeArmor:
- case aEnArmor:
- case aFixTrustDB:
- case aCardStatus:
- case aCardEdit:
- case aChangePIN:
- case aGPGConfList:
- break;
- case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break;
- case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break;
- default: rc = setup_trustdb(1, trustdb_name ); break;
- }
- if( rc )
- log_error(_("failed to initialize the TrustDB: %s\n"), gpg_strerror (rc));
-
-
- switch (cmd) {
- case aStore:
- case aSym:
- case aSign:
- case aSignSym:
- case aClearsign:
- if (!opt.quiet && any_explicit_recipient)
- log_info (_("WARNING: recipients (-r) given "
- "without using public key encryption\n"));
- break;
- default:
- break;
- }
-
- switch( cmd ) {
- case aStore: /* only store the file */
- if( argc > 1 )
- wrong_args(_("--store [filename]"));
- if( (rc = encode_store(fname)) )
- log_error ("\b%s: store failed: %s\n",
- print_fname_stdin(fname), gpg_strerror (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)) )
- log_error ("\b%s: symmetric encryption failed: %s\n",
- print_fname_stdin(fname), gpg_strerror (rc) );
- break;
-
- case aEncr: /* encrypt the given file */
- if(multifile)
- encode_crypt_files(argc, argv, remusr);
- else
- {
- if( argc > 1 )
- wrong_args(_("--encrypt [filename]"));
- if( (rc = encode_crypt(fname,remusr)) )
- log_error("%s: encryption failed: %s\n",
- print_fname_stdin(fname), gpg_strerror (rc) );
- }
- break;
-
- case aSign: /* sign the given file */
- sl = NULL;
- if( detached_sig ) { /* sign all files */
- for( ; argc; argc--, argv++ )
- add_to_strlist( &sl, *argv );
- }
- else {
- if( argc > 1 )
- wrong_args(_("--sign [filename]"));
- if( argc ) {
- sl = xcalloc (1, sizeof *sl + strlen(fname));
- strcpy(sl->d, fname);
- }
- }
- if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
- log_error("signing failed: %s\n", gpg_strerror (rc) );
- free_strlist(sl);
- break;
-
- case aSignEncr: /* sign and encrypt the given file */
- if( argc > 1 )
- wrong_args(_("--sign --encrypt [filename]"));
- if( argc ) {
- sl = xcalloc (1, sizeof *sl + strlen(fname));
- strcpy(sl->d, fname);
- }
- else
- sl = NULL;
- if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
- log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), gpg_strerror (rc) );
- free_strlist(sl);
- break;
-
- case aSignSym: /* sign and conventionally encrypt the given file */
- if (argc > 1)
- wrong_args(_("--sign --symmetric [filename]"));
- rc = sign_symencrypt_file (fname, locusr);
- if (rc)
- log_error("%s: sign+symmetric failed: %s\n",
- print_fname_stdin(fname), gpg_strerror (rc) );
- break;
-
- case aClearsign: /* make a clearsig */
- if( argc > 1 )
- wrong_args(_("--clearsign [filename]"));
- if( (rc = clearsign_file(fname, locusr, NULL)) )
- log_error("%s: clearsign failed: %s\n",
- print_fname_stdin(fname), gpg_strerror (rc) );
- break;
-
- case aVerify:
- if(multifile)
- {
- if( (rc = verify_files( argc, argv ) ))
- log_error("verify files failed: %s\n", gpg_strerror (rc) );
- }
- else
- {
- if( (rc = verify_signatures( argc, argv ) ))
- log_error("verify signatures failed: %s\n", gpg_strerror (rc) );
- }
- break;
-
- case aDecrypt:
- if(multifile)
- decrypt_messages(argc, argv);
- else
- {
- if( argc > 1 )
- wrong_args(_("--decrypt [filename]"));
- if( (rc = decrypt_message( fname ) ))
- log_error("decrypt_message failed: %s\n", gpg_strerror (rc) );
- }
- break;
-
- case aSignKey: /* sign the key given as argument */
- if( argc != 1 )
- wrong_args(_("--sign-key user-id"));
- username = make_username( fname );
- keyedit_menu(fname, locusr, NULL, 1 );
- xfree (username);
- break;
-
- case aLSignKey:
- if( argc != 1 )
- wrong_args(_("--lsign-key user-id"));
- username = make_username( fname );
- keyedit_menu(fname, locusr, NULL, 2 );
- xfree (username);
- break;
-
- case aNRSignKey:
- if( argc != 1 )
- wrong_args(_("--nrsign-key user-id"));
- username = make_username( fname );
- keyedit_menu(fname, locusr, NULL, 3 );
- xfree (username);
- break;
-
- case aNRLSignKey:
- if( argc != 1 )
- wrong_args(_("--nrlsign-key user-id"));
- username = make_username( fname );
- keyedit_menu(fname, locusr, NULL, 4 );
- xfree (username);
- break;
-
- case aEditKey: /* Edit a key signature */
- if( !argc )
- wrong_args(_("--edit-key user-id [commands]"));
- username = make_username( fname );
- if( argc > 1 ) {
- sl = NULL;
- for( argc--, argv++ ; argc; argc--, argv++ )
- append_to_strlist( &sl, *argv );
- keyedit_menu( username, locusr, sl, 0 );
- free_strlist(sl);
- }
- else
- keyedit_menu(username, locusr, NULL, 0 );
- xfree (username);
- break;
-
- case aDeleteKeys:
- case aDeleteSecretKeys:
- case aDeleteSecretAndPublicKeys:
- sl = NULL;
- /* I'm adding these in reverse order as add_to_strlist2
- reverses them again, and it's easier to understand in the
- proper order :) */
- for( ; argc; argc-- )
- add_to_strlist2( &sl, argv[argc-1], utf8_strings );
- delete_keys(sl,cmd==aDeleteSecretKeys,cmd==aDeleteSecretAndPublicKeys);
- free_strlist(sl);
- break;
-
- case aCheckKeys:
- opt.check_sigs = 1;
- case aListSigs:
- opt.list_sigs = 1;
- case aListKeys:
- sl = NULL;
- for( ; argc; argc--, argv++ )
- add_to_strlist2( &sl, *argv, utf8_strings );
- public_key_list( sl );
- free_strlist(sl);
- break;
- case aListSecretKeys:
- sl = NULL;
- for( ; argc; argc--, argv++ )
- add_to_strlist2( &sl, *argv, utf8_strings );
- secret_key_list( sl );
- free_strlist(sl);
- break;
-
- case aKeygen: /* generate a key */
- if( opt.batch ) {
- if( argc > 1 )
- wrong_args("--gen-key [parameterfile]");
- generate_keypair( argc? *argv : NULL, NULL );
- }
- else {
- if( argc )
- wrong_args("--gen-key");
- generate_keypair(NULL, NULL);
- }
- break;
-
- case aFastImport:
- opt.import_options |= IMPORT_FAST_IMPORT;
- case aImport:
- import_keys( argc? argv:NULL, argc, NULL, opt.import_options );
- break;
-
- case aExport:
- case aExportAll:
- case aSendKeys:
- case aRecvKeys:
- sl = NULL;
- for( ; argc; argc--, argv++ )
- add_to_strlist2( &sl, *argv, utf8_strings );
- if( cmd == aSendKeys )
- rc=keyserver_export( sl );
- else if( cmd == aRecvKeys )
- rc=keyserver_import( sl );
- else
- rc=export_pubkeys( sl, opt.export_options );
- if(rc)
- {
- if(cmd==aSendKeys)
- log_error(_("keyserver send failed: %s\n"),gpg_strerror (rc));
- else if(cmd==aRecvKeys)
- log_error(_("keyserver receive failed: %s\n"),gpg_strerror (rc));
- else
- log_error(_("key export failed: %s\n"),gpg_strerror (rc));
- }
- free_strlist(sl);
- break;
-
- case aSearchKeys:
- sl = NULL;
- for( ; argc; argc--, argv++ )
- {
- if (utf8_strings)
- sl = append_to_strlist ( &sl, *argv );
- else
- {
- char *p = native_to_utf8 ( *argv );
- sl = append_to_strlist( &sl, p );
- xfree( p );
- }
- }
-
- rc=keyserver_search( sl );
- if(rc)
- log_error(_("keyserver search failed: %s\n"),gpg_strerror (rc));
- free_strlist(sl);
- break;
-
- case aRefreshKeys:
- sl = NULL;
- for( ; argc; argc--, argv++ )
- add_to_strlist2( &sl, *argv, utf8_strings );
- rc=keyserver_refresh(sl);
- if(rc)
- log_error(_("keyserver refresh failed: %s\n"),gpg_strerror (rc));
- free_strlist(sl);
- break;
-
- case aExportSecret:
- sl = NULL;
- for( ; argc; argc--, argv++ )
- add_to_strlist2( &sl, *argv, utf8_strings );
- export_seckeys( sl );
- free_strlist(sl);
- break;
-
- case aExportSecretSub:
- sl = NULL;
- for( ; argc; argc--, argv++ )
- add_to_strlist2( &sl, *argv, utf8_strings );
- export_secsubkeys( sl );
- free_strlist(sl);
- break;
-
- case aGenRevoke:
- if( argc != 1 )
- wrong_args("--gen-revoke user-id");
- username = make_username(*argv);
- gen_revoke( username );
- xfree ( username );
- break;
-
- case aDesigRevoke:
- if( argc != 1 )
- wrong_args("--desig-revoke user-id");
- username = make_username(*argv);
- gen_desig_revoke( username );
- xfree ( username );
- break;
-
- case aDeArmor:
- if( argc > 1 )
- wrong_args("--dearmor [file]");
- rc = dearmor_file( argc? *argv: NULL );
- if( rc )
- log_error(_("dearmoring failed: %s\n"), gpg_strerror (rc));
- break;
-
- case aEnArmor:
- if( argc > 1 )
- wrong_args("--enarmor [file]");
- rc = enarmor_file( argc? *argv: NULL );
- if( rc )
- log_error(_("enarmoring failed: %s\n"), gpg_strerror (rc));
- break;
-
-
- case aPrimegen:
-#if 0 /*FIXME-XXX*/
- { int mode = argc < 2 ? 0 : atoi(*argv);
-
- if( mode == 1 && argc == 2 ) {
- mpi_print( stdout, generate_public_prime( atoi(argv[1]) ), 1);
- }
- else if( mode == 2 && argc == 3 ) {
- mpi_print( stdout, generate_elg_prime(
- 0, atoi(argv[1]),
- atoi(argv[2]), NULL,NULL ), 1);
- }
- else if( mode == 3 && argc == 3 ) {
- gcry_mpi_t *factors;
- mpi_print( stdout, generate_elg_prime(
- 1, atoi(argv[1]),
- atoi(argv[2]), NULL,&factors ), 1);
- putchar('\n');
- mpi_print( stdout, factors[0], 1 ); /* print q */
- }
- else if( mode == 4 && argc == 3 ) {
- gcry_mpi_t g = mpi_alloc(1);
- mpi_print( stdout, generate_elg_prime(
- 0, atoi(argv[1]),
- atoi(argv[2]), g, NULL ), 1);
- putchar('\n');
- mpi_print( stdout, g, 1 );
- mpi_free(g);
- }
- else
- wrong_args("--gen-prime mode bits [qbits] ");
- putchar('\n');
- }
-#endif
- break;
-
- case aGenRandom:
- {
- int level = argc ? atoi(*argv):0;
- int count = argc > 1 ? atoi(argv[1]): 0;
- int endless = !count;
-
- if( argc < 1 || argc > 2 || level < 0 || level > 2 || count < 0 )
- wrong_args("--gen-random 0|1|2 [count]");
-
- while( endless || count ) {
- byte *p;
- /* Wee need a multiple of 3, so that in case of
- armored output we get a correct string. No
- linefolding is done, as it is best to levae this to
- other tools */
- size_t n = !endless && count < 99? count : 99;
-
- p = gcry_random_bytes (n, level);
-#ifdef HAVE_DOSISH_SYSTEM
- setmode ( fileno(stdout), O_BINARY );
-#endif
- if (opt.armor) {
- char *tmp = make_radix64_string (p, n);
- fputs (tmp, stdout);
- xfree (tmp);
- if (n%3 == 1)
- putchar ('=');
- if (n%3)
- putchar ('=');
- } else {
- fwrite( p, n, 1, stdout );
- }
- xfree (p);
- if( !endless )
- count -= n;
- }
- if (opt.armor)
- putchar ('\n');
- }
- break;
-
- case aPrintMD:
- if( argc < 1)
- wrong_args("--print-md algo [files]");
- {
- int all_algos = (**argv=='*' && !(*argv)[1]);
- int algo = all_algos? 0 : gcry_md_map_name (*argv);
-
- if( !algo && !all_algos )
- log_error(_("invalid hash algorithm `%s'\n"), *argv );
- else {
- argc--; argv++;
- if( !argc )
- print_mds(NULL, algo);
- else {
- for(; argc; argc--, argv++ )
- print_mds(*argv, algo);
- }
- }
- }
- break;
-
- case aPrintMDs: /* old option */
- if( !argc )
- print_mds(NULL,0);
- else {
- for(; argc; argc--, argv++ )
- print_mds(*argv,0);
- }
- break;
-
- case aListTrustDB:
- if( !argc )
- list_trustdb(NULL);
- else {
- for( ; argc; argc--, argv++ )
- list_trustdb( *argv );
- }
- break;
-
- case aUpdateTrustDB:
- if( argc )
- wrong_args("--update-trustdb");
- update_trustdb();
- break;
-
- case aCheckTrustDB:
- /* Old versions allowed for arguments - ignore them */
- check_trustdb();
- break;
-
- case aFixTrustDB:
- log_error("this command is not yet implemented.\n");
- log_error("A workaround is to use \"--export-ownertrust\", remove\n");
- log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
- break;
-
- case aListTrustPath:
- if( !argc )
- wrong_args("--list-trust-path <user-ids>");
- for( ; argc; argc--, argv++ ) {
- username = make_username( *argv );
- list_trust_path( username );
- xfree (username);
- }
- break;
-
- case aExportOwnerTrust:
- if( argc )
- wrong_args("--export-ownertrust");
- export_ownertrust();
- break;
-
- case aImportOwnerTrust:
- if( argc > 1 )
- wrong_args("--import-ownertrust [file]");
- import_ownertrust( argc? *argv:NULL );
- break;
-
- case aPipeMode:
- if ( argc )
- wrong_args ("--pipemode");
- run_in_pipemode ();
- break;
-
- case aRebuildKeydbCaches:
- if (argc)
- wrong_args ("--rebuild-keydb-caches");
- keydb_rebuild_caches ();
- break;
-
- case aCardStatus:
- if (argc)
- wrong_args ("--card-status");
- card_status (stdout, NULL, 0);
- break;
-
- case aCardEdit:
- if (argc)
- {
- sl = NULL;
- for (argc--, argv++ ; argc; argc--, argv++)
- append_to_strlist (&sl, *argv);
- card_edit (sl);
- free_strlist (sl);
- }
- else
- card_edit (NULL);
- break;
-
- case aChangePIN:
- if (!argc)
- change_pin (0);
- else if (argc == 1)
- change_pin ( atoi (*argv));
- else
- wrong_args ("--change-pin [no]");
- break;
-
- case aGPGConfList:
- { /* List options and default values in the GPG Conf format. */
-
- /* The following list is taken from gnupg/tools/gpgconf-comp.c. */
- /* Option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING
- FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE. */
-#define GC_OPT_FLAG_NONE 0UL
- /* The RUNTIME flag for an option indicates that the option can be
- changed at runtime. */
-#define GC_OPT_FLAG_RUNTIME (1UL << 3)
- /* The DEFAULT flag for an option indicates that the option has a
- default value. */
-#define GC_OPT_FLAG_DEFAULT (1UL << 4)
- /* The DEF_DESC flag for an option indicates that the option has a
- default, which is described by the value of the default field. */
-#define GC_OPT_FLAG_DEF_DESC (1UL << 5)
- /* The NO_ARG_DESC flag for an option indicates that the argument has
- a default, which is described by the value of the ARGDEF field. */
-#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6)
-
- if (!config_filename)
- config_filename = make_filename (opt.homedir, "gpg.conf", NULL);
-
- printf ("gpgconf-gpg.conf:%lu:\"%s\n",
- GC_OPT_FLAG_DEFAULT, config_filename);
-
- printf ("verbose:%lu:\n"
- "quiet:%lu:\n"
- "debug-level:%lu:\"none:\n"
- "log-file:%lu:\n",
- GC_OPT_FLAG_NONE,
- GC_OPT_FLAG_NONE,
- GC_OPT_FLAG_DEFAULT,
- GC_OPT_FLAG_NONE );
- printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE);
-
- }
- break;
-
- case aListPackets:
- opt.list_packets=2;
- default:
- if( argc > 1 )
- wrong_args(_("[filename]"));
- /* Issue some output for the unix newbie */
- if( !fname && !opt.outfile && isatty( fileno(stdin) )
- && isatty( fileno(stdout) ) && isatty( fileno(stderr) ) )
- log_info(_("Go ahead and type your message ...\n"));
-
- if( !(a = iobuf_open(fname)) )
- log_error(_("can't open `%s'\n"), print_fname_stdin(fname));
- else {
-
- if( !opt.no_armor ) {
- if( use_armor_filter( a ) ) {
- memset( &afx, 0, sizeof afx);
- iobuf_push_filter( a, armor_filter, &afx );
- }
- }
- if( cmd == aListPackets ) {
- set_packet_list_mode(1);
- opt.list_packets=1;
- }
- rc = proc_packets(NULL, a );
- if( rc )
- log_error("processing message failed: %s\n", gpg_strerror (rc) );
- iobuf_close(a);
- }
- break;
- }
-
- /* cleanup */
- FREE_STRLIST(remusr);
- FREE_STRLIST(locusr);
- g10_exit(0);
- return 8; /*NEVER REACHED*/
-}
-
-/* Note: This function is used by signal handlers!. */
-static void
-emergency_cleanup (void)
-{
- gcry_control (GCRYCTL_TERM_SECMEM );
-}
-
-
-void
-g10_exit( int rc )
-{
- gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
- if (opt.debug & DBG_MEMSTAT_VALUE)
- {
- gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
- gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
- }
- if (opt.debug)
- gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
- emergency_cleanup ();
- rc = rc? rc : log_get_errorcount(0)? 2 :
- g10_errors_seen? 1 : 0;
- exit (rc );
-}
-
-
-/* Pretty-print hex hashes. This assumes at least an 80-character
- display, but there are a few other similar assumptions in the
- display code. */
-static void
-print_hex( MD_HANDLE md, int algo, const char *fname )
-{
- int i,n,count,indent=0;
- const byte *p;
-
- if(fname)
- indent=printf("%s: ",fname);
-
- if(indent>40)
- {
- printf("\n");
- indent=0;
- }
-
- if(algo==DIGEST_ALGO_RMD160)
- indent+=printf("RMD160 = ");
- else if(algo>0)
- indent+=printf("%6s = ", gcry_md_algo_name (algo));
- else
- algo=abs(algo);
-
- count=indent;
-
- p = gcry_md_read (md, algo);
- n = gcry_md_get_algo_dlen (algo);
-
- count+=printf("%02X",*p++);
-
- for(i=1;i<n;i++,p++)
- {
- if(n==16)
- {
- if(count+2>79)
- {
- printf("\n%*s",indent," ");
- count=indent;
- }
- else
- count+=printf(" ");
-
- if(!(i%8))
- count+=printf(" ");
- }
- else if (n==20)
- {
- if(!(i%2))
- {
- if(count+4>79)
- {
- printf("\n%*s",indent," ");
- count=indent;
- }
- else
- count+=printf(" ");
- }
-
- if(!(i%10))
- count+=printf(" ");
- }
- else
- {
- if(!(i%4))
- {
- if(count+8>79)
- {
- printf("\n%*s",indent," ");
- count=indent;
- }
- else
- count+=printf(" ");
- }
- }
-
- count+=printf("%02X",*p);
- }
-
- printf("\n");
-}
-
-static void
-print_hashline( MD_HANDLE md, int algo, const char *fname )
-{
- int i, n;
- const byte *p;
-
- if ( fname ) {
- for (p = fname; *p; p++ ) {
- if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' )
- printf("%%%02X", *p );
- else
- putchar( *p );
- }
- }
- putchar(':');
- printf("%d:", algo );
- p = gcry_md_read (md, algo );
- n = gcry_md_get_algo_dlen (algo);
- for(i=0; i < n ; i++, p++ )
- printf("%02X", *p );
- putchar(':');
- putchar('\n');
-}
-
-static void
-print_mds( const char *fname, int algo )
-{
- FILE *fp;
- char buf[1024];
- size_t n;
- MD_HANDLE md;
-
- if( !fname ) {
- fp = stdin;
-#ifdef HAVE_DOSISH_SYSTEM
- setmode ( fileno(fp) , O_BINARY );
-#endif
- }
- else {
- fp = fopen( fname, "rb" );
- }
- if( !fp ) {
- log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
- return;
- }
-
- gcry_md_open (&md, 0, 0 );
- if( algo )
- gcry_md_enable ( md, algo );
- else {
- gcry_md_enable (md, GCRY_MD_MD5 );
- gcry_md_enable (md, GCRY_MD_SHA1 );
- gcry_md_enable (md, GCRY_MD_RMD160 );
-#ifdef USE_SHA256
- gcry_md_enable (md, GCRY_MD_SHA256 );
-#endif
-#ifdef USE_SHA512
- gcry_md_enable (md, GCRY_MD_SHA384 );
- gcry_md_enable (md, GCRY_MD_SHA512 );
-#endif
- }
-
- while( (n=fread( buf, 1, DIM(buf), fp )) )
- gcry_md_write (md, buf, n);
- if( ferror(fp) )
- log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
- else {
- gcry_md_final (md);
- if ( opt.with_colons ) {
- if ( algo )
- print_hashline( md, algo, fname );
- else {
- print_hashline( md, GCRY_MD_MD5, fname );
- print_hashline( md, GCRY_MD_SHA1, fname );
- print_hashline( md, GCRY_MD_RMD160, fname );
-#ifdef USE_SHA256
- print_hashline( md, GCRY_MD_SHA256, fname );
-#endif
-#ifdef USE_SHA512
- print_hashline( md, GCRY_MD_SHA384, fname );
- print_hashline( md, GCRY_MD_SHA512, fname );
-#endif
- }
- }
- else {
- if( algo )
- print_hex(md,-algo,fname);
- else {
- print_hex( md, GCRY_MD_MD5, fname );
- print_hex( md, GCRY_MD_SHA1, fname );
- print_hex( md, GCRY_MD_RMD160, fname );
-#ifdef USE_SHA256
- print_hex( md, GCRY_MD_SHA256, fname );
-#endif
-#ifdef USE_SHA512
- print_hex( md, GCRY_MD_SHA384, fname );
- print_hex( md, GCRY_MD_SHA512, fname );
-#endif
- }
- }
- }
- gcry_md_close (md);
-
- if( fp != stdin )
- fclose(fp);
-}
-
-
-/****************
- * Check the supplied name,value string and add it to the notation
- * data to be used for signatures. which==0 for sig notations, and 1
- * for cert notations.
-*/
-static void
-add_notation_data( const char *string, int which )
-{
- const char *s;
- STRLIST sl,*notation_data;
- int critical=0;
- int highbit=0;
- int saw_at=0;
-
- if(which)
- notation_data=&opt.cert_notation_data;
- else
- notation_data=&opt.sig_notation_data;
-
- if( *string == '!' ) {
- critical = 1;
- string++;
- }
-
- /* If and when the IETF assigns some official name tags, we'll
- have to add them here. */
-
- for( s=string ; *s != '='; s++ )
- {
- if( *s=='@')
- saw_at=1;
-
- if( !*s || (*s & 0x80) || (!isgraph(*s) && !isspace(*s)) )
- {
- log_error(_("a notation name must have only printable characters "
- "or spaces, and end with an '='\n") );
- return;
- }
- }
-
- if(!saw_at && !opt.expert)
- {
- log_error(
- _("a user notation name must contain the '@' character\n"));
- return;
- }
-
- /* we only support printable text - therefore we enforce the use
- * of only printable characters (an empty value is valid) */
- for( s++; *s ; s++ ) {
- if( *s & 0x80 )
- highbit = 1;
- else if( iscntrl(*s) ) {
- log_error(_("a notation value must not use "
- "any control characters\n") );
- return;
- }
- }
-
- if( highbit ) /* must use UTF8 encoding */
- sl = add_to_strlist2( notation_data, string, utf8_strings );
- else
- sl = add_to_strlist( notation_data, string );
-
- if( critical )
- sl->flags |= 1;
-}
-
-
-static void
-add_policy_url( const char *string, int which )
-{
- int i,critical=0;
- STRLIST sl;
-
- if(*string=='!')
- {
- string++;
- critical=1;
- }
-
- for(i=0;i<strlen(string);i++)
- if(string[i]&0x80 || iscntrl(string[i]))
- break;
-
- if(i==0 || i<strlen(string))
- {
- if(which)
- log_error(_("the given certification policy URL is invalid\n"));
- else
- log_error(_("the given signature policy URL is invalid\n"));
- }
-
- if(which)
- sl=add_to_strlist( &opt.cert_policy_url, string );
- else
- sl=add_to_strlist( &opt.sig_policy_url, string );
-
- if(critical)
- sl->flags |= 1;
-}
-
-
-static void
-add_keyserver_url( const char *string, int which )
-{
- int i,critical=0;
- STRLIST sl;
-
- if(*string=='!')
- {
- string++;
- critical=1;
- }
-
- for(i=0;i<strlen(string);i++)
- if(string[i]&0x80 || iscntrl(string[i]))
- break;
-
- if(i==0 || i<strlen(string))
- {
- if(which)
- BUG();
- else
- log_error(_("the given signature preferred"
- " keyserver URL is invalid\n"));
- }
-
- if(which)
- BUG();
- else
- sl=add_to_strlist( &opt.sig_keyserver_url, string );
-
- if(critical)
- sl->flags |= 1;
-}
-
diff --git a/g10/getkey.c b/g10/getkey.c
deleted file mode 100644
index f51b8f2df..000000000
--- a/g10/getkey.c
+++ /dev/null
@@ -1,2618 +0,0 @@
-/* getkey.c - Get a key from the database
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <ctype.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "packet.h"
-#include "memory.h"
-#include "iobuf.h"
-#include "keydb.h"
-#include "options.h"
-#include "main.h"
-#include "trustdb.h"
-#include "i18n.h"
-
-#define MAX_PK_CACHE_ENTRIES 200
-#define MAX_UID_CACHE_ENTRIES 200
-
-#if MAX_PK_CACHE_ENTRIES < 2
-#error We need the cache for key creation
-#endif
-
-
-struct getkey_ctx_s {
- int exact;
- KBNODE keyblock;
- KBPOS kbpos;
- KBNODE found_key; /* pointer into some keyblock */
- int last_rc;
- int req_usage;
- int req_algo;
- KEYDB_HANDLE kr_handle;
- int not_allocated;
- int nitems;
- KEYDB_SEARCH_DESC items[1];
-};
-
-#if 0
-static struct {
- int any;
- int okay_count;
- int nokey_count;
- int error_count;
-} lkup_stats[21];
-#endif
-
-typedef struct keyid_list {
- struct keyid_list *next;
- u32 keyid[2];
-} *keyid_list_t;
-
-
-#if MAX_PK_CACHE_ENTRIES
- typedef struct pk_cache_entry {
- struct pk_cache_entry *next;
- u32 keyid[2];
- PKT_public_key *pk;
- } *pk_cache_entry_t;
- static pk_cache_entry_t pk_cache;
- static int pk_cache_entries; /* number of entries in pk cache */
- static int pk_cache_disabled;
-#endif
-
-#if MAX_UID_CACHE_ENTRIES < 5
-#error we really need the userid cache
-#endif
-typedef struct user_id_db {
- struct user_id_db *next;
- keyid_list_t keyids;
- int len;
- char name[1];
-} *user_id_db_t;
-static user_id_db_t user_id_db;
-static int uid_cache_entries; /* number of entries in uid cache */
-
-static void merge_selfsigs( KBNODE keyblock );
-static int lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode );
-
-#if 0
-static void
-print_stats()
-{
- int i;
- for(i=0; i < DIM(lkup_stats); i++ ) {
- if( lkup_stats[i].any )
- fprintf(stderr,
- "lookup stats: mode=%-2d ok=%-6d nokey=%-6d err=%-6d\n",
- i,
- lkup_stats[i].okay_count,
- lkup_stats[i].nokey_count,
- lkup_stats[i].error_count );
- }
-}
-#endif
-
-
-void
-cache_public_key( PKT_public_key *pk )
-{
-#if MAX_PK_CACHE_ENTRIES
- pk_cache_entry_t ce;
- u32 keyid[2];
-
- if( pk_cache_disabled )
- return;
-
- if( pk->dont_cache )
- return;
-
- if( is_ELGAMAL(pk->pubkey_algo)
- || pk->pubkey_algo == PUBKEY_ALGO_DSA
- || is_RSA(pk->pubkey_algo) ) {
- keyid_from_pk( pk, keyid );
- }
- else
- return; /* don't know how to get the keyid */
-
- for( ce = pk_cache; ce; ce = ce->next )
- if( ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1] ) {
- if( DBG_CACHE )
- log_debug("cache_public_key: already in cache\n");
- return;
- }
-
- if( pk_cache_entries >= MAX_PK_CACHE_ENTRIES ) {
- /* fixme: use another algorithm to free some cache slots */
- pk_cache_disabled=1;
- if( opt.verbose > 1 )
- log_info(_("too many entries in pk cache - disabled\n"));
- return;
- }
- pk_cache_entries++;
- ce = xmalloc ( sizeof *ce );
- ce->next = pk_cache;
- pk_cache = ce;
- ce->pk = copy_public_key( NULL, pk );
- ce->keyid[0] = keyid[0];
- ce->keyid[1] = keyid[1];
-#endif
-}
-
-
-/*
- * Return the user ID from the given keyblock.
- * We use the primary uid flag which has been set by the merge_selfsigs
- * function. The returned value is only valid as long as then given
- * keyblock is not changed
- */
-static const char *
-get_primary_uid ( KBNODE keyblock, size_t *uidlen )
-{
- KBNODE k;
- const char *s;
-
- for (k=keyblock; k; k=k->next ) {
- if ( k->pkt->pkttype == PKT_USER_ID
- && !k->pkt->pkt.user_id->attrib_data
- && k->pkt->pkt.user_id->is_primary ) {
- *uidlen = k->pkt->pkt.user_id->len;
- return k->pkt->pkt.user_id->name;
- }
- }
- /* fixme: returning translatable constants instead of a user ID is
- * not good because they are probably not utf-8 encoded. */
- s = _("[User id not found]");
- *uidlen = strlen (s);
- return s;
-}
-
-
-static void
-release_keyid_list ( keyid_list_t k )
-{
- while ( k ) {
- keyid_list_t k2 = k->next;
- xfree (k);
- k = k2;
- }
-}
-
-/****************
- * Store the association of keyid and userid
- * Feed only public keys to this function.
- */
-static void
-cache_user_id( KBNODE keyblock )
-{
- user_id_db_t r;
- const char *uid;
- size_t uidlen;
- keyid_list_t keyids = NULL;
- KBNODE k;
-
- for (k=keyblock; k; k = k->next ) {
- if ( k->pkt->pkttype == PKT_PUBLIC_KEY
- || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- keyid_list_t a = xcalloc (1, sizeof *a );
- /* Hmmm: For a long list of keyids it might be an advantage
- * to append the keys */
- keyid_from_pk( k->pkt->pkt.public_key, a->keyid );
- /* first check for duplicates */
- for(r=user_id_db; r; r = r->next ) {
- keyid_list_t b = r->keyids;
- for ( b = r->keyids; b; b = b->next ) {
- if( b->keyid[0] == a->keyid[0]
- && b->keyid[1] == a->keyid[1] ) {
- if( DBG_CACHE )
- log_debug("cache_user_id: already in cache\n");
- release_keyid_list ( keyids );
- xfree ( a );
- return;
- }
- }
- }
- /* now put it into the cache */
- a->next = keyids;
- keyids = a;
- }
- }
- if ( !keyids )
- BUG (); /* No key no fun */
-
-
- uid = get_primary_uid ( keyblock, &uidlen );
-
- if( uid_cache_entries >= MAX_UID_CACHE_ENTRIES ) {
- /* fixme: use another algorithm to free some cache slots */
- r = user_id_db;
- user_id_db = r->next;
- release_keyid_list ( r->keyids );
- xfree (r);
- uid_cache_entries--;
- }
- r = xmalloc ( sizeof *r + uidlen-1 );
- r->keyids = keyids;
- r->len = uidlen;
- memcpy(r->name, uid, r->len);
- r->next = user_id_db;
- user_id_db = r;
- uid_cache_entries++;
-}
-
-
-void
-getkey_disable_caches()
-{
-#if MAX_PK_CACHE_ENTRIES
- {
- pk_cache_entry_t ce, ce2;
-
- for( ce = pk_cache; ce; ce = ce2 ) {
- ce2 = ce->next;
- free_public_key( ce->pk );
- xfree ( ce );
- }
- pk_cache_disabled=1;
- pk_cache_entries = 0;
- pk_cache = NULL;
- }
-#endif
- /* fixme: disable user id cache ? */
-}
-
-
-static void
-pk_from_block ( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE keyblock )
-{
- KBNODE a = ctx->found_key ? ctx->found_key : keyblock;
-
- assert ( a->pkt->pkttype == PKT_PUBLIC_KEY
- || a->pkt->pkttype == PKT_PUBLIC_SUBKEY );
-
- copy_public_key ( pk, a->pkt->pkt.public_key );
-}
-
-static void
-sk_from_block ( GETKEY_CTX ctx,
- PKT_secret_key *sk, KBNODE keyblock )
-{
- KBNODE a = ctx->found_key ? ctx->found_key : keyblock;
-
- assert ( a->pkt->pkttype == PKT_SECRET_KEY
- || a->pkt->pkttype == PKT_SECRET_SUBKEY );
-
- copy_secret_key( sk, a->pkt->pkt.secret_key);
-}
-
-
-/****************
- * Get a public key and store it into the allocated pk
- * can be called with PK set to NULL to just read it into some
- * internal structures.
- */
-int
-get_pubkey( PKT_public_key *pk, u32 *keyid )
-{
- int internal = 0;
- int rc = 0;
-
-#if MAX_PK_CACHE_ENTRIES
- { /* Try to get it from the cache */
- pk_cache_entry_t ce;
- for( ce = pk_cache; ce; ce = ce->next ) {
- if( ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1] ) {
- if( pk )
- copy_public_key( pk, ce->pk );
- return 0;
- }
- }
- }
-#endif
- /* more init stuff */
- if( !pk ) {
- pk = xcalloc (1, sizeof *pk );
- internal++;
- }
-
-
- /* do a lookup */
- { struct getkey_ctx_s ctx;
- KBNODE kb = NULL;
- memset( &ctx, 0, sizeof ctx );
- ctx.exact = 1; /* use the key ID exactly as given */
- ctx.not_allocated = 1;
- ctx.kr_handle = keydb_new (0);
- ctx.nitems = 1;
- ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
- ctx.items[0].u.kid[0] = keyid[0];
- ctx.items[0].u.kid[1] = keyid[1];
- ctx.req_algo = pk->req_algo;
- ctx.req_usage = pk->req_usage;
- rc = lookup( &ctx, &kb, 0 );
- if ( !rc ) {
- pk_from_block ( &ctx, pk, kb );
- }
- get_pubkey_end( &ctx );
- release_kbnode ( kb );
- }
- if( !rc )
- goto leave;
-
- rc = GPG_ERR_NO_PUBKEY;
-
- leave:
- if( !rc )
- cache_public_key( pk );
- if( internal )
- free_public_key(pk);
- return rc;
-}
-
-
-/* Get a public key and store it into the allocated pk. This function
- differs from get_pubkey() in that it does not do a check of the key
- to avoid recursion. It should be used only in very certain cases. */
-int
-get_pubkey_fast (PKT_public_key *pk, u32 *keyid)
-{
- int rc = 0;
- KEYDB_HANDLE hd;
- KBNODE keyblock;
-
- assert (pk);
-#if MAX_PK_CACHE_ENTRIES
- { /* Try to get it from the cache */
- pk_cache_entry_t ce;
-
- for (ce = pk_cache; ce; ce = ce->next)
- {
- if (ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1])
- {
- if (pk)
- copy_public_key (pk, ce->pk);
- return 0;
- }
- }
- }
-#endif
-
- hd = keydb_new (0);
- rc = keydb_search_kid (hd, keyid);
- if (rc == -1)
- {
- keydb_release (hd);
- return GPG_ERR_NO_PUBKEY;
- }
- rc = keydb_get_keyblock (hd, &keyblock);
- keydb_release (hd);
- if (rc)
- {
- log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
- return GPG_ERR_NO_PUBKEY;
- }
-
- assert ( keyblock->pkt->pkttype == PKT_PUBLIC_KEY
- || keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY );
- copy_public_key (pk, keyblock->pkt->pkt.public_key );
- release_kbnode (keyblock);
-
- /* Not caching key here since it won't have all of the fields
- properly set. */
-
- return 0;
-}
-
-
-
-KBNODE
-get_pubkeyblock( u32 *keyid )
-{
- struct getkey_ctx_s ctx;
- int rc = 0;
- KBNODE keyblock = NULL;
-
- memset( &ctx, 0, sizeof ctx );
- /* no need to set exact here because we want the entire block */
- ctx.not_allocated = 1;
- ctx.kr_handle = keydb_new (0);
- ctx.nitems = 1;
- ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
- ctx.items[0].u.kid[0] = keyid[0];
- ctx.items[0].u.kid[1] = keyid[1];
- rc = lookup( &ctx, &keyblock, 0 );
- get_pubkey_end( &ctx );
-
- return rc ? NULL : keyblock;
-}
-
-
-
-
-/****************
- * Get a secret key and store it into sk
- */
-int
-get_seckey( PKT_secret_key *sk, u32 *keyid )
-{
- int rc;
- struct getkey_ctx_s ctx;
- KBNODE kb = NULL;
-
- memset( &ctx, 0, sizeof ctx );
- ctx.exact = 1; /* use the key ID exactly as given */
- ctx.not_allocated = 1;
- ctx.kr_handle = keydb_new (1);
- ctx.nitems = 1;
- ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
- ctx.items[0].u.kid[0] = keyid[0];
- ctx.items[0].u.kid[1] = keyid[1];
- ctx.req_algo = sk->req_algo;
- ctx.req_usage = sk->req_usage;
- rc = lookup( &ctx, &kb, 1 );
- if ( !rc ) {
- sk_from_block ( &ctx, sk, kb );
- }
- get_seckey_end( &ctx );
- release_kbnode ( kb );
-
- if( !rc ) {
- /* check the secret key (this may prompt for a passprase to
- * unlock the secret key
- */
- rc = check_secret_key( sk, 0 );
- }
-
- return rc;
-}
-
-
-/****************
- * Check whether the secret key is available. This is just a fast
- * check and does not tell us whether the secret key is valid. It
- * merely tells other whether there is some secret key.
- * Returns: 0 := key is available
- * GPG_ERR_NO_SECKEY := not availabe
- */
-int
-seckey_available( u32 *keyid )
-{
- int rc;
- KEYDB_HANDLE hd = keydb_new (1);
-
- rc = keydb_search_kid (hd, keyid);
- if ( rc == -1 )
- rc = GPG_ERR_NO_SECKEY;
- keydb_release (hd);
- return rc;
-}
-
-
-/****************
- * Return the type of the user id:
- *
- * Please use the constants KEYDB_SERCH_MODE_xxx
- * 0 = Invalid user ID
- * 1 = exact match
- * 2 = match a substring
- * 3 = match an email address
- * 4 = match a substring of an email address
- * 5 = match an email address, but compare from end
- * 6 = word match mode
- * 10 = it is a short KEYID (don't care about keyid[0])
- * 11 = it is a long KEYID
- * 12 = it is a trustdb index (keyid is looked up)
- * 16 = it is a 16 byte fingerprint
- * 20 = it is a 20 byte fingerprint
- * 21 = Unified fingerprint :fpr:pk_algo:
- * (We don't use pk_algo yet)
- *
- * Rules used:
- * - If the username starts with 8,9,16 or 17 hex-digits (the first one
- * must be in the range 0..9), this is considered a keyid; depending
- * on the length a short or complete one.
- * - If the username starts with 32,33,40 or 41 hex-digits (the first one
- * must be in the range 0..9), this is considered a fingerprint.
- * - If the username starts with a left angle, we assume it is a complete
- * email address and look only at this part.
- * - If the username starts with a colon we assume it is a unified
- * key specfification.
- * - If the username starts with a '.', we assume it is the ending
- * part of an email address
- * - If the username starts with an '@', we assume it is a part of an
- * email address
- * - If the userid start with an '=' an exact compare is done.
- * - If the userid starts with a '*' a case insensitive substring search is
- * done (This is the default).
- * - If the userid starts with a '+' we will compare individual words
- * and a match requires that all the words are in the userid.
- * Words are delimited by white space or "()<>[]{}.@-+_,;/&!"
- * (note that you can't search for these characters). Compare
- * is not case sensitive.
- */
-
-int
-classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc )
-{
- const char *s;
- int hexprefix = 0;
- int hexlength;
- int mode = 0;
- KEYDB_SEARCH_DESC dummy_desc;
-
- if (!desc)
- desc = &dummy_desc;
-
- /* clear the structure so that the mode field is set to zero unless
- * we set it to the correct value right at the end of this function */
- memset (desc, 0, sizeof *desc);
-
- /* skip leading spaces. Fixme: what is with trailing spaces? */
- for(s = name; *s && spacep (s); s++ )
- ;
-
- switch (*s) {
- case 0: /* empty string is an error */
- return 0;
-
- case '.': /* an email address, compare from end */
- mode = KEYDB_SEARCH_MODE_MAILEND;
- s++;
- desc->u.name = s;
- break;
-
- case '<': /* an email address */
- mode = KEYDB_SEARCH_MODE_MAIL;
- desc->u.name = s;
- break;
-
- case '@': /* part of an email address */
- mode = KEYDB_SEARCH_MODE_MAILSUB;
- s++;
- desc->u.name = s;
- break;
-
- case '=': /* exact compare */
- mode = KEYDB_SEARCH_MODE_EXACT;
- s++;
- desc->u.name = s;
- break;
-
- case '*': /* case insensitive substring search */
- mode = KEYDB_SEARCH_MODE_SUBSTR;
- s++;
- desc->u.name = s;
- break;
-
- case '+': /* compare individual words */
- mode = KEYDB_SEARCH_MODE_WORDS;
- s++;
- desc->u.name = s;
- break;
-
- case '#': /* local user id */
- return 0; /* This is now obsolete and van't not be used anymore*/
-
- case ':': /*Unified fingerprint */
- {
- const char *se, *si;
- int i;
-
- se = strchr( ++s,':');
- if ( !se )
- return 0;
- for (i=0,si=s; si < se; si++, i++ ) {
- if ( !strchr("01234567890abcdefABCDEF", *si ) )
- return 0; /* invalid digit */
- }
- if (i != 32 && i != 40)
- return 0; /* invalid length of fpr*/
- for (i=0,si=s; si < se; i++, si +=2)
- desc->u.fpr[i] = hextobyte(si);
- for ( ; i < 20; i++)
- desc->u.fpr[i]= 0;
- s = se + 1;
- mode = KEYDB_SEARCH_MODE_FPR;
- }
- break;
-
- default:
- if (s[0] == '0' && s[1] == 'x') {
- hexprefix = 1;
- s += 2;
- }
-
- hexlength = strspn(s, "0123456789abcdefABCDEF");
- if (hexlength >= 8 && s[hexlength] =='!') {
- desc->exact = 1;
- hexlength++; /* just for the following check */
- }
-
- /* check if a hexadecimal number is terminated by EOS or blank */
- if (hexlength && s[hexlength] && !spacep (s+hexlength)) {
- if (hexprefix) /* a "0x" prefix without correct */
- return 0; /* termination is an error */
- else /* The first chars looked like */
- hexlength = 0; /* a hex number, but really were not. */
- }
-
- if (desc->exact)
- hexlength--;
-
- if (hexlength == 8
- || (!hexprefix && hexlength == 9 && *s == '0')){
- /* short keyid */
- if (hexlength == 9)
- s++;
- desc->u.kid[0] = 0;
- desc->u.kid[1] = strtoul( s, NULL, 16 );
- mode = KEYDB_SEARCH_MODE_SHORT_KID;
- }
- else if (hexlength == 16
- || (!hexprefix && hexlength == 17 && *s == '0')) {
- /* complete keyid */
- char buf[9];
- if (hexlength == 17)
- s++;
- mem2str(buf, s, 9 );
- desc->u.kid[0] = strtoul( buf, NULL, 16 );
- desc->u.kid[1] = strtoul( s+8, NULL, 16 );
- mode = KEYDB_SEARCH_MODE_LONG_KID;
- }
- else if (hexlength == 32 || (!hexprefix && hexlength == 33
- && *s == '0')) {
- /* md5 fingerprint */
- int i;
- if (hexlength == 33)
- s++;
- memset(desc->u.fpr+16, 0, 4);
- for (i=0; i < 16; i++, s+=2) {
- int c = hextobyte(s);
- if (c == -1)
- return 0;
- desc->u.fpr[i] = c;
- }
- mode = KEYDB_SEARCH_MODE_FPR16;
- }
- else if (hexlength == 40 || (!hexprefix && hexlength == 41
- && *s == '0')) {
- /* sha1/rmd160 fingerprint */
- int i;
- if (hexlength == 41)
- s++;
- for (i=0; i < 20; i++, s+=2) {
- int c = hextobyte(s);
- if (c == -1)
- return 0;
- desc->u.fpr[i] = c;
- }
- mode = KEYDB_SEARCH_MODE_FPR20;
- }
- else {
- if (hexprefix) /* This was a hex number with a prefix */
- return 0; /* and a wrong length */
-
- desc->exact = 0;
- desc->u.name = s;
- mode = KEYDB_SEARCH_MODE_SUBSTR; /* default mode */
- }
- }
-
- desc->mode = mode;
- return mode;
-}
-
-
-static int
-skip_disabled(void *dummy,u32 *keyid)
-{
- int rc,disabled=0;
- PKT_public_key *pk=xcalloc (1,sizeof(PKT_public_key));
-
- rc = get_pubkey(pk, keyid);
- if(rc)
- {
- log_error("error checking disabled status of %08lX: %s\n",
- (ulong)keyid[1],gpg_strerror (rc));
- goto leave;
- }
-
- disabled=pk_is_disabled(pk);
-
- leave:
- free_public_key(pk);
- return disabled;
-}
-
-/****************
- * Try to get the pubkey by the userid. This function looks for the
- * first pubkey certificate which has the given name in a user_id.
- * if pk/sk has the pubkey algo set, the function will only return
- * a pubkey with that algo.
- * The caller should provide storage for either the pk or the sk.
- * If ret_kb is not NULL the function will return the keyblock there.
- */
-
-static int
-key_byname( GETKEY_CTX *retctx, STRLIST namelist,
- PKT_public_key *pk, PKT_secret_key *sk,
- int secmode, int include_disabled,
- KBNODE *ret_kb, KEYDB_HANDLE *ret_kdbhd )
-{
- int rc = 0;
- int n;
- STRLIST r;
- GETKEY_CTX ctx;
- KBNODE help_kb = NULL;
-
- if( retctx ) {/* reset the returned context in case of error */
- assert (!ret_kdbhd); /* not allowed because the handle is
- stored in the context */
- *retctx = NULL;
- }
- if (ret_kdbhd)
- *ret_kdbhd = NULL;
-
- /* build the search context */
- for(n=0, r=namelist; r; r = r->next )
- n++;
- ctx = xcalloc (1,sizeof *ctx + (n-1)*sizeof ctx->items );
- ctx->nitems = n;
-
- for(n=0, r=namelist; r; r = r->next, n++ ) {
- classify_user_id (r->d, &ctx->items[n]);
-
- if (ctx->items[n].exact)
- ctx->exact = 1;
- if (!ctx->items[n].mode) {
- xfree (ctx);
- return GPG_ERR_INV_USER_ID;
- }
- if(!include_disabled
- && ctx->items[n].mode!=KEYDB_SEARCH_MODE_SHORT_KID
- && ctx->items[n].mode!=KEYDB_SEARCH_MODE_LONG_KID
- && ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR16
- && ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR20
- && ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR)
- ctx->items[n].skipfnc=skip_disabled;
- }
-
- ctx->kr_handle = keydb_new (secmode);
- if ( !ret_kb )
- ret_kb = &help_kb;
-
- if( secmode ) {
- if (sk) {
- ctx->req_algo = sk->req_algo;
- ctx->req_usage = sk->req_usage;
- }
- rc = lookup( ctx, ret_kb, 1 );
- if ( !rc && sk ) {
- sk_from_block ( ctx, sk, *ret_kb );
- }
- }
- else {
- if (pk) {
- ctx->req_algo = pk->req_algo;
- ctx->req_usage = pk->req_usage;
- }
- rc = lookup( ctx, ret_kb, 0 );
- if ( !rc && pk ) {
- pk_from_block ( ctx, pk, *ret_kb );
- }
- }
-
- release_kbnode ( help_kb );
-
- if (retctx) /* caller wants the context */
- *retctx = ctx;
- else {
- if (ret_kdbhd) {
- *ret_kdbhd = ctx->kr_handle;
- ctx->kr_handle = NULL;
- }
- get_pubkey_end (ctx);
- }
-
- return rc;
-}
-
-/*
- * Find a public key from NAME and returh the keyblock or the key.
- * If ret_kdb is not NULL, the KEYDB handle used to locate this keyblock is
- * returned and the caller is responsible for closing it.
- */
-int
-get_pubkey_byname (PKT_public_key *pk,
- const char *name, KBNODE *ret_keyblock,
- KEYDB_HANDLE *ret_kdbhd, int include_disabled )
-{
- int rc;
- STRLIST namelist = NULL;
-
- add_to_strlist( &namelist, name );
- rc = key_byname( NULL, namelist, pk, NULL, 0,
- include_disabled, ret_keyblock, ret_kdbhd);
- free_strlist( namelist );
- return rc;
-}
-
-int
-get_pubkey_bynames( GETKEY_CTX *retctx, PKT_public_key *pk,
- STRLIST names, KBNODE *ret_keyblock )
-{
- return key_byname( retctx, names, pk, NULL, 0, 1, ret_keyblock, NULL);
-}
-
-int
-get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock )
-{
- int rc;
-
- rc = lookup( ctx, ret_keyblock, 0 );
- if ( !rc && pk && ret_keyblock )
- pk_from_block ( ctx, pk, *ret_keyblock );
-
- return rc;
-}
-
-
-void
-get_pubkey_end( GETKEY_CTX ctx )
-{
- if( ctx ) {
- memset (&ctx->kbpos, 0, sizeof ctx->kbpos);
- keydb_release (ctx->kr_handle);
- if( !ctx->not_allocated )
- xfree ( ctx );
- }
-}
-
-
-
-
-/****************
- * Search for a key with the given fingerprint.
- * FIXME:
- * We should replace this with the _byname function. This can be done
- * by creating a userID conforming to the unified fingerprint style.
- */
-int
-get_pubkey_byfprint( PKT_public_key *pk,
- const byte *fprint, size_t fprint_len)
-{
- int rc;
-
- if( fprint_len == 20 || fprint_len == 16 ) {
- struct getkey_ctx_s ctx;
- KBNODE kb = NULL;
-
- memset( &ctx, 0, sizeof ctx );
- ctx.exact = 1 ;
- ctx.not_allocated = 1;
- ctx.kr_handle = keydb_new (0);
- ctx.nitems = 1;
- ctx.items[0].mode = fprint_len==16? KEYDB_SEARCH_MODE_FPR16
- : KEYDB_SEARCH_MODE_FPR20;
- memcpy( ctx.items[0].u.fpr, fprint, fprint_len );
- rc = lookup( &ctx, &kb, 0 );
- if (!rc && pk )
- pk_from_block ( &ctx, pk, kb );
- release_kbnode ( kb );
- get_pubkey_end( &ctx );
- }
- else
- rc = GPG_ERR_GENERAL; /* Oops */
- return rc;
-}
-
-
-/* Get a public key and store it into the allocated pk. This function
- differs from get_pubkey_byfprint() in that it does not do a check
- of the key to avoid recursion. It should be used only in very
- certain cases. PK may be NULL to check just for the existance of
- the key. */
-int
-get_pubkey_byfprint_fast (PKT_public_key *pk,
- const byte *fprint, size_t fprint_len)
-{
- int rc = 0;
- KEYDB_HANDLE hd;
- KBNODE keyblock;
- byte fprbuf[MAX_FINGERPRINT_LEN];
- int i;
-
- for (i=0; i < MAX_FINGERPRINT_LEN && i < fprint_len; i++)
- fprbuf[i] = fprint[i];
- while (i < MAX_FINGERPRINT_LEN)
- fprbuf[i++] = 0;
-
- hd = keydb_new (0);
- rc = keydb_search_fpr (hd, fprbuf);
- if (rc == -1)
- {
- keydb_release (hd);
- return GPG_ERR_NO_PUBKEY;
- }
- rc = keydb_get_keyblock (hd, &keyblock);
- keydb_release (hd);
- if (rc)
- {
- log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
- return GPG_ERR_NO_PUBKEY;
- }
-
- assert ( keyblock->pkt->pkttype == PKT_PUBLIC_KEY
- || keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY );
- if (pk)
- copy_public_key (pk, keyblock->pkt->pkt.public_key );
- release_kbnode (keyblock);
-
- /* Not caching key here since it won't have all of the fields
- properly set. */
-
- return 0;
-}
-
-/****************
- * Search for a key with the given fingerprint and return the
- * complete keyblock which may have more than only this key.
- */
-int
-get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint,
- size_t fprint_len )
-{
- int rc;
-
- if( fprint_len == 20 || fprint_len == 16 ) {
- struct getkey_ctx_s ctx;
-
- memset( &ctx, 0, sizeof ctx );
- ctx.not_allocated = 1;
- ctx.kr_handle = keydb_new (0);
- ctx.nitems = 1;
- ctx.items[0].mode = fprint_len==16? KEYDB_SEARCH_MODE_FPR16
- : KEYDB_SEARCH_MODE_FPR20;
- memcpy( ctx.items[0].u.fpr, fprint, fprint_len );
- rc = lookup( &ctx, ret_keyblock, 0 );
- get_pubkey_end( &ctx );
- }
- else
- rc = GPG_ERR_GENERAL; /* Oops */
-
- return rc;
-}
-
-
-/****************
- * Get a secret key by name and store it into sk
- * If NAME is NULL use the default key
- */
-static int
-get_seckey_byname2( GETKEY_CTX *retctx,
- PKT_secret_key *sk, const char *name, int unprotect,
- KBNODE *retblock )
-{
- STRLIST namelist = NULL;
- int rc;
-
- if( !name && opt.def_secret_key && *opt.def_secret_key ) {
- add_to_strlist( &namelist, opt.def_secret_key );
- rc = key_byname( retctx, namelist, NULL, sk, 1, 1, retblock, NULL );
- }
- else if( !name ) { /* use the first one as default key */
- struct getkey_ctx_s ctx;
- KBNODE kb = NULL;
-
- assert (!retctx ); /* do we need this at all */
- assert (!retblock);
- memset( &ctx, 0, sizeof ctx );
- ctx.not_allocated = 1;
- ctx.kr_handle = keydb_new (1);
- ctx.nitems = 1;
- ctx.items[0].mode = KEYDB_SEARCH_MODE_FIRST;
- rc = lookup( &ctx, &kb, 1 );
- if (!rc && sk )
- sk_from_block ( &ctx, sk, kb );
- release_kbnode ( kb );
- get_seckey_end( &ctx );
- }
- else {
- add_to_strlist( &namelist, name );
- rc = key_byname( retctx, namelist, NULL, sk, 1, 1, retblock, NULL );
- }
-
- free_strlist( namelist );
-
- if( !rc && unprotect )
- rc = check_secret_key( sk, 0 );
-
- return rc;
-}
-
-int
-get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock )
-{
- return get_seckey_byname2 ( NULL, sk, name, unlock, NULL );
-}
-
-
-int
-get_seckey_bynames( GETKEY_CTX *retctx, PKT_secret_key *sk,
- STRLIST names, KBNODE *ret_keyblock )
-{
- return key_byname( retctx, names, NULL, sk, 1, 1, ret_keyblock, NULL );
-}
-
-
-int
-get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock )
-{
- int rc;
-
- rc = lookup( ctx, ret_keyblock, 1 );
- if ( !rc && sk && ret_keyblock )
- sk_from_block ( ctx, sk, *ret_keyblock );
-
- return rc;
-}
-
-
-void
-get_seckey_end( GETKEY_CTX ctx )
-{
- get_pubkey_end( ctx );
-}
-
-
-/****************
- * Search for a key with the given fingerprint.
- * FIXME:
- * We should replace this with the _byname function. Thiscsan be done
- * by creating a userID conforming to the unified fingerprint style.
- */
-int
-get_seckey_byfprint( PKT_secret_key *sk,
- const byte *fprint, size_t fprint_len)
-{
- int rc;
-
- if( fprint_len == 20 || fprint_len == 16 ) {
- struct getkey_ctx_s ctx;
- KBNODE kb = NULL;
-
- memset( &ctx, 0, sizeof ctx );
- ctx.exact = 1 ;
- ctx.not_allocated = 1;
- ctx.kr_handle = keydb_new (1);
- ctx.nitems = 1;
- ctx.items[0].mode = fprint_len==16? KEYDB_SEARCH_MODE_FPR16
- : KEYDB_SEARCH_MODE_FPR20;
- memcpy( ctx.items[0].u.fpr, fprint, fprint_len );
- rc = lookup( &ctx, &kb, 1 );
- if (!rc && sk )
- sk_from_block ( &ctx, sk, kb );
- release_kbnode ( kb );
- get_pubkey_end( &ctx );
- }
- else
- rc = GPG_ERR_GENERAL; /* Oops */
- return rc;
-}
-
-
-/************************************************
- ************* Merging stuff ********************
- ************************************************/
-
-/****************
- * merge all selfsignatures with the keys.
- * FIXME: replace this at least for the public key parts
- * by merge_selfsigs.
- * It is still used in keyedit.c and
- * at 2 or 3 other places - check whether it is really needed.
- * It might be needed by the key edit and import stuff because
- * the keylock is changed.
- */
-void
-merge_keys_and_selfsig( KBNODE keyblock )
-{
- PKT_public_key *pk = NULL;
- PKT_secret_key *sk = NULL;
- PKT_signature *sig;
- KBNODE k;
- u32 kid[2] = { 0, 0 };
- u32 sigdate = 0;
-
- if (keyblock && keyblock->pkt->pkttype == PKT_PUBLIC_KEY ) {
- /* divert to our new function */
- merge_selfsigs (keyblock);
- return;
- }
- /* still need the old one because the new one can't handle secret keys */
-
- for(k=keyblock; k; k = k->next ) {
- if( k->pkt->pkttype == PKT_PUBLIC_KEY
- || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- pk = k->pkt->pkt.public_key; sk = NULL;
- if( pk->version < 4 )
- pk = NULL; /* not needed for old keys */
- else if( k->pkt->pkttype == PKT_PUBLIC_KEY )
- keyid_from_pk( pk, kid );
- else if( !pk->expiredate ) { /* and subkey */
- /* insert the expiration date here */
- /*FIXME!!! pk->expiredate = subkeys_expiretime( k, kid );*/
- }
- sigdate = 0;
- }
- else if( k->pkt->pkttype == PKT_SECRET_KEY
- || k->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- pk = NULL; sk = k->pkt->pkt.secret_key;
- if( sk->version < 4 )
- sk = NULL;
- else if( k->pkt->pkttype == PKT_SECRET_KEY )
- keyid_from_sk( sk, kid );
- sigdate = 0;
- }
- else if( (pk || sk ) && k->pkt->pkttype == PKT_SIGNATURE
- && (sig=k->pkt->pkt.signature)->sig_class >= 0x10
- && sig->sig_class <= 0x30 && sig->version > 3
- && !(sig->sig_class == 0x18 || sig->sig_class == 0x28)
- && sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1] ) {
- /* okay this is a self-signature which can be used.
- * This is not used for subkey binding signature, becuase this
- * is done above.
- * FIXME: We should only use this if the signature is valid
- * but this is time consuming - we must provide another
- * way to handle this
- */
- const byte *p;
- u32 ed;
-
- p = parse_sig_subpkt( sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL );
- if( pk ) {
- ed = p? pk->timestamp + buffer_to_u32(p):0;
- if( sig->timestamp > sigdate ) {
- pk->expiredate = ed;
- sigdate = sig->timestamp;
- }
- }
- else {
- ed = p? sk->timestamp + buffer_to_u32(p):0;
- if( sig->timestamp > sigdate ) {
- sk->expiredate = ed;
- sigdate = sig->timestamp;
- }
- }
- }
-
- if(pk && (pk->expiredate==0 ||
- (pk->max_expiredate && pk->expiredate>pk->max_expiredate)))
- pk->expiredate=pk->max_expiredate;
-
- if(sk && (sk->expiredate==0 ||
- (sk->max_expiredate && sk->expiredate>sk->max_expiredate)))
- sk->expiredate=sk->max_expiredate;
- }
-}
-
-/*
- * Apply information from SIGNODE (which is the valid self-signature
- * associated with that UID) to the UIDNODE:
- * - wether the UID has been revoked
- * - assumed creation date of the UID
- * - temporary store the keyflags here
- * - temporary store the key expiration time here
- * - mark whether the primary user ID flag hat been set.
- * - store the preferences
- */
-static void
-fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated )
-{
- PKT_user_id *uid = uidnode->pkt->pkt.user_id;
- PKT_signature *sig = signode->pkt->pkt.signature;
- const byte *p, *sym, *hash, *zip;
- size_t n, nsym, nhash, nzip;
-
- uid->created = 0; /* not created == invalid */
- if ( IS_UID_REV ( sig ) ) {
- uid->is_revoked = 1;
- return; /* has been revoked */
- }
-
- uid->created = sig->timestamp; /* this one is okay */
- uid->selfsigversion = sig->version;
- /* If we got this far, it's not expired :) */
- uid->is_expired = 0;
- uid->expiredate = sig->expiredate;
-
- /* store the key flags in the helper variable for later processing */
- uid->help_key_usage = 0;
- p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n );
- if ( p && n ) {
- /* first octet of the keyflags */
- if ( (*p & 0x03) )
- uid->help_key_usage |= PUBKEY_USAGE_SIG;
- if ( (*p & 0x0c) )
- uid->help_key_usage |= PUBKEY_USAGE_ENC;
- /* Note: we do not set the CERT flag here because it can be assumed
- * that thre is no real policy to set it. */
- if ( (*p & 0x20) )
- uid->help_key_usage |= PUBKEY_USAGE_AUTH;
- }
-
- /* ditto or the key expiration */
- uid->help_key_expire = 0;
- p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
- if ( p ) {
- uid->help_key_expire = keycreated + buffer_to_u32(p);
- }
-
- /* Set the primary user ID flag - we will later wipe out some
- * of them to only have one in our keyblock */
- uid->is_primary = 0;
- p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PRIMARY_UID, NULL );
- if ( p && *p )
- uid->is_primary = 2;
- /* We could also query this from the unhashed area if it is not in
- * the hased area and then later try to decide which is the better
- * there should be no security problem with this.
- * For now we only look at the hashed one.
- */
-
- /* Now build the preferences list. These must come from the
- hashed section so nobody can modify the ciphers a key is
- willing to accept. */
- p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PREF_SYM, &n );
- sym = p; nsym = p?n:0;
- p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PREF_HASH, &n );
- hash = p; nhash = p?n:0;
- p = parse_sig_subpkt ( sig->hashed, SIGSUBPKT_PREF_COMPR, &n );
- zip = p; nzip = p?n:0;
- if (uid->prefs)
- xfree (uid->prefs);
- n = nsym + nhash + nzip;
- if (!n)
- uid->prefs = NULL;
- else {
- uid->prefs = xmalloc (sizeof (*uid->prefs) * (n+1));
- n = 0;
- for (; nsym; nsym--, n++) {
- uid->prefs[n].type = PREFTYPE_SYM;
- uid->prefs[n].value = *sym++;
- }
- for (; nhash; nhash--, n++) {
- uid->prefs[n].type = PREFTYPE_HASH;
- uid->prefs[n].value = *hash++;
- }
- for (; nzip; nzip--, n++) {
- uid->prefs[n].type = PREFTYPE_ZIP;
- uid->prefs[n].value = *zip++;
- }
- uid->prefs[n].type = PREFTYPE_NONE; /* end of list marker */
- uid->prefs[n].value = 0;
- }
-
- /* see whether we have the MDC feature */
- uid->mdc_feature = 0;
- p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n);
- if (p && n && (p[0] & 0x01))
- uid->mdc_feature = 1;
-
- /* and the keyserver modify flag */
- uid->ks_modify = 1;
- p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KS_FLAGS, &n);
- if (p && n && (p[0] & 0x80))
- uid->ks_modify = 0;
-}
-
-static void
-merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
-{
- PKT_public_key *pk = NULL;
- KBNODE k;
- u32 kid[2];
- u32 sigdate, uiddate, uiddate2;
- KBNODE signode, uidnode, uidnode2;
- u32 curtime = make_timestamp ();
- unsigned int key_usage = 0;
- u32 keytimestamp = 0;
- u32 key_expire = 0;
- int key_expire_seen = 0;
- byte sigversion = 0;
-
- *r_revoked = 0;
- if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY )
- BUG ();
- pk = keyblock->pkt->pkt.public_key;
- keytimestamp = pk->timestamp;
-
- keyid_from_pk( pk, kid );
- pk->main_keyid[0] = kid[0];
- pk->main_keyid[1] = kid[1];
-
- if ( pk->version < 4 ) {
- /* before v4 the key packet itself contains the expiration
- * date and there was no way to change it, so we start with
- * the one from the key packet */
- key_expire = pk->max_expiredate;
- key_expire_seen = 1;
- }
-
- /* first pass: find the latest direct key self-signature.
- * We assume that the newest one overrides all others
- */
-
- /* In case this key was already merged */
- xfree (pk->revkey);
- pk->revkey=NULL;
- pk->numrevkeys=0;
-
- signode = NULL;
- sigdate = 0; /* helper to find the latest signature */
- for(k=keyblock; k && k->pkt->pkttype != PKT_USER_ID; k = k->next ) {
- if ( k->pkt->pkttype == PKT_SIGNATURE ) {
- PKT_signature *sig = k->pkt->pkt.signature;
- if ( sig->keyid[0] == kid[0] && sig->keyid[1]==kid[1] ) {
- if ( check_key_signature( keyblock, k, NULL ) )
- ; /* signature did not verify */
- else if ( IS_KEY_REV (sig) ){
- /* key has been revoked - there is no way to override
- * such a revocation, so we theoretically can stop now.
- * We should not cope with expiration times for revocations
- * here because we have to assume that an attacker can
- * generate all kinds of signatures. However due to the
- * fact that the key has been revoked it does not harm
- * either and by continuing we gather some more info on
- * that key.
- */
- *r_revoked = 1;
- }
- else if ( IS_KEY_SIG (sig) ) {
- /* Add any revocation keys onto the pk. This is
- particularly interesting since we normally only
- get data from the most recent 1F signature, but
- you need multiple 1F sigs to properly handle
- revocation keys (PGP does it this way, and a
- revocation key could be sensitive and hence in a
- different signature). */
- if(sig->revkey) {
- int i;
-
- pk->revkey=
- xrealloc(pk->revkey,sizeof(struct revocation_key)*
- (pk->numrevkeys+sig->numrevkeys));
-
- for(i=0;i<sig->numrevkeys;i++)
- memcpy(&pk->revkey[pk->numrevkeys++],
- sig->revkey[i],
- sizeof(struct revocation_key));
- }
-
- if( sig->timestamp >= sigdate ) {
- if(sig->flags.expired)
- ; /* signature has expired - ignore it */
- else {
- sigdate = sig->timestamp;
- signode = k;
- if( sig->version > sigversion )
- sigversion = sig->version;
-
- }
- }
- }
- }
- }
- }
-
- /* Remove dupes from the revocation keys */
-
- if(pk->revkey)
- {
- int i,j,x,changed=0;
-
- for(i=0;i<pk->numrevkeys;i++)
- {
- for(j=i+1;j<pk->numrevkeys;j++)
- {
- if(memcmp(&pk->revkey[i],&pk->revkey[j],
- sizeof(struct revocation_key))==0)
- {
- /* remove j */
-
- for(x=j;x<pk->numrevkeys-1;x++)
- pk->revkey[x]=pk->revkey[x+1];
-
- pk->numrevkeys--;
- j--;
- changed=1;
- }
- }
- }
-
- if(changed)
- pk->revkey=xrealloc(pk->revkey,
- pk->numrevkeys*sizeof(struct revocation_key));
- }
-
- if ( signode ) {
- /* some information from a direct key signature take precedence
- * over the same information given in UID sigs.
- */
- PKT_signature *sig = signode->pkt->pkt.signature;
- const byte *p;
- size_t n;
-
- p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n );
- if ( p && n ) {
- /* first octet of the keyflags */
- if ( (*p & 0x03) )
- key_usage |= PUBKEY_USAGE_SIG;
- if ( (*p & 0x0c) )
- key_usage |= PUBKEY_USAGE_ENC;
- if ( (*p & 0x20) )
- key_usage |= PUBKEY_USAGE_AUTH;
- }
-
- p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
- if ( p ) {
- key_expire = keytimestamp + buffer_to_u32(p);
- key_expire_seen = 1;
- }
-
- /* mark that key as valid: one direct key signature should
- * render a key as valid */
- pk->is_valid = 1;
- }
-
- /* pass 1.5: look for key revocation signatures that were not made
- by the key (i.e. did a revocation key issue a revocation for
- us?). Only bother to do this if there is a revocation key in
- the first place. */
-
- if(pk->revkey)
- for(k=keyblock; k && k->pkt->pkttype != PKT_USER_ID; k = k->next )
- {
- if ( k->pkt->pkttype == PKT_SIGNATURE )
- {
- PKT_signature *sig = k->pkt->pkt.signature;
-
- if(IS_KEY_REV(sig) &&
- (sig->keyid[0]!=kid[0] || sig->keyid[1]!=kid[1]))
- {
- /* Failure here means the sig did not verify, is was
- not issued by a revocation key, or a revocation
- key loop was broken. */
-
- if(check_revocation_keys(pk,sig)==0)
- *r_revoked=1;
-
- /* In the future handle subkey and cert revocations?
- PGP doesn't, but it's in 2440. */
- }
- }
- }
-
- /* second pass: look at the self-signature of all user IDs */
- signode = uidnode = NULL;
- sigdate = 0; /* helper to find the latest signature in one user ID */
- for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next ) {
- if ( k->pkt->pkttype == PKT_USER_ID ) {
- if ( uidnode && signode )
- {
- fixup_uidnode ( uidnode, signode, keytimestamp );
- pk->is_valid=1;
- }
- uidnode = k;
- signode = NULL;
- sigdate = 0;
- }
- else if ( k->pkt->pkttype == PKT_SIGNATURE && uidnode ) {
- PKT_signature *sig = k->pkt->pkt.signature;
- if ( sig->keyid[0] == kid[0] && sig->keyid[1]==kid[1] ) {
- if ( check_key_signature( keyblock, k, NULL ) )
- ; /* signature did not verify */
- else if ( (IS_UID_SIG (sig) || IS_UID_REV (sig))
- && sig->timestamp >= sigdate ) {
- /* Note: we allow to invalidate cert revocations
- * by a newer signature. An attacker can't use this
- * because a key should be revoced with a key revocation.
- * The reason why we have to allow for that is that at
- * one time an email address may become invalid but later
- * the same email address may become valid again (hired,
- * fired, hired again).
- */
- if(sig->flags.expired) {
- /* Expired uids don't get to be primary unless
- they are the only uid there is. */
- uidnode->pkt->pkt.user_id->is_primary=0;
- uidnode->pkt->pkt.user_id->is_expired=1;
- uidnode->pkt->pkt.user_id->expiredate=sig->expiredate;
- }
- else {
- sigdate = sig->timestamp;
- signode = k;
- if( sig->version > sigversion )
- sigversion = sig->version;
- }
- }
- }
- }
- }
- if ( uidnode && signode ) {
- fixup_uidnode ( uidnode, signode, keytimestamp );
- pk->is_valid = 1;
- }
-
- /* If the key isn't valid yet, and we have
- --allow-non-selfsigned-uid set, then force it valid. */
- if(!pk->is_valid && opt.allow_non_selfsigned_uid)
- {
- if(opt.verbose)
- log_info(_("Invalid key %08lX made valid by "
- "--allow-non-selfsigned-uid\n"),
- (ulong)keyid_from_pk(pk,NULL));
-
- pk->is_valid = 1;
- }
-
- /* The key STILL isn't valid, so try and find an ultimately
- trusted signature. */
- if(!pk->is_valid)
- {
- uidnode=NULL;
-
- for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k=k->next)
- {
- if ( k->pkt->pkttype == PKT_USER_ID )
- uidnode = k;
- else if ( k->pkt->pkttype == PKT_SIGNATURE && uidnode )
- {
- PKT_signature *sig = k->pkt->pkt.signature;
-
- if(sig->keyid[0] != kid[0] || sig->keyid[1]!=kid[1])
- {
- PKT_public_key *ultimate_pk;
-
- ultimate_pk=xcalloc (1,sizeof(*ultimate_pk));
-
- /* We don't want to use the full get_pubkey to
- avoid infinite recursion in certain cases.
- There is no reason to check that an ultimately
- trusted key is still valid - if it has been
- revoked or the user should also renmove the
- ultimate trust flag. */
- if(get_pubkey_fast(ultimate_pk,sig->keyid)==0
- && check_key_signature2(keyblock,k,ultimate_pk,
- NULL, NULL, NULL, NULL)==0
- && get_ownertrust(ultimate_pk)==TRUST_ULTIMATE)
- {
- free_public_key(ultimate_pk);
- pk->is_valid=1;
- break;
- }
-
- free_public_key(ultimate_pk);
- }
- }
- }
- }
-
- /* Record the highest selfsig version so we know if this is a v3
- key through and through, or a v3 key with a v4 selfsig
- somewhere. This is useful in a few places to know if the key
- must be treated as PGP2-style or OpenPGP-style. Note that a
- selfsig revocation with a higher version number will also raise
- this value. This is okay since such a revocation must be
- issued by the user (i.e. it cannot be issued by someone else to
- modify the key behavior.) */
-
- pk->selfsigversion=sigversion;
-
- /* Now that we had a look at all user IDs we can now get some information
- * from those user IDs.
- */
-
- if ( !key_usage ) {
- /* find the latest user ID with key flags set */
- uiddate = 0; /* helper to find the latest user ID */
- for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
- k = k->next ) {
- if ( k->pkt->pkttype == PKT_USER_ID ) {
- PKT_user_id *uid = k->pkt->pkt.user_id;
- if ( uid->help_key_usage && uid->created > uiddate ) {
- key_usage = uid->help_key_usage;
- uiddate = uid->created;
- }
- }
- }
- }
- if ( !key_usage ) { /* no key flags at all: get it from the algo */
- key_usage = openpgp_pk_algo_usage ( pk->pubkey_algo );
- }
- else { /* check that the usage matches the usage as given by the algo */
- int x = openpgp_pk_algo_usage ( pk->pubkey_algo );
- if ( x ) /* mask it down to the actual allowed usage */
- key_usage &= x;
- }
- pk->pubkey_usage = key_usage;
-
- if ( !key_expire_seen ) {
- /* find the latest valid user ID with a key expiration set
- * Note, that this may be a different one from the above because
- * some user IDs may have no expiration date set */
- uiddate = 0;
- for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
- k = k->next ) {
- if ( k->pkt->pkttype == PKT_USER_ID ) {
- PKT_user_id *uid = k->pkt->pkt.user_id;
- if ( uid->help_key_expire && uid->created > uiddate ) {
- key_expire = uid->help_key_expire;
- uiddate = uid->created;
- }
- }
- }
- }
-
- /* Currently only v3 keys have a maximum expiration date, but I'll
- bet v5 keys get this feature again. */
- if(key_expire==0 || (pk->max_expiredate && key_expire>pk->max_expiredate))
- key_expire=pk->max_expiredate;
-
- pk->has_expired = key_expire >= curtime? 0 : key_expire;
- pk->expiredate = key_expire;
-
- /* Fixme: we should see how to get rid of the expiretime fields but
- * this needs changes at other places too. */
-
- /* and now find the real primary user ID and delete all others */
- uiddate = uiddate2 = 0;
- uidnode = uidnode2 = NULL;
- for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next ) {
- if ( k->pkt->pkttype == PKT_USER_ID &&
- !k->pkt->pkt.user_id->attrib_data) {
- PKT_user_id *uid = k->pkt->pkt.user_id;
- if (uid->is_primary)
- {
- if(uid->created > uiddate)
- {
- uiddate = uid->created;
- uidnode = k;
- }
- else if(uid->created==uiddate && uidnode)
- {
- /* The dates are equal, so we need to do a
- different (and arbitrary) comparison. This
- should rarely, if ever, happen. It's good to
- try and guarantee that two different GnuPG
- users with two different keyrings at least pick
- the same primary. */
- if(cmp_user_ids(uid,uidnode->pkt->pkt.user_id)>0)
- uidnode=k;
- }
- }
- else
- {
- if(uid->created > uiddate2)
- {
- uiddate2 = uid->created;
- uidnode2 = k;
- }
- else if(uid->created==uiddate2 && uidnode2)
- {
- if(cmp_user_ids(uid,uidnode2->pkt->pkt.user_id)>0)
- uidnode2=k;
- }
- }
- }
- }
- if ( uidnode ) {
- for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
- k = k->next ) {
- if ( k->pkt->pkttype == PKT_USER_ID &&
- !k->pkt->pkt.user_id->attrib_data) {
- PKT_user_id *uid = k->pkt->pkt.user_id;
- if ( k != uidnode )
- uid->is_primary = 0;
- }
- }
- }
- else if( uidnode2 ) {
- /* none is flagged primary - use the latest user ID we have,
- and disambiguate with the arbitrary packet comparison. */
- uidnode2->pkt->pkt.user_id->is_primary = 1;
- }
- else
- {
- /* None of our uids were self-signed, so pick the one that
- sorts first to be the primary. This is the best we can do
- here since there are no self sigs to date the uids. */
-
- uidnode = NULL;
-
- for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
- k = k->next )
- {
- if(k->pkt->pkttype==PKT_USER_ID
- && !k->pkt->pkt.user_id->attrib_data)
- {
- if(!uidnode)
- {
- uidnode=k;
- uidnode->pkt->pkt.user_id->is_primary=1;
- continue;
- }
- else
- {
- if(cmp_user_ids(k->pkt->pkt.user_id,
- uidnode->pkt->pkt.user_id)>0)
- {
- uidnode->pkt->pkt.user_id->is_primary=0;
- uidnode=k;
- uidnode->pkt->pkt.user_id->is_primary=1;
- }
- else
- k->pkt->pkt.user_id->is_primary=0; /* just to be
- safe */
- }
- }
- }
- }
-}
-
-
-static void
-merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode )
-{
- PKT_public_key *mainpk = NULL, *subpk = NULL;
- PKT_signature *sig;
- KBNODE k;
- u32 mainkid[2];
- u32 sigdate = 0;
- KBNODE signode;
- u32 curtime = make_timestamp ();
- unsigned int key_usage = 0;
- u32 keytimestamp = 0;
- u32 key_expire = 0;
- const byte *p;
- size_t n;
-
- if ( subnode->pkt->pkttype != PKT_PUBLIC_SUBKEY )
- BUG ();
- mainpk = keyblock->pkt->pkt.public_key;
- if ( mainpk->version < 4 )
- return; /* (actually this should never happen) */
- keyid_from_pk( mainpk, mainkid );
- subpk = subnode->pkt->pkt.public_key;
- keytimestamp = subpk->timestamp;
-
- subpk->is_valid = 0;
- subpk->main_keyid[0] = mainpk->main_keyid[0];
- subpk->main_keyid[1] = mainpk->main_keyid[1];
-
- /* find the latest key binding self-signature. */
- signode = NULL;
- sigdate = 0; /* helper to find the latest signature */
- for(k=subnode->next; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY;
- k = k->next ) {
- if ( k->pkt->pkttype == PKT_SIGNATURE ) {
- sig = k->pkt->pkt.signature;
- if ( sig->keyid[0] == mainkid[0] && sig->keyid[1]==mainkid[1] ) {
- if ( check_key_signature( keyblock, k, NULL ) )
- ; /* signature did not verify */
- else if ( IS_SUBKEY_REV (sig) ) {
- /* Note that this means that the date on a
- revocation sig does not matter - even if the
- binding sig is dated after the revocation sig,
- the subkey is still marked as revoked. This
- seems ok, as it is just as easy to make new
- subkeys rather than re-sign old ones as the
- problem is in the distribution. Plus, PGP (7)
- does this the same way. */
- subpk->is_revoked = 1;
- /* although we could stop now, we continue to
- * figure out other information like the old expiration
- * time */
- }
- else if ( IS_SUBKEY_SIG (sig) && sig->timestamp >= sigdate ) {
- if(sig->flags.expired)
- ; /* signature has expired - ignore it */
- else {
- sigdate = sig->timestamp;
- signode = k;
- }
- }
- }
- }
- }
-
- if ( !signode ) {
- return; /* no valid key binding */
- }
-
- subpk->is_valid = 1;
- sig = signode->pkt->pkt.signature;
-
- p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n );
- if ( p && n ) {
- /* first octet of the keyflags */
- if ( (*p & 0x03) )
- key_usage |= PUBKEY_USAGE_SIG;
- if ( (*p & 0x0c) )
- key_usage |= PUBKEY_USAGE_ENC;
- if ( (*p & 0x20) )
- key_usage |= PUBKEY_USAGE_AUTH;
- }
- if ( !key_usage ) { /* no key flags at all: get it from the algo */
- key_usage = openpgp_pk_algo_usage ( subpk->pubkey_algo );
- }
- else { /* check that the usage matches the usage as given by the algo */
- int x = openpgp_pk_algo_usage ( subpk->pubkey_algo );
- if ( x ) /* mask it down to the actual allowed usage */
- key_usage &= x;
- }
- subpk->pubkey_usage = key_usage;
-
- p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
- if ( p )
- key_expire = keytimestamp + buffer_to_u32(p);
- else
- key_expire = 0;
- subpk->has_expired = key_expire >= curtime? 0 : key_expire;
- subpk->expiredate = key_expire;
-}
-
-
-
-/*
- * Merge information from the self-signatures with the key, so that
- * we can later use them more easy.
- * The function works by first applying the self signatures to the
- * primary key and the to each subkey.
- * Here are the rules we use to decide which inormation from which
- * self-signature is used:
- * We check all self signatures or validity and ignore all invalid signatures.
- * All signatures are then ordered by their creation date ....
- * For the primary key:
- * FIXME the docs
- */
-static void
-merge_selfsigs( KBNODE keyblock )
-{
- KBNODE k;
- int revoked;
- PKT_public_key *main_pk;
- prefitem_t *prefs;
- int mdc_feature;
-
- if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY ) {
- if (keyblock->pkt->pkttype == PKT_SECRET_KEY ) {
- log_error ("expected public key but found secret key "
- "- must stop\n");
- /* we better exit here becuase a public key is expected at
- other places too. FIXME: Figure this out earlier and
- don't get to here at all */
- g10_exit (1);
- }
- BUG ();
- }
-
- merge_selfsigs_main ( keyblock, &revoked );
-
- /* now merge in the data from each of the subkeys */
- for(k=keyblock; k; k = k->next ) {
- if ( k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- merge_selfsigs_subkey ( keyblock, k );
- }
- }
-
- main_pk = keyblock->pkt->pkt.public_key;
- if ( revoked || main_pk->has_expired || !main_pk->is_valid ) {
- /* if the primary key is revoked, expired, or invalid we
- * better set the appropriate flags on that key and all
- * subkeys */
- for(k=keyblock; k; k = k->next ) {
- if ( k->pkt->pkttype == PKT_PUBLIC_KEY
- || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- PKT_public_key *pk = k->pkt->pkt.public_key;
- if(!main_pk->is_valid)
- pk->is_valid = 0;
- if(revoked)
- pk->is_revoked = 1;
- if(main_pk->has_expired)
- pk->has_expired = main_pk->has_expired;
- }
- }
- return;
- }
-
- /* set the preference list of all keys to those of the primary real
- * user ID. Note: we use these preferences when we don't know by
- * which user ID the key has been selected.
- * fixme: we should keep atoms of commonly used preferences or
- * use reference counting to optimize the preference lists storage.
- * FIXME: it might be better to use the intersection of
- * all preferences.
- * Do a similar thing for the MDC feature flag.
- */
- prefs = NULL;
- mdc_feature = 0;
- for (k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next) {
- if (k->pkt->pkttype == PKT_USER_ID
- && !k->pkt->pkt.user_id->attrib_data
- && k->pkt->pkt.user_id->is_primary) {
- prefs = k->pkt->pkt.user_id->prefs;
- mdc_feature = k->pkt->pkt.user_id->mdc_feature;
- break;
- }
- }
- for(k=keyblock; k; k = k->next ) {
- if ( k->pkt->pkttype == PKT_PUBLIC_KEY
- || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- PKT_public_key *pk = k->pkt->pkt.public_key;
- if (pk->prefs)
- xfree (pk->prefs);
- pk->prefs = copy_prefs (prefs);
- pk->mdc_feature = mdc_feature;
- }
- }
-}
-
-
-/*
- * Merge the secret keys from secblock into the pubblock thereby
- * replacing the public (sub)keys with their secret counterparts Hmmm:
- * It might be better to get away from the concept of entire secret
- * keys at all and have a way to store just the real secret parts
- * from the key.
- */
-static void
-merge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
-{
- KBNODE pub;
-
- assert ( pubblock->pkt->pkttype == PKT_PUBLIC_KEY );
- assert ( secblock->pkt->pkttype == PKT_SECRET_KEY );
-
- for (pub=pubblock; pub; pub = pub->next ) {
- if ( pub->pkt->pkttype == PKT_PUBLIC_KEY ) {
- PKT_public_key *pk = pub->pkt->pkt.public_key;
- PKT_secret_key *sk = secblock->pkt->pkt.secret_key;
- assert ( pub == pubblock ); /* only in the first node */
- /* there is nothing to compare in this case, so just replace
- * some information */
- copy_public_parts_to_secret_key ( pk, sk );
- free_public_key ( pk );
- pub->pkt->pkttype = PKT_SECRET_KEY;
- pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk);
- }
- else if ( pub->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- KBNODE sec;
- PKT_public_key *pk = pub->pkt->pkt.public_key;
-
- /* this is more complicated: it may happen that the sequence
- * of the subkeys dosn't match, so we have to find the
- * appropriate secret key */
- for (sec=secblock->next; sec; sec = sec->next ) {
- if ( sec->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- PKT_secret_key *sk = sec->pkt->pkt.secret_key;
- if ( !cmp_public_secret_key ( pk, sk ) ) {
- copy_public_parts_to_secret_key ( pk, sk );
- free_public_key ( pk );
- pub->pkt->pkttype = PKT_SECRET_SUBKEY;
- pub->pkt->pkt.secret_key = copy_secret_key (NULL, sk);
- break;
- }
- }
- }
- if ( !sec )
- BUG(); /* already checked in premerge */
- }
- }
-}
-
-/* This function checks that for every public subkey a corresponding
- * secret subkey is available and deletes the public subkey otherwise.
- * We need this function because we can't delete it later when we
- * actually merge the secret parts into the pubring.
- * The function also plays some games with the node flags.
- */
-static void
-premerge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
-{
- KBNODE last, pub;
-
- assert ( pubblock->pkt->pkttype == PKT_PUBLIC_KEY );
- assert ( secblock->pkt->pkttype == PKT_SECRET_KEY );
-
- for (pub=pubblock,last=NULL; pub; last = pub, pub = pub->next ) {
- pub->flag &= ~3; /* reset bits 0 and 1 */
- if ( pub->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- KBNODE sec;
- PKT_public_key *pk = pub->pkt->pkt.public_key;
-
- for (sec=secblock->next; sec; sec = sec->next ) {
- if ( sec->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- PKT_secret_key *sk = sec->pkt->pkt.secret_key;
- if ( !cmp_public_secret_key ( pk, sk ) ) {
- if ( sk->protect.s2k.mode == 1001 ) {
- /* The secret parts are not available so
- we can't use that key for signing etc.
- Fix the pubkey usage */
- pk->pubkey_usage &= ~(PUBKEY_USAGE_SIG
- |PUBKEY_USAGE_AUTH);
- }
- /* transfer flag bits 0 and 1 to the pubblock */
- pub->flag |= (sec->flag &3);
- break;
- }
- }
- }
- if ( !sec ) {
- KBNODE next, ll;
-
- if (opt.verbose)
- log_info ( _("no secret subkey "
- "for public subkey %08lX - ignoring\n"),
- (ulong)keyid_from_pk (pk,NULL) );
- /* we have to remove the subkey in this case */
- assert ( last );
- /* find the next subkey */
- for (next=pub->next,ll=pub;
- next && pub->pkt->pkttype != PKT_PUBLIC_SUBKEY;
- ll = next, next = next->next )
- ;
- /* make new link */
- last->next = next;
- /* release this public subkey with all sigs */
- ll->next = NULL;
- release_kbnode( pub );
- /* let the loop continue */
- pub = last;
- }
- }
- }
- /* We need to copy the found bits (0 and 1) from the secret key to
- the public key. This has already been done for the subkeys but
- got lost on the primary key - fix it here *. */
- pubblock->flag |= (secblock->flag & 3);
-}
-
-
-
-
-/* See see whether the key fits
- * our requirements and in case we do not
- * request the primary key, we should select
- * a suitable subkey.
- * FIXME: Check against PGP 7 whether we still need a kludge
- * to favor type 16 keys over type 20 keys when type 20
- * has not been explitely requested.
- * Returns: True when a suitable key has been found.
- *
- * We have to distinguish four cases: FIXME!
- * 1. No usage and no primary key requested
- * Examples for this case are that we have a keyID to be used
- * for decrytion or verification.
- * 2. No usage but primary key requested
- * This is the case for all functions which work on an
- * entire keyblock, e.g. for editing or listing
- * 3. Usage and primary key requested
- * FXME
- * 4. Usage but no primary key requested
- * FIXME
- * FIXME: Tell what is going to happen here and something about the rationale
- * Note: We don't use this function if no specific usage is requested;
- * This way the getkey functions can be used for plain key listings.
- *
- * CTX ist the keyblock we are investigating, if FOUNDK is not NULL this
- * is the key we actually found by looking at the keyid or a fingerprint and
- * may eitehr point to the primary or one of the subkeys.
- */
-
-static int
-finish_lookup (GETKEY_CTX ctx)
-{
- KBNODE keyblock = ctx->keyblock;
- KBNODE k;
- KBNODE foundk = NULL;
- PKT_user_id *foundu = NULL;
-#define USAGE_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC)
- unsigned int req_usage = ( ctx->req_usage & USAGE_MASK );
- /* Request the primary if we're certifying another key, and also
- if signing data while --pgp6 or --pgp7 is on since pgp 6 and 7
- do not understand signatures made by a signing subkey. PGP 8
- does. */
- int req_prim = (ctx->req_usage & PUBKEY_USAGE_CERT) ||
- ((PGP6 || PGP7) && (ctx->req_usage & PUBKEY_USAGE_SIG));
- u32 latest_date;
- KBNODE latest_key;
- u32 curtime = make_timestamp ();
-
- assert( keyblock->pkt->pkttype == PKT_PUBLIC_KEY );
-
- ctx->found_key = NULL;
-
- if (ctx->exact) {
- for (k=keyblock; k; k = k->next) {
- if ( (k->flag & 1) ) {
- assert ( k->pkt->pkttype == PKT_PUBLIC_KEY
- || k->pkt->pkttype == PKT_PUBLIC_SUBKEY );
- foundk = k;
- break;
- }
- }
- }
-
- for (k=keyblock; k; k = k->next) {
- if ( (k->flag & 2) ) {
- assert (k->pkt->pkttype == PKT_USER_ID);
- foundu = k->pkt->pkt.user_id;
- break;
- }
- }
-
- if ( DBG_CACHE )
- log_debug( "finish_lookup: checking key %08lX (%s)(req_usage=%x)\n",
- (ulong)keyid_from_pk( keyblock->pkt->pkt.public_key, NULL),
- foundk? "one":"all", req_usage);
-
- if (!req_usage) {
- latest_key = foundk? foundk:keyblock;
- goto found;
- }
-
- if (!req_usage) {
- PKT_public_key *pk = foundk->pkt->pkt.public_key;
- if (pk->user_id)
- free_user_id (pk->user_id);
- pk->user_id = scopy_user_id (foundu);
- ctx->found_key = foundk;
- cache_user_id( keyblock );
- return 1; /* found */
- }
-
- latest_date = 0;
- latest_key = NULL;
- /* do not look at subkeys if a certification key is requested */
- if ((!foundk || foundk->pkt->pkttype == PKT_PUBLIC_SUBKEY) && !req_prim) {
- KBNODE nextk;
- /* either start a loop or check just this one subkey */
- for (k=foundk?foundk:keyblock; k; k = nextk ) {
- PKT_public_key *pk;
- nextk = k->next;
- if ( k->pkt->pkttype != PKT_PUBLIC_SUBKEY )
- continue;
- if ( foundk )
- nextk = NULL; /* what a hack */
- pk = k->pkt->pkt.public_key;
- if (DBG_CACHE)
- log_debug( "\tchecking subkey %08lX\n",
- (ulong)keyid_from_pk( pk, NULL));
- if ( !pk->is_valid ) {
- if (DBG_CACHE)
- log_debug( "\tsubkey not valid\n");
- continue;
- }
- if ( pk->is_revoked ) {
- if (DBG_CACHE)
- log_debug( "\tsubkey has been revoked\n");
- continue;
- }
- if ( pk->has_expired ) {
- if (DBG_CACHE)
- log_debug( "\tsubkey has expired\n");
- continue;
- }
- if ( pk->timestamp > curtime && !opt.ignore_valid_from ) {
- if (DBG_CACHE)
- log_debug( "\tsubkey not yet valid\n");
- continue;
- }
-
- if ( !((pk->pubkey_usage&USAGE_MASK) & req_usage) ) {
- if (DBG_CACHE)
- log_debug( "\tusage does not match: want=%x have=%x\n",
- req_usage, pk->pubkey_usage );
- continue;
- }
-
- if (DBG_CACHE)
- log_debug( "\tsubkey looks fine\n");
- if ( pk->timestamp > latest_date ) {
- latest_date = pk->timestamp;
- latest_key = k;
- }
- }
- }
-
- /* Okay now try the primary key unless we want an exact
- * key ID match on a subkey */
- if ((!latest_key && !(ctx->exact && foundk != keyblock)) || req_prim) {
- PKT_public_key *pk;
- if (DBG_CACHE && !foundk && !req_prim )
- log_debug( "\tno suitable subkeys found - trying primary\n");
- pk = keyblock->pkt->pkt.public_key;
- if ( !pk->is_valid ) {
- if (DBG_CACHE)
- log_debug( "\tprimary key not valid\n");
- }
- else if ( pk->is_revoked ) {
- if (DBG_CACHE)
- log_debug( "\tprimary key has been revoked\n");
- }
- else if ( pk->has_expired ) {
- if (DBG_CACHE)
- log_debug( "\tprimary key has expired\n");
- }
- else if ( !((pk->pubkey_usage&USAGE_MASK) & req_usage) ) {
- if (DBG_CACHE)
- log_debug( "\tprimary key usage does not match: "
- "want=%x have=%x\n",
- req_usage, pk->pubkey_usage );
- }
- else { /* okay */
- if (DBG_CACHE)
- log_debug( "\tprimary key may be used\n");
- latest_key = keyblock;
- latest_date = pk->timestamp;
- }
- }
-
- if ( !latest_key ) {
- if (DBG_CACHE)
- log_debug("\tno suitable key found - giving up\n");
- return 0;
- }
-
- found:
- if (DBG_CACHE)
- log_debug( "\tusing key %08lX\n",
- (ulong)keyid_from_pk( latest_key->pkt->pkt.public_key, NULL) );
-
- if (latest_key) {
- PKT_public_key *pk = latest_key->pkt->pkt.public_key;
- if (pk->user_id)
- free_user_id (pk->user_id);
- pk->user_id = scopy_user_id (foundu);
- }
-
- ctx->found_key = latest_key;
-
- if (latest_key != keyblock && opt.verbose) {
- log_info(_("using secondary key %08lX "
- "instead of primary key %08lX\n"),
- (ulong)keyid_from_pk( latest_key->pkt->pkt.public_key, NULL),
- (ulong)keyid_from_pk( keyblock->pkt->pkt.public_key, NULL) );
- }
-
- cache_user_id( keyblock );
-
- return 1; /* found */
-}
-
-
-static int
-lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
-{
- int rc;
- KBNODE secblock = NULL; /* helper */
- int no_suitable_key = 0;
-
- rc = 0;
- while (!(rc = keydb_search (ctx->kr_handle, ctx->items, ctx->nitems))) {
- /* If we are searching for the first key we have to make sure
- that the next interation does not no an implicit reset.
- This can be triggered by an empty key ring. */
- if (ctx->nitems && ctx->items->mode == KEYDB_SEARCH_MODE_FIRST)
- ctx->items->mode = KEYDB_SEARCH_MODE_NEXT;
-
- rc = keydb_get_keyblock (ctx->kr_handle, &ctx->keyblock);
- if (rc) {
- log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
- rc = 0;
- goto skip;
- }
-
- if ( secmode ) {
- /* find the correspondig public key and use this
- * this one for the selection process */
- u32 aki[2];
- KBNODE k = ctx->keyblock;
-
- if (k->pkt->pkttype != PKT_SECRET_KEY)
- BUG();
-
- keyid_from_sk (k->pkt->pkt.secret_key, aki);
- k = get_pubkeyblock (aki);
- if( !k ) {
- if (!opt.quiet)
- log_info(_("key %08lX: secret key without public key "
- "- skipped\n"), (ulong)aki[1] );
- goto skip;
- }
- secblock = ctx->keyblock;
- ctx->keyblock = k;
-
- premerge_public_with_secret ( ctx->keyblock, secblock );
- }
-
- /* warning: node flag bits 0 and 1 should be preserved by
- * merge_selfsigs. For secret keys, premerge did tranfer the
- * keys to the keyblock */
- merge_selfsigs ( ctx->keyblock );
- if ( finish_lookup (ctx) ) {
- no_suitable_key = 0;
- if ( secmode ) {
- merge_public_with_secret ( ctx->keyblock,
- secblock);
- release_kbnode (secblock);
- secblock = NULL;
- }
- goto found;
- }
- else
- no_suitable_key = 1;
-
- skip:
- /* release resources and continue search */
- if ( secmode ) {
- release_kbnode( secblock );
- secblock = NULL;
- }
- release_kbnode( ctx->keyblock );
- ctx->keyblock = NULL;
- }
-
- found:
- if( rc && rc != -1 )
- log_error("keydb_search failed: %s\n", gpg_strerror (rc));
-
- if( !rc ) {
- *ret_keyblock = ctx->keyblock; /* return the keyblock */
- ctx->keyblock = NULL;
- }
- else if (rc == -1 && no_suitable_key)
- rc = secmode ? GPG_ERR_UNUSABLE_SECKEY : GPG_ERR_UNUSABLE_PUBKEY;
- else if( rc == -1 )
- rc = secmode ? GPG_ERR_NO_SECKEY : GPG_ERR_NO_PUBKEY;
-
- if ( secmode ) {
- release_kbnode( secblock );
- secblock = NULL;
- }
- release_kbnode( ctx->keyblock );
- ctx->keyblock = NULL;
-
- ctx->last_rc = rc;
- return rc;
-}
-
-
-
-
-/****************
- * FIXME: Replace by the generic function
- * It does not work as it is right now - it is used at
- * 2 places: a) to get the key for an anonyous recipient
- * b) to get the ultimately trusted keys.
- * The a) usage might have some problems.
- *
- * set with_subkeys true to include subkeys
- * set with_spm true to include secret-parts-missing keys
- *
- * Enumerate all primary secret keys. Caller must use these procedure:
- * 1) create a void pointer and initialize it to NULL
- * 2) pass this void pointer by reference to this function
- * and provide space for the secret key (pass a buffer for sk)
- * 3) call this function as long as it does not return -1
- * to indicate EOF.
- * 4) Always call this function a last time with SK set to NULL,
- * so that can free it's context.
- */
-int
-enum_secret_keys( void **context, PKT_secret_key *sk,
- int with_subkeys, int with_spm )
-{
- int rc=0;
- struct {
- int eof;
- int first;
- KEYDB_HANDLE hd;
- KBNODE keyblock;
- KBNODE node;
- } *c = *context;
-
-
- if( !c ) { /* make a new context */
- c = xcalloc (1, sizeof *c );
- *context = c;
- c->hd = keydb_new (1);
- c->first = 1;
- c->keyblock = NULL;
- c->node = NULL;
- }
-
- if( !sk ) { /* free the context */
- keydb_release (c->hd);
- release_kbnode (c->keyblock);
- xfree ( c );
- *context = NULL;
- return 0;
- }
-
- if( c->eof )
- return -1;
-
- do {
- /* get the next secret key from the current keyblock */
- for (; c->node; c->node = c->node->next) {
- if ((c->node->pkt->pkttype == PKT_SECRET_KEY
- || (with_subkeys
- && c->node->pkt->pkttype == PKT_SECRET_SUBKEY) )
- && !(c->node->pkt->pkt.secret_key->protect.s2k.mode==1001
- && !with_spm)) {
- copy_secret_key (sk, c->node->pkt->pkt.secret_key );
- c->node = c->node->next;
- return 0; /* found */
- }
- }
- release_kbnode (c->keyblock);
- c->keyblock = c->node = NULL;
-
- rc = c->first? keydb_search_first (c->hd) : keydb_search_next (c->hd);
- c->first = 0;
- if (rc) {
- keydb_release (c->hd); c->hd = NULL;
- c->eof = 1;
- return -1; /* eof */
- }
-
- rc = keydb_get_keyblock (c->hd, &c->keyblock);
- c->node = c->keyblock;
- } while (!rc);
-
- return rc; /* error */
-}
-
-
-
-/*********************************************
- *********** user ID printing helpers *******
- *********************************************/
-
-/****************
- * Return a string with a printable representation of the user_id.
- * this string must be freed by m_free.
- */
-char*
-get_user_id_string( u32 *keyid )
-{
- user_id_db_t r;
- char *p;
- int pass=0;
- /* try it two times; second pass reads from key resources */
- do {
- for(r=user_id_db; r; r = r->next ) {
- keyid_list_t a;
- for (a=r->keyids; a; a= a->next ) {
- if( a->keyid[0] == keyid[0] && a->keyid[1] == keyid[1] ) {
- p = xmalloc ( r->len + 10 );
- sprintf(p, "%08lX %.*s",
- (ulong)keyid[1], r->len, r->name );
- return p;
- }
- }
- }
- } while( ++pass < 2 && !get_pubkey( NULL, keyid ) );
- p = xmalloc ( 15 );
- sprintf(p, "%08lX [?]", (ulong)keyid[1] );
- return p;
-}
-
-
-char*
-get_user_id_string_printable ( u32 *keyid )
-{
- char *p = get_user_id_string( keyid );
- char *p2 = utf8_to_native( p, strlen(p), 0 );
- xfree (p);
- p = make_printable_string (p2, strlen (p2), 0);
- xfree (p2);
- return p;
-}
-
-
-char*
-get_long_user_id_string( u32 *keyid )
-{
- user_id_db_t r;
- char *p;
- int pass=0;
- /* try it two times; second pass reads from key resources */
- do {
- for(r=user_id_db; r; r = r->next ) {
- keyid_list_t a;
- for (a=r->keyids; a; a= a->next ) {
- if( a->keyid[0] == keyid[0] && a->keyid[1] == keyid[1] ) {
- p = xmalloc ( r->len + 20 );
- sprintf(p, "%08lX%08lX %.*s",
- (ulong)keyid[0], (ulong)keyid[1],
- r->len, r->name );
- return p;
- }
- }
- }
- } while( ++pass < 2 && !get_pubkey( NULL, keyid ) );
- p = xmalloc ( 25 );
- sprintf(p, "%08lX%08lX [?]", (ulong)keyid[0], (ulong)keyid[1] );
- return p;
-}
-
-char*
-get_user_id( u32 *keyid, size_t *rn )
-{
- user_id_db_t r;
- char *p;
- int pass=0;
-
- /* try it two times; second pass reads from key resources */
- do {
- for(r=user_id_db; r; r = r->next ) {
- keyid_list_t a;
- for (a=r->keyids; a; a= a->next ) {
- if( a->keyid[0] == keyid[0] && a->keyid[1] == keyid[1] ) {
- p = xmalloc ( r->len );
- memcpy(p, r->name, r->len );
- *rn = r->len;
- return p;
- }
- }
- }
- } while( ++pass < 2 && !get_pubkey( NULL, keyid ) );
- p = xstrdup ( _("[User id not found]") );
- *rn = strlen(p);
- return p;
-}
-
-char*
-get_user_id_printable( u32 *keyid )
-{
- size_t rn;
- char *p = get_user_id( keyid, &rn );
- char *p2 = utf8_to_native( p, rn, 0 );
- xfree (p);
- p = make_printable_string (p2, strlen (p2), 0);
- xfree (p2);
- return p;
-}
-
-KEYDB_HANDLE
-get_ctx_handle(GETKEY_CTX ctx)
-{
- return ctx->kr_handle;
-}
diff --git a/g10/global.h b/g10/global.h
deleted file mode 100644
index d1c554dce..000000000
--- a/g10/global.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* global.h - Local typedefs and constants
- * Copyright (C) 2001 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef GPG_GLOBAL_H
-#define GPG_GLOBAL_H
-
-#define MAX_FINGERPRINT_LEN 20
-
-typedef struct kbnode_struct *KBNODE;
-typedef struct keydb_search_desc KEYDB_SEARCH_DESC;
-
-#include "gpg.h"
-
-#endif /*GPG_GLOBAL_H*/
diff --git a/g10/gpg.h b/g10/gpg.h
deleted file mode 100644
index bf61411f7..000000000
--- a/g10/gpg.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* gpg.h - top level include file for gpg etc.
- * Copyright (C) 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef GNUPG_G10_GPG_H
-#define GNUPG_G10_GPG_H
-
-/* Note, that this file should be the first one after the system
- header files. This is required to set the error source to the
- correct value and may be of advantage if we ever have to do
- special things. */
-
-#ifdef GPG_ERR_SOURCE_DEFAULT
-#error GPG_ERR_SOURCE_DEFAULT already defined
-#endif
-#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GPG
-#include <gpg-error.h>
-
-
-/* FIXME: merge this with global.h */
-
-
-#endif /*GNUPG_G10_GPG_H*/
diff --git a/g10/gpgv.c b/g10/gpgv.c
deleted file mode 100644
index 9bd954c6f..000000000
--- a/g10/gpgv.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/* gpgv.c - The GnuPG signature verify utility
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#ifdef HAVE_DOSISH_SYSTEM
-#include <fcntl.h> /* for setmode() */
-#endif
-
-#define INCLUDED_BY_MAIN_MODULE 1
-#include "gpg.h"
-#include "packet.h"
-#include "iobuf.h"
-#include "memory.h"
-#include "util.h"
-#include "main.h"
-#include "options.h"
-#include "keydb.h"
-#include "trustdb.h"
-#include "mpi.h"
-#include "cipher.h"
-#include "filter.h"
-#include "ttyio.h"
-#include "i18n.h"
-#include "status.h"
-
-
-enum cmd_and_opt_values { aNull = 0,
- oQuiet = 'q',
- oVerbose = 'v',
- oBatch = 500,
- oKeyring,
- oIgnoreTimeConflict,
- oStatusFD,
- oLoggerFD,
- oHomedir,
-aTest };
-
-
-static ARGPARSE_OPTS opts[] = {
-
- { 301, NULL, 0, N_("@\nOptions:\n ") },
-
- { oVerbose, "verbose", 0, N_("verbose") },
- { oQuiet, "quiet", 0, N_("be somewhat more quiet") },
- { oKeyring, "keyring" ,2, N_("take the keys from this keyring")},
- { oIgnoreTimeConflict, "ignore-time-conflict", 0,
- N_("make timestamp conflicts only a warning") },
- { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
- { oLoggerFD, "logger-fd",1, "@" },
- { oHomedir, "homedir", 2, "@" }, /* defaults to "~/.gnupg" */
-
-{0} };
-
-
-
-int g10_errors_seen = 0;
-
-#ifdef __riscos__
-RISCOS_GLOBAL_STATICS("GnuPG (gpgv) Heap")
-#endif /* __riscos__ */
-
-static const char *
-my_strusage( int level )
-{
- const char *p;
- switch( level ) {
- case 11: p = "gpgv (GnuPG)";
- break;
- case 13: p = VERSION; break;
- case 17: p = PRINTABLE_OS_NAME; break;
- case 19: p =
- _("Please report bugs to <[email protected]>.\n");
- break;
- case 1:
- case 40: p =
- _("Usage: gpgv [options] [files] (-h for help)");
- break;
- case 41: p =
- _("Syntax: gpg [options] [files]\n"
- "Check signatures against known trusted keys\n");
- break;
-
- default: p = NULL;
- }
- return p;
-}
-
-
-
-
-static void
-i18n_init(void)
-{
-#ifdef USE_SIMPLE_GETTEXT
- set_gettext_file( PACKAGE_GT );
-#else
-#ifdef ENABLE_NLS
-#ifdef HAVE_LC_MESSAGES
- setlocale( LC_TIME, "" );
- setlocale( LC_MESSAGES, "" );
-#else
- setlocale( LC_ALL, "" );
-#endif
- bindtextdomain( PACKAGE_GT, LOCALEDIR );
- textdomain( PACKAGE_GT );
-#endif
-#endif
-}
-
-
-int
-main( int argc, char **argv )
-{
- ARGPARSE_ARGS pargs;
- int rc=0;
- STRLIST sl;
- STRLIST nrings=NULL;
- unsigned configlineno;
-
-#ifdef __riscos__
- riscos_global_defaults();
-#endif /* __riscos__ */
-
- set_strusage (my_strusage);
- log_set_prefix ("gpgv", 1);
- gnupg_init_signals(0, NULL);
- i18n_init();
- opt.command_fd = -1; /* no command fd */
- opt.pgp2_workarounds = 1;
- opt.keyserver_options.auto_key_retrieve = 1;
- opt.trust_model = TM_ALWAYS;
- opt.batch = 1;
-
-#if defined (_WIN32)
- opt.homedir = read_w32_registry_string( NULL, "Software\\GNU\\GnuPG",
- "HomeDir" );
-#else
- opt.homedir = getenv("GNUPGHOME");
-#endif
- if( !opt.homedir || !*opt.homedir ) {
- opt.homedir = GNUPG_DEFAULT_HOMEDIR;
- }
- tty_no_terminal(1);
- tty_batchmode(1);
- disable_dotlock();
-
- set_native_charset (NULL); /* Try to auto set the character set */
-
- pargs.argc = &argc;
- pargs.argv = &argv;
- pargs.flags= 1; /* do not remove the args */
- while( optfile_parse( NULL, NULL, &configlineno, &pargs, opts) ) {
- switch( pargs.r_opt ) {
- case oQuiet: opt.quiet = 1; break;
- case oVerbose: g10_opt_verbose++;
- opt.verbose++; opt.list_sigs=1; break;
- case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
- case oStatusFD: set_status_fd( pargs.r.ret_int ); break;
- case oLoggerFD:
- log_set_fd (iobuf_translate_file_handle (pargs.r.ret_int, 1));
- break;
- case oHomedir: opt.homedir = pargs.r.ret_str; break;
- case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
- default : pargs.err = 2; break;
- }
- }
-
- if( log_get_errorcount(0) )
- g10_exit(2);
-
- g10_opt_homedir = opt.homedir;
-
- if( opt.verbose > 1 )
- set_packet_list_mode(1);
-
- if( !nrings ) /* no keyring given: use default one */
- keydb_add_resource ("trustedkeys" EXTSEP_S "gpg", 0, 0);
- for(sl = nrings; sl; sl = sl->next )
- keydb_add_resource (sl->d, 0, 0 );
-
- FREE_STRLIST(nrings);
-
- if( (rc = verify_signatures( argc, argv ) ))
- log_error("verify signatures failed: %s\n", gpg_strerror (rc) );
-
- /* cleanup */
- g10_exit(0);
- return 8; /*NEVER REACHED*/
-}
-
-
-void
-g10_exit( int rc )
-{
- rc = rc? rc : log_get_errorcount(0)? 2 :
- g10_errors_seen? 1 : 0;
- exit(rc );
-}
-
-
-
-void
-read_trust_options (byte *trust_model,ulong *created,ulong *nextcheck,
- byte *marginals,byte *completes,byte *cert_depth)
-{
-}
-
-
-/* Stub:
- * We have to override the trustcheck from pkclist.c becuase
- * this utility assumes that all keys in the keyring are trustworthy
- */
-int
-check_signatures_trust( PKT_signature *sig )
-{
- return 0;
-}
-
-
-/* Stub:
- * We don't have the trustdb , so we have to provide some stub functions
- * instead
- */
-
-int
-cache_disabled_value(PKT_public_key *pk)
-{
- return 0;
-}
-
-int
-get_validity_info (PKT_public_key *pk, PKT_user_id *uid)
-{
- return '?';
-}
-
-unsigned int
-get_validity (PKT_public_key *pk, PKT_user_id *uid)
-{
- return 0;
-}
-
-const char *
-trust_value_to_string (unsigned int value)
-{
- return "err";
-}
-
-/* Stub: */
-int
-get_ownertrust_info (PKT_public_key *pk)
-{
- return '?';
-}
-
-unsigned int
-get_ownertrust (PKT_public_key *pk)
-{
- return TRUST_UNKNOWN;
-}
-
-
-/* Stub:
- * Because we only work with trusted keys, it does not make sense to
- * get them from a keyserver
- */
-int
-keyserver_import_keyid( u32 *keyid, void *dummy )
-{
- return -1;
-}
-
-/* Stub:
- * No encryption here but mainproc links to these functions.
- */
-int
-get_session_key( PKT_pubkey_enc *k, DEK *dek )
-{
- return GPG_ERR_GENERAL;
-}
-/* Stub: */
-int
-get_override_session_key( DEK *dek, const char *string )
-{
- return GPG_ERR_GENERAL;
-}
-/* Stub: */
-int
-decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
-{
- return GPG_ERR_GENERAL;
-}
-
-
-/* Stub:
- * No interactive commnds, so we don't need the helptexts
- */
-void
-display_online_help( const char *keyword )
-{
-}
-
-/* Stub:
- * We don't use secret keys, but getkey.c links to this
- */
-int
-check_secret_key( PKT_secret_key *sk, int n )
-{
- return GPG_ERR_GENERAL;
-}
-
-/* Stub:
- * No secret key, so no passphrase needed
- */
-DEK *
-passphrase_to_dek( u32 *keyid, int pubkey_algo,
- int cipher_algo, STRING2KEY *s2k, int mode,
- const char *tmp, int *canceled)
-{
- if (canceled)
- *canceled = 0;
- return NULL;
-}
-
-/* Stubs to avoid linking to photoid.c */
-void show_photos(const struct user_attribute *attrs,int count,PKT_public_key *pk) {}
-int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len) {return 0;}
-char *image_type_to_string(byte type,int string) {return NULL;}
-
-/* Stubs to void linking to ../cipher/cipher.c */
-int string_to_cipher_algo( const char *string ) { return 0; }
-const char *cipher_algo_to_string( int algo ) { return "?";}
-void disable_cipher_algo( int algo ) {}
-int check_cipher_algo( int algo ) { return -1;}
-unsigned int cipher_get_keylen( int algo ) { return 0; }
-unsigned int cipher_get_blocksize( int algo ) {return 0;}
-CIPHER_HANDLE cipher_open( int algo, int mode, int secure ) { return NULL;}
-void cipher_close( CIPHER_HANDLE c ) {}
-int cipher_setkey( CIPHER_HANDLE c, byte *key, unsigned keylen ) { return -1;}
-void cipher_setiv( CIPHER_HANDLE c, const byte *iv, unsigned ivlen ){}
-void cipher_encrypt( CIPHER_HANDLE c, byte *outbuf,
- byte *inbuf, unsigned nbytes ) {}
-void cipher_decrypt( CIPHER_HANDLE c, byte *outbuf,
- byte *inbuf, unsigned nbytes ) {}
-void cipher_sync( CIPHER_HANDLE c ) {}
-
-
-/* Stubs to avoid linking to ../util/ttyio.c */
-int tty_batchmode( int onoff ) { return 0; }
-void tty_printf( const char *fmt, ... ) { }
-void tty_print_string( const byte *p, size_t n ) { }
-void tty_print_utf8_string( const byte *p, size_t n ) {}
-void tty_print_utf8_string2( const byte *p, size_t n, size_t max_n ) {}
-char *tty_get( const char *prompt ) { return NULL;}
-char *tty_get_hidden( const char *prompt ) {return NULL; }
-void tty_kill_prompt(void) {}
-int tty_get_answer_is_yes( const char *prompt ) {return 0;}
-int tty_no_terminal(int onoff) {return 0;}
-
-/* We do not do any locking, so use these stubs here */
-void disable_dotlock(void) {}
-DOTLOCK create_dotlock( const char *file_to_lock ) { return NULL; }
-int make_dotlock( DOTLOCK h, long timeout ) { return 0;}
-int release_dotlock( DOTLOCK h ) {return 0;}
-void dotlock_remove_lockfiles(void) {}
diff --git a/g10/helptext.c b/g10/helptext.c
deleted file mode 100644
index 4a65314eb..000000000
--- a/g10/helptext.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/* helptext.c - English help texts
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "ttyio.h"
-#include "main.h"
-#include "i18n.h"
-
-
-/****************
- * These helptexts are used for the "online" help feature. We use
- * a key consisting of words and dots. Because the lookup is only
- * done in an interactive mode on a user request (when she enters a "?"
- * as response to a prompt) we can use a simple search through the list.
- *
- * Mini glossary:
- *
- * "user ID", "trustdb", "NOTE" and "WARNING".
- */
-
-static struct helptexts { const char *key; const char *help; } helptexts[] = {
-
-/* begin of list */
-
-{ "edit_ownertrust.value", N_(
-"It's up to you to assign a value here; this value will never be exported\n"
-"to any 3rd party. We need it to implement the web-of-trust; it has nothing\n"
-"to do with the (implicitly created) web-of-certificates."
-)},
-
-{ "edit_ownertrust.set_ultimate.okay", N_(
- "To build the Web-of-Trust, GnuPG needs to know which keys are\n"
- "ultimately trusted - those are usually the keys for which you have\n"
- "access to the secret key. Answer \"yes\" to set this key to\n"
- "ultimately trusted\n"
-)},
-
-{ "revoked_key.override", N_(
-"If you want to use this revoked key anyway, answer \"yes\"."
-)},
-
-{ "untrusted_key.override", N_(
-"If you want to use this untrusted key anyway, answer \"yes\"."
-)},
-
-{ "pklist.user_id.enter", N_(
-"Enter the user ID of the addressee to whom you want to send the message."
-)},
-
-{ "keygen.algo", N_(
-"Select the algorithm to use.\n"
-"\n"
-"DSA (aka DSS) is the digital signature algorithm which can only be used\n"
-"for signatures. This is the suggested algorithm because verification of\n"
-"DSA signatures are much faster than those of ElGamal.\n"
-"\n"
-"ElGamal is an algorithm which can be used for signatures and encryption.\n"
-"OpenPGP distinguishs between two flavors of this algorithms: an encrypt only\n"
-"and a sign+encrypt; actually it is the same, but some parameters must be\n"
-"selected in a special way to create a safe key for signatures: this program\n"
-"does this but other OpenPGP implementations are not required to understand\n"
-"the signature+encryption flavor.\n"
-"\n"
-"The first (primary) key must always be a key which is capable of signing;\n"
-"this is the reason why the encryption only ElGamal key is not available in\n"
-"this menu."
-)},
-
-
-{ "keygen.algo.elg_se", N_(
-"Although these keys are defined in RFC2440 they are not suggested\n"
-"because they are not supported by all programs and signatures created\n"
-"with them are quite large and very slow to verify."
-)},
-
-{ "keygen.algo.rsa_se", N_(
-"In general it is not a good idea to use the same key for signing and\n"
-"encryption. This algorithm should only be used in certain domains.\n"
-"Please consult your security expert first."
-)},
-
-
-{ "keygen.size", N_(
- "Enter the size of the key"
-)},
-
-{ "keygen.size.huge.okay", N_(
- "Answer \"yes\" or \"no\""
-)},
-
-
-{ "keygen.size.large.okay", N_(
- "Answer \"yes\" or \"no\""
-)},
-
-
-{ "keygen.valid", N_(
- "Enter the required value as shown in the prompt.\n"
- "It is possible to enter a ISO date (YYYY-MM-DD) but you won't\n"
- "get a good error response - instead the system tries to interpret\n"
- "the given value as an interval."
-)},
-
-{ "keygen.valid.okay", N_(
- "Answer \"yes\" or \"no\""
-)},
-
-
-{ "keygen.name", N_(
- "Enter the name of the key holder"
-)},
-
-
-{ "keygen.email", N_(
- "please enter an optional but highly suggested email address"
-)},
-
-{ "keygen.comment", N_(
- "Please enter an optional comment"
-)},
-
-
-{ "keygen.userid.cmd", N_(
- ""
-"N to change the name.\n"
-"C to change the comment.\n"
-"E to change the email address.\n"
-"O to continue with key generation.\n"
-"Q to to quit the key generation."
-)},
-
-{ "keygen.sub.okay", N_(
- "Answer \"yes\" (or just \"y\") if it is okay to generate the sub key."
-)},
-
-{ "sign_uid.okay", N_(
- "Answer \"yes\" or \"no\""
-)},
-
-{ "sign_uid.class", N_(
-"When you sign a user ID on a key, you should first verify that the key\n"
-"belongs to the person named in the user ID. It is useful for others to\n"
-"know how carefully you verified this.\n\n"
-"\"0\" means you make no particular claim as to how carefully you verified the\n"
-" key.\n\n"
-"\"1\" means you believe the key is owned by the person who claims to own it\n"
-" but you could not, or did not verify the key at all. This is useful for\n"
-" a \"persona\" verification, where you sign the key of a pseudonymous user.\n\n"
-"\"2\" means you did casual verification of the key. For example, this could\n"
-" mean that you verified the key fingerprint and checked the user ID on the\n"
-" key against a photo ID.\n\n"
-"\"3\" means you did extensive verification of the key. For example, this could\n"
-" mean that you verified the key fingerprint with the owner of the key in\n"
-" person, and that you checked, by means of a hard to forge document with a\n"
-" photo ID (such as a passport) that the name of the key owner matches the\n"
-" name in the user ID on the key, and finally that you verified (by exchange\n"
-" of email) that the email address on the key belongs to the key owner.\n\n"
-"Note that the examples given above for levels 2 and 3 are *only* examples.\n"
-"In the end, it is up to you to decide just what \"casual\" and \"extensive\"\n"
-"mean to you when you sign other keys.\n\n"
-"If you don't know what the right answer is, answer \"0\"."
-)},
-
-{ "change_passwd.empty.okay", N_(
- "Answer \"yes\" or \"no\""
-)},
-
-
-{ "keyedit.save.okay", N_(
- "Answer \"yes\" or \"no\""
-)},
-
-
-{ "keyedit.cancel.okay", N_(
- "Answer \"yes\" or \"no\""
-)},
-
-{ "keyedit.sign_all.okay", N_(
- "Answer \"yes\" is you want to sign ALL the user IDs"
-)},
-
-{ "keyedit.remove.uid.okay", N_(
- "Answer \"yes\" if you really want to delete this user ID.\n"
- "All certificates are then also lost!"
-)},
-
-{ "keyedit.remove.subkey.okay", N_(
- "Answer \"yes\" if it is okay to delete the subkey"
-)},
-
-
-{ "keyedit.delsig.valid", N_(
- "This is a valid signature on the key; you normally don't want\n"
- "to delete this signature because it may be important to establish a\n"
- "trust connection to the key or another key certified by this key."
-)},
-{ "keyedit.delsig.unknown", N_(
- "This signature can't be checked because you don't have the\n"
- "corresponding key. You should postpone its deletion until you\n"
- "know which key was used because this signing key might establish\n"
- "a trust connection through another already certified key."
-)},
-{ "keyedit.delsig.invalid", N_(
- "The signature is not valid. It does make sense to remove it from\n"
- "your keyring."
-)},
-{ "keyedit.delsig.selfsig", N_(
- "This is a signature which binds the user ID to the key. It is\n"
- "usually not a good idea to remove such a signature. Actually\n"
- "GnuPG might not be able to use this key anymore. So do this\n"
- "only if this self-signature is for some reason not valid and\n"
- "a second one is available."
-)},
-
-{ "keyedit.updpref.okay", N_(
- "Change the preferences of all user IDs (or just of the selected ones)\n"
- "to the current list of preferences. The timestamp of all affected\n"
- "self-signatures will be advanced by one second.\n"
-)},
-
-
-{ "passphrase.enter", N_(
- ""
-"Please enter the passhrase; this is a secret sentence \n"
-)},
-
-
-{ "passphrase.repeat", N_(
- "Please repeat the last passphrase, so you are sure what you typed in."
-)},
-
-{ "detached_signature.filename", N_(
- "Give the name of the file to which the signature applies"
-)},
-
-/* openfile.c (overwrite_filep) */
-{ "openfile.overwrite.okay", N_(
- "Answer \"yes\" if it is okay to overwrite the file"
-)},
-
-/* openfile.c (ask_outfile_name) */
-{ "openfile.askoutname", N_(
- "Please enter a new filename. If you just hit RETURN the default\n"
- "file (which is shown in brackets) will be used."
-)},
-
-/* revoke.c (ask_revocation_reason) */
-{ "ask_revocation_reason.code", N_(
- "You should specify a reason for the certification. Depending on the\n"
- "context you have the ability to choose from this list:\n"
- " \"Key has been compromised\"\n"
- " Use this if you have a reason to believe that unauthorized persons\n"
- " got access to your secret key.\n"
- " \"Key is superseded\"\n"
- " Use this if you have replaced this key with a newer one.\n"
- " \"Key is no longer used\"\n"
- " Use this if you have retired this key.\n"
- " \"User ID is no longer valid\"\n"
- " Use this to state that the user ID should not longer be used;\n"
- " this is normally used to mark an email address invalid.\n"
-)},
-
-/* revoke.c (ask_revocation_reason) */
-{ "ask_revocation_reason.text", N_(
- "If you like, you can enter a text describing why you issue this\n"
- "revocation certificate. Please keep this text concise.\n"
- "An empty line ends the text.\n"
-)},
-
-/* end of list */
-{ NULL, NULL } };
-
-
-void
-display_online_help( const char *keyword )
-{
-
- tty_kill_prompt();
- if( !keyword )
- tty_printf(_("No help available") );
- else {
- const char *p;
- int i;
-
- for(i=0; (p=helptexts[i].key) && strcmp( p, keyword ); i++ )
- ;
- if( !p || !*helptexts[i].help )
- tty_printf(_("No help available for `%s'"), keyword );
- else
- tty_printf("%s", _(helptexts[i].help) );
- }
- tty_printf("\n");
-}
diff --git a/g10/import.c b/g10/import.c
deleted file mode 100644
index 9c323243a..000000000
--- a/g10/import.c
+++ /dev/null
@@ -1,1906 +0,0 @@
-/* import.c - Import OpenPGP key material
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "options.h"
-#include "packet.h"
-#include "errors.h"
-#include "keydb.h"
-#include "memory.h"
-#include "util.h"
-#include "trustdb.h"
-#include "main.h"
-#include "i18n.h"
-#include "ttyio.h"
-#include "status.h"
-#include "keyserver-internal.h"
-
-struct stats_s {
- ulong count;
- ulong no_user_id;
- ulong imported;
- ulong imported_rsa;
- ulong n_uids;
- ulong n_sigs;
- ulong n_subk;
- ulong unchanged;
- ulong n_revoc;
- ulong secret_read;
- ulong secret_imported;
- ulong secret_dups;
- ulong skipped_new_keys;
- ulong not_imported;
-};
-
-
-static int import( iobuf_t inp, const char* fname,
- struct stats_s *stats, unsigned int options );
-static int read_block( iobuf_t a, PACKET **pending_pkt, KBNODE *ret_root );
-static void revocation_present(KBNODE keyblock);
-static int import_one( const char *fname, KBNODE keyblock,
- struct stats_s *stats, unsigned int options);
-static int import_secret_one( const char *fname, KBNODE keyblock,
- struct stats_s *stats, unsigned int options);
-static int import_revoke_cert( const char *fname, KBNODE node,
- struct stats_s *stats);
-static int chk_self_sigs( const char *fname, KBNODE keyblock,
- PKT_public_key *pk, u32 *keyid, int *non_self );
-static int delete_inv_parts( const char *fname, KBNODE keyblock,
- u32 *keyid, unsigned int options );
-static int merge_blocks( const char *fname, KBNODE keyblock_orig,
- KBNODE keyblock, u32 *keyid,
- int *n_uids, int *n_sigs, int *n_subk );
-static int append_uid( KBNODE keyblock, KBNODE node, int *n_sigs,
- const char *fname, u32 *keyid );
-static int append_key( KBNODE keyblock, KBNODE node, int *n_sigs,
- const char *fname, u32 *keyid );
-static int merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
- const char *fname, u32 *keyid );
-static int merge_keysigs( KBNODE dst, KBNODE src, int *n_sigs,
- const char *fname, u32 *keyid );
-
-int
-parse_import_options(char *str,unsigned int *options)
-{
- struct parse_options import_opts[]=
- {
- {"allow-local-sigs",IMPORT_ALLOW_LOCAL_SIGS},
- {"repair-hkp-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG},
- {"repair-pks-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG},
- {"fast-import",IMPORT_FAST_IMPORT},
- {"convert-sk-to-pk",IMPORT_SK2PK},
- {NULL,0}
- };
-
- return parse_options(str,options,import_opts);
-}
-
-void *
-import_new_stats_handle (void)
-{
- return xcalloc (1, sizeof (struct stats_s) );
-}
-
-void
-import_release_stats_handle (void *p)
-{
- xfree (p);
-}
-
-/****************
- * Import the public keys from the given filename. Input may be armored.
- * This function rejects all keys which are not validly self signed on at
- * least one userid. Only user ids which are self signed will be imported.
- * Other signatures are not checked.
- *
- * Actually this function does a merge. It works like this:
- *
- * - get the keyblock
- * - check self-signatures and remove all userids and their signatures
- * without/invalid self-signatures.
- * - reject the keyblock, if we have no valid userid.
- * - See whether we have this key already in one of our pubrings.
- * If not, simply add it to the default keyring.
- * - Compare the key and the self-signatures of the new and the one in
- * our keyring. If they are different something weird is going on;
- * ask what to do.
- * - See whether we have only non-self-signature on one user id; if not
- * ask the user what to do.
- * - compare the signatures: If we already have this signature, check
- * that they compare okay; if not, issue a warning and ask the user.
- * (consider looking at the timestamp and use the newest?)
- * - Simply add the signature. Can't verify here because we may not have
- * the signature's public key yet; verification is done when putting it
- * into the trustdb, which is done automagically as soon as this pubkey
- * is used.
- * - Proceed with next signature.
- *
- * Key revocation certificates have special handling.
- *
- */
-static int
-import_keys_internal( iobuf_t inp, char **fnames, int nnames,
- void *stats_handle, unsigned int options )
-{
- int i, rc = 0;
- struct stats_s *stats = stats_handle;
-
- if (!stats)
- stats = import_new_stats_handle ();
-
- if (inp) {
- rc = import( inp, "[stream]", stats, options);
- }
- else {
- if( !fnames && !nnames )
- nnames = 1; /* Ohh what a ugly hack to jump into the loop */
-
- for(i=0; i < nnames; i++ ) {
- const char *fname = fnames? fnames[i] : NULL;
- iobuf_t inp2 = iobuf_open(fname);
- if( !fname )
- fname = "[stdin]";
- if( !inp2 )
- log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
- else {
- rc = import( inp2, fname, stats, options );
- iobuf_close(inp2);
- /* Must invalidate that ugly cache to actually close it. */
- iobuf_ioctl (NULL, 2, 0, (char*)fname);
- if( rc )
- log_error("import from `%s' failed: %s\n", fname,
- gpg_strerror (rc) );
- }
- if( !fname )
- break;
- }
- }
- if (!stats_handle) {
- import_print_stats (stats);
- import_release_stats_handle (stats);
- }
- /* If no fast import and the trustdb is dirty (i.e. we added a key
- or userID that had something other than a selfsig, a signature
- that was other than a selfsig, or any revocation), then
- update/check the trustdb if the user specified by setting
- interactive or by not setting no-auto-check-trustdb */
- if (!(options&IMPORT_FAST_IMPORT) && trustdb_pending_check())
- {
- if (opt.interactive)
- update_trustdb();
- else if (!opt.no_auto_check_trustdb)
- check_trustdb();
- }
-
- return rc;
-}
-
-void
-import_keys( char **fnames, int nnames,
- void *stats_handle, unsigned int options )
-{
- import_keys_internal( NULL, fnames, nnames, stats_handle, options);
-}
-
-int
-import_keys_stream( iobuf_t inp, void *stats_handle, unsigned int options )
-{
- return import_keys_internal( inp, NULL, 0, stats_handle, options);
-}
-
-static int
-import( iobuf_t inp, const char* fname,
- struct stats_s *stats, unsigned int options )
-{
- PACKET *pending_pkt = NULL;
- KBNODE keyblock;
- int rc = 0;
-
- getkey_disable_caches();
-
- if( !opt.no_armor ) { /* armored reading is not disabled */
- armor_filter_context_t *afx = xcalloc (1, sizeof *afx );
- afx->only_keyblocks = 1;
- iobuf_push_filter2( inp, armor_filter, afx, 1 );
- }
-
- while( !(rc = read_block( inp, &pending_pkt, &keyblock) )) {
- if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY )
- rc = import_one( fname, keyblock, stats, options );
- else if( keyblock->pkt->pkttype == PKT_SECRET_KEY )
- rc = import_secret_one( fname, keyblock, stats, options );
- else if( keyblock->pkt->pkttype == PKT_SIGNATURE
- && keyblock->pkt->pkt.signature->sig_class == 0x20 )
- rc = import_revoke_cert( fname, keyblock, stats );
- else {
- log_info( _("skipping block of type %d\n"),
- keyblock->pkt->pkttype );
- }
- release_kbnode(keyblock);
- /* fixme: we should increment the not imported counter but this
- does only make sense if we keep on going despite of errors. */
- if( rc )
- break;
- if( !(++stats->count % 100) && !opt.quiet )
- log_info(_("%lu keys processed so far\n"), stats->count );
- }
- if( rc == -1 )
- rc = 0;
- else if( rc && rc != GPG_ERR_INV_KEYRING )
- log_error( _("error reading `%s': %s\n"), fname, gpg_strerror (rc));
-
- return rc;
-}
-
-
-void
-import_print_stats (void *hd)
-{
- struct stats_s *stats = hd;
-
- if( !opt.quiet ) {
- log_info(_("Total number processed: %lu\n"), stats->count );
- if( stats->skipped_new_keys )
- log_info(_(" skipped new keys: %lu\n"),
- stats->skipped_new_keys );
- if( stats->no_user_id )
- log_info(_(" w/o user IDs: %lu\n"), stats->no_user_id );
- if( stats->imported || stats->imported_rsa ) {
- log_info(_(" imported: %lu"), stats->imported );
- if( stats->imported_rsa )
- fprintf(stderr, " (RSA: %lu)", stats->imported_rsa );
- putc('\n', stderr);
- }
- if( stats->unchanged )
- log_info(_(" unchanged: %lu\n"), stats->unchanged );
- if( stats->n_uids )
- log_info(_(" new user IDs: %lu\n"), stats->n_uids );
- if( stats->n_subk )
- log_info(_(" new subkeys: %lu\n"), stats->n_subk );
- if( stats->n_sigs )
- log_info(_(" new signatures: %lu\n"), stats->n_sigs );
- if( stats->n_revoc )
- log_info(_(" new key revocations: %lu\n"), stats->n_revoc );
- if( stats->secret_read )
- log_info(_(" secret keys read: %lu\n"), stats->secret_read );
- if( stats->secret_imported )
- log_info(_(" secret keys imported: %lu\n"), stats->secret_imported );
- if( stats->secret_dups )
- log_info(_(" secret keys unchanged: %lu\n"), stats->secret_dups );
- if( stats->not_imported )
- log_info(_(" not imported: %lu\n"), stats->not_imported );
- }
-
- if( is_status_enabled() ) {
- char buf[14*20];
- sprintf(buf, "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
- stats->count,
- stats->no_user_id,
- stats->imported,
- stats->imported_rsa,
- stats->unchanged,
- stats->n_uids,
- stats->n_subk,
- stats->n_sigs,
- stats->n_revoc,
- stats->secret_read,
- stats->secret_imported,
- stats->secret_dups,
- stats->skipped_new_keys,
- stats->not_imported );
- write_status_text( STATUS_IMPORT_RES, buf );
- }
-}
-
-
-/****************
- * Read the next keyblock from stream A.
- * PENDING_PKT should be initialzed to NULL
- * and not chnaged form the caller.
- * Retunr: 0 = okay, -1 no more blocks or another errorcode.
- */
-static int
-read_block( iobuf_t a, PACKET **pending_pkt, KBNODE *ret_root )
-{
- int rc;
- PACKET *pkt;
- KBNODE root = NULL;
- int in_cert;
-
- if( *pending_pkt ) {
- root = new_kbnode( *pending_pkt );
- *pending_pkt = NULL;
- in_cert = 1;
- }
- else
- in_cert = 0;
- pkt = xmalloc ( sizeof *pkt );
- init_packet(pkt);
- while( (rc=parse_packet(a, pkt)) != -1 ) {
- if( rc ) { /* ignore errors */
- if( rc != GPG_ERR_UNKNOWN_PACKET ) {
- log_error("read_block: read error: %s\n", gpg_strerror (rc) );
- rc = GPG_ERR_INV_KEYRING;
- goto ready;
- }
- free_packet( pkt );
- init_packet(pkt);
- continue;
- }
-
- if( !root && pkt->pkttype == PKT_SIGNATURE
- && pkt->pkt.signature->sig_class == 0x20 ) {
- /* this is a revocation certificate which is handled
- * in a special way */
- root = new_kbnode( pkt );
- pkt = NULL;
- goto ready;
- }
-
- /* make a linked list of all packets */
- switch( pkt->pkttype ) {
- case PKT_COMPRESSED:
- if( pkt->pkt.compressed->algorithm < 1
- || pkt->pkt.compressed->algorithm > 2 ) {
- rc = GPG_ERR_COMPR_ALGO;
- goto ready;
- }
- {
- compress_filter_context_t *cfx = xcalloc (1, sizeof *cfx );
- cfx->algo = pkt->pkt.compressed->algorithm;
- pkt->pkt.compressed->buf = NULL;
- iobuf_push_filter2( a, compress_filter, cfx, 1 );
- }
- free_packet( pkt );
- init_packet(pkt);
- break;
-
- case PKT_RING_TRUST:
- /* skip those packets */
- free_packet( pkt );
- init_packet(pkt);
- break;
-
- case PKT_PUBLIC_KEY:
- case PKT_SECRET_KEY:
- if( in_cert ) { /* store this packet */
- *pending_pkt = pkt;
- pkt = NULL;
- goto ready;
- }
- in_cert = 1;
- default:
- if( in_cert ) {
- if( !root )
- root = new_kbnode( pkt );
- else
- add_kbnode( root, new_kbnode( pkt ) );
- pkt = xmalloc ( sizeof *pkt );
- }
- init_packet(pkt);
- break;
- }
- }
- ready:
- if( rc == -1 && root )
- rc = 0;
-
- if( rc )
- release_kbnode( root );
- else
- *ret_root = root;
- free_packet( pkt );
- xfree ( pkt );
- return rc;
-}
-
-/* Walk through the subkeys on a pk to find if we have the PKS
- disease: multiple subkeys with their binding sigs stripped, and the
- sig for the first subkey placed after the last subkey. That is,
- instead of "pk uid sig sub1 bind1 sub2 bind2 sub3 bind3" we have
- "pk uid sig sub1 sub2 sub3 bind1". We can't do anything about sub2
- and sub3, as they are already lost, but we can try and rescue sub1
- by reordering the keyblock so that it reads "pk uid sig sub1 bind1
- sub2 sub3". Returns TRUE if the keyblock was modified. */
-
-static int
-fix_pks_corruption(KBNODE keyblock)
-{
- int changed=0,keycount=0;
- KBNODE node,last=NULL,sknode=NULL;
-
- /* First determine if we have the problem at all. Look for 2 or
- more subkeys in a row, followed by a single binding sig. */
- for(node=keyblock;node;last=node,node=node->next)
- {
- if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
- {
- keycount++;
- if(!sknode)
- sknode=node;
- }
- else if(node->pkt->pkttype==PKT_SIGNATURE &&
- node->pkt->pkt.signature->sig_class==0x18 &&
- keycount>=2 && node->next==NULL)
- {
- /* We might have the problem, as this key has two subkeys in
- a row without any intervening packets. */
-
- /* Sanity check */
- if(last==NULL)
- break;
-
- /* Temporarily attach node to sknode. */
- node->next=sknode->next;
- sknode->next=node;
- last->next=NULL;
-
- /* Note we aren't checking whether this binding sig is a
- selfsig. This is not necessary here as the subkey and
- binding sig will be rejected later if that is the
- case. */
- if(check_key_signature(keyblock,node,NULL))
- {
- /* Not a match, so undo the changes. */
- sknode->next=node->next;
- last->next=node;
- node->next=NULL;
- break;
- }
- else
- {
- sknode->flag |= 1; /* Mark it good so we don't need to
- check it again */
- changed=1;
- break;
- }
- }
- else
- keycount=0;
- }
-
- return changed;
-}
-
-
-static void
-print_import_ok (PKT_public_key *pk, PKT_secret_key *sk, unsigned int reason)
-{
- byte array[MAX_FINGERPRINT_LEN], *s;
- char buf[MAX_FINGERPRINT_LEN*2+30], *p;
- size_t i, n;
-
- sprintf (buf, "%u ", reason);
- p = buf + strlen (buf);
-
- if (pk)
- fingerprint_from_pk (pk, array, &n);
- else
- fingerprint_from_sk (sk, array, &n);
- s = array;
- for (i=0; i < n ; i++, s++, p += 2)
- sprintf (p, "%02X", *s);
-
- write_status_text (STATUS_IMPORT_OK, buf);
-}
-
-void
-print_import_check (PKT_public_key * pk, PKT_user_id * id)
-{
- char * buf;
- byte fpr[24];
- u32 keyid[2];
- size_t i, pos = 0, n;
-
- buf = xmalloc (17+41+id->len+32);
- keyid_from_pk (pk, keyid);
- sprintf (buf, "%08X%08X ", keyid[0], keyid[1]);
- pos = 17;
- fingerprint_from_pk (pk, fpr, &n);
- for (i = 0; i < n; i++, pos += 2)
- sprintf (buf+pos, "%02X", fpr[i]);
- strcat (buf, " ");
- pos += 1;
- strcat (buf, id->name);
- write_status_text (STATUS_IMPORT_CHECK, buf);
- xfree (buf);
-}
-
-/****************
- * Try to import one keyblock. Return an error only in serious cases, but
- * never for an invalid keyblock. It uses log_error to increase the
- * internal errorcount, so that invalid input can be detected by programs
- * which called g10.
- */
-static int
-import_one( const char *fname, KBNODE keyblock,
- struct stats_s *stats, unsigned int options )
-{
- PKT_public_key *pk;
- PKT_public_key *pk_orig;
- KBNODE node, uidnode;
- KBNODE keyblock_orig = NULL;
- u32 keyid[2];
- int rc = 0;
- int new_key = 0;
- int mod_key = 0;
- int non_self = 0;
-
- /* get the key and print some info about it */
- node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
- if( !node )
- BUG();
-
- pk = node->pkt->pkt.public_key;
- keyid_from_pk( pk, keyid );
- uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
-
- if(pk->pubkey_algo==PUBKEY_ALGO_ELGAMAL)
- log_info(_("NOTE: Elgamal primary key detected - "
- "this may take some time to import\n"));
-
- if( opt.verbose && !opt.interactive ) {
- log_info( "pub %4u%c/%08lX %s ",
- nbits_from_pk( pk ),
- pubkey_letter( pk->pubkey_algo ),
- (ulong)keyid[1], datestr_from_pk(pk) );
- if( uidnode )
- print_utf8_string( stderr, uidnode->pkt->pkt.user_id->name,
- uidnode->pkt->pkt.user_id->len );
- putc('\n', stderr);
- }
- if( !uidnode ) {
- log_error( _("key %08lX: no user ID\n"), (ulong)keyid[1]);
- return 0;
- }
-
- if (opt.interactive) {
- if(is_status_enabled())
- print_import_check (pk, uidnode->pkt->pkt.user_id);
- merge_keys_and_selfsig (keyblock);
- tty_printf ("\n");
- show_basic_key_info (keyblock);
- tty_printf ("\n");
- if (!cpr_get_answer_is_yes ("import.okay",
- "Do you want to import this key? (y/N) "))
- return 0;
- }
-
- clear_kbnode_flags( keyblock );
-
- if((options&IMPORT_REPAIR_PKS_SUBKEY_BUG) && fix_pks_corruption(keyblock)
- && opt.verbose)
- log_info(_("key %08lX: PKS subkey corruption repaired\n"),
- (ulong)keyid[1]);
-
- rc = chk_self_sigs( fname, keyblock , pk, keyid, &non_self );
- if( rc )
- return rc== -1? 0:rc;
-
- /* If we allow such a thing, mark unsigned uids as valid */
- if( opt.allow_non_selfsigned_uid )
- for( node=keyblock; node; node = node->next )
- if( node->pkt->pkttype == PKT_USER_ID && !(node->flag & 1) )
- {
- char *user=utf8_to_native(node->pkt->pkt.user_id->name,
- node->pkt->pkt.user_id->len,0);
- node->flag |= 1;
- log_info( _("key %08lX: accepted non self-signed user ID '%s'\n"),
- (ulong)keyid[1],user);
- xfree (user);
- }
-
- if( !delete_inv_parts( fname, keyblock, keyid, options ) ) {
- log_error ( _("key %08lX: no valid user IDs\n"), (ulong)keyid[1]);
- if( !opt.quiet )
- log_info(_("this may be caused by a missing self-signature\n"));
- stats->no_user_id++;
- return 0;
- }
-
- /* do we have this key already in one of our pubrings ? */
- pk_orig = xcalloc (1, sizeof *pk_orig );
- rc = get_pubkey_fast ( pk_orig, keyid );
- if( rc && gpg_err_code (rc) != GPG_ERR_NO_PUBKEY
- && gpg_err_code (rc) != GPG_ERR_UNUSABLE_PUBKEY ) {
- log_error( _("key %08lX: public key not found: %s\n"),
- (ulong)keyid[1], gpg_strerror (rc));
- }
- else if ( rc && opt.merge_only ) {
- if( opt.verbose )
- log_info( _("key %08lX: new key - skipped\n"), (ulong)keyid[1] );
- rc = 0;
- stats->skipped_new_keys++;
- }
- else if( rc ) { /* insert this key */
- KEYDB_HANDLE hd = keydb_new (0);
-
- rc = keydb_locate_writable (hd, NULL);
- if (rc) {
- log_error (_("no writable keyring found: %s\n"), gpg_strerror (rc));
- keydb_release (hd);
- return GPG_ERR_GENERAL;
- }
- if( opt.verbose > 1 )
- log_info (_("writing to `%s'\n"), keydb_get_resource_name (hd) );
- rc = keydb_insert_keyblock (hd, keyblock );
- if (rc)
- log_error (_("error writing keyring `%s': %s\n"),
- keydb_get_resource_name (hd), gpg_strerror (rc));
- else
- {
- /* This should not be possible since we delete the
- ownertrust when a key is deleted, but it can happen if
- the keyring and trustdb are out of sync. It can also
- be made to happen with the trusted-key command. */
-
- clear_ownertrusts (pk);
- if(non_self)
- revalidation_mark ();
- }
- keydb_release (hd);
-
- /* we are ready */
- if( !opt.quiet ) {
- char *p=get_user_id_printable (keyid);
- log_info( _("key %08lX: public key \"%s\" imported\n"),
- (ulong)keyid[1],p);
- xfree (p);
- }
- if( is_status_enabled() ) {
- char *us = get_long_user_id_string( keyid );
- write_status_text( STATUS_IMPORTED, us );
- xfree (us);
- print_import_ok (pk,NULL, 1);
- }
- stats->imported++;
- if( is_RSA( pk->pubkey_algo ) )
- stats->imported_rsa++;
- new_key = 1;
- }
- else { /* merge */
- KEYDB_HANDLE hd;
- int n_uids, n_sigs, n_subk;
-
- /* Compare the original against the new key; just to be sure nothing
- * weird is going on */
- if( cmp_public_keys( pk_orig, pk ) ) {
- log_error( _("key %08lX: doesn't match our copy\n"),
- (ulong)keyid[1]);
- goto leave;
- }
-
- /* now read the original keyblock */
- hd = keydb_new (0);
- {
- byte afp[MAX_FINGERPRINT_LEN];
- size_t an;
-
- fingerprint_from_pk (pk_orig, afp, &an);
- while (an < MAX_FINGERPRINT_LEN)
- afp[an++] = 0;
- rc = keydb_search_fpr (hd, afp);
- }
- if( rc ) {
- log_error (_("key %08lX: can't locate original keyblock: %s\n"),
- (ulong)keyid[1], gpg_strerror (rc));
- keydb_release (hd);
- goto leave;
- }
- rc = keydb_get_keyblock (hd, &keyblock_orig );
- if (rc) {
- log_error (_("key %08lX: can't read original keyblock: %s\n"),
- (ulong)keyid[1], gpg_strerror (rc));
- keydb_release (hd);
- goto leave;
- }
-
- collapse_uids( &keyblock );
- /* and try to merge the block */
- clear_kbnode_flags( keyblock_orig );
- clear_kbnode_flags( keyblock );
- n_uids = n_sigs = n_subk = 0;
- rc = merge_blocks( fname, keyblock_orig, keyblock,
- keyid, &n_uids, &n_sigs, &n_subk );
- if( rc ) {
- keydb_release (hd);
- goto leave;
- }
- if( n_uids || n_sigs || n_subk ) {
- mod_key = 1;
- /* keyblock_orig has been updated; write */
- rc = keydb_update_keyblock (hd, keyblock_orig);
- if (rc)
- log_error (_("error writing keyring `%s': %s\n"),
- keydb_get_resource_name (hd), gpg_strerror (rc) );
- else if(non_self)
- revalidation_mark ();
-
- /* we are ready */
- if( !opt.quiet ) {
- char *p=get_user_id_printable(keyid);
- if( n_uids == 1 )
- log_info( _("key %08lX: \"%s\" 1 new user ID\n"),
- (ulong)keyid[1], p);
- else if( n_uids )
- log_info( _("key %08lX: \"%s\" %d new user IDs\n"),
- (ulong)keyid[1], p, n_uids );
- if( n_sigs == 1 )
- log_info( _("key %08lX: \"%s\" 1 new signature\n"),
- (ulong)keyid[1], p);
- else if( n_sigs )
- log_info( _("key %08lX: \"%s\" %d new signatures\n"),
- (ulong)keyid[1], p, n_sigs );
- if( n_subk == 1 )
- log_info( _("key %08lX: \"%s\" 1 new subkey\n"),
- (ulong)keyid[1], p);
- else if( n_subk )
- log_info( _("key %08lX: \"%s\" %d new subkeys\n"),
- (ulong)keyid[1], p, n_subk );
- xfree (p);
- }
-
- stats->n_uids +=n_uids;
- stats->n_sigs +=n_sigs;
- stats->n_subk +=n_subk;
-
- if (is_status_enabled ())
- print_import_ok (pk, NULL,
- ((n_uids?2:0)|(n_sigs?4:0)|(n_subk?8:0)));
- }
- else {
- if (is_status_enabled ())
- print_import_ok (pk, NULL, 0);
-
- if( !opt.quiet ) {
- char *p=get_user_id_printable(keyid);
- log_info( _("key %08lX: \"%s\" not changed\n"),
- (ulong)keyid[1],p);
- xfree (p);
- }
- stats->unchanged++;
- }
- keydb_release (hd); hd = NULL;
- }
-
- leave:
- release_kbnode( keyblock_orig );
- free_public_key( pk_orig );
-
- revocation_present(keyblock);
-
- return rc;
-}
-
-/* Walk a secret keyblock and produce a public keyblock out of it. */
-static KBNODE
-sec_to_pub_keyblock(KBNODE sec_keyblock)
-{
- KBNODE secnode,pub_keyblock=NULL,ctx=NULL;
-
- while((secnode=walk_kbnode(sec_keyblock,&ctx,0)))
- {
- KBNODE pubnode;
-
- if(secnode->pkt->pkttype==PKT_SECRET_KEY ||
- secnode->pkt->pkttype==PKT_SECRET_SUBKEY)
- {
- /* Make a public key. We only need to convert enough to
- write the keyblock out. */
-
- PKT_secret_key *sk=secnode->pkt->pkt.secret_key;
- PACKET *pkt=xcalloc (1,sizeof(PACKET));
- PKT_public_key *pk=xcalloc (1,sizeof(PKT_public_key));
- int n;
-
- if(secnode->pkt->pkttype==PKT_SECRET_KEY)
- pkt->pkttype=PKT_PUBLIC_KEY;
- else
- pkt->pkttype=PKT_PUBLIC_SUBKEY;
-
- pkt->pkt.public_key=pk;
-
- pk->version=sk->version;
- pk->timestamp=sk->timestamp;
- pk->expiredate=sk->expiredate;
- pk->pubkey_algo=sk->pubkey_algo;
-
- n=pubkey_get_npkey(pk->pubkey_algo);
- if(n==0)
- pk->pkey[0]=mpi_copy(sk->skey[0]);
- else
- {
- int i;
-
- for(i=0;i<n;i++)
- pk->pkey[i]=mpi_copy(sk->skey[i]);
- }
-
- pubnode=new_kbnode(pkt);
- }
- else
- {
- pubnode=clone_kbnode(secnode);
- }
-
- if(pub_keyblock==NULL)
- pub_keyblock=pubnode;
- else
- add_kbnode(pub_keyblock,pubnode);
- }
-
- return pub_keyblock;
-}
-
-/****************
- * Ditto for secret keys. Handling is simpler than for public keys.
- * We allow secret key importing only when allow is true, this is so
- * that a secret key can not be imported accidently and thereby tampering
- * with the trust calculation.
- */
-static int
-import_secret_one( const char *fname, KBNODE keyblock,
- struct stats_s *stats, unsigned int options)
-{
- PKT_secret_key *sk;
- KBNODE node, uidnode;
- u32 keyid[2];
- int rc = 0;
-
- /* get the key and print some info about it */
- node = find_kbnode( keyblock, PKT_SECRET_KEY );
- if( !node )
- BUG();
-
- sk = node->pkt->pkt.secret_key;
- keyid_from_sk( sk, keyid );
- uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
-
- if( opt.verbose ) {
- log_info( "sec %4u%c/%08lX %s ",
- nbits_from_sk( sk ),
- pubkey_letter( sk->pubkey_algo ),
- (ulong)keyid[1], datestr_from_sk(sk) );
- if( uidnode )
- print_utf8_string( stderr, uidnode->pkt->pkt.user_id->name,
- uidnode->pkt->pkt.user_id->len );
- putc('\n', stderr);
- }
- stats->secret_read++;
-
- if( !uidnode ) {
- log_error( _("key %08lX: no user ID\n"), (ulong)keyid[1]);
- return 0;
- }
-
- if(sk->protect.algo>110)
- {
- log_error(_("key %08lX: secret key with invalid cipher %d "
- "- skipped\n"),(ulong)keyid[1],sk->protect.algo);
- return 0;
- }
-
- clear_kbnode_flags( keyblock );
-
- /* do we have this key already in one of our secrings ? */
- rc = seckey_available( keyid );
- if( gpg_err_code (rc) == GPG_ERR_NO_SECKEY && !opt.merge_only ) {
- /* simply insert this key */
- KEYDB_HANDLE hd = keydb_new (1);
-
- /* get default resource */
- rc = keydb_locate_writable (hd, NULL);
- if (rc) {
- log_error (_("no default secret keyring: %s\n"), gpg_strerror (rc));
- keydb_release (hd);
- return GPG_ERR_GENERAL;
- }
- rc = keydb_insert_keyblock (hd, keyblock );
- if (rc)
- log_error (_("error writing keyring `%s': %s\n"),
- keydb_get_resource_name (hd), gpg_strerror (rc) );
- keydb_release (hd);
- /* we are ready */
- if( !opt.quiet )
- log_info( _("key %08lX: secret key imported\n"), (ulong)keyid[1]);
- stats->secret_imported++;
- if (is_status_enabled ())
- print_import_ok (NULL, sk, 1|16);
-
- if(options&IMPORT_SK2PK)
- {
- /* Try and make a public key out of this. */
-
- KBNODE pub_keyblock=sec_to_pub_keyblock(keyblock);
- import_one(fname,pub_keyblock,stats,opt.import_options);
- release_kbnode(pub_keyblock);
- }
-
- }
- else if( !rc ) { /* we can't merge secret keys */
- log_error( _("key %08lX: already in secret keyring\n"),
- (ulong)keyid[1]);
- stats->secret_dups++;
- if (is_status_enabled ())
- print_import_ok (NULL, sk, 16);
-
- /* TODO: if we ever do merge secret keys, make sure to handle
- the sec_to_pub_keyblock feature as well. */
- }
- else
- log_error( _("key %08lX: secret key not found: %s\n"),
- (ulong)keyid[1], gpg_strerror (rc));
-
- return rc;
-}
-
-
-/****************
- * Import a revocation certificate; this is a single signature packet.
- */
-static int
-import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats )
-{
- PKT_public_key *pk=NULL;
- KBNODE onode, keyblock = NULL;
- KEYDB_HANDLE hd = NULL;
- u32 keyid[2];
- int rc = 0;
-
- assert( !node->next );
- assert( node->pkt->pkttype == PKT_SIGNATURE );
- assert( node->pkt->pkt.signature->sig_class == 0x20 );
-
- keyid[0] = node->pkt->pkt.signature->keyid[0];
- keyid[1] = node->pkt->pkt.signature->keyid[1];
-
- pk = xcalloc (1, sizeof *pk );
- rc = get_pubkey( pk, keyid );
- if( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY ) {
- log_error ( _("key %08lX: no public key - "
- "can't apply revocation certificate\n"), (ulong)keyid[1]);
- rc = 0;
- goto leave;
- }
- else if( rc ) {
- log_error( _("key %08lX: public key not found: %s\n"),
- (ulong)keyid[1], gpg_strerror (rc));
- goto leave;
- }
-
- /* read the original keyblock */
- hd = keydb_new (0);
- {
- byte afp[MAX_FINGERPRINT_LEN];
- size_t an;
-
- fingerprint_from_pk (pk, afp, &an);
- while (an < MAX_FINGERPRINT_LEN)
- afp[an++] = 0;
- rc = keydb_search_fpr (hd, afp);
- }
- if (rc) {
- log_error (_("key %08lX: can't locate original keyblock: %s\n"),
- (ulong)keyid[1], gpg_strerror (rc));
- goto leave;
- }
- rc = keydb_get_keyblock (hd, &keyblock );
- if (rc) {
- log_error (_("key %08lX: can't read original keyblock: %s\n"),
- (ulong)keyid[1], gpg_strerror (rc));
- goto leave;
- }
-
-
- /* it is okay, that node is not in keyblock because
- * check_key_signature works fine for sig_class 0x20 in this
- * special case. */
- rc = check_key_signature( keyblock, node, NULL);
- if( rc ) {
- log_error( _("key %08lX: invalid revocation certificate"
- ": %s - rejected\n"), (ulong)keyid[1], gpg_strerror (rc));
- goto leave;
- }
-
-
- /* check whether we already have this */
- for(onode=keyblock->next; onode; onode=onode->next ) {
- if( onode->pkt->pkttype == PKT_USER_ID )
- break;
- else if( onode->pkt->pkttype == PKT_SIGNATURE
- && !cmp_signatures(node->pkt->pkt.signature,
- onode->pkt->pkt.signature))
- {
- rc = 0;
- goto leave; /* yes, we already know about it */
- }
- }
-
-
- /* insert it */
- insert_kbnode( keyblock, clone_kbnode(node), 0 );
-
- /* and write the keyblock back */
- rc = keydb_update_keyblock (hd, keyblock );
- if (rc)
- log_error (_("error writing keyring `%s': %s\n"),
- keydb_get_resource_name (hd), gpg_strerror (rc) );
- keydb_release (hd); hd = NULL;
- /* we are ready */
- if( !opt.quiet ) {
- char *p=get_user_id_printable (keyid);
- log_info( _("key %08lX: \"%s\" revocation certificate imported\n"),
- (ulong)keyid[1],p);
- xfree (p);
- }
- stats->n_revoc++;
-
- /* If the key we just revoked was ultimately trusted, remove its
- ultimate trust. This doesn't stop the user from putting the
- ultimate trust back, but is a reasonable solution for now. */
- if(get_ownertrust(pk)==TRUST_ULTIMATE)
- clear_ownertrusts(pk);
-
- revalidation_mark ();
-
- leave:
- keydb_release (hd);
- release_kbnode( keyblock );
- free_public_key( pk );
- return rc;
-}
-
-
-/****************
- * loop over the keyblock and check all self signatures.
- * Mark all user-ids with a self-signature by setting flag bit 0.
- * Mark all user-ids with an invalid self-signature by setting bit 1.
- * This works also for subkeys, here the subkey is marked. Invalid or
- * extra subkey sigs (binding or revocation) are marked for deletion.
- * non_self is set to true if there are any sigs other than self-sigs
- * in this keyblock.
- */
-static int
-chk_self_sigs( const char *fname, KBNODE keyblock,
- PKT_public_key *pk, u32 *keyid, int *non_self )
-{
- KBNODE n,knode=NULL;
- PKT_signature *sig;
- int rc;
- u32 bsdate=0,rsdate=0;
- KBNODE bsnode=NULL,rsnode=NULL;
-
- for( n=keyblock; (n = find_next_kbnode(n, 0)); ) {
- if(n->pkt->pkttype==PKT_PUBLIC_SUBKEY)
- {
- knode=n;
- bsdate=0;
- rsdate=0;
- bsnode=NULL;
- rsnode=NULL;
- continue;
- }
- else if( n->pkt->pkttype != PKT_SIGNATURE )
- continue;
- sig = n->pkt->pkt.signature;
- if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
-
- /* This just caches the sigs for later use. That way we
- import a fully-cached key which speeds things up. */
- if(!opt.no_sig_cache)
- check_key_signature(keyblock,n,NULL);
-
- if( (sig->sig_class&~3) == 0x10 ) {
- KBNODE unode = find_prev_kbnode( keyblock, n, PKT_USER_ID );
- if( !unode ) {
- log_error( _("key %08lX: no user ID for signature\n"),
- (ulong)keyid[1]);
- return -1; /* the complete keyblock is invalid */
- }
-
- /* If it hasn't been marked valid yet, keep trying */
- if(!(unode->flag&1)) {
- rc = check_key_signature( keyblock, n, NULL);
- if( rc )
- {
- if (opt.verbose)
- {
- char *p=utf8_to_native(unode->pkt->pkt.user_id->name,
- strlen(unode->pkt->pkt.user_id->name),0);
- log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
- _("key %08lX: unsupported public key "
- "algorithm on user id \"%s\"\n"):
- _("key %08lX: invalid self-signature "
- "on user id \"%s\"\n"),
- (ulong)keyid[1],p);
- xfree (p);
- }
- }
- else
- unode->flag |= 1; /* mark that signature checked */
- }
- }
- else if( sig->sig_class == 0x18 ) {
- /* Note that this works based solely on the timestamps
- like the rest of gpg. If the standard gets
- revocation targets, this may need to be revised. */
-
- if( !knode )
- {
- if (opt.verbose)
- log_info( _("key %08lX: no subkey for subkey "
- "binding signature\n"),(ulong)keyid[1]);
- n->flag |= 4; /* delete this */
- }
- else
- {
- rc = check_key_signature( keyblock, n, NULL);
- if( rc )
- {
- if (opt.verbose)
- log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
- _("key %08lX: unsupported public key algorithm\n"):
- _("key %08lX: invalid subkey binding\n"),
- (ulong)keyid[1]);
- n->flag|=4;
- }
- else
- {
- /* It's valid, so is it newer? */
- if(sig->timestamp>=bsdate)
- {
- knode->flag |= 1; /* the subkey is valid */
- if(bsnode)
- {
- bsnode->flag|=4; /* Delete the last binding
- sig since this one is
- newer */
- if (opt.verbose)
- log_info(_("key %08lX: removed multiple "
- "subkey binding\n"),
- (ulong)keyid[1]);
- }
-
- bsnode=n;
- bsdate=sig->timestamp;
- }
- else
- n->flag|=4; /* older */
- }
- }
- }
- else if( sig->sig_class == 0x28 ) {
- /* We don't actually mark the subkey as revoked right
- now, so just check that the revocation sig is the
- most recent valid one. Note that we don't care if
- the binding sig is newer than the revocation sig.
- See the comment in getkey.c:merge_selfsigs_subkey for
- more */
- if( !knode ) {
- if (opt.verbose)
- log_info( _("key %08lX: no subkey for subkey "
- "revocation signature\n"),(ulong)keyid[1]);
- n->flag |= 4; /* delete this */
- }
- else {
- rc = check_key_signature( keyblock, n, NULL);
- if( rc ) {
- if (opt.verbose)
- log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
- _("key %08lX: unsupported public key algorithm\n"):
- _("key %08lX: invalid subkey revocation\n"),
- (ulong)keyid[1]);
- n->flag|=4;
- }
- else {
- /* It's valid, so is it newer? */
- if(sig->timestamp>=rsdate) {
- if(rsnode) {
- rsnode->flag|=4; /* Delete the last revocation
- sig since this one is
- newer */
- if (opt.verbose)
- log_info(_("key %08lX: removed multiple subkey "
- "revocation signatures\n"),
- (ulong)keyid[1]);
- }
-
- rsnode=n;
- rsdate=sig->timestamp;
- }
- else
- n->flag|=4; /* older */
- }
- }
- }
- }
- else
- *non_self=1;
- }
-
- return 0;
-}
-
-/****************
- * delete all parts which are invalid and those signatures whose
- * public key algorithm is not available in this implemenation;
- * but consider RSA as valid, because parse/build_packets knows
- * about it.
- * returns: true if at least one valid user-id is left over.
- */
-static int
-delete_inv_parts( const char *fname, KBNODE keyblock,
- u32 *keyid, unsigned int options)
-{
- KBNODE node;
- int nvalid=0, uid_seen=0, subkey_seen=0;
-
- for(node=keyblock->next; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_USER_ID ) {
- uid_seen = 1;
- if( (node->flag & 2) || !(node->flag & 1) ) {
- if( opt.verbose ) {
- log_info( _("key %08lX: skipped user ID '"),
- (ulong)keyid[1]);
- print_utf8_string( stderr, node->pkt->pkt.user_id->name,
- node->pkt->pkt.user_id->len );
- fputs("'\n", stderr );
- }
- delete_kbnode( node ); /* the user-id */
- /* and all following packets up to the next user-id */
- while( node->next
- && node->next->pkt->pkttype != PKT_USER_ID
- && node->next->pkt->pkttype != PKT_PUBLIC_SUBKEY
- && node->next->pkt->pkttype != PKT_SECRET_SUBKEY ){
- delete_kbnode( node->next );
- node = node->next;
- }
- }
- else
- nvalid++;
- }
- else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- if( (node->flag & 2) || !(node->flag & 1) ) {
- if( opt.verbose ) {
- log_info( _("key %08lX: skipped subkey\n"),
- (ulong)keyid[1]);
- }
- delete_kbnode( node ); /* the subkey */
- /* and all following signature packets */
- while( node->next
- && node->next->pkt->pkttype == PKT_SIGNATURE ) {
- delete_kbnode( node->next );
- node = node->next;
- }
- }
- else
- subkey_seen = 1;
- }
- else if( node->pkt->pkttype == PKT_SIGNATURE
- && openpgp_pk_test_algo( node->pkt->pkt.signature
- ->pubkey_algo, 0)
- && node->pkt->pkt.signature->pubkey_algo != PUBKEY_ALGO_RSA )
- delete_kbnode( node ); /* build_packet() can't handle this */
- else if( node->pkt->pkttype == PKT_SIGNATURE &&
- !node->pkt->pkt.signature->flags.exportable &&
- !(options&IMPORT_ALLOW_LOCAL_SIGS) &&
- seckey_available( node->pkt->pkt.signature->keyid ) ) {
- /* Here we violate the rfc a bit by still allowing
- * to import non-exportable signature when we have the
- * the secret key used to create this signature - it
- * seems that this makes sense. */
- if (opt.verbose)
- log_info( _("key %08lX: non exportable signature "
- "(class %02x) - skipped\n"),
- (ulong)keyid[1],
- node->pkt->pkt.signature->sig_class );
- delete_kbnode( node );
- }
- else if( node->pkt->pkttype == PKT_SIGNATURE
- && node->pkt->pkt.signature->sig_class == 0x20 ) {
- if( uid_seen ) {
- if (opt.verbose)
- log_error( _("key %08lX: revocation certificate "
- "at wrong place - skipped\n"),
- (ulong)keyid[1]);
- delete_kbnode( node );
- }
- else {
- /* If the revocation cert is from a different key than
- the one we're working on don't check it - it's
- probably from a revocation key and won't be
- verifiable with this key anyway. */
-
- if(node->pkt->pkt.signature->keyid[0]==keyid[0] &&
- node->pkt->pkt.signature->keyid[1]==keyid[1])
- {
- int rc = check_key_signature( keyblock, node, NULL);
- if( rc )
- {
- if (opt.verbose)
- log_info ( _("key %08lX: invalid revocation "
- "certificate: %s - skipped\n"),
- (ulong)keyid[1], gpg_strerror (rc));
- delete_kbnode( node );
- }
- }
- }
- }
- else if( node->pkt->pkttype == PKT_SIGNATURE &&
- (node->pkt->pkt.signature->sig_class == 0x18 ||
- node->pkt->pkt.signature->sig_class == 0x28) &&
- !subkey_seen ) {
- if (opt.verbose)
- log_info ( _("key %08lX: subkey signature "
- "in wrong place - skipped\n"),
- (ulong)keyid[1]);
- delete_kbnode( node );
- }
- else if( node->pkt->pkttype == PKT_SIGNATURE
- && !IS_CERT(node->pkt->pkt.signature))
- {
- if (opt.verbose)
- log_info (_("key %08lX: unexpected signature class (0x%02X) -"
- " skipped\n"),(ulong)keyid[1],
- node->pkt->pkt.signature->sig_class);
- delete_kbnode(node);
- }
- else if( (node->flag & 4) ) /* marked for deletion */
- delete_kbnode( node );
- }
-
- /* note: because keyblock is the public key, it is never marked
- * for deletion and so keyblock cannot change */
- commit_kbnode( &keyblock );
- return nvalid;
-}
-
-
-/****************
- * It may happen that the imported keyblock has duplicated user IDs.
- * We check this here and collapse those user IDs together with their
- * sigs into one.
- * Returns: True if the keyblock hash changed.
- */
-int
-collapse_uids( KBNODE *keyblock )
-{
- KBNODE n, n2;
- int in_uid;
- int any=0;
- u32 kid1;
-
- restart:
- for( n = *keyblock; n; n = n->next ) {
- if( n->pkt->pkttype != PKT_USER_ID )
- continue;
- for( n2 = n->next; n2; n2 = n2->next ) {
- if( n2->pkt->pkttype == PKT_USER_ID
- && !cmp_user_ids( n->pkt->pkt.user_id,
- n2->pkt->pkt.user_id ) ) {
- /* found a duplicate */
- any = 1;
- if( !n2->next
- || n2->next->pkt->pkttype == PKT_USER_ID
- || n2->next->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || n2->next->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- /* no more signatures: delete the user ID
- * and start over */
- remove_kbnode( keyblock, n2 );
- }
- else {
- /* The simple approach: Move one signature and
- * then start over to delete the next one :-( */
- move_kbnode( keyblock, n2->next, n->next );
- }
- goto restart;
- }
- }
- }
- if( !any )
- return 0;
-
- restart_sig:
- /* now we may have duplicate signatures on one user ID: fix this */
- for( in_uid = 0, n = *keyblock; n; n = n->next ) {
- if( n->pkt->pkttype == PKT_USER_ID )
- in_uid = 1;
- else if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || n->pkt->pkttype == PKT_SECRET_SUBKEY )
- in_uid = 0;
- else if( in_uid ) {
- n2 = n;
- do {
- KBNODE ncmp = NULL;
- for( ; n2; n2 = n2->next ) {
- if( n2->pkt->pkttype == PKT_USER_ID
- || n2->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || n2->pkt->pkttype == PKT_SECRET_SUBKEY )
- break;
- if( n2->pkt->pkttype != PKT_SIGNATURE )
- ;
- else if( !ncmp )
- ncmp = n2;
- else if( !cmp_signatures( ncmp->pkt->pkt.signature,
- n2->pkt->pkt.signature )) {
- remove_kbnode( keyblock, n2 );
- goto restart_sig;
- }
- }
- n2 = ncmp? ncmp->next : NULL;
- } while( n2 );
- }
- }
-
- if( (n = find_kbnode( *keyblock, PKT_PUBLIC_KEY )) )
- kid1 = keyid_from_pk( n->pkt->pkt.public_key, NULL );
- else if( (n = find_kbnode( *keyblock, PKT_SECRET_KEY )) )
- kid1 = keyid_from_sk( n->pkt->pkt.secret_key, NULL );
- else
- kid1 = 0;
- if (!opt.quiet)
- log_info (_("key %08lX: duplicated user ID detected - merged\n"),
- (ulong)kid1);
-
- return 1;
-}
-
-/* Check for a 0x20 revocation from a revocation key that is not
- present. This gets called without the benefit of merge_xxxx so you
- can't rely on pk->revkey and friends. */
-static void
-revocation_present(KBNODE keyblock)
-{
- KBNODE onode,inode;
- PKT_public_key *pk=keyblock->pkt->pkt.public_key;
-
- for(onode=keyblock->next;onode;onode=onode->next)
- {
- /* If we reach user IDs, we're done. */
- if(onode->pkt->pkttype==PKT_USER_ID)
- break;
-
- if(onode->pkt->pkttype==PKT_SIGNATURE &&
- onode->pkt->pkt.signature->sig_class==0x1F &&
- onode->pkt->pkt.signature->revkey)
- {
- int idx;
- PKT_signature *sig=onode->pkt->pkt.signature;
-
- for(idx=0;idx<sig->numrevkeys;idx++)
- {
- u32 keyid[2];
-
- keyid_from_fingerprint(sig->revkey[idx]->fpr,
- MAX_FINGERPRINT_LEN,keyid);
-
- for(inode=keyblock->next;inode;inode=inode->next)
- {
- /* If we reach user IDs, we're done. */
- if(inode->pkt->pkttype==PKT_USER_ID)
- break;
-
- if(inode->pkt->pkttype==PKT_SIGNATURE &&
- inode->pkt->pkt.signature->sig_class==0x20 &&
- inode->pkt->pkt.signature->keyid[0]==keyid[0] &&
- inode->pkt->pkt.signature->keyid[1]==keyid[1])
- {
- /* Okay, we have a revocation key, and a
- revocation issued by it. Do we have the key
- itself? */
- int rc;
-
- rc=get_pubkey_byfprint_fast (NULL,sig->revkey[idx]->fpr,
- MAX_FINGERPRINT_LEN);
- if ( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
- || gpg_err_code (rc) == GPG_ERR_UNUSABLE_PUBKEY)
- {
- /* No, so try and get it */
- if(opt.keyserver_scheme &&
- opt.keyserver_options.auto_key_retrieve)
- {
- log_info(_("WARNING: key %08lX may be revoked: "
- "fetching revocation key %08lX\n"),
- (ulong)keyid_from_pk(pk,NULL),
- (ulong)keyid[1]);
- keyserver_import_fprint(sig->revkey[idx]->fpr,
- MAX_FINGERPRINT_LEN);
-
- /* Do we have it now? */
- rc=get_pubkey_byfprint_fast (NULL,
- sig->revkey[idx]->fpr,
- MAX_FINGERPRINT_LEN);
- }
-
- if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
- || gpg_err_code (rc) == GPG_ERR_UNUSABLE_PUBKEY)
- log_info(_("WARNING: key %08lX may be revoked: "
- "revocation key %08lX not present.\n"),
- (ulong)keyid_from_pk(pk,NULL),
- (ulong)keyid[1]);
- }
- }
- }
- }
- }
- }
-}
-
-/****************
- * compare and merge the blocks
- *
- * o compare the signatures: If we already have this signature, check
- * that they compare okay; if not, issue a warning and ask the user.
- * o Simply add the signature. Can't verify here because we may not have
- * the signature's public key yet; verification is done when putting it
- * into the trustdb, which is done automagically as soon as this pubkey
- * is used.
- * Note: We indicate newly inserted packets with flag bit 0
- */
-static int
-merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
- u32 *keyid, int *n_uids, int *n_sigs, int *n_subk )
-{
- KBNODE onode, node;
- int rc, found;
-
- /* 1st: handle revocation certificates */
- for(node=keyblock->next; node; node=node->next ) {
- if( node->pkt->pkttype == PKT_USER_ID )
- break;
- else if( node->pkt->pkttype == PKT_SIGNATURE
- && node->pkt->pkt.signature->sig_class == 0x20 ) {
- /* check whether we already have this */
- found = 0;
- for(onode=keyblock_orig->next; onode; onode=onode->next ) {
- if( onode->pkt->pkttype == PKT_USER_ID )
- break;
- else if( onode->pkt->pkttype == PKT_SIGNATURE
- && onode->pkt->pkt.signature->sig_class == 0x20
- && !cmp_signatures(onode->pkt->pkt.signature,
- node->pkt->pkt.signature))
- {
- found = 1;
- break;
- }
- }
- if( !found ) {
- KBNODE n2 = clone_kbnode(node);
- insert_kbnode( keyblock_orig, n2, 0 );
- n2->flag |= 1;
- ++*n_sigs;
-
- if (!opt.quiet)
- {
- char *p=get_user_id_printable (keyid);
- log_info(_("key %08lX: \"%s\" "
- "revocation certificate added\n"),
- (ulong)keyid[1],p);
- xfree (p);
- }
- }
- }
- }
-
- /* 2nd: merge in any direct key (0x1F) sigs */
- for(node=keyblock->next; node; node=node->next ) {
- if( node->pkt->pkttype == PKT_USER_ID )
- break;
- else if( node->pkt->pkttype == PKT_SIGNATURE
- && node->pkt->pkt.signature->sig_class == 0x1F ) {
- /* check whether we already have this */
- found = 0;
- for(onode=keyblock_orig->next; onode; onode=onode->next ) {
- if( onode->pkt->pkttype == PKT_USER_ID )
- break;
- else if( onode->pkt->pkttype == PKT_SIGNATURE
- && onode->pkt->pkt.signature->sig_class == 0x1F
- && !cmp_signatures(onode->pkt->pkt.signature,
- node->pkt->pkt.signature)) {
- found = 1;
- break;
- }
- }
- if( !found ) {
- KBNODE n2 = clone_kbnode(node);
- insert_kbnode( keyblock_orig, n2, 0 );
- n2->flag |= 1;
- ++*n_sigs;
- if (!opt.quiet)
- log_info( _("key %08lX: direct key signature added\n"),
- (ulong)keyid[1]);
- }
- }
- }
-
- /* 3rd: try to merge new certificates in */
- for(onode=keyblock_orig->next; onode; onode=onode->next ) {
- if( !(onode->flag & 1) && onode->pkt->pkttype == PKT_USER_ID) {
- /* find the user id in the imported keyblock */
- for(node=keyblock->next; node; node=node->next )
- if( node->pkt->pkttype == PKT_USER_ID
- && !cmp_user_ids( onode->pkt->pkt.user_id,
- node->pkt->pkt.user_id ) )
- break;
- if( node ) { /* found: merge */
- rc = merge_sigs( onode, node, n_sigs, fname, keyid );
- if( rc )
- return rc;
- }
- }
- }
-
- /* 4th: add new user-ids */
- for(node=keyblock->next; node; node=node->next ) {
- if( node->pkt->pkttype == PKT_USER_ID) {
- /* do we have this in the original keyblock */
- for(onode=keyblock_orig->next; onode; onode=onode->next )
- if( onode->pkt->pkttype == PKT_USER_ID
- && !cmp_user_ids( onode->pkt->pkt.user_id,
- node->pkt->pkt.user_id ) )
- break;
- if( !onode ) { /* this is a new user id: append */
- rc = append_uid( keyblock_orig, node, n_sigs, fname, keyid);
- if( rc )
- return rc;
- ++*n_uids;
- }
- }
- }
-
- /* 5th: add new subkeys */
- for(node=keyblock->next; node; node=node->next ) {
- onode = NULL;
- if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- /* do we have this in the original keyblock? */
- for(onode=keyblock_orig->next; onode; onode=onode->next )
- if( onode->pkt->pkttype == PKT_PUBLIC_SUBKEY
- && !cmp_public_keys( onode->pkt->pkt.public_key,
- node->pkt->pkt.public_key ) )
- break;
- if( !onode ) { /* this is a new subkey: append */
- rc = append_key( keyblock_orig, node, n_sigs, fname, keyid);
- if( rc )
- return rc;
- ++*n_subk;
- }
- }
- else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- /* do we have this in the original keyblock? */
- for(onode=keyblock_orig->next; onode; onode=onode->next )
- if( onode->pkt->pkttype == PKT_SECRET_SUBKEY
- && !cmp_secret_keys( onode->pkt->pkt.secret_key,
- node->pkt->pkt.secret_key ) )
- break;
- if( !onode ) { /* this is a new subkey: append */
- rc = append_key( keyblock_orig, node, n_sigs, fname, keyid);
- if( rc )
- return rc;
- ++*n_subk;
- }
- }
- }
-
- /* 6th: merge subkey certificates */
- for(onode=keyblock_orig->next; onode; onode=onode->next ) {
- if( !(onode->flag & 1)
- && ( onode->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || onode->pkt->pkttype == PKT_SECRET_SUBKEY) ) {
- /* find the subkey in the imported keyblock */
- for(node=keyblock->next; node; node=node->next ) {
- if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
- && !cmp_public_keys( onode->pkt->pkt.public_key,
- node->pkt->pkt.public_key ) )
- break;
- else if( node->pkt->pkttype == PKT_SECRET_SUBKEY
- && !cmp_secret_keys( onode->pkt->pkt.secret_key,
- node->pkt->pkt.secret_key ) )
- break;
- }
- if( node ) { /* found: merge */
- rc = merge_keysigs( onode, node, n_sigs, fname, keyid );
- if( rc )
- return rc;
- }
- }
- }
-
-
- return 0;
-}
-
-
-/****************
- * append the userid starting with NODE and all signatures to KEYBLOCK.
- */
-static int
-append_uid( KBNODE keyblock, KBNODE node, int *n_sigs,
- const char *fname, u32 *keyid )
-{
- KBNODE n, n_where=NULL;
-
- assert(node->pkt->pkttype == PKT_USER_ID );
-
- /* find the position */
- for( n = keyblock; n; n_where = n, n = n->next ) {
- if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || n->pkt->pkttype == PKT_SECRET_SUBKEY )
- break;
- }
- if( !n )
- n_where = NULL;
-
- /* and append/insert */
- while( node ) {
- /* we add a clone to the original keyblock, because this
- * one is released first */
- n = clone_kbnode(node);
- if( n_where ) {
- insert_kbnode( n_where, n, 0 );
- n_where = n;
- }
- else
- add_kbnode( keyblock, n );
- n->flag |= 1;
- node->flag |= 1;
- if( n->pkt->pkttype == PKT_SIGNATURE )
- ++*n_sigs;
-
- node = node->next;
- if( node && node->pkt->pkttype != PKT_SIGNATURE )
- break;
- }
-
- return 0;
-}
-
-
-/****************
- * Merge the sigs from SRC onto DST. SRC and DST are both a PKT_USER_ID.
- * (how should we handle comment packets here?)
- */
-static int
-merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
- const char *fname, u32 *keyid )
-{
- KBNODE n, n2;
- int found=0;
-
- assert(dst->pkt->pkttype == PKT_USER_ID );
- assert(src->pkt->pkttype == PKT_USER_ID );
-
- for(n=src->next; n && n->pkt->pkttype != PKT_USER_ID; n = n->next ) {
- if( n->pkt->pkttype != PKT_SIGNATURE )
- continue;
- if( n->pkt->pkt.signature->sig_class == 0x18
- || n->pkt->pkt.signature->sig_class == 0x28 )
- continue; /* skip signatures which are only valid on subkeys */
- found = 0;
- for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next)
- if(!cmp_signatures(n->pkt->pkt.signature,n2->pkt->pkt.signature))
- {
- found++;
- break;
- }
- if( !found ) {
- /* This signature is new or newer, append N to DST.
- * We add a clone to the original keyblock, because this
- * one is released first */
- n2 = clone_kbnode(n);
- insert_kbnode( dst, n2, PKT_SIGNATURE );
- n2->flag |= 1;
- n->flag |= 1;
- ++*n_sigs;
- }
- }
-
- return 0;
-}
-
-/****************
- * Merge the sigs from SRC onto DST. SRC and DST are both a PKT_xxx_SUBKEY.
- */
-static int
-merge_keysigs( KBNODE dst, KBNODE src, int *n_sigs,
- const char *fname, u32 *keyid )
-{
- KBNODE n, n2;
- int found=0;
-
- assert( dst->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || dst->pkt->pkttype == PKT_SECRET_SUBKEY );
-
- for(n=src->next; n ; n = n->next ) {
- if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || n->pkt->pkttype == PKT_PUBLIC_KEY )
- break;
- if( n->pkt->pkttype != PKT_SIGNATURE )
- continue;
- found = 0;
- for(n2=dst->next; n2; n2 = n2->next){
- if( n2->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || n2->pkt->pkttype == PKT_PUBLIC_KEY )
- break;
- if( n2->pkt->pkttype == PKT_SIGNATURE
- && n->pkt->pkt.signature->keyid[0]
- == n2->pkt->pkt.signature->keyid[0]
- && n->pkt->pkt.signature->keyid[1]
- == n2->pkt->pkt.signature->keyid[1]
- && n->pkt->pkt.signature->timestamp
- <= n2->pkt->pkt.signature->timestamp
- && n->pkt->pkt.signature->sig_class
- == n2->pkt->pkt.signature->sig_class ) {
- found++;
- break;
- }
- }
- if( !found ) {
- /* This signature is new or newer, append N to DST.
- * We add a clone to the original keyblock, because this
- * one is released first */
- n2 = clone_kbnode(n);
- insert_kbnode( dst, n2, PKT_SIGNATURE );
- n2->flag |= 1;
- n->flag |= 1;
- ++*n_sigs;
- }
- }
-
- return 0;
-}
-
-/****************
- * append the subkey starting with NODE and all signatures to KEYBLOCK.
- * Mark all new and copied packets by setting flag bit 0.
- */
-static int
-append_key( KBNODE keyblock, KBNODE node, int *n_sigs,
- const char *fname, u32 *keyid )
-{
- KBNODE n;
-
- assert( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || node->pkt->pkttype == PKT_SECRET_SUBKEY );
-
- while( node ) {
- /* we add a clone to the original keyblock, because this
- * one is released first */
- n = clone_kbnode(node);
- add_kbnode( keyblock, n );
- n->flag |= 1;
- node->flag |= 1;
- if( n->pkt->pkttype == PKT_SIGNATURE )
- ++*n_sigs;
-
- node = node->next;
- if( node && node->pkt->pkttype != PKT_SIGNATURE )
- break;
- }
-
- return 0;
-}
diff --git a/g10/kbnode.c b/g10/kbnode.c
deleted file mode 100644
index 58daad871..000000000
--- a/g10/kbnode.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/* kbnode.c - keyblock node utility functions
- * Copyright (C) 1998, 1999, 2000, 2001 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "memory.h"
-#include "packet.h"
-#include "keydb.h"
-
-#define USE_UNUSED_NODES 1
-
-static KBNODE unused_nodes;
-
-static KBNODE
-alloc_node(void)
-{
- KBNODE n;
-
- n = unused_nodes;
- if( n )
- unused_nodes = n->next;
- else
- n = xmalloc ( sizeof *n );
- n->next = NULL;
- n->pkt = NULL;
- n->flag = 0;
- n->private_flag=0;
- n->recno = 0;
- return n;
-}
-
-static void
-free_node( KBNODE n )
-{
- if( n ) {
-#if USE_UNUSED_NODES
- n->next = unused_nodes;
- unused_nodes = n;
-#else
- xfree ( n );
-#endif
- }
-}
-
-
-
-KBNODE
-new_kbnode( PACKET *pkt )
-{
- KBNODE n = alloc_node();
- n->pkt = pkt;
- return n;
-}
-
-
-KBNODE
-clone_kbnode( KBNODE node )
-{
- KBNODE n = alloc_node();
-
- n->pkt = node->pkt;
- n->private_flag = node->private_flag | 2; /* mark cloned */
- return n;
-}
-
-
-void
-release_kbnode( KBNODE n )
-{
- KBNODE n2;
-
- while( n ) {
- n2 = n->next;
- if( !is_cloned_kbnode(n) ) {
- free_packet( n->pkt );
- xfree ( n->pkt );
- }
- free_node( n );
- n = n2;
- }
-}
-
-
-/****************
- * Delete NODE.
- * Note: This only works with walk_kbnode!!
- */
-void
-delete_kbnode( KBNODE node )
-{
- node->private_flag |= 1;
-}
-
-
-
-/****************
- * Append NODE to ROOT. ROOT must exist!
- */
-void
-add_kbnode( KBNODE root, KBNODE node )
-{
- KBNODE n1;
-
- for(n1=root; n1->next; n1 = n1->next)
- ;
- n1->next = node;
-}
-
-/****************
- * Insert NODE into the list after root but before a packet which is not of
- * type PKTTYPE
- * (only if PKTTYPE != 0)
- */
-void
-insert_kbnode( KBNODE root, KBNODE node, int pkttype )
-{
- if( !pkttype ) {
- node->next = root->next;
- root->next = node;
- }
- else {
- KBNODE n1;
-
- for(n1=root; n1->next; n1 = n1->next)
- if( pkttype != n1->next->pkt->pkttype ) {
- node->next = n1->next;
- n1->next = node;
- return;
- }
- /* no such packet, append */
- node->next = NULL;
- n1->next = node;
- }
-}
-
-
-/****************
- * Find the previous node (if PKTTYPE = 0) or the previous node
- * with pkttype PKTTYPE in the list starting with ROOT of NODE.
- */
-KBNODE
-find_prev_kbnode( KBNODE root, KBNODE node, int pkttype )
-{
- KBNODE n1;
-
- for (n1=NULL; root && root != node; root = root->next ) {
- if (!pkttype ||root->pkt->pkttype == pkttype)
- n1 = root;
- }
- return n1;
-}
-
-/****************
- * Ditto, but find the next packet. The behaviour is trivial if
- * PKTTYPE is 0 but if it is specified, the next node with a packet
- * of this type is returned. The function has some knowledge about
- * the valid ordering of packets: e.g. if the next signature packet
- * is requested, the function will not return one if it encounters
- * a user-id.
- */
-KBNODE
-find_next_kbnode( KBNODE node, int pkttype )
-{
- for( node=node->next ; node; node = node->next ) {
- if( !pkttype )
- return node;
- else if( pkttype == PKT_USER_ID
- && ( node->pkt->pkttype == PKT_PUBLIC_KEY
- || node->pkt->pkttype == PKT_SECRET_KEY ) )
- return NULL;
- else if( pkttype == PKT_SIGNATURE
- && ( node->pkt->pkttype == PKT_USER_ID
- || node->pkt->pkttype == PKT_PUBLIC_KEY
- || node->pkt->pkttype == PKT_SECRET_KEY ) )
- return NULL;
- else if( node->pkt->pkttype == pkttype )
- return node;
- }
- return NULL;
-}
-
-
-KBNODE
-find_kbnode( KBNODE node, int pkttype )
-{
- for( ; node; node = node->next ) {
- if( node->pkt->pkttype == pkttype )
- return node;
- }
- return NULL;
-}
-
-
-
-/****************
- * Walk through a list of kbnodes. This function returns
- * the next kbnode for each call; before using the function the first
- * time, the caller must set CONTEXT to NULL (This has simply the effect
- * to start with ROOT).
- */
-KBNODE
-walk_kbnode( KBNODE root, KBNODE *context, int all )
-{
- KBNODE n;
-
- do {
- if( !*context ) {
- *context = root;
- n = root;
- }
- else {
- n = (*context)->next;
- *context = n;
- }
- } while( !all && n && is_deleted_kbnode(n) );
-
- return n;
-}
-
-void
-clear_kbnode_flags( KBNODE n )
-{
- for( ; n; n = n->next ) {
- n->flag = 0;
- }
-}
-
-
-/****************
- * Commit changes made to the kblist at ROOT. Note that ROOT my change,
- * and it is therefore passed by reference.
- * The function has the effect of removing all nodes marked as deleted.
- * returns true if any node has been changed
- */
-int
-commit_kbnode( KBNODE *root )
-{
- KBNODE n, nl;
- int changed = 0;
-
- for( n = *root, nl=NULL; n; n = nl->next ) {
- if( is_deleted_kbnode(n) ) {
- if( n == *root )
- *root = nl = n->next;
- else
- nl->next = n->next;
- if( !is_cloned_kbnode(n) ) {
- free_packet( n->pkt );
- xfree ( n->pkt );
- }
- free_node( n );
- changed = 1;
- }
- else
- nl = n;
- }
- return changed;
-}
-
-void
-remove_kbnode( KBNODE *root, KBNODE node )
-{
- KBNODE n, nl;
-
- for( n = *root, nl=NULL; n; n = nl->next ) {
- if( n == node ) {
- if( n == *root )
- *root = nl = n->next;
- else
- nl->next = n->next;
- if( !is_cloned_kbnode(n) ) {
- free_packet( n->pkt );
- xfree ( n->pkt );
- }
- free_node( n );
- }
- else
- nl = n;
- }
-}
-
-
-/****************
- * Move NODE behind right after WHERE or to the beginning if WHERE is NULL.
- */
-void
-move_kbnode( KBNODE *root, KBNODE node, KBNODE where )
-{
- KBNODE tmp, prev;
-
- if( !root || !*root || !node )
- return; /* sanity check */
- for( prev = *root; prev && prev->next != node; prev = prev->next )
- ;
- if( !prev )
- return; /* node is not in the list */
-
- if( !where ) { /* move node before root */
- if( node == *root ) /* move to itself */
- return;
- prev->next = node->next;
- node->next = *root;
- *root = node;
- return;
- }
- /* move it after where */
- if( node == where )
- return;
- tmp = node->next;
- node->next = where->next;
- where->next = node;
- prev->next = tmp;
-}
-
-
-
-
-void
-dump_kbnode( KBNODE node )
-{
- for(; node; node = node->next ) {
- const char *s;
- switch( node->pkt->pkttype ) {
- case 0: s="empty"; break;
- case PKT_PUBLIC_KEY: s="public-key"; break;
- case PKT_SECRET_KEY: s="secret-key"; break;
- case PKT_SECRET_SUBKEY: s= "secret-subkey"; break;
- case PKT_PUBKEY_ENC: s="public-enc"; break;
- case PKT_SIGNATURE: s="signature"; break;
- case PKT_ONEPASS_SIG: s="onepass-sig"; break;
- case PKT_USER_ID: s="user-id"; break;
- case PKT_PUBLIC_SUBKEY: s="public-subkey"; break;
- case PKT_COMMENT: s="comment"; break;
- case PKT_RING_TRUST: s="trust"; break;
- case PKT_PLAINTEXT: s="plaintext"; break;
- case PKT_COMPRESSED: s="compressed"; break;
- case PKT_ENCRYPTED: s="encrypted"; break;
- case PKT_GPG_CONTROL: s="gpg-control"; break;
- default: s="unknown"; break;
- }
- fprintf(stderr, "node %p %02x/%02x type=%s",
- node, node->flag, node->private_flag, s);
- if( node->pkt->pkttype == PKT_USER_ID ) {
- PKT_user_id *uid = node->pkt->pkt.user_id;
- fputs(" \"", stderr);
- print_string( stderr, uid->name, uid->len, 0 );
- fprintf (stderr, "\" %c%c%c%c\n",
- uid->is_expired? 'e':'.',
- uid->is_revoked? 'r':'.',
- uid->created? 'v':'.',
- uid->is_primary? 'p':'.' );
- }
- else if( node->pkt->pkttype == PKT_SIGNATURE ) {
- fprintf(stderr, " class=%02x keyid=%08lX ts=%lu\n",
- node->pkt->pkt.signature->sig_class,
- (ulong)node->pkt->pkt.signature->keyid[1],
- (ulong)node->pkt->pkt.signature->timestamp);
- }
- else if( node->pkt->pkttype == PKT_GPG_CONTROL ) {
- fprintf(stderr, " ctrl=%d len=%u\n",
- node->pkt->pkt.gpg_control->control,
- (unsigned int)node->pkt->pkt.gpg_control->datalen);
- }
- else if( node->pkt->pkttype == PKT_PUBLIC_KEY
- || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- PKT_public_key *pk = node->pkt->pkt.public_key;
- fprintf(stderr, " keyid=%08lX a=%d u=%d %c%c%c%c\n",
- (ulong)keyid_from_pk( pk, NULL ),
- pk->pubkey_algo, pk->pubkey_usage,
- pk->has_expired? 'e':'.',
- pk->is_revoked? 'r':'.',
- pk->is_valid? 'v':'.',
- pk->mdc_feature? 'm':'.');
- }
- else
- fputs("\n", stderr);
- }
-}
diff --git a/g10/keydb.c b/g10/keydb.c
deleted file mode 100644
index b64f38cbc..000000000
--- a/g10/keydb.c
+++ /dev/null
@@ -1,725 +0,0 @@
-/* keydb.c - key database dispatcher
- * Copyright (C) 2001, 2002, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "options.h"
-#include "main.h" /*try_make_homedir ()*/
-#include "packet.h"
-#include "keyring.h"
-#include "keydb.h"
-#include "i18n.h"
-
-static int active_handles;
-
-typedef enum {
- KEYDB_RESOURCE_TYPE_NONE = 0,
- KEYDB_RESOURCE_TYPE_KEYRING
-} KeydbResourceType;
-#define MAX_KEYDB_RESOURCES 40
-
-struct resource_item {
- KeydbResourceType type;
- union {
- KEYRING_HANDLE kr;
- } u;
- void *token;
- int secret;
-};
-
-static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
-static int used_resources;
-static void *primary_keyring=NULL;
-
-struct keydb_handle {
- int locked;
- int found;
- int current;
- int used; /* items in active */
- struct resource_item active[MAX_KEYDB_RESOURCES];
-};
-
-
-static int lock_all (KEYDB_HANDLE hd);
-static void unlock_all (KEYDB_HANDLE hd);
-
-
-/*
- * Register a resource (which currently may only be a keyring file).
- * The first keyring which is added by this function is
- * created if it does not exist.
- * Note: this function may be called before secure memory is
- * available.
- * Flag 1 == force
- * Flag 2 == default
- */
-int
-keydb_add_resource (const char *url, int flags, int secret)
-{
- static int any_secret, any_public;
- const char *resname = url;
- iobuf_t iobuf = NULL;
- char *filename = NULL;
- int force=(flags&1);
- int rc = 0;
- KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
- void *token;
-
- /* Do we have an URL?
- * gnupg-ring:filename := this is a plain keyring
- * filename := See what is is, but create as plain keyring.
- */
- if (strlen (resname) > 11) {
- if (!strncmp( resname, "gnupg-ring:", 11) ) {
- rt = KEYDB_RESOURCE_TYPE_KEYRING;
- resname += 11;
- }
-#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
- else if (strchr (resname, ':')) {
- log_error ("invalid key resource URL `%s'\n", url );
- rc = GPG_ERR_GENERAL;
- goto leave;
- }
-#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
- }
-
- if (*resname != DIRSEP_C ) { /* do tilde expansion etc */
- if (strchr(resname, DIRSEP_C) )
- filename = make_filename (resname, NULL);
- else
- filename = make_filename (opt.homedir, resname, NULL);
- }
- else
- filename = xstrdup (resname);
-
- if (!force)
- force = secret? !any_secret : !any_public;
-
- /* see whether we can determine the filetype */
- if (rt == KEYDB_RESOURCE_TYPE_NONE) {
- FILE *fp = fopen( filename, "rb" );
-
- if (fp) {
- u32 magic;
-
- if (fread( &magic, 4, 1, fp) == 1 ) {
- if (magic == 0x13579ace || magic == 0xce9a5713)
- ; /* GDBM magic - no more support */
- else
- rt = KEYDB_RESOURCE_TYPE_KEYRING;
- }
- else /* maybe empty: assume ring */
- rt = KEYDB_RESOURCE_TYPE_KEYRING;
- fclose( fp );
- }
- else /* no file yet: create ring */
- rt = KEYDB_RESOURCE_TYPE_KEYRING;
- }
-
- switch (rt) {
- case KEYDB_RESOURCE_TYPE_NONE:
- log_error ("unknown type of key resource `%s'\n", url );
- rc = GPG_ERR_GENERAL;
- goto leave;
-
- case KEYDB_RESOURCE_TYPE_KEYRING:
- if (access(filename, F_OK))
- { /* file does not exist */
- mode_t oldmask;
- char *last_slash_in_filename;
-
- if (!force)
- {
- rc = gpg_error_from_errno (errno);
- goto leave;
- }
-
- last_slash_in_filename = strrchr (filename, DIRSEP_C);
- *last_slash_in_filename = 0;
- if (access(filename, F_OK))
- { /* On the first time we try to create the default
- homedir and check again. */
- static int tried;
-
- if (!tried)
- {
- tried = 1;
- try_make_homedir (filename);
- }
- if (access (filename, F_OK))
- {
- rc = gpg_error_from_errno (errno);
- *last_slash_in_filename = DIRSEP_C;
- goto leave;
- }
- }
- *last_slash_in_filename = DIRSEP_C;
-
- oldmask=umask(077);
- iobuf = iobuf_create (filename);
- umask(oldmask);
- if (!iobuf)
- {
- log_error ( _("error creating keyring `%s': %s\n"),
- filename, strerror(errno));
- rc = gpg_error_from_errno (errno);
- goto leave;
- }
-
- if (!opt.quiet)
- log_info (_("keyring `%s' created\n"), filename);
- iobuf_close (iobuf);
- iobuf = NULL;
- /* must invalidate that ugly cache */
- iobuf_ioctl (NULL, 2, 0, (char*)filename);
- } /* end file creation */
-
- if(keyring_register_filename (filename, secret, &token))
- {
- if (used_resources >= MAX_KEYDB_RESOURCES)
- rc = GPG_ERR_RESOURCE_LIMIT;
- else
- {
- if(flags&2)
- primary_keyring=token;
- all_resources[used_resources].type = rt;
- all_resources[used_resources].u.kr = NULL; /* Not used here */
- all_resources[used_resources].token = token;
- all_resources[used_resources].secret = secret;
- used_resources++;
- }
- }
- else
- {
- /* This keyring was already registered, so ignore it.
- However, we can still mark it as primary even if it was
- already registered. */
- if(flags&2)
- primary_keyring=token;
- }
- break;
-
- default:
- log_error ("resource type of `%s' not supported\n", url);
- rc = GPG_ERR_GENERAL;
- goto leave;
- }
-
- /* fixme: check directory permissions and print a warning */
-
- leave:
- if (rc)
- log_error ("keyblock resource `%s': %s\n", filename, gpg_strerror (rc));
- else if (secret)
- any_secret = 1;
- else
- any_public = 1;
- xfree (filename);
- return rc;
-}
-
-
-
-
-KEYDB_HANDLE
-keydb_new (int secret)
-{
- KEYDB_HANDLE hd;
- int i, j;
-
- hd = xcalloc (1,sizeof *hd);
- hd->found = -1;
-
- assert (used_resources <= MAX_KEYDB_RESOURCES);
- for (i=j=0; i < used_resources; i++)
- {
- if (!all_resources[i].secret != !secret)
- continue;
- switch (all_resources[i].type)
- {
- case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- hd->active[j].type = all_resources[i].type;
- hd->active[j].token = all_resources[i].token;
- hd->active[j].secret = all_resources[i].secret;
- hd->active[j].u.kr = keyring_new (all_resources[i].token, secret);
- if (!hd->active[j].u.kr) {
- xfree (hd);
- return NULL; /* fixme: release all previously allocated handles*/
- }
- j++;
- break;
- }
- }
- hd->used = j;
-
- active_handles++;
- return hd;
-}
-
-void
-keydb_release (KEYDB_HANDLE hd)
-{
- int i;
-
- if (!hd)
- return;
- assert (active_handles > 0);
- active_handles--;
-
- unlock_all (hd);
- for (i=0; i < hd->used; i++) {
- switch (hd->active[i].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- keyring_release (hd->active[i].u.kr);
- break;
- }
- }
-
- xfree (hd);
-}
-
-
-/*
- * Return the name of the current resource. This is function first
- * looks for the last found found, then for the current search
- * position, and last returns the first available resource. The
- * returned string is only valid as long as the handle exists. This
- * function does only return NULL if no handle is specified, in all
- * other error cases an empty string is returned.
- */
-const char *
-keydb_get_resource_name (KEYDB_HANDLE hd)
-{
- int idx;
- const char *s = NULL;
-
- if (!hd)
- return NULL;
-
- if ( hd->found >= 0 && hd->found < hd->used)
- idx = hd->found;
- else if ( hd->current >= 0 && hd->current < hd->used)
- idx = hd->current;
- else
- idx = 0;
-
- switch (hd->active[idx].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- s = NULL;
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- s = keyring_get_resource_name (hd->active[idx].u.kr);
- break;
- }
-
- return s? s: "";
-}
-
-
-
-static int
-lock_all (KEYDB_HANDLE hd)
-{
- int i, rc = 0;
-
- for (i=0; !rc && i < hd->used; i++) {
- switch (hd->active[i].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_lock (hd->active[i].u.kr, 1);
- break;
- }
- }
-
- if (rc) {
- /* revert the already set locks */
- for (i--; i >= 0; i--) {
- switch (hd->active[i].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- keyring_lock (hd->active[i].u.kr, 0);
- break;
- }
- }
- }
- else
- hd->locked = 1;
-
- return rc;
-}
-
-static void
-unlock_all (KEYDB_HANDLE hd)
-{
- int i;
-
- if (!hd->locked)
- return;
-
- for (i=hd->used-1; i >= 0; i--) {
- switch (hd->active[i].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- keyring_lock (hd->active[i].u.kr, 0);
- break;
- }
- }
- hd->locked = 0;
-}
-
-
-/*
- * Return the last found keyring. Caller must free it.
- * The returned keyblock has the kbode flag bit 0 set for the node with
- * the public key used to locate the keyblock or flag bit 1 set for
- * the user ID node.
- */
-int
-keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
-{
- int rc = 0;
-
- if (!hd)
- return GPG_ERR_INV_ARG;
-
- if ( hd->found < 0 || hd->found >= hd->used)
- return -1; /* nothing found */
-
- switch (hd->active[hd->found].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- rc = GPG_ERR_GENERAL; /* oops */
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
- break;
- }
-
- return rc;
-}
-
-/*
- * update the current keyblock with KB
- */
-int
-keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
-{
- int rc = 0;
-
- if (!hd)
- return GPG_ERR_INV_ARG;
-
- if ( hd->found < 0 || hd->found >= hd->used)
- return -1; /* nothing found */
-
- if( opt.dry_run )
- return 0;
-
- rc = lock_all (hd);
- if (rc)
- return rc;
-
- switch (hd->active[hd->found].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- rc = GPG_ERR_GENERAL; /* oops */
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
- break;
- }
-
- unlock_all (hd);
- return rc;
-}
-
-
-/*
- * Insert a new KB into one of the resources.
- */
-int
-keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
-{
- int rc = -1;
- int idx;
-
- if (!hd)
- return GPG_ERR_INV_ARG;
-
- if( opt.dry_run )
- return 0;
-
- if ( hd->found >= 0 && hd->found < hd->used)
- idx = hd->found;
- else if ( hd->current >= 0 && hd->current < hd->used)
- idx = hd->current;
- else
- return GPG_ERR_GENERAL;
-
- rc = lock_all (hd);
- if (rc)
- return rc;
-
- switch (hd->active[idx].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- rc = GPG_ERR_GENERAL; /* oops */
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb);
- break;
- }
-
- unlock_all (hd);
- return rc;
-}
-
-
-/*
- * The current keyblock will be deleted.
- */
-int
-keydb_delete_keyblock (KEYDB_HANDLE hd)
-{
- int rc = -1;
-
- if (!hd)
- return GPG_ERR_INV_ARG;
-
- if ( hd->found < 0 || hd->found >= hd->used)
- return -1; /* nothing found */
-
- if( opt.dry_run )
- return 0;
-
- rc = lock_all (hd);
- if (rc)
- return rc;
-
- switch (hd->active[hd->found].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- rc = GPG_ERR_GENERAL; /* oops */
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_delete_keyblock (hd->active[hd->found].u.kr);
- break;
- }
-
- unlock_all (hd);
- return rc;
-}
-
-
-/*
- * Locate the default writable key resource, so that the next
- * operation (which is only relevant for inserts) will be done on this
- * resource.
- */
-int
-keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
-{
- int rc;
-
- if (!hd)
- return GPG_ERR_INV_ARG;
-
- rc = keydb_search_reset (hd); /* this does reset hd->current */
- if (rc)
- return rc;
-
- /* If we have a primary set, try that one first */
- if(primary_keyring)
- {
- for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
- {
- if(hd->active[hd->current].token==primary_keyring)
- {
- if(keyring_is_writable (hd->active[hd->current].token))
- return 0;
- else
- break;
- }
- }
-
- rc = keydb_search_reset (hd); /* this does reset hd->current */
- if (rc)
- return rc;
- }
-
- for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
- {
- switch (hd->active[hd->current].type)
- {
- case KEYDB_RESOURCE_TYPE_NONE:
- BUG();
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- if (keyring_is_writable (hd->active[hd->current].token))
- return 0; /* found (hd->current is set to it) */
- break;
- }
- }
-
- return -1;
-}
-
-/*
- * Rebuild the caches of all key resources.
- */
-void
-keydb_rebuild_caches (void)
-{
- int i, rc;
-
- for (i=0; i < used_resources; i++)
- {
- if (all_resources[i].secret)
- continue;
- switch (all_resources[i].type)
- {
- case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_rebuild_cache (all_resources[i].token);
- if (rc)
- log_error (_("failed to rebuild keyring cache: %s\n"),
- gpg_strerror (rc));
- break;
- }
- }
-}
-
-
-
-/*
- * Start the next search on this handle right at the beginning
- */
-int
-keydb_search_reset (KEYDB_HANDLE hd)
-{
- int i, rc = 0;
-
- if (!hd)
- return GPG_ERR_INV_ARG;
-
- hd->current = 0;
- hd->found = -1;
- /* and reset all resources */
- for (i=0; !rc && i < hd->used; i++) {
- switch (hd->active[i].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_search_reset (hd->active[i].u.kr);
- break;
- }
- }
- return rc;
-}
-
-
-/*
- * Search through all keydb resources, starting at the current position,
- * for a keyblock which contains one of the keys described in the DESC array.
- */
-int
-keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
- size_t ndesc, size_t *descindex)
-{
- int rc = -1;
-
- if (!hd)
- return GPG_ERR_INV_ARG;
-
- while (rc == -1 && hd->current >= 0 && hd->current < hd->used) {
- switch (hd->active[hd->current].type) {
- case KEYDB_RESOURCE_TYPE_NONE:
- BUG(); /* we should never see it here */
- break;
- case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_search (hd->active[hd->current].u.kr, desc,
- ndesc, descindex);
- break;
- }
- if (rc == -1) /* EOF -> switch to next resource */
- hd->current++;
- else if (!rc)
- hd->found = hd->current;
- }
-
- return rc;
-}
-
-int
-keydb_search_first (KEYDB_HANDLE hd)
-{
- KEYDB_SEARCH_DESC desc;
-
- memset (&desc, 0, sizeof desc);
- desc.mode = KEYDB_SEARCH_MODE_FIRST;
- return keydb_search (hd, &desc, 1);
-}
-
-int
-keydb_search_next (KEYDB_HANDLE hd)
-{
- KEYDB_SEARCH_DESC desc;
-
- memset (&desc, 0, sizeof desc);
- desc.mode = KEYDB_SEARCH_MODE_NEXT;
- return keydb_search (hd, &desc, 1);
-}
-
-int
-keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
-{
- KEYDB_SEARCH_DESC desc;
-
- memset (&desc, 0, sizeof desc);
- desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
- desc.u.kid[0] = kid[0];
- desc.u.kid[1] = kid[1];
- return keydb_search (hd, &desc, 1);
-}
-
-int
-keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
-{
- KEYDB_SEARCH_DESC desc;
-
- memset (&desc, 0, sizeof desc);
- desc.mode = KEYDB_SEARCH_MODE_FPR;
- memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN);
- return keydb_search (hd, &desc, 1);
-}
diff --git a/g10/keydb.h b/g10/keydb.h
deleted file mode 100644
index 4920e88a1..000000000
--- a/g10/keydb.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/* keydb.h - Key database
- * Copyright (C) 1998, 1999, 2000, 2001, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef G10_KEYDB_H
-#define G10_KEYDB_H
-
-#include "types.h"
-#include "global.h"
-#include "packet.h"
-#include "cipher.h"
-
-/* What qualifies as a certification (rather than a signature?) */
-#define IS_CERT(s) (IS_KEY_SIG(s) || IS_UID_SIG(s) || IS_SUBKEY_SIG(s) \
- || IS_KEY_REV(s) || IS_UID_REV(s) || IS_SUBKEY_REV(s))
-#define IS_SIG(s) (!IS_CERT(s))
-#define IS_KEY_SIG(s) ((s)->sig_class == 0x1f)
-#define IS_UID_SIG(s) (((s)->sig_class & ~3) == 0x10)
-#define IS_SUBKEY_SIG(s) ((s)->sig_class == 0x18)
-#define IS_KEY_REV(s) ((s)->sig_class == 0x20)
-#define IS_UID_REV(s) ((s)->sig_class == 0x30)
-#define IS_SUBKEY_REV(s) ((s)->sig_class == 0x28)
-
-struct getkey_ctx_s;
-typedef struct getkey_ctx_s *GETKEY_CTX;
-
-/****************
- * A Keyblock is all packets which form an entire certificate;
- * i.e. the public key, certificate, trust packets, user ids,
- * signatures, and subkey.
- *
- * This structure is also used to bind arbitrary packets together.
- */
-
-struct kbnode_struct {
- KBNODE next;
- PACKET *pkt;
- int flag;
- int private_flag;
- ulong recno; /* used while updating the trustdb */
-};
-
-#define is_deleted_kbnode(a) ((a)->private_flag & 1)
-#define is_cloned_kbnode(a) ((a)->private_flag & 2)
-
-
-enum resource_type {
- rt_UNKNOWN = 0,
- rt_RING = 1
-};
-
-
-/****************
- * A data structre to hold information about the external position
- * of a keyblock.
- */
-struct keyblock_pos_struct {
- int resno; /* resource number */
- enum resource_type rt;
- off_t offset; /* position information */
- unsigned count; /* length of the keyblock in packets */
- iobuf_t fp; /* used by enum_keyblocks */
- int secret; /* working on a secret keyring */
- PACKET *pkt; /* ditto */
- int valid;
-};
-typedef struct keyblock_pos_struct KBPOS;
-
-/* structure to hold a couple of public key certificates */
-typedef struct pk_list *PK_LIST;
-struct pk_list {
- PK_LIST next;
- PKT_public_key *pk;
- int flags; /* flag bit 1==throw_keyid */
-};
-
-/* structure to hold a couple of secret key certificates */
-typedef struct sk_list *SK_LIST;
-struct sk_list {
- SK_LIST next;
- PKT_secret_key *sk;
- int mark; /* not used */
-};
-
-/* structure to collect all information which can be used to
- * identify a public key */
-typedef struct pubkey_find_info *PUBKEY_FIND_INFO;
-struct pubkey_find_info {
- u32 keyid[2];
- unsigned nbits;
- byte pubkey_algo;
- byte fingerprint[MAX_FINGERPRINT_LEN];
- char userid[1];
-};
-
-
-typedef struct keydb_handle *KEYDB_HANDLE;
-
-typedef enum {
- KEYDB_SEARCH_MODE_NONE,
- KEYDB_SEARCH_MODE_EXACT,
- KEYDB_SEARCH_MODE_SUBSTR,
- KEYDB_SEARCH_MODE_MAIL,
- KEYDB_SEARCH_MODE_MAILSUB,
- KEYDB_SEARCH_MODE_MAILEND,
- KEYDB_SEARCH_MODE_WORDS,
- KEYDB_SEARCH_MODE_SHORT_KID,
- KEYDB_SEARCH_MODE_LONG_KID,
- KEYDB_SEARCH_MODE_FPR16,
- KEYDB_SEARCH_MODE_FPR20,
- KEYDB_SEARCH_MODE_FPR,
- KEYDB_SEARCH_MODE_FIRST,
- KEYDB_SEARCH_MODE_NEXT
-} KeydbSearchMode;
-
-struct keydb_search_desc {
- KeydbSearchMode mode;
- int (*skipfnc)(void *,u32*);
- void *skipfncvalue;
- union {
- const char *name;
- char fpr[MAX_FINGERPRINT_LEN];
- u32 kid[2];
- } u;
- int exact;
-};
-
-/*-- keydb.c --*/
-
-/*
- Flag 1 == force
- Flag 2 == default
-*/
-int keydb_add_resource (const char *url, int flags, int secret);
-KEYDB_HANDLE keydb_new (int secret);
-void keydb_release (KEYDB_HANDLE hd);
-const char *keydb_get_resource_name (KEYDB_HANDLE hd);
-int keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb);
-int keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb);
-int keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb);
-int keydb_delete_keyblock (KEYDB_HANDLE hd);
-int keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved);
-void keydb_rebuild_caches (void);
-int keydb_search_reset (KEYDB_HANDLE hd);
-#define keydb_search(a,b,c) keydb_search2((a),(b),(c),NULL)
-int keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
- size_t ndesc, size_t *descindex);
-int keydb_search_first (KEYDB_HANDLE hd);
-int keydb_search_next (KEYDB_HANDLE hd);
-int keydb_search_kid (KEYDB_HANDLE hd, u32 *kid);
-int keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr);
-
-
-/*-- pkclist.c --*/
-void show_revocation_reason( PKT_public_key *pk, int mode );
-int check_signatures_trust( PKT_signature *sig );
-void release_pk_list( PK_LIST pk_list );
-int build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use );
-int algo_available( preftype_t preftype, int algo, void *hint );
-int select_algo_from_prefs( PK_LIST pk_list, int preftype,
- int request, void *hint );
-int select_mdc_from_pklist (PK_LIST pk_list);
-
-/*-- skclist.c --*/
-void release_sk_list( SK_LIST sk_list );
-int build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list,
- int unlock, unsigned use );
-
-/*-- passphrase.h --*/
-int have_static_passphrase(void);
-void read_passphrase_from_fd( int fd );
-void passphrase_clear_cache ( u32 *keyid, int algo );
-DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo,
- int cipher_algo, STRING2KEY *s2k, int mode,
- const char *tryagain_text, int *canceled);
-void set_next_passphrase( const char *s );
-char *get_last_passphrase(void);
-
-/*-- getkey.c --*/
-int classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc);
-void cache_public_key( PKT_public_key *pk );
-void getkey_disable_caches(void);
-int get_pubkey( PKT_public_key *pk, u32 *keyid );
-int get_pubkey_fast ( PKT_public_key *pk, u32 *keyid );
-KBNODE get_pubkeyblock( u32 *keyid );
-int get_pubkey_byname( PKT_public_key *pk, const char *name,
- KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd,
- int include_disabled );
-int get_pubkey_bynames( GETKEY_CTX *rx, PKT_public_key *pk,
- STRLIST names, KBNODE *ret_keyblock );
-int get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock );
-void get_pubkey_end( GETKEY_CTX ctx );
-int get_seckey( PKT_secret_key *sk, u32 *keyid );
-int get_primary_seckey( PKT_secret_key *sk, u32 *keyid );
-int get_pubkey_byfprint( PKT_public_key *pk, const byte *fprint,
- size_t fprint_len );
-int get_pubkey_byfprint_fast (PKT_public_key *pk,
- const byte *fprint, size_t fprint_len);
-int get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint,
- size_t fprint_len );
-int get_keyblock_bylid( KBNODE *ret_keyblock, ulong lid );
-int seckey_available( u32 *keyid );
-int get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock );
-int get_seckey_bynames( GETKEY_CTX *rx, PKT_secret_key *sk,
- STRLIST names, KBNODE *ret_keyblock );
-int get_seckey_byfprint( PKT_secret_key *sk,
- const byte *fprint, size_t fprint_len);
-int get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock );
-void get_seckey_end( GETKEY_CTX ctx );
-int enum_secret_keys( void **context, PKT_secret_key *sk,
- int with_subkeys, int with_spm );
-void merge_keys_and_selfsig( KBNODE keyblock );
-char*get_user_id_string( u32 *keyid );
-char*get_user_id_string_printable( u32 *keyid );
-char*get_long_user_id_string( u32 *keyid );
-char*get_user_id( u32 *keyid, size_t *rn );
-char*get_user_id_printable( u32 *keyid );
-KEYDB_HANDLE get_ctx_handle(GETKEY_CTX ctx);
-
-/*-- keyid.c --*/
-int pubkey_letter( int algo );
-u32 v3_keyid (gcry_mpi_t a, u32 *ki);
-u32 keyid_from_sk( PKT_secret_key *sk, u32 *keyid );
-u32 keyid_from_pk( PKT_public_key *pk, u32 *keyid );
-u32 keyid_from_sig( PKT_signature *sig, u32 *keyid );
-u32 keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid );
-byte *namehash_from_uid(PKT_user_id *uid);
-unsigned nbits_from_pk( PKT_public_key *pk );
-unsigned nbits_from_sk( PKT_secret_key *sk );
-const char *datestr_from_pk( PKT_public_key *pk );
-const char *datestr_from_sk( PKT_secret_key *sk );
-const char *datestr_from_sig( PKT_signature *sig );
-const char *expirestr_from_pk( PKT_public_key *pk );
-const char *expirestr_from_sk( PKT_secret_key *sk );
-const char *expirestr_from_sig( PKT_signature *sig );
-
-const char *colon_strtime (u32 t);
-const char *colon_datestr_from_pk (PKT_public_key *pk);
-const char *colon_datestr_from_sk (PKT_secret_key *sk);
-const char *colon_datestr_from_sig (PKT_signature *sig);
-const char *colon_expirestr_from_sig (PKT_signature *sig);
-
-byte *fingerprint_from_sk( PKT_secret_key *sk, byte *buf, size_t *ret_len );
-byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
-
-char *serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
- PKT_secret_key *sk);
-
-
-/*-- kbnode.c --*/
-KBNODE new_kbnode( PACKET *pkt );
-KBNODE clone_kbnode( KBNODE node );
-void release_kbnode( KBNODE n );
-void delete_kbnode( KBNODE node );
-void add_kbnode( KBNODE root, KBNODE node );
-void insert_kbnode( KBNODE root, KBNODE node, int pkttype );
-void move_kbnode( KBNODE *root, KBNODE node, KBNODE where );
-void remove_kbnode( KBNODE *root, KBNODE node );
-KBNODE find_prev_kbnode( KBNODE root, KBNODE node, int pkttype );
-KBNODE find_next_kbnode( KBNODE node, int pkttype );
-KBNODE find_kbnode( KBNODE node, int pkttype );
-KBNODE walk_kbnode( KBNODE root, KBNODE *context, int all );
-void clear_kbnode_flags( KBNODE n );
-int commit_kbnode( KBNODE *root );
-void dump_kbnode( KBNODE node );
-
-#endif /*G10_KEYDB_H*/
diff --git a/g10/keyedit.c b/g10/keyedit.c
deleted file mode 100644
index 4da174e3c..000000000
--- a/g10/keyedit.c
+++ /dev/null
@@ -1,3856 +0,0 @@
-/* keyedit.c - keyedit stuff
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <ctype.h>
-
-#include "gpg.h"
-#include "options.h"
-#include "packet.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "keydb.h"
-#include "memory.h"
-#include "photoid.h"
-#include "util.h"
-#include "main.h"
-#include "trustdb.h"
-#include "filter.h"
-#include "ttyio.h"
-#include "status.h"
-#include "i18n.h"
-
-static void show_prefs( PKT_user_id *uid, int verbose );
-static void show_key_with_all_names( KBNODE keyblock, int only_marked,
- int with_revoker, int with_fpr, int with_subkeys, int with_prefs );
-static void show_key_and_fingerprint( KBNODE keyblock );
-static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock, int photo );
-static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int menu_delsig( KBNODE pub_keyblock );
-static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int menu_addrevoker( KBNODE pub_keyblock,
- KBNODE sec_keyblock, int sensitive );
-static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int menu_select_uid( KBNODE keyblock, int idx );
-static int menu_select_key( KBNODE keyblock, int idx );
-static int count_uids( KBNODE keyblock );
-static int count_uids_with_flag( KBNODE keyblock, unsigned flag );
-static int count_keys_with_flag( KBNODE keyblock, unsigned flag );
-static int count_selected_uids( KBNODE keyblock );
-static int real_uids_left( KBNODE keyblock );
-static int count_selected_keys( KBNODE keyblock );
-static int menu_revsig( KBNODE keyblock );
-static int menu_revuid( KBNODE keyblock, KBNODE sec_keyblock );
-static int menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int enable_disable_key( KBNODE keyblock, int disable );
-static void menu_showphoto( KBNODE keyblock );
-
-static int update_trust=0;
-
-#define CONTROL_D ('D' - 'A' + 1)
-
-#define NODFLG_BADSIG (1<<0) /* bad signature */
-#define NODFLG_NOKEY (1<<1) /* no public key */
-#define NODFLG_SIGERR (1<<2) /* other sig error */
-
-#define NODFLG_MARK_A (1<<4) /* temporary mark */
-#define NODFLG_DELSIG (1<<5) /* to be deleted */
-
-#define NODFLG_SELUID (1<<8) /* indicate the selected userid */
-#define NODFLG_SELKEY (1<<9) /* indicate the selected key */
-#define NODFLG_SELSIG (1<<10) /* indicate a selected signature */
-
-struct sign_attrib {
- int non_exportable,non_revocable;
- struct revocation_reason_info *reason;
- byte trust_depth,trust_value;
- char *trust_regexp;
-};
-
-/****************
- * Print information about a signature, check it and return true
- * if the signature is okay. NODE must be a signature packet.
- */
-static int
-print_and_check_one_sig( KBNODE keyblock, KBNODE node,
- int *inv_sigs, int *no_key, int *oth_err,
- int *is_selfsig, int print_without_key )
-{
- PKT_signature *sig = node->pkt->pkt.signature;
- int rc, sigrc;
- int is_rev = sig->sig_class == 0x30;
-
- /* TODO: Make sure a cached sig record here still has the pk that
- issued it. See also keylist.c:list_keyblock_print */
-
- rc = check_key_signature (keyblock, node, is_selfsig);
- switch ( gpg_err_code (rc) ) {
- case 0:
- node->flag &= ~(NODFLG_BADSIG|NODFLG_NOKEY|NODFLG_SIGERR);
- sigrc = '!';
- break;
- case GPG_ERR_BAD_SIGNATURE:
- node->flag = NODFLG_BADSIG;
- sigrc = '-';
- if( inv_sigs )
- ++*inv_sigs;
- break;
- case GPG_ERR_NO_PUBKEY:
- case GPG_ERR_UNUSABLE_PUBKEY:
- node->flag = NODFLG_NOKEY;
- sigrc = '?';
- if( no_key )
- ++*no_key;
- break;
- default:
- node->flag = NODFLG_SIGERR;
- sigrc = '%';
- if( oth_err )
- ++*oth_err;
- break;
- }
- if( sigrc != '?' || print_without_key ) {
- tty_printf("%s%c%c %c%c%c%c%c%c ",
- is_rev? "rev":"sig",sigrc,
- (sig->sig_class-0x10>0 &&
- sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ',
- sig->flags.exportable?' ':'L',
- sig->flags.revocable?' ':'R',
- sig->flags.policy_url?'P':' ',
- sig->flags.notation?'N':' ',
- sig->flags.expired?'X':' ',
- (sig->trust_depth>9)?'T':
- (sig->trust_depth>0)?'0'+sig->trust_depth:' ');
- if(opt.list_options&LIST_SHOW_LONG_KEYID)
- tty_printf("%08lX%08lX",(ulong)sig->keyid[0],(ulong)sig->keyid[1]);
- else
- tty_printf("%08lX",(ulong)sig->keyid[1]);
- tty_printf(" %s", datestr_from_sig(sig));
- if(opt.list_options&LIST_SHOW_SIG_EXPIRE)
- tty_printf(" %s",expirestr_from_sig(sig));
- tty_printf(" ");
- if( sigrc == '%' )
- tty_printf("[%s] ", gpg_strerror (rc) );
- else if( sigrc == '?' )
- ;
- else if( *is_selfsig ) {
- tty_printf( is_rev? _("[revocation]")
- : _("[self-signature]") );
- }
- else {
- size_t n;
- char *p = get_user_id( sig->keyid, &n );
- tty_print_utf8_string2( p, n, 40 );
- xfree (p);
- }
- tty_printf("\n");
-
- if(sig->flags.policy_url && (opt.list_options&LIST_SHOW_POLICY))
- show_policy_url(sig,3,0);
-
- if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATION))
- show_notation(sig,3,0);
-
- if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER))
- show_keyserver_url(sig,3,0);
- }
-
- return (sigrc == '!');
-}
-
-
-
-/****************
- * Check the keysigs and set the flags to indicate errors.
- * Returns true if error found.
- */
-static int
-check_all_keysigs( KBNODE keyblock, int only_selected )
-{
- KBNODE kbctx;
- KBNODE node;
- int inv_sigs = 0;
- int no_key = 0;
- int oth_err = 0;
- int has_selfsig = 0;
- int mis_selfsig = 0;
- int selected = !only_selected;
- int anyuid = 0;
-
- for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
- if( node->pkt->pkttype == PKT_USER_ID ) {
- PKT_user_id *uid = node->pkt->pkt.user_id;
-
- if( only_selected )
- selected = (node->flag & NODFLG_SELUID);
- if( selected ) {
- tty_printf("uid ");
- tty_print_utf8_string( uid->name, uid->len );
- tty_printf("\n");
- if( anyuid && !has_selfsig )
- mis_selfsig++;
- has_selfsig = 0;
- anyuid = 1;
- }
- }
- else if( selected && node->pkt->pkttype == PKT_SIGNATURE
- && ( (node->pkt->pkt.signature->sig_class&~3) == 0x10
- || node->pkt->pkt.signature->sig_class == 0x30 ) ) {
- int selfsig;
-
- if( print_and_check_one_sig( keyblock, node, &inv_sigs,
- &no_key, &oth_err, &selfsig, 0 ) ) {
- if( selfsig )
- has_selfsig = 1;
- }
- /* Hmmm: should we update the trustdb here? */
- }
- }
- if( !has_selfsig )
- mis_selfsig++;
- if( inv_sigs == 1 )
- tty_printf(_("1 bad signature\n") );
- else if( inv_sigs )
- tty_printf(_("%d bad signatures\n"), inv_sigs );
- if( no_key == 1 )
- tty_printf(_("1 signature not checked due to a missing key\n") );
- else if( no_key )
- tty_printf(_("%d signatures not checked due to missing keys\n"), no_key );
- if( oth_err == 1 )
- tty_printf(_("1 signature not checked due to an error\n") );
- else if( oth_err )
- tty_printf(_("%d signatures not checked due to errors\n"), oth_err );
- if( mis_selfsig == 1 )
- tty_printf(_("1 user ID without valid self-signature detected\n"));
- else if( mis_selfsig )
- tty_printf(_("%d user IDs without valid self-signatures detected\n"),
- mis_selfsig);
-
- return inv_sigs || no_key || oth_err || mis_selfsig;
-}
-
-
-
-
-static int
-sign_mk_attrib( PKT_signature *sig, void *opaque )
-{
- struct sign_attrib *attrib = opaque;
- byte buf[8];
-
- if( attrib->non_exportable ) {
- buf[0] = 0; /* not exportable */
- build_sig_subpkt( sig, SIGSUBPKT_EXPORTABLE, buf, 1 );
- }
-
- if( attrib->non_revocable ) {
- buf[0] = 0; /* not revocable */
- build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 );
- }
-
- if( attrib->reason )
- revocation_reason_build_cb( sig, attrib->reason );
-
- if(attrib->trust_depth)
- {
- /* Not critical. If someone doesn't understand trust sigs,
- this can still be a valid regular signature. */
- buf[0] = attrib->trust_depth;
- buf[1] = attrib->trust_value;
- build_sig_subpkt(sig,SIGSUBPKT_TRUST,buf,2);
-
- /* Critical. If someone doesn't understands regexps, this
- whole sig should be invalid. Note the +1 for the length -
- regexps are null terminated. */
- if(attrib->trust_regexp)
- build_sig_subpkt(sig,SIGSUBPKT_FLAG_CRITICAL|SIGSUBPKT_REGEXP,
- attrib->trust_regexp,
- strlen(attrib->trust_regexp)+1);
- }
-
- return 0;
-}
-
-static void
-trustsig_prompt(byte *trust_value, byte *trust_depth, char **regexp)
-{
- char *p;
-
- *trust_value=0;
- *trust_depth=0;
- *regexp=NULL;
-
- tty_printf("\n");
- /* Same string as pkclist.c:do_edit_ownertrust */
- tty_printf(_(
- "Please decide how far you trust this user to correctly\n"
- "verify other users' keys (by looking at passports,\n"
- "checking fingerprints from different sources...)?\n\n"));
- tty_printf (_(" (%d) I trust marginally\n"), 1);
- tty_printf (_(" (%d) I trust fully\n"), 2);
- tty_printf("\n");
-
- while(*trust_value==0)
- {
- p = cpr_get("trustsig_prompt.trust_value",_("Your selection? "));
- trim_spaces(p);
- cpr_kill_prompt();
- /* 60 and 120 are as per RFC2440 */
- if(p[0]=='1' && !p[1])
- *trust_value=60;
- else if(p[0]=='2' && !p[1])
- *trust_value=120;
- xfree (p);
- }
-
- tty_printf("\n");
-
- tty_printf(_(
- "Please enter the depth of this trust signature.\n"
- "A depth greater than 1 allows the key you are signing to make\n"
- "trust signatures on your behalf.\n"));
- tty_printf("\n");
-
- while(*trust_depth==0)
- {
- p = cpr_get("trustsig_prompt.trust_depth",_("Your selection? "));
- trim_spaces(p);
- cpr_kill_prompt();
- *trust_depth=atoi(p);
- xfree (p);
- if(*trust_depth < 1 )
- *trust_depth=0;
- }
-
- tty_printf("\n");
-
- tty_printf(_("Please enter a domain to restrict this signature, "
- "or enter for none.\n"));
-
- tty_printf("\n");
-
- p=cpr_get("trustsig_prompt.trust_regexp",_("Your selection? "));
- trim_spaces(p);
- cpr_kill_prompt();
-
- if(strlen(p)>0)
- {
- char *q=p;
- int regexplen=100,ind;
-
- *regexp=xmalloc (regexplen);
-
- /* Now mangle the domain the user entered into a regexp. To do
- this, \-escape everything that isn't alphanumeric, and attach
- "<[^>]+[@.]" to the front, and ">$" to the end. */
-
- strcpy(*regexp,"<[^>]+[@.]");
- ind=strlen(*regexp);
-
- while(*q)
- {
- if(!((*q>='A' && *q<='Z')
- || (*q>='a' && *q<='z') || (*q>='0' && *q<='9')))
- (*regexp)[ind++]='\\';
-
- (*regexp)[ind++]=*q;
-
- if((regexplen-ind)<3)
- {
- regexplen+=100;
- *regexp=xrealloc(*regexp,regexplen);
- }
-
- q++;
- }
-
- (*regexp)[ind]='\0';
- strcat(*regexp,">$");
- }
-
- xfree (p);
- tty_printf("\n");
-}
-
-/****************
- * Loop over all locusr and and sign the uids after asking.
- * If no user id is marked, all user ids will be signed;
- * if some user_ids are marked those will be signed.
- */
-static int
-sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified,
- int local, int nonrevocable, int trust )
-{
- int rc = 0;
- SK_LIST sk_list = NULL;
- SK_LIST sk_rover = NULL;
- PKT_secret_key *sk = NULL;
- KBNODE node, uidnode;
- PKT_public_key *primary_pk=NULL;
- int select_all = !count_selected_uids(keyblock);
- int all_v3=1;
-
- /* Are there any non-v3 sigs on this key already? */
- if(PGP2)
- for(node=keyblock;node;node=node->next)
- if(node->pkt->pkttype==PKT_SIGNATURE &&
- node->pkt->pkt.signature->version>3)
- {
- all_v3=0;
- break;
- }
-
- /* build a list of all signators.
- *
- * We use the CERT flag to request the primary which must always
- * be one which is capable of signing keys. I can't see a reason
- * why to sign keys using a subkey. Implementation of USAGE_CERT
- * is just a hack in getkey.c and does not mean that a subkey
- * marked as certification capable will be used */
- rc=build_sk_list( locusr, &sk_list, 0, PUBKEY_USAGE_SIG|PUBKEY_USAGE_CERT);
- if( rc )
- goto leave;
-
- /* loop over all signators */
- for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
- u32 sk_keyid[2],pk_keyid[2];
- size_t n;
- char *p,*trust_regexp=NULL;
- int force_v4=0,class=0,selfsig=0;
- u32 duration=0,timestamp=0;
- byte trust_depth=0,trust_value=0;
-
- if(local || nonrevocable || trust ||
- opt.cert_policy_url || opt.cert_notation_data)
- force_v4=1;
-
- /* we have to use a copy of the sk, because make_keysig_packet
- * may remove the protection from sk and if we did other
- * changes to the secret key, we would save the unprotected
- * version */
- if( sk )
- free_secret_key(sk);
- sk = copy_secret_key( NULL, sk_rover->sk );
- keyid_from_sk( sk, sk_keyid );
- /* set mark A for all selected user ids */
- for( node=keyblock; node; node = node->next ) {
- if( select_all || (node->flag & NODFLG_SELUID) )
- node->flag |= NODFLG_MARK_A;
- else
- node->flag &= ~NODFLG_MARK_A;
- }
- /* reset mark for uids which are already signed */
- uidnode = NULL;
- for( node=keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
- primary_pk=node->pkt->pkt.public_key;
- keyid_from_pk( primary_pk, pk_keyid );
-
- /* Is this a self-sig? */
- if(pk_keyid[0]==sk_keyid[0] && pk_keyid[1]==sk_keyid[1])
- {
- selfsig=1;
- /* Do not force a v4 sig here, otherwise it would
- be difficult to remake a v3 selfsig. If this
- is a v3->v4 promotion case, then we set
- force_v4 later anyway. */
- force_v4=0;
- }
- }
- else if( node->pkt->pkttype == PKT_USER_ID ) {
- uidnode = (node->flag & NODFLG_MARK_A)? node : NULL;
- if(uidnode)
- {
- char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
- uidnode->pkt->pkt.user_id->len,
- 0);
-
- if(uidnode->pkt->pkt.user_id->is_revoked)
- {
- tty_printf(_("User ID \"%s\" is revoked."),user);
-
- if(opt.expert)
- {
- tty_printf("\n");
- /* No, so remove the mark and continue */
- if(!cpr_get_answer_is_yes("sign_uid.revoke_okay",
- _("Are you sure you "
- "still want to sign "
- "it? (y/N) ")))
- uidnode->flag &= ~NODFLG_MARK_A;
- }
- else
- {
- uidnode->flag &= ~NODFLG_MARK_A;
- tty_printf(_(" Unable to sign.\n"));
- }
- }
- else if(uidnode->pkt->pkt.user_id->is_expired)
- {
- tty_printf(_("User ID \"%s\" is expired."),user);
-
- if(opt.expert)
- {
- tty_printf("\n");
- /* No, so remove the mark and continue */
- if(!cpr_get_answer_is_yes("sign_uid.expire_okay",
- _("Are you sure you "
- "still want to sign "
- "it? (y/N) ")))
- uidnode->flag &= ~NODFLG_MARK_A;
- }
- else
- {
- uidnode->flag &= ~NODFLG_MARK_A;
- tty_printf(_(" Unable to sign.\n"));
- }
- }
- else if(!uidnode->pkt->pkt.user_id->created && !selfsig)
- {
- tty_printf(_("User ID \"%s\" is not self-signed."),
- user);
-
- if(opt.expert)
- {
- tty_printf("\n");
- /* No, so remove the mark and continue */
- if(!cpr_get_answer_is_yes("sign_uid.nosig_okay",
- _("Are you sure you "
- "still want to sign "
- "it? (y/N) ")))
- uidnode->flag &= ~NODFLG_MARK_A;
- }
- else
- {
- uidnode->flag &= ~NODFLG_MARK_A;
- tty_printf(_(" Unable to sign.\n"));
- }
- }
- xfree (user);
- }
- }
- else if( uidnode && node->pkt->pkttype == PKT_SIGNATURE
- && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
- if( sk_keyid[0] == node->pkt->pkt.signature->keyid[0]
- && sk_keyid[1] == node->pkt->pkt.signature->keyid[1] ) {
- char buf[50];
- char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
- uidnode->pkt->pkt.user_id->len,
- 0);
-
- /* It's a v3 self-sig. Make it into a v4 self-sig? */
- if(node->pkt->pkt.signature->version<4 && selfsig)
- {
- tty_printf(_("The self-signature on \"%s\"\n"
- "is a PGP 2.x-style signature.\n"),user);
-
- /* Note that the regular PGP2 warning below
- still applies if there are no v4 sigs on
- this key at all. */
-
- if(opt.expert)
- if(cpr_get_answer_is_yes("sign_uid.v4_promote_okay",
- _("Do you want to promote "
- "it to an OpenPGP self-"
- "signature? (y/N) ")))
- {
- force_v4=1;
- node->flag|=NODFLG_DELSIG;
- xfree (user);
- continue;
- }
- }
-
- /* Is the current signature expired? */
- if(node->pkt->pkt.signature->flags.expired)
- {
- tty_printf(_("Your current signature on \"%s\"\n"
- "has expired.\n"),user);
-
- if(cpr_get_answer_is_yes("sign_uid.replace_expired_okay",
- _("Do you want to issue a "
- "new signature to replace "
- "the expired one? (y/N) ")))
- {
- /* Mark these for later deletion. We
- don't want to delete them here, just in
- case the replacement signature doesn't
- happen for some reason. We only delete
- these after the replacement is already
- in place. */
-
- node->flag|=NODFLG_DELSIG;
- xfree (user);
- continue;
- }
- }
-
- if(!node->pkt->pkt.signature->flags.exportable && !local)
- {
- /* It's a local sig, and we want to make a
- exportable sig. */
- tty_printf(_("Your current signature on \"%s\"\n"
- "is a local signature.\n"),user);
-
- if(cpr_get_answer_is_yes("sign_uid.local_promote_okay",
- _("Do you want to promote "
- "it to a full exportable "
- "signature? (y/N) ")))
- {
- /* Mark these for later deletion. We
- don't want to delete them here, just in
- case the replacement signature doesn't
- happen for some reason. We only delete
- these after the replacement is already
- in place. */
-
- node->flag|=NODFLG_DELSIG;
- xfree (user);
- continue;
- }
- }
-
- /* Fixme: see whether there is a revocation in which
- * case we should allow to sign it again. */
- if (!node->pkt->pkt.signature->flags.exportable && local)
- tty_printf(_(
- "\"%s\" was already locally signed by key %08lX\n"),
- user,(ulong)sk_keyid[1] );
- else
- tty_printf(_(
- "\"%s\" was already signed by key %08lX\n"),
- user,(ulong)sk_keyid[1] );
-
- if(opt.expert
- && cpr_get_answer_is_yes("sign_uid.dupe_okay",
- _("Do you want to sign it "
- "again anyway? (y/N) ")))
- {
- /* Don't delete the old sig here since this is
- an --expert thing. */
- xfree (user);
- continue;
- }
-
- sprintf (buf, "%08lX%08lX",
- (ulong)sk->keyid[0], (ulong)sk->keyid[1] );
- write_status_text (STATUS_ALREADY_SIGNED, buf);
- uidnode->flag &= ~NODFLG_MARK_A; /* remove mark */
-
- xfree (user);
- }
- }
- }
- /* check whether any uids are left for signing */
- if( !count_uids_with_flag(keyblock, NODFLG_MARK_A) ) {
- tty_printf(_("Nothing to sign with key %08lX\n"),
- (ulong)sk_keyid[1] );
- continue;
- }
- /* Ask whether we really should sign these user id(s) */
- tty_printf("\n");
- show_key_with_all_names( keyblock, 1, 0, 1, 0, 0 );
- tty_printf("\n");
-
- if(primary_pk->expiredate && !selfsig)
- {
- u32 now=make_timestamp();
-
- if(primary_pk->expiredate<=now)
- {
- tty_printf(_("This key has expired!"));
-
- if(opt.expert)
- {
- tty_printf(" ");
- if(!cpr_get_answer_is_yes("sign_uid.expired_okay",
- _("Are you sure you still "
- "want to sign it? (y/N) ")))
- continue;
- }
- else
- {
- tty_printf(_(" Unable to sign.\n"));
- continue;
- }
- }
- else
- {
- char *answer;
-
- tty_printf(_("This key is due to expire on %s.\n"),
- expirestr_from_pk(primary_pk));
-
- answer=cpr_get("sign_uid.expire",
- _("Do you want your signature to "
- "expire at the same time? (Y/n) "));
- if(answer_is_yes_no_default(answer,1))
- {
- /* This fixes the signature timestamp we're going
- to make as now. This is so the expiration date
- is exactly correct, and not a few seconds off
- (due to the time it takes to answer the
- questions, enter the passphrase, etc). */
- timestamp=now;
- duration=primary_pk->expiredate-now;
- force_v4=1;
- }
-
- cpr_kill_prompt();
- xfree (answer);
- }
- }
-
- /* Only ask for duration if we haven't already set it to match
- the expiration of the pk */
- if(opt.ask_cert_expire && !duration && !selfsig)
- duration=ask_expire_interval(1);
-
- if(duration)
- force_v4=1;
-
- /* Is --pgp2 on, it's a v3 key, all the sigs on the key are
- currently v3 and we're about to sign it with a v4 sig? If
- so, danger! */
- if(PGP2 && all_v3 &&
- (sk->version>3 || force_v4) && primary_pk->version<=3)
- {
- tty_printf(_("You may not make an OpenPGP signature on a "
- "PGP 2.x key while in --pgp2 mode.\n"));
- tty_printf(_("This would make the key unusable in PGP 2.x.\n"));
-
- if(opt.expert)
- {
- if(!cpr_get_answer_is_yes("sign_uid.v4_on_v3_okay",
- _("Are you sure you still "
- "want to sign it? (y/N) ")))
- continue;
-
- all_v3=0;
- }
- else
- continue;
- }
-
- if(selfsig)
- ;
- else
- {
- if(opt.batch)
- class=0x10+opt.def_cert_check_level;
- else
- {
- char *answer;
-
- tty_printf(_("How carefully have you verified the key you are "
- "about to sign actually belongs\nto the person "
- "named above? If you don't know what to "
- "answer, enter \"0\".\n"));
- tty_printf("\n");
- tty_printf(_(" (0) I will not answer.%s\n"),
- opt.def_cert_check_level==0?" (default)":"");
- tty_printf(_(" (1) I have not checked at all.%s\n"),
- opt.def_cert_check_level==1?" (default)":"");
- tty_printf(_(" (2) I have done casual checking.%s\n"),
- opt.def_cert_check_level==2?" (default)":"");
- tty_printf(_(" (3) I have done very careful checking.%s\n"),
- opt.def_cert_check_level==3?" (default)":"");
- tty_printf("\n");
-
- while(class==0)
- {
- answer = cpr_get("sign_uid.class",_("Your selection? "
- "(enter '?' for more information): "));
-
- if(answer[0]=='\0')
- class=0x10+opt.def_cert_check_level; /* Default */
- else if(ascii_strcasecmp(answer,"0")==0)
- class=0x10; /* Generic */
- else if(ascii_strcasecmp(answer,"1")==0)
- class=0x11; /* Persona */
- else if(ascii_strcasecmp(answer,"2")==0)
- class=0x12; /* Casual */
- else if(ascii_strcasecmp(answer,"3")==0)
- class=0x13; /* Positive */
- else
- tty_printf(_("Invalid selection.\n"));
-
- xfree (answer);
- }
- }
-
- if(trust)
- trustsig_prompt(&trust_value,&trust_depth,&trust_regexp);
- }
-
- tty_printf(_("Are you really sure that you want to sign this key\n"
- "with your key: \""));
- p = get_user_id( sk_keyid, &n );
- tty_print_utf8_string( p, n );
- xfree (p); p = NULL;
- tty_printf("\" (%08lX)\n",(ulong)sk_keyid[1]);
-
- if(selfsig)
- {
- tty_printf(_("\nThis will be a self-signature.\n"));
-
- if( local )
- tty_printf(
- _("\nWARNING: the signature will not be marked "
- "as non-exportable.\n"));
-
- if( nonrevocable )
- tty_printf(
- _("\nWARNING: the signature will not be marked "
- "as non-revocable.\n"));
- }
- else
- {
- if( local )
- tty_printf(
- _("\nThe signature will be marked as non-exportable.\n"));
-
- if( nonrevocable )
- tty_printf(
- _("\nThe signature will be marked as non-revocable.\n"));
-
- switch(class)
- {
- case 0x11:
- tty_printf(_("\nI have not checked this key at all.\n"));
- break;
-
- case 0x12:
- tty_printf(_("\nI have checked this key casually.\n"));
- break;
-
- case 0x13:
- tty_printf(_("\nI have checked this key very carefully.\n"));
- break;
- }
- }
-
- tty_printf("\n");
-
- if( opt.batch && opt.answer_yes )
- ;
- else if( !cpr_get_answer_is_yes("sign_uid.okay", _("Really sign? ")) )
- continue;
-
- /* now we can sign the user ids */
- reloop: /* (must use this, because we are modifing the list) */
- primary_pk = NULL;
- for( node=keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_PUBLIC_KEY )
- primary_pk = node->pkt->pkt.public_key;
- else if( node->pkt->pkttype == PKT_USER_ID
- && (node->flag & NODFLG_MARK_A) ) {
- PACKET *pkt;
- PKT_signature *sig;
- struct sign_attrib attrib;
-
- assert( primary_pk );
- memset( &attrib, 0, sizeof attrib );
- attrib.non_exportable = local;
- attrib.non_revocable = nonrevocable;
- attrib.trust_depth = trust_depth;
- attrib.trust_value = trust_value;
- attrib.trust_regexp = trust_regexp;
- node->flag &= ~NODFLG_MARK_A;
-
- /* we force creation of a v4 signature for local
- * signatures, otherwise we would not generate the
- * subpacket with v3 keys and the signature becomes
- * exportable */
-
- if(selfsig)
- rc = make_keysig_packet( &sig, primary_pk,
- node->pkt->pkt.user_id,
- NULL,
- sk,
- 0x13, 0, force_v4?4:0, 0, 0,
- keygen_add_std_prefs, primary_pk);
- else
- rc = make_keysig_packet( &sig, primary_pk,
- node->pkt->pkt.user_id,
- NULL,
- sk,
- class, 0, force_v4?4:0,
- timestamp, duration,
- sign_mk_attrib, &attrib );
- if( rc ) {
- log_error(_("signing failed: %s\n"), gpg_strerror (rc));
- goto leave;
- }
-
- *ret_modified = 1; /* we changed the keyblock */
- update_trust = 1;
-
- pkt = xcalloc (1, sizeof *pkt );
- pkt->pkttype = PKT_SIGNATURE;
- pkt->pkt.signature = sig;
- insert_kbnode( node, new_kbnode(pkt), PKT_SIGNATURE );
- goto reloop;
- }
- }
-
- /* Delete any sigs that got promoted */
- for( node=keyblock; node; node = node->next )
- if( node->flag & NODFLG_DELSIG)
- delete_kbnode(node);
- } /* end loop over signators */
-
- leave:
- release_sk_list( sk_list );
- if( sk )
- free_secret_key(sk);
- return rc;
-}
-
-
-
-/****************
- * Change the passphrase of the primary and all secondary keys.
- * We use only one passphrase for all keys.
- */
-static int
-change_passphrase( KBNODE keyblock )
-{
- int rc = 0;
- int changed=0;
- KBNODE node;
- PKT_secret_key *sk;
- char *passphrase = NULL;
- int no_primary_secrets = 0;
-
- node = find_kbnode( keyblock, PKT_SECRET_KEY );
- if( !node ) {
- log_error("Oops; secret key not found anymore!\n");
- goto leave;
- }
- sk = node->pkt->pkt.secret_key;
-
- switch( is_secret_key_protected( sk ) ) {
- case -1:
- rc = GPG_ERR_PUBKEY_ALGO;
- break;
- case 0:
- tty_printf(_("This key is not protected.\n"));
- break;
- default:
- if( sk->protect.s2k.mode == 1001 ) {
- tty_printf(_("Secret parts of primary key are not available.\n"));
- no_primary_secrets = 1;
- }
- else if( sk->protect.s2k.mode == 1002 ) {
- tty_printf(_("Secret key is actually stored on a card.\n"));
- goto leave;
- }
- else {
- tty_printf(_("Key is protected.\n"));
- rc = check_secret_key( sk, 0 );
- if( !rc )
- passphrase = get_last_passphrase();
- }
- break;
- }
-
- /* unprotect all subkeys (use the supplied passphrase or ask)*/
- for(node=keyblock; !rc && node; node = node->next ) {
- if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- PKT_secret_key *subsk = node->pkt->pkt.secret_key;
- set_next_passphrase( passphrase );
- rc = check_secret_key( subsk, 0 );
- if( !rc && !passphrase )
- passphrase = get_last_passphrase();
- }
- }
-
- if( rc )
- tty_printf(_("Can't edit this key: %s\n"), gpg_strerror (rc));
- else {
- DEK *dek = NULL;
- STRING2KEY *s2k = xmalloc_secure ( sizeof *s2k );
- const char *errtext = NULL;
-
- tty_printf(_("Enter the new passphrase for this secret key.\n\n") );
-
- set_next_passphrase( NULL );
- for(;;) {
- s2k->mode = opt.s2k_mode;
- s2k->hash_algo = opt.s2k_digest_algo;
- dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo,
- s2k, 2, errtext, NULL);
- if( !dek ) {
- errtext = N_("passphrase not correctly repeated; try again");
- tty_printf ("%s.\n", _(errtext));
- }
- else if( !dek->keylen ) {
- rc = 0;
- tty_printf(_( "You don't want a passphrase -"
- " this is probably a *bad* idea!\n\n"));
- if( cpr_get_answer_is_yes("change_passwd.empty.okay",
- _("Do you really want to do this? ")))
- {
- changed++;
- break;
- }
- }
- else { /* okay */
- rc = 0;
- if( !no_primary_secrets ) {
- sk->protect.algo = dek->algo;
- sk->protect.s2k = *s2k;
- rc = protect_secret_key( sk, dek );
- }
- for(node=keyblock; !rc && node; node = node->next ) {
- if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- PKT_secret_key *subsk = node->pkt->pkt.secret_key;
- subsk->protect.algo = dek->algo;
- subsk->protect.s2k = *s2k;
- rc = protect_secret_key( subsk, dek );
- }
- }
- if( rc )
- log_error("protect_secret_key failed: %s\n", gpg_strerror (rc) );
- else
- changed++;
- break;
- }
- }
- xfree (s2k);
- xfree (dek);
- }
-
- leave:
- xfree ( passphrase );
- set_next_passphrase( NULL );
- return changed && !rc;
-}
-
-
-/****************
- * There are some keys out (due to a bug in gnupg), where the sequence
- * of the packets is wrong. This function fixes that.
- * Returns: true if the keyblock has been fixed.
- *
- * Note: This function does not work if there is more than one user ID.
- */
-static int
-fix_keyblock( KBNODE keyblock )
-{
- KBNODE node, last, subkey;
- int fixed=0;
-
- /* locate key signatures of class 0x10..0x13 behind sub key packets */
- for( subkey=last=NULL, node = keyblock; node;
- last=node, node = node->next ) {
- switch( node->pkt->pkttype ) {
- case PKT_PUBLIC_SUBKEY:
- case PKT_SECRET_SUBKEY:
- if( !subkey )
- subkey = last; /* actually it is the one before the subkey */
- break;
- case PKT_SIGNATURE:
- if( subkey ) {
- PKT_signature *sig = node->pkt->pkt.signature;
- if( sig->sig_class >= 0x10 && sig->sig_class <= 0x13 ) {
- log_info(_(
- "moving a key signature to the correct place\n"));
- last->next = node->next;
- node->next = subkey->next;
- subkey->next = node;
- node = last;
- fixed=1;
- }
- }
- break;
- default: break;
- }
- }
-
- return fixed;
-}
-
-/****************
- * Menu driven key editor. If sign_mode is true semi-automatical signing
- * will be performed. commands are ignore in this case
- *
- * Note: to keep track of some selection we use node->mark MARKBIT_xxxx.
- */
-
-void
-keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
- int sign_mode )
-{
- enum cmdids { cmdNONE = 0,
- cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
- cmdTSIGN, cmdLSIGN, cmdNRSIGN, cmdNRLSIGN, cmdREVSIG, cmdREVKEY,
- cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG, cmdSAVE, cmdADDUID,
- cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY, cmdADDREVOKER,
- cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, cmdEXPIRE,
- cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF, cmdUPDPREF,
- cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
- cmdNOP };
- static struct { const char *name;
- enum cmdids id;
- int need_sk;
- int not_with_sk;
- int signmode;
- const char *desc;
- } cmds[] = {
- { N_("quit") , cmdQUIT , 0,0,1, N_("quit this menu") },
- { N_("q") , cmdQUIT , 0,0,1, NULL },
- { N_("save") , cmdSAVE , 0,0,1, N_("save and quit") },
- { N_("help") , cmdHELP , 0,0,1, N_("show this help") },
- { "?" , cmdHELP , 0,0,1, NULL },
- { N_("fpr") , cmdFPR , 0,0,1, N_("show fingerprint") },
- { N_("list") , cmdLIST , 0,0,1, N_("list key and user IDs") },
- { N_("l") , cmdLIST , 0,0,1, NULL },
- { N_("uid") , cmdSELUID , 0,0,1, N_("select user ID N") },
- { N_("key") , cmdSELKEY , 0,0,0, N_("select secondary key N") },
- { N_("check") , cmdCHECK , 0,0,1, N_("list signatures") },
- { N_("c") , cmdCHECK , 0,0,1, NULL },
- { N_("sign") , cmdSIGN , 0,1,1, N_("sign the key") },
- { N_("s") , cmdSIGN , 0,1,1, NULL },
- { N_("tsign") , cmdTSIGN , 0,1,1, N_("make a trust signature")},
- { N_("lsign") , cmdLSIGN , 0,1,1, N_("sign the key locally") },
- { N_("nrsign") , cmdNRSIGN , 0,1,1, N_("sign the key non-revocably") },
- { N_("nrlsign") , cmdNRLSIGN , 0,1,1, N_("sign the key locally and non-revocably") },
- { N_("debug") , cmdDEBUG , 0,0,0, NULL },
- { N_("adduid") , cmdADDUID , 1,1,0, N_("add a user ID") },
- { N_("addphoto"), cmdADDPHOTO , 1,1,0, N_("add a photo ID") },
- { N_("deluid") , cmdDELUID , 0,1,0, N_("delete user ID") },
- /* delphoto is really deluid in disguise */
- { N_("delphoto"), cmdDELUID , 0,1,0, NULL },
- { N_("addkey") , cmdADDKEY , 1,1,0, N_("add a secondary key") },
- { N_("delkey") , cmdDELKEY , 0,1,0, N_("delete a secondary key") },
- { N_("addrevoker"),cmdADDREVOKER,1,1,0, N_("add a revocation key") },
- { N_("delsig") , cmdDELSIG , 0,1,0, N_("delete signatures") },
- { N_("expire") , cmdEXPIRE , 1,1,0, N_("change the expire date") },
- { N_("primary") , cmdPRIMARY , 1,1,0, N_("flag user ID as primary")},
- { N_("toggle") , cmdTOGGLE , 1,0,0, N_("toggle between secret "
- "and public key listing") },
- { N_("t" ) , cmdTOGGLE , 1,0,0, NULL },
- { N_("pref") , cmdPREF , 0,1,0,
- N_("list preferences (expert)")},
- { N_("showpref"), cmdSHOWPREF , 0,1,0,
- N_("list preferences (verbose)")},
- { N_("setpref") , cmdSETPREF , 1,1,0, N_("set preference list") },
- { N_("updpref") , cmdUPDPREF , 1,1,0, N_("updated preferences") },
- { N_("keyserver"),cmdPREFKS , 1,1,0,
- N_("set preferred keyserver URL")},
- { N_("passwd") , cmdPASSWD , 1,1,0, N_("change the passphrase") },
- { N_("trust") , cmdTRUST , 0,1,0, N_("change the ownertrust") },
- { N_("revsig") , cmdREVSIG , 0,1,0, N_("revoke signatures") },
- { N_("revuid") , cmdREVUID , 1,1,0, N_("revoke a user ID") },
- { N_("revkey") , cmdREVKEY , 1,1,0, N_("revoke a secondary key") },
- { N_("disable") , cmdDISABLEKEY, 0,1,0, N_("disable a key") },
- { N_("enable") , cmdENABLEKEY , 0,1,0, N_("enable a key") },
- { N_("showphoto"),cmdSHOWPHOTO , 0,0,0, N_("show photo ID") },
-
- { NULL, cmdNONE } };
- enum cmdids cmd = 0;
- int rc = 0;
- KBNODE keyblock = NULL;
- KEYDB_HANDLE kdbhd = NULL;
- KBNODE sec_keyblock = NULL;
- KEYDB_HANDLE sec_kdbhd = NULL;
- KBNODE cur_keyblock;
- char *answer = NULL;
- int redisplay = 1;
- int modified = 0;
- int sec_modified = 0;
- int toggle;
- int have_commands = !!commands;
-
- if ( opt.command_fd != -1 )
- ;
- else if( opt.batch && !have_commands ) {
- log_error(_("can't do that in batchmode\n"));
- goto leave;
- }
-
- if( sign_mode ) {
- commands = NULL;
- append_to_strlist( &commands, sign_mode == 1? "sign":
- sign_mode == 2?"lsign":
- sign_mode == 3?"nrsign":"nrlsign");
- have_commands = 1;
- }
-
- /* get the public key */
- rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1);
- if( rc )
- goto leave;
- if( fix_keyblock( keyblock ) )
- modified++;
- if( collapse_uids( &keyblock ) )
- modified++;
- reorder_keyblock(keyblock);
-
- if( !sign_mode ) {/* see whether we have a matching secret key */
- PKT_public_key *pk = keyblock->pkt->pkt.public_key;
-
- sec_kdbhd = keydb_new (1);
- {
- byte afp[MAX_FINGERPRINT_LEN];
- size_t an;
-
- fingerprint_from_pk (pk, afp, &an);
- while (an < MAX_FINGERPRINT_LEN)
- afp[an++] = 0;
- rc = keydb_search_fpr (sec_kdbhd, afp);
- }
- if (!rc) {
- rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
- if (rc) {
- log_error (_("error reading secret keyblock `%s': %s\n"),
- username, gpg_strerror (rc));
- }
- else {
- merge_keys_and_selfsig( sec_keyblock );
- if( fix_keyblock( sec_keyblock ) )
- sec_modified++;
- }
- }
-
- if (rc) {
- sec_keyblock = NULL;
- keydb_release (sec_kdbhd); sec_kdbhd = NULL;
- rc = 0;
- }
- }
-
- if( sec_keyblock ) {
- tty_printf(_("Secret key is available.\n"));
- }
-
- toggle = 0;
- cur_keyblock = keyblock;
- for(;;) { /* main loop */
- int i, arg_number, photo;
- const char *arg_string = "";
- char *p;
- PKT_public_key *pk=keyblock->pkt->pkt.public_key;
-
- tty_printf("\n");
- if( redisplay ) {
- show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
- tty_printf("\n");
- redisplay = 0;
- }
- do {
- xfree (answer);
- if( have_commands ) {
- if( commands ) {
- answer = xstrdup ( commands->d );
- commands = commands->next;
- }
- else if( opt.batch ) {
- answer = xstrdup ("quit");
- }
- else
- have_commands = 0;
- }
- if( !have_commands ) {
- answer = cpr_get_no_help("keyedit.prompt", _("Command> "));
- cpr_kill_prompt();
- }
- trim_spaces(answer);
- } while( *answer == '#' );
-
- arg_number = 0; /* Yes, here is the init which egcc complains about */
- photo = 0; /* This too */
- if( !*answer )
- cmd = cmdLIST;
- else if( *answer == CONTROL_D )
- cmd = cmdQUIT;
- else if( digitp( answer ) ) {
- cmd = cmdSELUID;
- arg_number = atoi(answer);
- }
- else {
- if( (p=strchr(answer,' ')) ) {
- *p++ = 0;
- trim_spaces(answer);
- trim_spaces(p);
- arg_number = atoi(p);
- arg_string = p;
- }
-
- for(i=0; cmds[i].name; i++ ) {
- if( !ascii_strcasecmp( answer, cmds[i].name ) )
- break;
- }
- if( sign_mode && !cmds[i].signmode )
- cmd = cmdINVCMD;
- else if( cmds[i].need_sk && !sec_keyblock ) {
- tty_printf(_("Need the secret key to do this.\n"));
- cmd = cmdNOP;
- }
- else if( cmds[i].not_with_sk && sec_keyblock && toggle ) {
- tty_printf(_("Please use the command \"toggle\" first.\n"));
- cmd = cmdNOP;
- }
- else
- cmd = cmds[i].id;
- }
- switch( cmd ) {
- case cmdHELP:
- for(i=0; cmds[i].name; i++ ) {
- if( sign_mode && !cmds[i].signmode )
- ;
- else if( cmds[i].need_sk && !sec_keyblock )
- ; /* skip if we do not have the secret key */
- else if( cmds[i].desc )
- tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
- }
- break;
-
- case cmdLIST:
- redisplay = 1;
- break;
-
- case cmdFPR:
- show_key_and_fingerprint( keyblock );
- break;
-
- case cmdSELUID:
- if( menu_select_uid( cur_keyblock, arg_number ) )
- redisplay = 1;
- break;
-
- case cmdSELKEY:
- if( menu_select_key( cur_keyblock, arg_number ) )
- redisplay = 1;
- break;
-
- case cmdCHECK:
- /* we can only do this with the public key becuase the
- * check functions can't cope with secret keys and it
- * is questionable whether this would make sense at all */
- check_all_keysigs( keyblock, count_selected_uids(keyblock) );
- break;
-
- case cmdSIGN: /* sign (only the public key) */
- case cmdLSIGN: /* sign (only the public key) */
- case cmdNRSIGN: /* sign (only the public key) */
- case cmdNRLSIGN: /* sign (only the public key) */
- case cmdTSIGN:
- if( pk->is_revoked )
- {
- tty_printf(_("Key is revoked."));
-
- if(opt.expert)
- {
- tty_printf(" ");
- if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
- _("Are you sure you still want "
- "to sign it? (y/N) ")))
- break;
- }
- else
- {
- tty_printf(_(" Unable to sign.\n"));
- break;
- }
- }
-
- if( count_uids(keyblock) > 1 && !count_selected_uids(keyblock) ) {
- if( !cpr_get_answer_is_yes("keyedit.sign_all.okay",
- _("Really sign all user IDs? ")) ) {
- tty_printf(_("Hint: Select the user IDs to sign\n"));
- break;
- }
- }
- if( !sign_uids( keyblock, locusr, &modified,
- (cmd == cmdLSIGN) || (cmd == cmdNRLSIGN),
- (cmd == cmdNRSIGN) || (cmd==cmdNRLSIGN),
- (cmd == cmdTSIGN))
- && sign_mode )
- goto do_cmd_save;
- break;
-
- case cmdDEBUG:
- dump_kbnode( cur_keyblock );
- break;
-
- case cmdTOGGLE:
- toggle = !toggle;
- cur_keyblock = toggle? sec_keyblock : keyblock;
- redisplay = 1;
- break;
-
- case cmdADDPHOTO:
- if (RFC2440 || RFC1991 || PGP2)
- {
- tty_printf(
- _("This command is not allowed while in %s mode.\n"),
- RFC2440?"OpenPGP":PGP2?"PGP2":"RFC-1991");
- break;
- }
- photo=1;
- /* fall through */
-
- case cmdADDUID:
- if( menu_adduid( keyblock, sec_keyblock, photo ) ) {
- redisplay = 1;
- sec_modified = modified = 1;
- merge_keys_and_selfsig( sec_keyblock );
- merge_keys_and_selfsig( keyblock );
- }
- break;
-
- case cmdDELUID: {
- int n1;
-
- if( !(n1=count_selected_uids(keyblock)) )
- tty_printf(_("You must select at least one user ID.\n"));
- else if( real_uids_left(keyblock) < 1 )
- tty_printf(_("You can't delete the last user ID!\n"));
- else if( cpr_get_answer_is_yes(
- "keyedit.remove.uid.okay",
- n1 > 1? _("Really remove all selected user IDs? ")
- : _("Really remove this user ID? ")
- ) ) {
- menu_deluid( keyblock, sec_keyblock );
- redisplay = 1;
- modified = 1;
- if( sec_keyblock )
- sec_modified = 1;
- }
- }
- break;
-
- case cmdDELSIG: {
- int n1;
-
- if( !(n1=count_selected_uids(keyblock)) )
- tty_printf(_("You must select at least one user ID.\n"));
- else if( menu_delsig( keyblock ) ) {
- /* no redisplay here, because it may scroll away some
- * status output of delsig */
- modified = 1;
- }
- }
- break;
-
- case cmdADDKEY:
- if( generate_subkeypair( keyblock, sec_keyblock ) ) {
- redisplay = 1;
- sec_modified = modified = 1;
- merge_keys_and_selfsig( sec_keyblock );
- merge_keys_and_selfsig( keyblock );
- }
- break;
-
-
- case cmdDELKEY: {
- int n1;
-
- if( !(n1=count_selected_keys( keyblock )) )
- tty_printf(_("You must select at least one key.\n"));
- else if( sec_keyblock && !cpr_get_answer_is_yes(
- "keyedit.remove.subkey.okay",
- n1 > 1?
- _("Do you really want to delete the selected keys? "):
- _("Do you really want to delete this key? ")
- ))
- ;
- else {
- menu_delkey( keyblock, sec_keyblock );
- redisplay = 1;
- modified = 1;
- if( sec_keyblock )
- sec_modified = 1;
- }
- }
- break;
-
- case cmdADDREVOKER:
- {
- int sensitive=0;
-
- if(arg_string && ascii_strcasecmp(arg_string,"sensitive")==0)
- sensitive=1;
- if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
- redisplay = 1;
- sec_modified = modified = 1;
- merge_keys_and_selfsig( sec_keyblock );
- merge_keys_and_selfsig( keyblock );
- }
- }
- break;
-
- case cmdREVUID: {
- int n1;
-
- if( !(n1=count_selected_uids(keyblock)) )
- tty_printf(_("You must select at least one user ID.\n"));
- else if( cpr_get_answer_is_yes(
- "keyedit.revoke.uid.okay",
- n1 > 1? _("Really revoke all selected user IDs? ")
- : _("Really revoke this user ID? ")
- ) ) {
- if(menu_revuid(keyblock,sec_keyblock))
- {
- modified=1;
- redisplay=1;
- }
- }
- }
- break;
-
- case cmdREVKEY: {
- int n1;
-
- if( !(n1=count_selected_keys( keyblock )) )
- tty_printf(_("You must select at least one key.\n"));
- else if( sec_keyblock && !cpr_get_answer_is_yes(
- "keyedit.revoke.subkey.okay",
- n1 > 1?
- _("Do you really want to revoke the selected keys? "):
- _("Do you really want to revoke this key? ")
- ))
- ;
- else {
- if( menu_revkey( keyblock, sec_keyblock ) ) {
- modified = 1;
- /*sec_modified = 1;*/
- }
- redisplay = 1;
- }
- }
- break;
-
- case cmdEXPIRE:
- if( menu_expire( keyblock, sec_keyblock ) ) {
- merge_keys_and_selfsig( sec_keyblock );
- merge_keys_and_selfsig( keyblock );
- sec_modified = 1;
- modified = 1;
- redisplay = 1;
- }
- break;
-
- case cmdPRIMARY:
- if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
- merge_keys_and_selfsig( keyblock );
- modified = 1;
- redisplay = 1;
- }
- break;
-
- case cmdPASSWD:
- if( change_passphrase( sec_keyblock ) )
- sec_modified = 1;
- break;
-
- case cmdTRUST:
- show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
- tty_printf("\n");
- if( edit_ownertrust( find_kbnode( keyblock,
- PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
- redisplay = 1;
- /* No real need to set update_trust here as
- edit_ownertrust() calls revalidation_mark()
- anyway. */
- update_trust=1;
- }
- break;
-
- case cmdPREF:
- show_key_with_all_names( keyblock, 0, 0, 0, 0, 1 );
- break;
-
- case cmdSHOWPREF:
- show_key_with_all_names( keyblock, 0, 0, 0, 0, 2 );
- break;
-
- case cmdSETPREF:
- keygen_set_std_prefs ( !*arg_string? "default" : arg_string, 0);
- break;
-
- case cmdUPDPREF:
- {
- PKT_user_id *temp=keygen_get_std_prefs();
- tty_printf(_("Current preference list:\n"));
- show_prefs(temp,1);
- xfree (temp);
- }
- if (cpr_get_answer_is_yes ("keyedit.updpref.okay",
- count_selected_uids (keyblock)?
- _("Really update the preferences"
- " for the selected user IDs? "):
- _("Really update the preferences? "))){
-
- if ( menu_set_preferences (keyblock, sec_keyblock) ) {
- merge_keys_and_selfsig (keyblock);
- modified = 1;
- redisplay = 1;
- }
- }
- break;
-
- case cmdPREFKS:
- if( menu_set_keyserver_url ( keyblock, sec_keyblock ) ) {
- merge_keys_and_selfsig( keyblock );
- modified = 1;
- redisplay = 1;
- }
- break;
-
- case cmdNOP:
- break;
-
- case cmdREVSIG:
- if( menu_revsig( keyblock ) ) {
- redisplay = 1;
- modified = 1;
- }
- break;
-
- case cmdENABLEKEY:
- case cmdDISABLEKEY:
- if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
- redisplay = 1;
- modified = 1;
- }
- break;
-
- case cmdSHOWPHOTO:
- menu_showphoto(keyblock);
- break;
-
- case cmdQUIT:
- if( have_commands )
- goto leave;
- if( !modified && !sec_modified )
- goto leave;
- if( !cpr_get_answer_is_yes("keyedit.save.okay",
- _("Save changes? ")) ) {
- if( cpr_enabled()
- || cpr_get_answer_is_yes("keyedit.cancel.okay",
- _("Quit without saving? ")) )
- goto leave;
- break;
- }
- /* fall thru */
- case cmdSAVE:
- do_cmd_save:
- if( modified || sec_modified ) {
- if( modified ) {
- rc = keydb_update_keyblock (kdbhd, keyblock);
- if( rc ) {
- log_error(_("update failed: %s\n"), gpg_strerror (rc) );
- break;
- }
- }
- if( sec_modified ) {
- rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
- if( rc ) {
- log_error( _("update secret failed: %s\n"),
- gpg_strerror (rc) );
- break;
- }
- }
- }
- else
- tty_printf(_("Key not changed so no update needed.\n"));
-
- if( update_trust )
- {
- revalidation_mark ();
- update_trust=0;
- }
- goto leave;
-
- case cmdINVCMD:
- default:
- tty_printf("\n");
- tty_printf(_("Invalid command (try \"help\")\n"));
- break;
- }
- } /* end main loop */
-
- leave:
- release_kbnode( keyblock );
- release_kbnode( sec_keyblock );
- keydb_release (kdbhd);
- xfree (answer);
-}
-
-
-/****************
- * show preferences of a public keyblock.
- */
-static void
-show_prefs (PKT_user_id *uid, int verbose)
-{
- const prefitem_t fake={0,0};
- const prefitem_t *prefs;
- int i;
-
- if( !uid )
- return;
-
- if( uid->prefs )
- prefs=uid->prefs;
- else if(verbose)
- prefs=&fake;
- else
- return;
-
- if (verbose) {
- int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
- tty_printf (" ");
- tty_printf (_("Cipher: "));
- for(i=any=0; prefs[i].type; i++ ) {
- if( prefs[i].type == PREFTYPE_SYM ) {
- const char *s = gcry_cipher_algo_name (prefs[i].value);
-
- if (any)
- tty_printf (", ");
- any = 1;
- /* We don't want to display strings for experimental algos */
- if (s && prefs[i].value < 100 )
- tty_printf ("%s", s );
- else
- tty_printf ("[%d]", prefs[i].value);
- if (prefs[i].value == CIPHER_ALGO_3DES )
- des_seen = 1;
- }
- }
- if (!des_seen) {
- if (any)
- tty_printf (", ");
- tty_printf ("%s", gcry_cipher_algo_name (CIPHER_ALGO_3DES));
- }
- tty_printf ("\n ");
- tty_printf (_("Digest: "));
- for(i=any=0; prefs[i].type; i++ ) {
- if( prefs[i].type == PREFTYPE_HASH ) {
- const char *s = gcry_md_algo_name (prefs[i].value);
-
- if (any)
- tty_printf (", ");
- any = 1;
- /* We don't want to display strings for experimental algos */
- if (s && prefs[i].value < 100 )
- tty_printf ("%s", s );
- else
- tty_printf ("[%d]", prefs[i].value);
- if (prefs[i].value == DIGEST_ALGO_SHA1 )
- sha1_seen = 1;
- }
- }
- if (!sha1_seen) {
- if (any)
- tty_printf (", ");
- tty_printf ("%s", gcry_md_algo_name (DIGEST_ALGO_SHA1));
- }
- tty_printf ("\n ");
- tty_printf (_("Compression: "));
- for(i=any=0; prefs[i].type; i++ ) {
- if( prefs[i].type == PREFTYPE_ZIP ) {
- const char *s=compress_algo_to_string(prefs[i].value);
-
- if (any)
- tty_printf (", ");
- any = 1;
- /* We don't want to display strings for experimental algos */
- if (s && prefs[i].value < 100 )
- tty_printf ("%s", s );
- else
- tty_printf ("[%d]", prefs[i].value);
- if (prefs[i].value == 0 )
- uncomp_seen = 1;
- }
- }
- if (!uncomp_seen) {
- if (any)
- tty_printf (", ");
- else {
- tty_printf ("%s",compress_algo_to_string(1));
- tty_printf (", ");
- }
- tty_printf ("%s",compress_algo_to_string(0));
- }
- if(uid->mdc_feature || !uid->ks_modify)
- {
- tty_printf ("\n ");
- tty_printf (_("Features: "));
- any=0;
- if(uid->mdc_feature)
- {
- tty_printf ("MDC");
- any=1;
- }
- if(!uid->ks_modify)
- {
- if(any)
- tty_printf (", ");
- tty_printf (_("Keyserver no-modify"));
- }
- }
- tty_printf("\n");
- }
- else {
- tty_printf(" ");
- for(i=0; prefs[i].type; i++ ) {
- tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' :
- prefs[i].type == PREFTYPE_HASH ? 'H' :
- prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
- prefs[i].value);
- }
- if (uid->mdc_feature)
- tty_printf (" [mdc]");
- if (!uid->ks_modify)
- tty_printf (" [no-ks-modify]");
- tty_printf("\n");
- }
-}
-
-
-/* This is the version of show_key_with_all_names used when
- opt.with_colons is used. It prints all available data in a easy to
- parse format and does not translate utf8 */
-static void
-show_key_with_all_names_colon (KBNODE keyblock)
-{
- KBNODE node;
- int i, j, ulti_hack=0;
- byte pk_version=0;
- PKT_public_key *primary=NULL;
-
- /* the keys */
- for ( node = keyblock; node; node = node->next )
- {
- if (node->pkt->pkttype == PKT_PUBLIC_KEY
- || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
- {
- PKT_public_key *pk = node->pkt->pkt.public_key;
- u32 keyid[2];
-
- if (node->pkt->pkttype == PKT_PUBLIC_KEY)
- {
- pk_version = pk->version;
- primary=pk;
- }
-
- keyid_from_pk (pk, keyid);
-
- fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
- if (!pk->is_valid)
- putchar ('i');
- else if (pk->is_revoked)
- putchar ('r');
- else if (pk->has_expired)
- putchar ('e');
- else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
- {
- int trust = get_validity_info (pk, NULL);
- if(trust=='u')
- ulti_hack=1;
- putchar (trust);
- }
-
- printf (":%u:%d:%08lX%08lX:%lu:%lu:",
- nbits_from_pk (pk),
- pk->pubkey_algo,
- (ulong)keyid[0], (ulong)keyid[1],
- (ulong)pk->timestamp,
- (ulong)pk->expiredate );
- if (pk->local_id)
- printf ("%lu", pk->local_id);
- putchar (':');
- if (node->pkt->pkttype==PKT_PUBLIC_KEY
- && !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
- putchar(get_ownertrust_info (pk));
- putchar(':');
- putchar('\n');
-
- print_fingerprint (pk, NULL, 0);
-
- /* print the revoker record */
- if( !pk->revkey && pk->numrevkeys )
- BUG();
- else
- {
- for (i=0; i < pk->numrevkeys; i++)
- {
- byte *p;
-
- printf ("rvk:::%d::::::", pk->revkey[i].algid);
- p = pk->revkey[i].fpr;
- for (j=0; j < 20; j++, p++ )
- printf ("%02X", *p);
- printf (":%02x%s:\n", pk->revkey[i].class,
- (pk->revkey[i].class&0x40)?"s":"");
- }
- }
- }
- }
-
- /* the user ids */
- i = 0;
- for (node = keyblock; node; node = node->next)
- {
- if ( node->pkt->pkttype == PKT_USER_ID )
- {
- PKT_user_id *uid = node->pkt->pkt.user_id;
-
- ++i;
-
- if(uid->attrib_data)
- printf("uat:");
- else
- printf("uid:");
-
- if ( uid->is_revoked )
- printf("r::::::::");
- else if ( uid->is_expired )
- printf("e::::::::");
- else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
- printf("::::::::");
- else
- {
- int uid_validity;
-
- if( primary && !ulti_hack )
- uid_validity = get_validity_info( primary, uid );
- else
- uid_validity = 'u';
- printf("%c::::::::",uid_validity);
- }
-
- if(uid->attrib_data)
- printf ("%u %lu",uid->numattribs,uid->attrib_len);
- else
- print_string (stdout, uid->name, uid->len, ':');
-
- putchar (':');
- /* signature class */
- putchar (':');
- /* capabilities */
- putchar (':');
- /* preferences */
- if (pk_version>3 || uid->selfsigversion>3)
- {
- const prefitem_t *prefs = uid->prefs;
-
- for (j=0; prefs && prefs[j].type; j++)
- {
- if (j)
- putchar (' ');
- printf ("%c%d", prefs[j].type == PREFTYPE_SYM ? 'S' :
- prefs[j].type == PREFTYPE_HASH ? 'H' :
- prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
- prefs[j].value);
- }
- if (uid->mdc_feature)
- printf (",mdc");
- if (!uid->ks_modify)
- printf (",no-ks-modify");
- }
- putchar (':');
- /* flags */
- printf ("%d,", i);
- if (uid->is_primary)
- putchar ('p');
- if (uid->is_revoked)
- putchar ('r');
- if (uid->is_expired)
- putchar ('e');
- if ((node->flag & NODFLG_SELUID))
- putchar ('s');
- if ((node->flag & NODFLG_MARK_A))
- putchar ('m');
- putchar (':');
- putchar('\n');
- }
- }
-}
-
-
-/****************
- * Display the key a the user ids, if only_marked is true, do only
- * so for user ids with mark A flag set and dont display the index number
- */
-static void
-show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
- int with_fpr, int with_subkeys, int with_prefs )
-{
- KBNODE node;
- int i, rc;
- int do_warn = 0;
- byte pk_version=0;
- PKT_public_key *primary=NULL;
-
- if (opt.with_colons)
- {
- show_key_with_all_names_colon (keyblock);
- return;
- }
-
- /* the keys */
- for( node = keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_PUBLIC_KEY
- || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) {
- PKT_public_key *pk = node->pkt->pkt.public_key;
- const char *otrust="err",*trust="err";
-
- if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
- /* do it here, so that debug messages don't clutter the
- * output */
- static int did_warn = 0;
-
- trust = get_validity_string (pk, NULL);
- otrust = get_ownertrust_string (pk);
-
- /* Show a warning once */
- if (!did_warn
- && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
- did_warn = 1;
- do_warn = 1;
- }
-
- pk_version = pk->version;
- primary = pk;
- }
-
- if(with_revoker) {
- if( !pk->revkey && pk->numrevkeys )
- BUG();
- else
- for(i=0;i<pk->numrevkeys;i++) {
- u32 r_keyid[2];
- char *user;
- const char *algo=
- gcry_pk_algo_name (pk->revkey[i].algid);
-
- keyid_from_fingerprint(pk->revkey[i].fpr,
- MAX_FINGERPRINT_LEN,r_keyid);
-
- user=get_user_id_string (r_keyid);
- tty_printf (_("This key may be revoked by %s key "),
- algo?algo:"?");
- tty_print_utf8_string (user, strlen (user));
- if ((pk->revkey[i].class&0x40))
- tty_printf (_(" (sensitive)"));
- tty_printf ("\n");
- xfree (user);
- }
- }
-
- keyid_from_pk(pk,NULL);
- tty_printf("%s%c %4u%c/",
- node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
- (node->flag & NODFLG_SELKEY)? '*':' ',
- nbits_from_pk( pk ),
- pubkey_letter( pk->pubkey_algo ));
-
- if(opt.list_options&LIST_SHOW_LONG_KEYID)
- tty_printf("%08lX",(ulong)pk->keyid[0]);
-
- tty_printf("%08lX ",(ulong)pk->keyid[1]);
- tty_printf(_("created: %s expires: %s"),
- datestr_from_pk(pk),
- expirestr_from_pk(pk) );
- tty_printf("\n");
-
- if( node->pkt->pkttype == PKT_PUBLIC_KEY )
- {
- tty_printf(" ");
- if(opt.list_options&LIST_SHOW_LONG_KEYID)
- tty_printf(" ");
- tty_printf(_("trust: %-13s"), otrust);
- tty_printf(_("validity: %s"), trust );
- tty_printf("\n");
- if( node->pkt->pkttype == PKT_PUBLIC_KEY
- && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
- {
- tty_printf("*** ");
- tty_printf(_("This key has been disabled"));
- tty_printf("\n");
- }
- }
-
- if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
- {
- print_fingerprint ( pk, NULL, 2 );
- tty_printf("\n");
- }
- }
- else if( node->pkt->pkttype == PKT_SECRET_KEY
- || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) ) {
- PKT_secret_key *sk = node->pkt->pkt.secret_key;
- tty_printf(_("%s%c %4u%c/%08lX created: %s expires: %s"),
- node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
- (node->flag & NODFLG_SELKEY)? '*':' ',
- nbits_from_sk( sk ),
- pubkey_letter( sk->pubkey_algo ),
- (ulong)keyid_from_sk(sk,NULL),
- datestr_from_sk(sk),
- expirestr_from_sk(sk) );
- tty_printf("\n");
- }
- else if( with_subkeys && node->pkt->pkttype == PKT_SIGNATURE
- && node->pkt->pkt.signature->sig_class == 0x28 ) {
- PKT_signature *sig = node->pkt->pkt.signature;
-
- rc = check_key_signature( keyblock, node, NULL );
- if( !rc )
- tty_printf( _("rev! subkey has been revoked: %s\n"),
- datestr_from_sig( sig ) );
- else if( gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE )
- tty_printf( _("rev- faked revocation found\n") );
- else if( rc )
- tty_printf( _("rev? problem checking revocation: %s\n"),
- gpg_strerror (rc) );
- }
- }
- /* the user ids */
- i = 0;
- for( node = keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_USER_ID ) {
- PKT_user_id *uid = node->pkt->pkt.user_id;
- ++i;
- if( !only_marked || (only_marked && (node->flag & NODFLG_MARK_A))){
- if(opt.list_options&LIST_SHOW_VALIDITY && primary)
- tty_printf("[%8.8s] ",
- trust_value_to_string(get_validity(primary,uid)));
- if( only_marked )
- tty_printf(" ");
- else if( node->flag & NODFLG_SELUID )
- tty_printf("(%d)* ", i);
- else if( uid->is_primary )
- tty_printf("(%d). ", i);
- else
- tty_printf("(%d) ", i);
- if ( uid->is_revoked )
- tty_printf (_("[revoked] "));
- if ( uid->is_expired )
- tty_printf (_("[expired] "));
- tty_print_utf8_string( uid->name, uid->len );
- tty_printf("\n");
- if( with_prefs )
- {
- if(pk_version>3 || uid->selfsigversion>3)
- show_prefs (uid, with_prefs == 2);
- else
- tty_printf(_("There are no preferences on a "
- "PGP 2.x-style user ID.\n"));
- }
- }
- }
- }
-
- if (do_warn)
- tty_printf (_("Please note that the shown key validity "
- "is not necessarily correct\n"
- "unless you restart the program.\n"));
-
-}
-
-
-/* Display basic key information. This fucntion is suitable to show
- information on the key without any dependencies on the trustdb or
- any other internal GnuPG stuff. KEYBLOCK may either be a public or
- a secret key.*/
-void
-show_basic_key_info ( KBNODE keyblock )
-{
- KBNODE node;
- int i;
-
- /* The primary key */
- for (node = keyblock; node; node = node->next)
- {
- if (node->pkt->pkttype == PKT_PUBLIC_KEY)
- {
- PKT_public_key *pk = node->pkt->pkt.public_key;
-
- /* Note, we use the same format string as in other show
- functions to make the translation job easier. */
- tty_printf (_("%s%c %4u%c/%08lX created: %s expires: %s"),
- node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
- ' ',
- nbits_from_pk( pk ),
- pubkey_letter( pk->pubkey_algo ),
- (ulong)keyid_from_pk(pk,NULL),
- datestr_from_pk(pk),
- expirestr_from_pk(pk) );
- tty_printf("\n");
- print_fingerprint ( pk, NULL, 3 );
- tty_printf("\n");
- }
- else if (node->pkt->pkttype == PKT_SECRET_KEY)
- {
- PKT_secret_key *sk = node->pkt->pkt.secret_key;
- tty_printf(_("%s%c %4u%c/%08lX created: %s expires: %s"),
- node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
- ' ',
- nbits_from_sk( sk ),
- pubkey_letter( sk->pubkey_algo ),
- (ulong)keyid_from_sk(sk,NULL),
- datestr_from_sk(sk),
- expirestr_from_sk(sk) );
- tty_printf("\n");
- print_fingerprint (NULL, sk, 3 );
- tty_printf("\n");
- }
- }
-
- /* The user IDs. */
- for (i=0, node = keyblock; node; node = node->next)
- {
- if (node->pkt->pkttype == PKT_USER_ID)
- {
- PKT_user_id *uid = node->pkt->pkt.user_id;
- ++i;
-
- tty_printf (" ");
- if (uid->is_revoked)
- tty_printf ("[revoked] ");
- if ( uid->is_expired )
- tty_printf ("[expired] ");
- tty_print_utf8_string (uid->name, uid->len);
- tty_printf ("\n");
- }
- }
-}
-
-static void
-show_key_and_fingerprint( KBNODE keyblock )
-{
- KBNODE node;
- PKT_public_key *pk = NULL;
-
- for( node = keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
- pk = node->pkt->pkt.public_key;
- tty_printf("pub %4u%c/%08lX %s ",
- nbits_from_pk( pk ),
- pubkey_letter( pk->pubkey_algo ),
- (ulong)keyid_from_pk(pk,NULL),
- datestr_from_pk(pk) );
- }
- else if( node->pkt->pkttype == PKT_USER_ID ) {
- PKT_user_id *uid = node->pkt->pkt.user_id;
- tty_print_utf8_string( uid->name, uid->len );
- break;
- }
- }
- tty_printf("\n");
- if( pk )
- print_fingerprint( pk, NULL, 2 );
-}
-
-
-/* Show a warning if no uids on the key have the primary uid flag
- set. */
-static void
-no_primary_warning(KBNODE keyblock, int uids)
-{
- KBNODE node;
- int select_all=1,have_uid=0,uid_count=0;
-
- if(uids)
- select_all=!count_selected_uids(keyblock);
-
- /* TODO: if we ever start behaving differently with a primary or
- non-primary attribute ID, we will need to check for attributes
- here as well. */
-
- for(node=keyblock; node; node = node->next)
- {
- if(node->pkt->pkttype==PKT_USER_ID
- && node->pkt->pkt.user_id->attrib_data==NULL)
- {
- uid_count++;
-
- if((select_all || (node->flag & NODFLG_SELUID))
- && node->pkt->pkt.user_id->is_primary==2)
- have_uid|=2;
- else
- have_uid|=1;
- }
- }
-
- if(uid_count>1 && have_uid&1 && !(have_uid&2))
- log_info(_("WARNING: no user ID has been marked as primary. This command "
- "may\n cause a different user ID to become the assumed primary.\n"));
-}
-
-/****************
- * Ask for a new user id, do the selfsignature and put it into
- * both keyblocks.
- * Return true if there is a new user id
- */
-static int
-menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock, int photo)
-{
- PKT_user_id *uid;
- PKT_public_key *pk=NULL;
- PKT_secret_key *sk=NULL;
- PKT_signature *sig=NULL;
- PACKET *pkt;
- KBNODE node;
- KBNODE pub_where=NULL, sec_where=NULL;
- int rc;
-
- for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
- if( node->pkt->pkttype == PKT_PUBLIC_KEY )
- pk = node->pkt->pkt.public_key;
- else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
- break;
- }
- if( !node ) /* no subkey */
- pub_where = NULL;
- for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
- if( node->pkt->pkttype == PKT_SECRET_KEY )
- sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
- else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
- break;
- }
- if( !node ) /* no subkey */
- sec_where = NULL;
- assert(pk && sk);
-
- if(photo) {
- int hasattrib=0;
-
- for( node = pub_keyblock; node; node = node->next )
- if( node->pkt->pkttype == PKT_USER_ID &&
- node->pkt->pkt.user_id->attrib_data!=NULL)
- {
- hasattrib=1;
- break;
- }
-
- /* It is legal but bad for compatibility to add a photo ID to a
- v3 key as it means that PGP2 will not be able to use that key
- anymore. Also, PGP may not expect a photo on a v3 key.
- Don't bother to ask this if the key already has a photo - any
- damage has already been done at that point. -dms */
- if(pk->version==3 && !hasattrib)
- {
- if(opt.expert)
- {
- tty_printf(_("WARNING: This is a PGP2-style key. "
- "Adding a photo ID may cause some versions\n"
- " of PGP to reject this key.\n"));
-
- if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
- _("Are you sure you still want "
- "to add it? (y/N) ")))
- return 0;
- }
- else
- {
- tty_printf(_("You may not add a photo ID to "
- "a PGP2-style key.\n"));
- return 0;
- }
- }
-
- uid = generate_photo_id(pk);
- } else
- uid = generate_user_id();
- if( !uid )
- return 0;
-
- rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
- keygen_add_std_prefs, pk );
- free_secret_key( sk );
- if( rc ) {
- log_error("signing failed: %s\n", gpg_strerror (rc) );
- free_user_id(uid);
- return 0;
- }
-
- /* insert/append to secret keyblock */
- pkt = xcalloc (1, sizeof *pkt );
- pkt->pkttype = PKT_USER_ID;
- pkt->pkt.user_id = scopy_user_id(uid);
- node = new_kbnode(pkt);
- if( sec_where )
- insert_kbnode( sec_where, node, 0 );
- else
- add_kbnode( sec_keyblock, node );
- pkt = xcalloc (1, sizeof *pkt );
- pkt->pkttype = PKT_SIGNATURE;
- pkt->pkt.signature = copy_signature(NULL, sig);
- if( sec_where )
- insert_kbnode( node, new_kbnode(pkt), 0 );
- else
- add_kbnode( sec_keyblock, new_kbnode(pkt) );
- /* insert/append to public keyblock */
- pkt = xcalloc (1, sizeof *pkt );
- pkt->pkttype = PKT_USER_ID;
- pkt->pkt.user_id = uid;
- node = new_kbnode(pkt);
- if( pub_where )
- insert_kbnode( pub_where, node, 0 );
- else
- add_kbnode( pub_keyblock, node );
- pkt = xcalloc (1, sizeof *pkt );
- pkt->pkttype = PKT_SIGNATURE;
- pkt->pkt.signature = copy_signature(NULL, sig);
- if( pub_where )
- insert_kbnode( node, new_kbnode(pkt), 0 );
- else
- add_kbnode( pub_keyblock, new_kbnode(pkt) );
- return 1;
-}
-
-
-/****************
- * Remove all selceted userids from the keyrings
- */
-static void
-menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
-{
- KBNODE node;
- int selected=0;
-
- for( node = pub_keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_USER_ID ) {
- selected = node->flag & NODFLG_SELUID;
- if( selected ) {
- /* Only cause a trust update if we delete a
- non-revoked user id */
- if(!node->pkt->pkt.user_id->is_revoked)
- update_trust=1;
- delete_kbnode( node );
- if( sec_keyblock ) {
- KBNODE snode;
- int s_selected = 0;
- PKT_user_id *uid = node->pkt->pkt.user_id;
- for( snode = sec_keyblock; snode; snode = snode->next ) {
- if( snode->pkt->pkttype == PKT_USER_ID ) {
- PKT_user_id *suid = snode->pkt->pkt.user_id;
-
- s_selected =
- (uid->len == suid->len
- && !memcmp( uid->name, suid->name, uid->len));
- if( s_selected )
- delete_kbnode( snode );
- }
- else if( s_selected
- && snode->pkt->pkttype == PKT_SIGNATURE )
- delete_kbnode( snode );
- else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
- s_selected = 0;
- }
- }
- }
- }
- else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
- delete_kbnode( node );
- else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
- selected = 0;
- }
- commit_kbnode( &pub_keyblock );
- if( sec_keyblock )
- commit_kbnode( &sec_keyblock );
-}
-
-
-static int
-menu_delsig( KBNODE pub_keyblock )
-{
- KBNODE node;
- PKT_user_id *uid = NULL;
- int changed=0;
-
- for( node = pub_keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_USER_ID ) {
- uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
- }
- else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
- int okay, valid, selfsig, inv_sig, no_key, other_err;
-
- tty_printf("uid ");
- tty_print_utf8_string( uid->name, uid->len );
- tty_printf("\n");
-
- okay = inv_sig = no_key = other_err = 0;
- valid = print_and_check_one_sig( pub_keyblock, node,
- &inv_sig, &no_key, &other_err,
- &selfsig, 1 );
-
- if( valid ) {
- okay = cpr_get_answer_yes_no_quit(
- "keyedit.delsig.valid",
- _("Delete this good signature? (y/N/q)"));
-
- /* Only update trust if we delete a good signature.
- The other two cases do not affect trust. */
- if(okay)
- update_trust=1;
- }
- else if( inv_sig || other_err )
- okay = cpr_get_answer_yes_no_quit(
- "keyedit.delsig.invalid",
- _("Delete this invalid signature? (y/N/q)"));
- else if( no_key )
- okay = cpr_get_answer_yes_no_quit(
- "keyedit.delsig.unknown",
- _("Delete this unknown signature? (y/N/q)"));
-
- if( okay == -1 )
- break;
- if( okay && selfsig && !cpr_get_answer_is_yes(
- "keyedit.delsig.selfsig",
- _("Really delete this self-signature? (y/N)") ))
- okay = 0;
- if( okay ) {
- delete_kbnode( node );
- changed++;
- }
-
- }
- else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
- uid = NULL;
- }
-
- if( changed ) {
- commit_kbnode( &pub_keyblock );
- tty_printf( changed == 1? _("Deleted %d signature.\n")
- : _("Deleted %d signatures.\n"), changed );
- }
- else
- tty_printf( _("Nothing deleted.\n") );
-
- return changed;
-}
-
-
-/****************
- * Remove some of the secondary keys
- */
-static void
-menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
-{
- KBNODE node;
- int selected=0;
-
- for( node = pub_keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- selected = node->flag & NODFLG_SELKEY;
- if( selected ) {
- delete_kbnode( node );
- if( sec_keyblock ) {
- KBNODE snode;
- int s_selected = 0;
- u32 ki[2];
-
- keyid_from_pk( node->pkt->pkt.public_key, ki );
- for( snode = sec_keyblock; snode; snode = snode->next ) {
- if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- u32 ki2[2];
-
- keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
- s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
- if( s_selected )
- delete_kbnode( snode );
- }
- else if( s_selected
- && snode->pkt->pkttype == PKT_SIGNATURE )
- delete_kbnode( snode );
- else
- s_selected = 0;
- }
- }
- }
- }
- else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
- delete_kbnode( node );
- else
- selected = 0;
- }
- commit_kbnode( &pub_keyblock );
- if( sec_keyblock )
- commit_kbnode( &sec_keyblock );
-
- /* No need to set update_trust here since signing keys are no
- longer used to certify other keys, so there is no change in
- trust when revoking/removing them */
-}
-
-
-/****************
- * Ask for a new revoker, do the selfsignature and put it into
- * both keyblocks.
- * Return true if there is a new revoker
- */
-static int
-menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
-{
- PKT_public_key *pk=NULL,*revoker_pk=NULL;
- PKT_secret_key *sk=NULL;
- PKT_signature *sig=NULL;
- PACKET *pkt;
- struct revocation_key revkey;
- size_t fprlen;
- int rc;
-
- assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
- assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
-
- pk=pub_keyblock->pkt->pkt.public_key;
-
- if(pk->numrevkeys==0 && pk->version==3)
- {
- /* It is legal but bad for compatibility to add a revoker to a
- v3 key as it means that PGP2 will not be able to use that key
- anymore. Also, PGP may not expect a revoker on a v3 key.
- Don't bother to ask this if the key already has a revoker -
- any damage has already been done at that point. -dms */
- if(opt.expert)
- {
- tty_printf(_("WARNING: This is a PGP 2.x-style key. "
- "Adding a designated revoker may cause\n"
- " some versions of PGP to reject this key.\n"));
-
- if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
- _("Are you sure you still want "
- "to add it? (y/N) ")))
- return 0;
- }
- else
- {
- tty_printf(_("You may not add a designated revoker to "
- "a PGP 2.x-style key.\n"));
- return 0;
- }
- }
-
- sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
-
- for(;;)
- {
- char *answer;
- u32 keyid[2];
- char *p;
- size_t n;
-
- if(revoker_pk)
- free_public_key(revoker_pk);
-
- revoker_pk=xcalloc (1,sizeof(*revoker_pk));
-
- tty_printf("\n");
-
- answer=cpr_get_utf8("keyedit.add_revoker",
- _("Enter the user ID of the designated revoker: "));
- if(answer[0]=='\0' || answer[0]=='\004')
- {
- xfree(answer); answer = NULL;
- goto fail;
- }
-
- rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
-
- if(rc)
- {
- log_error (_("key `%s' not found: %s\n"),answer,gpg_strerror (rc));
- xfree (answer); answer = NULL;
- continue;
- }
-
- xfree (answer); answer = NULL;
-
-
- fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
- if(fprlen!=20)
- {
- log_error(_("cannot appoint a PGP 2.x style key as a "
- "designated revoker\n"));
- continue;
- }
-
- revkey.class=0x80;
- if(sensitive)
- revkey.class|=0x40;
- revkey.algid=revoker_pk->pubkey_algo;
-
- if(cmp_public_keys(revoker_pk,pk)==0)
- {
- /* This actually causes no harm (after all, a key that
- designates itself as a revoker is the same as a
- regular key), but it's easy enough to check. */
- log_error(_("you cannot appoint a key as its own "
- "designated revoker\n"));
-
- continue;
- }
-
- keyid_from_pk(pk,NULL);
-
- /* Does this revkey already exist? */
- if(!pk->revkey && pk->numrevkeys)
- BUG();
- else
- {
- int i;
-
- for(i=0;i<pk->numrevkeys;i++)
- {
- if(memcmp(&pk->revkey[i],&revkey,
- sizeof(struct revocation_key))==0)
- {
- char buf[50];
-
- log_error(_("this key has already been designated "
- "as a revoker\n"));
-
- sprintf(buf,"%08lX%08lX",
- (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
- write_status_text(STATUS_ALREADY_SIGNED,buf);
-
- break;
- }
- }
-
- if(i<pk->numrevkeys)
- continue;
- }
-
- keyid_from_pk(revoker_pk,keyid);
-
- tty_printf("\npub %4u%c/%08lX %s ",
- nbits_from_pk( revoker_pk ),
- pubkey_letter( revoker_pk->pubkey_algo ),
- (ulong)keyid[1], datestr_from_pk(pk) );
-
- p = get_user_id( keyid, &n );
- tty_print_utf8_string( p, n );
- xfree (p);
- tty_printf("\n");
- print_fingerprint(revoker_pk,NULL,2);
- tty_printf("\n");
-
- tty_printf(_("WARNING: appointing a key as a designated revoker "
- "cannot be undone!\n"));
-
- tty_printf("\n");
-
- if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
- _("Are you sure you want to appoint this "
- "key as a designated revoker? (y/N): ")))
- continue;
-
- free_public_key(revoker_pk);
- revoker_pk=NULL;
- break;
- }
-
- /* The 1F signature must be at least v4 to carry the revocation key
- subpacket. */
- rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
- keygen_add_revkey,&revkey );
- if( rc )
- {
- log_error("signing failed: %s\n", gpg_strerror (rc) );
- goto fail;
- }
-
- free_secret_key(sk);
- sk=NULL;
-
- /* insert into secret keyblock */
- pkt = xcalloc (1, sizeof *pkt );
- pkt->pkttype = PKT_SIGNATURE;
- pkt->pkt.signature = copy_signature(NULL, sig);
- insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
-
- /* insert into public keyblock */
- pkt = xcalloc (1, sizeof *pkt );
- pkt->pkttype = PKT_SIGNATURE;
- pkt->pkt.signature = sig;
- insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
-
- return 1;
-
- fail:
- if(sk)
- free_secret_key(sk);
- if(sig)
- free_seckey_enc(sig);
- if(revoker_pk)
- free_public_key(revoker_pk);
-
- return 0;
-}
-
-
-static int
-menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
-{
- int n1, signumber, rc;
- u32 expiredate;
- int mainkey=0;
- PKT_secret_key *sk; /* copy of the main sk */
- PKT_public_key *main_pk, *sub_pk;
- PKT_user_id *uid;
- KBNODE node;
- u32 keyid[2];
-
- if( count_selected_keys( sec_keyblock ) ) {
- tty_printf(_("Please remove selections from the secret keys.\n"));
- return 0;
- }
-
- n1 = count_selected_keys( pub_keyblock );
- if( n1 > 1 ) {
- tty_printf(_("Please select at most one secondary key.\n"));
- return 0;
- }
- else if( n1 )
- tty_printf(_("Changing expiration time for a secondary key.\n"));
- else {
- tty_printf(_("Changing expiration time for the primary key.\n"));
- mainkey=1;
- }
-
- no_primary_warning(pub_keyblock,0);
-
- expiredate = ask_expiredate();
- node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
- sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
-
- /* Now we can actually change the self signature(s) */
- main_pk = sub_pk = NULL;
- uid = NULL;
- signumber = 0;
- for( node=pub_keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
- main_pk = node->pkt->pkt.public_key;
- keyid_from_pk( main_pk, keyid );
- main_pk->expiredate = expiredate;
- }
- else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
- && (node->flag & NODFLG_SELKEY ) ) {
- sub_pk = node->pkt->pkt.public_key;
- sub_pk->expiredate = expiredate;
- }
- else if( node->pkt->pkttype == PKT_USER_ID )
- uid = node->pkt->pkt.user_id;
- else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
- && ( mainkey || sub_pk ) ) {
- PKT_signature *sig = node->pkt->pkt.signature;
- if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
- && ( (mainkey && uid
- && uid->created && (sig->sig_class&~3) == 0x10)
- || (!mainkey && sig->sig_class == 0x18) ) ) {
- /* this is a selfsignature which is to be replaced */
- PKT_signature *newsig;
- PACKET *newpkt;
- KBNODE sn;
- int signumber2 = 0;
-
- signumber++;
-
- if( (mainkey && main_pk->version < 4)
- || (!mainkey && sub_pk->version < 4 ) ) {
- log_info(_(
- "You can't change the expiration date of a v3 key\n"));
- free_secret_key( sk );
- return 0;
- }
-
- /* find the corresponding secret self-signature */
- for( sn=sec_keyblock; sn; sn = sn->next ) {
- if( sn->pkt->pkttype == PKT_SIGNATURE ) {
- PKT_signature *b = sn->pkt->pkt.signature;
- if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
- && sig->sig_class == b->sig_class
- && ++signumber2 == signumber )
- break;
- }
- }
- if( !sn )
- log_info(_("No corresponding signature in secret ring\n"));
-
- if( mainkey )
- rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
- sk, keygen_add_key_expire, main_pk);
- else
- rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
- sk, keygen_add_key_expire, sub_pk );
- if( rc ) {
- log_error("make_keysig_packet failed: %s\n",
- gpg_strerror (rc));
- free_secret_key( sk );
- return 0;
- }
- /* replace the packet */
- newpkt = xcalloc (1, sizeof *newpkt );
- newpkt->pkttype = PKT_SIGNATURE;
- newpkt->pkt.signature = newsig;
- free_packet( node->pkt );
- xfree ( node->pkt );
- node->pkt = newpkt;
- if( sn ) {
- newpkt = xcalloc (1, sizeof *newpkt );
- newpkt->pkttype = PKT_SIGNATURE;
- newpkt->pkt.signature = copy_signature( NULL, newsig );
- free_packet( sn->pkt );
- xfree ( sn->pkt );
- sn->pkt = newpkt;
- }
- sub_pk = NULL;
- }
- }
- }
-
- free_secret_key( sk );
- update_trust=1;
- return 1;
-}
-
-static int
-change_primary_uid_cb ( PKT_signature *sig, void *opaque )
-{
- byte buf[1];
-
- /* first clear all primary uid flags so that we are sure none are
- * lingering around */
- delete_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID);
- delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
-
- /* if opaque is set,we want to set the primary id */
- if (opaque) {
- buf[0] = 1;
- build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
- }
-
- return 0;
-}
-
-
-/*
- * Set the primary uid flag for the selected UID. We will also reset
- * all other primary uid flags. For this to work with have to update
- * all the signature timestamps. If we would do this with the current
- * time, we lose quite a lot of information, so we use a a kludge to
- * do this: Just increment the timestamp by one second which is
- * sufficient to updated a signature during import.
- */
-static int
-menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
-{
- PKT_secret_key *sk; /* copy of the main sk */
- PKT_public_key *main_pk;
- PKT_user_id *uid;
- KBNODE node;
- u32 keyid[2];
- int selected;
- int attribute = 0;
- int modified = 0;
-
- if ( count_selected_uids (pub_keyblock) != 1 ) {
- tty_printf(_("Please select exactly one user ID.\n"));
- return 0;
- }
-
- node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
- sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
-
- /* Now we can actually change the self signature(s) */
- main_pk = NULL;
- uid = NULL;
- selected = 0;
-
- /* Is our selected uid an attribute packet? */
- for ( node=pub_keyblock; node; node = node->next )
- if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
- attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
-
- for ( node=pub_keyblock; node; node = node->next ) {
- if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
- break; /* ready */
-
- if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
- main_pk = node->pkt->pkt.public_key;
- keyid_from_pk( main_pk, keyid );
- }
- else if ( node->pkt->pkttype == PKT_USER_ID ) {
- uid = node->pkt->pkt.user_id;
- selected = node->flag & NODFLG_SELUID;
- }
- else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
- PKT_signature *sig = node->pkt->pkt.signature;
- if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
- && (uid && (sig->sig_class&~3) == 0x10)
- && attribute == (uid->attrib_data!=NULL)) {
- if(sig->version < 4) {
- char *user=utf8_to_native(uid->name,strlen(uid->name),0);
-
- log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
- user);
- xfree (user);
- }
- else {
- /* This is a selfsignature which is to be replaced.
- We can just ignore v3 signatures because they are
- not able to carry the primary ID flag. We also
- ignore self-sigs on user IDs that are not of the
- same type that we are making primary. That is, if
- we are making a user ID primary, we alter user IDs.
- If we are making an attribute packet primary, we
- alter attribute packets. */
-
- /* FIXME: We must make sure that we only have one
- self-signature per user ID here (not counting
- revocations) */
- PKT_signature *newsig;
- PACKET *newpkt;
- const byte *p;
- int action;
-
- /* see whether this signature has the primary UID flag */
- p = parse_sig_subpkt (sig->hashed,
- SIGSUBPKT_PRIMARY_UID, NULL );
- if ( !p )
- p = parse_sig_subpkt (sig->unhashed,
- SIGSUBPKT_PRIMARY_UID, NULL );
- if ( p && *p ) /* yes */
- action = selected? 0 : -1;
- else /* no */
- action = selected? 1 : 0;
-
- if (action) {
- int rc = update_keysig_packet (&newsig, sig,
- main_pk, uid, NULL,
- sk,
- change_primary_uid_cb,
- action > 0? "x":NULL );
- if( rc ) {
- log_error ("update_keysig_packet failed: %s\n",
- gpg_strerror (rc));
- free_secret_key( sk );
- return 0;
- }
- /* replace the packet */
- newpkt = xcalloc (1, sizeof *newpkt );
- newpkt->pkttype = PKT_SIGNATURE;
- newpkt->pkt.signature = newsig;
- free_packet( node->pkt );
- xfree ( node->pkt );
- node->pkt = newpkt;
- modified = 1;
- }
- }
- }
- }
- }
-
- free_secret_key( sk );
- return modified;
-}
-
-
-/*
- * Set preferences to new values for the selected user IDs
- */
-static int
-menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
-{
- PKT_secret_key *sk; /* copy of the main sk */
- PKT_public_key *main_pk;
- PKT_user_id *uid;
- KBNODE node;
- u32 keyid[2];
- int selected, select_all;
- int modified = 0;
-
- no_primary_warning(pub_keyblock,1);
-
- select_all = !count_selected_uids (pub_keyblock);
-
- node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
- sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
-
- /* Now we can actually change the self signature(s) */
- main_pk = NULL;
- uid = NULL;
- selected = 0;
- for ( node=pub_keyblock; node; node = node->next ) {
- if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
- break; /* ready */
-
- if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
- main_pk = node->pkt->pkt.public_key;
- keyid_from_pk( main_pk, keyid );
- }
- else if ( node->pkt->pkttype == PKT_USER_ID ) {
- uid = node->pkt->pkt.user_id;
- selected = select_all || (node->flag & NODFLG_SELUID);
- }
- else if ( main_pk && uid && selected
- && node->pkt->pkttype == PKT_SIGNATURE ) {
- PKT_signature *sig = node->pkt->pkt.signature;
- if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
- && (uid && (sig->sig_class&~3) == 0x10) ) {
- if( sig->version < 4 ) {
- char *user=utf8_to_native(uid->name,strlen(uid->name),0);
-
- log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
- user);
- xfree (user);
- }
- else {
- /* This is a selfsignature which is to be replaced
- * We have to ignore v3 signatures because they are
- * not able to carry the preferences */
- PKT_signature *newsig;
- PACKET *newpkt;
- int rc;
-
- rc = update_keysig_packet (&newsig, sig,
- main_pk, uid, NULL,
- sk,
- keygen_upd_std_prefs,
- NULL );
- if( rc ) {
- log_error ("update_keysig_packet failed: %s\n",
- gpg_strerror (rc));
- free_secret_key( sk );
- return 0;
- }
- /* replace the packet */
- newpkt = xcalloc (1, sizeof *newpkt );
- newpkt->pkttype = PKT_SIGNATURE;
- newpkt->pkt.signature = newsig;
- free_packet( node->pkt );
- xfree ( node->pkt );
- node->pkt = newpkt;
- modified = 1;
- }
- }
- }
- }
-
- free_secret_key( sk );
- return modified;
-}
-
-
-
-static int
-menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock )
-{
- PKT_secret_key *sk; /* copy of the main sk */
- PKT_public_key *main_pk;
- PKT_user_id *uid;
- KBNODE node;
- u32 keyid[2];
- int selected, select_all;
- int modified = 0;
- char *answer;
-
- no_primary_warning(pub_keyblock,1);
-
- answer=cpr_get_utf8("keyedit.add_keyserver",
- _("Enter your preferred keyserver URL: "));
- if(answer[0]=='\0' || answer[0]=='\004')
- {
- xfree(answer);
- return 0;
- }
-
- select_all = !count_selected_uids (pub_keyblock);
-
- node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
- sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
-
- /* Now we can actually change the self signature(s) */
- main_pk = NULL;
- uid = NULL;
- selected = 0;
- for ( node=pub_keyblock; node; node = node->next ) {
- if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
- break; /* ready */
-
- if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
- main_pk = node->pkt->pkt.public_key;
- keyid_from_pk( main_pk, keyid );
- }
- else if ( node->pkt->pkttype == PKT_USER_ID ) {
- uid = node->pkt->pkt.user_id;
- selected = select_all || (node->flag & NODFLG_SELUID);
- }
- else if ( main_pk && uid && selected
- && node->pkt->pkttype == PKT_SIGNATURE ) {
- PKT_signature *sig = node->pkt->pkt.signature;
- if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
- && (uid && (sig->sig_class&~3) == 0x10) ) {
- if( sig->version < 4 ) {
- char *user=utf8_to_native(uid->name,strlen(uid->name),0);
-
- log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
- user);
- xfree(user);
- }
- else {
- /* This is a selfsignature which is to be replaced
- * We have to ignore v3 signatures because they are
- * not able to carry the preferences */
- PKT_signature *newsig;
- PACKET *newpkt;
- int rc;
-
- rc = update_keysig_packet (&newsig, sig,
- main_pk, uid, NULL,
- sk,
- keygen_add_keyserver_url,
- answer );
- if( rc ) {
- log_error ("update_keysig_packet failed: %s\n",
- gpg_strerror (rc));
- xfree(answer);
- free_secret_key( sk );
- return 0;
- }
- /* replace the packet */
- newpkt = xcalloc (1, sizeof *newpkt );
- newpkt->pkttype = PKT_SIGNATURE;
- newpkt->pkt.signature = newsig;
- free_packet( node->pkt );
- xfree (node->pkt);
- node->pkt = newpkt;
- modified = 1;
- }
- }
- }
- }
-
- xfree(answer);
- free_secret_key( sk );
- return modified;
-}
-
-
-/****************
- * Select one user id or remove all selection if index is 0.
- * Returns: True if the selection changed;
- */
-static int
-menu_select_uid( KBNODE keyblock, int idx )
-{
- KBNODE node;
- int i;
-
- /* first check that the index is valid */
- if( idx ) {
- for( i=0, node = keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_USER_ID ) {
- if( ++i == idx )
- break;
- }
- }
- if( !node ) {
- tty_printf(_("No user ID with index %d\n"), idx );
- return 0;
- }
- }
- else { /* reset all */
- for( i=0, node = keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_USER_ID )
- node->flag &= ~NODFLG_SELUID;
- }
- return 1;
- }
- /* and toggle the new index */
- for( i=0, node = keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_USER_ID ) {
- if( ++i == idx ) {
- if( (node->flag & NODFLG_SELUID) )
- node->flag &= ~NODFLG_SELUID;
- else
- node->flag |= NODFLG_SELUID;
- }
- }
- }
-
- return 1;
-}
-
-/****************
- * Select secondary keys
- * Returns: True if the selection changed;
- */
-static int
-menu_select_key( KBNODE keyblock, int idx )
-{
- KBNODE node;
- int i;
-
- /* first check that the index is valid */
- if( idx ) {
- for( i=0, node = keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- if( ++i == idx )
- break;
- }
- }
- if( !node ) {
- tty_printf(_("No secondary key with index %d\n"), idx );
- return 0;
- }
- }
- else { /* reset all */
- for( i=0, node = keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || node->pkt->pkttype == PKT_SECRET_SUBKEY )
- node->flag &= ~NODFLG_SELKEY;
- }
- return 1;
- }
- /* and set the new index */
- for( i=0, node = keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- if( ++i == idx ) {
- if( (node->flag & NODFLG_SELKEY) )
- node->flag &= ~NODFLG_SELKEY;
- else
- node->flag |= NODFLG_SELKEY;
- }
- }
- }
-
- return 1;
-}
-
-
-static int
-count_uids_with_flag( KBNODE keyblock, unsigned flag )
-{
- KBNODE node;
- int i=0;
-
- for( node = keyblock; node; node = node->next )
- if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
- i++;
- return i;
-}
-
-static int
-count_keys_with_flag( KBNODE keyblock, unsigned flag )
-{
- KBNODE node;
- int i=0;
-
- for( node = keyblock; node; node = node->next )
- if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || node->pkt->pkttype == PKT_SECRET_SUBKEY)
- && (node->flag & flag) )
- i++;
- return i;
-}
-
-static int
-count_uids( KBNODE keyblock )
-{
- KBNODE node;
- int i=0;
-
- for( node = keyblock; node; node = node->next )
- if( node->pkt->pkttype == PKT_USER_ID )
- i++;
- return i;
-}
-
-
-/****************
- * Returns true if there is at least one selected user id
- */
-static int
-count_selected_uids( KBNODE keyblock )
-{
- return count_uids_with_flag( keyblock, NODFLG_SELUID);
-}
-
-static int
-count_selected_keys( KBNODE keyblock )
-{
- return count_keys_with_flag( keyblock, NODFLG_SELKEY);
-}
-
-/* returns how many real (i.e. not attribute) uids are unmarked */
-static int
-real_uids_left( KBNODE keyblock )
-{
- KBNODE node;
- int real=0;
-
- for(node=keyblock;node;node=node->next)
- if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) &&
- !node->pkt->pkt.user_id->attrib_data)
- real++;
-
- return real;
-}
-
-/*
- * Ask whether the signature should be revoked. If the user commits this,
- * flag bit MARK_A is set on the signature and the user ID.
- */
-static void
-ask_revoke_sig( KBNODE keyblock, KBNODE node )
-{
- int doit=0;
- PKT_signature *sig = node->pkt->pkt.signature;
- KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
-
- if( !unode ) {
- log_error("Oops: no user ID for signature\n");
- return;
- }
-
- tty_printf(_("user ID: \""));
- tty_print_utf8_string( unode->pkt->pkt.user_id->name,
- unode->pkt->pkt.user_id->len );
-
- if(sig->flags.exportable)
- tty_printf(_("\"\nsigned with your key %08lX at %s\n"),
- (ulong)sig->keyid[1], datestr_from_sig(sig) );
- else
- tty_printf(_("\"\nlocally signed with your key %08lX at %s\n"),
- (ulong)sig->keyid[1], datestr_from_sig(sig) );
-
- if(sig->flags.expired)
- {
- tty_printf(_("This signature expired on %s.\n"),
- expirestr_from_sig(sig));
- /* Use a different question so we can have different help text */
- doit=cpr_get_answer_is_yes("ask_revoke_sig.expired",
- _("Are you sure you still want to revoke it? (y/N) "));
- }
- else
- doit=cpr_get_answer_is_yes("ask_revoke_sig.one",
- _("Create a revocation certificate for this signature? (y/N) "));
-
- if(doit) {
- node->flag |= NODFLG_MARK_A;
- unode->flag |= NODFLG_MARK_A;
- }
-}
-
-/****************
- * Display all user ids of the current public key together with signatures
- * done by one of our keys. Then walk over all this sigs and ask the user
- * whether he wants to revoke this signature.
- * Return: True when the keyblock has changed.
- */
-static int
-menu_revsig( KBNODE keyblock )
-{
- PKT_signature *sig;
- PKT_public_key *primary_pk;
- KBNODE node;
- int changed = 0;
- int rc, any, skip=1, all=!count_selected_uids(keyblock);
- struct revocation_reason_info *reason = NULL;
-
- /* FIXME: detect duplicates here */
- tty_printf(_("You have signed these user IDs:\n"));
- for( node = keyblock; node; node = node->next ) {
- node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
- if( node->pkt->pkttype == PKT_USER_ID ) {
- if( node->flag&NODFLG_SELUID || all ) {
- PKT_user_id *uid = node->pkt->pkt.user_id;
- /* Hmmm: Should we show only UIDs with a signature? */
- tty_printf(" ");
- tty_print_utf8_string( uid->name, uid->len );
- tty_printf("\n");
- skip=0;
- }
- else
- skip=1;
- }
- else if( !skip && node->pkt->pkttype == PKT_SIGNATURE
- && ((sig = node->pkt->pkt.signature),
- !seckey_available(sig->keyid) ) ) {
- if( (sig->sig_class&~3) == 0x10 ) {
- tty_printf(_(" signed by %08lX at %s%s%s\n"),
- (ulong)sig->keyid[1], datestr_from_sig(sig),
- sig->flags.exportable?"":" (non-exportable)",
- sig->flags.revocable?"":" (non-revocable)");
- if(sig->flags.revocable)
- node->flag |= NODFLG_SELSIG;
- }
- else if( sig->sig_class == 0x30 ) {
- tty_printf(_(" revoked by %08lX at %s\n"),
- (ulong)sig->keyid[1], datestr_from_sig(sig) );
- }
- }
- }
-
- /* ask */
- for( node = keyblock; node; node = node->next ) {
- if( !(node->flag & NODFLG_SELSIG) )
- continue;
- ask_revoke_sig( keyblock, node );
- }
-
- /* present selected */
- any = 0;
- for( node = keyblock; node; node = node->next ) {
- if( !(node->flag & NODFLG_MARK_A) )
- continue;
- if( !any ) {
- any = 1;
- tty_printf(_("You are about to revoke these signatures:\n"));
- }
- if( node->pkt->pkttype == PKT_USER_ID ) {
- PKT_user_id *uid = node->pkt->pkt.user_id;
- tty_printf(" ");
- tty_print_utf8_string( uid->name, uid->len );
- tty_printf("\n");
- }
- else if( node->pkt->pkttype == PKT_SIGNATURE ) {
- sig = node->pkt->pkt.signature;
- tty_printf(_(" signed by %08lX at %s%s\n"),
- (ulong)sig->keyid[1], datestr_from_sig(sig),
- sig->flags.exportable?"":_(" (non-exportable)") );
- }
- }
- if( !any )
- return 0; /* none selected */
-
- if( !cpr_get_answer_is_yes("ask_revoke_sig.okay",
- _("Really create the revocation certificates? (y/N) ")) )
- return 0; /* forget it */
-
- reason = ask_revocation_reason( 0, 1, 0 );
- if( !reason ) { /* user decided to cancel */
- return 0;
- }
-
- /* now we can sign the user ids */
- reloop: /* (must use this, because we are modifing the list) */
- primary_pk = keyblock->pkt->pkt.public_key;
- for( node=keyblock; node; node = node->next ) {
- KBNODE unode;
- PACKET *pkt;
- struct sign_attrib attrib;
- PKT_secret_key *sk;
-
- if( !(node->flag & NODFLG_MARK_A)
- || node->pkt->pkttype != PKT_SIGNATURE )
- continue;
- unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
- assert( unode ); /* we already checked this */
-
- memset( &attrib, 0, sizeof attrib );
- attrib.reason = reason;
- attrib.non_exportable=!node->pkt->pkt.signature->flags.exportable;
-
- node->flag &= ~NODFLG_MARK_A;
- sk = xcalloc_secure (1, sizeof *sk );
- if( get_seckey( sk, node->pkt->pkt.signature->keyid ) ) {
- log_info(_("no secret key\n"));
- continue;
- }
- rc = make_keysig_packet( &sig, primary_pk,
- unode->pkt->pkt.user_id,
- NULL,
- sk,
- 0x30, 0, 0, 0, 0,
- sign_mk_attrib,
- &attrib );
- free_secret_key(sk);
- if( rc ) {
- log_error(_("signing failed: %s\n"), gpg_strerror (rc));
- release_revocation_reason_info( reason );
- return changed;
- }
- changed = 1; /* we changed the keyblock */
- update_trust = 1;
- /* Are we revoking our own uid? */
- if(primary_pk->keyid[0]==sig->keyid[0] &&
- primary_pk->keyid[1]==sig->keyid[1])
- unode->pkt->pkt.user_id->is_revoked=1;
- pkt = xcalloc (1, sizeof *pkt );
- pkt->pkttype = PKT_SIGNATURE;
- pkt->pkt.signature = sig;
- insert_kbnode( unode, new_kbnode(pkt), 0 );
- goto reloop;
- }
-
- release_revocation_reason_info( reason );
- return changed;
-}
-
-/* Revoke a user ID (i.e. revoke a user ID selfsig). Return true if
- keyblock changed. */
-static int
-menu_revuid( KBNODE pub_keyblock, KBNODE sec_keyblock )
-{
- PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
- PKT_secret_key *sk = copy_secret_key( NULL,
- sec_keyblock->pkt->pkt.secret_key );
- KBNODE node;
- int changed = 0;
- int rc;
- struct revocation_reason_info *reason = NULL;
-
- /* Note that this is correct as per the RFCs, but nevertheless
- somewhat meaningless in the real world. 1991 did define the 0x30
- sig class, but PGP 2.x did not actually implement it, so it would
- probably be safe to use v4 revocations everywhere. -ds */
-
- for( node = pub_keyblock; node; node = node->next )
- if(pk->version>3 || (node->pkt->pkttype==PKT_USER_ID &&
- node->pkt->pkt.user_id->selfsigversion>3))
- {
- if((reason = ask_revocation_reason( 0, 1, 4 )))
- break;
- else
- goto leave;
- }
-
- reloop: /* (better this way because we are modifing the keyring) */
- for( node = pub_keyblock; node; node = node->next )
- if(node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID))
- {
- PKT_user_id *uid=node->pkt->pkt.user_id;
-
- if(uid->is_revoked)
- {
- char *user=utf8_to_native(uid->name,uid->len,0);
- log_info(_("user ID \"%s\" is already revoked\n"),user);
- xfree (user);
- }
- else
- {
- PACKET *pkt;
- PKT_signature *sig;
- struct sign_attrib attrib;
- u32 timestamp=make_timestamp();
-
- if(uid->created>=timestamp)
- {
- /* Okay, this is a problem. The user ID selfsig was
- created in the future, so we need to warn the user and
- set our revocation timestamp one second after that so
- everything comes out clean. */
-
- log_info(_("WARNING: a user ID signature is dated %d"
- " seconds in the future\n"),uid->created-timestamp);
-
- timestamp=uid->created+1;
- }
-
- memset( &attrib, 0, sizeof attrib );
- attrib.reason = reason;
-
- node->flag &= ~NODFLG_SELUID;
-
- rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x30, 0,
- (reason==NULL)?3:0, timestamp, 0,
- sign_mk_attrib, &attrib );
- if( rc )
- {
- log_error(_("signing failed: %s\n"), gpg_strerror (rc));
- goto leave;
- }
- else
- {
- pkt = xcalloc (1, sizeof *pkt );
- pkt->pkttype = PKT_SIGNATURE;
- pkt->pkt.signature = sig;
- insert_kbnode( node, new_kbnode(pkt), 0 );
-
- /* If the trustdb has an entry for this key+uid then the
- trustdb needs an update. */
- if(!update_trust
- && (get_validity(pk,uid)&TRUST_MASK)>=TRUST_UNDEFINED)
- update_trust=1;
-
- changed = 1;
- node->pkt->pkt.user_id->is_revoked=1;
-
- goto reloop;
- }
- }
- }
-
- if(changed)
- commit_kbnode( &pub_keyblock );
-
- leave:
- free_secret_key(sk);
- release_revocation_reason_info( reason );
- return changed;
-}
-
-/****************
- * Revoke some of the secondary keys.
- * Hmmm: Should we add a revocation to the secret keyring too?
- * Does its all make sense to duplicate most of the information?
- */
-static int
-menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
-{
- PKT_public_key *mainpk;
- KBNODE node;
- int changed = 0;
- int rc;
- struct revocation_reason_info *reason = NULL;
-
- reason = ask_revocation_reason( 1, 0, 0 );
- if( !reason ) { /* user decided to cancel */
- return 0;
- }
-
- reloop: /* (better this way because we are modifing the keyring) */
- mainpk = pub_keyblock->pkt->pkt.public_key;
- for( node = pub_keyblock; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
- && (node->flag & NODFLG_SELKEY) ) {
- PACKET *pkt;
- PKT_signature *sig;
- PKT_secret_key *sk;
- PKT_public_key *subpk = node->pkt->pkt.public_key;
- struct sign_attrib attrib;
-
- memset( &attrib, 0, sizeof attrib );
- attrib.reason = reason;
-
- node->flag &= ~NODFLG_SELKEY;
- sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
- rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk,
- 0x28, 0, 0, 0, 0,
- sign_mk_attrib, &attrib );
- free_secret_key(sk);
- if( rc ) {
- log_error(_("signing failed: %s\n"), gpg_strerror (rc));
- release_revocation_reason_info( reason );
- return changed;
- }
- changed = 1; /* we changed the keyblock */
-
- pkt = xcalloc (1, sizeof *pkt );
- pkt->pkttype = PKT_SIGNATURE;
- pkt->pkt.signature = sig;
- insert_kbnode( node, new_kbnode(pkt), 0 );
- goto reloop;
- }
- }
- commit_kbnode( &pub_keyblock );
- /*commit_kbnode( &sec_keyblock );*/
-
- /* No need to set update_trust here since signing keys no longer
- are used to certify other keys, so there is no change in trust
- when revoking/removing them */
-
- release_revocation_reason_info( reason );
- return changed;
-}
-
-/* Note that update_ownertrust is going to mark the trustdb dirty when
- enabling or disabling a key. This is arguably sub-optimal as
- disabled keys are still counted in the web of trust, but perhaps
- not worth adding extra complexity to change. -ds */
-static int
-enable_disable_key( KBNODE keyblock, int disable )
-{
- PKT_public_key *pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )
- ->pkt->pkt.public_key;
- unsigned int trust, newtrust;
-
- trust = newtrust = get_ownertrust (pk);
- newtrust &= ~TRUST_FLAG_DISABLED;
- if( disable )
- newtrust |= TRUST_FLAG_DISABLED;
- if( trust == newtrust )
- return 0; /* already in that state */
- update_ownertrust(pk, newtrust );
- return 0;
-}
-
-
-static void
-menu_showphoto( KBNODE keyblock )
-{
- KBNODE node;
- int select_all = !count_selected_uids(keyblock);
- int count=0;
- PKT_public_key *pk=NULL;
- u32 keyid[2];
-
- /* Look for the public key first. We have to be really, really,
- explicit as to which photo this is, and what key it is a UID on
- since people may want to sign it. */
-
- for( node = keyblock; node; node = node->next )
- {
- if( node->pkt->pkttype == PKT_PUBLIC_KEY )
- {
- pk = node->pkt->pkt.public_key;
- keyid_from_pk(pk, keyid);
- }
- else if( node->pkt->pkttype == PKT_USER_ID )
- {
- PKT_user_id *uid = node->pkt->pkt.user_id;
- count++;
-
- if((select_all || (node->flag & NODFLG_SELUID)) &&
- uid->attribs!=NULL)
- {
- int i;
-
- for(i=0;i<uid->numattribs;i++)
- {
- byte type;
- u32 size;
-
- if(uid->attribs[i].type==ATTRIB_IMAGE &&
- parse_image_header(&uid->attribs[i],&type,&size))
- {
- tty_printf(_("Displaying %s photo ID of size %ld for "
- "key 0x%08lX (uid %d)\n"),
- image_type_to_string(type,1),
- (ulong)size,(ulong)keyid[1],count);
- show_photos(&uid->attribs[i],1,pk,NULL);
- }
- }
- }
- }
- }
-}
diff --git a/g10/keygen.c b/g10/keygen.c
deleted file mode 100644
index 72c5e1e8a..000000000
--- a/g10/keygen.c
+++ /dev/null
@@ -1,2916 +0,0 @@
-/* keygen.c - generate a key pair
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003, 2004 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "main.h"
-#include "packet.h"
-#include "cipher.h"
-#include "ttyio.h"
-#include "options.h"
-#include "keydb.h"
-#include "trustdb.h"
-#include "status.h"
-#include "i18n.h"
-#include "call-agent.h"
-
-
-#define MAX_PREFS 30
-
-enum para_name {
- pKEYTYPE,
- pKEYLENGTH,
- pKEYUSAGE,
- pSUBKEYTYPE,
- pSUBKEYLENGTH,
- pSUBKEYUSAGE,
- pAUTHKEYTYPE,
- pNAMEREAL,
- pNAMEEMAIL,
- pNAMECOMMENT,
- pPREFERENCES,
- pREVOKER,
- pUSERID,
- pEXPIREDATE,
- pKEYEXPIRE, /* in n seconds */
- pSUBKEYEXPIRE, /* in n seconds */
- pPASSPHRASE,
- pPASSPHRASE_DEK,
- pPASSPHRASE_S2K,
- pSERIALNO
-};
-
-struct para_data_s {
- struct para_data_s *next;
- int lnr;
- enum para_name key;
- union {
- DEK *dek;
- STRING2KEY *s2k;
- u32 expire;
- unsigned int usage;
- struct revocation_key revkey;
- char value[1];
- } u;
-};
-
-struct output_control_s {
- int lnr;
- int dryrun;
- int use_files;
- struct {
- char *fname;
- char *newfname;
- iobuf_t stream;
- armor_filter_context_t afx;
- } pub;
- struct {
- char *fname;
- char *newfname;
- iobuf_t stream;
- armor_filter_context_t afx;
- } sec;
-};
-
-
-struct opaque_data_usage_and_pk {
- unsigned int usage;
- PKT_public_key *pk;
-};
-
-
-static int prefs_initialized = 0;
-static byte sym_prefs[MAX_PREFS];
-static int nsym_prefs;
-static byte hash_prefs[MAX_PREFS];
-static int nhash_prefs;
-static byte zip_prefs[MAX_PREFS];
-static int nzip_prefs;
-static int mdc_available,ks_modify;
-
-static void do_generate_keypair( struct para_data_s *para,
- struct output_control_s *outctrl, int card);
-static int write_keyblock( iobuf_t out, KBNODE node );
-static int gen_card_key (int algo, int keyno, KBNODE pub_root, KBNODE sec_root,
- u32 expireval, struct para_data_s *para);
-
-
-
-static void
-write_uid( KBNODE root, const char *s )
-{
- PACKET *pkt = xcalloc (1,sizeof *pkt );
- size_t n = strlen(s);
-
- pkt->pkttype = PKT_USER_ID;
- pkt->pkt.user_id = xcalloc (1, sizeof *pkt->pkt.user_id + n - 1 );
- pkt->pkt.user_id->len = n;
- pkt->pkt.user_id->ref = 1;
- strcpy(pkt->pkt.user_id->name, s);
- add_kbnode( root, new_kbnode( pkt ) );
-}
-
-static void
-do_add_key_flags (PKT_signature *sig, unsigned int use)
-{
- byte buf[1];
-
- if (!use)
- return;
-
- buf[0] = 0;
- if (use & PUBKEY_USAGE_SIG)
- {
- if(sig->sig_class==0x18)
- buf[0] |= 0x02; /* Don't set the certify flag for subkeys */
- else
- buf[0] |= 0x01 | 0x02;
- }
- if (use & PUBKEY_USAGE_ENC)
- buf[0] |= 0x04 | 0x08;
- if (use & PUBKEY_USAGE_AUTH)
- buf[0] |= 0x20;
- build_sig_subpkt (sig, SIGSUBPKT_KEY_FLAGS, buf, 1);
-}
-
-
-int
-keygen_add_key_expire( PKT_signature *sig, void *opaque )
-{
- PKT_public_key *pk = opaque;
- byte buf[8];
- u32 u;
-
- if( pk->expiredate ) {
- if(pk->expiredate > pk->timestamp)
- u= pk->expiredate - pk->timestamp;
- else
- u= 0;
-
- buf[0] = (u >> 24) & 0xff;
- buf[1] = (u >> 16) & 0xff;
- buf[2] = (u >> 8) & 0xff;
- buf[3] = u & 0xff;
- build_sig_subpkt( sig, SIGSUBPKT_KEY_EXPIRE, buf, 4 );
- }
- else
- {
- /* Make sure we don't leave a key expiration subpacket lying
- around */
- delete_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE);
- }
-
- return 0;
-}
-
-static int
-keygen_add_key_flags_and_expire (PKT_signature *sig, void *opaque)
-{
- struct opaque_data_usage_and_pk *oduap = opaque;
-
- do_add_key_flags (sig, oduap->usage);
- return keygen_add_key_expire (sig, oduap->pk);
-}
-
-static int
-set_one_pref (int val, int type, const char *item, byte *buf, int *nbuf)
-{
- int i;
-
- for (i=0; i < *nbuf; i++ )
- if (buf[i] == val)
- {
- log_info (_("preference `%s' duplicated\n"), item);
- return -1;
- }
-
- if (*nbuf >= MAX_PREFS)
- {
- if(type==1)
- log_info(_("too many cipher preferences\n"));
- else if(type==2)
- log_info(_("too many digest preferences\n"));
- else if(type==3)
- log_info(_("too many compression preferences\n"));
- else
- BUG();
-
- return -1;
- }
-
- buf[(*nbuf)++] = val;
- return 0;
-}
-
-#ifdef USE_AES
-#define AES "S9 S8 S7 "
-#else
-#define AES ""
-#endif
-
-#ifdef USE_CAST5
-#define CAST5 "S3 "
-#else
-#define CAST5 ""
-#endif
-
-/*
- * Parse the supplied string and use it to set the standard
- * preferences. The string may be in a form like the one printed by
- * "pref" (something like: "S10 S3 H3 H2 Z2 Z1") or the actual
- * cipher/hash/compress names. Use NULL to set the default
- * preferences. Returns: 0 = okay
- */
-int
-keygen_set_std_prefs (const char *string,int personal)
-{
- byte sym[MAX_PREFS], hash[MAX_PREFS], zip[MAX_PREFS];
- int nsym=0, nhash=0, nzip=0, val, rc=0;
- int mdc=1, modify=0; /* mdc defaults on, modify defaults off. */
-
- if (!string || !ascii_strcasecmp (string, "default")) {
- if (opt.def_preference_list)
- string=opt.def_preference_list;
- else if ( !openpgp_cipher_test_algo(CIPHER_ALGO_IDEA) )
- string = AES CAST5 "S2 S1 H2 H3 Z2 Z1";
- else
- string = AES CAST5 "S2 H2 H3 Z2 Z1";
-
- /* If we have it, IDEA goes *after* 3DES so it won't be used
- unless we're encrypting along with a V3 key. Ideally, we
- would only put the S1 preference in if the key was RSA and
- <=2048 bits, as that is what won't break PGP2, but that is
- difficult with the current code, and not really worth
- checking as a non-RSA <=2048 bit key wouldn't be usable by
- PGP2 anyway. -dms */
- }
- else if (!ascii_strcasecmp (string, "none"))
- string = "";
-
- if(strlen(string))
- {
- char *tok,*prefstring;
-
- prefstring=xstrdup (string); /* need a writable string! */
-
- while((tok=strsep(&prefstring," ,")))
- {
- if((val=openpgp_cipher_map_name(tok)))
- {
- if(set_one_pref(val,1,tok,sym,&nsym))
- rc=-1;
- }
- else if((val=openpgp_md_map_name(tok)))
- {
- if(set_one_pref(val,2,tok,hash,&nhash))
- rc=-1;
- }
- else if((val=string_to_compress_algo(tok))>-1)
- {
- if(set_one_pref(val,3,tok,zip,&nzip))
- rc=-1;
- }
- else if (ascii_strcasecmp(tok,"mdc")==0)
- mdc=1;
- else if (ascii_strcasecmp(tok,"no-mdc")==0)
- mdc=0;
- else if (ascii_strcasecmp(tok,"ks-modify")==0)
- modify=1;
- else if (ascii_strcasecmp(tok,"no-ks-modify")==0)
- modify=0;
- else
- {
- log_info (_("invalid item `%s' in preference string\n"),tok);
-
- /* Complain if IDEA is not available. */
- if(ascii_strcasecmp(tok,"s1")==0
- || ascii_strcasecmp(tok,"idea")==0)
- idea_cipher_warn(1);
-
- rc=-1;
- }
- }
-
- xfree (prefstring);
- }
-
- if(!rc)
- {
- if(personal)
- {
- if(personal==PREFTYPE_SYM)
- {
- xfree (opt.personal_cipher_prefs);
-
- if(nsym==0)
- opt.personal_cipher_prefs=NULL;
- else
- {
- int i;
-
- opt.personal_cipher_prefs=
- xmalloc (sizeof(prefitem_t *)*(nsym+1));
-
- for (i=0; i<nsym; i++)
- {
- opt.personal_cipher_prefs[i].type = PREFTYPE_SYM;
- opt.personal_cipher_prefs[i].value = sym[i];
- }
-
- opt.personal_cipher_prefs[i].type = PREFTYPE_NONE;
- opt.personal_cipher_prefs[i].value = 0;
- }
- }
- else if(personal==PREFTYPE_HASH)
- {
- xfree (opt.personal_digest_prefs);
-
- if(nhash==0)
- opt.personal_digest_prefs=NULL;
- else
- {
- int i;
-
- opt.personal_digest_prefs=
- xmalloc (sizeof(prefitem_t *)*(nhash+1));
-
- for (i=0; i<nhash; i++)
- {
- opt.personal_digest_prefs[i].type = PREFTYPE_HASH;
- opt.personal_digest_prefs[i].value = hash[i];
- }
-
- opt.personal_digest_prefs[i].type = PREFTYPE_NONE;
- opt.personal_digest_prefs[i].value = 0;
- }
- }
- else if(personal==PREFTYPE_ZIP)
- {
- xfree (opt.personal_compress_prefs);
-
- if(nzip==0)
- opt.personal_compress_prefs=NULL;
- else
- {
- int i;
-
- opt.personal_compress_prefs=
- xmalloc (sizeof(prefitem_t *)*(nzip+1));
-
- for (i=0; i<nzip; i++)
- {
- opt.personal_compress_prefs[i].type = PREFTYPE_ZIP;
- opt.personal_compress_prefs[i].value = zip[i];
- }
-
- opt.personal_compress_prefs[i].type = PREFTYPE_NONE;
- opt.personal_compress_prefs[i].value = 0;
- }
- }
- }
- else
- {
- memcpy (sym_prefs, sym, (nsym_prefs=nsym));
- memcpy (hash_prefs, hash, (nhash_prefs=nhash));
- memcpy (zip_prefs, zip, (nzip_prefs=nzip));
- mdc_available = mdc;
- ks_modify = modify;
- prefs_initialized = 1;
- }
- }
-
- return rc;
-}
-
-#undef CAST5
-#undef AES
-
-/* Return a fake user ID containing the preferences. Caller must
- free. */
-PKT_user_id *keygen_get_std_prefs(void)
-{
- int i,j=0;
- PKT_user_id *uid=xcalloc (1,sizeof(PKT_user_id));
-
- if(!prefs_initialized)
- keygen_set_std_prefs(NULL,0);
-
- uid->prefs=xmalloc ((sizeof(prefitem_t *)*
- (nsym_prefs+nhash_prefs+nzip_prefs+1)));
-
- for(i=0;i<nsym_prefs;i++,j++)
- {
- uid->prefs[j].type=PREFTYPE_SYM;
- uid->prefs[j].value=sym_prefs[i];
- }
-
- for(i=0;i<nhash_prefs;i++,j++)
- {
- uid->prefs[j].type=PREFTYPE_HASH;
- uid->prefs[j].value=hash_prefs[i];
- }
-
- for(i=0;i<nzip_prefs;i++,j++)
- {
- uid->prefs[j].type=PREFTYPE_ZIP;
- uid->prefs[j].value=zip_prefs[i];
- }
-
- uid->prefs[j].type=PREFTYPE_NONE;
- uid->prefs[j].value=0;
-
- uid->mdc_feature=mdc_available;
- uid->ks_modify=ks_modify;
-
- return uid;
-}
-
-static void
-add_feature_mdc (PKT_signature *sig,int enabled)
-{
- const byte *s;
- size_t n;
- int i;
- char *buf;
-
- s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n );
- /* Already set or cleared */
- if (s && n &&
- ((enabled && (s[0] & 0x01)) || (!enabled && !(s[0] & 0x01))))
- return;
-
- if (!s || !n) { /* create a new one */
- n = 1;
- buf = xcalloc (1,n);
- }
- else {
- buf = xmalloc (n);
- memcpy (buf, s, n);
- }
-
- if(enabled)
- buf[0] |= 0x01; /* MDC feature */
- else
- buf[0] &= ~0x01;
-
- /* Are there any bits set? */
- for(i=0;i<n;i++)
- if(buf[i]!=0)
- break;
-
- if(i==n)
- delete_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES);
- else
- build_sig_subpkt (sig, SIGSUBPKT_FEATURES, buf, n);
-
- xfree (buf);
-}
-
-static void
-add_keyserver_modify (PKT_signature *sig,int enabled)
-{
- const byte *s;
- size_t n;
- int i;
- char *buf;
-
- /* The keyserver modify flag is a negative flag (i.e. no-modify) */
- enabled=!enabled;
-
- s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KS_FLAGS, &n );
- /* Already set or cleared */
- if (s && n &&
- ((enabled && (s[0] & 0x80)) || (!enabled && !(s[0] & 0x80))))
- return;
-
- if (!s || !n) { /* create a new one */
- n = 1;
- buf = xcalloc (1,n);
- }
- else {
- buf = xmalloc (n);
- memcpy (buf, s, n);
- }
-
- if(enabled)
- buf[0] |= 0x80; /* no-modify flag */
- else
- buf[0] &= ~0x80;
-
- /* Are there any bits set? */
- for(i=0;i<n;i++)
- if(buf[i]!=0)
- break;
-
- if(i==n)
- delete_sig_subpkt (sig->hashed, SIGSUBPKT_KS_FLAGS);
- else
- build_sig_subpkt (sig, SIGSUBPKT_KS_FLAGS, buf, n);
-
- xfree (buf);
-}
-
-int
-keygen_upd_std_prefs( PKT_signature *sig, void *opaque )
-{
- if (!prefs_initialized)
- keygen_set_std_prefs (NULL, 0);
-
- if (nsym_prefs)
- build_sig_subpkt (sig, SIGSUBPKT_PREF_SYM, sym_prefs, nsym_prefs);
- else
- {
- delete_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_SYM);
- delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_SYM);
- }
-
- if (nhash_prefs)
- build_sig_subpkt (sig, SIGSUBPKT_PREF_HASH, hash_prefs, nhash_prefs);
- else
- {
- delete_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_HASH);
- delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_HASH);
- }
-
- if (nzip_prefs)
- build_sig_subpkt (sig, SIGSUBPKT_PREF_COMPR, zip_prefs, nzip_prefs);
- else
- {
- delete_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_COMPR);
- delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_COMPR);
- }
-
- /* Make sure that the MDC feature flag is set if needed */
- add_feature_mdc (sig,mdc_available);
- add_keyserver_modify (sig,ks_modify);
-
- return 0;
-}
-
-
-/****************
- * Add preference to the self signature packet.
- * This is only called for packets with version > 3.
-
- */
-int
-keygen_add_std_prefs( PKT_signature *sig, void *opaque )
-{
- PKT_public_key *pk = opaque;
-
- do_add_key_flags (sig, pk->pubkey_usage);
- keygen_add_key_expire( sig, opaque );
- keygen_upd_std_prefs (sig, opaque);
-
- return 0;
-}
-
-
-int
-keygen_add_keyserver_url(PKT_signature *sig, void *opaque)
-{
- const char *url=opaque;
-
- build_sig_subpkt(sig,SIGSUBPKT_PREF_KS,url,strlen(url));
-
- return 0;
-}
-
-
-int
-keygen_add_revkey(PKT_signature *sig, void *opaque)
-{
- struct revocation_key *revkey=opaque;
- byte buf[2+MAX_FINGERPRINT_LEN];
-
- buf[0]=revkey->class;
- buf[1]=revkey->algid;
- memcpy(&buf[2],revkey->fpr,MAX_FINGERPRINT_LEN);
-
- build_sig_subpkt(sig,SIGSUBPKT_REV_KEY,buf,2+MAX_FINGERPRINT_LEN);
-
- /* All sigs with revocation keys set are nonrevocable */
- sig->flags.revocable=0;
- buf[0] = 0;
- build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 );
-
- parse_revkeys(sig);
-
- return 0;
-}
-
-static int
-write_direct_sig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
- struct revocation_key *revkey )
-{
- PACKET *pkt;
- PKT_signature *sig;
- int rc=0;
- KBNODE node;
- PKT_public_key *pk;
-
- if( opt.verbose )
- log_info(_("writing direct signature\n"));
-
- /* get the pk packet from the pub_tree */
- node = find_kbnode( pub_root, PKT_PUBLIC_KEY );
- if( !node )
- BUG();
- pk = node->pkt->pkt.public_key;
-
- /* we have to cache the key, so that the verification of the signature
- * creation is able to retrieve the public key */
- cache_public_key (pk);
-
- /* and make the signature */
- rc = make_keysig_packet(&sig,pk,NULL,NULL,sk,0x1F,0,0,0,0,
- keygen_add_revkey,revkey);
- if( rc ) {
- log_error("make_keysig_packet failed: %s\n", gpg_strerror (rc) );
- return rc;
- }
-
- pkt = xcalloc (1, sizeof *pkt );
- pkt->pkttype = PKT_SIGNATURE;
- pkt->pkt.signature = sig;
- add_kbnode( root, new_kbnode( pkt ) );
- return rc;
-}
-
-static int
-write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
- unsigned int use )
-{
- PACKET *pkt;
- PKT_signature *sig;
- PKT_user_id *uid;
- int rc=0;
- KBNODE node;
- PKT_public_key *pk;
-
- if( opt.verbose )
- log_info(_("writing self signature\n"));
-
- /* get the uid packet from the list */
- node = find_kbnode( root, PKT_USER_ID );
- if( !node )
- BUG(); /* no user id packet in tree */
- uid = node->pkt->pkt.user_id;
- /* get the pk packet from the pub_tree */
- node = find_kbnode( pub_root, PKT_PUBLIC_KEY );
- if( !node )
- BUG();
- pk = node->pkt->pkt.public_key;
- pk->pubkey_usage = use;
- /* we have to cache the key, so that the verification of the signature
- * creation is able to retrieve the public key */
- cache_public_key (pk);
-
- /* and make the signature */
- rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
- keygen_add_std_prefs, pk );
- if( rc ) {
- log_error("make_keysig_packet failed: %s\n", gpg_strerror (rc) );
- return rc;
- }
-
- pkt = xcalloc (1, sizeof *pkt );
- pkt->pkttype = PKT_SIGNATURE;
- pkt->pkt.signature = sig;
- add_kbnode( root, new_kbnode( pkt ) );
- return rc;
-}
-
-static int
-write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
- unsigned int use )
-{
- PACKET *pkt;
- PKT_signature *sig;
- int rc=0;
- KBNODE node;
- PKT_public_key *pk, *subpk;
- struct opaque_data_usage_and_pk oduap;
-
- if( opt.verbose )
- log_info(_("writing key binding signature\n"));
-
- /* get the pk packet from the pub_tree */
- node = find_kbnode( pub_root, PKT_PUBLIC_KEY );
- if( !node )
- BUG();
- pk = node->pkt->pkt.public_key;
- /* we have to cache the key, so that the verification of the signature
- * creation is able to retrieve the public key */
- cache_public_key (pk);
-
- /* find the last subkey */
- subpk = NULL;
- for(node=pub_root; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
- subpk = node->pkt->pkt.public_key;
- }
- if( !subpk )
- BUG();
-
- /* and make the signature */
- oduap.usage = use;
- oduap.pk = subpk;
- rc = make_keysig_packet( &sig, pk, NULL, subpk, sk, 0x18, 0, 0, 0, 0,
- keygen_add_key_flags_and_expire, &oduap );
- if( rc ) {
- log_error("make_keysig_packet failed: %s\n", gpg_strerror (rc) );
- return rc;
- }
-
- pkt = xcalloc (1, sizeof *pkt );
- pkt->pkttype = PKT_SIGNATURE;
- pkt->pkt.signature = sig;
- add_kbnode( root, new_kbnode( pkt ) );
- return rc;
-}
-
-
-static int
-key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp,
- const char *topname, const char *elems)
-{
- gcry_sexp_t list, l2;
- const char *s;
- int i, idx;
- int rc = 0;
-
- list = gcry_sexp_find_token (sexp, topname, 0);
- if (!list)
- return gpg_error (GPG_ERR_INV_OBJ);
- l2 = gcry_sexp_cadr (list);
- gcry_sexp_release (list);
- list = l2;
- if (!list)
- return gpg_error (GPG_ERR_NO_OBJ);
-
- for (idx=0,s=elems; *s; s++, idx++)
- {
- l2 = gcry_sexp_find_token (list, s, 1);
- if (!l2)
- {
- rc = gpg_error (GPG_ERR_NO_OBJ); /* required parameter not found */
- goto leave;
- }
- array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
- gcry_sexp_release (l2);
- if (!array[idx])
- {
- rc = gpg_error (GPG_ERR_INV_OBJ); /* required parameter invalid */
- goto leave;
- }
- }
- gcry_sexp_release (list);
-
- leave:
- if (rc)
- {
- for (i=0; i<idx; i++)
- {
- xfree (array[i]);
- array[i] = NULL;
- }
- gcry_sexp_release (list);
- }
- return rc;
-}
-
-
-static int
-genhelp_protect (DEK *dek, STRING2KEY *s2k, PKT_secret_key *sk)
-{
- int rc = 0;
-
- if (dek)
- {
- sk->protect.algo = dek->algo;
- sk->protect.s2k = *s2k;
- rc = protect_secret_key (sk, dek);
- if (rc)
- log_error ("protect_secret_key failed: %s\n", gpg_strerror (rc) );
- }
-
- return rc;
-}
-
-static void
-genhelp_factors (gcry_sexp_t misc_key_info, KBNODE sec_root)
-{
- size_t n;
- char *buf;
-
- if (misc_key_info)
- {
- /* DSA: don't know whether it makes sense to have the factors, so for now
- we store them in the secret keyring (but they are not secret)
- p = 2 * q * f1 * f2 * ... * fn
- We store only f1 to f_n-1; fn can be calculated because p and q
- are known. */
- n = gcry_sexp_sprint (misc_key_info, 0, NULL, 0);
- buf = xmalloc (n+4);
- strcpy (buf, "#::");
- n = gcry_sexp_sprint (misc_key_info, 0, buf+3, n);
- if (n)
- {
- n += 3;
- add_kbnode (sec_root, make_comment_node_from_buffer (buf, n));
- }
- xfree (buf);
- gcry_sexp_release (misc_key_info);
- }
-}
-
-
-static int
-gen_elg(int algo, unsigned int nbits,
- KBNODE pub_root, KBNODE sec_root, DEK *dek,
- STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval )
-{
- int rc;
- PACKET *pkt;
- PKT_secret_key *sk;
- PKT_public_key *pk;
- gcry_sexp_t s_parms, s_key;
- gcry_sexp_t misc_key_info;
-
- assert (is_ELGAMAL(algo));
-
- if (nbits < 512)
- {
- nbits = 1024;
- log_info (_("keysize invalid; using %u bits\n"), nbits);
- }
-
- if ((nbits % 32))
- {
- nbits = ((nbits + 31) / 32) * 32;
- log_info (_("keysize rounded up to %u bits\n"), nbits);
- }
-
- rc = gcry_sexp_build ( &s_parms, NULL,
- "(genkey(%s(nbits %d)))",
- algo == GCRY_PK_ELG_E ? "openpgp-elg" :
- algo == GCRY_PK_ELG ? "elg" : "x-oops" ,
- (int)nbits);
- if (rc)
- log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc));
-
- rc = gcry_pk_genkey (&s_key, s_parms);
- gcry_sexp_release (s_parms);
- if (rc)
- {
- log_error ("gcry_pk_genkey failed: %s\n", gpg_strerror (rc) );
- return rc;
- }
-
- sk = xcalloc (1, sizeof *sk);
- pk = xcalloc (1, sizeof *pk);
- sk->timestamp = pk->timestamp = make_timestamp();
- sk->version = pk->version = 4;
- if (expireval)
- sk->expiredate = pk->expiredate = sk->timestamp + expireval;
- sk->pubkey_algo = pk->pubkey_algo = algo;
-
- rc = key_from_sexp (pk->pkey, s_key, "public-key", "pgy");
- if (rc)
- {
- log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) );
- gcry_sexp_release (s_key);
- return rc;
- }
- rc = key_from_sexp (sk->skey, s_key, "private-key", "pgyx");
- if (rc)
- {
- log_error("key_from_sexp failed: %s\n", gpg_strerror (rc) );
- gcry_sexp_release (s_key);
- return rc;
- }
- misc_key_info = gcry_sexp_find_token (s_key, "misc-key-info", 0);
- gcry_sexp_release (s_key);
-
- sk->is_protected = 0;
- sk->protect.algo = 0;
-
- sk->csum = checksum_mpi (sk->skey[3]);
- if (ret_sk) /* not a subkey: return an unprotected version of the sk */
- *ret_sk = copy_secret_key (NULL, sk);
-
- rc = genhelp_protect (dek, s2k, sk);
- if (rc)
- {
- free_public_key (pk);
- free_secret_key (sk);
- gcry_sexp_release (misc_key_info);
- return rc;
- }
-
- pkt = xcalloc (1,sizeof *pkt);
- pkt->pkttype = ret_sk ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
- pkt->pkt.public_key = pk;
- add_kbnode(pub_root, new_kbnode( pkt ));
-
- /* don't know whether it makes sense to have the factors, so for now
- * we store them in the secret keyring (but they are not secret) */
- pkt = xcalloc (1,sizeof *pkt);
- pkt->pkttype = ret_sk ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY;
- pkt->pkt.secret_key = sk;
- add_kbnode(sec_root, new_kbnode( pkt ));
-
- genhelp_factors (misc_key_info, sec_root);
-
- return 0;
-}
-
-
-/****************
- * Generate a DSA key
- */
-static int
-gen_dsa (unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
- STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval )
-{
- int rc;
- PACKET *pkt;
- PKT_secret_key *sk;
- PKT_public_key *pk;
- gcry_sexp_t s_parms, s_key;
- gcry_sexp_t misc_key_info;
-
- if (nbits > 1024 || nbits < 512)
- {
- nbits = 1024;
- log_info(_("keysize invalid; using %u bits\n"), nbits);
- }
-
- if ((nbits % 64))
- {
- nbits = ((nbits + 63) / 64) * 64;
- log_info (_("keysize rounded up to %u bits\n"), nbits);
- }
-
- rc = gcry_sexp_build (&s_parms, NULL,
- "(genkey(dsa(nbits %d)))",
- (int)nbits);
- if (rc)
- log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc));
-
- rc = gcry_pk_genkey (&s_key, s_parms);
- gcry_sexp_release (s_parms);
- if (rc)
- {
- log_error ("gcry_pk_genkey failed: %s\n", gpg_strerror (rc) );
- return rc;
- }
-
- sk = xcalloc (1, sizeof *sk );
- pk = xcalloc (1, sizeof *pk );
- sk->timestamp = pk->timestamp = make_timestamp();
- sk->version = pk->version = 4;
- if (expireval)
- sk->expiredate = pk->expiredate = sk->timestamp + expireval;
- sk->pubkey_algo = pk->pubkey_algo = PUBKEY_ALGO_DSA;
-
- rc = key_from_sexp (pk->pkey, s_key, "public-key", "pqgy");
- if (rc)
- {
- log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc));
- gcry_sexp_release (s_key);
- return rc;
- }
- rc = key_from_sexp (sk->skey, s_key, "private-key", "pqgyx");
- if (rc)
- {
- log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) );
- gcry_sexp_release (s_key);
- return rc;
- }
- misc_key_info = gcry_sexp_find_token (s_key, "misc-key-info", 0);
- gcry_sexp_release (s_key);
-
- sk->is_protected = 0;
- sk->protect.algo = 0;
-
- sk->csum = checksum_mpi ( sk->skey[4] );
- if (ret_sk) /* not a subkey: return an unprotected version of the sk */
- *ret_sk = copy_secret_key( NULL, sk );
-
- rc = genhelp_protect (dek, s2k, sk);
- if (rc)
- {
- free_public_key (pk);
- free_secret_key (sk);
- gcry_sexp_release (misc_key_info);
- return rc;
- }
-
- pkt = xcalloc (1,sizeof *pkt);
- pkt->pkttype = ret_sk ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
- pkt->pkt.public_key = pk;
- add_kbnode(pub_root, new_kbnode( pkt ));
-
- pkt = xcalloc (1,sizeof *pkt);
- pkt->pkttype = ret_sk ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY;
- pkt->pkt.secret_key = sk;
- add_kbnode(sec_root, new_kbnode( pkt ));
-
- genhelp_factors (misc_key_info, sec_root);
-
- return 0;
-}
-
-
-/*
- * Generate an RSA key.
- */
-static int
-gen_rsa(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
- STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval )
-{
- int rc;
- PACKET *pkt;
- PKT_secret_key *sk;
- PKT_public_key *pk;
- gcry_sexp_t s_parms, s_key;
-
- assert (is_RSA(algo));
-
- if (nbits < 1024)
- {
- nbits = 1024;
- log_info(_("keysize invalid; using %u bits\n"), nbits);
- }
-
- if ((nbits % 32))
- {
- nbits = ((nbits + 31) / 32) * 32;
- log_info (_("keysize rounded up to %u bits\n"), nbits);
- }
-
- rc = gcry_sexp_build (&s_parms, NULL,
- "(genkey(rsa(nbits %d)))",
- (int)nbits);
- if (rc)
- log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc));
-
- rc = gcry_pk_genkey (&s_key, s_parms);
- gcry_sexp_release (s_parms);
- if (rc)
- {
- log_error ("gcry_pk_genkey failed: %s\n", gpg_strerror (rc) );
- return rc;
- }
-
- sk = xcalloc (1, sizeof *sk );
- pk = xcalloc (1, sizeof *pk );
- sk->timestamp = pk->timestamp = make_timestamp();
- sk->version = pk->version = 4;
- if (expireval)
- sk->expiredate = pk->expiredate = sk->timestamp + expireval;
- sk->pubkey_algo = pk->pubkey_algo = algo;
-
- rc = key_from_sexp (pk->pkey, s_key, "public-key", "ne");
- if (rc)
- {
- log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc));
- gcry_sexp_release (s_key);
- return rc;
- }
- rc = key_from_sexp (sk->skey, s_key, "private-key", "nedpqu");
- if (rc)
- {
- log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) );
- gcry_sexp_release (s_key);
- return rc;
- }
- gcry_sexp_release (s_key);
-
- sk->is_protected = 0;
- sk->protect.algo = 0;
-
- sk->csum = checksum_mpi (sk->skey[2] );
- sk->csum += checksum_mpi (sk->skey[3] );
- sk->csum += checksum_mpi (sk->skey[4] );
- sk->csum += checksum_mpi (sk->skey[5] );
- if (ret_sk) /* not a subkey: return an unprotected version of the sk */
- *ret_sk = copy_secret_key (NULL, sk);
-
- rc = genhelp_protect (dek, s2k, sk);
- if (rc)
- {
- free_public_key (pk);
- free_secret_key (sk);
- return rc;
- }
-
- pkt = xcalloc (1,sizeof *pkt);
- pkt->pkttype = ret_sk ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
- pkt->pkt.public_key = pk;
- add_kbnode (pub_root, new_kbnode( pkt ));
-
- pkt = xcalloc (1,sizeof *pkt);
- pkt->pkttype = ret_sk ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY;
- pkt->pkt.secret_key = sk;
- add_kbnode(sec_root, new_kbnode( pkt ));
-
- return 0;
-}
-
-
-/****************
- * check valid days:
- * return 0 on error or the multiplier
- */
-static int
-check_valid_days( const char *s )
-{
- if( !digitp(s) )
- return 0;
- for( s++; *s; s++)
- if( !digitp(s) )
- break;
- if( !*s )
- return 1;
- if( s[1] )
- return 0; /* e.g. "2323wc" */
- if( *s == 'd' || *s == 'D' )
- return 1;
- if( *s == 'w' || *s == 'W' )
- return 7;
- if( *s == 'm' || *s == 'M' )
- return 30;
- if( *s == 'y' || *s == 'Y' )
- return 365;
- return 0;
-}
-
-
-/****************
- * Returns: 0 to create both a DSA and a ElGamal key.
- * and only if key flags are to be written the desired usage.
- */
-static int
-ask_algo (int addmode, unsigned int *r_usage)
-{
- char *answer;
- int algo;
-
- *r_usage = 0;
- tty_printf(_("Please select what kind of key you want:\n"));
- if( !addmode )
- tty_printf(_(" (%d) DSA and ElGamal (default)\n"), 1 );
- tty_printf( _(" (%d) DSA (sign only)\n"), 2 );
- if( addmode )
- tty_printf( _(" (%d) ElGamal (encrypt only)\n"), 3 );
- if (opt.expert)
- tty_printf( _(" (%d) ElGamal (sign and encrypt)\n"), 4 );
- tty_printf( _(" (%d) RSA (sign only)\n"), 5 );
- if (addmode)
- tty_printf( _(" (%d) RSA (encrypt only)\n"), 6 );
- if (opt.expert)
- tty_printf( _(" (%d) RSA (sign and encrypt)\n"), 7 );
-
- for(;;) {
- answer = cpr_get("keygen.algo",_("Your selection? "));
- cpr_kill_prompt();
- algo = *answer? atoi(answer): 1;
- xfree (answer);
- if( algo == 1 && !addmode ) {
- algo = 0; /* create both keys */
- break;
- }
- else if( algo == 7 && opt.expert ) {
- algo = PUBKEY_ALGO_RSA;
- *r_usage = PUBKEY_USAGE_ENC | PUBKEY_USAGE_SIG;
- break;
- }
- else if( algo == 6 && addmode ) {
- algo = PUBKEY_ALGO_RSA;
- *r_usage = PUBKEY_USAGE_ENC;
- break;
- }
- else if( algo == 5 ) {
- algo = PUBKEY_ALGO_RSA;
- *r_usage = PUBKEY_USAGE_SIG;
- break;
- }
- else if( algo == 4 && opt.expert)
- {
- tty_printf(_(
-"The use of this algorithm is only supported by GnuPG. You will not be\n"
-"able to use this key to communicate with PGP users. This algorithm is also\n"
-"very slow, and may not be as secure as the other choices.\n"));
-
- if( cpr_get_answer_is_yes("keygen.algo.elg_se",
- _("Create anyway? ")))
- {
- algo = PUBKEY_ALGO_ELGAMAL;
- *r_usage = PUBKEY_USAGE_ENC | PUBKEY_USAGE_SIG;
- break;
- }
- }
- else if( algo == 3 && addmode ) {
- algo = PUBKEY_ALGO_ELGAMAL_E;
- *r_usage = PUBKEY_USAGE_ENC;
- break;
- }
- else if( algo == 2 ) {
- algo = PUBKEY_ALGO_DSA;
- *r_usage = PUBKEY_USAGE_SIG;
- break;
- }
- else
- tty_printf(_("Invalid selection.\n"));
- }
- return algo;
-}
-
-
-static unsigned
-ask_keysize( int algo )
-{
- char *answer;
- unsigned nbits;
-
- if (algo != PUBKEY_ALGO_DSA && algo != PUBKEY_ALGO_RSA) {
- tty_printf (_("About to generate a new %s keypair.\n"
- " minimum keysize is 768 bits\n"
- " default keysize is 1024 bits\n"
- " highest suggested keysize is 2048 bits\n"),
- gcry_pk_algo_name (algo) );
- }
-
- for(;;) {
- answer = cpr_get("keygen.size",
- _("What keysize do you want? (1024) "));
- cpr_kill_prompt();
- nbits = *answer? atoi(answer): 1024;
- xfree (answer);
- if( algo == PUBKEY_ALGO_DSA && (nbits < 512 || nbits > 1024) )
- tty_printf(_("DSA only allows keysizes from 512 to 1024\n"));
- else if( algo == PUBKEY_ALGO_RSA && nbits < 1024 )
- tty_printf(_("keysize too small;"
- " 1024 is smallest value allowed for RSA.\n"));
- else if( nbits < 768 )
- tty_printf(_("keysize too small;"
- " 768 is smallest value allowed.\n"));
- else if( nbits > 4096 ) {
- /* It is ridiculous and an annoyance to use larger key sizes!
- * GnuPG can handle much larger sizes; but it takes an eternity
- * to create such a key (but less than the time the Sirius
- * Computer Corporation needs to process one of the usual
- * complaints) and {de,en}cryption although needs some time.
- * So, before you complain about this limitation, I suggest that
- * you start a discussion with Marvin about this theme and then
- * do whatever you want. */
- tty_printf(_("keysize too large; %d is largest value allowed.\n"),
- 4096);
- }
- else if( nbits > 2048 && !cpr_enabled() ) {
- tty_printf(
- _("Keysizes larger than 2048 are not suggested because\n"
- "computations take REALLY long!\n"));
- if( cpr_get_answer_is_yes("keygen.size.huge.okay",_(
- "Are you sure that you want this keysize? ")) ) {
- tty_printf(_("Okay, but keep in mind that your monitor "
- "and keyboard radiation is also very vulnerable "
- "to attacks!\n"));
- break;
- }
- }
- else
- break;
- }
- tty_printf(_("Requested keysize is %u bits\n"), nbits );
- if( algo == PUBKEY_ALGO_DSA && (nbits % 64) ) {
- nbits = ((nbits + 63) / 64) * 64;
- tty_printf(_("rounded up to %u bits\n"), nbits );
- }
- else if( (nbits % 32) ) {
- nbits = ((nbits + 31) / 32) * 32;
- tty_printf(_("rounded up to %u bits\n"), nbits );
- }
- return nbits;
-}
-
-
-/****************
- * Parse an expire string and return it's value in days.
- * Returns -1 on error.
- */
-static int
-parse_expire_string( const char *string )
-{
- int mult;
- u32 abs_date=0;
- u32 curtime = make_timestamp();
- int valid_days;
-
- if( !*string )
- valid_days = 0;
- else if( (abs_date = scan_isodatestr(string)) && abs_date > curtime ) {
- /* This calculation is not perfectly okay because we
- * are later going to simply multiply by 86400 and don't
- * correct for leapseconds. A solution would be to change
- * the whole implemenation to work with dates and not intervals
- * which are required for v3 keys.
- */
- valid_days = abs_date/86400-curtime/86400+1;
- }
- else if( (mult=check_valid_days(string)) ) {
- valid_days = atoi(string) * mult;
- if( valid_days < 0 || valid_days > 39447 )
- valid_days = 0;
- }
- else {
- valid_days = -1;
- }
- return valid_days;
-}
-
-/* object == 0 for a key, and 1 for a sig */
-u32
-ask_expire_interval(int object)
-{
- char *answer;
- int valid_days=0;
- u32 interval = 0;
-
- switch(object)
- {
- case 0:
- tty_printf(_("Please specify how long the key should be valid.\n"
- " 0 = key does not expire\n"
- " <n> = key expires in n days\n"
- " <n>w = key expires in n weeks\n"
- " <n>m = key expires in n months\n"
- " <n>y = key expires in n years\n"));
- break;
-
- case 1:
- tty_printf(_("Please specify how long the signature should be valid.\n"
- " 0 = signature does not expire\n"
- " <n> = signature expires in n days\n"
- " <n>w = signature expires in n weeks\n"
- " <n>m = signature expires in n months\n"
- " <n>y = signature expires in n years\n"));
- break;
-
- default:
- BUG();
- }
-
- /* Note: The elgamal subkey for DSA has no expiration date because
- * it must be signed with the DSA key and this one has the expiration
- * date */
-
- answer = NULL;
- for(;;) {
- u32 curtime=make_timestamp();
-
- xfree (answer);
- if(object==0)
- answer = cpr_get("keygen.valid",_("Key is valid for? (0) "));
- else
- answer = cpr_get("siggen.valid",_("Signature is valid for? (0) "));
- cpr_kill_prompt();
- trim_spaces(answer);
- valid_days = parse_expire_string( answer );
- if( valid_days < 0 ) {
- tty_printf(_("invalid value\n"));
- continue;
- }
-
- if( !valid_days ) {
- tty_printf(_("%s does not expire at all\n"),
- object==0?"Key":"Signature");
- interval = 0;
- }
- else {
- interval = valid_days * 86400L;
- /* print the date when the key expires */
- tty_printf(_("%s expires at %s\n"),
- object==0?"Key":"Signature",
- asctimestamp((ulong)(curtime + interval) ) );
- /* FIXME: This check yields warning some machines: write a
- configure check and do this check here only for 32 bit
- machines */
- if( (time_t)((ulong)(curtime+interval)) < 0 )
- tty_printf(_("Your system can't display dates beyond 2038.\n"
- "However, it will be correctly handled up to 2106.\n"));
- }
-
- if( cpr_enabled() || cpr_get_answer_is_yes("keygen.valid.okay",
- _("Is this correct (y/n)? ")) )
- break;
- }
- xfree (answer);
- return interval;
-}
-
-u32
-ask_expiredate()
-{
- u32 x = ask_expire_interval(0);
- return x? make_timestamp() + x : 0;
-}
-
-
-static int
-count_chr( const char *string, int c )
-{
- int count;
-
- for (count=0; *string; string++ )
- if ( *string == c )
- count++;
- return count;
-}
-
-
-static int
-has_invalid_email_chars( const char *s )
-{
- int at_seen=0;
- static char valid_chars[] = "01234567890_-."
- "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
- for( ; *s; s++ ) {
- if( *s & 0x80 )
- return 1;
- if( *s == '@' )
- at_seen=1;
- else if( !at_seen && !( !!strchr( valid_chars, *s ) || *s == '+' ) )
- return 1;
- else if( at_seen && !strchr( valid_chars, *s ) )
- return 1;
- }
- return 0;
-}
-
-
-static char *
-ask_user_id( int mode )
-{
- char *answer;
- char *aname, *acomment, *amail, *uid;
-
- if( !mode )
- tty_printf( _("\n"
-"You need a User-ID to identify your key; the software constructs the user id\n"
-"from Real Name, Comment and Email Address in this form:\n"
-" \"Heinrich Heine (Der Dichter) <[email protected]>\"\n\n") );
- uid = aname = acomment = amail = NULL;
- for(;;) {
- char *p;
- int fail=0;
-
- if( !aname ) {
- for(;;) {
- xfree (aname);
- aname = cpr_get("keygen.name",_("Real name: "));
- trim_spaces(aname);
- cpr_kill_prompt();
-
- if( opt.allow_freeform_uid )
- break;
-
- if( strpbrk( aname, "<>" ) )
- tty_printf(_("Invalid character in name\n"));
- else if( digitp(aname) )
- tty_printf(_("Name may not start with a digit\n"));
- else if( strlen(aname) < 5 )
- tty_printf(_("Name must be at least 5 characters long\n"));
- else
- break;
- }
- }
- if( !amail ) {
- for(;;) {
- xfree (amail);
- amail = cpr_get("keygen.email",_("Email address: "));
- trim_spaces(amail);
- cpr_kill_prompt();
- if( !*amail || opt.allow_freeform_uid )
- break; /* no email address is okay */
- else if( has_invalid_email_chars(amail)
- || count_chr(amail,'@') != 1
- || *amail == '@'
- || amail[strlen(amail)-1] == '@'
- || amail[strlen(amail)-1] == '.'
- || strstr(amail, "..") )
- tty_printf(_("Not a valid email address\n"));
- else
- break;
- }
- }
- if( !acomment ) {
- for(;;) {
- xfree (acomment);
- acomment = cpr_get("keygen.comment",_("Comment: "));
- trim_spaces(acomment);
- cpr_kill_prompt();
- if( !*acomment )
- break; /* no comment is okay */
- else if( strpbrk( acomment, "()" ) )
- tty_printf(_("Invalid character in comment\n"));
- else
- break;
- }
- }
-
-
- xfree (uid);
- uid = p = xmalloc (strlen(aname)+strlen(amail)+strlen(acomment)+12+10);
- p = stpcpy(p, aname );
- if( *acomment )
- p = stpcpy(stpcpy(stpcpy(p," ("), acomment),")");
- if( *amail )
- p = stpcpy(stpcpy(stpcpy(p," <"), amail),">");
-
- /* print a note in case that UTF8 mapping has to be done */
- for(p=uid; *p; p++ ) {
- if( *p & 0x80 ) {
- tty_printf(_("You are using the `%s' character set.\n"),
- get_native_charset() );
- break;
- }
- }
-
- tty_printf(_("You selected this USER-ID:\n \"%s\"\n\n"), uid);
- /* fixme: add a warning if this user-id already exists */
- if( !*amail && !opt.allow_freeform_uid
- && (strchr( aname, '@' ) || strchr( acomment, '@'))) {
- fail = 1;
- tty_printf(_("Please don't put the email address "
- "into the real name or the comment\n") );
- }
-
- for(;;) {
- const char *ansstr = _("NnCcEeOoQq");
-
- if( strlen(ansstr) != 10 )
- BUG();
- if( cpr_enabled() ) {
- answer = xstrdup (ansstr+6);
- answer[1] = 0;
- }
- else {
- answer = cpr_get("keygen.userid.cmd", fail?
- _("Change (N)ame, (C)omment, (E)mail or (Q)uit? ") :
- _("Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "));
- cpr_kill_prompt();
- }
- if( strlen(answer) > 1 )
- ;
- else if( *answer == ansstr[0] || *answer == ansstr[1] ) {
- xfree (aname); aname = NULL;
- break;
- }
- else if( *answer == ansstr[2] || *answer == ansstr[3] ) {
- xfree (acomment); acomment = NULL;
- break;
- }
- else if( *answer == ansstr[4] || *answer == ansstr[5] ) {
- xfree (amail); amail = NULL;
- break;
- }
- else if( *answer == ansstr[6] || *answer == ansstr[7] ) {
- if( fail ) {
- tty_printf(_("Please correct the error first\n"));
- }
- else {
- xfree (aname); aname = NULL;
- xfree (acomment); acomment = NULL;
- xfree (amail); amail = NULL;
- break;
- }
- }
- else if( *answer == ansstr[8] || *answer == ansstr[9] ) {
- xfree (aname); aname = NULL;
- xfree (acomment); acomment = NULL;
- xfree (amail); amail = NULL;
- xfree (uid); uid = NULL;
- break;
- }
- xfree (answer);
- }
- xfree (answer);
- if( !amail && !acomment && !amail )
- break;
- xfree (uid); uid = NULL;
- }
- if( uid ) {
- char *p = native_to_utf8( uid );
- xfree ( uid );
- uid = p;
- }
- return uid;
-}
-
-
-static DEK *
-ask_passphrase( STRING2KEY **ret_s2k )
-{
- DEK *dek = NULL;
- STRING2KEY *s2k;
- const char *errtext = NULL;
-
- tty_printf(_("You need a Passphrase to protect your secret key.\n\n") );
-
- s2k = xmalloc ( sizeof *s2k );
- for(;;) {
- s2k->mode = opt.s2k_mode;
- s2k->hash_algo = opt.s2k_digest_algo;
- dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k,2,
- errtext, NULL);
- if( !dek ) {
- errtext = N_("passphrase not correctly repeated; try again");
- tty_printf(_("%s.\n"), _(errtext));
- }
- else if( !dek->keylen ) {
- xfree (dek); dek = NULL;
- xfree (s2k); s2k = NULL;
- tty_printf(_(
- "You don't want a passphrase - this is probably a *bad* idea!\n"
- "I will do it anyway. You can change your passphrase at any time,\n"
- "using this program with the option \"--edit-key\".\n\n"));
- break;
- }
- else
- break; /* okay */
- }
- *ret_s2k = s2k;
- return dek;
-}
-
-
-static int
-do_create( int algo, unsigned int nbits, KBNODE pub_root, KBNODE sec_root,
- DEK *dek, STRING2KEY *s2k, PKT_secret_key **sk, u32 expiredate )
-{
- int rc=0;
-
- if( !opt.batch )
- tty_printf(_(
-"We need to generate a lot of random bytes. It is a good idea to perform\n"
-"some other action (type on the keyboard, move the mouse, utilize the\n"
-"disks) during the prime generation; this gives the random number\n"
-"generator a better chance to gain enough entropy.\n") );
-
- if( algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E )
- rc = gen_elg(algo, nbits, pub_root, sec_root, dek, s2k, sk, expiredate);
- else if( algo == PUBKEY_ALGO_DSA )
- rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, sk, expiredate);
- else if( algo == PUBKEY_ALGO_RSA )
- rc = gen_rsa(algo, nbits, pub_root, sec_root, dek, s2k, sk, expiredate);
- else
- BUG();
-
-#ifdef ENABLE_COMMENT_PACKETS
- if( !rc ) {
- add_kbnode( pub_root,
- make_comment_node("#created by GNUPG v" VERSION " ("
- PRINTABLE_OS_NAME ")"));
- add_kbnode( sec_root,
- make_comment_node("#created by GNUPG v" VERSION " ("
- PRINTABLE_OS_NAME ")"));
- }
-#endif
- return rc;
-}
-
-
-/****************
- * Generate a new user id packet, or return NULL if canceled
- */
-PKT_user_id *
-generate_user_id()
-{
- PKT_user_id *uid;
- char *p;
- size_t n;
-
- p = ask_user_id( 1 );
- if( !p )
- return NULL;
- n = strlen(p);
- uid = xcalloc (1, sizeof *uid + n - 1 );
- uid->len = n;
- strcpy(uid->name, p);
- uid->ref = 1;
- return uid;
-}
-
-
-static void
-release_parameter_list( struct para_data_s *r )
-{
- struct para_data_s *r2;
-
- for( ; r ; r = r2 ) {
- r2 = r->next;
- if( r->key == pPASSPHRASE_DEK )
- xfree ( r->u.dek );
- else if( r->key == pPASSPHRASE_S2K )
- xfree ( r->u.s2k );
-
- xfree (r);
- }
-}
-
-static struct para_data_s *
-get_parameter( struct para_data_s *para, enum para_name key )
-{
- struct para_data_s *r;
-
- for( r = para; r && r->key != key; r = r->next )
- ;
- return r;
-}
-
-static const char *
-get_parameter_value( struct para_data_s *para, enum para_name key )
-{
- struct para_data_s *r = get_parameter( para, key );
- return (r && *r->u.value)? r->u.value : NULL;
-}
-
-static int
-get_parameter_algo( struct para_data_s *para, enum para_name key )
-{
- int i;
- struct para_data_s *r = get_parameter( para, key );
- if( !r )
- return -1;
- if( digitp( r->u.value ) )
- i = atoi( r->u.value );
- else
- i = openpgp_pk_map_name ( r->u.value );
- if (i == PUBKEY_ALGO_RSA_E || i == PUBKEY_ALGO_RSA_S)
- i = 0; /* we don't want to allow generation of these algorithms */
- return i;
-}
-
-/*
- * parse the usage parameter and set the keyflags. Return true on error.
- */
-static int
-parse_parameter_usage (const char *fname,
- struct para_data_s *para, enum para_name key)
-{
- struct para_data_s *r = get_parameter( para, key );
- char *p, *pn;
- unsigned int use;
-
- if( !r )
- return 0; /* none (this is an optional parameter)*/
-
- use = 0;
- pn = r->u.value;
- while ( (p = strsep (&pn, " \t,")) ) {
- if ( !*p)
- ;
- else if ( !ascii_strcasecmp (p, "sign") )
- use |= PUBKEY_USAGE_SIG;
- else if ( !ascii_strcasecmp (p, "encrypt") )
- use |= PUBKEY_USAGE_ENC;
- else if ( !ascii_strcasecmp (p, "auth") )
- use |= PUBKEY_USAGE_AUTH;
- else {
- log_error("%s:%d: invalid usage list\n", fname, r->lnr );
- return -1; /* error */
- }
- }
- r->u.usage = use;
- return 0;
-}
-
-static int
-parse_revocation_key (const char *fname,
- struct para_data_s *para, enum para_name key)
-{
- struct para_data_s *r = get_parameter( para, key );
- struct revocation_key revkey;
- char *pn;
- int i;
-
- if( !r )
- return 0; /* none (this is an optional parameter) */
-
- pn = r->u.value;
-
- revkey.class=0x80;
- revkey.algid=atoi(pn);
- if(!revkey.algid)
- goto fail;
-
- /* Skip to the fpr */
- while(*pn && *pn!=':')
- pn++;
-
- if(*pn!=':')
- goto fail;
-
- pn++;
-
- for(i=0;i<MAX_FINGERPRINT_LEN && *pn;i++,pn+=2)
- {
- int c=hextobyte(pn);
- if(c==-1)
- goto fail;
-
- revkey.fpr[i]=c;
- }
-
- /* skip to the tag */
- while(*pn && *pn!='s' && *pn!='S')
- pn++;
-
- if(ascii_strcasecmp(pn,"sensitive")==0)
- revkey.class|=0x40;
-
- memcpy(&r->u.revkey,&revkey,sizeof(struct revocation_key));
-
- return 0;
-
- fail:
- log_error("%s:%d: invalid revocation key\n", fname, r->lnr );
- return -1; /* error */
-}
-
-
-static u32
-get_parameter_u32( struct para_data_s *para, enum para_name key )
-{
- struct para_data_s *r = get_parameter( para, key );
-
- if( !r )
- return 0;
- if( r->key == pKEYEXPIRE || r->key == pSUBKEYEXPIRE )
- return r->u.expire;
- if( r->key == pKEYUSAGE || r->key == pSUBKEYUSAGE )
- return r->u.usage;
-
- return (unsigned int)strtoul( r->u.value, NULL, 10 );
-}
-
-static unsigned int
-get_parameter_uint( struct para_data_s *para, enum para_name key )
-{
- return get_parameter_u32( para, key );
-}
-
-static DEK *
-get_parameter_dek( struct para_data_s *para, enum para_name key )
-{
- struct para_data_s *r = get_parameter( para, key );
- return r? r->u.dek : NULL;
-}
-
-static STRING2KEY *
-get_parameter_s2k( struct para_data_s *para, enum para_name key )
-{
- struct para_data_s *r = get_parameter( para, key );
- return r? r->u.s2k : NULL;
-}
-
-static struct revocation_key *
-get_parameter_revkey( struct para_data_s *para, enum para_name key )
-{
- struct para_data_s *r = get_parameter( para, key );
- return r? &r->u.revkey : NULL;
-}
-
-static int
-proc_parameter_file( struct para_data_s *para, const char *fname,
- struct output_control_s *outctrl, int card )
-{
- struct para_data_s *r;
- const char *s1, *s2, *s3;
- size_t n;
- char *p;
- int i;
-
- /* check that we have all required parameters */
- assert( get_parameter( para, pKEYTYPE ) );
- i = get_parameter_algo( para, pKEYTYPE );
- if( i < 1 || openpgp_pk_test_algo ( i, PUBKEY_USAGE_SIG ) ) {
- r = get_parameter( para, pKEYTYPE );
- log_error("%s:%d: invalid algorithm\n", fname, r->lnr );
- return -1;
- }
-
- if (parse_parameter_usage (fname, para, pKEYUSAGE))
- return -1;
-
- i = get_parameter_algo( para, pSUBKEYTYPE );
- if( i > 0 && openpgp_pk_test_algo ( i, 0 ) ) {
- r = get_parameter( para, pSUBKEYTYPE );
- log_error("%s:%d: invalid algorithm\n", fname, r->lnr );
- return -1;
- }
- if (i > 0 && parse_parameter_usage (fname, para, pSUBKEYUSAGE))
- return -1;
-
-
- if( !get_parameter_value( para, pUSERID ) ) {
- /* create the formatted user ID */
- s1 = get_parameter_value( para, pNAMEREAL );
- s2 = get_parameter_value( para, pNAMECOMMENT );
- s3 = get_parameter_value( para, pNAMEEMAIL );
- if( s1 || s2 || s3 ) {
- n = (s1?strlen(s1):0) + (s2?strlen(s2):0) + (s3?strlen(s3):0);
- r = xcalloc (1, sizeof *r + n + 20 );
- r->key = pUSERID;
- p = r->u.value;
- if( s1 )
- p = stpcpy(p, s1 );
- if( s2 )
- p = stpcpy(stpcpy(stpcpy(p," ("), s2 ),")");
- if( s3 )
- p = stpcpy(stpcpy(stpcpy(p," <"), s3 ),">");
- r->next = para;
- para = r;
- }
- }
-
- /* Set preferences, if any. */
- keygen_set_std_prefs(get_parameter_value( para, pPREFERENCES ), 0);
-
- /* Set revoker, if any. */
- if (parse_revocation_key (fname, para, pREVOKER))
- return -1;
-
- /* make DEK and S2K from the Passphrase */
- r = get_parameter( para, pPASSPHRASE );
- if( r && *r->u.value ) {
- /* we have a plain text passphrase - create a DEK from it.
- * It is a little bit ridiculous to keep it in secure memory
- * but because we do this always, why not here. */
- STRING2KEY *s2k;
- DEK *dek;
-
- s2k = xmalloc_secure ( sizeof *s2k );
- s2k->mode = opt.s2k_mode;
- s2k->hash_algo = opt.s2k_digest_algo;
- set_next_passphrase( r->u.value );
- dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2,
- NULL, NULL);
- set_next_passphrase( NULL );
- assert( dek );
- memset( r->u.value, 0, strlen(r->u.value) );
-
- r = xcalloc (1, sizeof *r );
- r->key = pPASSPHRASE_S2K;
- r->u.s2k = s2k;
- r->next = para;
- para = r;
- r = xcalloc (1, sizeof *r );
- r->key = pPASSPHRASE_DEK;
- r->u.dek = dek;
- r->next = para;
- para = r;
- }
-
- /* make KEYEXPIRE from Expire-Date */
- r = get_parameter( para, pEXPIREDATE );
- if( r && *r->u.value ) {
- i = parse_expire_string( r->u.value );
- if( i < 0 ) {
- log_error("%s:%d: invalid expire date\n", fname, r->lnr );
- return -1;
- }
- r->u.expire = i * 86400L;
- r->key = pKEYEXPIRE; /* change hat entry */
- /* also set it for the subkey */
- r = xcalloc (1, sizeof *r + 20 );
- r->key = pSUBKEYEXPIRE;
- r->u.expire = i * 86400L;
- r->next = para;
- para = r;
- }
-
- if( !!outctrl->pub.newfname ^ !!outctrl->sec.newfname ) {
- log_error("%s:%d: only one ring name is set\n", fname, outctrl->lnr );
- return -1;
- }
-
- do_generate_keypair( para, outctrl, card);
- return 0;
-}
-
-
-/****************
- * Kludge to allow non interactive key generation controlled
- * by a parameter file (which currently is only stdin)
- * Note, that string parameters are expected to be in UTF-8
- */
-static void
-read_parameter_file( const char *fname )
-{
- static struct { const char *name;
- enum para_name key;
- } keywords[] = {
- { "Key-Type", pKEYTYPE},
- { "Key-Length", pKEYLENGTH },
- { "Key-Usage", pKEYUSAGE },
- { "Subkey-Type", pSUBKEYTYPE },
- { "Subkey-Length", pSUBKEYLENGTH },
- { "Subkey-Usage", pSUBKEYUSAGE },
- { "Name-Real", pNAMEREAL },
- { "Name-Email", pNAMEEMAIL },
- { "Name-Comment", pNAMECOMMENT },
- { "Expire-Date", pEXPIREDATE },
- { "Passphrase", pPASSPHRASE },
- { "Preferences", pPREFERENCES },
- { "Revoker", pREVOKER },
- { NULL, 0 }
- };
- FILE *fp;
- char line[1024], *p;
- int lnr;
- const char *err = NULL;
- struct para_data_s *para, *r;
- int i;
- struct output_control_s outctrl;
-
- memset( &outctrl, 0, sizeof( outctrl ) );
-
- if( !fname || !*fname || !strcmp(fname,"-") ) {
- fp = stdin;
- fname = "-";
- }
- else {
- fp = fopen( fname, "r" );
- if( !fp ) {
- log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
- return;
- }
- }
-
- lnr = 0;
- err = NULL;
- para = NULL;
- while( fgets( line, DIM(line)-1, fp ) ) {
- char *keyword, *value;
-
- lnr++;
- if( *line && line[strlen(line)-1] != '\n' ) {
- err = "line too long";
- break;
- }
- for( p = line; isspace(*(byte*)p); p++ )
- ;
- if( !*p || *p == '#' )
- continue;
- keyword = p;
- if( *keyword == '%' ) {
- for( ; !isspace(*(byte*)p); p++ )
- ;
- if( *p )
- *p++ = 0;
- for( ; isspace(*(byte*)p); p++ )
- ;
- value = p;
- trim_trailing_ws( value, strlen(value) );
- if( !ascii_strcasecmp( keyword, "%echo" ) )
- log_info("%s\n", value );
- else if( !ascii_strcasecmp( keyword, "%dry-run" ) )
- outctrl.dryrun = 1;
- else if( !ascii_strcasecmp( keyword, "%commit" ) ) {
- outctrl.lnr = lnr;
- proc_parameter_file( para, fname, &outctrl, 0 );
- release_parameter_list( para );
- para = NULL;
- }
- else if( !ascii_strcasecmp( keyword, "%pubring" ) ) {
- if( outctrl.pub.fname && !strcmp( outctrl.pub.fname, value ) )
- ; /* still the same file - ignore it */
- else {
- xfree ( outctrl.pub.newfname );
- outctrl.pub.newfname = xstrdup ( value );
- outctrl.use_files = 1;
- }
- }
- else if( !ascii_strcasecmp( keyword, "%secring" ) ) {
- if( outctrl.sec.fname && !strcmp( outctrl.sec.fname, value ) )
- ; /* still the same file - ignore it */
- else {
- xfree ( outctrl.sec.newfname );
- outctrl.sec.newfname = xstrdup ( value );
- outctrl.use_files = 1;
- }
- }
- else
- log_info("skipping control `%s' (%s)\n", keyword, value );
-
-
- continue;
- }
-
-
- if( !(p = strchr( p, ':' )) || p == keyword ) {
- err = "missing colon";
- break;
- }
- if( *p )
- *p++ = 0;
- for( ; isspace(*(byte*)p); p++ )
- ;
- if( !*p ) {
- err = "missing argument";
- break;
- }
- value = p;
- trim_trailing_ws( value, strlen(value) );
-
- for(i=0; keywords[i].name; i++ ) {
- if( !ascii_strcasecmp( keywords[i].name, keyword ) )
- break;
- }
- if( !keywords[i].name ) {
- err = "unknown keyword";
- break;
- }
- if( keywords[i].key != pKEYTYPE && !para ) {
- err = "parameter block does not start with \"Key-Type\"";
- break;
- }
-
- if( keywords[i].key == pKEYTYPE && para ) {
- outctrl.lnr = lnr;
- proc_parameter_file( para, fname, &outctrl, 0 );
- release_parameter_list( para );
- para = NULL;
- }
- else {
- for( r = para; r; r = r->next ) {
- if( r->key == keywords[i].key )
- break;
- }
- if( r ) {
- err = "duplicate keyword";
- break;
- }
- }
- r = xcalloc (1, sizeof *r + strlen( value ) );
- r->lnr = lnr;
- r->key = keywords[i].key;
- strcpy( r->u.value, value );
- r->next = para;
- para = r;
- }
- if( err )
- log_error("%s:%d: %s\n", fname, lnr, err );
- else if( ferror(fp) ) {
- log_error("%s:%d: read error: %s\n", fname, lnr, strerror(errno) );
- }
- else if( para ) {
- outctrl.lnr = lnr;
- proc_parameter_file( para, fname, &outctrl, 0 );
- }
-
- if( outctrl.use_files ) { /* close open streams */
- iobuf_close( outctrl.pub.stream );
- iobuf_close( outctrl.sec.stream );
- xfree ( outctrl.pub.fname );
- xfree ( outctrl.pub.newfname );
- xfree ( outctrl.sec.fname );
- xfree ( outctrl.sec.newfname );
- }
-
- release_parameter_list( para );
- if( strcmp( fname, "-" ) )
- fclose(fp);
-}
-
-
-/****************
- * Generate a keypair (fname is only used in batch mode) If
- * CARD_SERIALNO is not NULL the fucntion will create the keys on an
- * OpenPGP Card.
- */
-void
-generate_keypair( const char *fname, const char *card_serialno )
-{
- unsigned int nbits;
- char *uid = NULL;
- DEK *dek;
- STRING2KEY *s2k;
- int algo;
- unsigned int use;
- int both = 0;
- u32 expire;
- struct para_data_s *para = NULL;
- struct para_data_s *r;
- struct output_control_s outctrl;
-
- memset (&outctrl, 0, sizeof (outctrl));
-
- if (opt.batch && card_serialno)
- {
- /* We don't yet support unattended key generation. */
- log_error (_("sorry, can't do this in batch mode\n"));
- return;
- }
-
- if (opt.batch)
- {
- read_parameter_file( fname );
- return;
- }
-
- if (card_serialno)
- {
- r = xcalloc (1, sizeof *r + strlen (card_serialno) );
- r->key = pSERIALNO;
- strcpy( r->u.value, card_serialno);
- r->next = para;
- para = r;
-
- algo = PUBKEY_ALGO_RSA;
-
- r = xcalloc (1, sizeof *r + 20 );
- r->key = pKEYTYPE;
- sprintf( r->u.value, "%d", algo );
- r->next = para;
- para = r;
- r = xcalloc (1, sizeof *r + 20 );
- r->key = pKEYUSAGE;
- strcpy (r->u.value, "sign");
- r->next = para;
- para = r;
-
- r = xcalloc (1, sizeof *r + 20 );
- r->key = pSUBKEYTYPE;
- sprintf( r->u.value, "%d", algo );
- r->next = para;
- para = r;
- r = xcalloc (1, sizeof *r + 20 );
- r->key = pSUBKEYUSAGE;
- strcpy (r->u.value, "encrypt");
- r->next = para;
- para = r;
-
- r = xcalloc (1, sizeof *r + 20 );
- r->key = pAUTHKEYTYPE;
- sprintf( r->u.value, "%d", algo );
- r->next = para;
- para = r;
- }
- else
- {
- algo = ask_algo (0, &use);
-
- if (!algo)
- { /* default: DSA with ElG subkey of the specified size */
- both = 1;
- r = xcalloc (1, sizeof *r + 20 );
- r->key = pKEYTYPE;
- sprintf( r->u.value, "%d", PUBKEY_ALGO_DSA );
- r->next = para;
- para = r;
- tty_printf(_("DSA keypair will have 1024 bits.\n"));
- r = xcalloc (1, sizeof *r + 20 );
- r->key = pKEYLENGTH;
- strcpy( r->u.value, "1024" );
- r->next = para;
- para = r;
- r = xcalloc (1, sizeof *r + 20 );
- r->key = pKEYUSAGE;
- strcpy( r->u.value, "sign" );
- r->next = para;
- para = r;
-
- algo = PUBKEY_ALGO_ELGAMAL_E;
- r = xcalloc (1, sizeof *r + 20 );
- r->key = pSUBKEYTYPE;
- sprintf( r->u.value, "%d", algo );
- r->next = para;
- para = r;
- r = xcalloc (1, sizeof *r + 20 );
- r->key = pSUBKEYUSAGE;
- strcpy( r->u.value, "encrypt" );
- r->next = para;
- r->next = para;
- para = r;
- }
- else
- {
- r = xcalloc (1, sizeof *r + 20 );
- r->key = pKEYTYPE;
- sprintf( r->u.value, "%d", algo );
- r->next = para;
- para = r;
-
- if (use)
- {
- r = xcalloc (1, sizeof *r + 20 );
- r->key = pKEYUSAGE;
- sprintf( r->u.value, "%s%s",
- (use & PUBKEY_USAGE_SIG)? "sign ":"",
- (use & PUBKEY_USAGE_ENC)? "encrypt ":"" );
- r->next = para;
- para = r;
- }
- }
-
- nbits = ask_keysize( algo );
- r = xcalloc (1, sizeof *r + 20 );
- r->key = both? pSUBKEYLENGTH : pKEYLENGTH;
- sprintf( r->u.value, "%u", nbits);
- r->next = para;
- para = r;
- }
-
- expire = ask_expire_interval(0);
- r = xcalloc (1, sizeof *r + 20 );
- r->key = pKEYEXPIRE;
- r->u.expire = expire;
- r->next = para;
- para = r;
- r = xcalloc (1, sizeof *r + 20 );
- r->key = pSUBKEYEXPIRE;
- r->u.expire = expire;
- r->next = para;
- para = r;
-
- uid = ask_user_id(0);
- if (!uid)
- {
- log_error(_("Key generation canceled.\n"));
- release_parameter_list( para );
- return;
- }
- r = xcalloc (1, sizeof *r + strlen(uid) );
- r->key = pUSERID;
- strcpy( r->u.value, uid );
- r->next = para;
- para = r;
-
- dek = card_serialno? NULL : ask_passphrase( &s2k );
- if (dek)
- {
- r = xcalloc (1, sizeof *r );
- r->key = pPASSPHRASE_DEK;
- r->u.dek = dek;
- r->next = para;
- para = r;
- r = xcalloc (1, sizeof *r );
- r->key = pPASSPHRASE_S2K;
- r->u.s2k = s2k;
- r->next = para;
- para = r;
- }
-
- proc_parameter_file (para, "[internal]", &outctrl, !!card_serialno);
- release_parameter_list (para);
-}
-
-
-static void
-print_status_key_created (int letter, PKT_public_key *pk)
-{
- byte array[MAX_FINGERPRINT_LEN], *s;
- char buf[MAX_FINGERPRINT_LEN*2+30], *p;
- size_t i, n;
-
- p = buf;
- *p++ = letter;
- *p++ = ' ';
- fingerprint_from_pk (pk, array, &n);
- s = array;
- for (i=0; i < n ; i++, s++, p += 2)
- sprintf (p, "%02X", *s);
- *p = 0;
- write_status_text (STATUS_KEY_CREATED, buf);
-}
-
-
-
-static void
-do_generate_keypair (struct para_data_s *para,
- struct output_control_s *outctrl, int card)
-{
- KBNODE pub_root = NULL;
- KBNODE sec_root = NULL;
- PKT_secret_key *sk = NULL;
- const char *s;
- struct revocation_key *revkey;
- int rc;
- int did_sub = 0;
-
- if (outctrl->dryrun)
- {
- log_info ("dry-run mode - key generation skipped\n");
- return;
- }
-
-
- if (outctrl->use_files)
- {
- if (outctrl->pub.newfname)
- {
- iobuf_close (outctrl->pub.stream);
- outctrl->pub.stream = NULL;
- xfree (outctrl->pub.fname);
- outctrl->pub.fname = outctrl->pub.newfname;
- outctrl->pub.newfname = NULL;
-
- outctrl->pub.stream = iobuf_create (outctrl->pub.fname);
- if (!outctrl->pub.stream)
- {
- log_error ("can't create `%s': %s\n", outctrl->pub.fname,
- strerror (errno));
- return;
- }
- if (opt.armor)
- {
- outctrl->pub.afx.what = 1;
- iobuf_push_filter (outctrl->pub.stream, armor_filter,
- &outctrl->pub.afx);
- }
- }
- if (outctrl->sec.newfname)
- {
- iobuf_close (outctrl->sec.stream);
- outctrl->sec.stream = NULL;
- xfree (outctrl->sec.fname);
- outctrl->sec.fname = outctrl->sec.newfname;
- outctrl->sec.newfname = NULL;
-
- outctrl->sec.stream = iobuf_create (outctrl->sec.fname);
- if (!outctrl->sec.stream)
- {
- log_error ("can't create `%s': %s\n", outctrl->sec.fname,
- strerror (errno));
- return;
- }
- if (opt.armor)
- {
- outctrl->sec.afx.what = 5;
- iobuf_push_filter (outctrl->sec.stream, armor_filter,
- &outctrl->sec.afx);
- }
- }
- assert (outctrl->pub.stream);
- assert (outctrl->sec.stream);
- if (opt.verbose)
- {
- log_info (_("writing public key to `%s'\n"), outctrl->pub.fname);
- if (card)
- log_info (_("writing secret key stub to `%s'\n"),
- outctrl->sec.fname);
- else
- log_info (_("writing secret key to `%s'\n"), outctrl->sec.fname);
- }
- }
-
-
- /* We create the packets as a tree of kbnodes. Because the structure
- * we create is known in advance we simply generate a linked list.
- * The first packet is a dummy comment packet which we flag
- * as deleted. The very first packet must always be a KEY packet.
- */
- pub_root = make_comment_node ("#");
- delete_kbnode (pub_root);
- sec_root = make_comment_node ("#");
- delete_kbnode (sec_root);
- if (!card)
- {
- rc = do_create (get_parameter_algo (para, pKEYTYPE),
- get_parameter_uint (para, pKEYLENGTH),
- pub_root, sec_root,
- get_parameter_dek (para, pPASSPHRASE_DEK),
- get_parameter_s2k (para, pPASSPHRASE_S2K),
- &sk, get_parameter_u32 (para, pKEYEXPIRE));
- }
- else
- {
- rc = gen_card_key (PUBKEY_ALGO_RSA, 1, pub_root, sec_root,
- get_parameter_u32 (para, pKEYEXPIRE), para);
- if (!rc)
- {
- sk = sec_root->next->pkt->pkt.secret_key;
- assert (sk);
- }
-
- }
-
- if (!rc && (revkey = get_parameter_revkey (para, pREVOKER)))
- {
- rc = write_direct_sig (pub_root, pub_root, sk, revkey);
- if (!rc)
- write_direct_sig (sec_root, pub_root, sk, revkey);
- }
-
- if (!rc && (s = get_parameter_value (para, pUSERID)))
- {
- write_uid (pub_root, s);
- if (!rc)
- write_uid (sec_root, s);
- if (!rc)
- rc = write_selfsig (pub_root, pub_root, sk,
- get_parameter_uint (para, pKEYUSAGE));
- if (!rc)
- rc = write_selfsig (sec_root, pub_root, sk,
- get_parameter_uint (para, pKEYUSAGE));
- }
-
- if ((! rc) && get_parameter (para, pSUBKEYTYPE))
- {
- if (!card)
- {
- rc = do_create (get_parameter_algo (para, pSUBKEYTYPE),
- get_parameter_uint (para, pSUBKEYLENGTH),
- pub_root, sec_root,
- get_parameter_dek (para, pPASSPHRASE_DEK),
- get_parameter_s2k (para, pPASSPHRASE_S2K),
- NULL, get_parameter_u32 (para, pSUBKEYEXPIRE));
- }
- else
- {
- rc = gen_card_key (PUBKEY_ALGO_RSA, 2, pub_root, sec_root,
- get_parameter_u32 (para, pKEYEXPIRE), para);
- }
-
- if (!rc)
- rc = write_keybinding (pub_root, pub_root, sk,
- get_parameter_uint (para, pSUBKEYUSAGE));
- if (!rc)
- rc = write_keybinding (sec_root, pub_root, sk,
- get_parameter_uint (para, pSUBKEYUSAGE));
- did_sub = 1;
- }
-
- if ((! rc) && card && get_parameter (para, pAUTHKEYTYPE))
- {
- rc = gen_card_key (PUBKEY_ALGO_RSA, 3, pub_root, sec_root,
- get_parameter_u32 (para, pKEYEXPIRE), para);
-
- if (!rc)
- rc = write_keybinding (pub_root, pub_root, sk, PUBKEY_USAGE_AUTH);
- if (!rc)
- rc = write_keybinding (sec_root, pub_root, sk, PUBKEY_USAGE_AUTH);
- }
-
-
- if (!rc && outctrl->use_files)
- { /* direct write to specified files */
- rc = write_keyblock (outctrl->pub.stream, pub_root);
- if (rc)
- log_error ("can't write public key: %s\n", gpg_strerror (rc));
- if (!rc)
- {
- rc = write_keyblock (outctrl->sec.stream, sec_root);
- if (rc)
- log_error ("can't write secret key: %s\n", gpg_strerror (rc));
- }
-
- }
- else if (!rc)
- { /* write to the standard keyrings */
- KEYDB_HANDLE pub_hd = keydb_new (0);
- KEYDB_HANDLE sec_hd = keydb_new (1);
-
- /* FIXME: we may have to create the keyring first */
- rc = keydb_locate_writable (pub_hd, NULL);
- if (rc)
- log_error (_("no writable public keyring found: %s\n"),
- gpg_strerror (rc));
-
- if (!rc)
- {
- rc = keydb_locate_writable (sec_hd, NULL);
- if (rc)
- log_error (_("no writable secret keyring found: %s\n"),
- gpg_strerror (rc));
- }
-
- if (!rc && opt.verbose)
- {
- log_info (_("writing public key to `%s'\n"),
- keydb_get_resource_name (pub_hd));
- if (card)
- log_info (_("writing secret key stub to `%s'\n"),
- keydb_get_resource_name (sec_hd));
- else
- log_info (_("writing secret key to `%s'\n"),
- keydb_get_resource_name (sec_hd));
- }
-
- if (!rc)
- {
- rc = keydb_insert_keyblock (pub_hd, pub_root);
- if (rc)
- log_error (_("error writing public keyring `%s': %s\n"),
- keydb_get_resource_name (pub_hd), gpg_strerror (rc));
- }
-
- if (!rc)
- {
- rc = keydb_insert_keyblock (sec_hd, sec_root);
- if (rc)
- log_error (_("error writing secret keyring `%s': %s\n"),
- keydb_get_resource_name (pub_hd), gpg_strerror (rc));
- }
-
- keydb_release (pub_hd);
- keydb_release (sec_hd);
-
- if (!rc)
- {
- int no_enc_rsa =
- get_parameter_algo (para, pKEYTYPE) == PUBKEY_ALGO_RSA
- && get_parameter_uint (para, pKEYUSAGE)
- && !(get_parameter_uint (para, pKEYUSAGE) & PUBKEY_USAGE_ENC);
- PKT_public_key *pk = find_kbnode (pub_root,
- PKT_PUBLIC_KEY)->pkt->pkt.
- public_key;
-
- update_ownertrust (pk,
- ((get_ownertrust (pk) & ~TRUST_MASK)
- | TRUST_ULTIMATE));
-
- if (!opt.batch)
- {
- tty_printf (_("public and secret key created and signed.\n"));
- tty_printf (_("key marked as ultimately trusted.\n"));
- tty_printf ("\n");
- list_keyblock (pub_root, 0, 1, NULL);
- }
-
-
- if (!opt.batch
- && (get_parameter_algo (para, pKEYTYPE) == PUBKEY_ALGO_DSA
- || no_enc_rsa) && !get_parameter (para, pSUBKEYTYPE))
- {
- tty_printf (_("Note that this key cannot be used for "
- "encryption. You may want to use\n"
- "the command \"--edit-key\" to generate a "
- "secondary key for this purpose.\n"));
- }
-
- if (!opt.batch && card)
- {
- tty_printf(_(
-"Please create a revocation certificate now, so that you are able\n"
-"to revoke the key if it ever happens that you lose your card or\n"
-"the card gets damaged. Use the command \"--gen-revoke\".\n"
- ));
- }
- }
- }
-
- if (rc)
- {
- if (opt.batch)
- log_error ("key generation failed: %s\n", gpg_strerror (rc));
- else
- tty_printf (_("Key generation failed: %s\n"), gpg_strerror (rc));
- }
- else
- {
- PKT_public_key *pk = find_kbnode (pub_root,
- PKT_PUBLIC_KEY)->pkt->pkt.public_key;
- print_status_key_created (did_sub ? 'B' : 'P', pk);
- }
-
- release_kbnode (pub_root);
- release_kbnode (sec_root);
- if (sk && !card) /* The unprotected secret key unless we have */
- free_secret_key (sk); /* a shallow copy in card mode. */
-}
-
-
-/****************
- * add a new subkey to an existing key.
- * Returns true if a new key has been generated and put into the keyblocks.
- */
-int
-generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
-{
- int okay=0, rc=0;
- KBNODE node;
- PKT_secret_key *sk = NULL; /* this is the primary sk */
- int algo;
- unsigned int use;
- u32 expire;
- unsigned nbits;
- char *passphrase = NULL;
- DEK *dek = NULL;
- STRING2KEY *s2k = NULL;
- u32 cur_time;
-
- /* break out the primary secret key */
- node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
- if( !node ) {
- log_error("Oops; secret key not found anymore!\n");
- goto leave;
- }
-
- /* make a copy of the sk to keep the protected one in the keyblock */
- sk = copy_secret_key( NULL, node->pkt->pkt.secret_key );
-
- cur_time = make_timestamp();
- if( sk->timestamp > cur_time ) {
- ulong d = sk->timestamp - cur_time;
- log_info( d==1 ? _("key has been created %lu second "
- "in future (time warp or clock problem)\n")
- : _("key has been created %lu seconds "
- "in future (time warp or clock problem)\n"), d );
- if( !opt.ignore_time_conflict ) {
- rc = GPG_ERR_TIME_CONFLICT;
- goto leave;
- }
- }
-
- if (sk->version < 4) {
- log_info (_("NOTE: creating subkeys for v3 keys "
- "is not OpenPGP compliant\n"));
- goto leave;
- }
-
- /* unprotect to get the passphrase */
- switch( is_secret_key_protected( sk ) ) {
- case -1:
- rc = GPG_ERR_PUBKEY_ALGO;
- break;
- case 0:
- tty_printf("This key is not protected.\n");
- break;
- default:
- tty_printf("Key is protected.\n");
- rc = check_secret_key( sk, 0 );
- if( !rc )
- passphrase = get_last_passphrase();
- break;
- }
- if( rc )
- goto leave;
-
-
- algo = ask_algo( 1, &use );
- assert(algo);
- nbits = ask_keysize( algo );
- expire = ask_expire_interval(0);
- if( !cpr_enabled() && !cpr_get_answer_is_yes("keygen.sub.okay",
- _("Really create? ") ) )
- goto leave;
-
- if( passphrase ) {
- s2k = xmalloc_secure ( sizeof *s2k );
- s2k->mode = opt.s2k_mode;
- s2k->hash_algo = opt.s2k_digest_algo;
- set_next_passphrase( passphrase );
- dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2,
- NULL, NULL );
- }
-
- rc = do_create( algo, nbits, pub_keyblock, sec_keyblock,
- dek, s2k, NULL, expire );
- if( !rc )
- rc = write_keybinding(pub_keyblock, pub_keyblock, sk, use);
- if( !rc )
- rc = write_keybinding(sec_keyblock, pub_keyblock, sk, use);
- if( !rc ) {
- okay = 1;
- write_status_text (STATUS_KEY_CREATED, "S");
- }
-
- leave:
- if( rc )
- log_error(_("Key generation failed: %s\n"), gpg_strerror (rc) );
- xfree ( passphrase );
- xfree ( dek );
- xfree ( s2k );
- if( sk ) /* release the copy of the (now unprotected) secret key */
- free_secret_key(sk);
- set_next_passphrase( NULL );
- return okay;
-}
-
-/****************
- * Write a keyblock to an output stream
- */
-static int
-write_keyblock( iobuf_t out, KBNODE node )
-{
- for( ; node ; node = node->next ) {
- int rc = build_packet( out, node->pkt );
- if( rc ) {
- log_error("build_packet(%d) failed: %s\n",
- node->pkt->pkttype, gpg_strerror (rc) );
- return rc;
- }
- }
- return 0;
-}
-
-
-
-static int
-gen_card_key (int algo, int keyno, KBNODE pub_root, KBNODE sec_root,
- u32 expireval, struct para_data_s *para)
-{
- int rc;
- const char *s;
- struct agent_card_genkey_s info;
- PACKET *pkt;
- PKT_secret_key *sk;
- PKT_public_key *pk;
-
- assert (algo == PUBKEY_ALGO_RSA);
-
- rc = agent_scd_genkey (&info, keyno, 1);
-/* if (gpg_err_code (rc) == GPG_ERR_EEXIST) */
-/* { */
-/* tty_printf ("\n"); */
-/* log_error ("WARNING: key does already exists!\n"); */
-/* tty_printf ("\n"); */
-/* if ( cpr_get_answer_is_yes( "keygen.card.replace_key", */
-/* _("Replace existing key? "))) */
-/* rc = agent_scd_genkey (&info, keyno, 1); */
-/* } */
-
- if (rc)
- return rc;
-
- if ( !info.n || !info.e )
- {
- log_error ("communication error with SCD\n");
- gcry_mpi_release (info.n);
- gcry_mpi_release (info.e);
- return gpg_error (GPG_ERR_GENERAL);
- }
-
-
- pk = xcalloc (1, sizeof *pk );
- sk = xcalloc (1, sizeof *sk );
- sk->timestamp = pk->timestamp = info.created_at;
- sk->version = pk->version = 4;
- if (expireval)
- sk->expiredate = pk->expiredate = pk->timestamp + expireval;
- sk->pubkey_algo = pk->pubkey_algo = algo;
- pk->pkey[0] = info.n;
- pk->pkey[1] = info.e;
- sk->skey[0] = gcry_mpi_copy (pk->pkey[0]);
- sk->skey[1] = gcry_mpi_copy (pk->pkey[1]);
- sk->skey[2] = gcry_mpi_set_opaque (NULL, xstrdup ("dummydata"), 10*8);
- sk->is_protected = 1;
- sk->protect.s2k.mode = 1002;
- s = get_parameter_value (para, pSERIALNO);
- if (s)
- {
- for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1];
- sk->protect.ivlen++, s += 2)
- sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s);
- }
-
- pkt = xcalloc (1,sizeof *pkt);
- pkt->pkttype = keyno == 1 ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
- pkt->pkt.public_key = pk;
- add_kbnode(pub_root, new_kbnode( pkt ));
-
- pkt = xcalloc (1,sizeof *pkt);
- pkt->pkttype = keyno == 1 ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY;
- pkt->pkt.secret_key = sk;
- add_kbnode(sec_root, new_kbnode( pkt ));
-
- return 0;
-}
-
-
-
diff --git a/g10/keyid.c b/g10/keyid.c
deleted file mode 100644
index aaa70cccb..000000000
--- a/g10/keyid.c
+++ /dev/null
@@ -1,609 +0,0 @@
-/* keyid.c - key ID and fingerprint handling
- * Copyright (C) 1998, 1999, 2000, 2001, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <time.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "main.h"
-#include "packet.h"
-#include "options.h"
-#include "mpi.h"
-#include "keydb.h"
-#include "i18n.h"
-
-
-int
-pubkey_letter( int algo )
-{
- switch( algo ) {
- case PUBKEY_ALGO_RSA: return 'R' ;
- case PUBKEY_ALGO_RSA_E: return 'r' ;
- case PUBKEY_ALGO_RSA_S: return 's' ;
- case PUBKEY_ALGO_ELGAMAL_E: return 'g';
- case PUBKEY_ALGO_ELGAMAL: return 'G' ;
- case PUBKEY_ALGO_DSA: return 'D' ;
- default: return '?';
- }
-}
-
-static gcry_md_hd_t
-do_fingerprint_md( PKT_public_key *pk )
-{
- gcry_md_hd_t md;
- unsigned int n;
- unsigned int nn[PUBKEY_MAX_NPKEY];
- byte *pp[PUBKEY_MAX_NPKEY];
- int i;
- int npkey = pubkey_get_npkey( pk->pubkey_algo );
-
- gcry_md_open (&md, pk->version < 4 ? DIGEST_ALGO_RMD160
- : DIGEST_ALGO_SHA1, 0);
-
- n = pk->version < 4 ? 8 : 6;
- for(i=0; i < npkey; i++ ) {
- size_t nbytes;
-
- if (gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, 0, &nbytes, pk->pkey[i] ))
- BUG ();
- /* fixme: we should try to allocate a buffer on the stack */
- pp[i] = xmalloc(nbytes);
- if (gcry_mpi_print ( GCRYMPI_FMT_PGP, pp[i], nbytes, &nbytes,
- pk->pkey[i] ))
- BUG ();
- nn[i] = nbytes;
- n += nn[i];
- }
-
- gcry_md_putc ( md, 0x99 ); /* ctb */
- gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */
- gcry_md_putc ( md, n );
- if( pk->version < 4 )
- gcry_md_putc ( md, 3 );
- else
- gcry_md_putc ( md, 4 );
-
- { u32 a = pk->timestamp;
- gcry_md_putc ( md, a >> 24 );
- gcry_md_putc ( md, a >> 16 );
- gcry_md_putc ( md, a >> 8 );
- gcry_md_putc ( md, a );
- }
- if( pk->version < 4 ) {
- u16 a;
-
- if( pk->expiredate )
- a = (u16)((pk->expiredate - pk->timestamp) / 86400L);
- else
- a = 0;
- gcry_md_putc ( md, a >> 8 );
- gcry_md_putc ( md, a );
- }
- gcry_md_putc ( md, pk->pubkey_algo );
- for(i=0; i < npkey; i++ ) {
- gcry_md_write( md, pp[i], nn[i] );
- xfree (pp[i]);
- }
- gcry_md_final ( md );
-
- return md;
-}
-
-static gcry_md_hd_t
-do_fingerprint_md_sk( PKT_secret_key *sk )
-{
- PKT_public_key pk;
- int npkey = pubkey_get_npkey( sk->pubkey_algo ); /* npkey is correct! */
- int i;
-
- pk.pubkey_algo = sk->pubkey_algo;
- pk.version = sk->version;
- pk.timestamp = sk->timestamp;
- pk.expiredate = sk->expiredate;
- pk.pubkey_algo = sk->pubkey_algo;
- for( i=0; i < npkey; i++ )
- pk.pkey[i] = sk->skey[i];
- return do_fingerprint_md( &pk );
-}
-
-
-u32
-v3_keyid (gcry_mpi_t a, u32 *ki)
-{
- byte *buffer;
- size_t nbytes;
-
- if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nbytes, a ))
- BUG ();
- /* fixme: allocate it on the stack */
- buffer = xmalloc (nbytes);
- if (gcry_mpi_print( GCRYMPI_FMT_USG, buffer, nbytes, NULL, a ))
- BUG ();
- if (nbytes < 8) /* oops */
- ki[0] = ki[1] = 0;
- else
- {
- memcpy (ki+0, buffer+nbytes-8, 4);
- memcpy (ki+1, buffer+nbytes-4, 4);
- }
- xfree (buffer);
- return ki[1];
-}
-
-
-
-/****************
- * Get the keyid from the secret key and put it into keyid
- * if this is not NULL. Return the 32 low bits of the keyid.
- */
-u32
-keyid_from_sk( PKT_secret_key *sk, u32 *keyid )
-{
- u32 lowbits;
- u32 dummy_keyid[2];
-
- if( !keyid )
- keyid = dummy_keyid;
-
- if( sk->version < 4 && is_RSA(sk->pubkey_algo) ) {
- keyid[0] = keyid[1] = 0;
- lowbits = pubkey_get_npkey(sk->pubkey_algo) ?
- v3_keyid (sk->skey[0], keyid) : 0;
- }
- else {
- const byte *dp;
- gcry_md_hd_t md;
- md = do_fingerprint_md_sk(sk);
- dp = gcry_md_read ( md, 0 );
- keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
- keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
- lowbits = keyid[1];
- gcry_md_close (md);
- }
-
- return lowbits;
-}
-
-
-/****************
- * Get the keyid from the public key and put it into keyid
- * if this is not NULL. Return the 32 low bits of the keyid.
- */
-u32
-keyid_from_pk( PKT_public_key *pk, u32 *keyid )
-{
- u32 lowbits;
- u32 dummy_keyid[2];
-
- if( !keyid )
- keyid = dummy_keyid;
-
- if( pk->keyid[0] || pk->keyid[1] ) {
- keyid[0] = pk->keyid[0];
- keyid[1] = pk->keyid[1];
- lowbits = keyid[1];
- }
- else if( pk->version < 4 && is_RSA(pk->pubkey_algo) ) {
- keyid[0] = keyid[1] = 0;
- lowbits = pubkey_get_npkey(pk->pubkey_algo) ?
- v3_keyid (pk->pkey[0], keyid) : 0 ;
- pk->keyid[0] = keyid[0];
- pk->keyid[1] = keyid[1];
- }
- else {
- const byte *dp;
- gcry_md_hd_t md;
- md = do_fingerprint_md(pk);
- dp = gcry_md_read ( md, 0 );
- keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
- keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
- lowbits = keyid[1];
- gcry_md_close (md);
- pk->keyid[0] = keyid[0];
- pk->keyid[1] = keyid[1];
- }
-
- return lowbits;
-}
-
-
-/****************
- * Get the keyid from the fingerprint. This function is simple for most
- * keys, but has to do a keylookup for old stayle keys.
- */
-u32
-keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid )
-{
- u32 dummy_keyid[2];
-
- if( !keyid )
- keyid = dummy_keyid;
-
- if( fprint_len != 20 ) {
- /* This is special as we have to lookup the key first */
- PKT_public_key pk;
- int rc;
-
- memset( &pk, 0, sizeof pk );
- rc = get_pubkey_byfprint( &pk, fprint, fprint_len );
- if( rc ) {
- log_error("Oops: keyid_from_fingerprint: no pubkey\n");
- keyid[0] = 0;
- keyid[1] = 0;
- }
- else
- keyid_from_pk( &pk, keyid );
- }
- else {
- const byte *dp = fprint;
- keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
- keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
- }
-
- return keyid[1];
-}
-
-
-u32
-keyid_from_sig( PKT_signature *sig, u32 *keyid )
-{
- if( keyid ) {
- keyid[0] = sig->keyid[0];
- keyid[1] = sig->keyid[1];
- }
- return sig->keyid[1];
-}
-
-byte *
-namehash_from_uid(PKT_user_id *uid)
-{
- if(uid->namehash==NULL)
- {
- uid->namehash=xmalloc (20);
-
- if(uid->attrib_data)
- gcry_md_hash_buffer (GCRY_MD_RMD160, uid->namehash,
- uid->attrib_data,uid->attrib_len);
- else
- gcry_md_hash_buffer (GCRY_MD_RMD160, uid->namehash,
- uid->name,uid->len);
- }
-
- return uid->namehash;
-}
-
-/****************
- * return the number of bits used in the pk
- */
-unsigned
-nbits_from_pk( PKT_public_key *pk )
-{
- return pubkey_nbits( pk->pubkey_algo, pk->pkey );
-}
-
-/****************
- * return the number of bits used in the sk
- */
-unsigned
-nbits_from_sk( PKT_secret_key *sk )
-{
- return pubkey_nbits( sk->pubkey_algo, sk->skey );
-}
-
-static const char *
-mk_datestr (char *buffer, time_t atime)
-{
- struct tm *tp;
-
- if ( atime < 0 ) /* 32 bit time_t and after 2038-01-19 */
- strcpy (buffer, "????" "-??" "-??"); /* mark this as invalid */
- else {
- tp = gmtime (&atime);
- sprintf (buffer,"%04d-%02d-%02d",
- 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
- }
- return buffer;
-}
-
-/****************
- * return a string with the creation date of the pk
- * Note: this is alloced in a static buffer.
- * Format is: yyyy-mm-dd
- */
-const char *
-datestr_from_pk( PKT_public_key *pk )
-{
- static char buffer[11+5];
- time_t atime = pk->timestamp;
-
- return mk_datestr (buffer, atime);
-}
-
-const char *
-datestr_from_sk( PKT_secret_key *sk )
-{
- static char buffer[11+5];
- time_t atime = sk->timestamp;
-
- return mk_datestr (buffer, atime);
-}
-
-const char *
-datestr_from_sig( PKT_signature *sig )
-{
- static char buffer[11+5];
- time_t atime = sig->timestamp;
-
- return mk_datestr (buffer, atime);
-}
-
-const char *
-expirestr_from_pk( PKT_public_key *pk )
-{
- static char buffer[11+5];
- time_t atime;
-
- if( !pk->expiredate )
- return _("never ");
- atime = pk->expiredate;
- return mk_datestr (buffer, atime);
-}
-
-const char *
-expirestr_from_sk( PKT_secret_key *sk )
-{
- static char buffer[11+5];
- time_t atime;
-
- if( !sk->expiredate )
- return _("never ");
- atime = sk->expiredate;
- return mk_datestr (buffer, atime);
-}
-
-const char *
-expirestr_from_sig( PKT_signature *sig )
-{
- static char buffer[11+5];
- time_t atime;
-
- if(!sig->expiredate)
- return _("never ");
- atime=sig->expiredate;
- return mk_datestr (buffer, atime);
-}
-
-const char *
-colon_strtime (u32 t)
-{
- if (!t)
- return "";
- if (opt.fixed_list_mode) {
- static char buf[15];
- sprintf (buf, "%lu", (ulong)t);
- return buf;
- }
- return strtimestamp(t);
-}
-
-const char *
-colon_datestr_from_pk (PKT_public_key *pk)
-{
- if (opt.fixed_list_mode) {
- static char buf[15];
- sprintf (buf, "%lu", (ulong)pk->timestamp);
- return buf;
- }
- return datestr_from_pk (pk);
-}
-
-const char *
-colon_datestr_from_sk (PKT_secret_key *sk)
-{
- if (opt.fixed_list_mode) {
- static char buf[15];
- sprintf (buf, "%lu", (ulong)sk->timestamp);
- return buf;
- }
- return datestr_from_sk (sk);
-}
-
-const char *
-colon_datestr_from_sig (PKT_signature *sig)
-{
- if (opt.fixed_list_mode) {
- static char buf[15];
- sprintf (buf, "%lu", (ulong)sig->timestamp);
- return buf;
- }
- return datestr_from_sig (sig);
-}
-
-const char *
-colon_expirestr_from_sig (PKT_signature *sig)
-{
- if(!sig->expiredate)
- return "";
- if (opt.fixed_list_mode) {
- static char buf[15];
- sprintf (buf, "%lu", (ulong)sig->expiredate);
- return buf;
- }
- return expirestr_from_sig (sig);
-}
-
-
-/**************** .
- * Return a byte array with the fingerprint for the given PK/SK
- * The length of the array is returned in ret_len. Caller must free
- * the array or provide an array of length MAX_FINGERPRINT_LEN.
- */
-
-byte *
-fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len )
-{
- byte *buf;
- const byte *dp;
- size_t len;
-
- if( pk->version < 4 && is_RSA(pk->pubkey_algo) ) {
- /* RSA in version 3 packets is special */
- gcry_md_hd_t md;
-
- gcry_md_open (&md, DIGEST_ALGO_MD5, 0);
- if( pubkey_get_npkey( pk->pubkey_algo ) > 1 ) {
- size_t nbytes;
-
- if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes,
- pk->pkey[0]))
- BUG ();
- /* fixme: allocate it on the stack */
- buf = xmalloc(nbytes);
- if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes, NULL,pk->pkey[0]))
- BUG ();
- gcry_md_write (md, buf, nbytes);
- xfree (buf);
- if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, pk->pkey[1]))
- BUG ();
- /* fixme: allocate it on the stack */
- buf = xmalloc(nbytes);
- if (gcry_mpi_print( GCRYMPI_FMT_USG, buf, nbytes, NULL,pk->pkey[1]))
- BUG ();
- gcry_md_write( md, buf, nbytes );
- xfree(buf);
- }
- gcry_md_final (md);
- if( !array )
- array = xmalloc ( 16 );
- len = 16;
- memcpy(array, gcry_md_read (md, DIGEST_ALGO_MD5), 16 );
- gcry_md_close (md);
- }
- else {
- gcry_md_hd_t md;
- md = do_fingerprint_md(pk);
- dp = gcry_md_read ( md, 0 );
- len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
- assert( len <= MAX_FINGERPRINT_LEN );
- if( !array )
- array = xmalloc ( len );
- memcpy(array, dp, len );
- pk->keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
- pk->keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
- gcry_md_close (md);
- }
-
- *ret_len = len;
- return array;
-}
-
-byte *
-fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len )
-{
- byte *buf;
- const char *dp;
- size_t len;
-
- if( sk->version < 4 && is_RSA(sk->pubkey_algo) ) {
- /* RSA in version 3 packets is special */
- gcry_md_hd_t md;
-
- gcry_md_open (&md, DIGEST_ALGO_MD5, 0);
- if( pubkey_get_npkey( sk->pubkey_algo ) > 1 ) {
- size_t nbytes;
-
- if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, sk->skey[0]))
- BUG ();
- /* fixme: allocate it on the stack */
- buf = xmalloc(nbytes);
- if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes, NULL,sk->skey[0]))
- BUG ();
- gcry_md_write (md, buf, nbytes);
- xfree (buf);
- if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, sk->skey[1]))
- BUG ();
- /* fixme: allocate it on the stack */
- buf = xmalloc(nbytes);
- if (gcry_mpi_print( GCRYMPI_FMT_USG, buf,nbytes, NULL, sk->skey[1]))
- BUG ();
- gcry_md_write( md, buf, nbytes );
- xfree(buf);
- }
- gcry_md_final (md);
- if( !array )
- array = xmalloc ( 16 );
- len = 16;
- memcpy(array, gcry_md_read (md, DIGEST_ALGO_MD5), 16 );
- gcry_md_close (md);
- }
- else {
- gcry_md_hd_t md;
-
- md = do_fingerprint_md_sk(sk);
- dp = gcry_md_read ( md, 0 );
- len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
- assert( len <= MAX_FINGERPRINT_LEN );
- if( !array )
- array = xmalloc ( len );
- memcpy(array, dp, len );
- gcry_md_close (md);
- }
-
- *ret_len = len;
- return array;
-}
-
-
-/* Create a serialno/fpr string from the serial number and the secret
- * key. caller must free the returned string. There is no error
- * return. */
-char *
-serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
- PKT_secret_key *sk)
-{
- unsigned char fpr[MAX_FINGERPRINT_LEN];
- size_t fprlen;
- char *buffer, *p;
- int i;
-
- fingerprint_from_sk (sk, fpr, &fprlen);
- buffer = p= xmalloc (snlen*2 + 1 + fprlen*2 + 1);
- for (i=0; i < snlen; i++, p+=2)
- sprintf (p, "%02X", sn[i]);
- *p++ = '/';
- for (i=0; i < fprlen; i++, p+=2)
- sprintf (p, "%02X", fpr[i]);
- *p = 0;
- return buffer;
-}
-
-
-
-
-
-
-
-
diff --git a/g10/keylist.c b/g10/keylist.c
deleted file mode 100644
index 50850de71..000000000
--- a/g10/keylist.c
+++ /dev/null
@@ -1,1466 +0,0 @@
-/* keylist.c - List all or selected keys
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "options.h"
-#include "packet.h"
-#include "errors.h"
-#include "keydb.h"
-#include "memory.h"
-#include "photoid.h"
-#include "util.h"
-#include "ttyio.h"
-#include "trustdb.h"
-#include "main.h"
-#include "i18n.h"
-#include "status.h"
-
-static void list_all(int);
-static void list_one( STRLIST names, int secret);
-static void print_card_serialno (PKT_secret_key *sk);
-
-struct sig_stats
-{
- int inv_sigs;
- int no_key;
- int oth_err;
-};
-
-static FILE *attrib_fp=NULL;
-
-/****************
- * List the keys
- * If list is NULL, all available keys are listed
- */
-void
-public_key_list( STRLIST list )
-{
- if(opt.with_colons)
- {
- byte trust_model,marginals,completes,cert_depth;
- ulong created,nextcheck;
-
- read_trust_options(&trust_model,&created,&nextcheck,
- &marginals,&completes,&cert_depth);
-
- printf("tru:");
-
- if(nextcheck && nextcheck <= make_timestamp())
- printf("o");
- if(trust_model!=opt.trust_model)
- printf("t");
- if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
- {
- if(marginals!=opt.marginals_needed)
- printf("m");
- if(completes!=opt.completes_needed)
- printf("c");
- if(cert_depth!=opt.max_cert_depth)
- printf("d");
- }
-
- printf(":%d:%lu:%lu",trust_model,created,nextcheck);
-
- /* Only show marginals, completes, and cert_depth in the classic
- or PGP trust models since they are not meaningful
- otherwise. */
-
- if(trust_model==TM_PGP || trust_model==TM_CLASSIC)
- printf(":%d:%d:%d",marginals,completes,cert_depth);
-
- printf("\n");
- }
-
- if( !list )
- list_all(0);
- else
- list_one( list, 0 );
-}
-
-void
-secret_key_list( STRLIST list )
-{
- if( !list )
- list_all(1);
- else /* List by user id */
- list_one( list, 1 );
-}
-
-void
-print_seckey_info (PKT_secret_key *sk)
-{
- u32 sk_keyid[2];
- size_t n;
- char *p;
-
- keyid_from_sk (sk, sk_keyid);
- tty_printf ("\nsec %4u%c/%08lX %s ",
- nbits_from_sk (sk),
- pubkey_letter (sk->pubkey_algo),
- (ulong)sk_keyid[1], datestr_from_sk (sk));
-
- p = get_user_id (sk_keyid, &n);
- tty_print_utf8_string (p, n);
- xfree (p);
-
- tty_printf ("\n");
-}
-
-/* Print information about the public key. With FP passed as NULL,
- the tty output interface is used, otherwise output is directted to
- the given stream. */
-void
-print_pubkey_info (FILE *fp, PKT_public_key *pk)
-{
- u32 pk_keyid[2];
- size_t n;
- char *p;
-
- keyid_from_pk (pk, pk_keyid);
- if (fp)
- fprintf (fp, "pub %4u%c/%08lX %s ",
- nbits_from_pk (pk),
- pubkey_letter (pk->pubkey_algo),
- (ulong)pk_keyid[1], datestr_from_pk (pk));
- else
- tty_printf ("\npub %4u%c/%08lX %s ",
- nbits_from_pk (pk),
- pubkey_letter (pk->pubkey_algo),
- (ulong)pk_keyid[1], datestr_from_pk (pk));
-
- p = get_user_id (pk_keyid, &n);
- if (fp)
- print_utf8_string2 (fp, p, n, '\n');
- else
- tty_print_utf8_string (p, n);
- xfree (p);
-
- if (fp)
- putc ('\n', fp);
- else
- tty_printf ("\n\n");
-}
-
-/*
- mode=0 for stdout.
- mode=1 for log_info + status messages
- mode=2 for status messages only
-*/
-
-void
-show_policy_url(PKT_signature *sig,int indent,int mode)
-{
- const byte *p;
- size_t len;
- int seq=0,crit;
- FILE *fp=mode?log_get_stream():stdout;
-
- while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,&len,&seq,&crit)))
- {
- if(mode!=2)
- {
- int i;
- char *str;
-
- for(i=0;i<indent;i++)
- putchar(' ');
-
- if(crit)
- str=_("Critical signature policy: ");
- else
- str=_("Signature policy: ");
- if(mode)
- log_info("%s",str);
- else
- printf("%s",str);
- print_utf8_string(fp,p,len);
- fprintf(fp,"\n");
- }
-
- if(mode)
- write_status_buffer ( STATUS_POLICY_URL, p, len, 0 );
- }
-}
-
-
-/*
- mode=0 for stdout.
- mode=1 for log_info + status messages
- mode=2 for status messages only
-*/
-/* TODO: use this */
-void
-show_keyserver_url(PKT_signature *sig,int indent,int mode)
-{
- const byte *p;
- size_t len;
- int seq=0,crit;
- FILE *fp=mode?log_get_stream():stdout;
-
- while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&len,&seq,&crit)))
- {
- if(mode!=2)
- {
- int i;
- char *str;
-
- for(i=0;i<indent;i++)
- putchar(' ');
-
- if(crit)
- str=_("Critical preferred keyserver: ");
- else
- str=_("Preferred keyserver: ");
- if(mode)
- log_info("%s",str);
- else
- printf("%s",str);
- print_utf8_string(fp,p,len);
- fprintf(fp,"\n");
- }
-
- /* TODO: put in a status-fd tag for preferred keyservers */
- }
-}
-
-
-/*
- mode=0 for stdout.
- mode=1 for log_info + status messages
- mode=2 for status messages only
-*/
-
-void
-show_notation(PKT_signature *sig,int indent,int mode)
-{
- const byte *p;
- size_t len;
- int seq=0,crit;
- FILE *fp=mode?log_get_stream():stdout;
-
- /* There may be multiple notations in the same sig. */
-
- while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,&len,&seq,&crit)))
- if(len>=8)
- {
- int n1,n2;
-
- n1=(p[4]<<8)|p[5];
- n2=(p[6]<<8)|p[7];
-
- if(8+n1+n2!=len)
- {
- log_info(_("WARNING: invalid notation data found\n"));
- return;
- }
-
- if(mode!=2)
- {
- int i;
- char *str;
-
- for(i=0;i<indent;i++)
- putchar(' ');
-
- /* This is UTF8 */
- if(crit)
- str=_("Critical signature notation: ");
- else
- str=_("Signature notation: ");
- if(mode)
- log_info("%s",str);
- else
- printf("%s",str);
- print_utf8_string(fp,p+8,n1);
- fprintf(fp,"=");
-
- if(*p&0x80)
- print_utf8_string(fp,p+8+n1,n2);
- else
- fprintf(fp,"[ %s ]",_("not human readable"));
-
- fprintf(fp,"\n");
- }
-
- if(mode)
- {
- write_status_buffer ( STATUS_NOTATION_NAME, p+8 , n1, 0 );
- write_status_buffer ( STATUS_NOTATION_DATA, p+8+n1, n2, 50 );
- }
- }
- else
- log_info(_("WARNING: invalid notation data found\n"));
-}
-
-static void
-print_signature_stats(struct sig_stats *s)
-{
- if( s->inv_sigs == 1 )
- tty_printf(_("1 bad signature\n") );
- else if( s->inv_sigs )
- tty_printf(_("%d bad signatures\n"), s->inv_sigs );
- if( s->no_key == 1 )
- tty_printf(_("1 signature not checked due to a missing key\n") );
- else if( s->no_key )
- tty_printf(_("%d signatures not checked due to missing keys\n"),s->no_key);
- if( s->oth_err == 1 )
- tty_printf(_("1 signature not checked due to an error\n") );
- else if( s->oth_err )
- tty_printf(_("%d signatures not checked due to errors\n"), s->oth_err );
-}
-
-static void
-list_all( int secret )
-{
- KEYDB_HANDLE hd;
- KBNODE keyblock = NULL;
- int rc=0;
- const char *lastresname, *resname;
- struct sig_stats stats;
-
- memset(&stats,0,sizeof(stats));
-
- hd = keydb_new (secret);
- if (!hd)
- rc = GPG_ERR_GENERAL;
- else
- rc = keydb_search_first (hd);
- if( rc ) {
- if( rc != -1 )
- log_error("keydb_search_first failed: %s\n", gpg_strerror (rc) );
- goto leave;
- }
-
- lastresname = NULL;
- do {
- rc = keydb_get_keyblock (hd, &keyblock);
- if (rc) {
- log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
- goto leave;
- }
- if(!opt.with_colons)
- {
- resname = keydb_get_resource_name (hd);
- if (lastresname != resname )
- {
- int i;
-
- printf("%s\n", resname );
- for(i=strlen(resname); i; i-- )
- putchar('-');
- putchar('\n');
- lastresname = resname;
- }
- }
- merge_keys_and_selfsig( keyblock );
- list_keyblock( keyblock, secret, opt.fingerprint,
- opt.check_sigs?&stats:NULL);
- release_kbnode( keyblock );
- keyblock = NULL;
- } while (!(rc = keydb_search_next (hd)));
- if( rc && rc != -1 )
- log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
-
- if(opt.check_sigs && !opt.with_colons)
- print_signature_stats(&stats);
-
- leave:
- release_kbnode (keyblock);
- keydb_release (hd);
-}
-
-
-static void
-list_one( STRLIST names, int secret )
-{
- int rc = 0;
- KBNODE keyblock = NULL;
- GETKEY_CTX ctx;
- const char *resname;
- char *keyring_str = _("Keyring");
- int i;
- struct sig_stats stats;
-
- memset(&stats,0,sizeof(stats));
-
- /* fixme: using the bynames function has the disadvantage that we
- * don't know wether one of the names given was not found. OTOH,
- * this function has the advantage to list the names in the
- * sequence as defined by the keyDB and does not duplicate
- * outputs. A solution could be do test whether all given have
- * been listed (this needs a way to use the keyDB search
- * functions) or to have the search function return indicators for
- * found names. Yet another way is to use the keydb search
- * facilities directly. */
- if( secret ) {
- rc = get_seckey_bynames( &ctx, NULL, names, &keyblock );
- if( rc ) {
- log_error("error reading key: %s\n", gpg_strerror (rc) );
- get_seckey_end( ctx );
- return;
- }
- do {
- if ((opt.list_options&LIST_SHOW_KEYRING) && !opt.with_colons) {
- resname = keydb_get_resource_name (get_ctx_handle(ctx));
- printf("%s: %s\n", keyring_str, resname);
- for(i = strlen(resname) + strlen(keyring_str) + 2; i; i-- )
- putchar('-');
- putchar('\n');
- }
- list_keyblock( keyblock, 1, opt.fingerprint, NULL );
- release_kbnode( keyblock );
- } while( !get_seckey_next( ctx, NULL, &keyblock ) );
- get_seckey_end( ctx );
- }
- else {
- rc = get_pubkey_bynames( &ctx, NULL, names, &keyblock );
- if( rc ) {
- log_error("error reading key: %s\n", gpg_strerror (rc) );
- get_pubkey_end( ctx );
- return;
- }
- do {
- if ((opt.list_options&LIST_SHOW_KEYRING) && !opt.with_colons) {
- resname = keydb_get_resource_name (get_ctx_handle(ctx));
- printf("%s: %s\n", keyring_str, resname);
- for(i = strlen(resname) + strlen(keyring_str) + 2; i; i-- )
- putchar('-');
- putchar('\n');
- }
- list_keyblock( keyblock, 0, opt.fingerprint,
- opt.check_sigs?&stats:NULL );
- release_kbnode( keyblock );
- } while( !get_pubkey_next( ctx, NULL, &keyblock ) );
- get_pubkey_end( ctx );
- }
-
- if(opt.check_sigs && !opt.with_colons)
- print_signature_stats(&stats);
-}
-
-static void
-print_key_data( PKT_public_key *pk, u32 *keyid )
-{
- int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
- int i;
-
- for(i=0; i < n; i++ ) {
- printf("pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) );
- mpi_print(stdout, pk->pkey[i], 1 );
- putchar(':');
- putchar('\n');
- }
-}
-
-static void
-print_capabilities (PKT_public_key *pk, PKT_secret_key *sk, KBNODE keyblock)
-{
- if(pk || (sk && sk->protect.s2k.mode!=1001))
- {
- unsigned int use = pk? pk->pubkey_usage : sk->pubkey_usage;
-
- if ( (use & PUBKEY_USAGE_ENC) )
- putchar ('e');
-
- if ( (use & PUBKEY_USAGE_SIG) )
- {
- putchar ('s');
- if( pk? pk->is_primary : sk->is_primary )
- putchar ('c');
- }
-
- if ( (use & PUBKEY_USAGE_AUTH) )
- putchar ('a');
- }
-
- if ( keyblock ) { /* figure out the usable capabilities */
- KBNODE k;
- int enc=0, sign=0, cert=0, auth=0, disabled=0;
-
- for (k=keyblock; k; k = k->next ) {
- if ( k->pkt->pkttype == PKT_PUBLIC_KEY
- || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- pk = k->pkt->pkt.public_key;
-
- if(pk->is_primary)
- disabled=pk_is_disabled(pk);
-
- if ( pk->is_valid && !pk->is_revoked && !pk->has_expired ) {
- if ( (pk->pubkey_usage & PUBKEY_USAGE_ENC) )
- enc = 1;
- if ( (pk->pubkey_usage & PUBKEY_USAGE_SIG) )
- {
- sign = 1;
- if(pk->is_primary)
- cert = 1;
- }
- if ( (pk->pubkey_usage & PUBKEY_USAGE_AUTH) )
- auth = 1;
- }
- }
- else if ( k->pkt->pkttype == PKT_SECRET_KEY
- || k->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- sk = k->pkt->pkt.secret_key;
- if ( sk->is_valid && !sk->is_revoked && !sk->has_expired
- && sk->protect.s2k.mode!=1001 ) {
- if ( (sk->pubkey_usage & PUBKEY_USAGE_ENC) )
- enc = 1;
- if ( (sk->pubkey_usage & PUBKEY_USAGE_SIG) )
- {
- sign = 1;
- if(sk->is_primary)
- cert = 1;
- }
- if ( (sk->pubkey_usage & PUBKEY_USAGE_AUTH) )
- auth = 1;
- }
- }
- }
- if (enc)
- putchar ('E');
- if (sign)
- putchar ('S');
- if (cert)
- putchar ('C');
- if (auth)
- putchar ('A');
- if (disabled)
- putchar ('D');
- }
-
- putchar(':');
-}
-
-void
-dump_attribs(const PKT_user_id *uid,PKT_public_key *pk,PKT_secret_key *sk)
-{
- int i;
-
- if(!attrib_fp)
- return;
-
- for(i=0;i<uid->numattribs;i++)
- {
- if(is_status_enabled())
- {
- byte array[MAX_FINGERPRINT_LEN], *p;
- char buf[(MAX_FINGERPRINT_LEN*2)+90];
- size_t j,n;
-
- if(pk)
- fingerprint_from_pk( pk, array, &n );
- else if(sk)
- fingerprint_from_sk( sk, array, &n );
- else
- BUG();
-
- p = array;
- for(j=0; j < n ; j++, p++ )
- sprintf(buf+2*j, "%02X", *p );
-
- sprintf(buf+strlen(buf)," %lu %u %u %u %lu %lu %u",
- (ulong)uid->attribs[i].len,uid->attribs[i].type,i+1,
- uid->numattribs,(ulong)uid->created,(ulong)uid->expiredate,
- ((uid->is_primary?0x01:0)|
- (uid->is_revoked?0x02:0)|
- (uid->is_expired?0x04:0)));
- write_status_text(STATUS_ATTRIBUTE,buf);
- }
-
- fwrite(uid->attribs[i].data,uid->attribs[i].len,1,attrib_fp);
- }
-}
-
-static void
-list_keyblock_print ( KBNODE keyblock, int secret, int fpr, void *opaque )
-{
- int rc = 0;
- KBNODE kbctx;
- KBNODE node;
- PKT_public_key *pk;
- PKT_secret_key *sk;
- u32 keyid[2];
- int any=0;
- struct sig_stats *stats=opaque;
- int newformat=((opt.list_options&LIST_SHOW_VALIDITY) && !secret)
- || (opt.list_options&LIST_SHOW_LONG_KEYID);
-
- /* get the keyid from the keyblock */
- node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY );
- if( !node ) {
- log_error("Oops; key lost!\n");
- dump_kbnode( keyblock );
- return;
- }
-
- if( secret )
- {
- pk = NULL;
- sk = node->pkt->pkt.secret_key;
- keyid_from_sk( sk, keyid );
-
- printf("sec%c %4u%c/",(sk->protect.s2k.mode==1001)?'#':' ',
- nbits_from_sk( sk ),pubkey_letter( sk->pubkey_algo ));
-
- if(opt.list_options&LIST_SHOW_LONG_KEYID)
- printf("%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]);
- else
- printf("%08lX",(ulong)keyid[1]);
-
- printf(" %s%s",datestr_from_sk( sk ),newformat?"":" " );
-
- if(newformat && sk->expiredate )
- printf(_(" [expires: %s]"), expirestr_from_sk( sk ) );
- }
- else
- {
- int validity;
- pk = node->pkt->pkt.public_key;
- sk = NULL;
- keyid_from_pk( pk, keyid );
-
- validity=get_validity(pk,NULL);
-
- printf("pub %4u%c/",
- nbits_from_pk(pk),pubkey_letter(pk->pubkey_algo));
-
- if(opt.list_options&LIST_SHOW_LONG_KEYID)
- printf("%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]);
- else
- printf("%08lX",(ulong)keyid[1]);
-
- printf(" %s%s",datestr_from_pk( pk ),newformat?"":" " );
-
- /* We didn't include this before in the key listing, but there
- is room in the new format, so why not? */
- if(newformat && pk->expiredate)
- printf(_(" [expires: %s]"), expirestr_from_pk( pk ) );
-
- if(opt.list_options&LIST_SHOW_VALIDITY)
- printf(" [%s]",trust_value_to_string(validity));
- }
-
- for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
- if( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode ) {
- int indent;
- /* don't list revoked or expired UIDS unless we are in
- * verbose mode and signature listing has not been
- * requested */
- if ( !opt.verbose && !opt.list_sigs &&
- (node->pkt->pkt.user_id->is_revoked ||
- node->pkt->pkt.user_id->is_expired ))
- continue;
-
- if(attrib_fp && node->pkt->pkt.user_id->attrib_data!=NULL)
- dump_attribs(node->pkt->pkt.user_id,pk,sk);
-
- if(!any && newformat)
- printf("\n");
-
- if((opt.list_options&LIST_SHOW_VALIDITY) && pk)
- {
- const char *validity=
- trust_value_to_string(get_validity(pk,node->pkt->pkt.user_id));
-
- /* Includes the 3 spaces for [, ], and " ". */
- indent=((opt.list_options&LIST_SHOW_LONG_KEYID)?23:15)
- -strlen(validity);
-
- if(indent<0)
- indent=0;
-
- printf("uid%*s[%s] ",indent,"",validity);
- }
- else if(newformat)
- printf("uid%*s",26,"");
- else if(any)
- printf("uid%*s",29,"");
-
- if ( node->pkt->pkt.user_id->is_revoked )
- fputs ("[revoked] ", stdout);
- if ( node->pkt->pkt.user_id->is_expired )
- fputs ("[expired] ", stdout);
-
- print_utf8_string( stdout, node->pkt->pkt.user_id->name,
- node->pkt->pkt.user_id->len );
- putchar('\n');
- if( !any ) {
- if( fpr )
- print_fingerprint( pk, sk, 0 );
- print_card_serialno (sk);
- if( opt.with_key_data )
- print_key_data( pk, keyid );
- any = 1;
- }
-
- if((opt.list_options&LIST_SHOW_PHOTOS)
- && node->pkt->pkt.user_id->attribs!=NULL)
- show_photos(node->pkt->pkt.user_id->attribs,
- node->pkt->pkt.user_id->numattribs,pk,sk);
- }
- else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- u32 keyid2[2];
- PKT_public_key *pk2 = node->pkt->pkt.public_key;
-
- if( !any ) {
- putchar('\n');
- if( fpr )
- print_fingerprint( pk, sk, 0 ); /* of the main key */
- any = 1;
- }
-
- keyid_from_pk( pk2, keyid2 );
- printf("sub %4u%c/",
- nbits_from_pk( pk2 ),pubkey_letter( pk2->pubkey_algo ));
- if(opt.list_options&LIST_SHOW_LONG_KEYID)
- printf("%08lX%08lX",(ulong)keyid2[0],(ulong)keyid2[1]);
- else
- printf("%08lX",(ulong)keyid2[1]);
- printf(" %s",datestr_from_pk(pk2));
- if( pk2->expiredate )
- printf(_(" [expires: %s]"), expirestr_from_pk( pk2 ) );
- putchar('\n');
- if( fpr > 1 )
- print_fingerprint( pk2, NULL, 0 );
- if( opt.with_key_data )
- print_key_data( pk2, keyid2 );
- }
- else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- u32 keyid2[2];
- PKT_secret_key *sk2 = node->pkt->pkt.secret_key;
-
- if( !any ) {
- putchar('\n');
- if( fpr )
- print_fingerprint( pk, sk, 0 ); /* of the main key */
- print_card_serialno (sk);
- any = 1;
- }
-
- keyid_from_sk( sk2, keyid2 );
- printf("ssb %4u%c/",
- nbits_from_sk( sk2 ),pubkey_letter( sk2->pubkey_algo ));
- if(opt.list_options&LIST_SHOW_LONG_KEYID)
- printf("%08lX%08lX",(ulong)keyid2[0],(ulong)keyid2[1]);
- else
- printf("%08lX",(ulong)keyid2[1]);
- printf(" %s",datestr_from_sk( sk2 ) );
- if( sk2->expiredate )
- printf(_(" [expires: %s]"), expirestr_from_sk( sk2 ) );
- putchar('\n');
- if( fpr > 1 )
- {
- print_fingerprint( NULL, sk2, 0 );
- print_card_serialno (sk);
- }
- }
- else if( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) {
- PKT_signature *sig = node->pkt->pkt.signature;
- int sigrc;
- char *sigstr;
-
- if( stats ) {
- /*fflush(stdout);*/
- rc = check_key_signature( keyblock, node, NULL );
- switch( gpg_err_code (rc) ) {
- case 0: sigrc = '!'; break;
- case GPG_ERR_BAD_SIGNATURE: stats->inv_sigs++; sigrc = '-'; break;
- case GPG_ERR_NO_PUBKEY:
- case GPG_ERR_UNUSABLE_PUBKEY: stats->no_key++; continue;
- default: stats->oth_err++; sigrc = '%'; break;
- }
-
- /* TODO: Make sure a cached sig record here still has
- the pk that issued it. See also
- keyedit.c:print_and_check_one_sig */
-
- }
- else {
- rc = 0;
- sigrc = ' ';
- }
-
- if( !any ) { /* no user id, (maybe a revocation follows)*/
- /* Check if the pk is really revoked - there could be a
- 0x20 sig packet there even if we are not revoked
- (say, if a revocation key issued the packet, but the
- revocation key isn't present to verify it.) */
- if( sig->sig_class == 0x20 && pk->is_revoked )
- puts("[revoked]");
- else if( sig->sig_class == 0x18 )
- puts("[key binding]");
- else if( sig->sig_class == 0x28 )
- puts("[subkey revoked]");
- else
- putchar('\n');
- if( fpr )
- print_fingerprint( pk, sk, 0 );
- print_card_serialno (sk);
- any=1;
- }
-
- if( sig->sig_class == 0x20 || sig->sig_class == 0x28
- || sig->sig_class == 0x30 )
- sigstr = "rev";
- else if( (sig->sig_class&~3) == 0x10 )
- sigstr = "sig";
- else if( sig->sig_class == 0x18 )
- sigstr = "sig";
- else if( sig->sig_class == 0x1F )
- sigstr = "sig";
- else {
- printf("sig "
- "[unexpected signature class 0x%02x]\n",sig->sig_class );
- continue;
- }
-
- fputs( sigstr, stdout );
- printf("%c%c %c%c%c%c%c%c ",
- sigrc,(sig->sig_class-0x10>0 &&
- sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ',
- sig->flags.exportable?' ':'L',
- sig->flags.revocable?' ':'R',
- sig->flags.policy_url?'P':' ',
- sig->flags.notation?'N':' ',
- sig->flags.expired?'X':' ',
- (sig->trust_depth>9)?'T':
- (sig->trust_depth>0)?'0'+sig->trust_depth:' ');
- if(opt.list_options&LIST_SHOW_LONG_KEYID)
- printf("%08lX%08lX",(ulong)sig->keyid[0],(ulong)sig->keyid[1]);
- else
- printf("%08lX",(ulong)sig->keyid[1]);
- printf(" %s ", datestr_from_sig(sig));
- if( sigrc == '%' )
- printf("[%s] ", gpg_strerror (rc) );
- else if( sigrc == '?' )
- ;
- else if ( !opt.fast_list_mode ) {
- size_t n;
- char *p = get_user_id( sig->keyid, &n );
- print_utf8_string( stdout, p, n );
- xfree (p);
- }
- putchar('\n');
-
- if(sig->flags.policy_url && (opt.list_options&LIST_SHOW_POLICY))
- show_policy_url(sig,3,0);
-
- if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATION))
- show_notation(sig,3,0);
-
- if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER))
- show_keyserver_url(sig,3,0);
-
- /* fixme: check or list other sigs here */
- }
- }
- putchar('\n');
-}
-
-
-static void
-list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
-{
- int rc = 0;
- KBNODE kbctx;
- KBNODE node;
- PKT_public_key *pk;
- PKT_secret_key *sk;
- u32 keyid[2];
- int any=0;
- int trustletter = 0;
- int ulti_hack = 0;
-
- /* get the keyid from the keyblock */
- node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY );
- if( !node ) {
- log_error("Oops; key lost!\n");
- dump_kbnode( keyblock );
- return;
- }
-
- if( secret ) {
- pk = NULL;
- sk = node->pkt->pkt.secret_key;
- keyid_from_sk( sk, keyid );
- printf("sec::%u:%d:%08lX%08lX:%s:%s:::",
- nbits_from_sk( sk ),
- sk->pubkey_algo,
- (ulong)keyid[0],(ulong)keyid[1],
- colon_datestr_from_sk( sk ),
- colon_strtime (sk->expiredate)
- /* fixme: add LID here */ );
- }
- else {
- pk = node->pkt->pkt.public_key;
- sk = NULL;
- keyid_from_pk( pk, keyid );
- fputs( "pub:", stdout );
- if ( !pk->is_valid )
- putchar ('i');
- else if ( pk->is_revoked )
- putchar ('r');
- else if ( pk->has_expired )
- putchar ('e');
- else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
- ;
- else {
- trustletter = get_validity_info ( pk, NULL );
- if( trustletter == 'u' )
- ulti_hack = 1;
- putchar(trustletter);
- }
- printf(":%u:%d:%08lX%08lX:%s:%s:",
- nbits_from_pk( pk ),
- pk->pubkey_algo,
- (ulong)keyid[0],(ulong)keyid[1],
- colon_datestr_from_pk( pk ),
- colon_strtime (pk->expiredate) );
- if( pk->local_id )
- printf("%lu", pk->local_id );
- putchar(':');
- if( !opt.fast_list_mode && !opt.no_expensive_trust_checks )
- putchar( get_ownertrust_info(pk) );
- putchar(':');
- }
-
- if (opt.fixed_list_mode) {
- /* do not merge the first uid with the primary key */
- putchar(':');
- putchar(':');
- print_capabilities (pk, sk, keyblock);
- putchar('\n');
- if( fpr )
- print_fingerprint( pk, sk, 0 );
- if( opt.with_key_data )
- print_key_data( pk, keyid );
- any = 1;
- }
-
-
- for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
- if( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode ) {
- PKT_user_id *uid=node->pkt->pkt.user_id;
- if(attrib_fp && node->pkt->pkt.user_id->attrib_data!=NULL)
- dump_attribs(node->pkt->pkt.user_id,pk,sk);
- /*
- * Fixme: We need a is_valid flag here too
- */
- if( any ) {
- int i;
- char *str=uid->attrib_data?"uat":"uid";
- /* If we're listing a secret key, leave out the
- validity values for now. FIXME: This should be
- handled better in 1.9. */
- if ( sk )
- printf("%s:::::",str);
- else if ( uid->is_revoked )
- printf("%s:r::::",str);
- else if ( uid->is_expired )
- printf("%s:e::::",str);
- else if ( opt.no_expensive_trust_checks )
- printf("%s:::::",str);
- else {
- int uid_validity;
-
- if( pk && !ulti_hack )
- uid_validity=get_validity_info (pk, uid);
- else
- uid_validity = 'u';
- printf("%s:%c::::",str,uid_validity);
- }
-
- printf("%s:",colon_strtime(uid->created));
- printf("%s:",colon_strtime(uid->expiredate));
-
- namehash_from_uid(uid);
-
- for(i=0; i < 20; i++ )
- printf("%02X",uid->namehash[i]);
-
- printf("::");
- }
- if(uid->attrib_data)
- printf("%u %lu",uid->numattribs,uid->attrib_len);
- else
- print_string(stdout,uid->name,uid->len, ':' );
- putchar(':');
- if (any)
- putchar('\n');
- else {
- putchar(':');
- print_capabilities (pk, sk, keyblock);
- putchar('\n');
- if( fpr )
- print_fingerprint( pk, sk, 0 );
- if( opt.with_key_data )
- print_key_data( pk, keyid );
- any = 1;
- }
- }
- else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- u32 keyid2[2];
- PKT_public_key *pk2 = node->pkt->pkt.public_key;
-
- if( !any ) {
- putchar(':');
- putchar(':');
- print_capabilities (pk, sk, keyblock);
- putchar('\n');
- if( fpr )
- print_fingerprint( pk, sk, 0 ); /* of the main key */
- any = 1;
- }
-
- keyid_from_pk( pk2, keyid2 );
- fputs ("sub:", stdout );
- if ( !pk2->is_valid )
- putchar ('i');
- else if ( pk2->is_revoked )
- putchar ('r');
- else if ( pk2->has_expired )
- putchar ('e');
- else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
- ;
- else {
- /* trustletter should always be defined here */
- if(trustletter)
- printf("%c", trustletter );
- }
- printf(":%u:%d:%08lX%08lX:%s:%s:",
- nbits_from_pk( pk2 ),
- pk2->pubkey_algo,
- (ulong)keyid2[0],(ulong)keyid2[1],
- colon_datestr_from_pk( pk2 ),
- colon_strtime (pk2->expiredate)
- /* fixme: add LID and ownertrust here */
- );
- if( pk->local_id ) /* use the local_id of the main key??? */
- printf("%lu", pk->local_id );
- putchar(':');
- putchar(':');
- putchar(':');
- putchar(':');
- print_capabilities (pk2, NULL, NULL);
- putchar('\n');
- if( fpr > 1 )
- print_fingerprint( pk2, NULL, 0 );
- if( opt.with_key_data )
- print_key_data( pk2, keyid2 );
- }
- else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- u32 keyid2[2];
- PKT_secret_key *sk2 = node->pkt->pkt.secret_key;
-
- if( !any ) {
- putchar(':');
- putchar(':');
- print_capabilities (pk, sk, keyblock);
- putchar('\n');
- if( fpr )
- print_fingerprint( pk, sk, 0 ); /* of the main key */
- any = 1;
- }
-
- keyid_from_sk( sk2, keyid2 );
- printf("ssb::%u:%d:%08lX%08lX:%s:%s:::::",
- nbits_from_sk( sk2 ),
- sk2->pubkey_algo,
- (ulong)keyid2[0],(ulong)keyid2[1],
- colon_datestr_from_sk( sk2 ),
- colon_strtime (sk2->expiredate)
- /* fixme: add LID */ );
- print_capabilities (NULL, sk2, NULL);
- putchar ('\n');
- if( fpr > 1 )
- print_fingerprint( NULL, sk2, 0 );
- }
- else if( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) {
- PKT_signature *sig = node->pkt->pkt.signature;
- int sigrc, fprokay=0;
- char *sigstr;
- size_t fplen;
- byte fparray[MAX_FINGERPRINT_LEN];
-
- if( !any ) { /* no user id, (maybe a revocation follows)*/
- if( sig->sig_class == 0x20 )
- fputs("[revoked]:", stdout);
- else if( sig->sig_class == 0x18 )
- fputs("[key binding]:", stdout);
- else if( sig->sig_class == 0x28 )
- fputs("[subkey revoked]:", stdout);
- else
- putchar (':');
- putchar(':');
- print_capabilities (pk, sk, keyblock);
- putchar('\n');
- if( fpr )
- print_fingerprint( pk, sk, 0 );
- any=1;
- }
-
- if( sig->sig_class == 0x20 || sig->sig_class == 0x28
- || sig->sig_class == 0x30 )
- sigstr = "rev";
- else if( (sig->sig_class&~3) == 0x10 )
- sigstr = "sig";
- else if( sig->sig_class == 0x18 )
- sigstr = "sig";
- else if( sig->sig_class == 0x1F )
- sigstr = "sig";
- else {
- printf ("sig::::::::::%02x%c:\n",
- sig->sig_class, sig->flags.exportable?'x':'l');
- continue;
- }
- if( opt.check_sigs ) {
- PKT_public_key *signer_pk=NULL;
-
- fflush(stdout);
- if(opt.no_sig_cache)
- signer_pk = xcalloc (1, sizeof(PKT_public_key));
-
- rc = check_key_signature2( keyblock, node, NULL, signer_pk,
- NULL, NULL, NULL );
- switch( gpg_err_code (rc) ) {
- case 0: sigrc = '!'; break;
- case GPG_ERR_BAD_SIGNATURE: sigrc = '-'; break;
- case GPG_ERR_NO_PUBKEY:
- case GPG_ERR_UNUSABLE_PUBKEY: sigrc = '?'; break;
- default: sigrc = '%'; break;
- }
-
- if(opt.no_sig_cache)
- {
- if(!rc)
- {
- fingerprint_from_pk (signer_pk, fparray, &fplen);
- fprokay=1;
- }
- free_public_key(signer_pk);
- }
- }
- else {
- rc = 0;
- sigrc = ' ';
- }
- fputs( sigstr, stdout );
- putchar(':');
- if( sigrc != ' ' )
- putchar(sigrc);
- printf("::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
- (ulong)sig->keyid[0], (ulong)sig->keyid[1],
- colon_datestr_from_sig(sig),
- colon_expirestr_from_sig(sig));
-
- if(sig->trust_depth || sig->trust_value)
- printf("%d %d",sig->trust_depth,sig->trust_value);
- printf(":");
-
- if(sig->trust_regexp)
- print_string(stdout,sig->trust_regexp,
- strlen(sig->trust_regexp),':');
- printf(":");
-
- if( sigrc == '%' )
- printf("[%s] ", gpg_strerror (rc) );
- else if( sigrc == '?' )
- ;
- else if ( !opt.fast_list_mode ) {
- size_t n;
- char *p = get_user_id( sig->keyid, &n );
- print_string( stdout, p, n, ':' );
- xfree (p);
- }
- printf(":%02x%c:", sig->sig_class,sig->flags.exportable?'x':'l');
- if(opt.no_sig_cache && opt.check_sigs && fprokay)
- {
- size_t i;
-
- printf(":");
-
- for (i=0; i < fplen ; i++ )
- printf ("%02X", fparray[i] );
-
- printf(":");
- }
-
- printf("\n");
- /* fixme: check or list other sigs here */
- }
- }
- if( !any ) {/* oops, no user id */
- putchar(':');
- putchar(':');
- print_capabilities (pk, sk, keyblock);
- putchar('\n');
- }
-}
-
-/*
- * Reorder the keyblock so that the primary user ID (and not attribute
- * packet) comes first. Fixme: Replace this by a generic sort
- * function. */
-void
-reorder_keyblock (KBNODE keyblock)
-{
- KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
- KBNODE last, node;
-
- for (node=keyblock; node; primary0=node, node = node->next) {
- if( node->pkt->pkttype == PKT_USER_ID &&
- !node->pkt->pkt.user_id->attrib_data &&
- node->pkt->pkt.user_id->is_primary ) {
- primary = primary2 = node;
- for (node=node->next; node; primary2=node, node = node->next ) {
- if( node->pkt->pkttype == PKT_USER_ID
- || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
- || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- break;
- }
- }
- break;
- }
- }
- if ( !primary )
- return; /* no primary key flag found (should not happen) */
-
- for (last=NULL, node=keyblock; node; last = node, node = node->next) {
- if( node->pkt->pkttype == PKT_USER_ID )
- break;
- }
- assert (node);
- assert (last); /* the user ID is never the first packet */
- assert (primary0); /* ditto (this is the node before primary) */
- if ( node == primary )
- return; /* already the first one */
-
- last->next = primary;
- primary0->next = primary2->next;
- primary2->next = node;
-}
-
-void
-list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque )
-{
- reorder_keyblock (keyblock);
- if (opt.with_colons)
- list_keyblock_colon (keyblock, secret, fpr );
- else
- list_keyblock_print (keyblock, secret, fpr, opaque );
-}
-
-/*
- * standard function to print the finperprint.
- * mode 0: as used in key listings, opt.with_colons is honored
- * 1: print using log_info ()
- * 2: direct use of tty
- * 3: direct use of tty but only primary key.
- * modes 1 and 2 will try and print both subkey and primary key fingerprints
- */
-void
-print_fingerprint (PKT_public_key *pk, PKT_secret_key *sk, int mode )
-{
- byte array[MAX_FINGERPRINT_LEN], *p;
- size_t i, n;
- FILE *fp;
- const char *text;
- int primary=0;
-
- if(sk)
- {
- if(sk->main_keyid[0]==sk->keyid[0] && sk->main_keyid[1]==sk->keyid[1])
- primary=1;
- }
- else
- {
- if(pk->main_keyid[0]==pk->keyid[0] && pk->main_keyid[1]==pk->keyid[1])
- primary=1;
- }
-
- /* Just to be safe */
- if(mode&0x80 && !primary)
- {
- log_error("primary key is not really primary!\n");
- return;
- }
-
- mode&=~0x80;
-
- if(!primary && (mode==1 || mode==2))
- {
- if(sk)
- {
- PKT_secret_key *primary_sk=xcalloc (1,sizeof(*primary_sk));
- get_seckey(primary_sk,sk->main_keyid);
- print_fingerprint(NULL,primary_sk,mode|0x80);
- free_secret_key(primary_sk);
- }
- else
- {
- PKT_public_key *primary_pk=xcalloc (1,sizeof(*primary_pk));
- get_pubkey(primary_pk,pk->main_keyid);
- print_fingerprint(primary_pk,NULL,mode|0x80);
- free_public_key(primary_pk);
- }
- }
-
- if (mode == 1) {
- fp = log_get_stream ();
- if(primary)
- text = _("Primary key fingerprint:");
- else
- text = _(" Subkey fingerprint:");
- }
- else if (mode == 2) {
- fp = NULL; /* use tty */
- /* Translators: this should fit into 24 bytes to that the fingerprint
- * data is properly aligned with the user ID */
- if(primary)
- text = _(" Primary key fingerprint:");
- else
- text = _(" Subkey fingerprint:");
- }
- else if (mode == 3) {
- fp = NULL; /* use tty */
- text = _(" Key fingerprint =");
- }
- else {
- fp = stdout;
- text = _(" Key fingerprint =");
- }
-
- if (sk)
- fingerprint_from_sk (sk, array, &n);
- else
- fingerprint_from_pk (pk, array, &n);
- p = array;
- if (opt.with_colons && !mode) {
- fprintf (fp, "fpr:::::::::");
- for (i=0; i < n ; i++, p++ )
- fprintf (fp, "%02X", *p );
- putc(':', fp);
- }
- else {
- if (fp)
- fputs (text, fp);
- else
- tty_printf ("%s", text);
- if (n == 20) {
- for (i=0; i < n ; i++, i++, p += 2 ) {
- if (fp) {
- if (i == 10 )
- putc(' ', fp);
- fprintf (fp, " %02X%02X", *p, p[1] );
- }
- else {
- if (i == 10 )
- tty_printf (" ");
- tty_printf (" %02X%02X", *p, p[1]);
- }
- }
- }
- else {
- for (i=0; i < n ; i++, p++ ) {
- if (fp) {
- if (i && !(i%8) )
- putc (' ', fp);
- fprintf (fp, " %02X", *p );
- }
- else {
- if (i && !(i%8) )
- tty_printf (" ");
- tty_printf (" %02X", *p );
- }
- }
- }
- }
- if (fp)
- putc ('\n', fp);
- else
- tty_printf ("\n");
-}
-
-
-/* Print the serial number of an OpenPGP card if available. */
-static void
-print_card_serialno (PKT_secret_key *sk)
-{
- int i;
-
- if (!sk)
- return;
- if (!sk->is_protected || sk->protect.s2k.mode != 1002)
- return; /* Not a card. */
- if (opt.with_colons)
- return; /* Format not yet defined. */
-
- fputs (_(" Card serial no. ="), stdout);
- putchar (' ');
- if (sk->protect.ivlen == 16
- && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6) )
- { /* This is an OpenPGP card. Just print the relevant part. */
- for (i=8; i < 14; i++)
- {
- if (i == 10)
- putchar (' ');
- printf ("%02X", sk->protect.iv[i]);
- }
- }
- else
- { /* Something is wrong: Print all. */
- for (i=0; i < sk->protect.ivlen; i++)
- printf ("%02X", sk->protect.iv[i]);
- }
- putchar ('\n');
-}
-
-void set_attrib_fd(int fd)
-{
- static int last_fd=-1;
-
- if ( fd != -1 && last_fd == fd )
- return;
-
- if ( attrib_fp && attrib_fp != stdout && attrib_fp != stderr )
- fclose (attrib_fp);
- attrib_fp = NULL;
- if ( fd == -1 )
- return;
-
- if( fd == 1 )
- attrib_fp = stdout;
- else if( fd == 2 )
- attrib_fp = stderr;
- else
- attrib_fp = fdopen( fd, "w" );
- if( !attrib_fp ) {
- log_fatal("can't open fd %d for attribute output: %s\n",
- fd, strerror(errno));
- }
- last_fd = fd;
-}
diff --git a/g10/keyring.c b/g10/keyring.c
deleted file mode 100644
index 03a22667c..000000000
--- a/g10/keyring.c
+++ /dev/null
@@ -1,1588 +0,0 @@
-/* keyring.c - keyring file handling
- * Copyright (C) 2001, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "keyring.h"
-#include "packet.h"
-#include "keydb.h"
-#include "options.h"
-#include "main.h" /*for check_key_signature()*/
-#include "i18n.h"
-
-/* off_item is a funny named for an object used to keep track of known
- * keys. The idea was to use the offset to seek to the known keyblock, but
- * this is not possible if more than one process is using the keyring.
- */
-struct off_item {
- struct off_item *next;
- u32 kid[2];
- /*off_t off;*/
-};
-
-typedef struct off_item **OffsetHashTable;
-
-
-typedef struct keyring_name *KR_NAME;
-struct keyring_name {
- struct keyring_name *next;
- int secret;
- DOTLOCK lockhd;
- int is_locked;
- int did_full_scan;
- char fname[1];
-};
-typedef struct keyring_name const * CONST_KR_NAME;
-
-static KR_NAME kr_names;
-static int active_handles;
-
-static OffsetHashTable kr_offtbl;
-static int kr_offtbl_ready;
-
-
-struct keyring_handle {
- CONST_KR_NAME resource;
- int secret; /* this is for a secret keyring */
- struct {
- CONST_KR_NAME kr;
- iobuf_t iobuf;
- int eof;
- int error;
- } current;
- struct {
- CONST_KR_NAME kr;
- off_t offset;
- size_t pk_no;
- size_t uid_no;
- unsigned int n_packets; /*used for delete and update*/
- } found;
- struct {
- char *name;
- char *pattern;
- } word_match;
-};
-
-
-
-static int do_copy (int mode, const char *fname, KBNODE root, int secret,
- off_t start_offset, unsigned int n_packets );
-
-
-
-static struct off_item *
-new_offset_item (void)
-{
- struct off_item *k;
-
- k = xcalloc (1,sizeof *k);
- return k;
-}
-
-#if 0
-static void
-release_offset_items (struct off_item *k)
-{
- struct off_item *k2;
-
- for (; k; k = k2)
- {
- k2 = k->next;
- xfree (k);
- }
-}
-#endif
-
-static OffsetHashTable
-new_offset_hash_table (void)
-{
- struct off_item **tbl;
-
- tbl = xcalloc (2048, sizeof *tbl);
- return tbl;
-}
-
-#if 0
-static void
-release_offset_hash_table (OffsetHashTable tbl)
-{
- int i;
-
- if (!tbl)
- return;
- for (i=0; i < 2048; i++)
- release_offset_items (tbl[i]);
- xfree (tbl);
-}
-#endif
-
-static struct off_item *
-lookup_offset_hash_table (OffsetHashTable tbl, u32 *kid)
-{
- struct off_item *k;
-
- for (k = tbl[(kid[1] & 0x07ff)]; k; k = k->next)
- if (k->kid[0] == kid[0] && k->kid[1] == kid[1])
- return k;
- return NULL;
-}
-
-static void
-update_offset_hash_table (OffsetHashTable tbl, u32 *kid, off_t off)
-{
- struct off_item *k;
-
- for (k = tbl[(kid[1] & 0x07ff)]; k; k = k->next)
- {
- if (k->kid[0] == kid[0] && k->kid[1] == kid[1])
- {
- /*k->off = off;*/
- return;
- }
- }
-
- k = new_offset_item ();
- k->kid[0] = kid[0];
- k->kid[1] = kid[1];
- /*k->off = off;*/
- k->next = tbl[(kid[1] & 0x07ff)];
- tbl[(kid[1] & 0x07ff)] = k;
-}
-
-static void
-update_offset_hash_table_from_kb (OffsetHashTable tbl, KBNODE node, off_t off)
-{
- for (; node; node = node->next)
- {
- if (node->pkt->pkttype == PKT_PUBLIC_KEY
- || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
- {
- u32 aki[2];
- keyid_from_pk (node->pkt->pkt.public_key, aki);
- update_offset_hash_table (tbl, aki, off);
- }
- }
-}
-
-/*
- * Register a filename for plain keyring files. ptr is set to a
- * pointer to be used to create a handles etc, or the already-issued
- * pointer if it has already been registered. The function returns 1
- * if a new keyring was registered.
-*/
-int
-keyring_register_filename (const char *fname, int secret, void **ptr)
-{
- KR_NAME kr;
-
- if (active_handles)
- BUG (); /* We don't allow that */
-
- for (kr=kr_names; kr; kr = kr->next)
- {
- if ( !compare_filenames (kr->fname, fname) )
- {
- *ptr=kr;
- return 0; /* already registered */
- }
- }
-
- kr = xmalloc (sizeof *kr + strlen (fname));
- strcpy (kr->fname, fname);
- kr->secret = !!secret;
- kr->lockhd = NULL;
- kr->is_locked = 0;
- kr->did_full_scan = 0;
- /* keep a list of all issued pointers */
- kr->next = kr_names;
- kr_names = kr;
-
- /* create the offset table the first time a function here is used */
- if (!kr_offtbl)
- kr_offtbl = new_offset_hash_table ();
-
- *ptr=kr;
-
- return 1;
-}
-
-int
-keyring_is_writable (void *token)
-{
- KR_NAME r = token;
-
- return r? !access (r->fname, W_OK) : 0;
-}
-
-
-
-/* Create a new handle for the resource associated with TOKEN. SECRET
- is just just as a cross-check.
-
- The returned handle must be released using keyring_release (). */
-KEYRING_HANDLE
-keyring_new (void *token, int secret)
-{
- KEYRING_HANDLE hd;
- KR_NAME resource = token;
-
- assert (resource && !resource->secret == !secret);
-
- hd = xcalloc (1,sizeof *hd);
- hd->resource = resource;
- hd->secret = !!secret;
- active_handles++;
- return hd;
-}
-
-void
-keyring_release (KEYRING_HANDLE hd)
-{
- if (!hd)
- return;
- assert (active_handles > 0);
- active_handles--;
- xfree (hd->word_match.name);
- xfree (hd->word_match.pattern);
- iobuf_close (hd->current.iobuf);
- xfree (hd);
-}
-
-
-const char *
-keyring_get_resource_name (KEYRING_HANDLE hd)
-{
- if (!hd || !hd->resource)
- return NULL;
- return hd->resource->fname;
-}
-
-
-/*
- * Lock the keyring with the given handle, or unlok if yes is false.
- * We ignore the handle and lock all registered files.
- */
-int
-keyring_lock (KEYRING_HANDLE hd, int yes)
-{
- KR_NAME kr;
- int rc = 0;
-
- if (yes) {
- /* first make sure the lock handles are created */
- for (kr=kr_names; kr; kr = kr->next) {
- if (!keyring_is_writable(kr))
- continue;
- if (!kr->lockhd) {
- kr->lockhd = create_dotlock( kr->fname );
- if (!kr->lockhd) {
- log_info ("can't allocate lock for `%s'\n", kr->fname );
- rc = GPG_ERR_GENERAL;
- }
- }
- }
- if (rc)
- return rc;
-
- /* and now set the locks */
- for (kr=kr_names; kr; kr = kr->next) {
- if (!keyring_is_writable(kr))
- continue;
- if (kr->is_locked)
- ;
- else if (make_dotlock (kr->lockhd, -1) ) {
- log_info ("can't lock `%s'\n", kr->fname );
- rc = GPG_ERR_GENERAL;
- }
- else
- kr->is_locked = 1;
- }
- }
-
- if (rc || !yes) {
- for (kr=kr_names; kr; kr = kr->next) {
- if (!keyring_is_writable(kr))
- continue;
- if (!kr->is_locked)
- ;
- else if (release_dotlock (kr->lockhd))
- log_info ("can't unlock `%s'\n", kr->fname );
- else
- kr->is_locked = 0;
- }
- }
-
- return rc;
-}
-
-
-
-/*
- * Return the last found keyring. Caller must free it.
- * The returned keyblock has the kbode flag bit 0 set for the node with
- * the public key used to locate the keyblock or flag bit 1 set for
- * the user ID node.
- */
-int
-keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
-{
- PACKET *pkt;
- int rc;
- KBNODE keyblock = NULL, node, lastnode;
- iobuf_t a;
- int in_cert = 0;
- int pk_no = 0;
- int uid_no = 0;
- int save_mode;
-
- if (ret_kb)
- *ret_kb = NULL;
-
- if (!hd->found.kr)
- return -1; /* no successful search */
-
- a = iobuf_open (hd->found.kr->fname);
- if (!a) {
- log_error ("can't open `%s'\n", hd->found.kr->fname);
- return GPG_ERR_KEYRING_OPEN;
- }
-
- if (iobuf_seek (a, hd->found.offset) ) {
- log_error ("can't seek `%s'\n", hd->found.kr->fname);
- iobuf_close(a);
- return GPG_ERR_KEYRING_OPEN;
- }
-
- pkt = xmalloc (sizeof *pkt);
- init_packet (pkt);
- hd->found.n_packets = 0;;
- lastnode = NULL;
- save_mode = set_packet_list_mode(0);
- while ((rc=parse_packet (a, pkt)) != -1) {
- hd->found.n_packets++;
- if (gpg_err_code (rc) == GPG_ERR_UNKNOWN_PACKET) {
- free_packet (pkt);
- init_packet (pkt);
- continue;
- }
- if (rc) {
- log_error ("keyring_get_keyblock: read error: %s\n",
- gpg_strerror (rc) );
- rc = GPG_ERR_INV_KEYRING;
- break;
- }
- if (pkt->pkttype == PKT_COMPRESSED) {
- log_error ("skipped compressed packet in keyring\n");
- free_packet(pkt);
- init_packet(pkt);
- continue;
- }
-
- if (in_cert && (pkt->pkttype == PKT_PUBLIC_KEY
- || pkt->pkttype == PKT_SECRET_KEY)) {
- hd->found.n_packets--; /* fix counter */
- break; /* ready */
- }
-
- in_cert = 1;
- if (pkt->pkttype == PKT_RING_TRUST) {
- /*(this code is duplicated after the loop)*/
- if ( lastnode
- && lastnode->pkt->pkttype == PKT_SIGNATURE
- && (pkt->pkt.ring_trust->sigcache & 1) ) {
- /* this is a ring trust packet with a checked signature
- * status cache following directly a signature paket.
- * Set the cache status into that signature packet */
- PKT_signature *sig = lastnode->pkt->pkt.signature;
-
- sig->flags.checked = 1;
- sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2);
- }
- /* reset lastnode, so that we set the cache status only from
- * the ring trust packet immediately folling a signature */
- lastnode = NULL;
- }
- else {
- node = lastnode = new_kbnode (pkt);
- if (!keyblock)
- keyblock = node;
- else
- add_kbnode (keyblock, node);
-
- if ( pkt->pkttype == PKT_PUBLIC_KEY
- || pkt->pkttype == PKT_PUBLIC_SUBKEY
- || pkt->pkttype == PKT_SECRET_KEY
- || pkt->pkttype == PKT_SECRET_SUBKEY) {
- if (++pk_no == hd->found.pk_no)
- node->flag |= 1;
- }
- else if ( pkt->pkttype == PKT_USER_ID) {
- if (++uid_no == hd->found.uid_no)
- node->flag |= 2;
- }
- }
-
- pkt = xmalloc (sizeof *pkt);
- init_packet(pkt);
- }
- set_packet_list_mode(save_mode);
-
- if (rc == -1 && keyblock)
- rc = 0; /* got the entire keyblock */
-
- if (rc || !ret_kb)
- release_kbnode (keyblock);
- else {
- /*(duplicated form the loop body)*/
- if ( pkt && pkt->pkttype == PKT_RING_TRUST
- && lastnode
- && lastnode->pkt->pkttype == PKT_SIGNATURE
- && (pkt->pkt.ring_trust->sigcache & 1) ) {
- PKT_signature *sig = lastnode->pkt->pkt.signature;
- sig->flags.checked = 1;
- sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2);
- }
- *ret_kb = keyblock;
- }
- free_packet (pkt);
- xfree (pkt);
- iobuf_close(a);
-
- /* Make sure that future search operations fail immediately when
- * we know that we are working on a invalid keyring
- */
- if (gpg_err_code (rc) == GPG_ERR_INV_KEYRING)
- hd->current.error = rc;
-
- return rc;
-}
-
-int
-keyring_update_keyblock (KEYRING_HANDLE hd, KBNODE kb)
-{
- int rc;
-
- if (!hd->found.kr)
- return -1; /* no successful prior search */
-
- if (!hd->found.n_packets) {
- /* need to know the number of packets - do a dummy get_keyblock*/
- rc = keyring_get_keyblock (hd, NULL);
- if (rc) {
- log_error ("re-reading keyblock failed: %s\n", gpg_strerror (rc));
- return rc;
- }
- if (!hd->found.n_packets)
- BUG ();
- }
-
- /* The open iobuf isn't needed anymore and in fact is a problem when
- it comes to renaming the keyring files on some operating systems,
- so close it here */
- iobuf_close(hd->current.iobuf);
- hd->current.iobuf = NULL;
-
- /* do the update */
- rc = do_copy (3, hd->found.kr->fname, kb, hd->secret,
- hd->found.offset, hd->found.n_packets );
- if (!rc) {
- if (!hd->secret && kr_offtbl)
- {
- update_offset_hash_table_from_kb (kr_offtbl, kb, 0);
- }
- /* better reset the found info */
- hd->found.kr = NULL;
- hd->found.offset = 0;
- }
- return rc;
-}
-
-int
-keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb)
-{
- int rc;
- const char *fname;
-
- if (!hd)
- fname = NULL;
- else if (hd->found.kr)
- fname = hd->found.kr->fname;
- else if (hd->current.kr)
- fname = hd->current.kr->fname;
- else
- fname = hd->resource? hd->resource->fname:NULL;
-
- if (!fname)
- return GPG_ERR_GENERAL;
-
- /* close this one otherwise we will lose the position for
- * a next search. Fixme: it would be better to adjust the position
- * after the write opertions.
- */
- iobuf_close (hd->current.iobuf);
- hd->current.iobuf = NULL;
-
- /* do the insert */
- rc = do_copy (1, fname, kb, hd->secret, 0, 0 );
- if (!rc && !hd->secret && kr_offtbl)
- {
- update_offset_hash_table_from_kb (kr_offtbl, kb, 0);
- }
-
- return rc;
-}
-
-
-int
-keyring_delete_keyblock (KEYRING_HANDLE hd)
-{
- int rc;
-
- if (!hd->found.kr)
- return -1; /* no successful prior search */
-
- if (!hd->found.n_packets) {
- /* need to know the number of packets - do a dummy get_keyblock*/
- rc = keyring_get_keyblock (hd, NULL);
- if (rc) {
- log_error ("re-reading keyblock failed: %s\n", gpg_strerror (rc));
- return rc;
- }
- if (!hd->found.n_packets)
- BUG ();
- }
-
- /* close this one otherwise we will lose the position for
- * a next search. Fixme: it would be better to adjust the position
- * after the write opertions.
- */
- iobuf_close (hd->current.iobuf);
- hd->current.iobuf = NULL;
-
- /* do the delete */
- rc = do_copy (2, hd->found.kr->fname, NULL, hd->secret,
- hd->found.offset, hd->found.n_packets );
- if (!rc) {
- /* better reset the found info */
- hd->found.kr = NULL;
- hd->found.offset = 0;
- /* Delete is a rare operations, so we don't remove the keys
- * from the offset table */
- }
- return rc;
-}
-
-
-
-/*
- * Start the next search on this handle right at the beginning
- */
-int
-keyring_search_reset (KEYRING_HANDLE hd)
-{
- assert (hd);
-
- hd->current.kr = NULL;
- iobuf_close (hd->current.iobuf);
- hd->current.iobuf = NULL;
- hd->current.eof = 0;
- hd->current.error = 0;
-
- hd->found.kr = NULL;
- hd->found.offset = 0;
- return 0;
-}
-
-
-static int
-prepare_search (KEYRING_HANDLE hd)
-{
- if (hd->current.error)
- return hd->current.error; /* still in error state */
-
- if (hd->current.kr && !hd->current.eof) {
- if ( !hd->current.iobuf )
- return GPG_ERR_GENERAL; /* position invalid after a modify */
- return 0; /* okay */
- }
-
- if (!hd->current.kr && hd->current.eof)
- return -1; /* still EOF */
-
- if (!hd->current.kr) { /* start search with first keyring */
- hd->current.kr = hd->resource;
- if (!hd->current.kr) {
- hd->current.eof = 1;
- return -1; /* keyring not available */
- }
- assert (!hd->current.iobuf);
- }
- else { /* EOF */
- iobuf_close (hd->current.iobuf);
- hd->current.iobuf = NULL;
- hd->current.kr = NULL;
- hd->current.eof = 1;
- return -1;
- }
-
- hd->current.eof = 0;
- hd->current.iobuf = iobuf_open (hd->current.kr->fname);
- if (!hd->current.iobuf) {
- hd->current.error = gpg_error_from_errno (errno);
- log_error ("can't open `%s'\n", hd->current.kr->fname );
- return hd->current.error;
- }
-
- return 0;
-}
-
-
-/* A map of the all characters valid used for word_match()
- * Valid characters are in in this table converted to uppercase.
- * because the upper 128 bytes have special meaning, we assume
- * that they are all valid.
- * Note: We must use numerical values here in case that this program
- * will be converted to those little blue HAL9000s with their strange
- * EBCDIC character set (user ids are UTF-8).
- * wk 2000-04-13: Hmmm, does this really make sense, given the fact that
- * we can run gpg now on a S/390 running GNU/Linux, where the code
- * translation is done by the device drivers?
- */
-static const byte word_match_chars[256] = {
- /* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /* 10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /* 18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /* 20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /* 28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /* 30 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- /* 38 */ 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /* 40 */ 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- /* 48 */ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- /* 50 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- /* 58 */ 0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
- /* 60 */ 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- /* 68 */ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- /* 70 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- /* 78 */ 0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
- /* 80 */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- /* 88 */ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
- /* 90 */ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
- /* 98 */ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
- /* a0 */ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- /* a8 */ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
- /* b0 */ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
- /* b8 */ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
- /* c0 */ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- /* c8 */ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
- /* d0 */ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- /* d8 */ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
- /* e0 */ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
- /* e8 */ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
- /* f0 */ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- /* f8 */ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
-};
-
-/****************
- * Do a word match (original user id starts with a '+').
- * The pattern is already tokenized to a more suitable format:
- * There are only the real words in it delimited by one space
- * and all converted to uppercase.
- *
- * Returns: 0 if all words match.
- *
- * Note: This algorithm is a straightforward one and not very
- * fast. It works for UTF-8 strings. The uidlen should
- * be removed but due to the fact that old versions of
- * pgp don't use UTF-8 we still use the length; this should
- * be fixed in parse-packet (and replace \0 by some special
- * UTF-8 encoding)
- */
-static int
-word_match( const byte *uid, size_t uidlen, const byte *pattern )
-{
- size_t wlen, n;
- const byte *p;
- const byte *s;
-
- for( s=pattern; *s; ) {
- do {
- /* skip leading delimiters */
- while( uidlen && !word_match_chars[*uid] )
- uid++, uidlen--;
- /* get length of the word */
- n = uidlen; p = uid;
- while( n && word_match_chars[*p] )
- p++, n--;
- wlen = p - uid;
- /* and compare against the current word from pattern */
- for(n=0, p=uid; n < wlen && s[n] != ' ' && s[n] ; n++, p++ ) {
- if( word_match_chars[*p] != s[n] )
- break;
- }
- if( n == wlen && (s[n] == ' ' || !s[n]) )
- break; /* found */
- uid += wlen;
- uidlen -= wlen;
- } while( uidlen );
- if( !uidlen )
- return -1; /* not found */
-
- /* advance to next word in pattern */
- for(; *s != ' ' && *s ; s++ )
- ;
- if( *s )
- s++ ;
- }
- return 0; /* found */
-}
-
-/****************
- * prepare word word_match; that is parse the name and
- * build the pattern.
- * caller has to free the returned pattern
- */
-static char*
-prepare_word_match (const byte *name)
-{
- byte *pattern, *p;
- int c;
-
- /* the original length is always enough for the pattern */
- p = pattern = xmalloc (strlen(name)+1);
- do {
- /* skip leading delimiters */
- while( *name && !word_match_chars[*name] )
- name++;
- /* copy as long as we don't have a delimiter and convert
- * to uppercase.
- * fixme: how can we handle utf8 uppercasing */
- for( ; *name && (c=word_match_chars[*name]); name++ )
- *p++ = c;
- *p++ = ' '; /* append pattern delimiter */
- } while( *name );
- p[-1] = 0; /* replace last pattern delimiter by EOS */
-
- return pattern;
-}
-
-
-
-
-static int
-compare_name (int mode, const char *name, const char *uid, size_t uidlen)
-{
- int i;
- const char *s, *se;
-
- if (mode == KEYDB_SEARCH_MODE_EXACT) {
- for (i=0; name[i] && uidlen; i++, uidlen--)
- if (uid[i] != name[i])
- break;
- if (!uidlen && !name[i])
- return 0; /* found */
- }
- else if (mode == KEYDB_SEARCH_MODE_SUBSTR) {
- if (ascii_memistr( uid, uidlen, name ))
- return 0;
- }
- else if ( mode == KEYDB_SEARCH_MODE_MAIL
- || mode == KEYDB_SEARCH_MODE_MAILSUB
- || mode == KEYDB_SEARCH_MODE_MAILEND) {
- for (i=0, s= uid; i < uidlen && *s != '<'; s++, i++)
- ;
- if (i < uidlen) {
- /* skip opening delim and one char and look for the closing one*/
- s++; i++;
- for (se=s+1, i++; i < uidlen && *se != '>'; se++, i++)
- ;
- if (i < uidlen) {
- i = se - s;
- if (mode == KEYDB_SEARCH_MODE_MAIL) {
- if( strlen(name)-2 == i
- && !ascii_memcasecmp( s, name+1, i) )
- return 0;
- }
- else if (mode == KEYDB_SEARCH_MODE_MAILSUB) {
- if( ascii_memistr( s, i, name ) )
- return 0;
- }
- else { /* email from end */
- /* nyi */
- }
- }
- }
- }
- else if (mode == KEYDB_SEARCH_MODE_WORDS)
- return word_match (uid, uidlen, name);
- else
- BUG();
-
- return -1; /* not found */
-}
-
-
-/*
- * Search through the keyring(s), starting at the current position,
- * for a keyblock which contains one of the keys described in the DESC array.
- */
-int
-keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
- size_t ndesc, size_t *descindex)
-{
- int rc;
- PACKET pkt;
- int save_mode;
- off_t offset, main_offset;
- size_t n;
- int need_uid, need_words, need_keyid, need_fpr, any_skip;
- int pk_no, uid_no;
- int initial_skip;
- int use_offtbl;
- PKT_user_id *uid = NULL;
- PKT_public_key *pk = NULL;
- PKT_secret_key *sk = NULL;
- u32 aki[2];
-
- /* figure out what information we need */
- need_uid = need_words = need_keyid = need_fpr = any_skip = 0;
- for (n=0; n < ndesc; n++)
- {
- switch (desc[n].mode)
- {
- case KEYDB_SEARCH_MODE_EXACT:
- case KEYDB_SEARCH_MODE_SUBSTR:
- case KEYDB_SEARCH_MODE_MAIL:
- case KEYDB_SEARCH_MODE_MAILSUB:
- case KEYDB_SEARCH_MODE_MAILEND:
- need_uid = 1;
- break;
- case KEYDB_SEARCH_MODE_WORDS:
- need_uid = 1;
- need_words = 1;
- break;
- case KEYDB_SEARCH_MODE_SHORT_KID:
- case KEYDB_SEARCH_MODE_LONG_KID:
- need_keyid = 1;
- break;
- case KEYDB_SEARCH_MODE_FPR16:
- case KEYDB_SEARCH_MODE_FPR20:
- case KEYDB_SEARCH_MODE_FPR:
- need_fpr = 1;
- break;
- case KEYDB_SEARCH_MODE_FIRST:
- /* always restart the search in this mode */
- keyring_search_reset (hd);
- break;
- default: break;
- }
- if (desc[n].skipfnc)
- {
- any_skip = 1;
- need_keyid = 1;
- }
- }
-
- rc = prepare_search (hd);
- if (rc)
- return rc;
-
- use_offtbl = !hd->secret && kr_offtbl;
- if (!use_offtbl)
- ;
- else if (!kr_offtbl_ready)
- need_keyid = 1;
- else if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID)
- {
- struct off_item *oi;
-
- oi = lookup_offset_hash_table (kr_offtbl, desc[0].u.kid);
- if (!oi)
- { /* We know that we don't have this key */
- hd->found.kr = NULL;
- hd->current.eof = 1;
- return -1;
- }
- /* We could now create a positive search status and return.
- * However the problem is that another instance of gpg may
- * have changed the keyring so that the offsets are not valid
- * anymore - therefore we don't do it
- */
- }
-
- if (need_words)
- {
- const char *name = NULL;
-
- log_debug ("word search mode does not yet work\n");
- /* FIXME: here is a long standing bug in our function and in addition we
- just use the first search description */
- for (n=0; n < ndesc && !name; n++)
- {
- if (desc[n].mode == KEYDB_SEARCH_MODE_WORDS)
- name = desc[n].u.name;
- }
- assert (name);
- if ( !hd->word_match.name || strcmp (hd->word_match.name, name) )
- {
- /* name changed */
- xfree (hd->word_match.name);
- xfree (hd->word_match.pattern);
- hd->word_match.name = xstrdup (name);
- hd->word_match.pattern = prepare_word_match (name);
- }
- name = hd->word_match.pattern;
- }
-
- init_packet(&pkt);
- save_mode = set_packet_list_mode(0);
-
- hd->found.kr = NULL;
- main_offset = 0;
- pk_no = uid_no = 0;
- initial_skip = 1; /* skip until we see the start of a keyblock */
- while (!(rc=search_packet (hd->current.iobuf, &pkt, &offset, need_uid)))
- {
- byte afp[MAX_FINGERPRINT_LEN];
- size_t an;
-
- if (pkt.pkttype == PKT_PUBLIC_KEY || pkt.pkttype == PKT_SECRET_KEY)
- {
- main_offset = offset;
- pk_no = uid_no = 0;
- initial_skip = 0;
- }
- if (initial_skip)
- {
- free_packet (&pkt);
- continue;
- }
-
- pk = NULL;
- sk = NULL;
- uid = NULL;
- if ( pkt.pkttype == PKT_PUBLIC_KEY
- || pkt.pkttype == PKT_PUBLIC_SUBKEY)
- {
- pk = pkt.pkt.public_key;
- ++pk_no;
-
- if (need_fpr) {
- fingerprint_from_pk (pk, afp, &an);
- while (an < 20) /* fill up to 20 bytes */
- afp[an++] = 0;
- }
- if (need_keyid)
- keyid_from_pk (pk, aki);
-
- if (use_offtbl && !kr_offtbl_ready)
- update_offset_hash_table (kr_offtbl, aki, main_offset);
- }
- else if (pkt.pkttype == PKT_USER_ID)
- {
- uid = pkt.pkt.user_id;
- ++uid_no;
- }
- else if ( pkt.pkttype == PKT_SECRET_KEY
- || pkt.pkttype == PKT_SECRET_SUBKEY)
- {
- sk = pkt.pkt.secret_key;
- ++pk_no;
-
- if (need_fpr) {
- fingerprint_from_sk (sk, afp, &an);
- while (an < 20) /* fill up to 20 bytes */
- afp[an++] = 0;
- }
- if (need_keyid)
- keyid_from_sk (sk, aki);
-
- }
-
- for (n=0; n < ndesc; n++)
- {
- switch (desc[n].mode) {
- case KEYDB_SEARCH_MODE_NONE:
- BUG ();
- break;
- case KEYDB_SEARCH_MODE_EXACT:
- case KEYDB_SEARCH_MODE_SUBSTR:
- case KEYDB_SEARCH_MODE_MAIL:
- case KEYDB_SEARCH_MODE_MAILSUB:
- case KEYDB_SEARCH_MODE_MAILEND:
- case KEYDB_SEARCH_MODE_WORDS:
- if ( uid && !compare_name (desc[n].mode,
- desc[n].u.name,
- uid->name, uid->len))
- goto found;
- break;
-
- case KEYDB_SEARCH_MODE_SHORT_KID:
- if ((pk||sk) && desc[n].u.kid[1] == aki[1])
- goto found;
- break;
- case KEYDB_SEARCH_MODE_LONG_KID:
- if ((pk||sk) && desc[n].u.kid[0] == aki[0]
- && desc[n].u.kid[1] == aki[1])
- goto found;
- break;
- case KEYDB_SEARCH_MODE_FPR16:
- if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 16))
- goto found;
- break;
- case KEYDB_SEARCH_MODE_FPR20:
- case KEYDB_SEARCH_MODE_FPR:
- if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 20))
- goto found;
- break;
- case KEYDB_SEARCH_MODE_FIRST:
- if (pk||sk)
- goto found;
- break;
- case KEYDB_SEARCH_MODE_NEXT:
- if (pk||sk)
- goto found;
- break;
- default:
- rc = GPG_ERR_INV_ARG;
- goto found;
- }
- }
- free_packet (&pkt);
- continue;
- found:
- /* Record which desc we matched on. Note this value is only
- meaningful if this function returns with no errors. */
- if(descindex)
- *descindex=n;
- for (n=any_skip?0:ndesc; n < ndesc; n++)
- {
- if (desc[n].skipfnc
- && desc[n].skipfnc (desc[n].skipfncvalue, aki))
- break;
- }
- if (n == ndesc)
- goto real_found;
- free_packet (&pkt);
- }
- real_found:
- if (!rc)
- {
- hd->found.offset = main_offset;
- hd->found.kr = hd->current.kr;
- hd->found.pk_no = (pk||sk)? pk_no : 0;
- hd->found.uid_no = uid? uid_no : 0;
- }
- else if (rc == -1)
- {
- hd->current.eof = 1;
- /* if we scanned all keyrings, we are sure that
- * all known key IDs are in our offtbl, mark that. */
- if (use_offtbl && !kr_offtbl_ready)
- {
- KR_NAME kr;
-
- /* First set the did_full_scan flag for this keyring (ignore
- secret keyrings) */
- for (kr=kr_names; kr; kr = kr->next)
- {
- if (!kr->secret && hd->resource == kr)
- {
- kr->did_full_scan = 1;
- break;
- }
- }
- /* Then check whether all flags are set and if so, mark the
- offtbl ready */
- for (kr=kr_names; kr; kr = kr->next)
- {
- if (!kr->secret && !kr->did_full_scan)
- break;
- }
- if (!kr)
- kr_offtbl_ready = 1;
- }
- }
- else
- hd->current.error = rc;
-
- free_packet(&pkt);
- set_packet_list_mode(save_mode);
- return rc;
-}
-
-
-static int
-create_tmp_file (const char *template,
- char **r_bakfname, char **r_tmpfname, iobuf_t *r_fp)
-{
- char *bakfname, *tmpfname;
- mode_t oldmask;
-
- *r_bakfname = NULL;
- *r_tmpfname = NULL;
-
-# ifdef USE_ONLY_8DOT3
- /* Here is another Windoze bug?:
- * you cant rename("pubring.gpg.tmp", "pubring.gpg");
- * but rename("pubring.gpg.tmp", "pubring.aaa");
- * works. So we replace .gpg by .bak or .tmp
- */
- if (strlen (template) > 4
- && !strcmp (template+strlen(template)-4, EXTSEP_S "gpg") )
- {
- bakfname = xmalloc (strlen (template) + 1);
- strcpy (bakfname, template);
- strcpy (bakfname+strlen(template)-4, EXTSEP_S "bak");
-
- tmpfname = xmalloc (strlen( template ) + 1 );
- strcpy (tmpfname,template);
- strcpy (tmpfname+strlen(template)-4, EXTSEP_S "tmp");
- }
- else
- { /* file does not end with gpg; hmmm */
- bakfname = xmalloc (strlen( template ) + 5);
- strcpy (stpcpy(bakfname, template), EXTSEP_S "bak");
-
- tmpfname = xmalloc (strlen( template ) + 5);
- strcpy (stpcpy(tmpfname, template), EXTSEP_S "tmp");
- }
-# else /* Posix file names */
- bakfname = xmalloc (strlen( template ) + 2);
- strcpy (stpcpy (bakfname,template),"~");
-
- tmpfname = xmalloc (strlen( template ) + 5);
- strcpy (stpcpy(tmpfname,template), EXTSEP_S "tmp");
-# endif /* Posix filename */
-
- /* Create the temp file with limited access */
- oldmask=umask(077);
- *r_fp = iobuf_create (tmpfname);
- umask(oldmask);
- if (!*r_fp) {
- int tmperr = gpg_error_from_errno (errno);
- log_error ("can't create `%s': %s\n", tmpfname, strerror(errno) );
- xfree (tmpfname);
- xfree (bakfname);
- return tmperr;
- }
-
- *r_bakfname = bakfname;
- *r_tmpfname = tmpfname;
- return 0;
-}
-
-
-static int
-rename_tmp_file (const char *bakfname, const char *tmpfname,
- const char *fname, int secret )
-{
- int rc=0;
-
- /* invalidate close caches*/
- iobuf_ioctl (NULL, 2, 0, (char*)tmpfname );
- iobuf_ioctl (NULL, 2, 0, (char*)bakfname );
- iobuf_ioctl (NULL, 2, 0, (char*)fname );
-
- /* first make a backup file except for secret keyrings */
- if (!secret)
- {
-#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
- remove (bakfname);
-#endif
- if (rename (fname, bakfname) )
- {
- int tmperr = gpg_error_from_errno (errno);
- log_error ("renaming `%s' to `%s' failed: %s\n",
- fname, bakfname, strerror(errno) );
- return tmperr;
- }
- }
-
- /* then rename the file */
-#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
- remove( fname );
-#endif
- if (rename (tmpfname, fname) )
- {
- rc = gpg_error_from_errno (errno);
- log_error ("renaming `%s' to `%s' failed: %s\n",
- tmpfname, fname, strerror(errno) );
- if (secret)
- {
- log_info(_("WARNING: 2 files with confidential"
- " information exists.\n"));
- log_info(_("%s is the unchanged one\n"), fname );
- log_info(_("%s is the new one\n"), tmpfname );
- log_info(_("Please fix this possible security flaw\n"));
- }
- return rc;
- }
-
- /* Now make sure the file has the same permissions as the original */
-
-#ifndef HAVE_DOSISH_SYSTEM
- {
- struct stat statbuf;
-
- statbuf.st_mode=S_IRUSR | S_IWUSR;
-
- if(((secret && !opt.preserve_permissions) ||
- (stat(bakfname,&statbuf)==0)) &&
- (chmod(fname,statbuf.st_mode)==0))
- ;
- else
- log_error("WARNING: unable to restore permissions to `%s': %s",
- fname,strerror(errno));
- }
-#endif
-
- return 0;
-}
-
-
-static int
-write_keyblock (iobuf_t fp, KBNODE keyblock)
-{
- KBNODE kbctx = NULL, node;
- int rc;
-
- while ( (node = walk_kbnode (keyblock, &kbctx, 0)) )
- {
- if (node->pkt->pkttype == PKT_RING_TRUST)
- continue; /* we write it later on our own */
-
- if ( (rc = build_packet (fp, node->pkt) ))
- {
- log_error ("build_packet(%d) failed: %s\n",
- node->pkt->pkttype, gpg_strerror (rc) );
- return rc;
- }
- if (node->pkt->pkttype == PKT_SIGNATURE)
- { /* always write a signature cache packet */
- PKT_signature *sig = node->pkt->pkt.signature;
- unsigned int cacheval = 0;
-
- if (sig->flags.checked)
- {
- cacheval |= 1;
- if (sig->flags.valid)
- cacheval |= 2;
- }
- iobuf_put (fp, 0xb0); /* old style packet 12, 1 byte len*/
- iobuf_put (fp, 2); /* 2 bytes */
- iobuf_put (fp, 0); /* unused */
- if (iobuf_put (fp, cacheval)) {
- int tmperr = gpg_error_from_errno (errno);
- log_error ("writing sigcache packet failed\n");
- return tmperr;
- }
- }
- }
- return 0;
-}
-
-/*
- * Walk over all public keyrings, check the signatures and replace the
- * keyring with a new one where the signature cache is then updated.
- * This is only done for the public keyrings.
- */
-int
-keyring_rebuild_cache (void *token)
-{
- KEYRING_HANDLE hd;
- KEYDB_SEARCH_DESC desc;
- KBNODE keyblock = NULL, node;
- const char *lastresname = NULL, *resname;
- iobuf_t tmpfp = NULL;
- char *tmpfilename = NULL;
- char *bakfilename = NULL;
- int rc;
- ulong count = 0, sigcount = 0;
-
- hd = keyring_new (token, 0);
- memset (&desc, 0, sizeof desc);
- desc.mode = KEYDB_SEARCH_MODE_FIRST;
-
- rc=keyring_lock (hd, 1);
- if(rc)
- goto leave;
-
- while ( !(rc = keyring_search (hd, &desc, 1, NULL)) )
- {
- desc.mode = KEYDB_SEARCH_MODE_NEXT;
- resname = keyring_get_resource_name (hd);
- if (lastresname != resname )
- { /* we have switched to a new keyring - commit changes */
- if (tmpfp)
- {
- if (iobuf_close (tmpfp))
- {
- rc = gpg_error_from_errno (errno);
- log_error ("error closing `%s': %s\n",
- tmpfilename, strerror (errno));
- goto leave;
- }
- /* because we have switched resources, we can be sure that
- * the original file is closed */
- tmpfp = NULL;
- }
- rc = lastresname? rename_tmp_file (bakfilename, tmpfilename,
- lastresname, 0) : 0;
- xfree (tmpfilename); tmpfilename = NULL;
- xfree (bakfilename); bakfilename = NULL;
- if (rc)
- goto leave;
- lastresname = resname;
- if (!opt.quiet)
- log_info (_("checking keyring `%s'\n"), resname);
- rc = create_tmp_file (resname, &bakfilename, &tmpfilename, &tmpfp);
- if (rc)
- goto leave;
- }
-
- release_kbnode (keyblock);
- rc = keyring_get_keyblock (hd, &keyblock);
- if (rc)
- {
- log_error ("keyring_get_keyblock failed: %s\n", gpg_strerror (rc));
- goto leave;
- }
- assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
-
- /* check all signature to set the signature's cache flags */
- for (node=keyblock; node; node=node->next)
- {
- if (node->pkt->pkttype == PKT_SIGNATURE)
- {
- /* Note that this doesn't cache the result of a
- revocation issued by a designated revoker. This is
- because the pk in question does not carry the revkeys
- as we haven't merged the key and selfsigs. It is
- questionable whether this matters very much since
- there are very very few designated revoker revocation
- packets out there. */
- check_key_signature (keyblock, node, NULL);
- sigcount++;
- }
- }
-
- /* write the keyblock to the temporary file */
- rc = write_keyblock (tmpfp, keyblock);
- if (rc)
- goto leave;
-
- if ( !(++count % 50) && !opt.quiet)
- log_info(_("%lu keys checked so far (%lu signatures)\n"),
- count, sigcount );
-
- } /* end main loop */
- if (rc == -1)
- rc = 0;
- if (rc)
- {
- log_error ("keyring_search failed: %s\n", gpg_strerror (rc));
- goto leave;
- }
- log_info(_("%lu keys checked (%lu signatures)\n"), count, sigcount );
- if (tmpfp)
- {
- if (iobuf_close (tmpfp))
- {
- rc = gpg_error_from_errno (errno);
- log_error ("error closing `%s': %s\n",
- tmpfilename, strerror (errno));
- goto leave;
- }
- /* because we have switched resources, we can be sure that
- * the original file is closed */
- tmpfp = NULL;
- }
- rc = lastresname? rename_tmp_file (bakfilename, tmpfilename,
- lastresname, 0) : 0;
- xfree (tmpfilename); tmpfilename = NULL;
- xfree (bakfilename); bakfilename = NULL;
-
- leave:
- if (tmpfp)
- iobuf_cancel (tmpfp);
- xfree (tmpfilename);
- xfree (bakfilename);
- release_kbnode (keyblock);
- keyring_lock (hd, 0);
- keyring_release (hd);
- return rc;
-}
-
-
-/****************
- * Perform insert/delete/update operation.
- * mode 1 = insert
- * 2 = delete
- * 3 = update
- */
-static int
-do_copy (int mode, const char *fname, KBNODE root, int secret,
- off_t start_offset, unsigned int n_packets )
-{
- iobuf_t fp, newfp;
- int rc=0;
- char *bakfname = NULL;
- char *tmpfname = NULL;
-
- /* Open the source file. Because we do a rname, we have to check the
- permissions of the file */
- if (access (fname, W_OK))
- return gpg_error_from_errno (errno);
-
-
- fp = iobuf_open (fname);
- if (mode == 1 && !fp && errno == ENOENT) {
- /* insert mode but file does not exist: create a new file */
- KBNODE kbctx, node;
- mode_t oldmask;
-
- oldmask=umask(077);
- newfp = iobuf_create (fname);
- umask(oldmask);
- if( !newfp ) {
- int tmperr = gpg_error_from_errno (errno);
- log_error (_("%s: can't create: %s\n"),
- fname, strerror(errno));
- return tmperr;
- }
- if( !opt.quiet )
- log_info(_("%s: keyring created\n"), fname );
-
- kbctx=NULL;
- while ( (node = walk_kbnode( root, &kbctx, 0 )) ) {
- if( (rc = build_packet( newfp, node->pkt )) ) {
- log_error("build_packet(%d) failed: %s\n",
- node->pkt->pkttype, gpg_strerror (rc) );
- iobuf_cancel(newfp);
- return rc;
- }
- }
- if (iobuf_close(newfp)) {
- int tmperr = gpg_error_from_errno (errno);
- log_error ("%s: close failed: %s\n", fname, strerror(errno));
- return tmperr;
- }
- return 0; /* ready */
- }
-
- if( !fp ) {
- rc = gpg_error_from_errno (errno);
- log_error ("%s: can't open: %s\n", fname, strerror(errno) );
- goto leave;
- }
-
- /* create the new file */
- rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp);
- if (rc) {
- iobuf_close(fp);
- goto leave;
- }
- if( mode == 1 ) { /* insert */
- /* copy everything to the new file */
- rc = copy_all_packets (fp, newfp);
- if( rc != -1 ) {
- log_error("%s: copy to `%s' failed: %s\n",
- fname, tmpfname, gpg_strerror (rc) );
- iobuf_close(fp);
- iobuf_cancel(newfp);
- goto leave;
- }
- rc = 0;
- }
-
- if( mode == 2 || mode == 3 ) { /* delete or update */
- /* copy first part to the new file */
- rc = copy_some_packets( fp, newfp, start_offset );
- if( rc ) { /* should never get EOF here */
- log_error ("%s: copy to `%s' failed: %s\n",
- fname, tmpfname, gpg_strerror (rc) );
- iobuf_close(fp);
- iobuf_cancel(newfp);
- goto leave;
- }
- /* skip this keyblock */
- assert( n_packets );
- rc = skip_some_packets( fp, n_packets );
- if( rc ) {
- log_error("%s: skipping %u packets failed: %s\n",
- fname, n_packets, gpg_strerror (rc));
- iobuf_close(fp);
- iobuf_cancel(newfp);
- goto leave;
- }
- }
-
- if( mode == 1 || mode == 3 ) { /* insert or update */
- rc = write_keyblock (newfp, root);
- if (rc) {
- iobuf_close(fp);
- iobuf_cancel(newfp);
- goto leave;
- }
- }
-
- if( mode == 2 || mode == 3 ) { /* delete or update */
- /* copy the rest */
- rc = copy_all_packets( fp, newfp );
- if( rc != -1 ) {
- log_error("%s: copy to `%s' failed: %s\n",
- fname, tmpfname, gpg_strerror (rc) );
- iobuf_close(fp);
- iobuf_cancel(newfp);
- goto leave;
- }
- rc = 0;
- }
-
- /* close both files */
- if( iobuf_close(fp) ) {
- rc = gpg_error_from_errno (errno);
- log_error("%s: close failed: %s\n", fname, strerror(errno) );
- goto leave;
- }
- if( iobuf_close(newfp) ) {
- rc = gpg_error_from_errno (errno);
- log_error("%s: close failed: %s\n", tmpfname, strerror(errno) );
- goto leave;
- }
-
- rc = rename_tmp_file (bakfname, tmpfname, fname, secret);
-
- leave:
- xfree (bakfname);
- xfree (tmpfname);
- return rc;
-}
diff --git a/g10/keyring.h b/g10/keyring.h
deleted file mode 100644
index 528557a70..000000000
--- a/g10/keyring.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* keyring.h - Keyring operations
- * Copyright (C) 2001 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef GPG_KEYRING_H
-#define GPG_KEYRING_H 1
-
-#include "global.h"
-
-
-typedef struct keyring_handle *KEYRING_HANDLE;
-
-int keyring_register_filename (const char *fname, int secret, void **ptr);
-int keyring_is_writable (void *token);
-
-KEYRING_HANDLE keyring_new (void *token, int secret);
-void keyring_release (KEYRING_HANDLE hd);
-const char *keyring_get_resource_name (KEYRING_HANDLE hd);
-int keyring_lock (KEYRING_HANDLE hd, int yes);
-int keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb);
-int keyring_update_keyblock (KEYRING_HANDLE hd, KBNODE kb);
-int keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb);
-int keyring_locate_writable (KEYRING_HANDLE hd);
-int keyring_delete_keyblock (KEYRING_HANDLE hd);
-int keyring_search_reset (KEYRING_HANDLE hd);
-int keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
- size_t ndesc, size_t *descindex);
-int keyring_rebuild_cache (void *);
-
-#endif /*GPG_KEYRING_H*/
diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h
deleted file mode 100644
index 314d7898e..000000000
--- a/g10/keyserver-internal.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Keyserver internals */
-
-#ifndef _KEYSERVER_INTERNAL_H_
-#define _KEYSERVER_INTERNAL_H_
-
-#include <time.h>
-#include "keyserver.h"
-#include "../common/iobuf.h"
-#include "types.h"
-
-void parse_keyserver_options(char *options);
-int parse_keyserver_uri(char *uri,
- const char *configname,unsigned int configlineno);
-int keyserver_export(STRLIST users);
-int keyserver_import(STRLIST users);
-int keyserver_import_fprint(const byte *fprint,size_t fprint_len);
-int keyserver_import_keyid(u32 *keyid);
-int keyserver_refresh(STRLIST users);
-int keyserver_search(STRLIST tokens);
-
-#endif /* !_KEYSERVER_INTERNAL_H_ */
diff --git a/g10/keyserver.c b/g10/keyserver.c
deleted file mode 100644
index 445c07620..000000000
--- a/g10/keyserver.c
+++ /dev/null
@@ -1,1381 +0,0 @@
-/* keyserver.c - generic keyserver code
- * Copyright (C) 2001, 2002, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "filter.h"
-#include "keydb.h"
-#include "status.h"
-#include "exec.h"
-#include "main.h"
-#include "i18n.h"
-#include "iobuf.h"
-#include "memory.h"
-#include "ttyio.h"
-#include "options.h"
-#include "packet.h"
-#include "keyserver-internal.h"
-#include "util.h"
-
-#define GET 0
-#define SEND 1
-#define SEARCH 2
-
-struct keyrec
-{
- KEYDB_SEARCH_DESC desc;
- time_t createtime,expiretime;
- int size,flags;
- byte type;
- iobuf_t uidbuf;
- int lines;
-};
-
-struct kopts
-{
- char *name;
- int tell; /* tell remote process about this one */
- int *flag;
-} keyserver_opts[]=
-{
- {"include-revoked",1,&opt.keyserver_options.include_revoked},
- {"include-disabled",1,&opt.keyserver_options.include_disabled},
- {"include-subkeys",1,&opt.keyserver_options.include_subkeys},
- {"keep-temp-files",0,&opt.keyserver_options.keep_temp_files},
- {"honor-http-proxy",1,&opt.keyserver_options.honor_http_proxy},
- {"broken-http-proxy",1,&opt.keyserver_options.broken_http_proxy},
- {"refresh-add-fake-v3-keyids",0,&opt.keyserver_options.fake_v3_keyids},
- {"auto-key-retrieve",0,&opt.keyserver_options.auto_key_retrieve},
- {"try-dns-srv",1,&opt.keyserver_options.try_dns_srv},
- {NULL}
-};
-
-static int keyserver_work(int action,STRLIST list,
- KEYDB_SEARCH_DESC *desc,int count);
-
-void
-parse_keyserver_options(char *options)
-{
- char *tok;
-
- while((tok=strsep(&options," ,")))
- {
- int i,hit=0;
-
- if(tok[0]=='\0')
- continue;
-
- for(i=0;keyserver_opts[i].name;i++)
- {
- if(ascii_strcasecmp(tok,keyserver_opts[i].name)==0)
- {
- *(keyserver_opts[i].flag)=1;
- hit=1;
- break;
- }
- else if(ascii_strncasecmp("no-",tok,3)==0 &&
- ascii_strcasecmp(&tok[3],keyserver_opts[i].name)==0)
- {
- *(keyserver_opts[i].flag)=0;
- hit=1;
- break;
- }
- }
-
- /* These options need more than just a flag */
- if(!hit)
- {
- if(ascii_strcasecmp(tok,"verbose")==0)
- opt.keyserver_options.verbose++;
- else if(ascii_strcasecmp(tok,"no-verbose")==0)
- opt.keyserver_options.verbose--;
-#ifdef EXEC_TEMPFILE_ONLY
- else if(ascii_strcasecmp(tok,"use-temp-files")==0 ||
- ascii_strcasecmp(tok,"no-use-temp-files")==0)
- log_info(_("WARNING: keyserver option \"%s\" is not used "
- "on this platform\n"),tok);
-#else
- else if(ascii_strcasecmp(tok,"use-temp-files")==0)
- opt.keyserver_options.use_temp_files=1;
- else if(ascii_strcasecmp(tok,"no-use-temp-files")==0)
- opt.keyserver_options.use_temp_files=0;
-#endif
- else
- if(!parse_import_options(tok,
- &opt.keyserver_options.import_options) &&
- !parse_export_options(tok,
- &opt.keyserver_options.export_options))
- add_to_strlist(&opt.keyserver_options.other,tok);
- }
- }
-}
-
-int
-parse_keyserver_uri(char *uri,const char *configname,unsigned int configlineno)
-{
- int assume_hkp=0;
-
- assert(uri!=NULL);
-
- opt.keyserver_host=NULL;
- opt.keyserver_port=NULL;
- opt.keyserver_opaque=NULL;
-
- /* Get the scheme */
-
- opt.keyserver_scheme=strsep(&uri,":");
- if(uri==NULL)
- {
- /* Assume HKP if there is no scheme */
- assume_hkp=1;
- uri=opt.keyserver_scheme;
- opt.keyserver_scheme="hkp";
- }
- else
- {
- /* Force to lowercase */
- char *i;
-
- for(i=opt.keyserver_scheme;*i!='\0';i++)
- *i=ascii_tolower(*i);
- }
-
- if(ascii_strcasecmp(opt.keyserver_scheme,"x-broken-hkp")==0)
- {
- deprecated_warning(configname,configlineno,"x-broken-hkp",
- "--keyserver-options ","broken-http-proxy");
- opt.keyserver_scheme="hkp";
- opt.keyserver_options.broken_http_proxy=1;
- }
- else if(ascii_strcasecmp(opt.keyserver_scheme,"x-hkp")==0
- || ascii_strcasecmp(opt.keyserver_scheme,"http")==0)
- {
- /* Canonicalize this to "hkp" so it works with both the internal
- and external keyserver interface. */
- opt.keyserver_scheme="hkp";
- }
-
- if(assume_hkp || (uri[0]=='/' && uri[1]=='/'))
- {
- /* Two slashes means network path. */
-
- /* Skip over the "//", if any */
- if(!assume_hkp)
- uri+=2;
-
- /* Get the host */
- opt.keyserver_host=strsep(&uri,":/");
- if(opt.keyserver_host[0]=='\0')
- return GPG_ERR_BAD_URI;
-
- if(uri==NULL || uri[0]=='\0')
- opt.keyserver_port=NULL;
- else
- {
- char *ch;
-
- /* Get the port */
- opt.keyserver_port=strsep(&uri,"/");
-
- /* Ports are digits only */
- ch=opt.keyserver_port;
- while(*ch!='\0')
- {
- if(!digitp(ch))
- return GPG_ERR_BAD_URI;
-
- ch++;
- }
-
- /* It would seem to be reasonable to limit the range of the
- ports to values between 1-65535, but RFC 1738 and 1808
- imply there is no limit. Of course, the real world has
- limits. */
- }
-
- /* (any path part of the URI is discarded for now as no keyserver
- uses it yet) */
- }
- else if(uri[0]!='/')
- {
- /* No slash means opaque. Just record the opaque blob and get
- out. */
- opt.keyserver_opaque=uri;
- return 0;
- }
- else
- {
- /* One slash means absolute path. We don't need to support that
- yet. */
- return GPG_ERR_BAD_URI;
- }
-
- if(opt.keyserver_scheme[0]=='\0')
- return GPG_ERR_BAD_URI;
-
- return 0;
-}
-
-static void
-print_keyrec(int number,struct keyrec *keyrec)
-{
- int i;
-
- iobuf_writebyte(keyrec->uidbuf,0);
- iobuf_flush_temp(keyrec->uidbuf);
- printf("(%d)\t%s ",number,iobuf_get_temp_buffer(keyrec->uidbuf));
-
- if(keyrec->size>0)
- printf("%d bit ",keyrec->size);
-
- if(keyrec->type)
- {
- const char *str = gcry_pk_algo_name (keyrec->type);
-
- if(str)
- printf("%s ",str);
- else
- printf("unknown ");
- }
-
- switch(keyrec->desc.mode)
- {
- case KEYDB_SEARCH_MODE_SHORT_KID:
- printf("key %08lX",(ulong)keyrec->desc.u.kid[1]);
- break;
-
- case KEYDB_SEARCH_MODE_LONG_KID:
- printf("key %08lX%08lX",(ulong)keyrec->desc.u.kid[0],
- (ulong)keyrec->desc.u.kid[1]);
- break;
-
- case KEYDB_SEARCH_MODE_FPR16:
- printf("key ");
- for(i=0;i<16;i++)
- printf("%02X",(unsigned char)keyrec->desc.u.fpr[i]);
- break;
-
- case KEYDB_SEARCH_MODE_FPR20:
- printf("key ");
- for(i=0;i<20;i++)
- printf("%02X",(unsigned char)keyrec->desc.u.fpr[i]);
- break;
-
- default:
- BUG();
- break;
- }
-
- if(keyrec->createtime>0)
- printf(", created %s",strtimestamp(keyrec->createtime));
-
- if(keyrec->expiretime>0)
- printf(", expires %s",strtimestamp(keyrec->expiretime));
-
- if(keyrec->flags&1)
- printf(" (%s)",("revoked"));
- if(keyrec->flags&2)
- printf(" (%s)",("disabled"));
- if(keyrec->flags&4)
- printf(" (%s)",("expired"));
-
- printf("\n");
-}
-
-/* Returns a keyrec (which must be freed) once a key is complete, and
- NULL otherwise. Call with a NULL keystring once key parsing is
- complete to return any unfinished keys. */
-static struct keyrec *
-parse_keyrec(char *keystring)
-{
- static struct keyrec *work=NULL;
- struct keyrec *ret=NULL;
- char *record;
- int i;
-
- if(keystring==NULL)
- {
- if(work==NULL)
- return NULL;
- else if(work->desc.mode==KEYDB_SEARCH_MODE_NONE)
- {
- xfree (work);
- return NULL;
- }
- else
- {
- ret=work;
- work=NULL;
- return ret;
- }
- }
-
- if(work==NULL)
- {
- work=xcalloc (1,sizeof(struct keyrec));
- work->uidbuf=iobuf_temp();
- }
-
- /* Remove trailing whitespace */
- for(i=strlen(keystring);i>0;i--)
- if(ascii_isspace(keystring[i-1]))
- keystring[i-1]='\0';
- else
- break;
-
- if((record=strsep(&keystring,":"))==NULL)
- return ret;
-
- if(ascii_strcasecmp("pub",record)==0)
- {
- char *tok;
-
- if(work->desc.mode)
- {
- ret=work;
- work=xcalloc (1,sizeof(struct keyrec));
- work->uidbuf=iobuf_temp();
- }
-
- if((tok=strsep(&keystring,":"))==NULL)
- return ret;
-
- classify_user_id(tok,&work->desc);
- if(work->desc.mode!=KEYDB_SEARCH_MODE_SHORT_KID
- && work->desc.mode!=KEYDB_SEARCH_MODE_LONG_KID
- && work->desc.mode!=KEYDB_SEARCH_MODE_FPR16
- && work->desc.mode!=KEYDB_SEARCH_MODE_FPR20)
- {
- work->desc.mode=KEYDB_SEARCH_MODE_NONE;
- return ret;
- }
-
- /* Note all items after this are optional. This allows us to
- have a pub line as simple as pub:keyid and nothing else. */
-
- work->lines++;
-
- if((tok=strsep(&keystring,":"))==NULL)
- return ret;
-
- work->type=atoi(tok);
-
- if((tok=strsep(&keystring,":"))==NULL)
- return ret;
-
- work->size=atoi(tok);
-
- if((tok=strsep(&keystring,":"))==NULL)
- return ret;
-
- work->createtime=atoi(tok);
-
- if((tok=strsep(&keystring,":"))==NULL)
- return ret;
-
- work->expiretime=atoi(tok);
-
- if((tok=strsep(&keystring,":"))==NULL)
- return ret;
-
- while(*tok)
- switch(*tok++)
- {
- case 'r':
- case 'R':
- work->flags|=1;
- break;
-
- case 'd':
- case 'D':
- work->flags|=2;
- break;
-
- case 'e':
- case 'E':
- work->flags|=4;
- break;
- }
-
- if(work->expiretime && work->expiretime<=make_timestamp())
- work->flags|=4;
- }
- else if(ascii_strcasecmp("uid",record)==0 && work->desc.mode)
- {
- char *userid,*tok,*decoded;
-
- if((tok=strsep(&keystring,":"))==NULL)
- return ret;
-
- if(strlen(tok)==0)
- return ret;
-
- userid=tok;
-
- /* By definition, de-%-encoding is always smaller than the
- original string so we can decode in place. */
-
- i=0;
-
- while(*tok)
- if(tok[0]=='%' && tok[1] && tok[2])
- {
- if((userid[i]=hextobyte(&tok[1]))==-1)
- userid[i]='?';
-
- i++;
- tok+=3;
- }
- else
- userid[i++]=*tok++;
-
- /* We don't care about the other info provided in the uid: line
- since no keyserver supports marking userids with timestamps
- or revoked/expired/disabled yet. */
-
- /* No need to check for control characters, as utf8_to_native
- does this for us. */
-
- decoded=utf8_to_native(userid,i,0);
- iobuf_writestr(work->uidbuf,decoded);
- xfree (decoded);
- iobuf_writestr(work->uidbuf,"\n\t");
- work->lines++;
- }
-
- /* Ignore any records other than "pri" and "uid" for easy future
- growth. */
-
- return ret;
-}
-
-/* TODO: do this as a list sent to keyserver_work rather than calling
- it once for each key to get the correct counts after the import
- (cosmetics, really) and to better take advantage of the keyservers
- that can do multiple fetches in one go (LDAP). */
-static int
-show_prompt(KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search)
-{
- char *answer;
-
- if(count && opt.command_fd==-1)
- {
- static int from=1;
- tty_printf("Keys %d-%d of %d for \"%s\". ",from,numdesc,count,search);
- from=numdesc+1;
- }
-
- answer=cpr_get_no_help("keysearch.prompt",
- _("Enter number(s), N)ext, or Q)uit > "));
- /* control-d */
- if(answer[0]=='\x04')
- {
- printf("Q\n");
- answer[0]='q';
- }
-
- if(answer[0]=='q' || answer[0]=='Q')
- {
- xfree (answer);
- return 1;
- }
- else if(atoi(answer)>=1 && atoi(answer)<=numdesc)
- {
- char *split=answer,*num;
-
- while((num=strsep(&split," ,"))!=NULL)
- if(atoi(num)>=1 && atoi(num)<=numdesc)
- keyserver_work(GET,NULL,&desc[atoi(num)-1],1);
-
- xfree (answer);
- return 1;
- }
-
- return 0;
-}
-
-/* Count and searchstr are just for cosmetics. If the count is too
- small, it will grow safely. If negative it disables the "Key x-y
- of z" messages. */
-static void
-keyserver_search_prompt(iobuf_t buffer,const char *searchstr)
-{
- int i=0,validcount=0,started=0,header=0,count=1;
- unsigned int maxlen,buflen;
- KEYDB_SEARCH_DESC *desc;
- byte *line=NULL;
- /* TODO: Something other than 23? That's 24-1 (the prompt). */
- int maxlines=23,numlines=0;
-
- desc=xmalloc (count*sizeof(KEYDB_SEARCH_DESC));
-
- for(;;)
- {
- struct keyrec *keyrec;
- int rl;
-
- maxlen=1024;
- rl=iobuf_read_line(buffer,&line,&buflen,&maxlen);
-
- if(opt.with_colons)
- {
- if(!header && ascii_strncasecmp("SEARCH ",line,7)==0
- && ascii_strncasecmp(" BEGIN",&line[strlen(line)-7],6)==0)
- {
- header=1;
- continue;
- }
- else if(ascii_strncasecmp("SEARCH ",line,7)==0
- && ascii_strncasecmp(" END",&line[strlen(line)-5],4)==0)
- continue;
-
- printf("%s",line);
- }
-
- /* Look for an info: line. The only current info: values
- defined are the version and key count. */
- if(!started && rl>0 && ascii_strncasecmp("info:",line,5)==0)
- {
- char *tok,*str=&line[5];
-
- if((tok=strsep(&str,":"))!=NULL)
- {
- int version;
-
- if(sscanf(tok,"%d",&version)!=1)
- version=1;
-
- if(version!=1)
- {
- log_error(_("invalid keyserver protocol "
- "(us %d!=handler %d)\n"),1,version);
- break;
- }
- }
-
- if((tok=strsep(&str,":"))!=NULL && sscanf(tok,"%d",&count)==1)
- {
- if(count==0)
- goto notfound;
- else if(count<0)
- count=10;
- else
- validcount=1;
-
- desc=xrealloc(desc,count*sizeof(KEYDB_SEARCH_DESC));
- }
-
- started=1;
- continue;
- }
-
- if(rl==0)
- {
- keyrec=parse_keyrec(NULL);
-
- if(keyrec==NULL)
- {
- if(i==0)
- {
- count=0;
- break;
- }
-
- if(i!=count)
- validcount=0;
-
- for(;;)
- {
- if(show_prompt(desc,i,validcount?count:0,searchstr))
- break;
- validcount=0;
- }
-
- break;
- }
- }
- else
- keyrec=parse_keyrec(line);
-
- if(i==count)
- {
- /* keyserver helper sent more keys than they claimed in the
- info: line. */
- count+=10;
- desc=xrealloc(desc,count*sizeof(KEYDB_SEARCH_DESC));
- validcount=0;
- }
-
- if(keyrec)
- {
- desc[i]=keyrec->desc;
-
- if(!opt.with_colons)
- {
- if(numlines+keyrec->lines>maxlines)
- {
- if(show_prompt(desc,i,validcount?count:0,searchstr))
- break;
- else
- numlines=0;
- }
-
- print_keyrec(i+1,keyrec);
- }
-
- numlines+=keyrec->lines;
- iobuf_close(keyrec->uidbuf);
- xfree (keyrec);
-
- started=1;
- i++;
- }
- }
-
- xfree (desc);
- xfree (line);
-
- notfound:
- if(count==0)
- {
- if(searchstr)
- log_info(_("key \"%s\" not found on keyserver\n"),searchstr);
- else
- log_info(_("key not found on keyserver\n"));
- return;
- }
-}
-
-#define KEYSERVER_ARGS_KEEP " -o \"%O\" \"%I\""
-#define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\""
-
-static int
-keyserver_spawn(int action,STRLIST list,
- KEYDB_SEARCH_DESC *desc,int count,int *prog)
-{
- int ret=0,i,gotversion=0,outofband=0;
- STRLIST temp;
- unsigned int maxlen,buflen;
- char *command=NULL,*searchstr=NULL;
- byte *line=NULL;
- struct kopts *kopts;
- struct exec_info *spawn;
-
-#ifdef EXEC_TEMPFILE_ONLY
- opt.keyserver_options.use_temp_files=1;
-#endif
-
- /* Push the libexecdir into path. If DISABLE_KEYSERVER_PATH is set,
- use the 0 arg to replace the path. */
-#ifdef DISABLE_KEYSERVER_PATH
- set_exec_path(GNUPG_LIBEXECDIR,0);
-#else
- set_exec_path(GNUPG_LIBEXECDIR,opt.exec_path_set);
-#endif
-
- /* Build the filename for the helper to execute */
- command=xmalloc (strlen("gpgkeys_")+strlen(opt.keyserver_scheme)+1);
- strcpy(command,"gpgkeys_");
- strcat(command,opt.keyserver_scheme);
-
- if(opt.keyserver_options.use_temp_files)
- {
- if(opt.keyserver_options.keep_temp_files)
- {
- command=xrealloc(command,strlen(command)+
- strlen(KEYSERVER_ARGS_KEEP)+1);
- strcat(command,KEYSERVER_ARGS_KEEP);
- }
- else
- {
- command=xrealloc(command,strlen(command)+
- strlen(KEYSERVER_ARGS_NOKEEP)+1);
- strcat(command,KEYSERVER_ARGS_NOKEEP);
- }
-
- ret=exec_write(&spawn,NULL,command,NULL,0,0);
- }
- else
- ret=exec_write(&spawn,command,NULL,NULL,0,0);
-
- if(ret)
- return ret;
-
- fprintf(spawn->tochild,"# This is a gpg keyserver communications file\n");
- fprintf(spawn->tochild,"VERSION %d\n",KEYSERVER_PROTO_VERSION);
- fprintf(spawn->tochild,"PROGRAM %s\n",VERSION);
-
- if(opt.keyserver_opaque)
- fprintf(spawn->tochild,"OPAQUE %s\n",opt.keyserver_opaque);
- else
- {
- if(opt.keyserver_host)
- fprintf(spawn->tochild,"HOST %s\n",opt.keyserver_host);
-
- if(opt.keyserver_port)
- fprintf(spawn->tochild,"PORT %s\n",opt.keyserver_port);
- }
-
- /* Write options */
-
- for(i=0,kopts=keyserver_opts;kopts[i].name;i++)
- if(*(kopts[i].flag) && kopts[i].tell)
- fprintf(spawn->tochild,"OPTION %s\n",kopts[i].name);
-
- for(i=0;i<opt.keyserver_options.verbose;i++)
- fprintf(spawn->tochild,"OPTION verbose\n");
-
- temp=opt.keyserver_options.other;
-
- for(;temp;temp=temp->next)
- fprintf(spawn->tochild,"OPTION %s\n",temp->d);
-
- switch(action)
- {
- case GET:
- {
- fprintf(spawn->tochild,"COMMAND GET\n\n");
-
- /* Which keys do we want? */
-
- for(i=0;i<count;i++)
- {
- if(desc[i].mode==KEYDB_SEARCH_MODE_FPR20)
- {
- int f;
-
- fprintf(spawn->tochild,"0x");
-
- for(f=0;f<MAX_FINGERPRINT_LEN;f++)
- fprintf(spawn->tochild,"%02X",(byte)desc[i].u.fpr[f]);
-
- fprintf(spawn->tochild,"\n");
- }
- else if(desc[i].mode==KEYDB_SEARCH_MODE_FPR16)
- {
- int f;
-
- fprintf(spawn->tochild,"0x");
-
- for(f=0;f<16;f++)
- fprintf(spawn->tochild,"%02X",(byte)desc[i].u.fpr[f]);
-
- fprintf(spawn->tochild,"\n");
- }
- else if(desc[i].mode==KEYDB_SEARCH_MODE_LONG_KID)
- fprintf(spawn->tochild,"0x%08lX%08lX\n",
- (ulong)desc[i].u.kid[0],
- (ulong)desc[i].u.kid[1]);
- else
- fprintf(spawn->tochild,"0x%08lX\n",
- (ulong)desc[i].u.kid[1]);
- }
-
- fprintf(spawn->tochild,"\n");
-
- break;
- }
-
- case SEND:
- {
- STRLIST key;
-
- /* Note the extra \n here to send an empty keylist block */
- fprintf(spawn->tochild,"COMMAND SEND\n\n\n");
-
- for(key=list;key!=NULL;key=key->next)
- {
- armor_filter_context_t afx;
- iobuf_t buffer=iobuf_temp();
- KBNODE block;
-
- temp=NULL;
- add_to_strlist(&temp,key->d);
-
- memset(&afx,0,sizeof(afx));
- afx.what=1;
- iobuf_push_filter(buffer,armor_filter,&afx);
-
- /* TODO: Don't use the keyblock hack here - instead,
- output each key as a different ascii armored blob with
- its own INFO section. */
-
- if(export_pubkeys_stream(buffer,temp,&block,
- opt.keyserver_options.export_options)==-1)
- iobuf_close(buffer);
- else
- {
- KBNODE node;
-
- iobuf_flush_temp(buffer);
-
- merge_keys_and_selfsig(block);
-
- fprintf(spawn->tochild,"INFO %s BEGIN\n",key->d);
-
- for(node=block;node;node=node->next)
- {
- switch(node->pkt->pkttype)
- {
- default:
- continue;
-
- case PKT_PUBLIC_KEY:
- case PKT_PUBLIC_SUBKEY:
- {
- PKT_public_key *pk=node->pkt->pkt.public_key;
-
- keyid_from_pk(pk,NULL);
-
- fprintf(spawn->tochild,"%sb:%08lX%08lX:%u:%u:%u:%u:",
- node->pkt->pkttype==PKT_PUBLIC_KEY?"pu":"su",
- (ulong)pk->keyid[0],(ulong)pk->keyid[1],
- pk->pubkey_algo,
- nbits_from_pk(pk),
- pk->timestamp,
- pk->expiredate);
-
- if(pk->is_revoked)
- fprintf(spawn->tochild,"r");
- if(pk->has_expired)
- fprintf(spawn->tochild,"e");
-
- fprintf(spawn->tochild,"\n");
-
- break;
- }
-
- case PKT_USER_ID:
- {
- PKT_user_id *uid=node->pkt->pkt.user_id;
- int r;
-
- if(uid->attrib_data)
- continue;
-
- fprintf(spawn->tochild,"uid:");
-
- /* Quote ':', '%', and any 8-bit
- characters */
- for(r=0;r<uid->len;r++)
- {
- if(uid->name[r]==':' || uid->name[r]=='%'
- || uid->name[r]&0x80)
- fprintf(spawn->tochild,"%%%02X",uid->name[r]);
- else
- fprintf(spawn->tochild,"%c",uid->name[r]);
- }
-
- fprintf(spawn->tochild,":%u:%u:",
- uid->created,uid->expiredate);
-
- if(uid->is_revoked)
- fprintf(spawn->tochild,"r");
- if(uid->is_expired)
- fprintf(spawn->tochild,"e");
-
- fprintf(spawn->tochild,"\n");
- }
- }
- }
-
- fprintf(spawn->tochild,"INFO %s END\n",key->d);
-
- fprintf(spawn->tochild,"KEY %s BEGIN\n",key->d);
- fwrite(iobuf_get_temp_buffer(buffer),
- iobuf_get_temp_length(buffer),1,spawn->tochild);
- fprintf(spawn->tochild,"KEY %s END\n",key->d);
-
- iobuf_close(buffer);
- release_kbnode(block);
- }
-
- free_strlist(temp);
- }
-
- break;
- }
-
- case SEARCH:
- {
- STRLIST key;
-
- fprintf(spawn->tochild,"COMMAND SEARCH\n\n");
-
- /* Which keys do we want? Remember that the gpgkeys_ program
- is going to lump these together into a search string. */
-
- for(key=list;key!=NULL;key=key->next)
- {
- fprintf(spawn->tochild,"%s\n",key->d);
- if(key!=list)
- {
- searchstr=xrealloc(searchstr,
- strlen(searchstr)+strlen(key->d)+2);
- strcat(searchstr," ");
- }
- else
- {
- searchstr=xmalloc (strlen(key->d)+1);
- searchstr[0]='\0';
- }
-
- strcat(searchstr,key->d);
- }
-
- fprintf(spawn->tochild,"\n");
-
- break;
- }
-
- default:
- log_fatal(_("no keyserver action!\n"));
- break;
- }
-
- /* Done sending, so start reading. */
- ret=exec_read(spawn);
- if(ret)
- goto fail;
-
- /* Now handle the response */
-
- for(;;)
- {
- int plen;
- char *ptr;
-
- maxlen=1024;
- if(iobuf_read_line(spawn->fromchild,&line,&buflen,&maxlen)==0)
- {
- ret = iobuf_error (spawn->fromchild);
- goto fail; /* i.e. EOF */
- }
-
- ptr=line;
-
- /* remove trailing whitespace */
- plen=strlen(ptr);
- while(plen>0 && ascii_isspace(ptr[plen-1]))
- plen--;
- plen[ptr]='\0';
-
- if(*ptr=='\0')
- break;
-
- if(ascii_strncasecmp(ptr,"VERSION ",8)==0)
- {
- gotversion=1;
-
- if(atoi(&ptr[8])!=KEYSERVER_PROTO_VERSION)
- {
- log_error(_("invalid keyserver protocol (us %d!=handler %d)\n"),
- KEYSERVER_PROTO_VERSION,atoi(&ptr[8]));
- goto fail;
- }
- }
- else if(ascii_strncasecmp(ptr,"PROGRAM ",8)==0)
- {
- if(ascii_strncasecmp(&ptr[8],VERSION,strlen(VERSION))!=0)
- log_info(_("WARNING: keyserver handler from a different "
- "version of GnuPG (%s)\n"),&ptr[8]);
- }
- else if(ascii_strncasecmp(ptr,"OPTION OUTOFBAND",16)==0)
- outofband=1; /* Currently the only OPTION */
- }
-
- if(!gotversion)
- {
- log_error(_("keyserver did not send VERSION\n"));
- goto fail;
- }
-
- if(!outofband)
- switch(action)
- {
- case GET:
- {
- void *stats_handle;
-
- stats_handle=import_new_stats_handle();
-
- /* Slurp up all the key data. In the future, it might be
- nice to look for KEY foo OUTOFBAND and FAILED indicators.
- It's harmless to ignore them, but ignoring them does make
- gpg complain about "no valid OpenPGP data found". One
- way to do this could be to continue parsing this
- line-by-line and make a temp iobuf for each key. */
-
- import_keys_stream(spawn->fromchild,stats_handle,
- opt.keyserver_options.import_options);
-
- import_print_stats(stats_handle);
- import_release_stats_handle(stats_handle);
-
- break;
- }
-
- /* Nothing to do here */
- case SEND:
- break;
-
- case SEARCH:
- {
- keyserver_search_prompt(spawn->fromchild,searchstr);
-
- break;
- }
-
- default:
- log_fatal(_("no keyserver action!\n"));
- break;
- }
-
- fail:
- xfree (line);
-
- *prog=exec_finish(spawn);
-
- return ret;
-}
-
-static int
-keyserver_work(int action,STRLIST list,KEYDB_SEARCH_DESC *desc,int count)
-{
- int rc=0,ret=0;
-
- if(opt.keyserver_scheme==NULL)
- {
- log_error(_("no keyserver known (use option --keyserver)\n"));
- return GPG_ERR_BAD_URI;
- }
-
-#ifdef DISABLE_KEYSERVER_HELPERS
-
- log_error(_("external keyserver calls are not supported in this build\n"));
- return GPG_ERR_KEYSERVER;
-
-#else
- /* Spawn a handler */
-
- rc=keyserver_spawn(action,list,desc,count,&ret);
- if(ret)
- {
- switch(ret)
- {
- case KEYSERVER_SCHEME_NOT_FOUND:
- log_error(_("no handler for keyserver scheme \"%s\"\n"),
- opt.keyserver_scheme);
- break;
-
- case KEYSERVER_NOT_SUPPORTED:
- log_error(_("action \"%s\" not supported with keyserver "
- "scheme \"%s\"\n"),
- action==GET?"get":action==SEND?"send":
- action==SEARCH?"search":"unknown",
- opt.keyserver_scheme);
- break;
-
- case KEYSERVER_VERSION_ERROR:
- log_error(_("gpgkeys_%s does not support handler version %d\n"),
- opt.keyserver_scheme,KEYSERVER_PROTO_VERSION);
- break;
-
- case KEYSERVER_INTERNAL_ERROR:
- default:
- log_error(_("keyserver internal error\n"));
- break;
- }
-
- return GPG_ERR_KEYSERVER;
- }
-
- if(rc)
- {
- log_error(_("keyserver communications error: %s\n"),gpg_strerror (rc));
-
- return rc;
- }
-
- return 0;
-#endif /* ! DISABLE_KEYSERVER_HELPERS*/
-}
-
-int
-keyserver_export(STRLIST users)
-{
- /* We better ask for confirmation when the user entered --send-keys
- without arguments. Sending all keys might not be the thing he
- intended to do */
- if (users || opt.batch || opt.answer_yes)
- ;
- else if ( !cpr_get_answer_is_yes
- ("keyserver_export.send_all",
- _("Do you really want to send all your "
- "public keys to the keyserver? (y/N) ")))
- return -1;
-
- return keyserver_work(SEND,users,NULL,0);
-}
-
-int
-keyserver_import(STRLIST users)
-{
- KEYDB_SEARCH_DESC *desc;
- int num=100,count=0;
- int rc=0;
-
- /* Build a list of key ids */
- desc=xmalloc (sizeof(KEYDB_SEARCH_DESC)*num);
-
- for(;users;users=users->next)
- {
- classify_user_id (users->d, &desc[count]);
- if(desc[count].mode!=KEYDB_SEARCH_MODE_SHORT_KID &&
- desc[count].mode!=KEYDB_SEARCH_MODE_LONG_KID &&
- desc[count].mode!=KEYDB_SEARCH_MODE_FPR16 &&
- desc[count].mode!=KEYDB_SEARCH_MODE_FPR20)
- {
- log_error(_("skipping invalid key ID \"%s\"\n"),users->d);
- continue;
- }
-
- count++;
- if(count==num)
- {
- num+=100;
- desc=xrealloc(desc,sizeof(KEYDB_SEARCH_DESC)*num);
- }
- }
-
- if(count>0)
- rc=keyserver_work(GET,NULL,desc,count);
-
- xfree (desc);
-
- return rc;
-}
-
-int
-keyserver_import_fprint(const byte *fprint,size_t fprint_len)
-{
- KEYDB_SEARCH_DESC desc;
-
- memset(&desc,0,sizeof(desc));
-
- if(fprint_len==16)
- desc.mode=KEYDB_SEARCH_MODE_FPR16;
- else if(fprint_len==20)
- desc.mode=KEYDB_SEARCH_MODE_FPR20;
- else
- return -1;
-
- memcpy(desc.u.fpr,fprint,fprint_len);
-
- return keyserver_work(GET,NULL,&desc,1);
-}
-
-int
-keyserver_import_keyid(u32 *keyid)
-{
- KEYDB_SEARCH_DESC desc;
-
- memset(&desc,0,sizeof(desc));
-
- desc.mode=KEYDB_SEARCH_MODE_LONG_KID;
- desc.u.kid[0]=keyid[0];
- desc.u.kid[1]=keyid[1];
-
- return keyserver_work(GET,NULL,&desc,1);
-}
-
-/* code mostly stolen from do_export_stream */
-static int
-keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
-{
- int rc=0,ndesc,num=100;
- KBNODE keyblock=NULL,node;
- KEYDB_HANDLE kdbhd;
- KEYDB_SEARCH_DESC *desc;
- STRLIST sl;
-
- *count=0;
-
- *klist=xmalloc (sizeof(KEYDB_SEARCH_DESC)*num);
-
- kdbhd=keydb_new(0);
-
- if(!users)
- {
- ndesc = 1;
- desc = xcalloc (1, ndesc * sizeof *desc);
- desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
- }
- else
- {
- for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++)
- ;
- desc = xmalloc ( ndesc * sizeof *desc);
-
- for (ndesc=0, sl=users; sl; sl = sl->next)
- {
- if(classify_user_id (sl->d, desc+ndesc))
- ndesc++;
- else
- log_error (_("key `%s' not found: %s\n"),
- sl->d, gpg_strerror (GPG_ERR_INV_USER_ID));
- }
- }
-
- while (!(rc = keydb_search (kdbhd, desc, ndesc)))
- {
- if (!users)
- desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
-
- /* read the keyblock */
- rc = keydb_get_keyblock (kdbhd, &keyblock );
- if( rc )
- {
- log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) );
- goto leave;
- }
-
- if((node=find_kbnode(keyblock,PKT_PUBLIC_KEY)))
- {
- /* This is to work around a bug in some keyservers (pksd and
- OKS) that calculate v4 RSA keyids as if they were v3 RSA.
- The answer is to refresh both the correct v4 keyid
- (e.g. 99242560) and the fake v3 keyid (e.g. 68FDDBC7).
- This only happens for key refresh using the HKP scheme
- and if the refresh-add-fake-v3-keyids keyserver option is
- set. */
- if(fakev3 && is_RSA(node->pkt->pkt.public_key->pubkey_algo) &&
- node->pkt->pkt.public_key->version>=4)
- {
- (*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID;
- v3_keyid (node->pkt->pkt.public_key->pkey[0],
- (*klist)[*count].u.kid);
- (*count)++;
-
- if(*count==num)
- {
- num+=100;
- *klist=xrealloc(*klist,sizeof(KEYDB_SEARCH_DESC)*num);
- }
- }
-
- /* v4 keys get full fingerprints. v3 keys get long keyids.
- This is because it's easy to calculate any sort of key id
- from a v4 fingerprint, but not a v3 fingerprint. */
-
- if(node->pkt->pkt.public_key->version<4)
- {
- (*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID;
- keyid_from_pk(node->pkt->pkt.public_key,
- (*klist)[*count].u.kid);
- }
- else
- {
- size_t dummy;
-
- (*klist)[*count].mode=KEYDB_SEARCH_MODE_FPR20;
- fingerprint_from_pk(node->pkt->pkt.public_key,
- (*klist)[*count].u.fpr,&dummy);
- }
-
- (*count)++;
-
- if(*count==num)
- {
- num+=100;
- *klist=xrealloc(*klist,sizeof(KEYDB_SEARCH_DESC)*num);
- }
- }
- }
-
- if(rc==-1)
- rc=0;
-
- leave:
- xfree (desc);
- keydb_release(kdbhd);
- release_kbnode(keyblock);
-
- return rc;
-}
-
-/* Note this is different than the original HKP refresh. It allows
- usernames to refresh only part of the keyring. */
-
-int
-keyserver_refresh(STRLIST users)
-{
- int rc,count,fakev3=0;
- KEYDB_SEARCH_DESC *desc;
-
- /* We switch merge_only on during a refresh, as 'refresh' should
- never import new keys, even if their keyids match. Is it worth
- preserving the old merge_only value here? */
- opt.merge_only=1;
-
- /* If refresh_add_fake_v3_keyids is on and it's a HKP or MAILTO
- scheme, then enable fake v3 keyid generation. */
- if(opt.keyserver_options.fake_v3_keyids && opt.keyserver_scheme &&
- (ascii_strcasecmp(opt.keyserver_scheme,"hkp")==0 ||
- ascii_strcasecmp(opt.keyserver_scheme,"mailto")==0))
- fakev3=1;
-
- rc=keyidlist(users,&desc,&count,fakev3);
- if(rc)
- return rc;
-
- if(count>0)
- {
- if(opt.keyserver_uri)
- {
- if(count==1)
- log_info(_("refreshing 1 key from %s\n"),opt.keyserver_uri);
- else
- log_info(_("refreshing %d keys from %s\n"),
- count,opt.keyserver_uri);
- }
-
- rc=keyserver_work(GET,NULL,desc,count);
- }
-
- xfree (desc);
-
- return rc;
-}
-
-int
-keyserver_search(STRLIST tokens)
-{
- if(tokens)
- return keyserver_work(SEARCH,tokens,NULL,0);
- else
- return 0;
-}
diff --git a/g10/main.h b/g10/main.h
deleted file mode 100644
index 52bfa7659..000000000
--- a/g10/main.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/* main.h
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef G10_MAIN_H
-#define G10_MAIN_H
-#include "types.h"
-#include "gpg.h"
-#include "../common/iobuf.h"
-#include "mpi.h"
-#include "cipher.h"
-#include "keydb.h"
-
-/* It could be argued that the default cipher should be 3DES rather
- than CAST5, and the default compression should be 0
- (i.e. uncompressed) rather than 1 (zip). */
-#define DEFAULT_CIPHER_ALGO CIPHER_ALGO_CAST5
-#define DEFAULT_DIGEST_ALGO DIGEST_ALGO_SHA1
-#define DEFAULT_COMPRESS_ALGO 1
-
-typedef struct {
- int header_okay;
- PK_LIST pk_list;
- cipher_filter_context_t cfx;
-} encrypt_filter_context_t;
-
-struct groupitem
-{
- char *name;
- STRLIST values;
- struct groupitem *next;
-};
-
-/*-- g10.c --*/
-extern int g10_errors_seen;
-
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
- void g10_exit(int rc) __attribute__ ((noreturn));
-#else
- void g10_exit(int rc);
-#endif
-void print_pubkey_algo_note( int algo );
-void print_cipher_algo_note( int algo );
-void print_digest_algo_note( int algo );
-
-/*-- armor.c --*/
-char *make_radix64_string( const byte *data, size_t len );
-
-/*-- misc.c --*/
-void trap_unaligned(void);
-int disable_core_dumps(void);
-u16 checksum_u16( unsigned n );
-u16 checksum( byte *p, unsigned n );
-u16 checksum_mpi( gcry_mpi_t a );
-u32 buffer_to_u32( const byte *buffer );
-const byte *get_session_marker( size_t *rlen );
-int openpgp_cipher_test_algo( int algo );
-int openpgp_pk_test_algo( int algo, unsigned int usage_flags );
-int openpgp_pk_algo_usage ( int algo );
-int openpgp_md_test_algo( int algo );
-int openpgp_md_map_name (const char *string);
-int openpgp_cipher_map_name (const char *string);
-int openpgp_pk_map_name (const char *string);
-
-#ifdef USE_IDEA
-void idea_cipher_warn( int show );
-#else
-#define idea_cipher_warn(a)
-#endif
-
-struct expando_args
-{
- PKT_public_key *pk;
- PKT_secret_key *sk;
- byte imagetype;
-};
-
-char *pct_expando(const char *string,struct expando_args *args);
-int hextobyte( const char *s );
-void deprecated_warning(const char *configname,unsigned int configlineno,
- const char *option,const char *repl1,const char *repl2);
-const char *compress_algo_to_string(int algo);
-int string_to_compress_algo(const char *string);
-int check_compress_algo(int algo);
-int default_cipher_algo(void);
-int default_compress_algo(void);
-const char *compliance_option_string(void);
-void compliance_failure(void);
-
-struct parse_options
-{
- char *name;
- unsigned int bit;
-};
-
-int parse_options(char *str,unsigned int *options,struct parse_options *opts);
-
-
-/* Temporary helpers. */
-int pubkey_get_npkey( int algo );
-int pubkey_get_nskey( int algo );
-int pubkey_get_nsig( int algo );
-int pubkey_get_nenc( int algo );
-unsigned int pubkey_nbits( int algo, gcry_mpi_t *pkey );
-
-/* MPI helpers. */
-int mpi_write( iobuf_t out, gcry_mpi_t a );
-int mpi_write_opaque( iobuf_t out, gcry_mpi_t a );
-gcry_mpi_t mpi_read(iobuf_t inp, unsigned int *ret_nread, int secure );
-gcry_mpi_t mpi_read_opaque(iobuf_t inp, unsigned int *ret_nread );
-int mpi_print( FILE *fp, gcry_mpi_t a, int mode );
-
-
-
-
-/*-- helptext.c --*/
-void display_online_help( const char *keyword );
-
-/*-- encode.c --*/
-int encode_symmetric( const char *filename );
-int encode_store( const char *filename );
-int encode_crypt( const char *filename, STRLIST remusr );
-void encode_crypt_files(int nfiles, char **files, STRLIST remusr);
-int encrypt_filter( void *opaque, int control,
- iobuf_t a, byte *buf, size_t *ret_len);
-
-
-/*-- sign.c --*/
-int complete_sig( PKT_signature *sig, PKT_secret_key *sk, MD_HANDLE md );
-int sign_file( STRLIST filenames, int detached, STRLIST locusr,
- int do_encrypt, STRLIST remusr, const char *outfile );
-int clearsign_file( const char *fname, STRLIST locusr, const char *outfile );
-int sign_symencrypt_file (const char *fname, STRLIST locusr);
-
-/*-- sig-check.c --*/
-int check_revocation_keys (PKT_public_key *pk, PKT_signature *sig);
-int check_key_signature( KBNODE root, KBNODE node, int *is_selfsig );
-int check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
- PKT_public_key *ret_pk, int *is_selfsig,
- u32 *r_expiredate, int *r_expired );
-
-/*-- delkey.c --*/
-int delete_keys( STRLIST names, int secret, int allow_both );
-
-/*-- keyedit.c --*/
-void keyedit_menu( const char *username, STRLIST locusr, STRLIST cmds,
- int sign_mode );
-void show_basic_key_info (KBNODE keyblock);
-
-/*-- keygen.c --*/
-u32 ask_expire_interval(int object);
-u32 ask_expiredate(void);
-void generate_keypair( const char *fname, const char *card_serialno );
-int keygen_set_std_prefs (const char *string,int personal);
-PKT_user_id *keygen_get_std_prefs (void);
-int keygen_add_key_expire( PKT_signature *sig, void *opaque );
-int keygen_add_std_prefs( PKT_signature *sig, void *opaque );
-int keygen_upd_std_prefs( PKT_signature *sig, void *opaque );
-int keygen_add_keyserver_url(PKT_signature *sig, void *opaque);
-int keygen_add_revkey(PKT_signature *sig, void *opaque);
-int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
-
-/*-- openfile.c --*/
-int overwrite_filep( const char *fname );
-char *make_outfile_name( const char *iname );
-char *ask_outfile_name( const char *name, size_t namelen );
-int open_outfile( const char *iname, int mode, iobuf_t *a );
-iobuf_t open_sigfile( const char *iname, progress_filter_context_t *pfx );
-void try_make_homedir( const char *fname );
-
-/*-- seskey.c --*/
-void make_session_key( DEK *dek );
-gcry_mpi_t encode_session_key( DEK *dek, unsigned int nbits);
-gcry_mpi_t encode_md_value( int pubkey_algo, MD_HANDLE md,
- int hash_algo, unsigned nbits, int v3compathack );
-
-/*-- comment.c --*/
-KBNODE make_comment_node_from_buffer (const char *s, size_t n);
-KBNODE make_comment_node( const char *s );
-KBNODE make_mpi_comment_node( const char *s, gcry_mpi_t a );
-
-/*-- import.c --*/
-int parse_import_options(char *str,unsigned int *options);
-void import_keys( char **fnames, int nnames,
- void *stats_hd, unsigned int options );
-int import_keys_stream( iobuf_t inp,
- void *stats_hd, unsigned int options );
-void *import_new_stats_handle (void);
-void import_release_stats_handle (void *p);
-void import_print_stats (void *hd);
-
-int collapse_uids( KBNODE *keyblock );
-
-/*-- export.c --*/
-int parse_export_options(char *str,unsigned int *options);
-int export_pubkeys( STRLIST users, unsigned int options );
-int export_pubkeys_stream( iobuf_t out, STRLIST users,
- KBNODE *keyblock_out, unsigned int options );
-int export_seckeys( STRLIST users );
-int export_secsubkeys( STRLIST users );
-
-/* dearmor.c --*/
-int dearmor_file( const char *fname );
-int enarmor_file( const char *fname );
-
-/*-- revoke.c --*/
-struct revocation_reason_info;
-int gen_revoke( const char *uname );
-int gen_desig_revoke( const char *uname );
-int revocation_reason_build_cb( PKT_signature *sig, void *opaque );
-struct revocation_reason_info *
- ask_revocation_reason( int key_rev, int cert_rev, int hint );
-void release_revocation_reason_info( struct revocation_reason_info *reason );
-
-/*-- keylist.c --*/
-void public_key_list( STRLIST list );
-void secret_key_list( STRLIST list );
-void reorder_keyblock (KBNODE keyblock);
-void list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque );
-void print_fingerprint (PKT_public_key *pk, PKT_secret_key *sk, int mode);
-void show_policy_url(PKT_signature *sig,int indent,int mode);
-void show_keyserver_url(PKT_signature *sig,int indent,int mode);
-void show_notation(PKT_signature *sig,int indent,int mode);
-void dump_attribs(const PKT_user_id *uid,
- PKT_public_key *pk,PKT_secret_key *sk);
-void set_attrib_fd(int fd);
-void print_seckey_info (PKT_secret_key *sk);
-void print_pubkey_info (FILE *fp, PKT_public_key *pk);
-
-/*-- verify.c --*/
-void print_file_status( int status, const char *name, int what );
-int verify_signatures( int nfiles, char **files );
-int verify_files( int nfiles, char **files );
-
-/*-- decrypt.c --*/
-int decrypt_message( const char *filename );
-void decrypt_messages(int nfiles, char **files);
-
-/*-- plaintext.c --*/
-int hash_datafiles( MD_HANDLE md, MD_HANDLE md2,
- STRLIST files, const char *sigfilename, int textmode );
-
-/*-- pipemode.c --*/
-void run_in_pipemode (void);
-
-/*-- card-util.c --*/
-void change_pin (int no);
-void card_status (FILE *fp, char *serialnobuf, size_t serialnobuflen);
-void card_edit (STRLIST commands);
-
-/*-- signal.c --*/
-void init_signals(void);
-void pause_on_sigusr( int which );
-void block_all_signals(void);
-void unblock_all_signals(void);
-
-#endif /*G10_MAIN_H*/
diff --git a/g10/mainproc.c b/g10/mainproc.c
deleted file mode 100644
index 40b9bd20a..000000000
--- a/g10/mainproc.c
+++ /dev/null
@@ -1,1758 +0,0 @@
-/* mainproc.c - handle packets
- * Copyright (C) 1998,1999,2000,2001,2002,2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <time.h>
-
-#include "packet.h"
-#include "iobuf.h"
-#include "memory.h"
-#include "options.h"
-#include "util.h"
-#include "cipher.h"
-#include "keydb.h"
-#include "filter.h"
-#include "main.h"
-#include "status.h"
-#include "i18n.h"
-#include "trustdb.h"
-#include "keyserver-internal.h"
-#include "photoid.h"
-
-
-struct kidlist_item {
- struct kidlist_item *next;
- u32 kid[2];
- int pubkey_algo;
- int reason;
-};
-
-
-
-/****************
- * Structure to hold the context
- */
-typedef struct mainproc_context *CTX;
-struct mainproc_context {
- struct mainproc_context *anchor; /* may be useful in the future */
- PKT_public_key *last_pubkey;
- PKT_secret_key *last_seckey;
- PKT_user_id *last_user_id;
- md_filter_context_t mfx;
- int sigs_only; /* process only signatures and reject all other stuff */
- int encrypt_only; /* process only encrytion messages */
- STRLIST signed_data;
- const char *sigfilename;
- DEK *dek;
- int last_was_session_key;
- KBNODE list; /* the current list of packets */
- int have_data;
- iobuf_t iobuf; /* used to get the filename etc. */
- int trustletter; /* temp usage in list_node */
- ulong local_id; /* ditto */
- struct kidlist_item *pkenc_list; /* list of encryption packets */
- struct {
- int op;
- int stop_now;
- } pipemode;
-};
-
-
-static int do_proc_packets( CTX c, iobuf_t a );
-
-static void list_node( CTX c, KBNODE node );
-static void proc_tree( CTX c, KBNODE node );
-
-
-static void
-release_list( CTX c )
-{
- if( !c->list )
- return;
- proc_tree(c, c->list );
- release_kbnode( c->list );
- while( c->pkenc_list ) {
- struct kidlist_item *tmp = c->pkenc_list->next;
- xfree ( c->pkenc_list );
- c->pkenc_list = tmp;
- }
- c->pkenc_list = NULL;
- c->list = NULL;
- c->have_data = 0;
- c->last_was_session_key = 0;
- c->pipemode.op = 0;
- c->pipemode.stop_now = 0;
- xfree (c->dek); c->dek = NULL;
-}
-
-
-static int
-add_onepass_sig( CTX c, PACKET *pkt )
-{
- KBNODE node;
-
- if( c->list ) { /* add another packet */
- /* We can only append another onepass packet if the list
- * does contain only onepass packets */
- for( node=c->list; node && node->pkt->pkttype == PKT_ONEPASS_SIG;
- node = node->next )
- ;
- if( node ) {
- /* this is not the case, so we flush the current thing and
- * allow this packet to start a new verification thing */
- release_list( c );
- c->list = new_kbnode( pkt );
- }
- else
- add_kbnode( c->list, new_kbnode( pkt ));
- }
- else /* insert the first one */
- c->list = node = new_kbnode( pkt );
-
- return 1;
-}
-
-
-static int
-add_gpg_control( CTX c, PACKET *pkt )
-{
- if ( pkt->pkt.gpg_control->control == CTRLPKT_CLEARSIGN_START ) {
- /* New clear text signature.
- * Process the last one and reset everything */
- release_list(c);
- }
- else if ( pkt->pkt.gpg_control->control == CTRLPKT_PIPEMODE ) {
- /* Pipemode control packet */
- if ( pkt->pkt.gpg_control->datalen < 2 )
- log_fatal ("invalid pipemode control packet length\n");
- if (pkt->pkt.gpg_control->data[0] == 1) {
- /* start the whole thing */
- assert ( !c->list ); /* we should be in a pretty virgin state */
- assert ( !c->pipemode.op );
- c->pipemode.op = pkt->pkt.gpg_control->data[1];
- }
- else if (pkt->pkt.gpg_control->data[0] == 2) {
- /* the signed material follows in a plaintext packet */
- assert ( c->pipemode.op == 'B' );
- }
- else if (pkt->pkt.gpg_control->data[0] == 3) {
- assert ( c->pipemode.op == 'B' );
- release_list (c);
- /* and tell the outer loop to terminate */
- c->pipemode.stop_now = 1;
- }
- else
- log_fatal ("invalid pipemode control packet code\n");
- return 0; /* no need to store the packet */
- }
-
- if( c->list ) /* add another packet */
- add_kbnode( c->list, new_kbnode( pkt ));
- else /* insert the first one */
- c->list = new_kbnode( pkt );
-
- return 1;
-}
-
-
-
-static int
-add_user_id( CTX c, PACKET *pkt )
-{
- if( !c->list ) {
- log_error("orphaned user ID\n" );
- return 0;
- }
- add_kbnode( c->list, new_kbnode( pkt ) );
- return 1;
-}
-
-static int
-add_subkey( CTX c, PACKET *pkt )
-{
- if( !c->list ) {
- log_error("subkey w/o mainkey\n" );
- return 0;
- }
- add_kbnode( c->list, new_kbnode( pkt ) );
- return 1;
-}
-
-static int
-add_ring_trust( CTX c, PACKET *pkt )
-{
- if( !c->list ) {
- log_error("ring trust w/o key\n" );
- return 0;
- }
- add_kbnode( c->list, new_kbnode( pkt ) );
- return 1;
-}
-
-
-static int
-add_signature( CTX c, PACKET *pkt )
-{
- KBNODE node;
-
- if( pkt->pkttype == PKT_SIGNATURE && !c->list ) {
- /* This is the first signature for the following datafile.
- * GPG does not write such packets; instead it always uses
- * onepass-sig packets. The drawback of PGP's method
- * of prepending the signature to the data is
- * that it is not possible to make a signature from data read
- * from stdin. (GPG is able to read PGP stuff anyway.) */
- node = new_kbnode( pkt );
- c->list = node;
- return 1;
- }
- else if( !c->list )
- return 0; /* oops (invalid packet sequence)*/
- else if( !c->list->pkt )
- BUG(); /* so nicht */
-
- /* add a new signature node id at the end */
- node = new_kbnode( pkt );
- add_kbnode( c->list, node );
- return 1;
-}
-
-static void
-symkey_decrypt_sesskey (DEK * dek, byte *sesskey, size_t slen)
-{
- CIPHER_HANDLE hd;
- int n;
-
- if (slen < 17 || slen > 33)
- {
- log_error ( _("weird size for an encrypted session key (%d)\n"),
- (int)slen);
- return;
- }
- /* we checked the DEK values before, so consider all errors as fatal */
- if (gcry_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_decrypt (hd, sesskey, slen, NULL, 0);
- gcry_cipher_close (hd);
- /* check first byte (the cipher algo) */
- if (openpgp_cipher_test_algo (sesskey[0]))
- {
- log_error (_("invalid symkey algorithm detected (%d)\n"),
- sesskey[0]);
- return;
- }
- n = gcry_cipher_get_algo_keylen (sesskey[0]);
- if (n > DIM(dek->key))
- BUG ();
- /* now we replace the dek components with the real session key
- to decrypt the contents of the sequencing packet. */
- dek->keylen = n;
- dek->algo = sesskey[0];
- memcpy (dek->key, sesskey + 1, dek->keylen);
- /*log_hexdump ("thekey", dek->key, dek->keylen);*/
-}
-
-static void
-proc_symkey_enc( CTX c, PACKET *pkt )
-{
- PKT_symkey_enc *enc;
-
- enc = pkt->pkt.symkey_enc;
- if (!enc)
- log_error ("invalid symkey encrypted packet\n");
- else {
- int algo = enc->cipher_algo;
- const char *s;
-
- s = gcry_cipher_algo_name (algo);
- if (s && *s)
- log_info(_("%s encrypted data\n"), s );
- else
- log_info(_("encrypted with unknown algorithm %d\n"), algo );
-
- c->last_was_session_key = 2;
- if ( opt.list_only )
- goto leave;
- c->dek = passphrase_to_dek( NULL, 0, algo, &enc->s2k, 0, NULL, NULL );
- if (c->dek)
- c->dek->algo_info_printed = 1;
- if ( c->dek && enc->seskeylen )
- symkey_decrypt_sesskey( c->dek, enc->seskey, enc->seskeylen );
- }
-leave:
- free_packet(pkt);
-}
-
-static void
-proc_pubkey_enc( CTX c, PACKET *pkt )
-{
- PKT_pubkey_enc *enc;
- int result = 0;
-
- /* check whether the secret key is available and store in this case */
- c->last_was_session_key = 1;
- enc = pkt->pkt.pubkey_enc;
- /*printf("enc: encrypted by a pubkey with keyid %08lX\n", enc->keyid[1] );*/
- /* Hmmm: why do I have this algo check here - anyway there is
- * function to check it. */
- if( opt.verbose )
- log_info(_("public key is %08lX\n"), (ulong)enc->keyid[1] );
-
- if( is_status_enabled() ) {
- char buf[50];
- sprintf(buf, "%08lX%08lX %d 0",
- (ulong)enc->keyid[0], (ulong)enc->keyid[1], enc->pubkey_algo );
- write_status_text( STATUS_ENC_TO, buf );
- }
-
- if( !opt.list_only && opt.override_session_key ) {
- /* It does not make much sense to store the session key in
- * secure memory because it has already been passed on the
- * command line and the GCHQ knows about it */
- c->dek = xcalloc (1, sizeof *c->dek );
- result = get_override_session_key ( c->dek, opt.override_session_key );
- if ( result ) {
- xfree (c->dek); c->dek = NULL;
- }
- }
- else if( is_ELGAMAL(enc->pubkey_algo)
- || enc->pubkey_algo == PUBKEY_ALGO_DSA
- || is_RSA(enc->pubkey_algo) ) {
- if ( !c->dek && ((!enc->keyid[0] && !enc->keyid[1])
- || opt.try_all_secrets
- || !seckey_available( enc->keyid )) ) {
- if( opt.list_only )
- result = -1;
- else {
- c->dek = xcalloc_secure (1, sizeof *c->dek);
- if( (result = get_session_key( enc, c->dek )) ) {
- /* error: delete the DEK */
- xfree (c->dek); c->dek = NULL;
- }
- }
- }
- else
- result = GPG_ERR_NO_SECKEY;
- }
- else
- result = GPG_ERR_PUBKEY_ALGO;
-
- if( result == -1 )
- ;
- else {
- if( !result ) {
- if( opt.verbose > 1 )
- log_info( _("public key encrypted data: good DEK\n") );
- if ( opt.show_session_key ) {
- int i;
- char *buf = xmalloc ( c->dek->keylen*2 + 20 );
- sprintf ( buf, "%d:", c->dek->algo );
- for(i=0; i < c->dek->keylen; i++ )
- sprintf(buf+strlen(buf), "%02X", c->dek->key[i] );
- log_info( "session key: \"%s\"\n", buf );
- write_status_text ( STATUS_SESSION_KEY, buf );
- }
- }
- /* store it for later display */
- {
- struct kidlist_item *x = xmalloc ( sizeof *x );
- x->kid[0] = enc->keyid[0];
- x->kid[1] = enc->keyid[1];
- x->pubkey_algo = enc->pubkey_algo;
- x->reason = result;
- x->next = c->pkenc_list;
- c->pkenc_list = x;
- }
- }
- free_packet(pkt);
-}
-
-
-
-/****************
- * Print the list of public key encrypted packets which we could
- * not decrypt.
- */
-static void
-print_pkenc_list( struct kidlist_item *list, int failed )
-{
- for( ; list; list = list->next ) {
- PKT_public_key *pk;
- const char *algstr;
-
- if ( failed && !list->reason )
- continue;
- if ( !failed && list->reason )
- continue;
-
- algstr = gcry_pk_algo_name (list->pubkey_algo);
- pk = xcalloc (1, sizeof *pk );
-
- if (!algstr || !*algstr)
- algstr = "[?]";
- pk->pubkey_algo = list->pubkey_algo;
- if( !get_pubkey( pk, list->kid ) ) {
- size_t n;
- char *p;
- log_info( _("encrypted with %u-bit %s key, ID %08lX, created %s\n"),
- nbits_from_pk( pk ), algstr, (ulong)list->kid[1],
- strtimestamp(pk->timestamp) );
- fputs(" \"", log_get_stream() );
- p = get_user_id( list->kid, &n );
- print_utf8_string2 ( log_get_stream(), p, n, '"' );
- xfree (p);
- fputs("\"\n", log_get_stream() );
- }
- else {
- log_info(_("encrypted with %s key, ID %08lX\n"),
- algstr, (ulong) list->kid[1] );
- }
- free_public_key( pk );
-
- if( gpg_err_code (list->reason) == GPG_ERR_NO_SECKEY ) {
- if( is_status_enabled() ) {
- char buf[20];
- sprintf(buf,"%08lX%08lX", (ulong)list->kid[0],
- (ulong)list->kid[1] );
- write_status_text( STATUS_NO_SECKEY, buf );
- }
- }
- else if (list->reason)
- log_info(_("public key decryption failed: %s\n"),
- gpg_strerror (list->reason));
- }
-}
-
-
-static void
-proc_encrypted( CTX c, PACKET *pkt )
-{
- int result = 0;
-
- if (!opt.quiet) {
- print_pkenc_list ( c->pkenc_list, 1 );
- print_pkenc_list ( c->pkenc_list, 0 );
- }
-
- write_status( STATUS_BEGIN_DECRYPTION );
-
- /*log_debug("dat: %sencrypted data\n", c->dek?"":"conventional ");*/
- if( opt.list_only )
- result = -1;
- else if( !c->dek && !c->last_was_session_key ) {
- int algo;
- STRING2KEY s2kbuf, *s2k = NULL;
-
- /* assume this is old style conventional encrypted data */
- if ( (algo = opt.def_cipher_algo))
- log_info (_("assuming %s encrypted data\n"),
- gcry_cipher_algo_name (algo));
- else if ( gcry_cipher_test_algo(CIPHER_ALGO_IDEA) ) {
- algo = opt.def_cipher_algo;
- if (!algo)
- algo = opt.s2k_cipher_algo;
- idea_cipher_warn(1);
- log_info (_("IDEA cipher unavailable, "
- "optimistically attempting to use %s instead\n"),
- gcry_cipher_algo_name (algo));
- }
- else {
- algo = CIPHER_ALGO_IDEA;
- if (!opt.s2k_digest_algo) {
- /* If no digest is given we assume MD5 */
- s2kbuf.mode = 0;
- s2kbuf.hash_algo = GCRY_MD_MD5;
- s2k = &s2kbuf;
- }
- log_info (_("assuming %s encrypted data\n"), "IDEA");
- }
-
- c->dek = passphrase_to_dek ( NULL, 0, algo, s2k, 0, NULL, NULL );
- if (c->dek)
- c->dek->algo_info_printed = 1;
- }
- else if( !c->dek )
- result = GPG_ERR_NO_SECKEY;
- if( !result )
- result = decrypt_data( c, pkt->pkt.encrypted, c->dek );
-
- xfree (c->dek); c->dek = NULL;
- if( result == -1 )
- ;
- else if( !result || (gpg_err_code (result)==GPG_ERR_BAD_SIGNATURE
- && opt.ignore_mdc_error)) {
- write_status( STATUS_DECRYPTION_OKAY );
- if( opt.verbose > 1 )
- log_info(_("decryption okay\n"));
- if( pkt->pkt.encrypted->mdc_method && !result )
- write_status( STATUS_GOODMDC );
- else if(!opt.no_mdc_warn)
- log_info (_("WARNING: message was not integrity protected\n"));
- }
- else if( gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE ) {
- log_error(_("WARNING: encrypted message has been manipulated!\n"));
- write_status( STATUS_BADMDC );
- write_status( STATUS_DECRYPTION_FAILED );
- }
- else {
- write_status( STATUS_DECRYPTION_FAILED );
- log_error(_("decryption failed: %s\n"), gpg_strerror (result));
- /* Hmmm: does this work when we have encrypted using multiple
- * ways to specify the session key (symmmetric and PK)*/
- }
- free_packet(pkt);
- c->last_was_session_key = 0;
- write_status( STATUS_END_DECRYPTION );
-}
-
-
-
-static void
-proc_plaintext( CTX c, PACKET *pkt )
-{
- PKT_plaintext *pt = pkt->pkt.plaintext;
- int any, clearsig, only_md5, rc;
- KBNODE n;
-
- if( pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8 ) )
- log_info(_("NOTE: sender requested \"for-your-eyes-only\"\n"));
- else if( opt.verbose )
- log_info(_("original file name='%.*s'\n"), pt->namelen, pt->name);
- free_md_filter_context( &c->mfx );
- gcry_md_open (&c->mfx.md, 0, 0);
- /* fixme: we may need to push the textfilter if we have sigclass 1
- * and no armoring - Not yet tested
- * Hmmm, why don't we need it at all if we have sigclass 1
- * Should we assume that plaintext in mode 't' has always sigclass 1??
- * See: Russ Allbery's mail 1999-02-09
- */
- any = clearsig = only_md5 = 0;
- for(n=c->list; n; n = n->next ) {
- if( n->pkt->pkttype == PKT_ONEPASS_SIG ) {
- if( n->pkt->pkt.onepass_sig->digest_algo ) {
- gcry_md_enable ( c->mfx.md, n->pkt->pkt.onepass_sig->digest_algo );
- if( !any && n->pkt->pkt.onepass_sig->digest_algo
- == DIGEST_ALGO_MD5 )
- only_md5 = 1;
- else
- only_md5 = 0;
- any = 1;
- }
- if( n->pkt->pkt.onepass_sig->sig_class != 0x01 )
- only_md5 = 0;
- }
- else if( n->pkt->pkttype == PKT_GPG_CONTROL
- && n->pkt->pkt.gpg_control->control
- == CTRLPKT_CLEARSIGN_START ) {
- size_t datalen = n->pkt->pkt.gpg_control->datalen;
- const byte *data = n->pkt->pkt.gpg_control->data;
-
- /* check that we have at least the sigclass and one hash */
- if ( datalen < 2 )
- log_fatal("invalid control packet CTRLPKT_CLEARSIGN_START\n");
- /* Note that we don't set the clearsig flag for not-dash-escaped
- * documents */
- clearsig = (*data == 0x01);
- for( data++, datalen--; datalen; datalen--, data++ )
- gcry_md_enable ( c->mfx.md, *data );
- any = 1;
- break; /* no pass signature pakets are expected */
- }
- }
-
- if( !any && !opt.skip_verify ) {
- /* no onepass sig packet: enable all standard algos */
- gcry_md_enable ( c->mfx.md, DIGEST_ALGO_RMD160 );
- gcry_md_enable ( c->mfx.md, DIGEST_ALGO_SHA1 );
- gcry_md_enable ( c->mfx.md, DIGEST_ALGO_MD5 );
- }
- if( opt.pgp2_workarounds && only_md5 && !opt.skip_verify ) {
- /* This is a kludge to work around a bug in pgp2. It does only
- * catch those mails which are armored. To catch the non-armored
- * pgp mails we could see whether there is the signature packet
- * in front of the plaintext. If someone needs this, send me a patch.
- */
- gcry_md_open (&c->mfx.md2, DIGEST_ALGO_MD5, 0);
- }
- if ( DBG_HASHING ) {
- gcry_md_start_debug ( c->mfx.md, "verify" );
- if ( c->mfx.md2 )
- gcry_md_start_debug ( c->mfx.md2, "verify2" );
- }
- if ( c->pipemode.op == 'B' )
- rc = handle_plaintext( pt, &c->mfx, 1, 0, NULL );
- else {
- int failed;
-
- rc = handle_plaintext( pt, &c->mfx, c->sigs_only, clearsig, &failed);
- if( rc && failed && !c->sigs_only) {
- /* can't write output but we hash it anyway to
- * check the signature */
- rc = handle_plaintext( pt, &c->mfx, 1, clearsig, NULL );
- }
- }
- if( rc )
- log_error( "handle plaintext failed: %s\n", gpg_strerror (rc));
- free_packet(pkt);
- c->last_was_session_key = 0;
-
- /* We add a marker control packet instead of the plaintext packet.
- * This is so that we can later detect invalid packet sequences.
- */
- n = new_kbnode (create_gpg_control (CTRLPKT_PLAINTEXT_MARK, NULL, 0));
- if (c->list)
- add_kbnode (c->list, n);
- else
- c->list = n;
-}
-
-
-static int
-proc_compressed_cb( iobuf_t a, void *info )
-{
- return proc_signature_packets( info, a, ((CTX)info)->signed_data,
- ((CTX)info)->sigfilename );
-}
-
-static int
-proc_encrypt_cb( iobuf_t a, void *info )
-{
- return proc_encryption_packets( info, a );
-}
-
-static void
-proc_compressed( CTX c, PACKET *pkt )
-{
- PKT_compressed *zd = pkt->pkt.compressed;
- int rc;
-
- /*printf("zip: compressed data packet\n");*/
- if( c->sigs_only )
- rc = handle_compressed( c, zd, proc_compressed_cb, c );
- else if( c->encrypt_only )
- rc = handle_compressed( c, zd, proc_encrypt_cb, c );
- else
- rc = handle_compressed( c, zd, NULL, NULL );
- if( rc )
- log_error("uncompressing failed: %s\n", gpg_strerror (rc));
- free_packet(pkt);
- c->last_was_session_key = 0;
-}
-
-/****************
- * check the signature
- * Returns: 0 = valid signature or an error code
- */
-static int
-do_check_sig( CTX c, KBNODE node, int *is_selfsig,
- int *is_expkey, int *is_revkey )
-{
- PKT_signature *sig;
- MD_HANDLE md = NULL, md2 = NULL;
- int algo, rc;
-
- assert( node->pkt->pkttype == PKT_SIGNATURE );
- if( is_selfsig )
- *is_selfsig = 0;
- sig = node->pkt->pkt.signature;
-
- algo = sig->digest_algo;
- if( (rc = gcry_md_test_algo(algo)) )
- return rc;
-
- if( sig->sig_class == 0x00 ) {
- if( c->mfx.md )
- gcry_md_copy (&md,c->mfx.md);
- else /* detached signature */
- gcry_md_open (&md, 0, 0 ); /* signature_check() will
- enable the md*/
- }
- else if( sig->sig_class == 0x01 ) {
- /* how do we know that we have to hash the (already hashed) text
- * in canonical mode ??? (calculating both modes???) */
- if( c->mfx.md ) {
- gcry_md_copy (&md, c->mfx.md);
- if (c->mfx.md2)
- gcry_md_copy (&md2, c->mfx.md2);
- }
- else { /* detached signature */
- log_debug("Do we really need this here?");
- gcry_md_open (&md, 0, 0 ); /* signature_check() will
- enable the md*/
- gcry_md_open (&md2, 0, 0 );
- }
- }
- else if( (sig->sig_class&~3) == 0x10
- || sig->sig_class == 0x18
- || sig->sig_class == 0x1f
- || sig->sig_class == 0x20
- || sig->sig_class == 0x28
- || sig->sig_class == 0x30 ) {
- if( c->list->pkt->pkttype == PKT_PUBLIC_KEY
- || c->list->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- return check_key_signature( c->list, node, is_selfsig );
- }
- else if( sig->sig_class == 0x20 ) {
- log_info(_("standalone revocation - "
- "use \"gpg --import\" to apply\n"));
- return GPG_ERR_NOT_PROCESSED;
- }
- else {
- log_error("invalid root packet for sigclass %02x\n",
- sig->sig_class);
- return GPG_ERR_SIG_CLASS;
- }
- }
- else
- return GPG_ERR_SIG_CLASS;
- rc = signature_check2( sig, md, NULL, is_expkey, is_revkey, NULL );
- if( gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE && md2 )
- rc = signature_check2( sig, md2, NULL, is_expkey, is_revkey, NULL );
- gcry_md_close (md);
- gcry_md_close (md2);
-
- return rc;
-}
-
-
-static void
-print_userid( PACKET *pkt )
-{
- if( !pkt )
- BUG();
- if( pkt->pkttype != PKT_USER_ID ) {
- printf("ERROR: unexpected packet type %d", pkt->pkttype );
- return;
- }
- if( opt.with_colons )
- {
- if(pkt->pkt.user_id->attrib_data)
- printf("%u %lu",
- pkt->pkt.user_id->numattribs,
- pkt->pkt.user_id->attrib_len);
- else
- print_string( stdout, pkt->pkt.user_id->name,
- pkt->pkt.user_id->len, ':');
- }
- else
- print_utf8_string( stdout, pkt->pkt.user_id->name,
- pkt->pkt.user_id->len );
-}
-
-
-/****************
- * List the certificate in a user friendly way
- */
-
-static void
-list_node( CTX c, KBNODE node )
-{
- int any=0;
- int mainkey;
-
- if( !node )
- ;
- else if( (mainkey = (node->pkt->pkttype == PKT_PUBLIC_KEY) )
- || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- PKT_public_key *pk = node->pkt->pkt.public_key;
-
- if( opt.with_colons ) {
- u32 keyid[2];
- keyid_from_pk( pk, keyid );
- if( mainkey ) {
- c->local_id = pk->local_id;
- c->trustletter = opt.fast_list_mode?
- 0 : get_validity_info( pk, NULL );
- }
- printf("%s:", mainkey? "pub":"sub" );
- if( c->trustletter )
- putchar( c->trustletter );
- printf(":%u:%d:%08lX%08lX:%s:%s:",
- nbits_from_pk( pk ),
- pk->pubkey_algo,
- (ulong)keyid[0],(ulong)keyid[1],
- colon_datestr_from_pk( pk ),
- colon_strtime (pk->expiredate) );
- if( c->local_id )
- printf("%lu", c->local_id );
- putchar(':');
- if( mainkey && !opt.fast_list_mode )
- putchar( get_ownertrust_info (pk) );
- putchar(':');
- if( node->next && node->next->pkt->pkttype == PKT_RING_TRUST) {
- putchar('\n'); any=1;
- if( opt.fingerprint )
- print_fingerprint( pk, NULL, 0 );
- printf("rtv:1:%u:\n",
- node->next->pkt->pkt.ring_trust->trustval );
- }
- }
- else
- printf("%s %4u%c/%08lX %s ",
- mainkey? "pub":"sub",
- nbits_from_pk( pk ),
- pubkey_letter( pk->pubkey_algo ),
- (ulong)keyid_from_pk( pk, NULL ),
- datestr_from_pk( pk ) );
-
- if( mainkey ) {
- /* and now list all userids with their signatures */
- for( node = node->next; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_SIGNATURE ) {
- if( !any ) {
- if( node->pkt->pkt.signature->sig_class == 0x20 )
- puts("[revoked]");
- else
- putchar('\n');
- any = 1;
- }
- list_node(c, node );
- }
- else if( node->pkt->pkttype == PKT_USER_ID ) {
- if( any ) {
- if( opt.with_colons )
- printf("%s:::::::::",
- node->pkt->pkt.user_id->attrib_data?"uat":"uid");
- else
- printf( "uid%*s", 28, "" );
- }
- print_userid( node->pkt );
- if( opt.with_colons )
- putchar(':');
- putchar('\n');
- if( opt.fingerprint && !any )
- print_fingerprint( pk, NULL, 0 );
- if( node->next
- && node->next->pkt->pkttype == PKT_RING_TRUST ) {
- printf("rtv:2:%u:\n",
- node->next->pkt->pkt.ring_trust->trustval );
- }
- any=1;
- }
- else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- if( !any ) {
- putchar('\n');
- any = 1;
- }
- list_node(c, node );
- }
- }
- }
- else if( pk->expiredate ) { /* of subkey */
- printf(_(" [expires: %s]"), expirestr_from_pk( pk ) );
- }
-
- if( !any )
- putchar('\n');
- if( !mainkey && opt.fingerprint > 1 )
- print_fingerprint( pk, NULL, 0 );
- }
- else if( (mainkey = (node->pkt->pkttype == PKT_SECRET_KEY) )
- || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- PKT_secret_key *sk = node->pkt->pkt.secret_key;
-
- if( opt.with_colons ) {
- u32 keyid[2];
- keyid_from_sk( sk, keyid );
- printf("%s::%u:%d:%08lX%08lX:%s:%s:::",
- mainkey? "sec":"ssb",
- nbits_from_sk( sk ),
- sk->pubkey_algo,
- (ulong)keyid[0],(ulong)keyid[1],
- colon_datestr_from_sk( sk ),
- colon_strtime (sk->expiredate)
- /* fixme: add LID */ );
- }
- else
- printf("%s %4u%c/%08lX %s ",
- mainkey? "sec":"ssb",
- nbits_from_sk( sk ),
- pubkey_letter( sk->pubkey_algo ),
- (ulong)keyid_from_sk( sk, NULL ),
- datestr_from_sk( sk ) );
- if( mainkey ) {
- /* and now list all userids with their signatures */
- for( node = node->next; node; node = node->next ) {
- if( node->pkt->pkttype == PKT_SIGNATURE ) {
- if( !any ) {
- if( node->pkt->pkt.signature->sig_class == 0x20 )
- puts("[revoked]");
- else
- putchar('\n');
- any = 1;
- }
- list_node(c, node );
- }
- else if( node->pkt->pkttype == PKT_USER_ID ) {
- if( any ) {
- if( opt.with_colons )
- printf("%s:::::::::",
- node->pkt->pkt.user_id->attrib_data?"uat":"uid");
- else
- printf( "uid%*s", 28, "" );
- }
- print_userid( node->pkt );
- if( opt.with_colons )
- putchar(':');
- putchar('\n');
- if( opt.fingerprint && !any )
- print_fingerprint( NULL, sk, 0 );
- any=1;
- }
- else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
- if( !any ) {
- putchar('\n');
- any = 1;
- }
- list_node(c, node );
- }
- }
- }
- if( !any )
- putchar('\n');
- if( !mainkey && opt.fingerprint > 1 )
- print_fingerprint( NULL, sk, 0 );
- }
- else if( node->pkt->pkttype == PKT_SIGNATURE ) {
- PKT_signature *sig = node->pkt->pkt.signature;
- int is_selfsig = 0;
- int rc2=0;
- size_t n;
- char *p;
- int sigrc = ' ';
-
- if( !opt.list_sigs )
- return;
-
- if( sig->sig_class == 0x20 || sig->sig_class == 0x30 )
- fputs("rev", stdout);
- else
- fputs("sig", stdout);
- if( opt.check_sigs ) {
- fflush(stdout);
- switch( gpg_err_code (rc2=do_check_sig( c, node,
- &is_selfsig,
- NULL, NULL )) ) {
- case 0: sigrc = '!'; break;
- case GPG_ERR_BAD_SIGNATURE: sigrc = '-'; break;
- case GPG_ERR_NO_PUBKEY:
- case GPG_ERR_UNUSABLE_PUBKEY: sigrc = '?'; break;
- default: sigrc = '%'; break;
- }
- }
- else { /* check whether this is a self signature */
- u32 keyid[2];
-
- if( c->list->pkt->pkttype == PKT_PUBLIC_KEY
- || c->list->pkt->pkttype == PKT_SECRET_KEY ) {
- if( c->list->pkt->pkttype == PKT_PUBLIC_KEY )
- keyid_from_pk( c->list->pkt->pkt.public_key, keyid );
- else
- keyid_from_sk( c->list->pkt->pkt.secret_key, keyid );
-
- if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
- is_selfsig = 1;
- }
- }
- if( opt.with_colons ) {
- putchar(':');
- if( sigrc != ' ' )
- putchar(sigrc);
- printf("::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
- (ulong)sig->keyid[0], (ulong)sig->keyid[1],
- colon_datestr_from_sig(sig),
- colon_expirestr_from_sig(sig));
-
- if(sig->trust_depth || sig->trust_value)
- printf("%d %d",sig->trust_depth,sig->trust_value);
- printf(":");
-
- if(sig->trust_regexp)
- print_string(stdout,sig->trust_regexp,
- strlen(sig->trust_regexp),':');
- printf(":");
- }
- else
- printf("%c %08lX %s ",
- sigrc, (ulong)sig->keyid[1], datestr_from_sig(sig));
- if( sigrc == '%' )
- printf("[%s] ", gpg_strerror (rc2) );
- else if( sigrc == '?' )
- ;
- else if( is_selfsig ) {
- if( opt.with_colons )
- putchar(':');
- fputs( sig->sig_class == 0x18? "[keybind]":"[selfsig]", stdout);
- if( opt.with_colons )
- putchar(':');
- }
- else if( !opt.fast_list_mode ) {
- p = get_user_id( sig->keyid, &n );
- print_string( stdout, p, n, opt.with_colons );
- xfree (p);
- }
- if( opt.with_colons )
- printf(":%02x%c:", sig->sig_class, sig->flags.exportable?'x':'l');
- putchar('\n');
- }
- else
- log_error("invalid node with packet of type %d\n", node->pkt->pkttype);
-}
-
-
-
-int
-proc_packets( void *anchor, iobuf_t a )
-{
- int rc;
- CTX c = xcalloc (1, sizeof *c );
-
- c->anchor = anchor;
- rc = do_proc_packets( c, a );
- xfree ( c );
- return rc;
-}
-
-
-
-int
-proc_signature_packets( void *anchor, iobuf_t a,
- STRLIST signedfiles, const char *sigfilename )
-{
- CTX c = xcalloc (1, sizeof *c );
- int rc;
-
- c->anchor = anchor;
- c->sigs_only = 1;
- c->signed_data = signedfiles;
- c->sigfilename = sigfilename;
- rc = do_proc_packets( c, a );
- xfree ( c );
- return rc;
-}
-
-int
-proc_encryption_packets( void *anchor, iobuf_t a )
-{
- CTX c = xcalloc (1, sizeof *c );
- int rc;
-
- c->anchor = anchor;
- c->encrypt_only = 1;
- rc = do_proc_packets( c, a );
- xfree ( c );
- return rc;
-}
-
-
-int
-do_proc_packets( CTX c, iobuf_t a )
-{
- PACKET *pkt = xmalloc ( sizeof *pkt );
- int rc=0;
- int any_data=0;
- int newpkt;
-
- c->iobuf = a;
- init_packet(pkt);
- while( (rc=parse_packet(a, pkt)) != -1 ) {
- any_data = 1;
- if( rc ) {
- free_packet(pkt);
- /* stop processing when an invalid packet has been encountered
- * but don't do so when we are doing a --list-packet. */
- if( gpg_err_code (rc) == GPG_ERR_INV_PACKET && opt.list_packets != 2 )
- break;
- continue;
- }
- newpkt = -1;
- if( opt.list_packets ) {
- switch( pkt->pkttype ) {
- case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break;
- case PKT_SYMKEY_ENC: proc_symkey_enc( c, pkt ); break;
- case PKT_ENCRYPTED:
- case PKT_ENCRYPTED_MDC: proc_encrypted( c, pkt ); break;
- case PKT_COMPRESSED: proc_compressed( c, pkt ); break;
- default: newpkt = 0; break;
- }
- }
- else if( c->sigs_only ) {
- switch( pkt->pkttype ) {
- case PKT_PUBLIC_KEY:
- case PKT_SECRET_KEY:
- case PKT_USER_ID:
- case PKT_SYMKEY_ENC:
- case PKT_PUBKEY_ENC:
- case PKT_ENCRYPTED:
- case PKT_ENCRYPTED_MDC:
- write_status_text( STATUS_UNEXPECTED, "0" );
- rc = GPG_ERR_UNEXPECTED;
- goto leave;
- case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break;
- case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break;
- case PKT_COMPRESSED: proc_compressed( c, pkt ); break;
- case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
- case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break;
- default: newpkt = 0; break;
- }
- }
- else if( c->encrypt_only ) {
- switch( pkt->pkttype ) {
- case PKT_PUBLIC_KEY:
- case PKT_SECRET_KEY:
- case PKT_USER_ID:
- write_status_text( STATUS_UNEXPECTED, "0" );
- rc = GPG_ERR_UNEXPECTED;
- goto leave;
- case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break;
- case PKT_SYMKEY_ENC: proc_symkey_enc( c, pkt ); break;
- case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break;
- case PKT_ENCRYPTED:
- case PKT_ENCRYPTED_MDC: proc_encrypted( c, pkt ); break;
- case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break;
- case PKT_COMPRESSED: proc_compressed( c, pkt ); break;
- case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
- case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break;
- default: newpkt = 0; break;
- }
- }
- else {
- switch( pkt->pkttype ) {
- case PKT_PUBLIC_KEY:
- case PKT_SECRET_KEY:
- release_list( c );
- c->list = new_kbnode( pkt );
- newpkt = 1;
- break;
- case PKT_PUBLIC_SUBKEY:
- case PKT_SECRET_SUBKEY:
- newpkt = add_subkey( c, pkt );
- break;
- case PKT_USER_ID: newpkt = add_user_id( c, pkt ); break;
- case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break;
- case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break;
- case PKT_SYMKEY_ENC: proc_symkey_enc( c, pkt ); break;
- case PKT_ENCRYPTED:
- case PKT_ENCRYPTED_MDC: proc_encrypted( c, pkt ); break;
- case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break;
- case PKT_COMPRESSED: proc_compressed( c, pkt ); break;
- case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
- case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break;
- case PKT_RING_TRUST: newpkt = add_ring_trust( c, pkt ); break;
- default: newpkt = 0; break;
- }
- }
- /* This is a very ugly construct and frankly, I don't remember why
- * I used it. Adding the MDC check here is a hack.
- * The right solution is to initiate another context for encrypted
- * packet and not to reuse the current one ... It works right
- * when there is a compression packet inbetween which adds just
- * an extra layer.
- * Hmmm: Rewrite this whole module here??
- */
- if( pkt->pkttype != PKT_SIGNATURE && pkt->pkttype != PKT_MDC )
- c->have_data = pkt->pkttype == PKT_PLAINTEXT;
-
- if( newpkt == -1 )
- ;
- else if( newpkt ) {
- pkt = xmalloc ( sizeof *pkt );
- init_packet(pkt);
- }
- else
- free_packet(pkt);
- if ( c->pipemode.stop_now ) {
- /* we won't get an EOF in pipemode, so we have to
- * break the loop here */
- rc = -1;
- break;
- }
- }
- if( gpg_err_code (rc) == GPG_ERR_INV_PACKET )
- write_status_text( STATUS_NODATA, "3" );
- if( any_data )
- rc = 0;
- else if( rc == -1 )
- write_status_text( STATUS_NODATA, "2" );
-
-
- leave:
- release_list( c );
- xfree (c->dek);
- free_packet( pkt );
- xfree ( pkt );
- free_md_filter_context( &c->mfx );
- return rc;
-}
-
-
-static int
-check_sig_and_print( CTX c, KBNODE node )
-{
- PKT_signature *sig = node->pkt->pkt.signature;
- const char *astr, *tstr;
- int rc, is_expkey=0, is_revkey=0;
-
- if( opt.skip_verify ) {
- log_info(_("signature verification suppressed\n"));
- return 0;
- }
-
- /* It is not in all cases possible to check multiple signatures:
- * PGP 2 (which is also allowed by OpenPGP), does use the packet
- * sequence: sig+data, OpenPGP does use onepas+data=sig and GnuPG
- * sometimes uses (because I did'nt read the specs right) data+sig.
- * Because it is possible to create multiple signatures with
- * different packet sequence (e.g. data+sig and sig+data) it might
- * not be possible to get it right: let's say we have:
- * data+sig, sig+data,sig+data and we have not yet encountered the last
- * data, we could also see this a one data with 2 signatures and then
- * data+sig.
- * To protect against this we check that all signatures follow
- * without any intermediate packets. Note, that we won't get this
- * error when we use onepass packets or cleartext signatures because
- * we reset the list every time
- *
- * FIXME: Now that we have these marker packets, we should create a
- * real grammar and check against this.
- */
- {
- KBNODE n;
- int n_sig=0;
-
- for (n=c->list; n; n=n->next ) {
- if ( n->pkt->pkttype == PKT_SIGNATURE )
- n_sig++;
- }
- if (n_sig > 1) { /* more than one signature - check sequence */
- int tmp, onepass;
-
- for (tmp=onepass=0,n=c->list; n; n=n->next ) {
- if (n->pkt->pkttype == PKT_ONEPASS_SIG)
- onepass++;
- else if (n->pkt->pkttype == PKT_GPG_CONTROL
- && n->pkt->pkt.gpg_control->control
- == CTRLPKT_CLEARSIGN_START ) {
- onepass++; /* handle the same way as a onepass */
- }
- else if ( (tmp && n->pkt->pkttype != PKT_SIGNATURE) ) {
- log_error(_("can't handle these multiple signatures\n"));
- return 0;
- }
- else if ( n->pkt->pkttype == PKT_SIGNATURE )
- tmp = 1;
- else if (!tmp && !onepass
- && n->pkt->pkttype == PKT_GPG_CONTROL
- && n->pkt->pkt.gpg_control->control
- == CTRLPKT_PLAINTEXT_MARK ) {
- /* plaintext before signatures but no one-pass packets*/
- log_error(_("can't handle these multiple signatures\n"));
- return 0;
- }
- }
- }
- }
-
- tstr = asctimestamp(sig->timestamp);
- astr = gcry_pk_algo_name (sig->pubkey_algo);
- if(opt.verify_options&VERIFY_SHOW_LONG_KEYID)
- {
- log_info(_("Signature made %.*s\n"),(int)strlen(tstr), tstr);
- log_info(_(" using %s key %08lX%08lX\n"),
- astr? astr: "?",(ulong)sig->keyid[0],(ulong)sig->keyid[1] );
- }
- else
- log_info(_("Signature made %.*s using %s key ID %08lX\n"),
- (int)strlen(tstr), tstr, astr? astr: "?",
- (ulong)sig->keyid[1] );
-
- rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
- if( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
- && opt.keyserver_scheme && opt.keyserver_options.auto_key_retrieve) {
- if( keyserver_import_keyid ( sig->keyid )==0 )
- rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
- }
-
-
- /* If the key still isn't found, try to inform the user where it
- can be found. */
- if(gpg_err_code (rc)==GPG_ERR_NO_PUBKEY && sig->flags.pref_ks)
- {
- const byte *p;
- int seq=0;
- size_t n;
-
- while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&n,&seq,NULL)))
- {
- /* According to my favorite copy editor, in English
- grammar, you say "at" if the key is located on a web
- page, but "from" if it is located on a keyserver. I'm
- not going to even try to make two strings here :) */
- log_info(_("Key available at: ") );
- print_string( log_get_stream(), p, n, 0 );
- putc( '\n', log_get_stream() );
- }
- }
-
-
- if( !rc || gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE ) {
- KBNODE un, keyblock;
- int count=0, statno;
- char keyid_str[50];
- PKT_public_key *pk=NULL;
-
- if(rc)
- statno=STATUS_BADSIG;
- else if(sig->flags.expired)
- statno=STATUS_EXPSIG;
- else if(is_expkey)
- statno=STATUS_EXPKEYSIG;
- else if(is_revkey)
- statno=STATUS_REVKEYSIG;
- else
- statno=STATUS_GOODSIG;
-
- keyblock = get_pubkeyblock( sig->keyid );
-
- sprintf (keyid_str, "%08lX%08lX [uncertain] ",
- (ulong)sig->keyid[0], (ulong)sig->keyid[1]);
-
- /* find and print the primary user ID */
- for( un=keyblock; un; un = un->next ) {
- int valid;
-
- if(un->pkt->pkttype==PKT_PUBLIC_KEY)
- {
- pk=un->pkt->pkt.public_key;
- continue;
- }
- if( un->pkt->pkttype != PKT_USER_ID )
- continue;
- if ( !un->pkt->pkt.user_id->created )
- continue;
- if ( un->pkt->pkt.user_id->is_revoked )
- continue;
- if ( un->pkt->pkt.user_id->is_expired )
- continue;
- if ( !un->pkt->pkt.user_id->is_primary )
- continue;
- /* We want the textual user ID here */
- if ( un->pkt->pkt.user_id->attrib_data )
- continue;
-
- assert(pk);
-
- /* Get it before we print anything to avoid interrupting
- the output with the "please do a --check-trustdb"
- line. */
- valid=get_validity(pk,un->pkt->pkt.user_id);
-
- keyid_str[17] = 0; /* cut off the "[uncertain]" part */
- write_status_text_and_buffer (statno, keyid_str,
- un->pkt->pkt.user_id->name,
- un->pkt->pkt.user_id->len,
- -1 );
-
- log_info(rc? _("BAD signature from \"")
- : sig->flags.expired ? _("Expired signature from \"")
- : _("Good signature from \""));
- print_utf8_string( log_get_stream(), un->pkt->pkt.user_id->name,
- un->pkt->pkt.user_id->len );
- if(opt.verify_options&VERIFY_SHOW_VALIDITY)
- fprintf (log_get_stream(),
- "\" [%s]\n",trust_value_to_string(valid));
- else
- fputs("\"\n", log_get_stream() );
- count++;
- }
- if( !count ) { /* just in case that we have no valid textual
- userid */
- /* Try for an invalid textual userid */
- for( un=keyblock; un; un = un->next ) {
- if( un->pkt->pkttype == PKT_USER_ID &&
- !un->pkt->pkt.user_id->attrib_data )
- break;
- }
-
- /* Try for any userid at all */
- if(!un) {
- for( un=keyblock; un; un = un->next ) {
- if( un->pkt->pkttype == PKT_USER_ID )
- break;
- }
- }
-
- if (opt.trust_model==TM_ALWAYS || !un)
- keyid_str[17] = 0; /* cut off the "[uncertain]" part */
-
- write_status_text_and_buffer (statno, keyid_str,
- un? un->pkt->pkt.user_id->name:"[?]",
- un? un->pkt->pkt.user_id->len:3,
- -1 );
-
- log_info(rc? _("BAD signature from \"")
- : sig->flags.expired ? _("Expired signature from \"")
- : _("Good signature from \""));
- if (opt.trust_model!=TM_ALWAYS && un) {
- fputs(_("[uncertain]"), log_get_stream() );
- putc(' ', log_get_stream() );
- }
- print_utf8_string( log_get_stream(),
- un? un->pkt->pkt.user_id->name:"[?]",
- un? un->pkt->pkt.user_id->len:3 );
- fputs("\"\n", log_get_stream() );
- }
-
- /* If we have a good signature and already printed
- * the primary user ID, print all the other user IDs */
- if ( count && !rc ) {
- for( un=keyblock; un; un = un->next ) {
- if( un->pkt->pkttype != PKT_USER_ID )
- continue;
- if ( un->pkt->pkt.user_id->is_revoked )
- continue;
- if ( un->pkt->pkt.user_id->is_expired )
- continue;
- /* Only skip textual primaries */
- if ( un->pkt->pkt.user_id->is_primary &&
- !un->pkt->pkt.user_id->attrib_data )
- continue;
-
- if(un->pkt->pkt.user_id->attrib_data)
- {
- dump_attribs(un->pkt->pkt.user_id,pk,NULL);
-
- if(opt.verify_options&VERIFY_SHOW_PHOTOS)
- show_photos(un->pkt->pkt.user_id->attribs,
- un->pkt->pkt.user_id->numattribs,pk,NULL);
- }
-
- log_info( _(" aka \""));
- print_utf8_string( log_get_stream(), un->pkt->pkt.user_id->name,
- un->pkt->pkt.user_id->len );
- if(opt.verify_options&VERIFY_SHOW_VALIDITY)
- fprintf (log_get_stream(), "\" [%s]\n",
- trust_value_to_string(get_validity(pk,
- un->pkt->
- pkt.user_id)));
- else
- fputs("\"\n", log_get_stream() );
- }
- }
- release_kbnode( keyblock );
-
- if( !rc )
- {
- if(opt.verify_options&VERIFY_SHOW_POLICY)
- show_policy_url(sig,0,1);
- else
- show_policy_url(sig,0,2);
-
- if(opt.verify_options&VERIFY_SHOW_KEYSERVER)
- show_keyserver_url(sig,0,1);
- else
- show_keyserver_url(sig,0,2);
-
- if(opt.verify_options&VERIFY_SHOW_NOTATION)
- show_notation(sig,0,1);
- else
- show_notation(sig,0,2);
- }
-
- if( !rc && is_status_enabled() ) {
- /* print a status response with the fingerprint */
- PKT_public_key *vpk = xcalloc (1, sizeof *vpk );
-
- if( !get_pubkey( vpk, sig->keyid ) ) {
- byte array[MAX_FINGERPRINT_LEN], *p;
- char buf[MAX_FINGERPRINT_LEN*4+90], *bufp;
- size_t i, n;
-
- bufp = buf;
- fingerprint_from_pk( vpk, array, &n );
- p = array;
- for(i=0; i < n ; i++, p++, bufp += 2)
- sprintf(bufp, "%02X", *p );
- /* TODO: Replace the reserved '0' in the field below
- with bits for status flags (policy url, notation,
- etc.). Remember to make the buffer larger to
- match! */
- sprintf(bufp, " %s %lu %lu %d 0 %d %d %02X ",
- strtimestamp( sig->timestamp ),
- (ulong)sig->timestamp,(ulong)sig->expiredate,
- sig->version,sig->pubkey_algo,sig->digest_algo,
- sig->sig_class);
- bufp = bufp + strlen (bufp);
- if (!vpk->is_primary) {
- u32 akid[2];
-
- akid[0] = vpk->main_keyid[0];
- akid[1] = vpk->main_keyid[1];
- free_public_key (vpk);
- vpk = xcalloc (1, sizeof *vpk );
- if (get_pubkey (vpk, akid)) {
- /* impossible error, we simply return a zeroed out fpr */
- n = MAX_FINGERPRINT_LEN < 20? MAX_FINGERPRINT_LEN : 20;
- memset (array, 0, n);
- }
- else
- fingerprint_from_pk( vpk, array, &n );
- }
- p = array;
- for(i=0; i < n ; i++, p++, bufp += 2)
- sprintf(bufp, "%02X", *p );
- write_status_text( STATUS_VALIDSIG, buf );
- }
- free_public_key( vpk );
- }
-
- if( !rc )
- rc = check_signatures_trust( sig );
-
- if(sig->flags.expired)
- {
- log_info(_("Signature expired %s\n"),
- asctimestamp(sig->expiredate));
- rc=GPG_ERR_GENERAL; /* need a better error here? */
- }
- else if(sig->expiredate)
- log_info(_("Signature expires %s\n"),asctimestamp(sig->expiredate));
-
- if(opt.verbose)
- log_info(_("%s signature, digest algorithm %s\n"),
- sig->sig_class==0x00?_("binary"):
- sig->sig_class==0x01?_("textmode"):_("unknown"),
- gcry_md_algo_name (sig->digest_algo));
-
- if( rc )
- g10_errors_seen = 1;
- if( opt.batch && rc )
- g10_exit(1);
- }
- else {
- char buf[50];
- sprintf(buf, "%08lX%08lX %d %d %02x %lu %d",
- (ulong)sig->keyid[0], (ulong)sig->keyid[1],
- sig->pubkey_algo, sig->digest_algo,
- sig->sig_class, (ulong)sig->timestamp, rc );
- write_status_text( STATUS_ERRSIG, buf );
- if( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY ) {
- buf[16] = 0;
- write_status_text( STATUS_NO_PUBKEY, buf );
- }
- if( rc != GPG_ERR_NOT_PROCESSED )
- log_error(_("Can't check signature: %s\n"), gpg_strerror (rc) );
- }
- return rc;
-}
-
-
-/****************
- * Process the tree which starts at node
- */
-static void
-proc_tree( CTX c, KBNODE node )
-{
- KBNODE n1;
- int rc;
-
- if( opt.list_packets || opt.list_only )
- return;
-
- /* we must skip our special plaintext marker packets here becuase
- they may be the root packet. These packets are only used in
- addionla checks and skipping them here doesn't matter */
- while ( node
- && node->pkt->pkttype == PKT_GPG_CONTROL
- && node->pkt->pkt.gpg_control->control
- == CTRLPKT_PLAINTEXT_MARK ) {
- node = node->next;
- }
- if (!node)
- return;
-
- c->local_id = 0;
- c->trustletter = ' ';
- if( node->pkt->pkttype == PKT_PUBLIC_KEY
- || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
- merge_keys_and_selfsig( node );
- list_node( c, node );
- }
- else if( node->pkt->pkttype == PKT_SECRET_KEY ) {
- merge_keys_and_selfsig( node );
- list_node( c, node );
- }
- else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) {
- /* check all signatures */
- if( !c->have_data ) {
- free_md_filter_context( &c->mfx );
- /* prepare to create all requested message digests */
- gcry_md_open (&c->mfx.md, 0, 0);
-
- /* fixme: why looking for the signature packet and not 1passpacket*/
- for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); ) {
- gcry_md_enable ( c->mfx.md, n1->pkt->pkt.signature->digest_algo);
- }
- /* ask for file and hash it */
- if( c->sigs_only ) {
- rc = hash_datafiles( c->mfx.md, NULL,
- c->signed_data, c->sigfilename,
- n1? (n1->pkt->pkt.onepass_sig->sig_class == 0x01):0 );
- }
- else {
- rc = ask_for_detached_datafile( c->mfx.md, c->mfx.md2,
- iobuf_get_real_fname(c->iobuf),
- n1? (n1->pkt->pkt.onepass_sig->sig_class == 0x01):0 );
- }
- if( rc ) {
- log_error("can't hash datafile: %s\n", gpg_strerror (rc));
- return;
- }
- }
- else if ( c->signed_data ) {
- log_error (_("not a detached signature\n") );
- return;
- }
-
- for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); )
- check_sig_and_print( c, n1 );
- }
- else if( node->pkt->pkttype == PKT_GPG_CONTROL
- && node->pkt->pkt.gpg_control->control
- == CTRLPKT_CLEARSIGN_START ) {
- /* clear text signed message */
- if( !c->have_data ) {
- log_error("cleartext signature without data\n" );
- return;
- }
- else if ( c->signed_data ) {
- log_error (_("not a detached signature\n") );
- return;
- }
-
- for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); )
- check_sig_and_print( c, n1 );
- }
- else if( node->pkt->pkttype == PKT_SIGNATURE ) {
- PKT_signature *sig = node->pkt->pkt.signature;
- int multiple_ok=1;
-
- n1=find_next_kbnode(node, PKT_SIGNATURE);
- if(n1)
- {
- byte class=sig->sig_class;
- byte hash=sig->digest_algo;
-
- for(; n1; (n1 = find_next_kbnode(n1, PKT_SIGNATURE)))
- {
- /* We can't currently handle multiple signatures of
- different classes or digests (we'd pretty much have
- to run a different hash context for each), but if
- they are all the same, make an exception. */
- if(n1->pkt->pkt.signature->sig_class!=class
- || n1->pkt->pkt.signature->digest_algo!=hash)
- {
- multiple_ok=0;
- log_info(_("WARNING: multiple signatures detected. "
- "Only the first will be checked.\n"));
- break;
- }
- }
- }
-
- if( sig->sig_class != 0x00 && sig->sig_class != 0x01 )
- log_info(_("standalone signature of class 0x%02x\n"),
- sig->sig_class);
- else if( !c->have_data ) {
- /* detached signature */
- free_md_filter_context( &c->mfx );
- gcry_md_open (&c->mfx.md, sig->digest_algo, 0);
- if( !opt.pgp2_workarounds )
- ;
- else if( sig->digest_algo == DIGEST_ALGO_MD5
- && is_RSA( sig->pubkey_algo ) ) {
- /* enable a workaround for a pgp2 bug */
- gcry_md_open (&c->mfx.md2, DIGEST_ALGO_MD5, 0 );
- }
- else if( sig->digest_algo == DIGEST_ALGO_SHA1
- && sig->pubkey_algo == PUBKEY_ALGO_DSA
- && sig->sig_class == 0x01 ) {
- /* enable the workaround also for pgp5 when the detached
- * signature has been created in textmode */
- gcry_md_open (&c->mfx.md2, sig->digest_algo, 0 );
- }
-#if 0 /* workaround disabled */
- /* Here we have another hack to work around a pgp 2 bug
- * It works by not using the textmode for detached signatures;
- * this will let the first signature check (on md) fail
- * but the second one (on md2) which adds an extra CR should
- * then produce the "correct" hash. This is very, very ugly
- * hack but it may help in some cases (and break others)
- */
- /* c->mfx.md2? 0 :(sig->sig_class == 0x01) */
-#endif
- if ( DBG_HASHING ) {
- gcry_md_start_debug ( c->mfx.md, "verify" );
- if ( c->mfx.md2 )
- gcry_md_start_debug ( c->mfx.md2, "verify2" );
- }
- if( c->sigs_only ) {
- rc = hash_datafiles( c->mfx.md, c->mfx.md2,
- c->signed_data, c->sigfilename,
- (sig->sig_class == 0x01) );
- }
- else {
- rc = ask_for_detached_datafile( c->mfx.md, c->mfx.md2,
- iobuf_get_real_fname(c->iobuf),
- (sig->sig_class == 0x01) );
- }
- if( rc ) {
- log_error("can't hash datafile: %s\n", gpg_strerror (rc));
- return;
- }
- }
- else if ( c->signed_data ) {
- log_error (_("not a detached signature\n") );
- return;
- }
- else if ( c->pipemode.op == 'B' )
- ; /* this is a detached signature trough the pipemode handler */
- else if (!opt.quiet)
- log_info(_("old style (PGP 2.x) signature\n"));
-
- if(multiple_ok)
- for( n1 = node; n1; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )) )
- check_sig_and_print( c, n1 );
- else
- check_sig_and_print( c, node );
- }
- else {
- dump_kbnode (c->list);
- log_error(_("invalid root packet detected in proc_tree()\n"));
- dump_kbnode (node);
- }
-}
diff --git a/g10/mdfilter.c b/g10/mdfilter.c
deleted file mode 100644
index b58189146..000000000
--- a/g10/mdfilter.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* mdfilter.c - filter data and calculate a message digest
- * Copyright (C) 1998, 1999, 2000, 2001 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "errors.h"
-#include "iobuf.h"
-#include "memory.h"
-#include "util.h"
-#include "filter.h"
-
-
-
-/****************
- * This filter is used to collect a message digest
- */
-int
-md_filter( void *opaque, int control,
- iobuf_t a, byte *buf, size_t *ret_len)
-{
- size_t size = *ret_len;
- md_filter_context_t *mfx = opaque;
- int i, rc=0;
-
- if( control == IOBUFCTRL_UNDERFLOW ) {
- if( mfx->maxbuf_size && size > mfx->maxbuf_size )
- size = mfx->maxbuf_size;
- i = iobuf_read( a, buf, size );
- if( i == -1 ) i = 0;
- if( i ) {
- gcry_md_write(mfx->md, buf, i );
- if( mfx->md2 )
- gcry_md_write(mfx->md2, buf, i );
- }
- else
- rc = -1; /* eof */
- *ret_len = i;
- }
- else if( control == IOBUFCTRL_DESC )
- *(char**)buf = "md_filter";
- return rc;
-}
-
-
-void
-free_md_filter_context( md_filter_context_t *mfx )
-{
- gcry_md_close (mfx->md);
- gcry_md_close (mfx->md2);
- mfx->md = NULL;
- mfx->md2 = NULL;
- mfx->maxbuf_size = 0;
-}
-
diff --git a/g10/misc.c b/g10/misc.c
deleted file mode 100644
index 7012a8a25..000000000
--- a/g10/misc.c
+++ /dev/null
@@ -1,1000 +0,0 @@
-/* misc.c - miscellaneous functions
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <assert.h>
-#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
-#include <asm/sysinfo.h>
-#include <asm/unistd.h>
-#endif
-#ifdef HAVE_SETRLIMIT
-#include <time.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#endif
-
-#include "gpg.h"
-#include "util.h"
-#include "main.h"
-#include "photoid.h"
-#include "options.h"
-#include "i18n.h"
-
-#define MAX_EXTERN_MPI_BITS 16384
-
-
-#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
-static int
-setsysinfo(unsigned long op, void *buffer, unsigned long size,
- int *start, void *arg, unsigned long flag)
-{
- return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
-}
-
-void
-trap_unaligned(void)
-{
- unsigned int buf[2];
-
- buf[0] = SSIN_UACPROC;
- buf[1] = UAC_SIGBUS | UAC_NOPRINT;
- setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
-}
-#else
-void
-trap_unaligned(void)
-{ /* dummy */
-}
-#endif
-
-
-int
-disable_core_dumps()
-{
-#ifdef HAVE_DOSISH_SYSTEM
- return 0;
-#else
-#ifdef HAVE_SETRLIMIT
- struct rlimit limit;
-
- limit.rlim_cur = 0;
- limit.rlim_max = 0;
- if( !setrlimit( RLIMIT_CORE, &limit ) )
- return 0;
- if( errno != EINVAL && errno != ENOSYS )
- log_fatal(_("can't disable core dumps: %s\n"), strerror(errno) );
-#endif
- return 1;
-#endif
-}
-
-
-
-u16
-checksum_u16( unsigned n )
-{
- u16 a;
-
- a = (n >> 8) & 0xff;
- a += n & 0xff;
- return a;
-}
-
-
-u16
-checksum( byte *p, unsigned n )
-{
- u16 a;
-
- for(a=0; n; n-- )
- a += *p++;
- return a;
-}
-
-u16
-checksum_mpi( gcry_mpi_t a )
-{
- int rc;
- u16 csum;
- byte *buffer;
- size_t nbytes;
-
- rc = gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, 0, &nbytes, a );
- if (rc)
- BUG ();
- /* fixme: for numbers not in secure memory we should use a stack
- * based buffer and only allocate a larger one if mpi_print return
- * an error */
- buffer = gcry_is_secure(a)? gcry_xmalloc_secure(nbytes):gcry_xmalloc(nbytes);
- rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, NULL, a );
- if (rc)
- BUG ();
- csum = checksum (buffer, nbytes );
- xfree (buffer );
- return csum;
-}
-
-u32
-buffer_to_u32( const byte *buffer )
-{
- unsigned long a;
- a = *buffer << 24;
- a |= buffer[1] << 16;
- a |= buffer[2] << 8;
- a |= buffer[3];
- return a;
-}
-
-
-static void
-no_exp_algo(void)
-{
- static int did_note = 0;
-
- if( !did_note ) {
- did_note = 1;
- log_info(_("Experimental algorithms should not be used!\n"));
- }
-}
-
-void
-print_pubkey_algo_note( int algo )
-{
- if( algo >= 100 && algo <= 110 )
- no_exp_algo();
-}
-
-void
-print_cipher_algo_note( int algo )
-{
- if( algo >= 100 && algo <= 110 )
- no_exp_algo();
- else if( algo == CIPHER_ALGO_3DES
- || algo == CIPHER_ALGO_CAST5
- || algo == CIPHER_ALGO_BLOWFISH
- || algo == CIPHER_ALGO_TWOFISH
- || algo == CIPHER_ALGO_RIJNDAEL
- || algo == CIPHER_ALGO_RIJNDAEL192
- || algo == CIPHER_ALGO_RIJNDAEL256
- )
- ;
- else {
- static int did_note = 0;
-
- if( !did_note ) {
- did_note = 1;
- log_info(_("this cipher algorithm is deprecated; "
- "please use a more standard one!\n"));
- }
- }
-}
-
-void
-print_digest_algo_note( int algo )
-{
- if( algo >= 100 && algo <= 110 )
- no_exp_algo();
-}
-
-
-/* Return a string which is used as a kind of process ID */
-const byte *
-get_session_marker( size_t *rlen )
-{
- static byte marker[SIZEOF_UNSIGNED_LONG*2];
- static int initialized;
-
- if ( !initialized ) {
- volatile ulong aa, bb; /* we really want the uninitialized value */
- ulong a, b;
-
- initialized = 1;
- /* also this marker is guessable it is not easy to use this
- * for a faked control packet because an attacker does not
- * have enough control about the time the verification does
- * take place. Of course, we can add just more random but
- * than we need the random generator even for verification
- * tasks - which does not make sense. */
- a = aa ^ (ulong)getpid();
- b = bb ^ (ulong)time(NULL);
- memcpy( marker, &a, SIZEOF_UNSIGNED_LONG );
- memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG );
- }
- *rlen = sizeof(marker);
- return marker;
-}
-
-/****************
- * Wrapper around the libgcrypt function with addional checks on
- * openPGP contraints for the algo ID.
- */
-int
-openpgp_cipher_test_algo( int algo )
-{
- if( algo < 0 || algo > 110 )
- return GPG_ERR_CIPHER_ALGO;
- return gcry_cipher_test_algo (algo);
-}
-
-int
-openpgp_pk_test_algo( int algo, unsigned int usage_flags )
-{
- size_t value = usage_flags;
-
- if (algo == GCRY_PK_ELG_E)
- algo = GCRY_PK_ELG;
-#ifdef __GNUC__
-#warning need to handle the usage here?
-#endif
- if (algo < 0 || algo > 110)
- return GPG_ERR_PUBKEY_ALGO;
- return gcry_pk_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, &value);
-}
-
-int
-openpgp_pk_algo_usage ( int algo )
-{
- int use = 0;
-
- /* they are hardwired in gpg 1.0 */
- switch ( algo ) {
- case PUBKEY_ALGO_RSA:
- use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH;
- break;
- case PUBKEY_ALGO_RSA_E:
- use = PUBKEY_USAGE_ENC;
- break;
- case PUBKEY_ALGO_RSA_S:
- use = PUBKEY_USAGE_SIG;
- break;
- case PUBKEY_ALGO_ELGAMAL_E:
- use = PUBKEY_USAGE_ENC;
- break;
- case PUBKEY_ALGO_DSA:
- use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
- break;
- case PUBKEY_ALGO_ELGAMAL:
- use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH;
- break;
- default:
- break;
- }
- return use;
-}
-
-int
-openpgp_md_test_algo( int algo )
-{
- if( algo < 0 || algo > 110 )
- return GPG_ERR_DIGEST_ALGO;
- return gcry_md_test_algo (algo);
-}
-
-int
-openpgp_md_map_name (const char *string)
-{
- int i = gcry_md_map_name (string);
-
- if (!i && (string[0]=='H' || string[0]=='h'))
- { /* Didn't find it, so try the Hx format */
- long val;
- char *endptr;
-
- string++;
-
- val=strtol(string,&endptr,10);
- if (*string!='\0' && *endptr=='\0' && !openpgp_md_test_algo(val))
- i = val;
- }
- return i < 0 || i > 110? 0 : i;
-}
-
-int
-openpgp_cipher_map_name (const char *string)
-{
- int i = gcry_cipher_map_name (string);
-
- if (!i && (string[0]=='S' || string[0]=='s'))
- { /* Didn't find it, so try the Sx format */
- long val;
- char *endptr;
-
- string++;
-
- val=strtol(string,&endptr,10);
- if (*string!='\0' && *endptr=='\0' && !openpgp_cipher_test_algo(val))
- i = val;
- }
- return i < 0 || i > 110? 0 : i;
-}
-
-int
-openpgp_pk_map_name (const char *string)
-{
- int i = gcry_pk_map_name (string);
- return i < 0 || i > 110? 0 : i;
-}
-
-#ifdef USE_IDEA
-/* Special warning for the IDEA cipher */
-void
-idea_cipher_warn(int show)
-{
- static int warned=0;
-
- if(!warned || show)
- {
- log_info(_("the IDEA cipher plugin is not present\n"));
- log_info(_("please see http://www.gnupg.org/why-not-idea.html "
- "for more information\n"));
- warned=1;
- }
-}
-#endif
-
-/* Expand %-strings. Returns a string which must be m_freed. Returns
- NULL if the string cannot be expanded (too large). */
-char *
-pct_expando(const char *string,struct expando_args *args)
-{
- const char *ch=string;
- int idx=0,maxlen=0,done=0;
- u32 pk_keyid[2]={0,0},sk_keyid[2]={0,0};
- char *ret=NULL;
-
- if(args->pk)
- keyid_from_pk(args->pk,pk_keyid);
-
- if(args->sk)
- keyid_from_sk(args->sk,sk_keyid);
-
- /* This is used so that %k works in photoid command strings in
- --list-secret-keys (which of course has a sk, but no pk). */
- if(!args->pk && args->sk)
- keyid_from_sk(args->sk,pk_keyid);
-
- while(*ch!='\0')
- {
- char *str=NULL;
-
- if(!done)
- {
- /* 8192 is way bigger than we'll need here */
- if(maxlen>=8192)
- goto fail;
-
- maxlen+=1024;
- ret= xrealloc(ret,maxlen);
- }
-
- done=0;
-
- if(*ch=='%')
- {
- switch(*(ch+1))
- {
- case 's': /* short key id */
- if(idx+8<maxlen)
- {
- sprintf(&ret[idx],"%08lX",(ulong)sk_keyid[1]);
- idx+=8;
- done=1;
- }
- break;
-
- case 'S': /* long key id */
- if(idx+16<maxlen)
- {
- sprintf(&ret[idx],"%08lX%08lX",
- (ulong)sk_keyid[0],(ulong)sk_keyid[1]);
- idx+=16;
- done=1;
- }
- break;
-
- case 'k': /* short key id */
- if(idx+8<maxlen)
- {
- sprintf(&ret[idx],"%08lX",(ulong)pk_keyid[1]);
- idx+=8;
- done=1;
- }
- break;
-
- case 'K': /* long key id */
- if(idx+16<maxlen)
- {
- sprintf(&ret[idx],"%08lX%08lX",
- (ulong)pk_keyid[0],(ulong)pk_keyid[1]);
- idx+=16;
- done=1;
- }
- break;
-
- case 'p': /* primary pk fingerprint of a sk */
- case 'f': /* pk fingerprint */
- case 'g': /* sk fingerprint */
- {
- byte array[MAX_FINGERPRINT_LEN];
- size_t len;
- int i;
-
- if( ch[1]=='p' && args->sk)
- {
- if(args->sk->is_primary)
- fingerprint_from_sk(args->sk,array,&len);
- else if(args->sk->main_keyid[0] || args->sk->main_keyid[1])
- {
- PKT_public_key *pk= xcalloc(1, sizeof(PKT_public_key));
-
- if(get_pubkey_fast(pk,args->sk->main_keyid)==0)
- fingerprint_from_pk(pk,array,&len);
- else
- memset(array,0,(len=MAX_FINGERPRINT_LEN));
- free_public_key(pk);
- }
- else
- memset(array,0,(len=MAX_FINGERPRINT_LEN));
- }
- else if( ch[1]=='f' && args->pk)
- fingerprint_from_pk(args->pk,array,&len);
- else if( ch[1]=='g' && args->sk)
- fingerprint_from_sk(args->sk,array,&len);
- else
- memset(array, 0, (len=MAX_FINGERPRINT_LEN));
-
- if(idx+(len*2)<maxlen)
- {
- for(i=0;i<len;i++)
- {
- sprintf(&ret[idx],"%02X",array[i]);
- idx+=2;
- }
- done=1;
- }
- }
- break;
-
- case 't': /* e.g. "jpg" */
- str=image_type_to_string(args->imagetype,0);
- /* fall through */
-
- case 'T': /* e.g. "image/jpeg" */
- if(str==NULL)
- str=image_type_to_string(args->imagetype,2);
-
- if(idx+strlen(str)<maxlen)
- {
- strcpy(&ret[idx],str);
- idx+=strlen(str);
- done=1;
- }
- break;
-
- case '%':
- if(idx+1<maxlen)
- {
- ret[idx++]='%';
- ret[idx]='\0';
- done=1;
- }
- break;
-
- /* Any unknown %-keys (like %i, %o, %I, and %O) are
- passed through for later expansion. Note this also
- handles the case where the last character in the
- string is a '%' - the terminating \0 will end up here
- and properly terminate the string. */
- default:
- if(idx+2<maxlen)
- {
- ret[idx++]='%';
- ret[idx++]=*(ch+1);
- ret[idx]='\0';
- done=1;
- }
- break;
- }
-
- if(done)
- ch++;
- }
- else
- {
- if(idx+1<maxlen)
- {
- ret[idx++]=*ch;
- ret[idx]='\0';
- done=1;
- }
- }
-
- if(done)
- ch++;
- }
-
- return ret;
-
- fail:
- xfree (ret);
- return NULL;
-}
-
-int
-hextobyte( const char *s )
-{
- int c;
-
- if( *s >= '0' && *s <= '9' )
- c = 16 * (*s - '0');
- else if( *s >= 'A' && *s <= 'F' )
- c = 16 * (10 + *s - 'A');
- else if( *s >= 'a' && *s <= 'f' )
- c = 16 * (10 + *s - 'a');
- else
- return -1;
- s++;
- if( *s >= '0' && *s <= '9' )
- c += *s - '0';
- else if( *s >= 'A' && *s <= 'F' )
- c += 10 + *s - 'A';
- else if( *s >= 'a' && *s <= 'f' )
- c += 10 + *s - 'a';
- else
- return -1;
- return c;
-}
-
-void
-deprecated_warning(const char *configname,unsigned int configlineno,
- const char *option,const char *repl1,const char *repl2)
-{
- if(configname)
- {
- if(strncmp("--",option,2)==0)
- option+=2;
-
- if(strncmp("--",repl1,2)==0)
- repl1+=2;
-
- log_info(_("%s:%d: deprecated option \"%s\"\n"),
- configname,configlineno,option);
- }
- else
- log_info(_("WARNING: \"%s\" is a deprecated option\n"),option);
-
- log_info(_("please use \"%s%s\" instead\n"),repl1,repl2);
-}
-
-const char *
-compress_algo_to_string(int algo)
-{
- const char *s="?";
-
- switch(algo)
- {
- case 0:
- s="Uncompressed";
- break;
-
- case 1:
- s="ZIP";
- break;
-
- case 2:
- s="ZLIB";
- break;
- }
-
- return s;
-}
-
-int
-string_to_compress_algo(const char *string)
-{
- if(ascii_strcasecmp(string,"uncompressed")==0)
- return 0;
- else if(ascii_strcasecmp(string,"zip")==0)
- return 1;
- else if(ascii_strcasecmp(string,"zlib")==0)
- return 2;
- else if(ascii_strcasecmp(string,"z0")==0)
- return 0;
- else if(ascii_strcasecmp(string,"z1")==0)
- return 1;
- else if(ascii_strcasecmp(string,"z2")==0)
- return 2;
- else
- return -1;
-}
-
-int
-check_compress_algo(int algo)
-{
- if(algo>=0 && algo<=2)
- return 0;
-
- return GPG_ERR_COMPR_ALGO;
-}
-
-int
-default_cipher_algo(void)
-{
- if(opt.def_cipher_algo)
- return opt.def_cipher_algo;
- else if(opt.personal_cipher_prefs)
- return opt.personal_cipher_prefs[0].value;
- else
- return opt.s2k_cipher_algo;
-}
-
-/* There is no default_digest_algo function, but see
- sign.c:hash_for */
-
-int
-default_compress_algo(void)
-{
- if(opt.def_compress_algo!=-1)
- return opt.def_compress_algo;
- else if(opt.personal_compress_prefs)
- return opt.personal_compress_prefs[0].value;
- else
- return DEFAULT_COMPRESS_ALGO;
-}
-
-const char *
-compliance_option_string(void)
-{
- switch(opt.compliance)
- {
- case CO_RFC2440:
- return "--openpgp";
- case CO_PGP2:
- return "--pgp2";
- case CO_PGP6:
- return "--pgp6";
- case CO_PGP7:
- return "--pgp7";
- case CO_PGP8:
- return "--pgp8";
- default:
- return "???";
- }
-}
-
-static const char *
-compliance_string(void)
-{
- switch(opt.compliance)
- {
- case CO_RFC2440:
- return "OpenPGP";
- case CO_PGP2:
- return "PGP 2.x";
- case CO_PGP6:
- return "PGP 6.x";
- case CO_PGP7:
- return "PGP 7.x";
- case CO_PGP8:
- return "PGP 8.x";
- default:
- return "???";
- }
-}
-
-void
-compliance_failure(void)
-{
- log_info(_("this message may not be usable by %s\n"),compliance_string());
- opt.compliance=CO_GNUPG;
-}
-
-int
-parse_options(char *str,unsigned int *options,struct parse_options *opts)
-{
- char *tok;
-
- while((tok=strsep(&str," ,")))
- {
- int i,rev=0;
-
- if(tok[0]=='\0')
- continue;
-
- if(ascii_strncasecmp("no-",tok,3)==0)
- {
- rev=1;
- tok+=3;
- }
-
- for(i=0;opts[i].name;i++)
- {
- if(ascii_strcasecmp(opts[i].name,tok)==0)
- {
- if(rev)
- *options&=~opts[i].bit;
- else
- *options|=opts[i].bit;
- break;
- }
- }
-
- if(!opts[i].name)
- return 0;
- }
-
- return 1;
-}
-
-
-
-/* Temporary helper. */
-int
-pubkey_get_npkey( int algo )
-{
- size_t n;
-
- if (algo == GCRY_PK_ELG_E)
- algo = GCRY_PK_ELG;
- if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &n))
- n = 0;
- return n;
-}
-
-/* Temporary helper. */
-int
-pubkey_get_nskey( int algo )
-{
- size_t n;
-
- if (algo == GCRY_PK_ELG_E)
- algo = GCRY_PK_ELG;
- if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &n ))
- n = 0;
- return n;
-}
-
-/* Temporary helper. */
-int
-pubkey_get_nsig( int algo )
-{
- size_t n;
-
- if (algo == GCRY_PK_ELG_E)
- algo = GCRY_PK_ELG;
- if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSIGN, NULL, &n))
- n = 0;
- return n;
-}
-
-/* Temporary helper. */
-int
-pubkey_get_nenc( int algo )
-{
- size_t n;
-
- if (algo == GCRY_PK_ELG_E)
- algo = GCRY_PK_ELG;
- if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NENCR, NULL, &n ))
- n = 0;
- return n;
-}
-
-
-/* Temporary helper. */
-unsigned int
-pubkey_nbits( int algo, gcry_mpi_t *key )
-{
- int rc, nbits;
- gcry_sexp_t sexp;
-
- if( algo == GCRY_PK_DSA ) {
- rc = gcry_sexp_build ( &sexp, NULL,
- "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
- key[0], key[1], key[2], key[3] );
- }
- else if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) {
- rc = gcry_sexp_build ( &sexp, NULL,
- "(public-key(elg(p%m)(g%m)(y%m)))",
- key[0], key[1], key[2] );
- }
- else if( algo == GCRY_PK_RSA ) {
- rc = gcry_sexp_build ( &sexp, NULL,
- "(public-key(rsa(n%m)(e%m)))",
- key[0], key[1] );
- }
- else
- return 0;
-
- if ( rc )
- BUG ();
-
- nbits = gcry_pk_get_nbits( sexp );
- gcry_sexp_release( sexp );
- return nbits;
-}
-
-
-/* MPI helper functions. */
-
-
-/****************
- * write an mpi to out.
- */
-int
-mpi_write( iobuf_t out, gcry_mpi_t a )
-{
- char buffer[(MAX_EXTERN_MPI_BITS+7)/8];
- size_t nbytes;
- int rc;
-
- nbytes = (MAX_EXTERN_MPI_BITS+7)/8;
- rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a );
- if( !rc )
- rc = iobuf_write( out, buffer, nbytes );
-
- return rc;
-}
-
-/****************
- * Writyeg a MPI to out, but in this case it is an opaque one,
- * s used vor v3 protected keys.
- */
-int
-mpi_write_opaque( iobuf_t out, gcry_mpi_t a )
-{
- size_t nbytes, nbits;
- int rc;
- char *p;
-
- assert( gcry_mpi_get_flag( a, GCRYMPI_FLAG_OPAQUE ) );
- p = gcry_mpi_get_opaque( a, &nbits );
- nbytes = (nbits+7) / 8;
- iobuf_put( out, nbits >> 8 );
- iobuf_put( out, nbits );
- rc = iobuf_write( out, p, nbytes );
- return rc;
-}
-
-
-/****************
- * Read an external representation of an mpi and return the MPI
- * The external format is a 16 bit unsigned value stored in network byte order,
- * giving the number of bits for the following integer. The integer is stored
- * with MSB first (left padded with zeroes to align on a byte boundary).
- */
-gcry_mpi_t
-mpi_read(iobuf_t inp, unsigned int *ret_nread, int secure)
-{
- int c, c1, c2, i;
- unsigned int nbits, nbytes, nread=0;
- gcry_mpi_t a = NULL;
- byte *buf = NULL;
- byte *p;
-
- if( (c = c1 = iobuf_get(inp)) == -1 )
- goto leave;
- nbits = c << 8;
- if( (c = c2 = iobuf_get(inp)) == -1 )
- goto leave;
- nbits |= c;
- if( nbits > MAX_EXTERN_MPI_BITS ) {
- log_error("mpi too large (%u bits)\n", nbits);
- goto leave;
- }
- nread = 2;
- nbytes = (nbits+7) / 8;
- buf = secure? gcry_xmalloc_secure( nbytes+2 ) : gcry_xmalloc( nbytes+2 );
- p = buf;
- p[0] = c1;
- p[1] = c2;
- for( i=0 ; i < nbytes; i++ ) {
- p[i+2] = iobuf_get(inp) & 0xff;
- nread++;
- }
- nread += nbytes;
- if( gcry_mpi_scan( &a, GCRYMPI_FMT_PGP, buf, nread, &nread ) )
- a = NULL;
-
- leave:
- gcry_free(buf);
- if( nread > *ret_nread )
- log_bug("mpi larger than packet");
- else
- *ret_nread = nread;
- return a;
-}
-
-/****************
- * Same as mpi_read but the value is stored as an opaque MPI.
- * This function is used to read encrypted MPI of v3 packets.
- */
-gcry_mpi_t
-mpi_read_opaque(iobuf_t inp, unsigned *ret_nread )
-{
- int c, c1, c2, i;
- unsigned nbits, nbytes, nread=0;
- gcry_mpi_t a = NULL;
- byte *buf = NULL;
- byte *p;
-
- if( (c = c1 = iobuf_get(inp)) == -1 )
- goto leave;
- nbits = c << 8;
- if( (c = c2 = iobuf_get(inp)) == -1 )
- goto leave;
- nbits |= c;
- if( nbits > MAX_EXTERN_MPI_BITS ) {
- log_error("mpi too large (%u bits)\n", nbits);
- goto leave;
- }
- nread = 2;
- nbytes = (nbits+7) / 8;
- buf = gcry_xmalloc( nbytes );
- p = buf;
- for( i=0 ; i < nbytes; i++ ) {
- p[i] = iobuf_get(inp) & 0xff;
- }
- nread += nbytes;
- a = gcry_mpi_set_opaque(NULL, buf, nbits );
- buf = NULL;
-
- leave:
- gcry_free(buf);
- if( nread > *ret_nread )
- log_bug("mpi larger than packet");
- else
- *ret_nread = nread;
- return a;
-}
-
-
-int
-mpi_print( FILE *fp, gcry_mpi_t a, int mode )
-{
- int n=0;
-
- if( !a )
- return fprintf(fp, "[MPI_NULL]");
- if( !mode ) {
- unsigned int n1;
- n1 = gcry_mpi_get_nbits(a);
- n += fprintf(fp, "[%u bits]", n1);
- }
- else {
- int rc;
- unsigned char *buffer;
-
- rc = gcry_mpi_aprint( GCRYMPI_FMT_HEX, &buffer, NULL, a );
- assert( !rc );
- fputs( buffer, fp );
- n += strlen(buffer);
- gcry_free( buffer );
- }
- return n;
-}
-
-
diff --git a/g10/mkdtemp.c b/g10/mkdtemp.c
deleted file mode 100644
index 55e5b189f..000000000
--- a/g10/mkdtemp.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* mkdtemp.c - libc replacement function
- * Copyright (C) 2001 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-/* This is a replacement function for mkdtemp in case the platform
- we're building on (like mine!) doesn't have it. */
-
-#include <config.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "types.h"
-#include "cipher.h"
-
-#ifdef MKDIR_TAKES_ONE_ARG
-# undef mkdir
-# define mkdir(a,b) mkdir(a)
-#endif
-
-char *mkdtemp(char *template)
-{
- unsigned int attempts,idx,count=0;
- byte *ch;
-
- idx=strlen(template);
-
- /* Walk backwards to count all the Xes */
- while(idx>0 && template[idx-1]=='X')
- {
- count++;
- idx--;
- }
-
- if(count==0)
- {
- errno=EINVAL;
- return NULL;
- }
-
- ch=&template[idx];
-
- /* Try 4 times to make the temp directory */
- for(attempts=0;attempts<4;attempts++)
- {
- unsigned int remaining=count;
- char *marker=ch;
- byte *randombits;
-
- idx=0;
-
- /* Using really random bits is probably overkill here. The
- worst thing that can happen with a directory name collision
- is that the function will return an error. */
-
- randombits=get_random_bits(4*remaining,0,0);
-
- while(remaining>1)
- {
- sprintf(marker,"%02X",randombits[idx++]);
- marker+=2;
- remaining-=2;
- }
-
- /* Any leftover Xes? get_random_bits rounds up to full bytes,
- so this is safe. */
- if(remaining>0)
- sprintf(marker,"%X",randombits[idx]&0xF);
-
- xfree (randombits);
-
- if(mkdir(template,0700)==0)
- break;
- }
-
- if(attempts==4)
- return NULL; /* keeps the errno from mkdir, whatever it is */
-
- return template;
-}
diff --git a/g10/openfile.c b/g10/openfile.c
deleted file mode 100644
index 7dbbf7d6a..000000000
--- a/g10/openfile.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/* openfile.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "memory.h"
-#include "ttyio.h"
-#include "options.h"
-#include "main.h"
-#include "status.h"
-#include "i18n.h"
-
-#ifdef USE_ONLY_8DOT3
-#define SKELEXT ".skl"
-#else
-#define SKELEXT EXTSEP_S "skel"
-#endif
-
-#if defined (HAVE_DRIVE_LETTERS) || defined (__riscos__)
-#define CMP_FILENAME(a,b) ascii_strcasecmp( (a), (b) )
-#else
-#define CMP_FILENAME(a,b) strcmp( (a), (b) )
-#endif
-
-#ifdef MKDIR_TAKES_ONE_ARG
-#undef mkdir
-#define mkdir(a,b) mkdir(a)
-#endif
-
-/* FIXME: Implement opt.interactive. */
-
-/****************
- * Check whether FNAME exists and ask if it's okay to overwrite an
- * existing one.
- * Returns: True: it's okay to overwrite or the file does not exist
- * False: Do not overwrite
- */
-int
-overwrite_filep( const char *fname )
-{
- if( !fname || (*fname == '-' && !fname[1]) )
- return 1; /* writing to stdout is always okay */
-
- if( access( fname, F_OK ) )
- return 1; /* does not exist */
-
-#ifndef HAVE_DOSISH_SYSTEM
- if ( !strcmp ( fname, "/dev/null" ) )
- return 1; /* does not do any harm */
-#endif
-
- /* fixme: add some backup stuff in case of overwrite */
- if( opt.answer_yes )
- return 1;
- if( opt.answer_no || opt.batch )
- return 0; /* do not overwrite */
-
- tty_printf(_("File `%s' exists. "), fname);
- if( cpr_get_answer_is_yes("openfile.overwrite.okay",
- _("Overwrite (y/N)? ")) )
- return 1;
- return 0;
-}
-
-
-/****************
- * Strip know extensions from iname and return a newly allocated
- * filename. Return NULL if we can't do that.
- */
-char *
-make_outfile_name( const char *iname )
-{
- size_t n;
-
- if( (!iname || (*iname=='-' && !iname[1]) ))
- return xstrdup ("-");
-
- n = strlen(iname);
- if( n > 4 && ( !CMP_FILENAME(iname+n-4, EXTSEP_S "gpg")
- || !CMP_FILENAME(iname+n-4, EXTSEP_S "pgp")
- || !CMP_FILENAME(iname+n-4, EXTSEP_S "sig")
- || !CMP_FILENAME(iname+n-4, EXTSEP_S "asc") ) ) {
- char *buf = xstrdup ( iname );
- buf[n-4] = 0;
- return buf;
- }
- else if( n > 5 && !CMP_FILENAME(iname+n-5, EXTSEP_S "sign") ) {
- char *buf = xstrdup ( iname );
- buf[n-5] = 0;
- return buf;
- }
-
- log_info(_("%s: unknown suffix\n"), iname );
- return NULL;
-}
-
-
-/****************
- * Ask for a outputfilename and use the given one as default.
- * Return NULL if no file has been given or it is not possible to
- * ask the user.
- */
-char *
-ask_outfile_name( const char *name, size_t namelen )
-{
- size_t n;
- const char *s;
- char *prompt;
- char *fname;
- char *defname;
-
- if( opt.batch )
- return NULL;
-
- s = _("Enter new filename");
-
- n = strlen(s) + namelen + 10;
- defname = name && namelen? make_printable_string( name, namelen, 0): NULL;
- prompt = xmalloc (n);
- if( defname )
- sprintf(prompt, "%s [%s]: ", s, defname );
- else
- sprintf(prompt, "%s: ", s );
- fname = cpr_get("openfile.askoutname", prompt );
- cpr_kill_prompt();
- xfree (prompt);
- if( !*fname ) {
- xfree ( fname ); fname = NULL;
- fname = defname; defname = NULL;
- }
- xfree (defname);
- if (fname)
- trim_spaces (fname);
- return fname;
-}
-
-
-/****************
- * Make an output filename for the inputfile INAME.
- * Returns an iobuf_t and an errorcode
- * Mode 0 = use ".gpg"
- * 1 = use ".asc"
- * 2 = use ".sig"
- */
-int
-open_outfile( const char *iname, int mode, iobuf_t *a )
-{
- int rc = 0;
-
- *a = NULL;
- if( (!iname || (*iname=='-' && !iname[1])) && !opt.outfile ) {
- if( !(*a = iobuf_create(NULL)) ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("%s: can't open: %s\n"), "[stdout]", strerror(errno) );
- }
- else if( opt.verbose )
- log_info(_("writing to stdout\n"));
- }
- else {
- char *buf = NULL;
- const char *name;
-
- if( opt.dry_run )
- name = "/dev/null";
- else if( opt.outfile )
- name = opt.outfile;
- else {
-#ifdef USE_ONLY_8DOT3
- if (opt.mangle_dos_filenames)
- {
- /* It is quite common DOS system to have only one dot in a
- * a filename So if we have something like this, we simple
- * replace the suffix execpt in cases where the suffix is
- * larger than 3 characters and not the same as.
- * We should really map the filenames to 8.3 but this tends to
- * be more complicated and is probaly a duty of the filesystem
- */
- char *dot;
- const char *newsfx = mode==1 ? ".asc" :
- mode==2 ? ".sig" : ".gpg";
-
- buf = xmalloc (strlen(iname)+4+1);
- strcpy(buf,iname);
- dot = strchr(buf, '.' );
- if ( dot && dot > buf && dot[1] && strlen(dot) <= 4
- && CMP_FILENAME(newsfx, dot) )
- {
- strcpy(dot, newsfx );
- }
- else if ( dot && !dot[1] ) /* don't duplicate a dot */
- strcpy( dot, newsfx+1 );
- else
- strcat ( buf, newsfx );
- }
- if (!buf)
-#endif /* USE_ONLY_8DOT3 */
- {
- buf = xmalloc (strlen(iname)+4+1);
- strcpy(stpcpy(buf,iname), mode==1 ? EXTSEP_S "asc" :
- mode==2 ? EXTSEP_S "sig" : EXTSEP_S "gpg");
- }
- name = buf;
- }
-
- rc = 0;
- while( !overwrite_filep (name) )
- {
- char *tmp = ask_outfile_name (NULL, 0);
- if ( !tmp || !*tmp )
- {
- xfree (tmp);
- rc = GPG_ERR_EEXIST;
- break;
- }
- xfree (buf);
- name = buf = tmp;
- }
-
- if( !rc )
- {
- if( !(*a = iobuf_create( name )) )
- {
- rc = gpg_error_from_errno (errno);
- log_error(_("%s: can't create: %s\n"), name, strerror(errno) );
- }
- else if( opt.verbose )
- log_info(_("writing to `%s'\n"), name );
- }
- xfree (buf);
- }
-
- return rc;
-}
-
-
-/****************
- * Try to open a file without the extension ".sig" or ".asc"
- * Return NULL if such a file is not available.
- */
-iobuf_t
-open_sigfile( const char *iname, progress_filter_context_t *pfx )
-{
- iobuf_t a = NULL;
- size_t len;
-
- if( iname && !(*iname == '-' && !iname[1]) ) {
- len = strlen(iname);
- if( len > 4 && ( !strcmp(iname + len - 4, EXTSEP_S "sig")
- || ( len > 5 && !strcmp(iname + len - 5, EXTSEP_S "sign") )
- || !strcmp(iname + len - 4, EXTSEP_S "asc")) ) {
- char *buf;
- buf = xstrdup (iname);
- buf[len-(buf[len-1]=='n'?5:4)] = 0 ;
- a = iobuf_open( buf );
- if( a && opt.verbose )
- log_info(_("assuming signed data in `%s'\n"), buf );
- if (a && pfx)
- handle_progress (pfx, a, buf);
- xfree (buf);
- }
- }
- return a;
-}
-
-/****************
- * Copy the option file skeleton to the given directory.
- */
-static void
-copy_options_file( const char *destdir )
-{
- const char *datadir = GNUPG_DATADIR;
- char *fname;
- FILE *src, *dst;
- int linefeeds=0;
- int c;
- mode_t oldmask;
- int esc = 0;
- int any_option = 0;
-
- if( opt.dry_run )
- return;
-
- fname = xmalloc ( strlen(datadir) + strlen(destdir) + 15 );
- strcpy(stpcpy(fname, datadir), DIRSEP_S "options" SKELEXT );
- src = fopen( fname, "r" );
- if( !src ) {
- log_error(_("%s: can't open: %s\n"), fname, strerror(errno) );
- xfree (fname);
- return;
- }
- strcpy(stpcpy(fname, destdir), DIRSEP_S "gpg" EXTSEP_S "conf" );
- oldmask=umask(077);
- dst = fopen( fname, "w" );
- umask(oldmask);
- if( !dst ) {
- log_error(_("%s: can't create: %s\n"), fname, strerror(errno) );
- fclose( src );
- xfree (fname);
- return;
- }
-
- while( (c=getc(src)) != EOF ) {
- if( linefeeds < 3 ) {
- if( c == '\n' )
- linefeeds++;
- }
- else {
- putc( c, dst );
- if (c== '\n')
- esc = 1;
- else if (esc == 1) {
- if (c == ' ' || c == '\t')
- ;
- else if (c == '#')
- esc = 2;
- else
- any_option = 1;
- }
- }
- }
- fclose( dst );
- fclose( src );
- log_info(_("new configuration file `%s' created\n"), fname );
- if (any_option)
- log_info (_("WARNING: options in `%s'"
- " are not yet active during this run\n"),
- fname);
- xfree (fname);
-}
-
-
-void
-try_make_homedir( const char *fname )
-{
- const char *defhome = GNUPG_DEFAULT_HOMEDIR;
-
- /* Create the directory only if the supplied directory name
- * is the same as the default one. This way we avoid to create
- * arbitrary directories when a non-default homedirectory is used.
- * To cope with HOME, we do compare only the suffix if we see that
- * the default homedir does start with a tilde.
- */
- if( opt.dry_run || opt.no_homedir_creation )
- return;
-
- if ( ( *defhome == '~'
- && ( strlen(fname) >= strlen (defhome+1)
- && !strcmp(fname+strlen(fname)-strlen(defhome+1),
- defhome+1 ) ))
- || ( *defhome != '~'
- && !compare_filenames( fname, defhome ) )
- ) {
- if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
- log_fatal( _("%s: can't create directory: %s\n"),
- fname, strerror(errno) );
- else if( !opt.quiet )
- log_info( _("%s: directory created\n"), fname );
- copy_options_file( fname );
-/* log_info(_("you have to start GnuPG again, " */
-/* "so it can read the new configuration file\n") ); */
-/* g10_exit(1); */
- }
-}
diff --git a/g10/options.h b/g10/options.h
deleted file mode 100644
index a4cbc3834..000000000
--- a/g10/options.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/* options.h
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef G10_OPTIONS_H
-#define G10_OPTIONS_H
-
-#include <types.h>
-#include "main.h"
-#include "packet.h"
-
-#undef ENABLE_COMMENT_PACKETS /* don't create comment packets */
-
-#ifndef EXTERN_UNLESS_MAIN_MODULE
-/* Norcraft can't cope with common symbols */
-#if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE)
-#define EXTERN_UNLESS_MAIN_MODULE extern
-#else
-#define EXTERN_UNLESS_MAIN_MODULE
-#endif
-#endif
-
-EXTERN_UNLESS_MAIN_MODULE
-struct {
- int verbose;
- int quiet;
- unsigned debug;
- int armor;
- int compress;
- char *outfile;
- int dry_run;
- int list_only;
- int textmode;
- int expert;
- int ask_sig_expire;
- int ask_cert_expire;
- int batch; /* run in batch mode */
- int answer_yes; /* answer yes on most questions */
- int answer_no; /* answer no on most questions */
- int check_sigs; /* check key signatures */
- int with_colons;
- int with_key_data;
- int with_fingerprint; /* opt --with-fingerprint active */
- int fingerprint; /* list fingerprints */
- int list_sigs; /* list signatures */
- int no_armor;
- int list_packets; /* list-packets mode: 1=normal, 2=invoked by command*/
- int def_cipher_algo;
- int force_v3_sigs;
- int force_v4_certs;
- int force_mdc;
- int disable_mdc;
- int def_digest_algo;
- int cert_digest_algo;
- int def_compress_algo;
- const char *def_secret_key;
- char *def_recipient;
- int def_recipient_self;
- int def_cert_check_level;
- int sk_comments;
- int no_version;
- int marginals_needed;
- int completes_needed;
- int max_cert_depth;
- const char *homedir;
- const char *agent_program;
- char *display; /* 5 options to be passed to the gpg-agent */
- char *ttyname;
- char *ttytype;
- char *lc_ctype;
- char *lc_messages;
-
- int skip_verify;
- int compress_keys;
- int compress_sigs;
- /* TM_CLASSIC must be zero to accomodate trustdbs generated before
- we started storing the trust model inside the trustdb. */
- enum {TM_CLASSIC=0, TM_PGP=1, TM_ALWAYS, TM_AUTO} trust_model;
- unsigned int force_ownertrust;
- enum
- {
- CO_GNUPG=0, CO_RFC2440, CO_RFC1991, CO_PGP2, CO_PGP6, CO_PGP7, CO_PGP8
- } compliance;
- int pgp2_workarounds;
- unsigned int emulate_bugs; /* bug emulation flags EMUBUG_xxxx */
- int shm_coprocess;
- const char *set_filename;
- STRLIST comments;
- int throw_keyid;
- const char *photo_viewer;
- int s2k_mode;
- int s2k_digest_algo;
- int s2k_cipher_algo;
- int simple_sk_checksum; /* create the deprecated rfc2440 secret
- key protection*/
- int not_dash_escaped;
- int escape_from;
- int lock_once;
- char *keyserver_uri;
- char *keyserver_scheme;
- char *keyserver_host;
- char *keyserver_port;
- char *keyserver_opaque;
- struct
- {
- int verbose;
- int include_revoked;
- int include_disabled;
- int include_subkeys;
- int honor_http_proxy;
- int broken_http_proxy;
- int use_temp_files;
- int keep_temp_files;
- int fake_v3_keyids;
- int auto_key_retrieve;
- int try_dns_srv;
- unsigned int import_options;
- unsigned int export_options;
- STRLIST other;
- } keyserver_options;
- int exec_disable;
- int exec_path_set;
- unsigned int import_options;
- unsigned int export_options;
- unsigned int list_options;
- unsigned int verify_options;
- char *def_preference_list;
- prefitem_t *personal_cipher_prefs;
- prefitem_t *personal_digest_prefs;
- prefitem_t *personal_compress_prefs;
- int no_perm_warn;
- int no_mdc_warn;
- char *temp_dir;
- int no_encrypt_to;
- int interactive;
- STRLIST sig_notation_data;
- STRLIST cert_notation_data;
- STRLIST sig_policy_url;
- STRLIST cert_policy_url;
- STRLIST sig_keyserver_url;
- int use_embedded_filename;
- int allow_non_selfsigned_uid;
- int allow_freeform_uid;
- int no_literal;
- ulong set_filesize;
- int fast_list_mode;
- int fixed_list_mode;
- int ignore_time_conflict;
- int ignore_valid_from;
- int ignore_crc_error;
- int ignore_mdc_error;
- int command_fd;
- const char *override_session_key;
- int show_session_key;
- int use_agent;
- const char *gpg_agent_info;
- int merge_only;
- int try_all_secrets;
- int no_expensive_trust_checks;
- int no_sig_cache;
- int no_sig_create_check;
- int no_auto_check_trustdb;
- int preserve_permissions;
- int no_homedir_creation;
- struct groupitem *grouplist;
- int strict;
- int mangle_dos_filenames;
- int enable_progress_filter;
-} opt;
-
-
-#define EMUBUG_MDENCODE 4
-
-#define DBG_PACKET_VALUE 1 /* debug packet reading/writing */
-#define DBG_MPI_VALUE 2 /* debug mpi details */
-#define DBG_CIPHER_VALUE 4 /* debug cipher handling */
- /* (may reveal sensitive data) */
-#define DBG_FILTER_VALUE 8 /* debug internal filter handling */
-#define DBG_IOBUF_VALUE 16 /* debug iobuf stuff */
-#define DBG_MEMORY_VALUE 32 /* debug memory allocation stuff */
-#define DBG_CACHE_VALUE 64 /* debug the cacheing */
-#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */
-#define DBG_TRUST_VALUE 256 /* debug the trustdb */
-#define DBG_HASHING_VALUE 512 /* debug hashing operations */
-#define DBG_EXTPROG_VALUE 1024 /* debug external program calls */
-
-
-#define DBG_PACKET (opt.debug & DBG_PACKET_VALUE)
-#define DBG_CIPHER (opt.debug & DBG_CIPHER_VALUE)
-#define DBG_FILTER (opt.debug & DBG_FILTER_VALUE)
-#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE)
-#define DBG_TRUST (opt.debug & DBG_TRUST_VALUE)
-#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
-#define DBG_EXTPROG (opt.debug & DBG_EXTPROG_VALUE)
-
-#define GNUPG (opt.compliance==CO_GNUPG)
-#define RFC1991 (opt.compliance==CO_RFC1991 || opt.compliance==CO_PGP2)
-#define RFC2440 (opt.compliance==CO_RFC2440)
-#define PGP2 (opt.compliance==CO_PGP2)
-#define PGP6 (opt.compliance==CO_PGP6)
-#define PGP7 (opt.compliance==CO_PGP7)
-#define PGP8 (opt.compliance==CO_PGP8)
-
-/* Various option flags */
-
-#define IMPORT_ALLOW_LOCAL_SIGS 1
-#define IMPORT_REPAIR_PKS_SUBKEY_BUG 2
-#define IMPORT_FAST_IMPORT 4
-#define IMPORT_SK2PK 8
-
-#define EXPORT_INCLUDE_NON_RFC 1
-#define EXPORT_INCLUDE_LOCAL_SIGS 2
-#define EXPORT_INCLUDE_ATTRIBUTES 4
-#define EXPORT_INCLUDE_SENSITIVE_REVKEYS 8
-#define EXPORT_SEXP_FORMAT 16
-
-
-#define LIST_SHOW_PHOTOS 1
-#define LIST_SHOW_POLICY 2
-#define LIST_SHOW_NOTATION 4
-#define LIST_SHOW_KEYSERVER 8
-#define LIST_SHOW_VALIDITY 16
-#define LIST_SHOW_LONG_KEYID 32
-#define LIST_SHOW_KEYRING 64
-#define LIST_SHOW_SIG_EXPIRE 128
-
-
-#define VERIFY_SHOW_PHOTOS 1
-#define VERIFY_SHOW_POLICY 2
-#define VERIFY_SHOW_NOTATION 4
-#define VERIFY_SHOW_KEYSERVER 8
-#define VERIFY_SHOW_VALIDITY 16
-#define VERIFY_SHOW_LONG_KEYID 32
-
-#endif /*G10_OPTIONS_H*/
-
-
-
-
diff --git a/g10/options.skel b/g10/options.skel
deleted file mode 100644
index 3d15f811c..000000000
--- a/g10/options.skel
+++ /dev/null
@@ -1,212 +0,0 @@
-# These first three lines are not copied to the gpg.conf file in
-# the users home directory.
-# $Id$
-# Options for GnuPG
-# Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-#
-# This file is free software; as a special exception the author gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# This file is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#
-# Unless you specify which option file to use (with the command line
-# option "--options filename"), GnuPG uses the file ~/.gnupg/gpg.conf
-# by default.
-#
-# An options file can contain any long options which are available in
-# GnuPG. If the first non white space character of a line is a '#',
-# this line is ignored. Empty lines are also ignored.
-#
-# See the man page for a list of options.
-
-# Uncomment the following option to get rid of the copyright notice
-
-#no-greeting
-
-# If you have more than 1 secret key in your keyring, you may want to
-# uncomment the following option and set your preferred keyid.
-
-#default-key 621CC013
-
-# If you do not pass a recipient to gpg, it will ask for one. Using
-# this option you can encrypt to a default key. Key validation will
-# not be done in this case. The second form uses the default key as
-# default recipient.
-
-#default-recipient some-user-id
-#default-recipient-self
-
-# By default GnuPG creates version 3 signatures for data files. This
-# is not strictly OpenPGP compliant but PGP 6 and most versions of PGP
-# 7 require them. To disable this behavior, you may use this option
-# or --openpgp.
-
-#no-force-v3-sigs
-
-# Because some mailers change lines starting with "From " to ">From "
-# it is good to handle such lines in a special way when creating
-# cleartext signatures; all other PGP versions do it this way too.
-# To enable full OpenPGP compliance you may want to use this option.
-
-#no-escape-from-lines
-
-# If you do not use the Latin-1 (ISO-8859-1) charset, you should tell
-# GnuPG which is the native character set. Please check the man page
-# for supported character sets. This character set is only used for
-# metadata and not for the actual message which does not undergo any
-# translation. Note that future version of GnuPG will change to UTF-8
-# as default character set.
-
-#charset utf-8
-
-# Group names may be defined like this:
-# group mynames = paige 0x12345678 joe patti
-#
-# Any time "mynames" is a recipient (-r or --recipient), it will be
-# expanded to the names "paige", "joe", and "patti", and the key ID
-# "0x12345678". Note there is only one level of expansion - you
-# cannot make an group that points to another group. Note also that
-# if there are spaces in the recipient name, this will appear as two
-# recipients. In these cases it is better to use the key ID.
-
-#group mynames = paige 0x12345678 joe patti
-
-# Some old Windows platforms require 8.3 filenames. If your system
-# can handle long filenames, uncomment this.
-
-#no-mangle-dos-filenames
-
-# Lock the file only once for the lifetime of a process. If you do
-# not define this, the lock will be obtained and released every time
-# it is needed - normally this is not needed.
-
-#lock-once
-
-# GnuPG can send and receive keys to and from a keyserver. These
-# servers can be HKP, email, or LDAP (if GnuPG is built with LDAP
-# support).
-#
-# Example HKP keyserver:
-# hkp://subkeys.pgp.net
-#
-# Example email keyserver:
-#
-# Example LDAP keyservers:
-# ldap://pgp.surfnet.nl:11370
-# ldap://keyserver.pgp.com
-#
-# Regular URL syntax applies, and you can set an alternate port
-# through the usual method:
-# hkp://keyserver.example.net:22742
-#
-# If you have problems connecting to a HKP server through a buggy http
-# proxy, you can use keyserver option broken-http-proxy (see below),
-# but first you should make sure that you have read the man page
-# regarding proxies (keyserver option honor-http-proxy)
-#
-# Most users just set the name and type of their preferred keyserver.
-# Note that most servers (with the notable exception of
-# ldap://keyserver.pgp.com) synchronize changes with each other. Note
-# also that a single server name may actually point to multiple
-# servers via DNS round-robin. hkp://subkeys.pgp.net is an example of
-# such a "server", which spreads the load over a number of physical
-# servers.
-
-keyserver hkp://subkeys.pgp.net
-#keyserver mailto:[email protected]
-#keyserver ldap://pgp.surfnet.nl:11370
-#keyserver ldap://keyserver.pgp.com
-
-# Common options for keyserver functions:
-#
-# include-disabled = when searching, include keys marked as "disabled"
-# on the keyserver (not all keyservers support this).
-#
-# no-include-revoked = when searching, do not include keys marked as
-# "revoked" on the keyserver.
-#
-# verbose = show more information as the keys are fetched.
-# Can be used more than once to increase the amount
-# of information shown.
-#
-# use-temp-files = use temporary files instead of a pipe to talk to the
-# keyserver. Some platforms (Win32 for one) always
-# have this on.
-#
-# keep-temp-files = do not delete temporary files after using them
-# (really only useful for debugging)
-#
-# honor-http-proxy = if the keyserver uses HTTP, honor the http_proxy
-# environment variable
-#
-# broken-http-proxy = try to work around a buggy HTTP proxy
-#
-# auto-key-retrieve = automatically fetch keys as needed from the keyserver
-# when verifying signatures or when importing keys that
-# have been revoked by a revocation key that is not
-# present on the keyring.
-#
-# no-include-attributes = do not include attribute IDs (aka "photo IDs")
-# when sending keys to the keyserver.
-
-#keyserver-options auto-key-retrieve
-
-# Uncomment this line to display photo user IDs in key listings and
-# when a signature from a key with a photo is verified.
-
-#show-photos
-
-# Use this program to display photo user IDs
-#
-# %i is expanded to a temporary file that contains the photo.
-# %I is the same as %i, but the file isn't deleted afterwards by GnuPG.
-# %k is expanded to the key ID of the key.
-# %K is expanded to the long OpenPGP key ID of the key.
-# %t is expanded to the extension of the image (e.g. "jpg").
-# %T is expanded to the MIME type of the image (e.g. "image/jpeg").
-# %f is expanded to the fingerprint of the key.
-# %% is %, of course.
-#
-# If %i or %I are not present, then the photo is supplied to the
-# viewer on standard input. If your platform supports it, standard
-# input is the best way to do this as it avoids the time and effort in
-# generating and then cleaning up a secure temp file.
-#
-# The default program is "xloadimage -fork -quiet -title 'KeyID 0x%k' stdin"
-# On Mac OS X and Windows, the default is to use your regular JPEG image
-# viewer.
-#
-# Some other viewers:
-# photo-viewer "qiv %i"
-# photo-viewer "ee %i"
-# photo-viewer "display -title 'KeyID 0x%k'"
-#
-# This one saves a copy of the photo ID in your home directory:
-# photo-viewer "cat > ~/photoid-for-key-%k.%t"
-#
-# Use your MIME handler to view photos:
-# photo-viewer "metamail -q -d -b -c %T -s 'KeyID 0x%k' -f GnuPG"
-
-# Passphrase agent
-#
-# We support the old experimental passphrase agent protocol as well as
-# the new Assuan based one (currently available in the "newpg" package
-# at ftp.gnupg.org/gcrypt/alpha/aegypten/). To make use of the agent,
-# you have to run an agent as daemon and use the option
-#
-# use-agent
-#
-# which tries to use the agent but will fallback to the regular mode
-# if there is a problem connecting to the agent. The normal way to
-# locate the agent is by looking at the environment variable
-# GPG_AGENT_INFO which should have been set during gpg-agent startup.
-# In certain situations the use of this variable is not possible, thus
-# the option
-#
-# --gpg-agent-info=<path>:<pid>:1
-#
-# may be used to override it.
diff --git a/g10/packet.h b/g10/packet.h
deleted file mode 100644
index 2d87c9c7d..000000000
--- a/g10/packet.h
+++ /dev/null
@@ -1,514 +0,0 @@
-/* packet.h - packet definitions
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef G10_PACKET_H
-#define G10_PACKET_H
-
-#include "gpg.h"
-#include <gcrypt.h>
-
-#include "types.h"
-#include "../common/iobuf.h"
-#include "../jnlib/strlist.h"
-#include "cipher.h"
-#include "filter.h"
-#include "global.h"
-
-#define DEBUG_PARSE_PACKET 1
-
-typedef enum {
- PKT_NONE =0,
- PKT_PUBKEY_ENC =1, /* public key encrypted packet */
- PKT_SIGNATURE =2, /* secret key encrypted packet */
- PKT_SYMKEY_ENC =3, /* session key packet (OpenPGP)*/
- PKT_ONEPASS_SIG =4, /* one pass sig packet (OpenPGP)*/
- PKT_SECRET_KEY =5, /* secret key */
- PKT_PUBLIC_KEY =6, /* public key */
- PKT_SECRET_SUBKEY =7, /* secret subkey (OpenPGP) */
- PKT_COMPRESSED =8, /* compressed data packet */
- PKT_ENCRYPTED =9, /* conventional encrypted data */
- PKT_MARKER =10, /* marker packet (OpenPGP) */
- PKT_PLAINTEXT =11, /* plaintext data with filename and mode */
- PKT_RING_TRUST =12, /* keyring trust packet */
- PKT_USER_ID =13, /* user id packet */
- PKT_PUBLIC_SUBKEY =14, /* public subkey (OpenPGP) */
- PKT_OLD_COMMENT =16, /* comment packet from an OpenPGP draft */
- PKT_ATTRIBUTE =17, /* PGP's attribute packet */
- PKT_ENCRYPTED_MDC =18, /* integrity protected encrypted data */
- PKT_MDC =19, /* manipulation detection code packet */
- PKT_COMMENT =61, /* new comment packet (private) */
- PKT_GPG_CONTROL =63 /* internal control packet */
-} pkttype_t;
-
-typedef struct packet_struct PACKET;
-
-/* PKT_GPG_CONTROL types */
-typedef enum {
- CTRLPKT_CLEARSIGN_START = 1,
- CTRLPKT_PIPEMODE = 2,
- CTRLPKT_PLAINTEXT_MARK =3
-} ctrlpkttype_t;
-
-typedef enum {
- PREFTYPE_NONE = 0,
- PREFTYPE_SYM = 1,
- PREFTYPE_HASH = 2,
- PREFTYPE_ZIP = 3
-} preftype_t;
-
-typedef struct {
- byte type;
- byte value;
-} prefitem_t;
-
-typedef struct {
- int mode;
- byte hash_algo;
- byte salt[8];
- u32 count;
-} STRING2KEY;
-
-typedef struct {
- byte version;
- byte cipher_algo; /* cipher algorithm used */
- STRING2KEY s2k;
- byte seskeylen; /* keylength in byte or 0 for no seskey */
- byte seskey[1];
-} PKT_symkey_enc;
-
-typedef struct {
- u32 keyid[2]; /* 64 bit keyid */
- byte version;
- byte pubkey_algo; /* algorithm used for public key scheme */
- byte throw_keyid;
- gcry_mpi_t data[PUBKEY_MAX_NENC];
-} PKT_pubkey_enc;
-
-
-typedef struct {
- u32 keyid[2]; /* 64 bit keyid */
- byte sig_class; /* sig classification */
- byte digest_algo; /* algorithm used for digest */
- byte pubkey_algo; /* algorithm used for public key scheme */
- byte last; /* a stupid flag */
-} PKT_onepass_sig;
-
-
-typedef struct {
- size_t size; /* allocated */
- size_t len; /* used */
- byte data[1];
-} subpktarea_t;
-
-struct revocation_key {
- byte class;
- byte algid;
- byte fpr[MAX_FINGERPRINT_LEN];
-};
-
-typedef struct {
- ulong local_id; /* internal use, valid if > 0 */
- struct {
- unsigned checked:1; /* signature has been checked */
- unsigned valid:1; /* signature is good (if checked is set) */
- unsigned unknown_critical:1;
- unsigned exportable:1;
- unsigned revocable:1;
- unsigned policy_url:1; /* At least one policy URL is present */
- unsigned notation:1; /* At least one notation is present */
- unsigned pref_ks:1; /* At least one preferred keyserver is present */
- unsigned expired:1;
- } flags;
- u32 keyid[2]; /* 64 bit keyid */
- u32 timestamp; /* signature made */
- u32 expiredate; /* expires at this date or 0 if not at all */
- byte version;
- byte sig_class; /* sig classification, append for MD calculation*/
- byte pubkey_algo; /* algorithm used for public key scheme */
- /* (PUBKEY_ALGO_xxx) */
- byte digest_algo; /* algorithm used for digest (DIGEST_ALGO_xxxx) */
- byte trust_depth;
- byte trust_value;
- const byte *trust_regexp;
- struct revocation_key **revkey;
- int numrevkeys;
- subpktarea_t *hashed; /* all subpackets with hashed data (v4 only) */
- subpktarea_t *unhashed; /* ditto for unhashed data */
- byte digest_start[2]; /* first 2 bytes of the digest */
- gcry_mpi_t data[PUBKEY_MAX_NSIG];
-} PKT_signature;
-
-#define ATTRIB_IMAGE 1
-
-/* This is the cooked form of attributes */
-struct user_attribute {
- byte type;
- const byte *data;
- u32 len;
-};
-
-typedef struct {
- int ref; /* reference counter */
- int len; /* length of the name */
- struct user_attribute *attribs;
- int numattribs;
- byte *attrib_data; /* if this is not NULL, the packet is an attribute */
- unsigned long attrib_len;
- byte *namehash;
- int help_key_usage;
- u32 help_key_expire;
- int help_full_count;
- int help_marginal_count;
- int is_primary; /* 2 if set via the primary flag, 1 if calculated */
- int is_revoked;
- int is_expired;
- u32 expiredate; /* expires at this date or 0 if not at all */
- prefitem_t *prefs; /* list of preferences (may be NULL)*/
- int mdc_feature;
- int ks_modify;
- u32 created; /* according to the self-signature */
- byte selfsigversion;
- char name[1];
-} PKT_user_id;
-
-
-/****************
- * Note about the pkey/skey elements: We assume that the secret keys
- * has the same elemts as the public key at the begin of the array, so
- * that npkey < nskey and it is possible to compare the secret and
- * public keys by comparing the first npkey elements of pkey against skey.
- */
-typedef struct {
- u32 timestamp; /* key made */
- u32 expiredate; /* expires at this date or 0 if not at all */
- u32 max_expiredate; /* must not expire past this date */
- byte hdrbytes; /* number of header bytes */
- byte version;
- byte selfsigversion; /* highest version of all of the self-sigs */
- byte pubkey_algo; /* algorithm used for public key scheme */
- byte pubkey_usage; /* for now only used to pass it to getkey() */
- byte req_usage; /* hack to pass a request to getkey() */
- byte req_algo; /* Ditto */
- u32 has_expired; /* set to the expiration date if expired */
- int is_revoked; /* key has been revoked */
- int is_valid; /* key (especially subkey) is valid */
- int dont_cache; /* do not cache this */
- ulong local_id; /* internal use, valid if > 0 */
- u32 main_keyid[2]; /* keyid of the primary key */
- u32 keyid[2]; /* calculated by keyid_from_pk() */
- byte is_primary;
- byte is_disabled; /* 0 for unset, 1 for enabled, 2 for disabled. */
- prefitem_t *prefs; /* list of preferences (may be NULL) */
- int mdc_feature; /* mdc feature set */
- PKT_user_id *user_id; /* if != NULL: found by that uid */
- struct revocation_key *revkey;
- int numrevkeys;
- u32 trust_timestamp;
- byte trust_depth;
- byte trust_value;
- const byte *trust_regexp;
- gcry_mpi_t pkey[PUBKEY_MAX_NPKEY];
-} PKT_public_key;
-
-/* Evaluates as true if the pk is disabled, and false if it isn't. If
- there is no disable value cached, fill one in. */
-#define pk_is_disabled(a) (((a)->is_disabled)?((a)->is_disabled==2):(cache_disabled_value((a))))
-
-typedef struct {
- u32 timestamp; /* key made */
- u32 expiredate; /* expires at this date or 0 if not at all */
- u32 max_expiredate; /* must not expire past this date */
- byte hdrbytes; /* number of header bytes */
- byte version;
- byte pubkey_algo; /* algorithm used for public key scheme */
- byte pubkey_usage;
- byte req_usage;
- byte req_algo;
- u32 has_expired; /* set to the expiration date if expired */
- int is_revoked; /* key has been revoked */
- int is_valid; /* key (especially subkey) is valid */
- u32 main_keyid[2]; /* keyid of the primary key */
- u32 keyid[2];
- byte is_primary;
- byte is_protected; /* The secret info is protected and must */
- /* be decrypted before use, the protected */
- /* MPIs are simply (void*) pointers to memory */
- /* and should never be passed to a mpi_xxx() */
- struct {
- byte algo; /* cipher used to protect the secret information*/
- byte sha1chk; /* SHA1 is used instead of a 16 bit checksum */
- STRING2KEY s2k;
- byte ivlen; /* used length of the iv */
- byte iv[16]; /* initialization vector for CFB mode */
- } protect;
- gcry_mpi_t skey[PUBKEY_MAX_NSKEY];
- u16 csum; /* checksum */
-} PKT_secret_key;
-
-
-typedef struct {
- int len; /* length of data */
- char data[1];
-} PKT_comment;
-
-typedef struct {
- u32 len; /* reserved */
- byte new_ctb;
- byte algorithm;
- iobuf_t buf; /* iobuf_t reference */
-} PKT_compressed;
-
-typedef struct {
- u32 len; /* length of encrypted data */
- int extralen; /* this is (blocksize+2) */
- byte new_ctb; /* uses a new CTB */
- byte mdc_method; /* > 0: integrity protected encrypted data packet */
- iobuf_t buf; /* iobuf_t reference */
-} PKT_encrypted;
-
-typedef struct {
- byte hash[20];
-} PKT_mdc;
-
-typedef struct {
- unsigned int trustval;
- unsigned int sigcache;
-} PKT_ring_trust;
-
-typedef struct {
- u32 len; /* length of encrypted data */
- iobuf_t buf; /* iobuf_t reference */
- byte new_ctb;
- byte is_partial; /* partial length encoded */
- int mode;
- u32 timestamp;
- int namelen;
- char name[1];
-} PKT_plaintext;
-
-typedef struct {
- int control;
- size_t datalen;
- char data[1];
-} PKT_gpg_control;
-
-/* combine all packets into a union */
-struct packet_struct {
- pkttype_t pkttype;
- union {
- void *generic;
- PKT_symkey_enc *symkey_enc; /* PKT_SYMKEY_ENC */
- PKT_pubkey_enc *pubkey_enc; /* PKT_PUBKEY_ENC */
- PKT_onepass_sig *onepass_sig; /* PKT_ONEPASS_SIG */
- PKT_signature *signature; /* PKT_SIGNATURE */
- PKT_public_key *public_key; /* PKT_PUBLIC_[SUB)KEY */
- PKT_secret_key *secret_key; /* PKT_SECRET_[SUB]KEY */
- PKT_comment *comment; /* PKT_COMMENT */
- PKT_user_id *user_id; /* PKT_USER_ID */
- PKT_compressed *compressed; /* PKT_COMPRESSED */
- PKT_encrypted *encrypted; /* PKT_ENCRYPTED[_MDC] */
- PKT_mdc *mdc; /* PKT_MDC */
- PKT_ring_trust *ring_trust; /* PKT_RING_TRUST */
- PKT_plaintext *plaintext; /* PKT_PLAINTEXT */
- PKT_gpg_control *gpg_control; /* PKT_GPG_CONTROL */
- } pkt;
-};
-
-#define init_packet(a) do { (a)->pkttype = 0; \
- (a)->pkt.generic = NULL; \
- } while(0)
-
-typedef enum {
- SIGSUBPKT_TEST_CRITICAL=-3,
- SIGSUBPKT_LIST_UNHASHED=-2,
- SIGSUBPKT_LIST_HASHED =-1,
- SIGSUBPKT_NONE = 0,
- SIGSUBPKT_SIG_CREATED = 2, /* signature creation time */
- SIGSUBPKT_SIG_EXPIRE = 3, /* signature expiration time */
- SIGSUBPKT_EXPORTABLE = 4, /* exportable */
- SIGSUBPKT_TRUST = 5, /* trust signature */
- SIGSUBPKT_REGEXP = 6, /* regular expression */
- SIGSUBPKT_REVOCABLE = 7, /* revocable */
- SIGSUBPKT_KEY_EXPIRE = 9, /* key expiration time */
- SIGSUBPKT_ARR =10, /* additional recipient request */
- SIGSUBPKT_PREF_SYM =11, /* preferred symmetric algorithms */
- SIGSUBPKT_REV_KEY =12, /* revocation key */
- SIGSUBPKT_ISSUER =16, /* issuer key ID */
- SIGSUBPKT_NOTATION =20, /* notation data */
- SIGSUBPKT_PREF_HASH =21, /* preferred hash algorithms */
- SIGSUBPKT_PREF_COMPR =22, /* preferred compression algorithms */
- SIGSUBPKT_KS_FLAGS =23, /* key server preferences */
- SIGSUBPKT_PREF_KS =24, /* preferred key server */
- SIGSUBPKT_PRIMARY_UID =25, /* primary user id */
- SIGSUBPKT_POLICY =26, /* policy URL */
- SIGSUBPKT_KEY_FLAGS =27, /* key flags */
- SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */
- SIGSUBPKT_REVOC_REASON =29, /* reason for revocation */
- SIGSUBPKT_FEATURES =30, /* feature flags */
-
- SIGSUBPKT_FLAG_CRITICAL=128
-} sigsubpkttype_t;
-
-
-/*-- mainproc.c --*/
-int proc_packets( void *ctx, iobuf_t a );
-int proc_signature_packets( void *ctx, iobuf_t a,
- STRLIST signedfiles, const char *sigfile );
-int proc_encryption_packets( void *ctx, iobuf_t a );
-int list_packets( iobuf_t a );
-
-/*-- parse-packet.c --*/
-int set_packet_list_mode( int mode );
-
-#if DEBUG_PARSE_PACKET
-int dbg_search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid,
- const char* file, int lineno );
-int dbg_parse_packet( iobuf_t inp, PACKET *ret_pkt,
- const char* file, int lineno );
-int dbg_copy_all_packets( iobuf_t inp, iobuf_t out,
- const char* file, int lineno );
-int dbg_copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff,
- const char* file, int lineno );
-int dbg_skip_some_packets( iobuf_t inp, unsigned n,
- const char* file, int lineno );
-#define search_packet( a,b,c,d ) \
- dbg_search_packet( (a), (b), (c), (d), __FILE__, __LINE__ )
-#define parse_packet( a, b ) \
- dbg_parse_packet( (a), (b), __FILE__, __LINE__ )
-#define copy_all_packets( a,b ) \
- dbg_copy_all_packets((a),(b), __FILE__, __LINE__ )
-#define copy_some_packets( a,b,c ) \
- dbg_copy_some_packets((a),(b),(c), __FILE__, __LINE__ )
-#define skip_some_packets( a,b ) \
- dbg_skip_some_packets((a),(b), __FILE__, __LINE__ )
-#else
-int search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid );
-int parse_packet( iobuf_t inp, PACKET *ret_pkt);
-int copy_all_packets( iobuf_t inp, iobuf_t out );
-int copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff );
-int skip_some_packets( iobuf_t inp, unsigned n );
-#endif
-
-const byte *enum_sig_subpkt ( const subpktarea_t *subpkts,
- sigsubpkttype_t reqtype,
- size_t *ret_n, int *start, int *critical );
-const byte *parse_sig_subpkt ( const subpktarea_t *buffer,
- sigsubpkttype_t reqtype,
- size_t *ret_n );
-const byte *parse_sig_subpkt2 ( PKT_signature *sig,
- sigsubpkttype_t reqtype,
- size_t *ret_n );
-int parse_one_sig_subpkt( const byte *buffer, size_t n, int type );
-void parse_revkeys(PKT_signature *sig);
-int parse_attribute_subpkts(PKT_user_id *uid);
-void make_attribute_uidname(PKT_user_id *uid, size_t max_namelen);
-PACKET *create_gpg_control ( ctrlpkttype_t type,
- const byte *data,
- size_t datalen );
-
-/*-- build-packet.c --*/
-int build_packet( iobuf_t inp, PACKET *pkt );
-u32 calc_packet_length( PACKET *pkt );
-void hash_public_key( MD_HANDLE md, PKT_public_key *pk );
-void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
- const byte *buffer, size_t buflen );
-void build_sig_subpkt_from_sig( PKT_signature *sig );
-int delete_sig_subpkt(subpktarea_t *buffer, sigsubpkttype_t type );
-void build_attribute_subpkt(PKT_user_id *uid,byte type,
- const void *buf,u32 buflen,
- const void *header,u32 headerlen);
-
-/*-- free-packet.c --*/
-void free_symkey_enc( PKT_symkey_enc *enc );
-void free_pubkey_enc( PKT_pubkey_enc *enc );
-void free_seckey_enc( PKT_signature *enc );
-int digest_algo_from_sig( PKT_signature *sig );
-void release_public_key_parts( PKT_public_key *pk );
-void free_public_key( PKT_public_key *key );
-void release_secret_key_parts( PKT_secret_key *sk );
-void free_secret_key( PKT_secret_key *sk );
-void free_attributes(PKT_user_id *uid);
-void free_user_id( PKT_user_id *uid );
-void free_comment( PKT_comment *rem );
-void free_packet( PACKET *pkt );
-prefitem_t *copy_prefs (const prefitem_t *prefs);
-PKT_public_key *copy_public_key( PKT_public_key *d, PKT_public_key *s );
-void copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk );
-PKT_secret_key *copy_secret_key( PKT_secret_key *d, PKT_secret_key *s );
-PKT_signature *copy_signature( PKT_signature *d, PKT_signature *s );
-PKT_user_id *scopy_user_id (PKT_user_id *sd );
-int cmp_public_keys( PKT_public_key *a, PKT_public_key *b );
-int cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b );
-int cmp_signatures( PKT_signature *a, PKT_signature *b );
-int cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk );
-int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );
-
-
-/*-- sig-check.c --*/
-int signature_check( PKT_signature *sig, MD_HANDLE digest );
-int signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate,
- int *r_expired, int *r_revoked, PKT_public_key *ret_pk );
-
-/*-- seckey-cert.c --*/
-int is_secret_key_protected( PKT_secret_key *sk );
-int check_secret_key( PKT_secret_key *sk, int retries );
-int protect_secret_key( PKT_secret_key *sk, DEK *dek );
-
-/*-- pubkey-enc.c --*/
-int get_session_key( PKT_pubkey_enc *k, DEK *dek );
-int get_override_session_key( DEK *dek, const char *string );
-
-/*-- compress.c --*/
-int handle_compressed( void *ctx, PKT_compressed *cd,
- int (*callback)(iobuf_t, void *), void *passthru );
-
-/*-- encr-data.c --*/
-int decrypt_data( void *ctx, PKT_encrypted *ed, DEK *dek );
-
-/*-- plaintext.c --*/
-int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
- int nooutput, int clearsig, int *create_failed );
-int ask_for_detached_datafile( MD_HANDLE md, MD_HANDLE md2,
- const char *inname, int textmode );
-
-/*-- comment.c --*/
-int write_comment( iobuf_t out, const char *s );
-
-/*-- sign.c --*/
-int make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
- PKT_user_id *uid, PKT_public_key *subpk,
- PKT_secret_key *sk, int sigclass, int digest_algo,
- int sigversion, u32 timestamp, u32 duration,
- int (*mksubpkt)(PKT_signature *, void *),
- void *opaque );
-int update_keysig_packet( PKT_signature **ret_sig,
- PKT_signature *orig_sig,
- PKT_public_key *pk,
- PKT_user_id *uid,
- PKT_public_key *subpk,
- PKT_secret_key *sk,
- int (*mksubpkt)(PKT_signature *, void *),
- void *opaque );
-
-/*-- keygen.c --*/
-PKT_user_id *generate_user_id(void);
-
-#endif /*G10_PACKET_H*/
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
deleted file mode 100644
index c922eb5d9..000000000
--- a/g10/parse-packet.c
+++ /dev/null
@@ -1,2332 +0,0 @@
-/* parse-packet.c - read packets
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "packet.h"
-#include "iobuf.h"
-#include "mpi.h"
-#include "util.h"
-#include "cipher.h"
-#include "memory.h"
-#include "filter.h"
-#include "photoid.h"
-#include "options.h"
-#include "main.h"
-#include "i18n.h"
-
-static int mpi_print_mode = 0;
-static int list_mode = 0;
-
-static int parse( iobuf_t inp, PACKET *pkt, int onlykeypkts,
- off_t *retpos, int *skip, iobuf_t out, int do_skip
-#ifdef DEBUG_PARSE_PACKET
- ,const char *dbg_w, const char *dbg_f, int dbg_l
-#endif
- );
-static int copy_packet( iobuf_t inp, iobuf_t out, int pkttype,
- unsigned long pktlen );
-static void skip_packet( iobuf_t inp, int pkttype, unsigned long pktlen );
-static void skip_rest( iobuf_t inp, unsigned long pktlen );
-static void *read_rest( iobuf_t inp, size_t pktlen );
-static int parse_symkeyenc( iobuf_t inp, int pkttype, unsigned long pktlen,
- PACKET *packet );
-static int parse_pubkeyenc( iobuf_t inp, int pkttype, unsigned long pktlen,
- PACKET *packet );
-static int parse_signature( iobuf_t inp, int pkttype, unsigned long pktlen,
- PKT_signature *sig );
-static int parse_onepass_sig( iobuf_t inp, int pkttype, unsigned long pktlen,
- PKT_onepass_sig *ops );
-static int parse_key( iobuf_t inp, int pkttype, unsigned long pktlen,
- byte *hdr, int hdrlen, PACKET *packet );
-static int parse_user_id( iobuf_t inp, int pkttype, unsigned long pktlen,
- PACKET *packet );
-static int parse_attribute( iobuf_t inp, int pkttype, unsigned long pktlen,
- PACKET *packet );
-static int parse_comment( iobuf_t inp, int pkttype, unsigned long pktlen,
- PACKET *packet );
-static void parse_trust( iobuf_t inp, int pkttype, unsigned long pktlen,
- PACKET *packet );
-static int parse_plaintext( iobuf_t inp, int pkttype, unsigned long pktlen,
- PACKET *packet, int new_ctb);
-static int parse_compressed( iobuf_t inp, int pkttype, unsigned long pktlen,
- PACKET *packet, int new_ctb );
-static int parse_encrypted( iobuf_t inp, int pkttype, unsigned long pktlen,
- PACKET *packet, int new_ctb);
-static int parse_mdc( iobuf_t inp, int pkttype, unsigned long pktlen,
- PACKET *packet, int new_ctb);
-static int parse_gpg_control( iobuf_t inp, int pkttype, unsigned long pktlen,
- PACKET *packet );
-
-static unsigned short
-read_16(iobuf_t inp)
-{
- unsigned short a;
- a = iobuf_get_noeof(inp) << 8;
- a |= iobuf_get_noeof(inp);
- return a;
-}
-
-static unsigned long
-read_32(iobuf_t inp)
-{
- unsigned long a;
- a = iobuf_get_noeof(inp) << 24;
- a |= iobuf_get_noeof(inp) << 16;
- a |= iobuf_get_noeof(inp) << 8;
- a |= iobuf_get_noeof(inp);
- return a;
-}
-
-
-int
-set_packet_list_mode( int mode )
-{
- int old = list_mode;
- list_mode = mode;
- /* FIXME(gcrypt) mpi_print_mode = DBG_MPI; */
- return old;
-}
-
-static void
-unknown_pubkey_warning( int algo )
-{
- static byte unknown_pubkey_algos[256];
-
- algo &= 0xff;
- if( !unknown_pubkey_algos[algo] ) {
- if( opt.verbose )
- log_info(_("can't handle public key algorithm %d\n"), algo );
- unknown_pubkey_algos[algo] = 1;
- }
-}
-
-/****************
- * Parse a Packet and return it in packet
- * Returns: 0 := valid packet in pkt
- * -1 := no more packets
- * >0 := error
- * Note: The function may return an error and a partly valid packet;
- * caller must free this packet.
- */
-#ifdef DEBUG_PARSE_PACKET
-int
-dbg_parse_packet( iobuf_t inp, PACKET *pkt, const char *dbg_f, int dbg_l )
-{
- int skip, rc;
-
- do {
- rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0, "parse", dbg_f, dbg_l );
- } while( skip );
- return rc;
-}
-#else
-int
-parse_packet( iobuf_t inp, PACKET *pkt )
-{
- int skip, rc;
-
- do {
- rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0 );
- } while( skip );
- return rc;
-}
-#endif
-
-/****************
- * Like parse packet, but only return secret or public (sub)key packets.
- */
-#ifdef DEBUG_PARSE_PACKET
-int
-dbg_search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid,
- const char *dbg_f, int dbg_l )
-{
- int skip, rc;
-
- do {
- rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0, "search", dbg_f, dbg_l );
- } while( skip );
- return rc;
-}
-#else
-int
-search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid )
-{
- int skip, rc;
-
- do {
- rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0 );
- } while( skip );
- return rc;
-}
-#endif
-
-/****************
- * Copy all packets from INP to OUT, thereby removing unused spaces.
- */
-#ifdef DEBUG_PARSE_PACKET
-int
-dbg_copy_all_packets( iobuf_t inp, iobuf_t out,
- const char *dbg_f, int dbg_l )
-{
- PACKET pkt;
- int skip, rc=0;
- do {
- init_packet(&pkt);
- } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0, "copy", dbg_f, dbg_l )));
- return rc;
-}
-#else
-int
-copy_all_packets( iobuf_t inp, iobuf_t out )
-{
- PACKET pkt;
- int skip, rc=0;
- do {
- init_packet(&pkt);
- } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )));
- return rc;
-}
-#endif
-
-/****************
- * Copy some packets from INP to OUT, thereby removing unused spaces.
- * Stop at offset STOPoff (i.e. don't copy packets at this or later offsets)
- */
-#ifdef DEBUG_PARSE_PACKET
-int
-dbg_copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff,
- const char *dbg_f, int dbg_l )
-{
- PACKET pkt;
- int skip, rc=0;
- do {
- if( iobuf_tell(inp) >= stopoff )
- return 0;
- init_packet(&pkt);
- } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0,
- "some", dbg_f, dbg_l )) );
- return rc;
-}
-#else
-int
-copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff )
-{
- PACKET pkt;
- int skip, rc=0;
- do {
- if( iobuf_tell(inp) >= stopoff )
- return 0;
- init_packet(&pkt);
- } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )) );
- return rc;
-}
-#endif
-
-/****************
- * Skip over N packets
- */
-#ifdef DEBUG_PARSE_PACKET
-int
-dbg_skip_some_packets( iobuf_t inp, unsigned n,
- const char *dbg_f, int dbg_l )
-{
- int skip, rc=0;
- PACKET pkt;
-
- for( ;n && !rc; n--) {
- init_packet(&pkt);
- rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1, "skip", dbg_f, dbg_l );
- }
- return rc;
-}
-#else
-int
-skip_some_packets( iobuf_t inp, unsigned n )
-{
- int skip, rc=0;
- PACKET pkt;
-
- for( ;n && !rc; n--) {
- init_packet(&pkt);
- rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1 );
- }
- return rc;
-}
-#endif
-
-
-/****************
- * Parse packet. Set the variable skip points to 1 if the packet
- * should be skipped; this is the case if either ONLYKEYPKTS is set
- * and the parsed packet isn't one or the
- * packet-type is 0, indicating deleted stuff.
- * if OUT is not NULL, a special copymode is used.
- */
-static int
-parse( iobuf_t inp, PACKET *pkt, int onlykeypkts, off_t *retpos,
- int *skip, iobuf_t out, int do_skip
-#ifdef DEBUG_PARSE_PACKET
- ,const char *dbg_w, const char *dbg_f, int dbg_l
-#endif
- )
-{
- int rc=0, c, ctb, pkttype, lenbytes;
- unsigned long pktlen;
- byte hdr[8];
- int hdrlen;
- int new_ctb = 0;
- int with_uid = (onlykeypkts == 2);
-
- *skip = 0;
- assert( !pkt->pkt.generic );
- if( retpos )
- *retpos = iobuf_tell(inp);
-
- if( (ctb = iobuf_get(inp)) == -1 ) {
- rc = -1;
- goto leave;
- }
- hdrlen=0;
- hdr[hdrlen++] = ctb;
- if( !(ctb & 0x80) ) {
- log_error("%s: invalid packet (ctb=%02x)\n", iobuf_where(inp), ctb );
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- pktlen = 0;
- new_ctb = !!(ctb & 0x40);
- if( new_ctb ) {
- pkttype = ctb & 0x3f;
- if( (c = iobuf_get(inp)) == -1 ) {
- log_error("%s: 1st length byte missing\n", iobuf_where(inp) );
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- if (pkttype == PKT_COMPRESSED) {
- iobuf_set_partial_block_mode(inp, c & 0xff);
- pktlen = 0;/* to indicate partial length */
- }
- else {
- hdr[hdrlen++] = c;
- if( c < 192 )
- pktlen = c;
- else if( c < 224 ) {
- pktlen = (c - 192) * 256;
- if( (c = iobuf_get(inp)) == -1 ) {
- log_error("%s: 2nd length byte missing\n",
- iobuf_where(inp) );
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- hdr[hdrlen++] = c;
- pktlen += c + 192;
- }
- else if( c == 255 ) {
- pktlen = (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 24;
- pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 16;
- pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 8;
- if( (c = iobuf_get(inp)) == -1 ) {
- log_error("%s: 4 byte length invalid\n",
- iobuf_where(inp) );
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- pktlen |= (hdr[hdrlen++] = c );
- }
- else { /* partial body length */
- iobuf_set_partial_block_mode(inp, c & 0xff);
- pktlen = 0;/* to indicate partial length */
- }
- }
- }
- else {
- pkttype = (ctb>>2)&0xf;
- lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
- if( !lenbytes ) {
- pktlen = 0; /* don't know the value */
- switch (pkttype) {
- case PKT_ENCRYPTED:
- case PKT_PLAINTEXT:
- /* These partial length encodings are from an very
- early GnuPG release and deprecated. However we
- still support them read-wise. Note, that we should
- not allow them for any key related packets, because
- this might render a keyring unusable if an errenous
- packet indicated this mode but not complying to it
- gets imported. */
- iobuf_set_block_mode(inp, 1);
- break;
-
- case PKT_COMPRESSED:
- break; /* the orginal pgp 2 way. */
-
- default:
- log_error ("%s: old style partial length "
- "for invalid packet type\n", iobuf_where(inp) );
- rc = gpg_error (GPG_ERR_INV_PACKET);
- goto leave;
- }
- }
- else {
- for( ; lenbytes; lenbytes-- ) {
- pktlen <<= 8;
- pktlen |= hdr[hdrlen++] = iobuf_get_noeof(inp);
- }
- }
- }
-
- if (pktlen == 0xffffffff) {
- /* with a some probability this is caused by a problem in the
- * the uncompressing layer - in some error cases it just loops
- * and spits out 0xff bytes. */
- log_error ("%s: garbled packet detected\n", iobuf_where(inp) );
- g10_exit (2);
- }
-
- if( out && pkttype ) {
- rc = iobuf_write( out, hdr, hdrlen );
- if (!rc)
- rc = copy_packet(inp, out, pkttype, pktlen );
- goto leave;
- }
-
- if (with_uid && pkttype == PKT_USER_ID)
- ;
- else if( do_skip
- || !pkttype
- || (onlykeypkts && pkttype != PKT_PUBLIC_SUBKEY
- && pkttype != PKT_PUBLIC_KEY
- && pkttype != PKT_SECRET_SUBKEY
- && pkttype != PKT_SECRET_KEY ) ) {
- skip_rest(inp, pktlen);
- *skip = 1;
- rc = 0;
- goto leave;
- }
-
- if( DBG_PACKET ) {
-#ifdef DEBUG_PARSE_PACKET
- log_debug("parse_packet(iob=%d): type=%d length=%lu%s (%s.%s.%d)\n",
- iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"",
- dbg_w, dbg_f, dbg_l );
-#else
- log_debug("parse_packet(iob=%d): type=%d length=%lu%s\n",
- iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"" );
-#endif
- }
- pkt->pkttype = pkttype;
- rc = GPG_ERR_UNKNOWN_PACKET; /* default error */
- switch( pkttype ) {
- case PKT_PUBLIC_KEY:
- case PKT_PUBLIC_SUBKEY:
- pkt->pkt.public_key = xcalloc (1,sizeof *pkt->pkt.public_key );
- rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt );
- break;
- case PKT_SECRET_KEY:
- case PKT_SECRET_SUBKEY:
- pkt->pkt.secret_key = xcalloc (1,sizeof *pkt->pkt.secret_key );
- rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt );
- break;
- case PKT_SYMKEY_ENC:
- rc = parse_symkeyenc( inp, pkttype, pktlen, pkt );
- break;
- case PKT_PUBKEY_ENC:
- rc = parse_pubkeyenc(inp, pkttype, pktlen, pkt );
- break;
- case PKT_SIGNATURE:
- pkt->pkt.signature = xcalloc (1,sizeof *pkt->pkt.signature );
- rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature );
- break;
- case PKT_ONEPASS_SIG:
- pkt->pkt.onepass_sig = xcalloc (1,sizeof *pkt->pkt.onepass_sig );
- rc = parse_onepass_sig(inp, pkttype, pktlen, pkt->pkt.onepass_sig );
- break;
- case PKT_USER_ID:
- rc = parse_user_id(inp, pkttype, pktlen, pkt );
- break;
- case PKT_ATTRIBUTE:
- pkt->pkttype = pkttype = PKT_USER_ID; /* we store it in the userID */
- rc = parse_attribute(inp, pkttype, pktlen, pkt);
- break;
- case PKT_OLD_COMMENT:
- case PKT_COMMENT:
- rc = parse_comment(inp, pkttype, pktlen, pkt);
- break;
- case PKT_RING_TRUST:
- parse_trust(inp, pkttype, pktlen, pkt);
- rc = 0;
- break;
- case PKT_PLAINTEXT:
- rc = parse_plaintext(inp, pkttype, pktlen, pkt, new_ctb );
- break;
- case PKT_COMPRESSED:
- rc = parse_compressed(inp, pkttype, pktlen, pkt, new_ctb );
- break;
- case PKT_ENCRYPTED:
- case PKT_ENCRYPTED_MDC:
- rc = parse_encrypted(inp, pkttype, pktlen, pkt, new_ctb );
- break;
- case PKT_MDC:
- rc = parse_mdc(inp, pkttype, pktlen, pkt, new_ctb );
- break;
- case PKT_GPG_CONTROL:
- rc = parse_gpg_control(inp, pkttype, pktlen, pkt );
- break;
- default:
- skip_packet(inp, pkttype, pktlen);
- break;
- }
-
- leave:
- if( !rc && iobuf_error(inp) )
- rc = GPG_ERR_INV_KEYRING;
- return rc;
-}
-
-static void
-dump_hex_line( int c, int *i )
-{
- if( *i && !(*i%8) ) {
- if( *i && !(*i%24) )
- printf("\n%4d:", *i );
- else
- putchar(' ');
- }
- if( c == -1 )
- printf(" EOF" );
- else
- printf(" %02x", c );
- ++*i;
-}
-
-
-static int
-copy_packet( iobuf_t inp, iobuf_t out, int pkttype, unsigned long pktlen )
-{
- int rc, n;
- char buf[100];
-
- if( iobuf_in_block_mode(inp) ) {
- while( (n = iobuf_read( inp, buf, 100 )) != -1 )
- if( (rc = iobuf_write(out, buf, n )) )
- return rc; /* write error */
- }
- else if( !pktlen && pkttype == PKT_COMPRESSED ) {
- log_debug("copy_packet: compressed!\n");
- /* compressed packet, copy till EOF */
- while( (n = iobuf_read( inp, buf, 100 )) != -1 )
- if( (rc = iobuf_write(out, buf, n )) )
- return rc; /* write error */
- }
- else {
- for( ; pktlen; pktlen -= n ) {
- n = pktlen > 100 ? 100 : pktlen;
- n = iobuf_read( inp, buf, n );
- if( n == -1 )
- return GPG_ERR_GENERAL; /* FIXME(gcrypt): read error*/;
- if( (rc = iobuf_write(out, buf, n )) )
- return rc; /* write error */
- }
- }
- return 0;
-}
-
-
-static void
-skip_packet( iobuf_t inp, int pkttype, unsigned long pktlen )
-{
- if( list_mode ) {
- if( pkttype == PKT_MARKER )
- fputs(":marker packet:\n", stdout );
- else
- printf(":unknown packet: type %2d, length %lu\n", pkttype, pktlen);
- if( pkttype ) {
- int c, i=0 ;
- if( pkttype != PKT_MARKER )
- fputs("dump:", stdout );
- if( iobuf_in_block_mode(inp) ) {
- while( (c=iobuf_get(inp)) != -1 )
- dump_hex_line(c, &i);
- }
- else {
- for( ; pktlen; pktlen-- )
- dump_hex_line(iobuf_get(inp), &i);
- }
- putchar('\n');
- return;
- }
- }
- skip_rest(inp,pktlen);
-}
-
-static void
-skip_rest( iobuf_t inp, unsigned long pktlen )
-{
- if( iobuf_in_block_mode(inp) ) {
- while( iobuf_get(inp) != -1 )
- ;
- }
- else {
- for( ; pktlen; pktlen-- )
- if( iobuf_get(inp) == -1 )
- break;
- }
-}
-
-
-static void *
-read_rest( iobuf_t inp, size_t pktlen )
-{
- byte *p;
- int i;
-
- if( iobuf_in_block_mode(inp) ) {
- log_error("read_rest: can't store stream data\n");
- p = NULL;
- }
- else {
- p = xmalloc ( pktlen );
- for(i=0; pktlen; pktlen--, i++ )
- p[i] = iobuf_get(inp);
- }
- return p;
-}
-
-
-
-static int
-parse_symkeyenc( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
-{
- PKT_symkey_enc *k;
- int rc = 0;
- int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen;
-
- if( pktlen < 4 ) {
- log_error("packet(%d) too short\n", pkttype);
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- version = iobuf_get_noeof(inp); pktlen--;
- if( version != 4 ) {
- log_error("packet(%d) with unknown version %d\n", pkttype, version);
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- if( pktlen > 200 ) { /* (we encode the seskeylen in a byte) */
- log_error("packet(%d) too large\n", pkttype);
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- cipher_algo = iobuf_get_noeof(inp); pktlen--;
- s2kmode = iobuf_get_noeof(inp); pktlen--;
- hash_algo = iobuf_get_noeof(inp); pktlen--;
- switch( s2kmode ) {
- case 0: /* simple s2k */
- minlen = 0;
- break;
- case 1: /* salted s2k */
- minlen = 8;
- break;
- case 3: /* iterated+salted s2k */
- minlen = 9;
- break;
- default:
- log_error("unknown S2K %d\n", s2kmode );
- goto leave;
- }
- if( minlen > pktlen ) {
- log_error("packet with S2K %d too short\n", s2kmode );
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- seskeylen = pktlen - minlen;
- k = packet->pkt.symkey_enc = xcalloc (1, sizeof *packet->pkt.symkey_enc
- + seskeylen - 1 );
- k->version = version;
- k->cipher_algo = cipher_algo;
- k->s2k.mode = s2kmode;
- k->s2k.hash_algo = hash_algo;
- if( s2kmode == 1 || s2kmode == 3 ) {
- for(i=0; i < 8 && pktlen; i++, pktlen-- )
- k->s2k.salt[i] = iobuf_get_noeof(inp);
- }
- if( s2kmode == 3 ) {
- k->s2k.count = iobuf_get(inp); pktlen--;
- }
- k->seskeylen = seskeylen;
- for(i=0; i < seskeylen && pktlen; i++, pktlen-- )
- k->seskey[i] = iobuf_get_noeof(inp);
- assert( !pktlen );
-
- if( list_mode ) {
- printf(":symkey enc packet: version %d, cipher %d, s2k %d, hash %d\n",
- version, cipher_algo, s2kmode, hash_algo);
- if( s2kmode == 1 || s2kmode == 3 ) {
- printf("\tsalt ");
- for(i=0; i < 8; i++ )
- printf("%02x", k->s2k.salt[i]);
- if( s2kmode == 3 )
- printf(", count %lu\n", (ulong)k->s2k.count );
- printf("\n");
- }
- }
-
- leave:
- skip_rest(inp, pktlen);
- return rc;
-}
-
-static int
-parse_pubkeyenc( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
-{
- unsigned int n;
- int rc = 0;
- int i, ndata;
- PKT_pubkey_enc *k;
-
- k = packet->pkt.pubkey_enc = xcalloc (1,sizeof *packet->pkt.pubkey_enc);
- if( pktlen < 12 ) {
- log_error("packet(%d) too short\n", pkttype);
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- k->version = iobuf_get_noeof(inp); pktlen--;
- if( k->version != 2 && k->version != 3 ) {
- log_error("packet(%d) with unknown version %d\n", pkttype, k->version);
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- k->keyid[0] = read_32(inp); pktlen -= 4;
- k->keyid[1] = read_32(inp); pktlen -= 4;
- k->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
- k->throw_keyid = 0; /* only used as flag for build_packet */
- if( list_mode )
- printf(":pubkey enc packet: version %d, algo %d, keyid %08lX%08lX\n",
- k->version, k->pubkey_algo, (ulong)k->keyid[0], (ulong)k->keyid[1]);
-
- ndata = pubkey_get_nenc(k->pubkey_algo);
- if( !ndata ) {
- if( list_mode )
- printf("\tunsupported algorithm %d\n", k->pubkey_algo );
- unknown_pubkey_warning( k->pubkey_algo );
- k->data[0] = NULL; /* no need to store the encrypted data */
- }
- else {
- for( i=0; i < ndata; i++ ) {
- n = pktlen;
- k->data[i] = mpi_read(inp, &n, 0); pktlen -=n;
- if( list_mode ) {
- printf("\tdata: ");
- mpi_print(stdout, k->data[i], mpi_print_mode );
- putchar('\n');
- }
- if (!k->data[i])
- rc = GPG_ERR_INV_PACKET;
- }
- }
-
- leave:
- skip_rest(inp, pktlen);
- return rc;
-}
-
-
-static void
-dump_sig_subpkt( int hashed, int type, int critical,
- const byte *buffer, size_t buflen, size_t length )
-{
- const char *p=NULL;
- int i;
-
- /* The CERT has warning out with explains how to use GNUPG to
- * detect the ARRs - we print our old message here when it is a faked
- * ARR and add an additional notice */
- if ( type == SIGSUBPKT_ARR && !hashed ) {
- printf("\tsubpkt %d len %u (additional recipient request)\n"
- "WARNING: PGP versions > 5.0 and < 6.5.8 will automagically "
- "encrypt to this key and thereby reveal the plaintext to "
- "the owner of this ARR key. Detailed info follows:\n",
- type, (unsigned)length );
- }
-
- buffer++;
- length--;
-
- printf("\t%s%ssubpkt %d len %u (", /*)*/
- critical ? "critical ":"",
- hashed ? "hashed ":"", type, (unsigned)length );
- if( length > buflen ) {
- printf("too short: buffer is only %u)\n", (unsigned)buflen );
- return;
- }
- switch( type ) {
- case SIGSUBPKT_SIG_CREATED:
- if( length >= 4 )
- printf("sig created %s", strtimestamp( buffer_to_u32(buffer) ) );
- break;
- case SIGSUBPKT_SIG_EXPIRE:
- if( length >= 4 )
- printf("sig expires after %s",
- strtimevalue( buffer_to_u32(buffer) ) );
- break;
- case SIGSUBPKT_EXPORTABLE:
- if( length )
- printf("%sexportable", *buffer? "":"not ");
- break;
- case SIGSUBPKT_TRUST:
- if(length!=2)
- p="[invalid trust subpacket]";
- else
- printf("trust signature of depth %d, value %d",buffer[0],buffer[1]);
- break;
- case SIGSUBPKT_REGEXP:
- if(!length)
- p="[invalid regexp subpacket]";
- else
- printf("regular expression: \"%s\"",buffer);
- break;
- case SIGSUBPKT_REVOCABLE:
- if( length )
- printf("%srevocable", *buffer? "":"not ");
- break;
- case SIGSUBPKT_KEY_EXPIRE:
- if( length >= 4 )
- printf("key expires after %s",
- strtimevalue( buffer_to_u32(buffer) ) );
- break;
- case SIGSUBPKT_PREF_SYM:
- fputs("pref-sym-algos:", stdout );
- for( i=0; i < length; i++ )
- printf(" %d", buffer[i] );
- break;
- case SIGSUBPKT_REV_KEY:
- fputs("revocation key: ", stdout );
- if( length < 22 )
- p = "[too short]";
- else {
- printf("c=%02x a=%d f=", buffer[0], buffer[1] );
- for( i=2; i < length; i++ )
- printf("%02X", buffer[i] );
- }
- break;
- case SIGSUBPKT_ISSUER:
- if( length >= 8 )
- printf("issuer key ID %08lX%08lX",
- (ulong)buffer_to_u32(buffer),
- (ulong)buffer_to_u32(buffer+4) );
- break;
- case SIGSUBPKT_NOTATION:
- {
- fputs("notation: ", stdout );
- if( length < 8 )
- p = "[too short]";
- else {
- const byte *s = buffer;
- size_t n1, n2;
-
- n1 = (s[4] << 8) | s[5];
- n2 = (s[6] << 8) | s[7];
- s += 8;
- if( 8+n1+n2 != length )
- p = "[error]";
- else {
- print_string( stdout, s, n1, ')' );
- putc( '=', stdout );
-
- if( *buffer & 0x80 )
- print_string( stdout, s+n1, n2, ')' );
- else
- p = "[not human readable]";
- }
- }
- }
- break;
- case SIGSUBPKT_PREF_HASH:
- fputs("pref-hash-algos:", stdout );
- for( i=0; i < length; i++ )
- printf(" %d", buffer[i] );
- break;
- case SIGSUBPKT_PREF_COMPR:
- fputs("pref-zip-algos:", stdout );
- for( i=0; i < length; i++ )
- printf(" %d", buffer[i] );
- break;
- case SIGSUBPKT_KS_FLAGS:
- fputs("key server preferences:",stdout);
- for(i=0;i<length;i++)
- printf(" %02X", buffer[i]);
- break;
- case SIGSUBPKT_PREF_KS:
- fputs("preferred key server: ", stdout );
- print_string( stdout, buffer, length, ')' );
- break;
- case SIGSUBPKT_PRIMARY_UID:
- p = "primary user ID";
- break;
- case SIGSUBPKT_POLICY:
- fputs("policy: ", stdout );
- print_string( stdout, buffer, length, ')' );
- break;
- case SIGSUBPKT_KEY_FLAGS:
- fputs ( "key flags:", stdout );
- for( i=0; i < length; i++ )
- printf(" %02X", buffer[i] );
- break;
- case SIGSUBPKT_SIGNERS_UID:
- p = "signer's user ID";
- break;
- case SIGSUBPKT_REVOC_REASON:
- if( length ) {
- printf("revocation reason 0x%02x (", *buffer );
- print_string( stdout, buffer+1, length-1, ')' );
- p = ")";
- }
- break;
- case SIGSUBPKT_ARR:
- fputs("Big Brother's key (ignored): ", stdout );
- if( length < 22 )
- p = "[too short]";
- else {
- printf("c=%02x a=%d f=", buffer[0], buffer[1] );
- for( i=2; i < length; i++ )
- printf("%02X", buffer[i] );
- }
- break;
- case SIGSUBPKT_FEATURES:
- fputs ( "features:", stdout );
- for( i=0; i < length; i++ )
- printf(" %02x", buffer[i] );
- break;
- default:
- if(type>=100 && type<=110)
- p="experimental / private subpacket";
- else
- p = "?";
- break;
- }
-
- printf("%s)\n", p? p: "");
-}
-
-/****************
- * Returns: >= 0 offset into buffer
- * -1 unknown type
- * -2 unsupported type
- * -3 subpacket too short
- */
-int
-parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
-{
- switch( type ) {
- case SIGSUBPKT_REV_KEY:
- if(n < 22)
- break;
- return 0;
- case SIGSUBPKT_SIG_CREATED:
- case SIGSUBPKT_SIG_EXPIRE:
- case SIGSUBPKT_KEY_EXPIRE:
- if( n < 4 )
- break;
- return 0;
- case SIGSUBPKT_KEY_FLAGS:
- case SIGSUBPKT_KS_FLAGS:
- case SIGSUBPKT_PREF_SYM:
- case SIGSUBPKT_PREF_HASH:
- case SIGSUBPKT_PREF_COMPR:
- case SIGSUBPKT_POLICY:
- case SIGSUBPKT_PREF_KS:
- case SIGSUBPKT_FEATURES:
- case SIGSUBPKT_REGEXP:
- return 0;
- case SIGSUBPKT_EXPORTABLE:
- case SIGSUBPKT_REVOCABLE:
- if( !n )
- break;
- return 0;
- case SIGSUBPKT_ISSUER: /* issuer key ID */
- if( n < 8 )
- break;
- return 0;
- case SIGSUBPKT_NOTATION:
- if( n < 8 ) /* minimum length needed */
- break;
- return 0;
- case SIGSUBPKT_REVOC_REASON:
- if( !n )
- break;
- return 0;
- case SIGSUBPKT_PRIMARY_UID:
- if ( n != 1 )
- break;
- return 0;
- case SIGSUBPKT_TRUST:
- if ( n != 2 )
- break;
- return 0;
- default: return -1;
- }
- return -3;
-}
-
-
-static int
-can_handle_critical( const byte *buffer, size_t n, int type )
-{
- switch( type ) {
- case SIGSUBPKT_NOTATION:
- if( n >= 8 && (*buffer & 0x80) )
- return 1; /* human readable is handled */
- return 0;
-
- case SIGSUBPKT_SIG_CREATED:
- case SIGSUBPKT_SIG_EXPIRE:
- case SIGSUBPKT_KEY_EXPIRE:
- case SIGSUBPKT_EXPORTABLE:
- case SIGSUBPKT_REVOCABLE:
- case SIGSUBPKT_REV_KEY:
- case SIGSUBPKT_ISSUER:/* issuer key ID */
- case SIGSUBPKT_PREF_SYM:
- case SIGSUBPKT_PREF_HASH:
- case SIGSUBPKT_PREF_COMPR:
- case SIGSUBPKT_KEY_FLAGS:
- case SIGSUBPKT_PRIMARY_UID:
- case SIGSUBPKT_FEATURES:
- case SIGSUBPKT_TRUST:
- case SIGSUBPKT_REGEXP:
- /* Is it enough to show the policy or keyserver? */
- case SIGSUBPKT_POLICY:
- case SIGSUBPKT_PREF_KS:
- return 1;
-
- default:
- return 0;
- }
-}
-
-
-const byte *
-enum_sig_subpkt( const subpktarea_t *pktbuf, sigsubpkttype_t reqtype,
- size_t *ret_n, int *start, int *critical )
-{
- const byte *buffer;
- int buflen;
- int type;
- int critical_dummy;
- int offset;
- size_t n;
- int seq = 0;
- int reqseq = start? *start: 0;
-
- if(!critical)
- critical=&critical_dummy;
-
- if( !pktbuf || reqseq == -1 ) {
- /* return some value different from NULL to indicate that
- * there is no critical bit we do not understand. The caller
- * will never use the value. Yes I know, it is an ugly hack */
- return reqtype == SIGSUBPKT_TEST_CRITICAL? (const byte*)&pktbuf : NULL;
- }
- buffer = pktbuf->data;
- buflen = pktbuf->len;
- while( buflen ) {
- n = *buffer++; buflen--;
- if( n == 255 ) { /* 4 byte length header */
- if( buflen < 4 )
- goto too_short;
- n = (buffer[0] << 24) | (buffer[1] << 16)
- | (buffer[2] << 8) | buffer[3];
- buffer += 4;
- buflen -= 4;
- }
- else if( n >= 192 ) { /* 2 byte special encoded length header */
- if( buflen < 2 )
- goto too_short;
- n = (( n - 192 ) << 8) + *buffer + 192;
- buffer++;
- buflen--;
- }
- if( buflen < n )
- goto too_short;
- type = *buffer;
- if( type & 0x80 ) {
- type &= 0x7f;
- *critical = 1;
- }
- else
- *critical = 0;
- if( !(++seq > reqseq) )
- ;
- else if( reqtype == SIGSUBPKT_TEST_CRITICAL ) {
- if( *critical ) {
- if( n-1 > buflen+1 )
- goto too_short;
- if( !can_handle_critical(buffer+1, n-1, type ) )
- {
- if(opt.verbose)
- log_info(_("subpacket of type %d has "
- "critical bit set\n"),type);
- if( start )
- *start = seq;
- return NULL; /* this is an error */
- }
- }
- }
- else if( reqtype < 0 ) /* list packets */
- dump_sig_subpkt( reqtype == SIGSUBPKT_LIST_HASHED,
- type, *critical, buffer, buflen, n );
- else if( type == reqtype ) { /* found */
- buffer++;
- n--;
- if( n > buflen )
- goto too_short;
- if( ret_n )
- *ret_n = n;
- offset = parse_one_sig_subpkt(buffer, n, type );
- switch( offset ) {
- case -3:
- log_error("subpacket of type %d too short\n", type);
- return NULL;
- case -2:
- return NULL;
- case -1:
- BUG(); /* not yet needed */
- default:
- break;
- }
- if( start )
- *start = seq;
- return buffer+offset;
- }
- buffer += n; buflen -=n;
- }
- if( reqtype == SIGSUBPKT_TEST_CRITICAL )
- return buffer; /* as value true to indicate that there is no */
- /* critical bit we don't understand */
- if( start )
- *start = -1;
- return NULL; /* end of packets; not found */
-
- too_short:
- log_error("buffer shorter than subpacket\n");
- if( start )
- *start = -1;
- return NULL;
-}
-
-
-const byte *
-parse_sig_subpkt (const subpktarea_t *buffer, sigsubpkttype_t reqtype,
- size_t *ret_n)
-{
- return enum_sig_subpkt( buffer, reqtype, ret_n, NULL, NULL );
-}
-
-const byte *
-parse_sig_subpkt2 (PKT_signature *sig, sigsubpkttype_t reqtype,
- size_t *ret_n )
-{
- const byte *p;
-
- p = parse_sig_subpkt (sig->hashed, reqtype, ret_n );
- if( !p )
- p = parse_sig_subpkt (sig->unhashed, reqtype, ret_n );
- return p;
-}
-
-/* Find all revocation keys. Look in hashed area only. */
-void parse_revkeys(PKT_signature *sig)
-{
- struct revocation_key *revkey;
- int seq=0;
- size_t len;
-
- if(sig->sig_class!=0x1F)
- return;
-
- while((revkey=
- (struct revocation_key *)enum_sig_subpkt(sig->hashed,
- SIGSUBPKT_REV_KEY,
- &len,&seq,NULL)))
- {
- if(len==sizeof(struct revocation_key) &&
- (revkey->class&0x80)) /* 0x80 bit must be set */
- {
- sig->revkey=xrealloc(sig->revkey,
- sizeof(struct revocation_key *)*(sig->numrevkeys+1));
- sig->revkey[sig->numrevkeys]=revkey;
- sig->numrevkeys++;
- }
- }
-}
-
-static int
-parse_signature( iobuf_t inp, int pkttype, unsigned long pktlen,
- PKT_signature *sig )
-{
- int md5_len=0;
- unsigned n;
- int is_v4=0;
- int rc=0;
- int i, ndata;
-
- if( pktlen < 16 ) {
- log_error("packet(%d) too short\n", pkttype);
- goto leave;
- }
- sig->version = iobuf_get_noeof(inp); pktlen--;
- if( sig->version == 4 )
- is_v4=1;
- else if( sig->version != 2 && sig->version != 3 ) {
- log_error("packet(%d) with unknown version %d\n", pkttype, sig->version);
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
-
- if( !is_v4 ) {
- md5_len = iobuf_get_noeof(inp); pktlen--;
- }
- sig->sig_class = iobuf_get_noeof(inp); pktlen--;
- if( !is_v4 ) {
- sig->timestamp = read_32(inp); pktlen -= 4;
- sig->keyid[0] = read_32(inp); pktlen -= 4;
- sig->keyid[1] = read_32(inp); pktlen -= 4;
- }
- sig->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
- sig->digest_algo = iobuf_get_noeof(inp); pktlen--;
- sig->flags.exportable=1;
- sig->flags.revocable=1;
- if( is_v4 ) { /* read subpackets */
- n = read_16(inp); pktlen -= 2; /* length of hashed data */
- if( n > 10000 ) {
- log_error("signature packet: hashed data too long\n");
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- if( n ) {
- sig->hashed = xmalloc (sizeof (*sig->hashed) + n - 1 );
- sig->hashed->size = n;
- sig->hashed->len = n;
- if( iobuf_read (inp, sig->hashed->data, n ) != n ) {
- log_error ("premature eof while reading "
- "hashed signature data\n");
- rc = -1;
- goto leave;
- }
- pktlen -= n;
- }
- n = read_16(inp); pktlen -= 2; /* length of unhashed data */
- if( n > 10000 ) {
- log_error("signature packet: unhashed data too long\n");
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- if( n ) {
- sig->unhashed = xmalloc (sizeof(*sig->unhashed) + n - 1 );
- sig->unhashed->size = n;
- sig->unhashed->len = n;
- if( iobuf_read(inp, sig->unhashed->data, n ) != n ) {
- log_error("premature eof while reading "
- "unhashed signature data\n");
- rc = -1;
- goto leave;
- }
- pktlen -= n;
- }
- }
-
- if( pktlen < 5 ) { /* sanity check */
- log_error("packet(%d) too short\n", pkttype);
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
-
- sig->digest_start[0] = iobuf_get_noeof(inp); pktlen--;
- sig->digest_start[1] = iobuf_get_noeof(inp); pktlen--;
-
- if( is_v4 && sig->pubkey_algo ) { /*extract required information */
- const byte *p;
- size_t len;
-
- /* set sig->flags.unknown_critical if there is a
- * critical bit set for packets which we do not understand */
- if( !parse_sig_subpkt (sig->hashed, SIGSUBPKT_TEST_CRITICAL, NULL)
- || !parse_sig_subpkt (sig->unhashed, SIGSUBPKT_TEST_CRITICAL,
- NULL) )
- {
- sig->flags.unknown_critical = 1;
- }
-
- p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL );
- if(p)
- sig->timestamp = buffer_to_u32(p);
- else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110))
- log_error("signature packet without timestamp\n");
-
- p = parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL );
- if( p )
- {
- sig->keyid[0] = buffer_to_u32(p);
- sig->keyid[1] = buffer_to_u32(p+4);
- }
- else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110))
- log_error("signature packet without keyid\n");
-
- p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL);
- if(p)
- sig->expiredate=sig->timestamp+buffer_to_u32(p);
- if(sig->expiredate && sig->expiredate<=make_timestamp())
- sig->flags.expired=1;
-
- p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,NULL);
- if(p)
- sig->flags.policy_url=1;
-
- p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,NULL);
- if(p)
- sig->flags.pref_ks=1;
-
- p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,NULL);
- if(p)
- sig->flags.notation=1;
-
- p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_REVOCABLE,NULL);
- if(p && *p==0)
- sig->flags.revocable=0;
-
- p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_TRUST,&len);
- if(p && len==2)
- {
- sig->trust_depth=p[0];
- sig->trust_value=p[1];
-
- /* Only look for a regexp if there is also a trust
- subpacket. */
- sig->trust_regexp=
- parse_sig_subpkt(sig->hashed,SIGSUBPKT_REGEXP,&len);
-
- /* If the regular expression is of 0 length, there is no
- regular expression. */
- if(len==0)
- sig->trust_regexp=NULL;
- }
-
- /* We accept the exportable subpacket from either the hashed
- or unhashed areas as older versions of gpg put it in the
- unhashed area. In theory, anyway, we should never see this
- packet off of a local keyring. */
-
- p=parse_sig_subpkt2(sig,SIGSUBPKT_EXPORTABLE,NULL);
- if(p && *p==0)
- sig->flags.exportable=0;
-
- /* Find all revocation keys. */
- if(sig->sig_class==0x1F)
- parse_revkeys(sig);
- }
-
- if( list_mode ) {
- printf(":signature packet: algo %d, keyid %08lX%08lX\n"
- "\tversion %d, created %lu, md5len %d, sigclass %02x\n"
- "\tdigest algo %d, begin of digest %02x %02x\n",
- sig->pubkey_algo,
- (ulong)sig->keyid[0], (ulong)sig->keyid[1],
- sig->version, (ulong)sig->timestamp, md5_len, sig->sig_class,
- sig->digest_algo,
- sig->digest_start[0], sig->digest_start[1] );
- if( is_v4 ) {
- parse_sig_subpkt (sig->hashed, SIGSUBPKT_LIST_HASHED, NULL );
- parse_sig_subpkt (sig->unhashed, SIGSUBPKT_LIST_UNHASHED, NULL);
- }
- }
-
- ndata = pubkey_get_nsig(sig->pubkey_algo);
- if( !ndata ) {
- if( list_mode )
- printf("\tunknown algorithm %d\n", sig->pubkey_algo );
- unknown_pubkey_warning( sig->pubkey_algo );
- /* we store the plain material in data[0], so that we are able
- * to write it back with build_packet() */
- sig->data[0] = gcry_mpi_set_opaque(NULL, read_rest(inp, pktlen),
- pktlen*8 );
- pktlen = 0;
- }
- else {
- for( i=0; i < ndata; i++ ) {
- n = pktlen;
- sig->data[i] = mpi_read(inp, &n, 0 );
- pktlen -=n;
- if( list_mode ) {
- printf("\tdata: ");
- mpi_print(stdout, sig->data[i], mpi_print_mode );
- putchar('\n');
- }
- if (!sig->data[i])
- rc = GPG_ERR_INV_PACKET;
- }
- }
-
- leave:
- skip_rest(inp, pktlen);
- return rc;
-}
-
-
-static int
-parse_onepass_sig( iobuf_t inp, int pkttype, unsigned long pktlen,
- PKT_onepass_sig *ops )
-{
- int version;
- int rc = 0;
-
- if( pktlen < 13 ) {
- log_error("packet(%d) too short\n", pkttype);
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- version = iobuf_get_noeof(inp); pktlen--;
- if( version != 3 ) {
- log_error("onepass_sig with unknown version %d\n", version);
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- ops->sig_class = iobuf_get_noeof(inp); pktlen--;
- ops->digest_algo = iobuf_get_noeof(inp); pktlen--;
- ops->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
- ops->keyid[0] = read_32(inp); pktlen -= 4;
- ops->keyid[1] = read_32(inp); pktlen -= 4;
- ops->last = iobuf_get_noeof(inp); pktlen--;
- if( list_mode )
- printf(":onepass_sig packet: keyid %08lX%08lX\n"
- "\tversion %d, sigclass %02x, digest %d, pubkey %d, last=%d\n",
- (ulong)ops->keyid[0], (ulong)ops->keyid[1],
- version, ops->sig_class,
- ops->digest_algo, ops->pubkey_algo, ops->last );
-
-
- leave:
- skip_rest(inp, pktlen);
- return rc;
-}
-
-
-static gcry_mpi_t
-read_protected_v3_mpi (iobuf_t inp, unsigned long *length)
-{
- int c;
- unsigned int nbits, nbytes;
- unsigned char *buf, *p;
- gcry_mpi_t val;
-
- if (*length < 2)
- {
- log_error ("mpi too small\n");
- return NULL;
- }
-
- if ((c=iobuf_get (inp)) == -1)
- return NULL;
- --*length;
- nbits = c << 8;
- if ((c=iobuf_get(inp)) == -1)
- return NULL;
- --*length;
- nbits |= c;
-
- if (nbits > 16384)
- {
- log_error ("mpi too large (%u bits)\n", nbits);
- return NULL;
- }
- nbytes = (nbits+7) / 8;
- buf = p = xmalloc (2 + nbytes);
- *p++ = nbits >> 8;
- *p++ = nbits;
- for (; nbytes && length; nbytes--, --*length)
- *p++ = iobuf_get (inp);
- if (nbytes)
- {
- log_error ("packet shorter tham mpi\n");
- xfree (buf);
- return NULL;
- }
-
- /* convert buffer into an opaque gcry_mpi_t */
- val = gcry_mpi_set_opaque (NULL, buf, (p-buf)*8);
- return val;
-}
-
-
-static int
-parse_key( iobuf_t inp, int pkttype, unsigned long pktlen,
- byte *hdr, int hdrlen, PACKET *pkt )
-{
- int i, version, algorithm;
- unsigned n;
- unsigned long timestamp, expiredate, max_expiredate;
- int npkey, nskey;
- int is_v4=0;
- int rc=0;
-
- version = iobuf_get_noeof(inp); pktlen--;
- if( pkttype == PKT_PUBLIC_SUBKEY && version == '#' ) {
- /* early versions of G10 use old PGP comments packets;
- * luckily all those comments are started by a hash */
- if( list_mode ) {
- printf(":rfc1991 comment packet: \"" );
- for( ; pktlen; pktlen-- ) {
- int c;
- c = iobuf_get_noeof(inp);
- if( c >= ' ' && c <= 'z' )
- putchar(c);
- else
- printf("\\x%02x", c );
- }
- printf("\"\n");
- }
- skip_rest(inp, pktlen);
- return 0;
- }
- else if( version == 4 )
- is_v4=1;
- else if( version != 2 && version != 3 ) {
- log_error("packet(%d) with unknown version %d\n", pkttype, version);
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
-
- if( pktlen < 11 ) {
- log_error("packet(%d) too short\n", pkttype);
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
-
- timestamp = read_32(inp); pktlen -= 4;
- if( is_v4 ) {
- expiredate = 0; /* have to get it from the selfsignature */
- max_expiredate = 0;
- }
- else {
- unsigned short ndays;
- ndays = read_16(inp); pktlen -= 2;
- if( ndays )
- expiredate = timestamp + ndays * 86400L;
- else
- expiredate = 0;
-
- max_expiredate=expiredate;
- }
- algorithm = iobuf_get_noeof(inp); pktlen--;
- if( list_mode )
- printf(":%s key packet:\n"
- "\tversion %d, algo %d, created %lu, expires %lu\n",
- pkttype == PKT_PUBLIC_KEY? "public" :
- pkttype == PKT_SECRET_KEY? "secret" :
- pkttype == PKT_PUBLIC_SUBKEY? "public sub" :
- pkttype == PKT_SECRET_SUBKEY? "secret sub" : "??",
- version, algorithm, timestamp, expiredate );
-
- if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
- PKT_secret_key *sk = pkt->pkt.secret_key;
-
- sk->timestamp = timestamp;
- sk->expiredate = expiredate;
- sk->max_expiredate = max_expiredate;
- sk->hdrbytes = hdrlen;
- sk->version = version;
- sk->is_primary = pkttype == PKT_SECRET_KEY;
- sk->pubkey_algo = algorithm;
- sk->req_usage = 0;
- sk->pubkey_usage = 0; /* not yet used */
- }
- else {
- PKT_public_key *pk = pkt->pkt.public_key;
-
- pk->timestamp = timestamp;
- pk->expiredate = expiredate;
- pk->max_expiredate = max_expiredate;
- pk->hdrbytes = hdrlen;
- pk->version = version;
- pk->is_primary = pkttype == PKT_PUBLIC_KEY;
- pk->pubkey_algo = algorithm;
- pk->req_usage = 0;
- pk->pubkey_usage = 0; /* not yet used */
- pk->is_revoked = 0;
- pk->is_disabled = 0;
- pk->keyid[0] = 0;
- pk->keyid[1] = 0;
- }
- nskey = pubkey_get_nskey( algorithm );
- npkey = pubkey_get_npkey( algorithm );
- if( !npkey ) {
- if( list_mode )
- printf("\tunknown algorithm %d\n", algorithm );
- unknown_pubkey_warning( algorithm );
- }
-
-
- if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
- PKT_secret_key *sk = pkt->pkt.secret_key;
- byte temp[16];
- size_t snlen = 0;
-
- if( !npkey ) {
- sk->skey[0] = gcry_mpi_set_opaque( NULL, read_rest(inp, pktlen),
- pktlen*8 );
- pktlen = 0;
- goto leave;
- }
-
- for(i=0; i < npkey; i++ ) {
- n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
- if( list_mode ) {
- printf( "\tskey[%d]: ", i);
- mpi_print(stdout, sk->skey[i], mpi_print_mode );
- putchar('\n');
- }
- if (!sk->skey[i])
- rc = GPG_ERR_INV_PACKET;
- }
- if (rc) /* one of the MPIs were bad */
- goto leave;
- sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
- sk->protect.sha1chk = 0;
- if( sk->protect.algo ) {
- sk->is_protected = 1;
- sk->protect.s2k.count = 0;
- if( sk->protect.algo == 254 || sk->protect.algo == 255 ) {
- if( pktlen < 3 ) {
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- sk->protect.sha1chk = (sk->protect.algo == 254);
- sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
- /* Note that a sk->protect.algo > 110 is illegal, but
- I'm not erroring on it here as otherwise there
- would be no way to delete such a key. */
- sk->protect.s2k.mode = iobuf_get_noeof(inp); pktlen--;
- sk->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
- /* check for the special GNU extension */
- if( is_v4 && sk->protect.s2k.mode == 101 ) {
- for(i=0; i < 4 && pktlen; i++, pktlen-- )
- temp[i] = iobuf_get_noeof(inp);
- if( i < 4 || memcmp( temp, "GNU", 3 ) ) {
- if( list_mode )
- printf( "\tunknown S2K %d\n",
- sk->protect.s2k.mode );
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- /* here we know that it is a gnu extension
- * What follows is the GNU protection mode:
- * All values have special meanings
- * and they are mapped in the mode with a base of 1000.
- */
- sk->protect.s2k.mode = 1000 + temp[3];
- }
- switch( sk->protect.s2k.mode ) {
- case 1:
- case 3:
- for(i=0; i < 8 && pktlen; i++, pktlen-- )
- temp[i] = iobuf_get_noeof(inp);
- memcpy(sk->protect.s2k.salt, temp, 8 );
- break;
- }
- switch( sk->protect.s2k.mode ) {
- case 0: if( list_mode ) printf( "\tsimple S2K" );
- break;
- case 1: if( list_mode ) printf( "\tsalted S2K" );
- break;
- case 3: if( list_mode ) printf( "\titer+salt S2K" );
- break;
- case 1001: if( list_mode ) printf( "\tgnu-dummy S2K" );
- break;
- case 1002: if (list_mode) printf("\tgnu-divert-to-card S2K");
- break;
- default:
- if( list_mode )
- printf( "\tunknown %sS2K %d\n",
- sk->protect.s2k.mode < 1000? "":"GNU ",
- sk->protect.s2k.mode );
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
-
- if( list_mode ) {
- printf(", algo: %d,%s hash: %d",
- sk->protect.algo,
- sk->protect.sha1chk?" SHA1 protection,"
- :" simple checksum,",
- sk->protect.s2k.hash_algo );
- if( sk->protect.s2k.mode == 1
- || sk->protect.s2k.mode == 3 ) {
- printf(", salt: ");
- for(i=0; i < 8; i++ )
- printf("%02x", sk->protect.s2k.salt[i]);
- }
- putchar('\n');
- }
-
- if( sk->protect.s2k.mode == 3 ) {
- if( pktlen < 1 ) {
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- sk->protect.s2k.count = iobuf_get(inp);
- pktlen--;
- if( list_mode )
- printf("\tprotect count: %lu\n",
- (ulong)sk->protect.s2k.count);
- }
- else if( sk->protect.s2k.mode == 1002 ) {
- /* Read the serial number. */
- if (pktlen < 1) {
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- snlen = iobuf_get (inp);
- pktlen--;
- if (pktlen < snlen || snlen == -1) {
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- }
- }
- /* Note that a sk->protect.algo > 110 is illegal, but I'm
- not erroring on it here as otherwise there would be no
- way to delete such a key. */
- else { /* old version; no S2K, so we set mode to 0, hash MD5 */
- sk->protect.s2k.mode = 0;
- sk->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
- if( list_mode )
- printf( "\tprotect algo: %d (hash algo: %d)\n",
- sk->protect.algo, sk->protect.s2k.hash_algo );
- }
- /* It is really ugly that we don't know the size
- * of the IV here in cases we are not aware of the algorithm.
- * so a
- * sk->protect.ivlen = cipher_get_blocksize(sk->protect.algo);
- * won't work. The only solution I see is to hardwire it here.
- * NOTE: if you change the ivlen above 16, don't forget to
- * enlarge temp.
- */
- switch( sk->protect.algo ) {
- case 7: case 8: case 9: /* reserved for AES */
- case 10: /* Twofish */
- sk->protect.ivlen = 16;
- break;
- default:
- sk->protect.ivlen = 8;
- }
- if( sk->protect.s2k.mode == 1001 )
- sk->protect.ivlen = 0;
- else if( sk->protect.s2k.mode == 1002 ) {
- if (snlen > 16)
- log_info ("WARNING: serial number of card truncated\n");
- sk->protect.ivlen = snlen < 16? snlen : 16;
-
- }
- if( pktlen < sk->protect.ivlen ) {
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- for(i=0; i < sk->protect.ivlen && pktlen; i++, pktlen-- )
- temp[i] = iobuf_get_noeof(inp);
- if( list_mode ) {
- printf( sk->protect.s2k.mode == 1002? "\tserial-number: "
- : "\tprotect IV: ");
- for(i=0; i < sk->protect.ivlen; i++ )
- printf(" %02x", temp[i] );
- putchar('\n');
- }
- memcpy(sk->protect.iv, temp, sk->protect.ivlen );
- }
- else
- sk->is_protected = 0;
- /* It does not make sense to read it into secure memory.
- * If the user is so careless, not to protect his secret key,
- * we can assume, that he operates an open system :=(.
- * So we put the key into secure memory when we unprotect it. */
- if( sk->protect.s2k.mode == 1001
- || sk->protect.s2k.mode == 1002 ) {
- /* better set some dummy stuff here */
- sk->skey[npkey] = gcry_mpi_set_opaque(NULL, xstrdup ("dummydata"),
- 10*8);
- pktlen = 0;
- }
- else if( is_v4 && sk->is_protected ) {
- /* ugly; the length is encrypted too, so we read all
- * stuff up to the end of the packet into the first
- * skey element */
- sk->skey[npkey] = gcry_mpi_set_opaque(NULL, read_rest(inp, pktlen),
- pktlen*8 );
- pktlen = 0;
- if( list_mode ) {
- printf("\tencrypted stuff follows\n");
- }
- }
- else { /* v3 method: the mpi length is not encrypted */
- for(i=npkey; i < nskey; i++ ) {
- if ( sk->is_protected ) {
- sk->skey[i] = read_protected_v3_mpi (inp, &pktlen);
- if( list_mode )
- printf( "\tskey[%d]: [encrypted]\n", i);
- }
- else {
- n = pktlen;
- sk->skey[i] = mpi_read(inp, &n, 0 );
- pktlen -=n;
- if( list_mode ) {
- printf( "\tskey[%d]: ", i);
- mpi_print(stdout, sk->skey[i], mpi_print_mode );
- putchar('\n');
- }
- }
-
- if (!sk->skey[i])
- rc = GPG_ERR_INV_PACKET;
- }
- if (rc)
- goto leave;
-
- sk->csum = read_16(inp); pktlen -= 2;
- if( list_mode ) {
- printf("\tchecksum: %04hx\n", sk->csum);
- }
- }
- }
- else {
- PKT_public_key *pk = pkt->pkt.public_key;
-
- if( !npkey ) {
- pk->pkey[0] = gcry_mpi_set_opaque( NULL, read_rest(inp, pktlen),
- pktlen*8 );
- pktlen = 0;
- goto leave;
- }
-
- for(i=0; i < npkey; i++ ) {
- n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
- if( list_mode ) {
- printf( "\tpkey[%d]: ", i);
- mpi_print(stdout, pk->pkey[i], mpi_print_mode );
- putchar('\n');
- }
- if (!pk->pkey[i])
- rc = GPG_ERR_INV_PACKET;
- }
- if (rc)
- goto leave;
- }
-
- leave:
- skip_rest(inp, pktlen);
- return rc;
-}
-
-/* Attribute subpackets have the same format as v4 signature
- subpackets. This is not part of OpenPGP, but is done in several
- versions of PGP nevertheless. */
-int
-parse_attribute_subpkts(PKT_user_id *uid)
-{
- size_t n;
- int count=0;
- struct user_attribute *attribs=NULL;
- const byte *buffer=uid->attrib_data;
- int buflen=uid->attrib_len;
- byte type;
-
- xfree (uid->attribs);
-
- while(buflen)
- {
- n = *buffer++; buflen--;
- if( n == 255 ) { /* 4 byte length header */
- if( buflen < 4 )
- goto too_short;
- n = (buffer[0] << 24) | (buffer[1] << 16)
- | (buffer[2] << 8) | buffer[3];
- buffer += 4;
- buflen -= 4;
- }
- else if( n >= 192 ) { /* 2 byte special encoded length header */
- if( buflen < 2 )
- goto too_short;
- n = (( n - 192 ) << 8) + *buffer + 192;
- buffer++;
- buflen--;
- }
- if( buflen < n )
- goto too_short;
-
- attribs=xrealloc(attribs,(count+1)*sizeof(struct user_attribute));
- memset(&attribs[count],0,sizeof(struct user_attribute));
-
- type=*buffer;
- buffer++;
- buflen--;
- n--;
-
- attribs[count].type=type;
- attribs[count].data=buffer;
- attribs[count].len=n;
- buffer+=n;
- buflen-=n;
- count++;
- }
-
- uid->attribs=attribs;
- uid->numattribs=count;
- return count;
-
- too_short:
- log_error("buffer shorter than attribute subpacket\n");
- uid->attribs=attribs;
- uid->numattribs=count;
- return count;
-}
-
-static void setup_user_id(PACKET *packet)
-{
- packet->pkt.user_id->ref = 1;
- packet->pkt.user_id->attribs = NULL;
- packet->pkt.user_id->attrib_data = NULL;
- packet->pkt.user_id->attrib_len = 0;
- packet->pkt.user_id->is_primary = 0;
- packet->pkt.user_id->is_revoked = 0;
- packet->pkt.user_id->is_expired = 0;
- packet->pkt.user_id->expiredate = 0;
- packet->pkt.user_id->created = 0;
- packet->pkt.user_id->help_key_usage = 0;
- packet->pkt.user_id->help_key_expire = 0;
- packet->pkt.user_id->prefs = NULL;
- packet->pkt.user_id->namehash = NULL;
-}
-
-static int
-parse_user_id( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
-{
- byte *p;
-
- packet->pkt.user_id = xmalloc (sizeof *packet->pkt.user_id + pktlen);
- packet->pkt.user_id->len = pktlen;
-
- setup_user_id(packet);
-
- p = packet->pkt.user_id->name;
- for( ; pktlen; pktlen--, p++ )
- *p = iobuf_get_noeof(inp);
- *p = 0;
-
- if( list_mode ) {
- int n = packet->pkt.user_id->len;
- printf(":user ID packet: \"");
- /* fixme: Hey why don't we replace this with print_string?? */
- for(p=packet->pkt.user_id->name; n; p++, n-- ) {
- if( *p >= ' ' && *p <= 'z' )
- putchar(*p);
- else
- printf("\\x%02x", *p );
- }
- printf("\"\n");
- }
- return 0;
-}
-
-
-void
-make_attribute_uidname(PKT_user_id *uid, size_t max_namelen)
-{
- assert ( max_namelen > 70 );
- if(uid->numattribs<=0)
- sprintf(uid->name,"[bad attribute packet of size %lu]",uid->attrib_len);
- else if(uid->numattribs>1)
- sprintf(uid->name,"[%d attributes of size %lu]",
- uid->numattribs,uid->attrib_len);
- else
- {
- /* Only one attribute, so list it as the "user id" */
-
- if(uid->attribs->type==ATTRIB_IMAGE)
- {
- u32 len;
- byte type;
-
- if(parse_image_header(uid->attribs,&type,&len))
- sprintf(uid->name,"[%.20s image of size %lu]",
- image_type_to_string(type,1),(ulong)len);
- else
- sprintf(uid->name,"[invalid image]");
- }
- else
- sprintf(uid->name,"[unknown attribute of size %lu]",
- (ulong)uid->attribs->len);
- }
-
- uid->len = strlen(uid->name);
-}
-
-static int
-parse_attribute( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
-{
- byte *p;
-
-#define EXTRA_UID_NAME_SPACE 71
- packet->pkt.user_id = xmalloc (sizeof *packet->pkt.user_id
- + EXTRA_UID_NAME_SPACE);
-
- setup_user_id(packet);
-
- packet->pkt.user_id->attrib_data = xmalloc (pktlen);
- packet->pkt.user_id->attrib_len = pktlen;
- p = packet->pkt.user_id->attrib_data;
- for( ; pktlen; pktlen--, p++ )
- *p = iobuf_get_noeof(inp);
-
- /* Now parse out the individual attribute subpackets. This is
- somewhat pointless since there is only one currently defined
- attribute type (jpeg), but it is correct by the spec. */
- parse_attribute_subpkts(packet->pkt.user_id);
-
- make_attribute_uidname(packet->pkt.user_id, EXTRA_UID_NAME_SPACE);
-
- if( list_mode ) {
- printf(":attribute packet: %s\n", packet->pkt.user_id->name );
- }
- return 0;
-}
-
-
-static int
-parse_comment( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
-{
- byte *p;
-
- packet->pkt.comment = xmalloc (sizeof *packet->pkt.comment + pktlen - 1);
- packet->pkt.comment->len = pktlen;
- p = packet->pkt.comment->data;
- for( ; pktlen; pktlen--, p++ )
- *p = iobuf_get_noeof(inp);
-
- if( list_mode ) {
- int n = packet->pkt.comment->len;
- printf(":%scomment packet: \"", pkttype == PKT_OLD_COMMENT?
- "OpenPGP draft " : "" );
- for(p=packet->pkt.comment->data; n; p++, n-- ) {
- if( *p >= ' ' && *p <= 'z' )
- putchar(*p);
- else
- printf("\\x%02x", *p );
- }
- printf("\"\n");
- }
- return 0;
-}
-
-
-static void
-parse_trust( iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *pkt )
-{
- int c;
-
- if (pktlen)
- {
- c = iobuf_get_noeof(inp);
- pktlen--;
- pkt->pkt.ring_trust = xmalloc ( sizeof *pkt->pkt.ring_trust );
- pkt->pkt.ring_trust->trustval = c;
- pkt->pkt.ring_trust->sigcache = 0;
- if (!c && pktlen==1)
- {
- c = iobuf_get_noeof (inp);
- pktlen--;
- /* we require that bit 7 of the sigcache is 0 (easier eof handling)*/
- if ( !(c & 0x80) )
- pkt->pkt.ring_trust->sigcache = c;
- }
- if( list_mode )
- printf(":trust packet: flag=%02x sigcache=%02x\n",
- pkt->pkt.ring_trust->trustval,
- pkt->pkt.ring_trust->sigcache);
- }
- else
- {
- if( list_mode )
- printf(":trust packet: empty\n");
- }
- skip_rest (inp, pktlen);
-}
-
-
-static int
-parse_plaintext( iobuf_t inp, int pkttype, unsigned long pktlen,
- PACKET *pkt, int new_ctb )
-{
- int rc = 0;
- int mode, namelen, partial=0;
- PKT_plaintext *pt;
- byte *p;
- int c, i;
-
- if( pktlen && pktlen < 6 ) {
- log_error("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen);
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- /* A packet length of zero indicates partial body length. A zero
- data length isn't a zero length packet due to the header (mode,
- name, etc), so this is accurate. */
- if(pktlen==0)
- partial=1;
- mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
- namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
- pt = pkt->pkt.plaintext = xmalloc (sizeof *pkt->pkt.plaintext + namelen -1);
- pt->new_ctb = new_ctb;
- pt->mode = mode;
- pt->namelen = namelen;
- pt->is_partial = partial;
- if( pktlen ) {
- for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ )
- pt->name[i] = iobuf_get_noeof(inp);
- }
- else {
- for( i=0; i < namelen; i++ )
- if( (c=iobuf_get(inp)) == -1 )
- break;
- else
- pt->name[i] = c;
- }
- pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4;
- pt->len = pktlen;
- pt->buf = inp;
- pktlen = 0;
-
- if( list_mode ) {
- printf(":literal data packet:\n"
- "\tmode %c, created %lu, name=\"",
- mode >= ' ' && mode <'z'? mode : '?',
- (ulong)pt->timestamp );
- for(p=pt->name,i=0; i < namelen; p++, i++ ) {
- if( *p >= ' ' && *p <= 'z' )
- putchar(*p);
- else
- printf("\\x%02x", *p );
- }
- printf("\",\n\traw data: %lu bytes\n", (ulong)pt->len );
- }
-
- leave:
- return rc;
-}
-
-
-static int
-parse_compressed( iobuf_t inp, int pkttype, unsigned long pktlen,
- PACKET *pkt, int new_ctb )
-{
- PKT_compressed *zd;
-
- /* pktlen is here 0, but data follows
- * (this should be the last object in a file or
- * the compress algorithm should know the length)
- */
- zd = pkt->pkt.compressed = xmalloc (sizeof *pkt->pkt.compressed );
- zd->algorithm = iobuf_get_noeof(inp);
- zd->len = 0; /* not used */
- zd->new_ctb = new_ctb;
- zd->buf = inp;
- if( list_mode )
- printf(":compressed packet: algo=%d\n", zd->algorithm);
- return 0;
-}
-
-
-static int
-parse_encrypted( iobuf_t inp, int pkttype, unsigned long pktlen,
- PACKET *pkt, int new_ctb )
-{
- int rc = 0;
- PKT_encrypted *ed;
- unsigned long orig_pktlen = pktlen;
-
- ed = pkt->pkt.encrypted = xmalloc (sizeof *pkt->pkt.encrypted );
- ed->len = pktlen;
- /* we don't know the extralen which is (cipher_blocksize+2)
- because the algorithm ist not specified in this packet.
- However, it is only important to know this for some sanity
- checks on the packet length - it doesn't matter that we can't
- do it */
- ed->extralen = 0;
- ed->buf = NULL;
- ed->new_ctb = new_ctb;
- ed->mdc_method = 0;
- if( pkttype == PKT_ENCRYPTED_MDC ) {
- /* fixme: add some pktlen sanity checks */
- int version;
-
- version = iobuf_get_noeof(inp);
- if (orig_pktlen)
- pktlen--;
- if( version != 1 ) {
- log_error("encrypted_mdc packet with unknown version %d\n",
- version);
- /*skip_rest(inp, pktlen); should we really do this? */
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- ed->mdc_method = DIGEST_ALGO_SHA1;
- }
- if( orig_pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */
- log_error("packet(%d) too short\n", pkttype);
- rc = GPG_ERR_INV_PACKET;
- skip_rest(inp, pktlen);
- goto leave;
- }
- if( list_mode ) {
- if( orig_pktlen )
- printf(":encrypted data packet:\n\tlength: %lu\n", orig_pktlen);
- else
- printf(":encrypted data packet:\n\tlength: unknown\n");
- if( ed->mdc_method )
- printf("\tmdc_method: %d\n", ed->mdc_method );
- }
-
- ed->buf = inp;
- pktlen = 0;
-
- leave:
- return rc;
-}
-
-
-static int
-parse_mdc( iobuf_t inp, int pkttype, unsigned long pktlen,
- PACKET *pkt, int new_ctb )
-{
- int rc = 0;
- PKT_mdc *mdc;
- byte *p;
-
- mdc = pkt->pkt.mdc= xmalloc (sizeof *pkt->pkt.mdc );
- if( list_mode )
- printf(":mdc packet: length=%lu\n", pktlen);
- if( !new_ctb || pktlen != 20 ) {
- log_error("mdc_packet with invalid encoding\n");
- rc = GPG_ERR_INV_PACKET;
- goto leave;
- }
- p = mdc->hash;
- for( ; pktlen; pktlen--, p++ )
- *p = iobuf_get_noeof(inp);
-
- leave:
- return rc;
-}
-
-
-/*
- * This packet is internally generated by PGG (by armor.c) to
- * transfer some information to the lower layer. To make sure that
- * this packet is really a GPG faked one and not one comming from outside,
- * we first check that tehre is a unique tag in it.
- * The format of such a control packet is:
- * n byte session marker
- * 1 byte control type CTRLPKT_xxxxx
- * m byte control data
- */
-
-static int
-parse_gpg_control( iobuf_t inp,
- int pkttype, unsigned long pktlen, PACKET *packet )
-{
- byte *p;
- const byte *sesmark;
- size_t sesmarklen;
- int i;
-
- if ( list_mode )
- printf(":packet 63: length %lu ", pktlen);
-
- sesmark = get_session_marker ( &sesmarklen );
- if ( pktlen < sesmarklen+1 ) /* 1 is for the control bytes */
- goto skipit;
- for( i=0; i < sesmarklen; i++, pktlen-- ) {
- if ( sesmark[i] != iobuf_get_noeof(inp) )
- goto skipit;
- }
- if ( list_mode )
- puts ("- gpg control packet");
-
- packet->pkt.gpg_control = xmalloc (sizeof *packet->pkt.gpg_control
- + pktlen - 1);
- packet->pkt.gpg_control->control = iobuf_get_noeof(inp); pktlen--;
- packet->pkt.gpg_control->datalen = pktlen;
- p = packet->pkt.gpg_control->data;
- for( ; pktlen; pktlen--, p++ )
- *p = iobuf_get_noeof(inp);
-
- return 0;
-
- skipit:
- if ( list_mode ) {
- int c;
-
- i=0;
- printf("- private (rest length %lu)\n", pktlen);
- if( iobuf_in_block_mode(inp) ) {
- while( (c=iobuf_get(inp)) != -1 )
- dump_hex_line(c, &i);
- }
- else {
- for( ; pktlen; pktlen-- )
- dump_hex_line(iobuf_get(inp), &i);
- }
- putchar('\n');
- }
- skip_rest(inp,pktlen);
- return GPG_ERR_INV_PACKET;
-}
-
-/* create a gpg control packet to be used internally as a placeholder */
-PACKET *
-create_gpg_control( ctrlpkttype_t type, const byte *data, size_t datalen )
-{
- PACKET *packet;
- byte *p;
-
- packet = xmalloc ( sizeof *packet );
- init_packet(packet);
- packet->pkttype = PKT_GPG_CONTROL;
- packet->pkt.gpg_control = xmalloc (sizeof *packet->pkt.gpg_control
- + datalen - 1);
- packet->pkt.gpg_control->control = type;
- packet->pkt.gpg_control->datalen = datalen;
- p = packet->pkt.gpg_control->data;
- for( ; datalen; datalen--, p++ )
- *p = *data++;
-
- return packet;
-}
diff --git a/g10/passphrase.c b/g10/passphrase.c
deleted file mode 100644
index 986070a16..000000000
--- a/g10/passphrase.c
+++ /dev/null
@@ -1,1237 +0,0 @@
-/* passphrase.c - Get a passphrase
- * Copyright (C) 1998,1999,2000,2001,2002,2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <assert.h>
-#if !defined(HAVE_DOSISH_SYSTEM) && !defined(__riscos__)
-#include <sys/socket.h>
-#include <sys/un.h>
-#endif
-#if defined (_WIN32) || defined (__CYGWIN32__)
-# include <windows.h>
-#endif
-#include <errno.h>
-#ifdef HAVE_LOCALE_H
-#include <locale.h>
-#endif
-#ifdef HAVE_LANGINFO_CODESET
-#include <langinfo.h>
-#endif
-
-#include "gpg.h"
-#include "util.h"
-#include "memory.h"
-#include "options.h"
-#include "ttyio.h"
-#include "cipher.h"
-#include "keydb.h"
-#include "main.h"
-#include "i18n.h"
-#include "status.h"
-
-
-enum gpga_protocol_codes {
- /* Request codes */
- GPGA_PROT_GET_VERSION = 1,
- GPGA_PROT_GET_PASSPHRASE = 2,
- GPGA_PROT_CLEAR_PASSPHRASE= 3,
- GPGA_PROT_SHUTDOWN = 4,
- GPGA_PROT_FLUSH = 5,
-
- /* Reply codes */
- GPGA_PROT_REPLY_BASE = 0x10000,
- GPGA_PROT_OKAY = 0x10001,
- GPGA_PROT_GOT_PASSPHRASE = 0x10002,
-
- /* Error codes */
- GPGA_PROT_ERROR_BASE = 0x20000,
- GPGA_PROT_PROTOCOL_ERROR = 0x20001,
- GPGA_PROT_INVALID_REQUEST= 0x20002,
- GPGA_PROT_CANCELED = 0x20003,
- GPGA_PROT_NO_PASSPHRASE = 0x20004,
- GPGA_PROT_BAD_PASSPHRASE = 0x20005,
- GPGA_PROT_INVALID_DATA = 0x20006,
- GPGA_PROT_NOT_IMPLEMENTED= 0x20007,
- GPGA_PROT_UI_PROBLEM = 0x20008
-};
-
-
-#define buftou32( p ) ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
- (*((byte*)(p)+2) << 8) | (*((byte*)(p)+3)))
-#define u32tobuf( p, a ) do { \
- ((byte*)p)[0] = (byte)((a) >> 24); \
- ((byte*)p)[1] = (byte)((a) >> 16); \
- ((byte*)p)[2] = (byte)((a) >> 8); \
- ((byte*)p)[3] = (byte)((a) ); \
- } while(0)
-
-#define digitp(p) (*(p) >= '0' && *(p) <= '9')
-#define hexdigitp(a) (digitp (a) \
- || (*(a) >= 'A' && *(a) <= 'F') \
- || (*(a) >= 'a' && *(a) <= 'f'))
-#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
- *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
-#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
-
-
-
-static char *fd_passwd = NULL;
-static char *next_pw = NULL;
-static char *last_pw = NULL;
-
-#if defined (_WIN32)
-static int read_fd = 0;
-static int write_fd = 0;
-#endif
-
-static void hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create );
-
-int
-have_static_passphrase()
-{
- if ( opt.use_agent )
- return 0;
- return !!fd_passwd;
-}
-
-/****************
- * Set the passphrase to be used for the next query and only for the next
- * one.
- */
-void
-set_next_passphrase( const char *s )
-{
- xfree (next_pw);
- next_pw = NULL;
- if( s ) {
- next_pw = gcry_xmalloc_secure ( strlen(s)+1 );
- strcpy(next_pw, s );
- }
-}
-
-/****************
- * Get the last passphrase used in passphrase_to_dek.
- * Note: This removes the passphrase from this modules and
- * the caller must free the result. May return NULL:
- */
-char *
-get_last_passphrase()
-{
- char *p = last_pw;
- last_pw = NULL;
- return p;
-}
-
-
-void
-read_passphrase_from_fd( int fd )
-{
- int i, len;
- char *pw;
-
- if ( opt.use_agent )
- { /* Not used but we have to do a dummy read, so that it won't end
- up at the begin of the message if the quite usual trick to
- prepend the passphtrase to the message is used. */
- char buf[1];
-
- while (!(read (fd, buf, 1) != 1 || *buf == '\n' ))
- ;
- *buf = 0;
- return;
- }
-
- if (!opt.batch )
- tty_printf("Reading passphrase from file descriptor %d ...", fd );
- for (pw = NULL, i = len = 100; ; i++ )
- {
- if (i >= len-1 )
- {
- char *pw2 = pw;
- len += 100;
- pw = gcry_xmalloc_secure ( len );
- if( pw2 )
- memcpy(pw, pw2, i );
- else
- i=0;
- }
- if (read( fd, pw+i, 1) != 1 || pw[i] == '\n' )
- break;
- }
- pw[i] = 0;
- if (!opt.batch)
- tty_printf("\b\b\b \n" );
-
- xfree ( fd_passwd );
- fd_passwd = pw;
-}
-
-static int
-writen ( int fd, const void *buf, size_t nbytes )
-{
-#if defined (_WIN32)
- DWORD nwritten, nleft = nbytes;
-
- while (nleft > 0) {
- if ( !WriteFile( (HANDLE)write_fd, buf, nleft, &nwritten, NULL) ) {
- log_error("write failed: ec=%d\n", (int)GetLastError());
- return -1;
- }
- /*log_info("** WriteFile fd=%d nytes=%d nwritten=%d\n",
- write_fd, nbytes, (int)nwritten);*/
- Sleep(100);
-
- nleft -= nwritten;
- buf = (const BYTE *)buf + nwritten;
- }
-#elif defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
- /* not implemented */
-#else
- size_t nleft = nbytes;
- int nwritten;
-
- while( nleft > 0 ) {
- nwritten = write( fd, buf, nleft );
- if( nwritten < 0 ) {
- if ( errno == EINTR )
- nwritten = 0;
- else {
- log_error ( "write() failed: %s\n", strerror (errno) );
- return -1;
- }
- }
- nleft -= nwritten;
- buf = (const char*)buf + nwritten;
- }
-#endif
-
- return 0;
-}
-
-
-static int
-readn ( int fd, void *buf, size_t buflen, size_t *ret_nread )
-{
-#if defined (_WIN32)
- DWORD nread, nleft = buflen;
-
- while (nleft > 0) {
- if ( !ReadFile( (HANDLE)read_fd, buf, nleft, &nread, NULL) ) {
- log_error("read() error: ec=%d\n", (int)GetLastError());
- return -1;
- }
- if (!nread || GetLastError() == ERROR_BROKEN_PIPE)
- break;
- /*log_info("** ReadFile fd=%d buflen=%d nread=%d\n",
- read_fd, buflen, (int)nread);*/
- Sleep(100);
-
- nleft -= nread;
- buf = (BYTE *)buf + nread;
- }
- if (ret_nread)
- *ret_nread = buflen - nleft;
-
-#elif defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
- /* not implemented */
-#else
- size_t nleft = buflen;
- int nread;
- char *p;
-
- p = buf;
- while( nleft > 0 ) {
- nread = read ( fd, buf, nleft );
- if( nread < 0 ) {
- if (nread == EINTR)
- nread = 0;
- else {
- log_error ( "read() error: %s\n", strerror (errno) );
- return -1;
- }
- }
- else if( !nread )
- break; /* EOF */
- nleft -= nread;
- buf = (char*)buf + nread;
- }
- if( ret_nread )
- *ret_nread = buflen - nleft;
-#endif
-
- return 0;
-}
-
-/* read an entire line */
-static int
-readline (int fd, char *buf, size_t buflen)
-{
- size_t nleft = buflen;
- char *p;
- int nread = 0;
-
- while (nleft > 0)
- {
- int n = read (fd, buf, nleft);
- if (n < 0)
- {
- if (errno == EINTR)
- continue;
- return -1; /* read error */
- }
- else if (!n)
- {
- return -1; /* incomplete line */
- }
- p = buf;
- nleft -= n;
- buf += n;
- nread += n;
-
- for (; n && *p != '\n'; n--, p++)
- ;
- if (n)
- {
- break; /* at least one full line available - that's enough.
- This function is just a temporary hack until we use
- the assuna lib in gpg. So it is okay to forget
- about pending bytes */
- }
- }
-
- return nread;
-}
-
-
-
-#if !defined (__riscos__)
-
-#if !defined (_WIN32)
-/* For the new Assuan protocol we may have to send options */
-static int
-agent_send_option (int fd, const char *name, const char *value)
-{
- char buf[200];
- int nread;
- char *line;
- int i;
-
- line = xmalloc (7 + strlen (name) + 1 + strlen (value) + 2);
- strcpy (stpcpy (stpcpy (stpcpy (
- stpcpy (line, "OPTION "), name), "="), value), "\n");
- i = writen (fd, line, strlen (line));
- xfree (line);
- if (i)
- return -1;
-
- /* get response */
- nread = readline (fd, buf, DIM(buf)-1);
- if (nread < 3)
- return -1;
-
- if (buf[0] == 'O' && buf[1] == 'K' && (buf[2] == ' ' || buf[2] == '\n'))
- return 0; /* okay */
-
- return -1;
-}
-
-static int
-agent_send_all_options (int fd)
-{
- char *dft_display = NULL;
- const char *dft_ttyname = NULL;
- char *dft_ttytype = NULL;
- char *old_lc = NULL;
- char *dft_lc = NULL;
- int rc = 0;
-
- dft_display = getenv ("DISPLAY");
- if (opt.display || dft_display)
- {
- if (agent_send_option (fd, "display",
- opt.display ? opt.display : dft_display))
- return -1;
- }
-
- if (!opt.ttyname)
- {
- dft_ttyname = getenv ("GPG_TTY");
- if ((!dft_ttyname || !*dft_ttyname) && tty_get_ttyname ())
- dft_ttyname = tty_get_ttyname ();
- }
- if (opt.ttyname || dft_ttyname)
- {
- if (agent_send_option (fd, "ttyname",
- opt.ttyname ? opt.ttyname : dft_ttyname))
- return -1;
- }
-
- dft_ttytype = getenv ("TERM");
- if (opt.ttytype || (dft_ttyname && dft_ttytype))
- {
- if (agent_send_option (fd, "ttytype",
- opt.ttyname ? opt.ttytype : dft_ttytype))
- return -1;
- }
-
-#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE)
- old_lc = setlocale (LC_CTYPE, NULL);
- if (old_lc)
- old_lc = xstrdup (old_lc);
- dft_lc = setlocale (LC_CTYPE, "");
-#endif
- if (opt.lc_ctype || (dft_ttyname && dft_lc))
- {
- rc = agent_send_option (fd, "lc-ctype",
- opt.lc_ctype ? opt.lc_ctype : dft_lc);
- }
-#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE)
- if (old_lc)
- {
- setlocale (LC_CTYPE, old_lc);
- xfree (old_lc);
- }
-#endif
- if (rc)
- return rc;
-
-#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)
- old_lc = setlocale (LC_MESSAGES, NULL);
- if (old_lc)
- old_lc = xstrdup (old_lc);
- dft_lc = setlocale (LC_MESSAGES, "");
-#endif
- if (opt.lc_messages || (dft_ttyname && dft_lc))
- {
- rc = agent_send_option (fd, "lc-messages",
- opt.lc_messages ? opt.lc_messages : dft_lc);
- }
-#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)
- if (old_lc)
- {
- setlocale (LC_MESSAGES, old_lc);
- xfree (old_lc);
- }
-#endif
- return rc;
-}
-#endif /*!_WIN32*/
-
-
-/*
- * Open a connection to the agent and send the magic string
- * Returns: -1 on error or an filedescriptor for urther processing
- */
-
-static int
-agent_open (int *ret_prot)
-{
-#if defined (_WIN32)
- int fd;
- char *infostr, *p;
- HANDLE h;
- char pidstr[128];
-
- *ret_prot = 0;
- if ( !(infostr = read_w32_registry_string(NULL, "Software\\GNU\\GnuPG",
- "agentPID"))
- || *infostr == '0') {
- log_error( _("gpg-agent is not available in this session\n"));
- return -1;
- }
- free(infostr);
-
- sprintf(pidstr, "%u", (unsigned int)GetCurrentProcessId());
- if (write_w32_registry_string(NULL, "Software\\GNU\\GnuPG",
- "agentCID", pidstr)) {
- log_error( _("can't set client pid for the agent\n") );
- return -1;
- }
- h = OpenEvent(EVENT_ALL_ACCESS, FALSE, "gpg_agent");
- SetEvent(h);
- Sleep(50); /* some time for the server */
- if ( !(p = read_w32_registry_string(NULL, "Software\\GNU\\GnuPG",
- "agentReadFD")) ) {
- log_error( _("can't get server read FD for the agent\n") );
- return -1;
- }
- read_fd = atol(p);
- free(p);
- if ( !(p = read_w32_registry_string(NULL, "Software\\GNU\\GnuPG",
- "agentWriteFD")) ) {
- log_error ( _("can't get server write FD for the agent\n") );
- return -1;
- }
- write_fd = atol(p);
- free(p);
- fd = 0;
-
- if ( writen ( fd, "GPGA\0\0\0\x01", 8 ) ) {
- fd = -1;
- }
-#else /* Posix */
-
- int fd;
- char *infostr, *p;
- struct sockaddr_un client_addr;
- size_t len;
- int prot;
-
- if (opt.gpg_agent_info)
- infostr = xstrdup (opt.gpg_agent_info);
- else
- {
- infostr = getenv ( "GPG_AGENT_INFO" );
- if ( !infostr || !*infostr ) {
- log_error (_("gpg-agent is not available in this session\n"));
- opt.use_agent = 0;
- return -1;
- }
- infostr = xstrdup ( infostr );
- }
-
- if ( !(p = strchr ( infostr, ':')) || p == infostr
- || (p-infostr)+1 >= sizeof client_addr.sun_path ) {
- log_error( _("malformed GPG_AGENT_INFO environment variable\n"));
- xfree (infostr );
- opt.use_agent = 0;
- return -1;
- }
- *p++ = 0;
- /* See whether this is the new gpg-agent using the Assuna protocl.
- This agent identifies itself by have an info string with a
- version number in the 3rd field. */
- while (*p && *p != ':')
- p++;
- prot = *p? atoi (p+1) : 0;
- if ( prot < 0 || prot > 1) {
- log_error (_("gpg-agent protocol version %d is not supported\n"),prot);
- xfree (infostr );
- opt.use_agent = 0;
- return -1;
- }
- *ret_prot = prot;
-
- if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 ) {
- log_error ("can't create socket: %s\n", strerror(errno) );
- xfree (infostr );
- opt.use_agent = 0;
- return -1;
- }
-
- memset( &client_addr, 0, sizeof client_addr );
- client_addr.sun_family = AF_UNIX;
- strcpy( client_addr.sun_path, infostr );
- len = offsetof (struct sockaddr_un, sun_path)
- + strlen(client_addr.sun_path) + 1;
-
- if( connect( fd, (struct sockaddr*)&client_addr, len ) == -1 ) {
- log_error ( _("can't connect to `%s': %s\n"),
- infostr, strerror (errno) );
- xfree (infostr );
- close (fd );
- opt.use_agent = 0;
- return -1;
- }
- xfree (infostr);
-
- if (!prot) {
- if ( writen ( fd, "GPGA\0\0\0\x01", 8 ) ) {
- close (fd);
- fd = -1;
- }
- }
- else { /* assuan based gpg-agent */
- char line[200];
- int nread;
-
- nread = readline (fd, line, DIM(line));
- if (nread < 3 || !(line[0] == 'O' && line[1] == 'K'
- && (line[2] == '\n' || line[2] == ' ')) ) {
- log_error ( _("communication problem with gpg-agent\n"));
- close (fd );
- opt.use_agent = 0;
- return -1;
- }
-
- if (agent_send_all_options (fd)) {
- log_error (_("problem with the agent - disabling agent use\n"));
- close (fd);
- opt.use_agent = 0;
- return -1;
- }
-
- }
-#endif
-
- return fd;
-}
-
-
-static void
-agent_close ( int fd )
-{
-#if defined (_WIN32)
- HANDLE h = OpenEvent(EVENT_ALL_ACCESS, FALSE, "gpg_agent");
- ResetEvent(h);
-#else
- close (fd);
-#endif
-}
-#endif /* !__riscos__ */
-
-
-
-/*
- * Ask the GPG Agent for the passphrase.
- * Mode 0: Allow cached passphrase
- * 1: No cached passphrase FIXME: Not really implemented
- * 2: Ditto, but change the text to "repeat entry"
- *
- * Note that TRYAGAIN_TEXT must not be translated. If canceled is not
- * NULL, the function does set it to 1 if the user canceled the
- * operation.
- */
-static char *
-agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text,
- int *canceled)
-{
-#if defined(__riscos__)
- return NULL;
-#else
- size_t n;
- char *atext = NULL;
- char buf[50];
- int fd = -1;
- int nread;
- u32 reply;
- char *pw = NULL;
- PKT_public_key *pk = xcalloc (1, sizeof *pk );
- byte fpr[MAX_FINGERPRINT_LEN];
- int have_fpr = 0;
- int prot;
- char *orig_codeset = NULL;
-
- if (canceled)
- *canceled = 0;
-
-#if MAX_FINGERPRINT_LEN < 20
-#error agent needs a 20 byte fingerprint
-#endif
-
- memset (fpr, 0, MAX_FINGERPRINT_LEN );
- if( keyid && get_pubkey( pk, keyid ) )
- {
- free_public_key( pk );
- pk = NULL; /* oops: no key for some reason */
- }
-
-#ifdef ENABLE_NLS
- /* The Assuan agent protocol requires us to transmit utf-8 strings */
- orig_codeset = bind_textdomain_codeset (PACKAGE_GT, NULL);
-#ifdef HAVE_LANGINFO_CODESET
- if (!orig_codeset)
- orig_codeset = nl_langinfo (CODESET);
-#endif
- if (orig_codeset)
- { /* We only switch when we are able to restore the codeset later. */
- orig_codeset = xstrdup (orig_codeset);
- if (!bind_textdomain_codeset (PACKAGE_GT, "utf-8"))
- orig_codeset = NULL;
- }
-#endif
-
- if ( (fd = agent_open (&prot)) == -1 )
- goto failure;
-
- if ( !mode && pk && keyid )
- {
- char *uid;
- size_t uidlen;
- const char *algo_name = gcry_pk_algo_name ( pk->pubkey_algo );
- const char *timestr;
- char *maink;
-
- if ( !algo_name )
- algo_name = "?";
-
- if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
- && keyid[1] != keyid[3] )
- maink = xasprintf ( _(" (main key ID %08lX)"), (ulong)keyid[3] );
- else
- maink = NULL;
-
- uid = get_user_id ( keyid, &uidlen );
- timestr = strtimestamp (pk->timestamp);
- atext = xasprintf (
- _("You need a passphrase to unlock the"
- " secret key for user:\n"
- "\"%.*s\"\n"
- "%u-bit %s key, ID %08lX, created %s%s\n" ),
- uidlen, uid,
- nbits_from_pk (pk), algo_name, (ulong)keyid[1], timestr,
- maink?maink:"" );
- xfree (uid);
- xfree (maink);
-
- {
- size_t dummy;
- fingerprint_from_pk( pk, fpr, &dummy );
- have_fpr = 1;
- }
-
- }
- else if (mode == 2 )
- atext = xstrdup ( _("Repeat passphrase\n") );
- else
- atext = xstrdup ( _("Enter passphrase\n") );
-
- if (!prot)
- { /* old style protocol */
- n = 4 + 20 + strlen (atext);
- u32tobuf (buf, n );
- u32tobuf (buf+4, GPGA_PROT_GET_PASSPHRASE );
- memcpy (buf+8, fpr, 20 );
- if ( writen ( fd, buf, 28 ) || writen ( fd, atext, strlen (atext) ) )
- goto failure;
- xfree (atext); atext = NULL;
-
- /* get response */
- if ( readn ( fd, buf, 12, &nread ) )
- goto failure;
-
- if ( nread < 8 )
- {
- log_error ( "response from agent too short\n" );
- goto failure;
- }
- n = buftou32 ( buf );
- reply = buftou32 ( buf + 4 );
- if ( reply == GPGA_PROT_GOT_PASSPHRASE )
- {
- size_t pwlen;
- size_t nn;
-
- if ( nread < 12 || n < 8 )
- {
- log_error ( "response from agent too short\n" );
- goto failure;
- }
- pwlen = buftou32 ( buf + 8 );
- nread -= 12;
- n -= 8;
- if ( pwlen > n || n > 1000 )
- {
- log_error (_("passphrase too long\n"));
- /* or protocol error */
- goto failure;
- }
- /* we read the whole block in one chunk to give no hints
- * on how long the passhrase actually is - this wastes some bytes
- * but because we already have this padding we should not loosen
- * this by issuing 2 read calls */
- pw = xmalloc_secure ( n+1 );
- if ( readn ( fd, pw, n, &nn ) )
- goto failure;
- if ( n != nn )
- {
- log_error (_("invalid response from agent\n"));
- goto failure;
- }
- pw[pwlen] = 0; /* make a C String */
- agent_close (fd);
- free_public_key( pk );
-#ifdef ENABLE_NLS
- if (orig_codeset)
- bind_textdomain_codeset (PACKAGE_GT, orig_codeset);
-#endif
- xfree (orig_codeset);
- return pw;
- }
- else if ( reply == GPGA_PROT_CANCELED )
- {
- log_info ( _("cancelled by user\n") );
- if (canceled)
- *canceled = 1;
- }
- else
- log_error ( _("problem with the agent: agent returns 0x%lx\n"),
- (ulong)reply );
- }
- else
- { /* The new Assuan protocol */
- char *line, *p;
- const unsigned char *s;
- int i;
-
- if (!tryagain_text)
- tryagain_text = "X";
- else
- tryagain_text = _(tryagain_text);
-
- /* We allocate 2 time the needed space for atext so that there
- is enough space for escaping */
- line = xmalloc (15 + 46
- + 3*strlen (tryagain_text) + 3*strlen (atext) + 2);
- strcpy (line, "GET_PASSPHRASE ");
- p = line+15;
- if (!mode && have_fpr)
- {
- for (i=0; i < 20; i++, p +=2 )
- sprintf (p, "%02X", fpr[i]);
- }
- else
- *p++ = 'X'; /* no caching */
- *p++ = ' ';
- for (i=0, s=tryagain_text; *s; s++)
- {
- if (*s < ' ' || *s == '+')
- {
- sprintf (p, "%%%02X", *s);
- p += 3;
- }
- else if (*s == ' ')
- *p++ = '+';
- else
- *p++ = *s;
- }
- *p++ = ' ';
- *p++ = 'X'; /* Use the standard prompt */
- *p++ = ' ';
- /* copy description */
- for (i=0, s= atext; *s; s++)
- {
- if (*s < ' ' || *s == '+')
- {
- sprintf (p, "%%%02X", *s);
- p += 3;
- }
- else if (*s == ' ')
- *p++ = '+';
- else
- *p++ = *s;
- }
- *p++ = '\n';
- i = writen (fd, line, p - line);
- xfree (line);
- if (i)
- goto failure;
- xfree (atext); atext = NULL;
-
- /* get response */
- pw = xmalloc_secure (500);
- nread = readline (fd, pw, 499);
- if (nread < 3)
- goto failure;
-
- if (pw[0] == 'O' && pw[1] == 'K' && pw[2] == ' ')
- { /* we got a passphrase - convert it back from hex */
- size_t pwlen = 0;
-
- for (i=3; i < nread && hexdigitp (pw+i); i+=2)
- pw[pwlen++] = xtoi_2 (pw+i);
- pw[pwlen] = 0; /* make a C String */
- agent_close (fd);
- free_public_key( pk );
-#ifdef ENABLE_NLS
- if (orig_codeset)
- bind_textdomain_codeset (PACKAGE_GT, orig_codeset);
-#endif
- xfree (orig_codeset);
- return pw;
- }
- else if (nread > 7 && !memcmp (pw, "ERR 111", 7)
- && (pw[7] == ' ' || pw[7] == '\n') )
- {
- log_info (_("cancelled by user\n") );
- if (canceled)
- *canceled = 1;
- }
- else
- {
- log_error (_("problem with the agent - disabling agent use\n"));
- opt.use_agent = 0;
- }
- }
-
-
- failure:
-#ifdef ENABLE_NLS
- if (orig_codeset)
- bind_textdomain_codeset (PACKAGE_GT, orig_codeset);
-#endif
- xfree (atext);
- if ( fd != -1 )
- agent_close (fd);
- xfree (pw );
- free_public_key( pk );
-
- return NULL;
-#endif /* Posix or W32 */
-}
-
-/*
- * Clear the cached passphrase
- */
-void
-passphrase_clear_cache ( u32 *keyid, int algo )
-{
-#if defined(__riscos__)
- return ;
-#else
- size_t n;
- char buf[200];
- int fd = -1;
- size_t nread;
- u32 reply;
- PKT_public_key *pk;
- byte fpr[MAX_FINGERPRINT_LEN];
- int prot;
-
-#if MAX_FINGERPRINT_LEN < 20
-#error agent needs a 20 byte fingerprint
-#endif
-
- if (!opt.use_agent)
- return;
-
- pk = xcalloc (1, sizeof *pk );
- memset (fpr, 0, MAX_FINGERPRINT_LEN );
- if( !keyid || get_pubkey( pk, keyid ) )
- {
- log_debug ("oops, no key in passphrase_clear_cache\n");
- goto failure; /* oops: no key for some reason */
- }
-
- {
- size_t dummy;
- fingerprint_from_pk( pk, fpr, &dummy );
- }
-
- if ( (fd = agent_open (&prot)) == -1 )
- goto failure;
-
- if (!prot)
- {
- n = 4 + 20;
- u32tobuf (buf, n );
- u32tobuf (buf+4, GPGA_PROT_CLEAR_PASSPHRASE );
- memcpy (buf+8, fpr, 20 );
- if ( writen ( fd, buf, 28 ) )
- goto failure;
-
- /* get response */
- if ( readn ( fd, buf, 8, &nread ) )
- goto failure;
-
- if ( nread < 8 ) {
- log_error ( "response from agent too short\n" );
- goto failure;
- }
-
- reply = buftou32 ( buf + 4 );
- if ( reply != GPGA_PROT_OKAY && reply != GPGA_PROT_NO_PASSPHRASE )
- {
- log_error ( _("problem with the agent: agent returns 0x%lx\n"),
- (ulong)reply );
- }
- }
- else
- { /* The assuan protocol */
- char *line, *p;
- int i;
-
- line = xmalloc (17 + 40 + 2);
- strcpy (line, "CLEAR_PASSPHRASE ");
- p = line+17;
- for (i=0; i < 20; i++, p +=2 )
- sprintf (p, "%02X", fpr[i]);
- *p++ = '\n';
- i = writen (fd, line, p - line);
- xfree (line);
- if (i)
- goto failure;
-
- /* get response */
- nread = readline (fd, buf, DIM(buf)-1);
- if (nread < 3)
- goto failure;
-
- if (buf[0] == 'O' && buf[1] == 'K' && (buf[2] == ' ' || buf[2] == '\n'))
- ;
- else
- {
- log_error (_("problem with the agent - disabling agent use\n"));
- opt.use_agent = 0;
- }
- }
-
- failure:
- if (fd != -1)
- agent_close (fd);
- free_public_key( pk );
-#endif /* Posix or W32 */
-}
-
-
-
-
-/****************
- * Get a passphrase for the secret key with KEYID, display TEXT
- * if the user needs to enter the passphrase.
- * mode 0 = standard, 1 = same but don't show key info,
- * 2 = create new passphrase
- * Returns: a DEK with a session key; caller must free
- * or NULL if the passphrase was not correctly repeated.
- * (only for mode 2)
- * a dek->keylen of 0 means: no passphrase entered.
- * (only for mode 2)
- *
- * pubkey_algo is only informational. Note that TRYAGAIN_TEXT must
- * not be translated as this is done within this function (required to
- * switch to utf-8 when the agent is in use). If CANCELED is not
- * NULL, it is set to 1 if the user choosed to cancel the operation,
- * otherwise it will be set to 0.
- */
-DEK *
-passphrase_to_dek( u32 *keyid, int pubkey_algo,
- int cipher_algo, STRING2KEY *s2k, int mode,
- const char *tryagain_text, int *canceled)
-{
- char *pw = NULL;
- DEK *dek;
- STRING2KEY help_s2k;
-
- if (canceled)
- *canceled = 0;
-
- if( !s2k ) {
- /* This is used for the old rfc1991 mode
- * Note: This must match the code in encode.c with opt.rfc1991 set */
- s2k = &help_s2k;
- s2k->mode = 0;
- s2k->hash_algo = opt.s2k_digest_algo;
- }
-
- if( !next_pw && is_status_enabled() ) {
- char buf[50];
-
- if( keyid ) {
- u32 used_kid[2];
- char *us;
-
- if( keyid[2] && keyid[3] ) {
- used_kid[0] = keyid[2];
- used_kid[1] = keyid[3];
- }
- else {
- used_kid[0] = keyid[0];
- used_kid[1] = keyid[1];
- }
-
- us = get_long_user_id_string( keyid );
- write_status_text( STATUS_USERID_HINT, us );
- xfree (us);
-
- sprintf( buf, "%08lX%08lX %08lX%08lX %d 0",
- (ulong)keyid[0], (ulong)keyid[1],
- (ulong)used_kid[0], (ulong)used_kid[1],
- pubkey_algo );
-
- write_status_text( STATUS_NEED_PASSPHRASE, buf );
- }
- else {
- sprintf( buf, "%d %d %d", cipher_algo, s2k->mode, s2k->hash_algo );
- write_status_text( STATUS_NEED_PASSPHRASE_SYM, buf );
- }
- }
-
- if( keyid && !opt.batch && !next_pw && mode!=1 ) {
- PKT_public_key *pk = xcalloc (1, sizeof *pk );
- size_t n;
- char *p;
-
- tty_printf(_("\nYou need a passphrase to unlock the secret key for\n"
- "user: \"") );
- p = get_user_id( keyid, &n );
- tty_print_utf8_string( p, n );
- xfree (p);
- tty_printf("\"\n");
-
- if( !get_pubkey( pk, keyid ) ) {
- const char *s = gcry_pk_algo_name ( pk->pubkey_algo );
- tty_printf( _("%u-bit %s key, ID %08lX, created %s"),
- nbits_from_pk( pk ), s?s:"?", (ulong)keyid[1],
- strtimestamp(pk->timestamp) );
- if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
- && keyid[1] != keyid[3] )
- tty_printf( _(" (main key ID %08lX)"), (ulong)keyid[3] );
- tty_printf("\n");
- }
-
- tty_printf("\n");
- free_public_key( pk );
- }
-
- agent_died:
- if( next_pw ) {
- pw = next_pw;
- next_pw = NULL;
- }
- else if ( opt.use_agent ) {
- pw = agent_get_passphrase ( keyid, mode == 2? 1: 0,
- tryagain_text, canceled );
- if (!pw)
- {
- if (!opt.use_agent)
- goto agent_died;
- pw = xstrdup ("");
- }
- if( *pw && mode == 2 ) {
- char *pw2 = agent_get_passphrase ( keyid, 2, NULL, canceled );
- if (!pw2)
- {
- if (!opt.use_agent)
- {
- xfree (pw);
- pw = NULL;
- goto agent_died;
- }
- pw2 = xstrdup ("");
- }
- if( strcmp(pw, pw2) ) {
- xfree (pw2);
- xfree (pw);
- return NULL;
- }
- xfree (pw2);
- }
- }
- else if( fd_passwd ) {
- pw = xmalloc_secure ( strlen(fd_passwd)+1 );
- strcpy( pw, fd_passwd );
- }
- else if( opt.batch ) {
- log_error(_("can't query password in batchmode\n"));
- pw = xstrdup ( "" ); /* return an empty passphrase */
- }
- else {
- pw = cpr_get_hidden("passphrase.enter", _("Enter passphrase: ") );
- tty_kill_prompt();
- if( mode == 2 && !cpr_enabled() ) {
- char *pw2 = cpr_get_hidden("passphrase.repeat",
- _("Repeat passphrase: ") );
- tty_kill_prompt();
- if( strcmp(pw, pw2) ) {
- xfree (pw2);
- xfree (pw);
- return NULL;
- }
- xfree (pw2);
- }
- }
-
- if( !pw || !*pw )
- write_status( STATUS_MISSING_PASSPHRASE );
-
- dek = xcalloc_secure (1, sizeof *dek );
- dek->algo = cipher_algo;
- if( !*pw && mode == 2 )
- dek->keylen = 0;
- else
- hash_passphrase( dek, pw, s2k, mode==2 );
- xfree (last_pw);
- last_pw = pw;
- return dek;
-}
-
-
-/****************
- * Hash a passphrase using the supplied s2k. If create is true, create
- * a new salt or what else must be filled into the s2k for a new key.
- * always needs: dek->algo, s2k->mode, s2k->hash_algo.
- */
-static void
-hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create )
-{
- MD_HANDLE md;
- int pass, i;
- int used = 0;
- int pwlen = strlen(pw);
-
- assert( s2k->hash_algo );
- dek->keylen = gcry_cipher_get_algo_keylen (dek->algo);
- if( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) )
- BUG();
-
- gcry_md_open (&md, s2k->hash_algo, 1);
- for(pass=0; used < dek->keylen ; pass++ ) {
- if( pass ) {
- gcry_md_reset(md);
- for(i=0; i < pass; i++ ) /* preset the hash context */
- gcry_md_putc (md, 0 );
- }
-
- if( s2k->mode == 1 || s2k->mode == 3 ) {
- int len2 = pwlen + 8;
- ulong count = len2;
-
- if( create && !pass ) {
- gcry_randomize(s2k->salt, 8, GCRY_STRONG_RANDOM );
- if( s2k->mode == 3 )
- s2k->count = 96; /* 65536 iterations */
- }
-
- if( s2k->mode == 3 ) {
- count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6);
- if( count < len2 )
- count = len2;
- }
- /* a little bit complicated because we need a ulong for count */
- while( count > len2 ) { /* maybe iterated+salted */
- gcry_md_write( md, s2k->salt, 8 );
- gcry_md_write( md, pw, pwlen );
- count -= len2;
- }
- if( count < 8 )
- gcry_md_write( md, s2k->salt, count );
- else {
- gcry_md_write( md, s2k->salt, 8 );
- count -= 8;
- gcry_md_write( md, pw, count );
- }
- }
- else
- gcry_md_write( md, pw, pwlen );
- gcry_md_final ( md );
- i = gcry_md_get_algo_dlen (s2k->hash_algo);
- if( i > dek->keylen - used )
- i = dek->keylen - used;
- memcpy( dek->key+used, gcry_md_read (md, s2k->hash_algo), i );
- used += i;
- }
- gcry_md_close (md);
-}
-
diff --git a/g10/photoid.c b/g10/photoid.c
deleted file mode 100644
index 00cc7a273..000000000
--- a/g10/photoid.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/* photoid.c - photo ID handling code
- * Copyright (C) 2001, 2002 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#ifdef _WIN32
-# include <windows.h>
-# ifndef VER_PLATFORM_WIN32_WINDOWS
-# define VER_PLATFORM_WIN32_WINDOWS 1
-# endif
-#endif
-#include "packet.h"
-#include "status.h"
-#include "exec.h"
-#include "keydb.h"
-#include "util.h"
-#include "i18n.h"
-#include "iobuf.h"
-#include "memory.h"
-#include "options.h"
-#include "main.h"
-#include "photoid.h"
-
-/* Generate a new photo id packet, or return NULL if canceled */
-PKT_user_id *generate_photo_id(PKT_public_key *pk)
-{
- PKT_user_id *uid;
- int error=1,i;
- unsigned int len;
- char *filename=NULL;
- byte *photo=NULL;
- byte header[16];
- iobuf_t file;
-
- header[0]=0x10; /* little side of photo header length */
- header[1]=0; /* big side of photo header length */
- header[2]=1; /* 1 == version of photo header */
- header[3]=1; /* 1 == JPEG */
-
- for(i=4;i<16;i++) /* The reserved bytes */
- header[i]=0;
-
-#define EXTRA_UID_NAME_SPACE 71
- uid=xcalloc (1,sizeof(*uid)+71);
-
- printf(_("\nPick an image to use for your photo ID. "
- "The image must be a JPEG file.\n"
- "Remember that the image is stored within your public key. "
- "If you use a\n"
- "very large picture, your key will become very large as well!\n"
- "Keeping the image close to 240x288 is a good size to use.\n"));
-
- while(photo==NULL)
- {
- printf("\n");
-
- xfree (filename);
-
- filename=cpr_get("photoid.jpeg.add",
- _("Enter JPEG filename for photo ID: "));
-
- if(strlen(filename)==0)
- goto scram;
-
- file=iobuf_open(filename);
- if(!file)
- {
- log_error(_("Unable to open photo \"%s\": %s\n"),
- filename,strerror(errno));
- continue;
- }
-
- len=iobuf_get_filelength(file);
- if(len>6144)
- {
- printf("This JPEG is really large (%d bytes) !\n",len);
- if(!cpr_get_answer_is_yes("photoid.jpeg.size",
- _("Are you sure you want to use it (y/N)? ")))
- {
- iobuf_close(file);
- continue;
- }
- }
-
- photo=xmalloc (len);
- iobuf_read(file,photo,len);
- iobuf_close(file);
-
- /* Is it a JPEG? */
- if(photo[0]!=0xFF || photo[1]!=0xD8 ||
- photo[6]!='J' || photo[7]!='F' || photo[8]!='I' || photo[9]!='F')
- {
- log_error(_("\"%s\" is not a JPEG file\n"),filename);
- xfree (photo);
- photo=NULL;
- continue;
- }
-
- /* Build the packet */
- build_attribute_subpkt(uid,1,photo,len,header,16);
- parse_attribute_subpkts(uid);
- make_attribute_uidname(uid, EXTRA_UID_NAME_SPACE);
-
- /* Showing the photo is not safe when noninteractive since the
- "user" may not be able to dismiss a viewer window! */
- if(opt.command_fd==-1)
- {
- show_photos(uid->attribs,uid->numattribs,pk,NULL);
- switch(cpr_get_answer_yes_no_quit("photoid.jpeg.okay",
- _("Is this photo correct (y/N/q)? ")))
- {
- case -1:
- goto scram;
- case 0:
- free_attributes(uid);
- xfree (photo);
- photo=NULL;
- continue;
- }
- }
- }
-
- error=0;
- uid->ref=1;
-
- scram:
- xfree (filename);
- xfree (photo);
-
- if(error)
- {
- free_attributes(uid);
- xfree (uid);
- return NULL;
- }
-
- return uid;
-}
-
-/* Returns 0 for error, 1 for valid */
-int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len)
-{
- u16 headerlen;
-
- if(attr->len<3)
- return 0;
-
- /* For historical reasons (i.e. "oops!"), the header length is
- little endian. */
- headerlen=(attr->data[1]<<8) | attr->data[0];
-
- if(headerlen>attr->len)
- return 0;
-
- if(type && attr->len>=4)
- {
- if(attr->data[2]==1) /* header version 1 */
- *type=attr->data[3];
- else
- *type=0;
- }
-
- *len=attr->len-headerlen;
-
- if(*len==0)
- return 0;
-
- return 1;
-}
-
-/* style==0 for extension, 1 for name, 2 for MIME type. Remember that
- the "name" style string could be used in a user ID name field, so
- make sure it is not too big (see parse-packet.c:parse_attribute).
- Extensions should be 3 characters long for the best cross-platform
- compatibility. */
-char *image_type_to_string(byte type,int style)
-{
- char *string;
-
- switch(type)
- {
- case 1: /* jpeg */
- if(style==0)
- string="jpg";
- else if(style==1)
- string="jpeg";
- else
- string="image/jpeg";
- break;
-
- default:
- if(style==0)
- string="bin";
- else if(style==1)
- string="unknown";
- else
- string="image/x-unknown";
- break;
- }
-
- return string;
-}
-
-#if !defined(FIXED_PHOTO_VIEWER) && !defined(DISABLE_PHOTO_VIEWER)
-static const char *get_default_photo_command(void)
-{
-#if defined(_WIN32)
- OSVERSIONINFO osvi;
-
- memset(&osvi,0,sizeof(osvi));
- osvi.dwOSVersionInfoSize=sizeof(osvi);
- GetVersionEx(&osvi);
-
- if(osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
- return "start /w %i";
- else
- return "cmd /c start /w %i";
-#elif defined(__APPLE__)
- /* OS X. This really needs more than just __APPLE__. */
- return "open %I";
-#elif defined(__riscos__)
- return "Filer_Run %I";
-#else
- return "xloadimage -fork -quiet -title 'KeyID 0x%k' stdin";
-#endif
-}
-#endif
-
-void show_photos(const struct user_attribute *attrs,
- int count,PKT_public_key *pk,PKT_secret_key *sk)
-{
-#ifndef DISABLE_PHOTO_VIEWER
- int i;
- struct expando_args args;
- u32 len;
- u32 kid[2]={0,0};
-
- memset(&args,0,sizeof(args));
- args.pk=pk;
- args.sk=sk;
-
- if(pk)
- keyid_from_pk(pk,kid);
- else if(sk)
- keyid_from_sk(sk,kid);
-
- for(i=0;i<count;i++)
- if(attrs[i].type==ATTRIB_IMAGE &&
- parse_image_header(&attrs[i],&args.imagetype,&len))
- {
- char *command,*name;
- struct exec_info *spawn;
- int offset=attrs[i].len-len;
-
-#ifdef FIXED_PHOTO_VIEWER
- opt.photo_viewer=FIXED_PHOTO_VIEWER;
-#else
- if(!opt.photo_viewer)
- opt.photo_viewer=get_default_photo_command();
-#endif
-
- /* make command grow */
- command=pct_expando(opt.photo_viewer,&args);
- if(!command)
- goto fail;
-
- name=xmalloc (16+strlen(EXTSEP_S)+
- strlen(image_type_to_string(args.imagetype,0))+1);
-
- /* Make the filename. Notice we are not using the image
- encoding type for more than cosmetics. Most external image
- viewers can handle a multitude of types, and even if one
- cannot understand a particular type, we have no way to know
- which. The spec permits this, by the way. -dms */
-
-#ifdef USE_ONLY_8DOT3
- sprintf(name,"%08lX" EXTSEP_S "%s",(ulong)kid[1],
- image_type_to_string(args.imagetype,0));
-#else
- sprintf(name,"%08lX%08lX" EXTSEP_S "%s",(ulong)kid[0],(ulong)kid[1],
- image_type_to_string(args.imagetype,0));
-#endif
-
- if(exec_write(&spawn,NULL,command,name,1,1)!=0)
- {
- xfree (name);
- goto fail;
- }
-
-#ifdef __riscos__
- riscos_set_filetype_by_mimetype(spawn->tempfile_in,
- image_type_to_string(args.imagetype,2));
-#endif
-
- xfree (name);
-
- fwrite(&attrs[i].data[offset],attrs[i].len-offset,1,spawn->tochild);
-
- if(exec_read(spawn)!=0)
- {
- exec_finish(spawn);
- goto fail;
- }
-
- if(exec_finish(spawn)!=0)
- goto fail;
- }
-
- return;
-
- fail:
- log_error(_("unable to display photo ID!\n"));
-#endif
-}
diff --git a/g10/photoid.h b/g10/photoid.h
deleted file mode 100644
index 187ca5ba2..000000000
--- a/g10/photoid.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* photoid.h
- * Copyright (C) 2001, 2002 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-/* Photo ID functions */
-
-#ifndef _PHOTOID_H_
-#define _PHOTOID_H_
-
-#include "packet.h"
-
-PKT_user_id *generate_photo_id(PKT_public_key *pk);
-int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len);
-char *image_type_to_string(byte type,int style);
-void show_photos(const struct user_attribute *attrs,
- int count,PKT_public_key *pk,PKT_secret_key *sk);
-
-#endif /* !_PHOTOID_H_ */
diff --git a/g10/pipemode.c b/g10/pipemode.c
deleted file mode 100644
index 9f2ddfdb5..000000000
--- a/g10/pipemode.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/* pipemode.c - pipemode handler
- * Copyright (C) 1998, 1990, 2000, 2001 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "options.h"
-#include "packet.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "keydb.h"
-#include "memory.h"
-#include "util.h"
-#include "main.h"
-#include "status.h"
-#include "filter.h"
-
-
-#define CONTROL_PACKET_SPACE 30
-#define FAKED_LITERAL_PACKET_SPACE (9+2+2)
-
-
-enum pipemode_state_e {
- STX_init = 0,
- STX_wait_operation,
- STX_begin,
- STX_text,
- STX_detached_signature,
- STX_detached_signature_wait_text,
- STX_signed_data,
- STX_wait_init
-};
-
-struct pipemode_context_s {
- enum pipemode_state_e state;
- int operation;
- int stop;
- int block_mode;
- UnarmorPump unarmor_ctx;
-};
-
-
-static size_t
-make_control ( byte *buf, int code, int operation )
-{
- const byte *sesmark;
- size_t sesmarklen, n=0;;
-
- sesmark = get_session_marker( &sesmarklen );
- if ( sesmarklen > 20 )
- BUG();
-
- buf[n++] = 0xff; /* new format, type 63, 1 length byte */
- n++; /* length will fixed below */
- memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
- buf[n++] = CTRLPKT_PIPEMODE;
- buf[n++] = code;
- buf[n++] = operation;
- buf[1] = n-2;
- return n;
-}
-
-
-
-static int
-pipemode_filter( void *opaque, int control,
- iobuf_t a, byte *buf, size_t *ret_len)
-{
- size_t size = *ret_len;
- struct pipemode_context_s *stx = opaque;
- int rc=0;
- size_t n = 0;
- int esc = 0;
-
- if( control == IOBUFCTRL_UNDERFLOW ) {
- *ret_len = 0;
- /* reserve some space for one control packet */
- if ( size <= CONTROL_PACKET_SPACE+FAKED_LITERAL_PACKET_SPACE )
- BUG();
- size -= CONTROL_PACKET_SPACE+FAKED_LITERAL_PACKET_SPACE;
-
- if ( stx->block_mode ) {
- /* reserve 2 bytes for the block length */
- buf[n++] = 0;
- buf[n++] = 0;
- }
-
-
- while ( n < size ) {
- /* FIXME: we have to make sure that we have a large enough
- * buffer for a control packet even after we already read
- * something. The easest way to do this is probably by ungetting
- * the control sequence and returning the buffer we have
- * already assembled */
- int c = iobuf_get (a);
- if (c == -1) {
- if ( stx->state != STX_init ) {
- log_error ("EOF encountered at wrong state\n");
- stx->stop = 1;
- return -1;
- }
- break;
- }
- if ( esc ) {
- switch (c) {
- case '@':
- if ( stx->state == STX_text ) {
- buf[n++] = c;
- break;
- }
- else if ( stx->state == STX_detached_signature ) {
- esc = 0;
- goto do_unarmor; /* not a very elegant solution */
- }
- else if ( stx->state == STX_detached_signature_wait_text) {
- esc = 0;
- break; /* just ignore it in this state */
- }
- log_error ("@@ not allowed in current state\n");
- return -1;
- case '<': /* begin of stream part */
- if ( stx->state != STX_init ) {
- log_error ("nested begin of stream\n");
- stx->stop = 1;
- return -1;
- }
- stx->state = STX_wait_operation;
- stx->block_mode = 0;
- unarmor_pump_release (stx->unarmor_ctx);
- stx->unarmor_ctx = NULL;
- break;
- case '>': /* end of stream part */
- if ( stx->state != STX_wait_init ) {
- log_error ("invalid state for @>\n");
- stx->stop = 1;
- return -1;
- }
- stx->state = STX_init;
- break;
- case 'V': /* operation = verify */
- case 'E': /* operation = encrypt */
- case 'S': /* operation = sign */
- case 'B': /* operation = detach sign */
- case 'C': /* operation = clearsign */
- case 'D': /* operation = decrypt */
- if ( stx->state != STX_wait_operation ) {
- log_error ("invalid state for operation code\n");
- stx->stop = 1;
- return -1;
- }
- stx->operation = c;
- if ( stx->operation == 'B') {
- stx->state = STX_detached_signature;
- if ( !opt.no_armor )
- stx->unarmor_ctx = unarmor_pump_new ();
- }
- else
- stx->state = STX_begin;
- n += make_control ( buf+n, 1, stx->operation );
- /* must leave after a control packet */
- goto leave;
-
- case 't': /* plaintext text follows */
- if ( stx->state == STX_detached_signature_wait_text )
- stx->state = STX_detached_signature;
- if ( stx->state == STX_detached_signature ) {
- if ( stx->operation != 'B' ) {
- log_error ("invalid operation for this state\n");
- stx->stop = 1;
- return -1;
- }
- stx->state = STX_signed_data;
- n += make_control ( buf+n, 2, 'B' );
- /* and now we fake a literal data packet much the same
- * as in armor.c */
- buf[n++] = 0xaf; /* old packet format, type 11,
- var length */
- buf[n++] = 0; /* set the length header */
- buf[n++] = 6;
- buf[n++] = 'b'; /* we ignore it anyway */
- buf[n++] = 0; /* namelength */
- memset(buf+n, 0, 4); /* timestamp */
- n += 4;
- /* and return now so that we are sure to have
- * more space in the bufer for the next control
- * packet */
- stx->block_mode = 1;
- goto leave2;
- }
- else {
- log_error ("invalid state for @t\n");
- stx->stop = 1;
- return -1;
- }
- break;
-
- case '.': /* ready */
- if ( stx->state == STX_signed_data ) {
- if (stx->block_mode) {
- buf[0] = (n-2) >> 8;
- buf[1] = (n-2);
- if ( buf[0] || buf[1] ) {
- /* end of blocks marker */
- buf[n++] = 0;
- buf[n++] = 0;
- }
- stx->block_mode = 0;
- }
- n += make_control ( buf+n, 3, 'B' );
- }
- else {
- log_error ("invalid state for @.\n");
- stx->stop = 1;
- return -1;
- }
- stx->state = STX_wait_init;
- goto leave;
-
- default:
- log_error ("invalid escape sequence 0x%02x in stream\n",
- c);
- stx->stop = 1;
- return -1;
- }
- esc = 0;
- }
- else if (c == '@')
- esc = 1;
- else if (stx->unarmor_ctx) {
- do_unarmor: /* used to handle a @@ */
- c = unarmor_pump (stx->unarmor_ctx, c);
- if ( !(c & ~255) )
- buf[n++] = c;
- else if ( c < 0 ) {
- /* end of armor or error - we don't care becuase
- the armor can be modified anyway. The unarmored
- stuff should stand for itself. */
- unarmor_pump_release (stx->unarmor_ctx);
- stx->unarmor_ctx = NULL;
- stx->state = STX_detached_signature_wait_text;
- }
- }
- else if (stx->state == STX_detached_signature_wait_text)
- ; /* just wait */
- else
- buf[n++] = c;
- }
-
- leave:
- if ( !n ) {
- stx->stop = 1;
- rc = -1; /* eof */
- }
- if ( stx->block_mode ) {
- /* fixup the block length */
- buf[0] = (n-2) >> 8;
- buf[1] = (n-2);
- }
- leave2:
- /*log_hexdump ("pipemode:", buf, n );*/
- *ret_len = n;
- }
- else if( control == IOBUFCTRL_DESC )
- *(char**)buf = "pipemode_filter";
- return rc;
-}
-
-
-
-void
-run_in_pipemode(void)
-{
- iobuf_t fp;
- armor_filter_context_t afx;
- struct pipemode_context_s stx;
- int rc;
-
- memset( &afx, 0, sizeof afx);
- memset( &stx, 0, sizeof stx);
-
- fp = iobuf_open("-");
- iobuf_push_filter (fp, pipemode_filter, &stx );
-
- do {
- write_status (STATUS_BEGIN_STREAM);
- rc = proc_packets( NULL, fp );
- write_status (STATUS_END_STREAM);
- } while ( !stx.stop );
-
-}
-
-
-
-
-
-
diff --git a/g10/pkclist.c b/g10/pkclist.c
deleted file mode 100644
index 71e6492e8..000000000
--- a/g10/pkclist.c
+++ /dev/null
@@ -1,1372 +0,0 @@
-/* pkclist.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2002
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "options.h"
-#include "packet.h"
-#include "errors.h"
-#include "keydb.h"
-#include "memory.h"
-#include "util.h"
-#include "main.h"
-#include "trustdb.h"
-#include "ttyio.h"
-#include "status.h"
-#include "photoid.h"
-#include "i18n.h"
-
-
-#define CONTROL_D ('D' - 'A' + 1)
-
-
-/****************
- * Show the revocation reason as it is stored with the given signature
- */
-static void
-do_show_revocation_reason( PKT_signature *sig )
-{
- size_t n, nn;
- const byte *p, *pp;
- int seq = 0;
- const char *text;
-
- while( (p = enum_sig_subpkt (sig->hashed, SIGSUBPKT_REVOC_REASON,
- &n, &seq, NULL )) ) {
- if( !n )
- continue; /* invalid - just skip it */
-
- if( *p == 0 )
- text = _("No reason specified");
- else if( *p == 0x01 )
- text = _("Key is superseded");
- else if( *p == 0x02 )
- text = _("Key has been compromised");
- else if( *p == 0x03 )
- text = _("Key is no longer used");
- else if( *p == 0x20 )
- text = _("User ID is no longer valid");
- else
- text = NULL;
-
- log_info( _("reason for revocation: ") );
- if( text )
- fputs( text, log_get_stream () );
- else
- fprintf( log_get_stream (), "code=%02x", *p );
- putc( '\n', log_get_stream () );
- n--; p++;
- pp = NULL;
- do {
- /* We don't want any empty lines, so skip them */
- while( n && *p == '\n' ) {
- p++;
- n--;
- }
- if( n ) {
- pp = memchr( p, '\n', n );
- nn = pp? pp - p : n;
- log_info( _("revocation comment: ") );
- print_string( log_get_stream(), p, nn, 0 );
- putc( '\n', log_get_stream() );
- p += nn; n -= nn;
- }
- } while( pp );
- }
-}
-
-/* Mode 0: try and find the revocation based on the pk (i.e. check
- subkeys, etc.) Mode 1: use only the revocation on the main pk */
-
-void
-show_revocation_reason( PKT_public_key *pk, int mode )
-{
- /* Hmmm, this is not so easy becuase we have to duplicate the code
- * used in the trustbd to calculate the keyflags. We need to find
- * a clean way to check revocation certificates on keys and
- * signatures. And there should be no duplicate code. Because we
- * enter this function only when the trustdb told us that we have
- * a revoked key, we could simply look for a revocation cert and
- * display this one, when there is only one. Let's try to do this
- * until we have a better solution. */
- KBNODE node, keyblock = NULL;
- byte fingerprint[MAX_FINGERPRINT_LEN];
- size_t fingerlen;
- int rc;
-
- /* get the keyblock */
- fingerprint_from_pk( pk, fingerprint, &fingerlen );
- rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
- if( rc ) { /* that should never happen */
- log_debug( "failed to get the keyblock\n");
- return;
- }
-
- for( node=keyblock; node; node = node->next ) {
- if( (mode && node->pkt->pkttype == PKT_PUBLIC_KEY) ||
- ( ( node->pkt->pkttype == PKT_PUBLIC_KEY
- || node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
- && !cmp_public_keys( node->pkt->pkt.public_key, pk ) ) )
- break;
- }
- if( !node ) {
- log_debug("Oops, PK not in keyblock\n");
- release_kbnode( keyblock );
- return;
- }
- /* now find the revocation certificate */
- for( node = node->next; node ; node = node->next ) {
- if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
- break;
- if( node->pkt->pkttype == PKT_SIGNATURE
- && (node->pkt->pkt.signature->sig_class == 0x20
- || node->pkt->pkt.signature->sig_class == 0x28 ) ) {
- /* FIXME: we should check the signature here */
- do_show_revocation_reason ( node->pkt->pkt.signature );
- break;
- }
- }
-
- /* We didn't find it, so check if the whole key is revoked */
- if(!node && !mode)
- show_revocation_reason(pk,1);
-
- release_kbnode( keyblock );
-}
-
-
-static void
-show_paths (const PKT_public_key *pk, int only_first )
-{
- log_debug("not yet implemented\n");
-#if 0
- void *context = NULL;
- unsigned otrust, validity;
- int last_level, level;
-
- last_level = 0;
- while( (level=enum_cert_paths( &context, &lid, &otrust, &validity)) != -1){
- char *p;
- int c, rc;
- size_t n;
- u32 keyid[2];
- PKT_public_key *pk ;
-
- if( level < last_level && only_first )
- break;
- last_level = level;
-
- rc = keyid_from_lid( lid, keyid );
-
- if( rc ) {
- log_error("ooops: can't get keyid for lid %lu\n", lid);
- return;
- }
-
- pk = xcalloc (1, sizeof *pk );
- rc = get_pubkey( pk, keyid );
- if( rc ) {
- log_error("key %08lX: public key not found: %s\n",
- (ulong)keyid[1], gpg_strerror (rc) );
- return;
- }
-
- tty_printf("%*s%4u%c/%08lX.%lu %s \"",
- level*2, "",
- nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
- (ulong)keyid[1], lid, datestr_from_pk( pk ) );
-
- c = trust_letter(otrust);
- if( c )
- putchar( c );
- else
- printf( "%02x", otrust );
- putchar('/');
- c = trust_letter(validity);
- if( c )
- putchar( c );
- else
- printf( "%02x", validity );
- putchar(' ');
-
- p = get_user_id( keyid, &n );
- tty_print_utf8_string( p, n ),
- xfree (p);
- tty_printf("\"\n");
- free_public_key( pk );
- }
- enum_cert_paths( &context, NULL, NULL, NULL ); /* release context */
-#endif
- tty_printf("\n");
-}
-
-
-
-
-/****************
- * mode: 0 = standard
- * 1 = Without key info and additional menu option 'm'
- * this does also add an option to set the key to ultimately trusted.
- * Returns:
- * -2 = nothing changed - caller should show some additional info
- * -1 = quit operation
- * 0 = nothing changed
- * 1 = new ownertrust now in new_trust
- */
-static int
-do_edit_ownertrust (PKT_public_key *pk, int mode,
- unsigned *new_trust, int defer_help )
-{
- char *p;
- size_t n;
- u32 keyid[2];
- int changed=0;
- int quit=0;
- int show=0;
- int min_num;
- int did_help=defer_help;
- unsigned int minimum=get_min_ownertrust(pk);
-
- switch(minimum)
- {
- default: min_num=0; break;
- case TRUST_UNDEFINED: min_num=1; break;
- case TRUST_NEVER: min_num=2; break;
- case TRUST_MARGINAL: min_num=3; break;
- case TRUST_FULLY: min_num=4; break;
- }
-
- keyid_from_pk (pk, keyid);
- for(;;) {
- /* a string with valid answers */
- const char *ans = _("iImMqQsS");
-
- if( !did_help )
- {
- if( !mode )
- {
- KBNODE keyblock, un;
-
- tty_printf(_("No trust value assigned to:\n"
- "%4u%c/%08lX %s \""),
- nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
- (ulong)keyid[1], datestr_from_pk( pk ) );
- p = get_user_id( keyid, &n );
- tty_print_utf8_string( p, n ),
- xfree (p);
- tty_printf("\"\n");
-
- keyblock = get_pubkeyblock (keyid);
- if (!keyblock)
- BUG ();
- for (un=keyblock; un; un = un->next) {
- if (un->pkt->pkttype != PKT_USER_ID )
- continue;
- if (un->pkt->pkt.user_id->is_revoked )
- continue;
- if (un->pkt->pkt.user_id->is_expired )
- continue;
- /* Only skip textual primaries */
- if (un->pkt->pkt.user_id->is_primary &&
- !un->pkt->pkt.user_id->attrib_data )
- continue;
-
- if((opt.verify_options&VERIFY_SHOW_PHOTOS)
- && un->pkt->pkt.user_id->attrib_data)
- show_photos(un->pkt->pkt.user_id->attribs,
- un->pkt->pkt.user_id->numattribs,pk,NULL);
-
- tty_printf (" %s", _(" aka \""));
- tty_print_utf8_string (un->pkt->pkt.user_id->name,
- un->pkt->pkt.user_id->len );
- tty_printf("\"\n");
- }
-
- print_fingerprint (pk, NULL, 2);
- tty_printf("\n");
- }
- /* This string also used in keyedit.c:sign_uids */
- tty_printf (_(
- "Please decide how far you trust this user to correctly\n"
- "verify other users' keys (by looking at passports,\n"
- "checking fingerprints from different sources...)?\n\n"));
- if(min_num<=1)
- tty_printf (_(" %d = I don't know\n"), 1);
- if(min_num<=2)
- tty_printf (_(" %d = I do NOT trust\n"), 2);
- if(min_num<=3)
- tty_printf (_(" %d = I trust marginally\n"), 3);
- if(min_num<=4)
- tty_printf (_(" %d = I trust fully\n"), 4);
- if (mode)
- tty_printf (_(" %d = I trust ultimately\n"), 5);
-#if 0
- /* not yet implemented */
- tty_printf (_(" i = please show me more information\n") );
-#endif
- if( mode )
- tty_printf(_(" m = back to the main menu\n"));
- else
- {
- tty_printf(_(" s = skip this key\n"));
- tty_printf(_(" q = quit\n"));
- }
- tty_printf("\n");
- if(minimum)
- tty_printf(_("The minimum trust level for this key is: %s\n\n"),
- trust_value_to_string(minimum));
- did_help = 1;
- }
- if( strlen(ans) != 8 )
- BUG();
- p = cpr_get("edit_ownertrust.value",_("Your decision? "));
- trim_spaces(p);
- cpr_kill_prompt();
- if( !*p )
- did_help = 0;
- else if( *p && p[1] )
- ;
- else if( !p[1] && ((*p >= '0'+min_num) && *p <= (mode?'5':'4')) )
- {
- unsigned int trust;
- switch( *p )
- {
- case '1': trust = TRUST_UNDEFINED; break;
- case '2': trust = TRUST_NEVER ; break;
- case '3': trust = TRUST_MARGINAL ; break;
- case '4': trust = TRUST_FULLY ; break;
- case '5': trust = TRUST_ULTIMATE ; break;
- default: BUG();
- }
- if (trust == TRUST_ULTIMATE
- && !cpr_get_answer_is_yes ("edit_ownertrust.set_ultimate.okay",
- _("Do you really want to set this key"
- " to ultimate trust? ")))
- ; /* no */
- else
- {
- *new_trust = trust;
- changed = 1;
- break;
- }
- }
-#if 0
- /* not yet implemented */
- else if( *p == ans[0] || *p == ans[1] )
- {
- tty_printf(_("Certificates leading to an ultimately trusted key:\n"));
- show = 1;
- break;
- }
-#endif
- else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) )
- {
- break ; /* back to the menu */
- }
- else if( !mode && (*p == ans[6] || *p == ans[7] ) )
- {
- break; /* skip */
- }
- else if( !mode && (*p == ans[4] || *p == ans[5] ) )
- {
- quit = 1;
- break ; /* back to the menu */
- }
- xfree (p); p = NULL;
- }
- xfree (p);
- return show? -2: quit? -1 : changed;
-}
-
-/*
- * Display a menu to change the ownertrust of the key PK (which should
- * be a primary key).
- * For mode values see do_edit_ownertrust ()
- */
-int
-edit_ownertrust (PKT_public_key *pk, int mode )
-{
- unsigned int trust;
- int no_help = 0;
-
- for(;;)
- {
- switch ( do_edit_ownertrust (pk, mode, &trust, no_help ) )
- {
- case -1: /* quit */
- return -1;
- case -2: /* show info */
- show_paths(pk, 1);
- no_help = 1;
- break;
- case 1: /* trust value set */
- trust &= ~TRUST_FLAG_DISABLED;
- trust |= get_ownertrust (pk) & TRUST_FLAG_DISABLED;
- update_ownertrust (pk, trust );
- return 1;
- default:
- return 0;
- }
- }
-}
-
-
-/****************
- * Check whether we can trust this pk which has a trustlevel of TRUSTLEVEL
- * Returns: true if we trust.
- */
-static int
-do_we_trust( PKT_public_key *pk, unsigned int *trustlevel )
-{
- unsigned int trustmask = 0;
-
- /* FIXME: get_pubkey_byname already checks the validity and won't
- * return keys which are either expired or revoked - so these
- * question here won't get triggered. We have to find a solution
- * for this. It might make sense to have a function in getkey.c
- * which does only the basic checks and returns even revoked and
- * expired keys. This fnction could then also returhn a list of
- * keys if the speicified name is ambiguous
- */
- if( (*trustlevel & TRUST_FLAG_REVOKED) ) {
- log_info(_("key %08lX: key has been revoked!\n"),
- (ulong)keyid_from_pk( pk, NULL) );
- show_revocation_reason( pk, 0 );
- if( opt.batch )
- return 0; /* no */
-
- if( !cpr_get_answer_is_yes("revoked_key.override",
- _("Use this key anyway? ")) )
- return 0; /* no */
- trustmask |= TRUST_FLAG_REVOKED;
- }
- if( (*trustlevel & TRUST_FLAG_SUB_REVOKED) ) {
- log_info(_("key %08lX: subkey has been revoked!\n"),
- (ulong)keyid_from_pk( pk, NULL) );
- show_revocation_reason( pk, 0 );
- if( opt.batch )
- return 0;
-
- if( !cpr_get_answer_is_yes("revoked_key.override",
- _("Use this key anyway? ")) )
- return 0;
- trustmask |= TRUST_FLAG_SUB_REVOKED;
- }
- *trustlevel &= ~trustmask;
-
- if( opt.trust_model==TM_ALWAYS ) {
- if( opt.verbose )
- log_info("No trust check due to --trust-model always option\n");
- return 1;
- }
-
- switch( (*trustlevel & TRUST_MASK) ) {
- case TRUST_EXPIRED:
- log_info(_("%08lX: key has expired\n"),
- (ulong)keyid_from_pk( pk, NULL) );
- return 0; /* no */
-
- default:
- log_error ("invalid trustlevel %u returned from validation layer\n",
- *trustlevel);
- /* fall thru */
- case TRUST_UNKNOWN:
- case TRUST_UNDEFINED:
- log_info(_("%08lX: There is no assurance this key belongs "
- "to the named user\n"),(ulong)keyid_from_pk( pk, NULL) );
- return 0; /* no */
-
- /* No way to get here? */
- case TRUST_NEVER:
- log_info(_("%08lX: We do NOT trust this key\n"),
- (ulong)keyid_from_pk( pk, NULL) );
- return 0; /* no */
-
- case TRUST_MARGINAL:
- log_info(_("%08lX: There is limited assurance this key belongs "
- "to the named user\n"),(ulong)keyid_from_pk(pk,NULL));
- return 1; /* yes */
-
- case TRUST_FULLY:
- if( opt.verbose )
- log_info(_("This key probably belongs to the named user\n"));
- return 1; /* yes */
-
- case TRUST_ULTIMATE:
- if( opt.verbose )
- log_info(_("This key belongs to us\n"));
- return 1; /* yes */
- }
-
- return 1; /* yes */
-}
-
-
-
-/****************
- * wrapper around do_we_trust, so we can ask whether to use the
- * key anyway.
- */
-static int
-do_we_trust_pre( PKT_public_key *pk, unsigned int trustlevel )
-{
- int rc;
-
- rc = do_we_trust( pk, &trustlevel );
-
- if( (trustlevel & TRUST_FLAG_REVOKED) && !rc )
- return 0;
- if( (trustlevel & TRUST_FLAG_SUB_REVOKED) && !rc )
- return 0;
-
- if( !opt.batch && !rc ) {
- u32 keyid[2];
-
- keyid_from_pk( pk, keyid);
- tty_printf( "%4u%c/%08lX %s \"",
- nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
- (ulong)keyid[1], datestr_from_pk( pk ) );
- /* If the pk was chosen by a particular user ID, this is the
- one to ask about. */
- if(pk->user_id)
- tty_print_utf8_string(pk->user_id->name,pk->user_id->len);
- else
- {
- size_t n;
- char *p = get_user_id( keyid, &n );
- tty_print_utf8_string( p, n );
- xfree (p);
- }
- tty_printf("\"\n");
- print_fingerprint (pk, NULL, 2);
- tty_printf("\n");
-
- tty_printf(_(
-"It is NOT certain that the key belongs to the person named\n"
-"in the user ID. If you *really* know what you are doing,\n"
-"you may answer the next question with yes\n\n"));
-
- if( cpr_get_answer_is_yes("untrusted_key.override",
- _("Use this key anyway? ")) )
- rc = 1;
-
- /* Hmmm: Should we set a flag to tell the user about
- * his decision the next time he encrypts for this recipient?
- */
- }
- else if( opt.trust_model==TM_ALWAYS && !rc ) {
- if( !opt.quiet )
- log_info(_("WARNING: Using untrusted key!\n"));
- rc = 1;
- }
- return rc;
-}
-
-
-
-/****************
- * Check whether we can trust this signature.
- * Returns: Error if we shall not trust this signatures.
- */
-int
-check_signatures_trust( PKT_signature *sig )
-{
- PKT_public_key *pk = xcalloc (1, sizeof *pk );
- unsigned int trustlevel;
- int rc=0;
-
- rc = get_pubkey( pk, sig->keyid );
- if (rc)
- { /* this should not happen */
- log_error("Ooops; the key vanished - can't check the trust\n");
- rc = GPG_ERR_NO_PUBKEY;
- goto leave;
- }
-
- if ( opt.trust_model==TM_ALWAYS )
- {
- if( !opt.quiet )
- log_info(_("WARNING: Using untrusted key!\n"));
- if (opt.with_fingerprint)
- print_fingerprint (pk, NULL, 1);
- goto leave;
- }
-
- trustlevel = get_validity (pk, NULL);
-
- if ( (trustlevel & TRUST_FLAG_REVOKED) )
- {
- write_status( STATUS_KEYREVOKED );
- log_info(_("WARNING: This key has been revoked by its owner!\n"));
- log_info(_(" This could mean that the signature is forgery.\n"));
- show_revocation_reason( pk, 0 );
- }
- else if ((trustlevel & TRUST_FLAG_SUB_REVOKED) )
- {
- write_status( STATUS_KEYREVOKED );
- log_info(_("WARNING: This subkey has been revoked by its owner!\n"));
- show_revocation_reason( pk, 0 );
- }
-
- if ((trustlevel & TRUST_FLAG_DISABLED))
- log_info (_("Note: This key has been disabled.\n"));
-
- switch ( (trustlevel & TRUST_MASK) )
- {
- case TRUST_EXPIRED:
- log_info(_("Note: This key has expired!\n"));
- print_fingerprint (pk, NULL, 1);
- break;
-
- default:
- log_error ("invalid trustlevel %u returned from validation layer\n",
- trustlevel);
- /* fall thru */
- case TRUST_UNKNOWN:
- case TRUST_UNDEFINED:
- write_status( STATUS_TRUST_UNDEFINED );
- log_info(_("WARNING: This key is not certified with"
- " a trusted signature!\n"));
- log_info(_(" There is no indication that the "
- "signature belongs to the owner.\n" ));
- print_fingerprint (pk, NULL, 1);
- break;
-
- case TRUST_NEVER:
- /* currently we won't get that status */
- write_status( STATUS_TRUST_NEVER );
- log_info(_("WARNING: We do NOT trust this key!\n"));
- log_info(_(" The signature is probably a FORGERY.\n"));
- if (opt.with_fingerprint)
- print_fingerprint (pk, NULL, 1);
- rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
- break;
-
- case TRUST_MARGINAL:
- write_status( STATUS_TRUST_MARGINAL );
- log_info(_("WARNING: This key is not certified with"
- " sufficiently trusted signatures!\n"));
- log_info(_(" It is not certain that the"
- " signature belongs to the owner.\n" ));
- print_fingerprint (pk, NULL, 1);
- break;
-
- case TRUST_FULLY:
- write_status( STATUS_TRUST_FULLY );
- if (opt.with_fingerprint)
- print_fingerprint (pk, NULL, 1);
- break;
-
- case TRUST_ULTIMATE:
- write_status( STATUS_TRUST_ULTIMATE );
- if (opt.with_fingerprint)
- print_fingerprint (pk, NULL, 1);
- break;
- }
-
- leave:
- free_public_key( pk );
- return rc;
-}
-
-
-void
-release_pk_list( PK_LIST pk_list )
-{
- PK_LIST pk_rover;
-
- for( ; pk_list; pk_list = pk_rover ) {
- pk_rover = pk_list->next;
- free_public_key( pk_list->pk );
- xfree ( pk_list );
- }
-}
-
-
-static int
-key_present_in_pk_list(PK_LIST pk_list, PKT_public_key *pk)
-{
- for( ; pk_list; pk_list = pk_list->next)
- if (cmp_public_keys(pk_list->pk, pk) == 0)
- return 0;
-
- return -1;
-}
-
-
-/****************
- * Return a malloced string with a default reciepient if there is any
- */
-static char *
-default_recipient(void)
-{
- PKT_secret_key *sk;
- byte fpr[MAX_FINGERPRINT_LEN+1];
- size_t n;
- char *p;
- int i;
-
- if( opt.def_recipient )
- return xstrdup ( opt.def_recipient );
- if( !opt.def_recipient_self )
- return NULL;
- sk = xcalloc (1, sizeof *sk );
- i = get_seckey_byname( sk, NULL, 0 );
- if( i ) {
- free_secret_key( sk );
- return NULL;
- }
- n = MAX_FINGERPRINT_LEN;
- fingerprint_from_sk( sk, fpr, &n );
- free_secret_key( sk );
- p = xmalloc ( 2*n+3 );
- *p++ = '0';
- *p++ = 'x';
- for(i=0; i < n; i++ )
- sprintf( p+2*i, "%02X", fpr[i] );
- p -= 2;
- return p;
-}
-
-static int
-expand_id(const char *id,STRLIST *into,unsigned int flags)
-{
- struct groupitem *groups;
- int count=0;
-
- for(groups=opt.grouplist;groups;groups=groups->next)
- {
- /* need strcasecmp() here, as this should be localized */
- if(strcasecmp(groups->name,id)==0)
- {
- STRLIST each,sl;
-
- /* this maintains the current utf8-ness */
- for(each=groups->values;each;each=each->next)
- {
- sl=add_to_strlist(into,each->d);
- sl->flags=flags;
- count++;
- }
-
- break;
- }
- }
-
- return count;
-}
-
-/* For simplicity, and to avoid potential loops, we only expand once -
- you can't make an alias that points to an alias. */
-static STRLIST
-expand_group(STRLIST input)
-{
- STRLIST sl,output=NULL,rover;
-
- for(rover=input;rover;rover=rover->next)
- if(expand_id(rover->d,&output,rover->flags)==0)
- {
- /* Didn't find any groups, so use the existing string */
- sl=add_to_strlist(&output,rover->d);
- sl->flags=rover->flags;
- }
-
- return output;
-}
-
-int
-build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use )
-{
- PK_LIST pk_list = NULL;
- PKT_public_key *pk=NULL;
- int rc=0;
- int any_recipients=0;
- STRLIST rov,remusr;
- char *def_rec = NULL;
-
- if(opt.grouplist)
- remusr=expand_group(rcpts);
- else
- remusr=rcpts;
-
- /* check whether there are any recipients in the list and build the
- * list of the encrypt-to ones (we always trust them) */
- for( rov = remusr; rov; rov = rov->next ) {
- if( !(rov->flags & 1) )
- {
- any_recipients = 1;
-
- if((rov->flags&2) && (PGP2 || PGP6 || PGP7 || PGP8))
- {
- log_info(_("you may not use %s while in %s mode\n"),
- "--hidden-recipient",
- compliance_option_string());
-
- compliance_failure();
- }
- }
- else if( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) {
- pk = xcalloc (1, sizeof *pk );
- pk->req_usage = use;
- /* We can encrypt-to a disabled key */
- if( (rc = get_pubkey_byname( pk, rov->d, NULL, NULL, 1 )) ) {
- free_public_key( pk ); pk = NULL;
- log_error(_("%s: skipped: %s\n"), rov->d, gpg_strerror (rc) );
- write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
- rov->d, strlen (rov->d), -1);
- goto fail;
- }
- else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use )) ) {
- /* Skip the actual key if the key is already present
- * in the list */
- if (key_present_in_pk_list(pk_list, pk) == 0) {
- free_public_key(pk); pk = NULL;
- log_info(_("%s: skipped: public key already present\n"),
- rov->d);
- }
- else {
- PK_LIST r;
- r = xmalloc ( sizeof *r );
- r->pk = pk; pk = NULL;
- r->next = pk_list;
- r->flags = (rov->flags&2)?1:0;
- pk_list = r;
-
- if(r->flags&1 && (PGP2 || PGP6 || PGP7 || PGP8))
- {
- log_info(_("you may not use %s while in %s mode\n"),
- "--hidden-encrypt-to",
- compliance_option_string());
-
- compliance_failure();
- }
- }
- }
- else {
- free_public_key( pk ); pk = NULL;
- log_error(_("%s: skipped: %s\n"), rov->d, gpg_strerror (rc) );
- write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
- rov->d, strlen (rov->d), -1);
- goto fail;
- }
- }
- }
-
- if( !any_recipients && !opt.batch ) { /* ask */
- int have_def_rec;
- char *answer=NULL;
- STRLIST backlog=NULL;
-
- def_rec = default_recipient();
- have_def_rec = !!def_rec;
- if( !have_def_rec )
- tty_printf(_(
- "You did not specify a user ID. (you may use \"-r\")\n"));
- for(;;) {
- rc = 0;
- xfree (answer);
- if( have_def_rec ) {
- answer = def_rec;
- def_rec = NULL;
- }
- else if (backlog) {
- answer = strlist_pop (&backlog);
- }
- else {
- answer = cpr_get_utf8("pklist.user_id.enter",
- _("\nEnter the user ID. End with an empty line: "));
- trim_spaces(answer);
- cpr_kill_prompt();
- }
- if( !answer || !*answer ) {
- xfree (answer);
- break;
- }
- if(expand_id(answer,&backlog,0))
- continue;
- if( pk )
- free_public_key( pk );
- pk = xcalloc (1, sizeof *pk );
- pk->req_usage = use;
- rc = get_pubkey_byname( pk, answer, NULL, NULL, 0 );
- if( rc )
- tty_printf(_("No such user ID.\n"));
- else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use)) ) {
- if( have_def_rec ) {
- if (key_present_in_pk_list(pk_list, pk) == 0) {
- free_public_key(pk); pk = NULL;
- log_info(_("skipped: public key "
- "already set as default recipient\n") );
- }
- else {
- PK_LIST r = xmalloc ( sizeof *r );
- r->pk = pk; pk = NULL;
- r->next = pk_list;
- r->flags = 0; /* no throwing default ids */
- pk_list = r;
- }
- any_recipients = 1;
- continue;
- }
- else {
- int trustlevel;
-
- trustlevel = get_validity (pk, pk->user_id);
- if( (trustlevel & TRUST_FLAG_DISABLED) ) {
- tty_printf(_("Public key is disabled.\n") );
- }
- else if( do_we_trust_pre( pk, trustlevel ) ) {
- /* Skip the actual key if the key is already present
- * in the list */
- if (key_present_in_pk_list(pk_list, pk) == 0) {
- free_public_key(pk); pk = NULL;
- log_info(_("skipped: public key already set\n") );
- }
- else {
- PK_LIST r;
- u32 keyid[2];
-
- keyid_from_pk( pk, keyid);
- tty_printf("Added %4u%c/%08lX %s \"",
- nbits_from_pk( pk ),
- pubkey_letter( pk->pubkey_algo ),
- (ulong)keyid[1],
- datestr_from_pk( pk ) );
- if(pk->user_id)
- tty_print_utf8_string(pk->user_id->name,
- pk->user_id->len);
- else
- {
- size_t n;
- char *p = get_user_id( keyid, &n );
- tty_print_utf8_string( p, n );
- xfree (p);
- }
- tty_printf("\"\n");
-
- r = xmalloc ( sizeof *r );
- r->pk = pk; pk = NULL;
- r->next = pk_list;
- r->flags = 0; /* no throwing interactive ids */
- pk_list = r;
- }
- any_recipients = 1;
- continue;
- }
- }
- }
- xfree (def_rec); def_rec = NULL;
- have_def_rec = 0;
- }
- if( pk ) {
- free_public_key( pk );
- pk = NULL;
- }
- }
- else if( !any_recipients && (def_rec = default_recipient()) ) {
- pk = xcalloc (1, sizeof *pk );
- pk->req_usage = use;
- /* The default recipient may be disabled */
- rc = get_pubkey_byname( pk, def_rec, NULL, NULL, 1 );
- if( rc )
- log_error(_("unknown default recipient `%s'\n"), def_rec );
- else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use)) ) {
- /* Mark any_recipients here since the default recipient
- would have been used if it wasn't already there. It
- doesn't really matter if we got this key from the default
- recipient or an encrypt-to. */
- any_recipients = 1;
- if (key_present_in_pk_list(pk_list, pk) == 0)
- log_info(_("skipped: public key already set as default recipient\n"));
- else {
- PK_LIST r = xmalloc ( sizeof *r );
- r->pk = pk; pk = NULL;
- r->next = pk_list;
- r->flags = 0; /* no throwing default ids */
- pk_list = r;
- }
- }
- if( pk ) {
- free_public_key( pk );
- pk = NULL;
- }
- xfree (def_rec); def_rec = NULL;
- }
- else {
- any_recipients = 0;
- for(; remusr; remusr = remusr->next ) {
- if( (remusr->flags & 1) )
- continue; /* encrypt-to keys are already handled */
-
- pk = xcalloc (1, sizeof *pk );
- pk->req_usage = use;
- if( (rc = get_pubkey_byname( pk, remusr->d, NULL, NULL, 0 )) ) {
- free_public_key( pk ); pk = NULL;
- log_error(_("%s: skipped: %s\n"), remusr->d, gpg_strerror (rc) );
- write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
- remusr->d, strlen (remusr->d),
- -1);
- goto fail;
- }
- else if( !(rc=openpgp_pk_test_algo (pk->pubkey_algo, use )) ) {
- int trustlevel;
-
- trustlevel = get_validity (pk, pk->user_id);
- if( (trustlevel & TRUST_FLAG_DISABLED) ) {
- free_public_key(pk); pk = NULL;
- log_info(_("%s: skipped: public key is disabled\n"),
- remusr->d);
- write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
- remusr->d,
- strlen (remusr->d),
- -1);
- rc = gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
- goto fail;
- }
- else if( do_we_trust_pre( pk, trustlevel ) ) {
- /* note: do_we_trust may have changed the trustlevel */
-
- /* We have at least one valid recipient. It doesn't matters
- * if this recipient is already present. */
- any_recipients = 1;
-
- /* Skip the actual key if the key is already present
- * in the list */
- if (key_present_in_pk_list(pk_list, pk) == 0) {
- free_public_key(pk); pk = NULL;
- log_info(_("%s: skipped: public key already present\n"),
- remusr->d);
- }
- else {
- PK_LIST r;
- r = xmalloc ( sizeof *r );
- r->pk = pk; pk = NULL;
- r->next = pk_list;
- r->flags = (remusr->flags&2)?1:0;
- pk_list = r;
- }
- }
- else { /* we don't trust this pk */
- free_public_key( pk ); pk = NULL;
- write_status_text_and_buffer (STATUS_INV_RECP, "10 ",
- remusr->d,
- strlen (remusr->d),
- -1);
- rc = gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
- goto fail;
- }
- }
- else {
- free_public_key( pk ); pk = NULL;
- write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
- remusr->d,
- strlen (remusr->d),
- -1);
- log_error(_("%s: skipped: %s\n"), remusr->d, gpg_strerror (rc) );
- goto fail;
- }
- }
- }
-
- if( !rc && !any_recipients ) {
- log_error(_("no valid addressees\n"));
- write_status_text (STATUS_NO_RECP, "0");
- rc = GPG_ERR_NO_USER_ID;
- }
-
- fail:
-
- if( rc )
- release_pk_list( pk_list );
- else
- *ret_pk_list = pk_list;
- if(opt.grouplist)
- free_strlist(remusr);
- return rc;
-}
-
-
-/* In pgp6 mode, disallow all ciphers except IDEA (1), 3DES (2), and
- CAST5 (3), all hashes except MD5 (1), SHA1 (2), and RIPEMD160 (3),
- and all compressions except none (0) and ZIP (1). pgp7 and pgp8
- mode expands the cipher list to include AES128 (7), AES192 (8),
- AES256 (9), and TWOFISH (10). pgp8 adds the SHA-256 hash (8). For
- a true PGP key all of this is unneeded as they are the only items
- present in the preferences subpacket, but checking here covers the
- weird case of encrypting to a key that had preferences from a
- different implementation which was then used with PGP. I am not
- completely comfortable with this as the right thing to do, as it
- slightly alters the list of what the user is supposedly requesting.
- It is not against the RFC however, as the preference chosen will
- never be one that the user didn't specify somewhere ("The
- implementation may use any mechanism to pick an algorithm in the
- intersection"), and PGP has no mechanism to fix such a broken
- preference list, so I'm including it. -dms */
-
-int
-algo_available( preftype_t preftype, int algo, void *hint )
-{
- if( preftype == PREFTYPE_SYM )
- {
- if(PGP6 && (algo != CIPHER_ALGO_IDEA
- && algo != CIPHER_ALGO_3DES
- && algo != CIPHER_ALGO_CAST5))
- return 0;
-
- if((PGP7 || PGP8) && (algo != CIPHER_ALGO_IDEA
- && algo != CIPHER_ALGO_3DES
- && algo != CIPHER_ALGO_CAST5
- && algo != CIPHER_ALGO_AES
- && algo != CIPHER_ALGO_AES192
- && algo != CIPHER_ALGO_AES256
- && algo != CIPHER_ALGO_TWOFISH))
- return 0;
-
- return algo && !gcry_cipher_test_algo (algo);
- }
- else if( preftype == PREFTYPE_HASH )
- {
- if(hint && ((*(int *)hint) != gcry_md_get_algo_dlen (algo)))
- return 0;
-
- if((PGP6 || PGP7) && (algo != DIGEST_ALGO_MD5
- && algo != DIGEST_ALGO_SHA1
- && algo != DIGEST_ALGO_RMD160))
- return 0;
-
-
- if(PGP8 && (algo != DIGEST_ALGO_MD5
- && algo != DIGEST_ALGO_SHA1
- && algo != DIGEST_ALGO_RMD160
- && algo != DIGEST_ALGO_SHA256))
- return 0;
-
- return algo && !gcry_md_test_algo( algo );
- }
- else if( preftype == PREFTYPE_ZIP )
- {
- if((PGP6 || PGP7 || PGP8) && (algo != COMPRESS_ALGO_NONE
- && algo != COMPRESS_ALGO_ZIP))
- return 0;
-
- return !check_compress_algo( algo );
- }
- else
- return 0;
-}
-
-
-
-/****************
- * Return -1 if we could not find an algorithm.
- */
-int
-select_algo_from_prefs(PK_LIST pk_list, int preftype, int request, void *hint)
-{
- PK_LIST pkr;
- u32 bits[8];
- const prefitem_t *prefs;
- int i, j;
- int compr_hack=0;
- int any;
-
- if( !pk_list )
- return -1;
-
- memset( bits, ~0, 8 * sizeof *bits );
- for( pkr = pk_list; pkr; pkr = pkr->next ) {
- u32 mask[8];
-
- memset( mask, 0, 8 * sizeof *mask );
- if( preftype == PREFTYPE_SYM ) {
- if( PGP2 &&
- pkr->pk->version < 4 &&
- pkr->pk->selfsigversion < 4 )
- mask[0] |= (1<<1); /* IDEA is implicitly there for v3 keys
- with v3 selfsigs (rfc2440:12.1) if
- --pgp2 mode is on. This doesn't
- mean it's actually available, of
- course. */
- else
- mask[0] |= (1<<2); /* 3DES is implicitly there for everyone else */
- }
- else if( preftype == PREFTYPE_HASH ) {
- /* While I am including this code for completeness, note
- that currently --pgp2 mode locks the hash at MD5, so this
- function will never even be called. Even if the hash
- wasn't locked at MD5, we don't support sign+encrypt in
- --pgp2 mode, and that's the only time PREFTYPE_HASH is
- used anyway. -dms */
- if( PGP2 &&
- pkr->pk->version < 4 &&
- pkr->pk->selfsigversion < 4 )
- mask[0] |= (1<<1); /* MD5 is there for v3 keys with v3
- selfsigs when --pgp2 is on. */
- else
- mask[0] |= (1<<2); /* SHA1 is there for everyone else */
- }
- else if( preftype == PREFTYPE_ZIP )
- mask[0] |= (1<<0); /* Uncompressed is implicit */
-
- if (pkr->pk->user_id) /* selected by user ID */
- prefs = pkr->pk->user_id->prefs;
- else
- prefs = pkr->pk->prefs;
-
- any = 0;
- if( prefs ) {
- for (i=0; prefs[i].type; i++ ) {
- if( prefs[i].type == preftype ) {
- mask[prefs[i].value/32] |= 1 << (prefs[i].value%32);
- any = 1;
- }
- }
- }
-
- if( (!prefs || !any) && preftype == PREFTYPE_ZIP ) {
- mask[0] |= 3; /* asume no_compression and old pgp */
- compr_hack = 1;
- }
-
-#if 0
- log_debug("pref mask=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
- (ulong)mask[7], (ulong)mask[6], (ulong)mask[5], (ulong)mask[4],
- (ulong)mask[3], (ulong)mask[2], (ulong)mask[1], (ulong)mask[0]);
-#endif
- for(i=0; i < 8; i++ )
- bits[i] &= mask[i];
-#if 0
- log_debug("pref bits=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
- (ulong)bits[7], (ulong)bits[6], (ulong)bits[5], (ulong)bits[4],
- (ulong)bits[3], (ulong)bits[2], (ulong)bits[1], (ulong)bits[0]);
-#endif
- }
- /* usable algorithms are now in bits
- * We now use the last key from pk_list to select
- * the algorithm we want to use. there are no
- * preferences for the last key, we select the one
- * corresponding to first set bit.
- */
- i = -1;
- any = 0;
-
- /* Can we use the requested algorithm? */
- if(request>-1 && (bits[request/32] & (1<<(request%32))) &&
- algo_available(preftype,request,hint))
- return request;
-
- /* If we have personal prefs set, use them instead of the last key */
- if(preftype==PREFTYPE_SYM && opt.personal_cipher_prefs)
- prefs=opt.personal_cipher_prefs;
- else if(preftype==PREFTYPE_HASH && opt.personal_digest_prefs)
- prefs=opt.personal_digest_prefs;
- else if(preftype==PREFTYPE_ZIP && opt.personal_compress_prefs)
- prefs=opt.personal_compress_prefs;
-
- if( prefs ) {
- for(j=0; prefs[j].type; j++ ) {
- if( prefs[j].type == preftype ) {
- if( (bits[prefs[j].value/32] & (1<<(prefs[j].value%32))) ) {
- if( algo_available( preftype, prefs[j].value, hint ) ) {
- any = 1;
- i = prefs[j].value;
- break;
- }
- }
- }
- }
- }
- if( !prefs || !any ) {
- for(j=0; j < 256; j++ )
- if( (bits[j/32] & (1<<(j%32))) ) {
- if( algo_available( preftype, j, hint ) ) {
- i = j;
- break;
- }
- }
- }
-
-#if 0
- log_debug("prefs of type %d: selected %d\n", preftype, i );
-#endif
- if( compr_hack && !i ) {
- /* selected no compression, but we should check whether
- * algorithm 1 is also available (the ordering is not relevant
- * in this case). */
- if( bits[0] & (1<<1) )
- i = 1; /* yep; we can use compression algo 1 */
- }
-
- /* "If you are building an authentication system, the recipient
- may specify a preferred signing algorithm. However, the signer
- would be foolish to use a weak algorithm simply because the
- recipient requests it." RFC2440:13. If we settle on MD5, and
- SHA1 is also available, use SHA1 instead. Of course, if the
- user intentionally chose MD5 (by putting it in their personal
- prefs), then we should do what they say. */
-
- if(preftype==PREFTYPE_HASH &&
- i==DIGEST_ALGO_MD5 && (bits[0] & (1<<DIGEST_ALGO_SHA1)))
- {
- i=DIGEST_ALGO_SHA1;
-
- if(opt.personal_digest_prefs)
- for(j=0; prefs[j].type; j++ )
- if(opt.personal_digest_prefs[j].type==PREFTYPE_HASH &&
- opt.personal_digest_prefs[j].value==DIGEST_ALGO_MD5)
- {
- i=DIGEST_ALGO_MD5;
- break;
- }
- }
-
- return i;
-}
-
-/*
- * Select the MDC flag from the pk_list. We can only use MDC if all recipients
- * support this feature
- */
-int
-select_mdc_from_pklist (PK_LIST pk_list)
-{
- PK_LIST pkr;
-
- if( !pk_list )
- return 0;
-
- for (pkr = pk_list; pkr; pkr = pkr->next) {
- int mdc;
-
- if (pkr->pk->user_id) /* selected by user ID */
- mdc = pkr->pk->user_id->mdc_feature;
- else
- mdc = pkr->pk->mdc_feature;
- if (!mdc)
- return 0; /* at least one recipient does not support it */
- }
- return 1; /* can be used */
-}
diff --git a/g10/pkglue.c b/g10/pkglue.c
deleted file mode 100644
index f062d8366..000000000
--- a/g10/pkglue.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/* pkglue.c - public key operations glue code
- * Copyright (C) 2000, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "pkglue.h"
-
-
-static gcry_mpi_t
-mpi_from_sexp (gcry_sexp_t sexp, const char * item)
-{
- gcry_sexp_t list;
- gcry_mpi_t data;
-
- list = gcry_sexp_find_token (sexp, item, 0);
- assert (list);
- data = gcry_sexp_nth_mpi (list, 1, 0);
- assert (data);
- gcry_sexp_release (list);
- return data;
-}
-
-
-/****************
- * Emulate our old PK interface here - sometime in the future we might
- * change the internal design to directly fit to libgcrypt.
- */
-int
-pk_sign (int algo, gcry_mpi_t * data, gcry_mpi_t hash, gcry_mpi_t * skey)
-{
- gcry_sexp_t s_sig, s_hash, s_skey;
- int rc;
-
- /* make a sexp from skey */
- if (algo == GCRY_PK_DSA)
- {
- rc = gcry_sexp_build (&s_skey, NULL,
- "(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)
- {
- rc = gcry_sexp_build (&s_skey, NULL,
- "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
- skey[0], skey[1], skey[2], skey[3], skey[4],
- skey[5]);
- }
- else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
- {
- rc = gcry_sexp_build (&s_skey, NULL,
- "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
- skey[0], skey[1], skey[2], skey[3]);
- }
- else
- return GPG_ERR_PUBKEY_ALGO;
-
- if (rc)
- BUG ();
-
- /* put hash into a S-Exp s_hash */
- if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
- BUG ();
-
- rc = gcry_pk_sign (&s_sig, s_hash, s_skey);
- gcry_sexp_release (s_hash);
- gcry_sexp_release (s_skey);
-
- if (rc)
- ;
- else if (algo == GCRY_PK_RSA)
- data[0] = mpi_from_sexp (s_sig, "s");
- else
- {
- data[0] = mpi_from_sexp (s_sig, "r");
- data[1] = mpi_from_sexp (s_sig, "s");
- }
-
- gcry_sexp_release (s_sig);
- return rc;
-}
-
-/****************
- * Emulate our old PK interface here - sometime in the future we might
- * change the internal design to directly fit to libgcrypt.
- */
-int
-pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey)
-{
- gcry_sexp_t s_sig, s_hash, s_pkey;
- int rc;
-
- /* make a sexp from pkey */
- if (algo == GCRY_PK_DSA)
- {
- rc = gcry_sexp_build (&s_pkey, NULL,
- "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
- pkey[0], pkey[1], pkey[2], pkey[3]);
- }
- else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
- {
- rc = gcry_sexp_build (&s_pkey, NULL,
- "(public-key(elg(p%m)(g%m)(y%m)))",
- pkey[0], pkey[1], pkey[2]);
- }
- else if (algo == GCRY_PK_RSA)
- {
- rc = gcry_sexp_build (&s_pkey, NULL,
- "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]);
- }
- else
- return GPG_ERR_PUBKEY_ALGO;
-
- if (rc)
- BUG ();
-
- /* put hash into a S-Exp s_hash */
- if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
- BUG ();
-
- /* put data into a S-Exp s_sig */
- if (algo == GCRY_PK_DSA)
- {
- if (!data[0] || !data[1])
- rc = gpg_error (GPG_ERR_BAD_MPI);
- else
- rc = gcry_sexp_build (&s_sig, NULL,
- "(sig-val(dsa(r%m)(s%m)))", data[0], data[1]);
- }
- else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
- {
- if (!data[0] || !data[1])
- rc = gpg_error (GPG_ERR_BAD_MPI);
- else
- rc = gcry_sexp_build (&s_sig, NULL,
- "(sig-val(elg(r%m)(s%m)))", data[0], data[1]);
- }
- else if (algo == GCRY_PK_RSA)
- {
- if (!data[0])
- rc = gpg_error (GPG_ERR_BAD_MPI);
- else
- rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%m)))", data[0]);
- }
- else
- BUG ();
-
- if (rc)
- BUG ();
-
-
- rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
- gcry_sexp_release (s_sig);
- gcry_sexp_release (s_hash);
- gcry_sexp_release (s_pkey);
- return rc;
-}
-
-
-
-
-/****************
- * Emulate our old PK interface here - sometime in the future we might
- * change the internal design to directly fit to libgcrypt.
- */
-int
-pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, gcry_mpi_t * pkey)
-{
- gcry_sexp_t s_ciph, s_data, s_pkey;
- int rc;
-
- /* make a sexp from pkey */
- if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
- {
- rc = gcry_sexp_build (&s_pkey, NULL,
- "(public-key(elg(p%m)(g%m)(y%m)))",
- pkey[0], pkey[1], pkey[2]);
- }
- else if (algo == GCRY_PK_RSA)
- {
- rc = gcry_sexp_build (&s_pkey, NULL,
- "(public-key(rsa(n%m)(e%m)))",
- pkey[0], pkey[1]);
- }
- else
- return GPG_ERR_PUBKEY_ALGO;
-
- if (rc)
- BUG ();
-
- /* put the data into a simple list */
- if (gcry_sexp_build (&s_data, NULL, "%m", data))
- BUG ();
-
- /* pass it to libgcrypt */
- rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
- gcry_sexp_release (s_data);
- gcry_sexp_release (s_pkey);
-
- if (rc)
- ;
- 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)
- resarr[1] = mpi_from_sexp (s_ciph, "b");
- }
-
- gcry_sexp_release (s_ciph);
- return rc;
-}
-
-
-
-/****************
- * Emulate our old PK interface here - sometime in the future we might
- * change the internal design to directly fit to libgcrypt.
- */
-int
-pk_decrypt (int algo, gcry_mpi_t * result, gcry_mpi_t * data,
- gcry_mpi_t * skey)
-{
- gcry_sexp_t s_skey, s_data, s_plain;
- int rc;
-
- *result = NULL;
- /* make a sexp from skey */
- if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
- {
- rc = gcry_sexp_build (&s_skey, NULL,
- "(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)
- {
- rc = gcry_sexp_build (&s_skey, NULL,
- "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
- skey[0], skey[1], skey[2], skey[3], skey[4],
- skey[5]);
- }
- else
- return GPG_ERR_PUBKEY_ALGO;
-
- if (rc)
- BUG ();
-
- /* put data into a S-Exp s_data */
- if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
- {
- if (!data[0] || !data[1])
- rc = gpg_error (GPG_ERR_BAD_MPI);
- else
- rc = gcry_sexp_build (&s_data, NULL,
- "(enc-val(elg(a%m)(b%m)))", data[0], data[1]);
- }
- else if (algo == GCRY_PK_RSA)
- {
- if (!data[0])
- rc = gpg_error (GPG_ERR_BAD_MPI);
- else
- rc = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", data[0]);
- }
- else
- BUG ();
-
- if (rc)
- BUG ();
-
- rc = gcry_pk_decrypt (&s_plain, s_data, s_skey);
- gcry_sexp_release (s_skey);
- gcry_sexp_release (s_data);
- if (rc)
- return rc;
-
- *result = gcry_sexp_nth_mpi (s_plain, 0, 0);
- gcry_sexp_release (s_plain);
- if (!*result)
- return -1; /* oops */
-
- return 0;
-}
-
-
-/* Check whether SKEY is a suitable secret key. */
-int
-pk_check_secret_key (int algo, gcry_mpi_t *skey)
-{
- gcry_sexp_t s_skey;
- int rc;
-
- if (algo == GCRY_PK_DSA)
- {
- rc = gcry_sexp_build (&s_skey, NULL,
- "(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_ELG || algo == GCRY_PK_ELG_E)
- {
- rc = gcry_sexp_build (&s_skey, NULL,
- "(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)
- {
- rc = gcry_sexp_build (&s_skey, NULL,
- "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
- skey[0], skey[1], skey[2], skey[3], skey[4],
- skey[5]);
- }
- else
- return GPG_ERR_PUBKEY_ALGO;
-
- if (!rc)
- {
- rc = gcry_pk_testkey (s_skey);
- gcry_sexp_release (s_skey);
- }
- return rc;
-}
diff --git a/g10/pkglue.h b/g10/pkglue.h
deleted file mode 100644
index 43b82785b..000000000
--- a/g10/pkglue.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* pkglue.h - public key operations definitions
- * Copyright (C) 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef GNUPG_G10_PKGLUE_H
-#define GNUPG_G10_PKGLUE_H
-
-int pk_sign (int algo, gcry_mpi_t *data, gcry_mpi_t hash,
- gcry_mpi_t *skey);
-int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data,
- gcry_mpi_t *pkey);
-int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
- gcry_mpi_t *pkey);
-int pk_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
- gcry_mpi_t *skey);
-int pk_check_secret_key (int algo, gcry_mpi_t *skey);
-
-
-#endif /*GNUPG_G10_PKGLUE_H*/
diff --git a/g10/plaintext.c b/g10/plaintext.c
deleted file mode 100644
index d84a523fe..000000000
--- a/g10/plaintext.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/* plaintext.c - process plaintext packets
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#ifdef HAVE_DOSISH_SYSTEM
-#include <fcntl.h> /* for setmode() */
-#endif
-
-#include "gpg.h"
-#include "util.h"
-#include "memory.h"
-#include "options.h"
-#include "packet.h"
-#include "ttyio.h"
-#include "filter.h"
-#include "main.h"
-#include "status.h"
-#include "i18n.h"
-
-
-
-/****************
- * Handle a plaintext packet. If MFX is not NULL, update the MDs
- * Note: we should use the filter stuff here, but we have to add some
- * easy mimic to set a read limit, so we calculate only the
- * bytes from the plaintext.
- */
-int
-handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
- int nooutput, int clearsig, int *create_failed )
-{
- char *fname = NULL;
- FILE *fp = NULL;
- int rc = 0;
- int c;
- int convert = pt->mode == 't';
-#ifdef __riscos__
- int filetype = 0xfff;
-#endif
- int dummy_create_failed;
-
- if (!create_failed)
- create_failed = &dummy_create_failed;
- *create_failed = 0;
-
- /* create the filename as C string */
- if( nooutput )
- ;
- else if( opt.outfile ) {
- fname = xmalloc ( strlen( opt.outfile ) + 1);
- strcpy(fname, opt.outfile );
- }
- else if( pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8 ) ) {
- log_info(_("data not saved; use option \"--output\" to save it\n"));
- nooutput = 1;
- }
- else if( !opt.use_embedded_filename ) {
- fname = make_outfile_name( iobuf_get_real_fname(pt->buf) );
- if( !fname )
- fname = ask_outfile_name( pt->name, pt->namelen );
- if( !fname ) {
- *create_failed = 1;
- rc = GPG_ERR_GENERAL;
- goto leave;
- }
- }
- else {
- fname = make_printable_string( pt->name, pt->namelen, 0 );
- }
-
- if( nooutput )
- ;
- else if( !*fname || (*fname=='-' && !fname[1])) {
- /* no filename or "-" given; write to stdout */
- fp = stdout;
-#ifdef HAVE_DOSISH_SYSTEM
- setmode ( fileno(fp) , O_BINARY );
-#endif
- }
- else {
- while( !overwrite_filep (fname) ) {
- char *tmp = ask_outfile_name (NULL, 0);
- if ( !tmp || !*tmp ) {
- xfree (tmp);
- *create_failed = 1;
- rc = GPG_ERR_GENERAL;
- goto leave;
- }
- xfree (fname);
- fname = tmp;
- }
- }
-
-#ifndef __riscos__
- if( fp || nooutput )
- ;
- else if( !(fp = fopen(fname,"wb")) ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("error creating `%s': %s\n"), fname, strerror(errno) );
- *create_failed = 1;
- goto leave;
- }
-#else /* __riscos__ */
- /* Convert all '.' in fname to '/' -- we don't create directories! */
- for( c=0; fname[c]; ++c )
- if( fname[c] == '.' )
- fname[c] = '/';
-
- if( fp || nooutput )
- ;
- else {
- fp = fopen(fname,"wb");
- if( !fp ) {
- rc == gpg_error_from_errno (errno);
- log_error(_("error creating `%s': %s\n"), fname, strerror(errno) );
- *create_failed = 1;
- if (errno == 106)
- log_info("Do output file and input file have the same name?\n");
- goto leave;
- }
-
- /* If there's a ,xxx extension in the embedded filename,
- use that, else check whether the user input (in fname)
- has a ,xxx appended, then use that in preference */
- if( (c = riscos_get_filetype_from_string( pt->name,
- pt->namelen )) != -1 )
- filetype = c;
- if( (c = riscos_get_filetype_from_string( fname,
- strlen(fname) )) != -1 )
- filetype = c;
- riscos_set_filetype_by_number(fname, filetype);
- }
-#endif /* __riscos__ */
-
- if( !pt->is_partial ) {
- /* we have an actual length (which might be zero). */
- assert( !clearsig );
- if( convert ) { /* text mode */
- for( ; pt->len; pt->len-- ) {
- if( (c = iobuf_get(pt->buf)) == -1 ) {
- rc = gpg_error_from_errno (errno);
- log_error("Problem reading source (%u bytes remaining)\n",
- (unsigned)pt->len);
- goto leave;
- }
- if( mfx->md )
- gcry_md_putc (mfx->md, c );
-#ifndef HAVE_DOSISH_SYSTEM
- if( c == '\r' ) /* convert to native line ending */
- continue; /* fixme: this hack might be too simple */
-#endif
- if( fp ) {
- if( putc( c, fp ) == EOF ) {
- rc = gpg_error_from_errno (errno);
- log_error("Error writing to `%s': %s\n",
- fname, strerror(errno) );
- goto leave;
- }
- }
- }
- }
- else { /* binary mode */
- byte *buffer = xmalloc ( 32768 );
- while( pt->len ) {
- int len = pt->len > 32768 ? 32768 : pt->len;
- len = iobuf_read( pt->buf, buffer, len );
- if( len == -1 ) {
- rc = gpg_error_from_errno (errno);
- log_error("Problem reading source (%u bytes remaining)\n",
- (unsigned)pt->len);
- xfree ( buffer );
- goto leave;
- }
- if( mfx->md )
- gcry_md_write( mfx->md, buffer, len );
- if( fp ) {
- if( fwrite( buffer, 1, len, fp ) != len ) {
- rc = gpg_error_from_errno (errno);
- log_error("Error writing to `%s': %s\n",
- fname, strerror(errno) );
- xfree ( buffer );
- goto leave;
- }
- }
- pt->len -= len;
- }
- xfree ( buffer );
- }
- }
- else if( !clearsig ) {
- if( convert ) { /* text mode */
- while( (c = iobuf_get(pt->buf)) != -1 ) {
- if( mfx->md )
- gcry_md_putc (mfx->md, c );
-#ifndef HAVE_DOSISH_SYSTEM
- if( convert && c == '\r' )
- continue; /* fixme: this hack might be too simple */
-#endif
- if( fp ) {
- if( putc( c, fp ) == EOF ) {
- rc = gpg_error_from_errno (errno);
- log_error("Error writing to `%s': %s\n",
- fname, strerror(errno) );
- goto leave;
- }
- }
- }
- }
- else { /* binary mode */
- byte *buffer = xmalloc ( 32768 );
- int eof;
- for( eof=0; !eof; ) {
- /* Why do we check for len < 32768:
- * If we won't, we would practically read 2 EOFs but
- * the first one has already popped the block_filter
- * off and therefore we don't catch the boundary.
- * So, always assume EOF if iobuf_read returns less bytes
- * then requested */
- int len = iobuf_read( pt->buf, buffer, 32768 );
- if( len == -1 )
- break;
- if( len < 32768 )
- eof = 1;
- if( mfx->md )
- gcry_md_write( mfx->md, buffer, len );
- if( fp ) {
- if( fwrite( buffer, 1, len, fp ) != len ) {
- rc = gpg_error_from_errno (errno);
- log_error("Error writing to `%s': %s\n",
- fname, strerror(errno) );
- xfree ( buffer );
- goto leave;
- }
- }
- }
- xfree ( buffer );
- }
- pt->buf = NULL;
- }
- else { /* clear text signature - don't hash the last cr,lf */
- int state = 0;
-
- while( (c = iobuf_get(pt->buf)) != -1 ) {
- if( fp ) {
- if( putc( c, fp ) == EOF ) {
- rc = gpg_error_from_errno (errno);
- log_error("Error writing to `%s': %s\n",
- fname, strerror(errno) );
- goto leave;
- }
- }
- if( !mfx->md )
- continue;
- if( state == 2 ) {
- gcry_md_putc (mfx->md, '\r' );
- gcry_md_putc (mfx->md, '\n' );
- state = 0;
- }
- if( !state ) {
- if( c == '\r' )
- state = 1;
- else if( c == '\n' )
- state = 2;
- else
- gcry_md_putc (mfx->md, c );
- }
- else if( state == 1 ) {
- if( c == '\n' )
- state = 2;
- else {
- gcry_md_putc (mfx->md, '\r' );
- if( c == '\r' )
- state = 1;
- else {
- state = 0;
- gcry_md_putc (mfx->md, c );
- }
- }
- }
- }
- pt->buf = NULL;
- }
-
- if( fp && fp != stdout && fclose(fp) ) {
- rc = gpg_error_from_errno (errno);
- log_error("Error closing `%s': %s\n", fname, strerror(errno) );
- fp = NULL;
- goto leave;
- }
- fp = NULL;
-
- leave:
- if( fp && fp != stdout )
- fclose(fp);
- xfree (fname);
- return rc;
-}
-
-static void
-do_hash( MD_HANDLE md, MD_HANDLE md2, iobuf_t fp, int textmode )
-{
- text_filter_context_t tfx;
- int c;
-
- if( textmode ) {
- memset( &tfx, 0, sizeof tfx);
- iobuf_push_filter( fp, text_filter, &tfx );
- }
- if( md2 ) { /* work around a strange behaviour in pgp2 */
- /* It seems that at least PGP5 converts a single CR to a CR,LF too */
- int lc = -1;
- while( (c = iobuf_get(fp)) != -1 ) {
- if( c == '\n' && lc == '\r' )
- gcry_md_putc (md2, c);
- else if( c == '\n' ) {
- gcry_md_putc (md2, '\r');
- gcry_md_putc (md2, c);
- }
- else if( c != '\n' && lc == '\r' ) {
- gcry_md_putc (md2, '\n');
- gcry_md_putc (md2, c);
- }
- else
- gcry_md_putc (md2, c);
-
- if( md )
- gcry_md_putc (md, c );
- lc = c;
- }
- }
- else {
- while( (c = iobuf_get(fp)) != -1 ) {
- if( md )
- gcry_md_putc (md, c );
- }
- }
-}
-
-
-/****************
- * Ask for the detached datafile and calculate the digest from it.
- * INFILE is the name of the input file.
- */
-int
-ask_for_detached_datafile( MD_HANDLE md, MD_HANDLE md2,
- const char *inname, int textmode )
-{
- progress_filter_context_t pfx;
- char *answer = NULL;
- iobuf_t fp;
- int rc = 0;
-
- fp = open_sigfile( inname, &pfx ); /* open default file */
-
- if( !fp && !opt.batch ) {
- int any=0;
- tty_printf(_("Detached signature.\n"));
- do {
- xfree (answer);
- answer = cpr_get("detached_signature.filename",
- _("Please enter name of data file: "));
- cpr_kill_prompt();
- if( any && !*answer ) {
- rc = GPG_ERR_GENERAL;
- goto leave;
- }
- fp = iobuf_open(answer);
- if( !fp && errno == ENOENT ) {
- tty_printf("No such file, try again or hit enter to quit.\n");
- any++;
- }
- else if( !fp ) {
- rc = gpg_error_from_errno (errno);
- log_error("can't open `%s': %s\n", answer, strerror(errno) );
- goto leave;
- }
- } while( !fp );
- }
-
- if( !fp ) {
- if( opt.verbose )
- log_info(_("reading stdin ...\n"));
- fp = iobuf_open( NULL );
- assert(fp);
- }
- do_hash( md, md2, fp, textmode );
- iobuf_close(fp);
-
- leave:
- xfree (answer);
- return rc;
-}
-
-
-
-/****************
- * Hash the given files and append the hash to hash context md.
- * If FILES is NULL, hash stdin.
- */
-int
-hash_datafiles( MD_HANDLE md, MD_HANDLE md2, STRLIST files,
- const char *sigfilename, int textmode )
-{
- progress_filter_context_t pfx;
- iobuf_t fp;
- STRLIST sl;
-
- if( !files ) {
- /* check whether we can open the signed material */
- fp = open_sigfile( sigfilename, &pfx );
- if( fp ) {
- do_hash( md, md2, fp, textmode );
- iobuf_close(fp);
- return 0;
- }
- log_error (_("no signed data\n"));
- return GPG_ERR_NO_DATA;
- }
-
-
- for (sl=files; sl; sl = sl->next ) {
- fp = iobuf_open( sl->d );
- if( !fp ) {
- int tmperr = gpg_error_from_errno (errno);
- log_error(_("can't open signed data `%s'\n"),
- print_fname_stdin(sl->d));
- return tmperr;
- }
- handle_progress (&pfx, fp, sl->d);
- do_hash( md, md2, fp, textmode );
- iobuf_close(fp);
- }
-
- return 0;
-}
diff --git a/g10/progress.c b/g10/progress.c
deleted file mode 100644
index 9d9805065..000000000
--- a/g10/progress.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/* progress.c
- * Copyright (C) 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-
-#include "gpg.h"
-#include "iobuf.h"
-#include "filter.h"
-#include "status.h"
-#include "util.h"
-#include "options.h"
-
-/****************
- * The filter is used to report progress to the user.
- */
-int
-progress_filter (void *opaque, int control,
- iobuf_t a, byte *buf, size_t *ret_len)
-{
- int rc = 0;
- progress_filter_context_t *pfx = opaque;
-
- if (control == IOBUFCTRL_INIT)
- {
- char buffer[50];
-
- pfx->last = 0;
- pfx->offset = 0;
- pfx->last_time = make_timestamp ();
-
- sprintf (buffer, "%.20s ? %lu %lu",
- pfx->what? pfx->what : "?",
- pfx->offset,
- pfx->total);
- write_status_text (STATUS_PROGRESS, buffer);
- }
- else if (control == IOBUFCTRL_UNDERFLOW)
- {
- u32 timestamp = make_timestamp ();
- int len = iobuf_read (a, buf, *ret_len);
-
- if (len >= 0)
- {
- pfx->offset += len;
- *ret_len = len;
- }
- else
- {
- *ret_len = 0;
- rc = -1;
- }
- if ((len == -1 && pfx->offset != pfx->last)
- || timestamp - pfx->last_time > 0)
- {
- char buffer[50];
-
- sprintf (buffer, "%.20s ? %lu %lu",
- pfx->what? pfx->what : "?",
- pfx->offset,
- pfx->total);
- write_status_text (STATUS_PROGRESS, buffer);
-
- pfx->last = pfx->offset;
- pfx->last_time = timestamp;
- }
- }
- else if (control == IOBUFCTRL_FREE)
- {
- /* Note, that we must always dealloc resources of a filter
- within the filter handler and not anywhere else. (We set it
- to NULL and check all uses just in case.) */
- xfree (pfx->what);
- pfx->what = NULL;
- }
- else if (control == IOBUFCTRL_DESC)
- *(char**)buf = "progress_filter";
- return rc;
-}
-
-void
-handle_progress (progress_filter_context_t *pfx, iobuf_t inp, const char *name)
-{
- off_t filesize = 0;
-
- if (!opt.enable_progress_filter)
- return;
-
- if (!is_status_enabled ())
- return;
-
- if (name && *name && !(*name == '-' && !name[1]))
- filesize = iobuf_get_filelength (inp);
- else if (opt.set_filesize)
- filesize = opt.set_filesize;
-
- /* register the progress filter */
- pfx->what = xstrdup (name ? name : "stdin");
- pfx->total = filesize;
- iobuf_push_filter (inp, progress_filter, pfx);
-}
diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
deleted file mode 100644
index 4b45b9f5c..000000000
--- a/g10/pubkey-enc.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/* pubkey-enc.c - public key encoded packet handling
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "memory.h"
-#include "packet.h"
-#include "mpi.h"
-#include "keydb.h"
-#include "trustdb.h"
-#include "cipher.h"
-#include "status.h"
-#include "options.h"
-#include "main.h"
-#include "i18n.h"
-#include "pkglue.h"
-#include "call-agent.h"
-
-static int get_it( PKT_pubkey_enc *k,
- DEK *dek, PKT_secret_key *sk, u32 *keyid );
-
-
-/* check that the given algo is mentioned in one of the valid user IDs */
-static int
-is_algo_in_prefs ( KBNODE keyblock, preftype_t type, int algo )
-{
- KBNODE k;
-
- for (k=keyblock; k; k=k->next) {
- if (k->pkt->pkttype == PKT_USER_ID) {
- PKT_user_id *uid = k->pkt->pkt.user_id;
- prefitem_t *prefs = uid->prefs;
-
- if (uid->created && prefs &&
- !uid->is_revoked && !uid->is_expired ) {
- for (; prefs->type; prefs++ )
- if (prefs->type == type && prefs->value == algo)
- return 1;
- }
- }
- }
- return 0;
-}
-
-
-/****************
- * Get the session key from a pubkey enc packet and return
- * it in DEK, which should have been allocated in secure memory.
- */
-int
-get_session_key( PKT_pubkey_enc *k, DEK *dek )
-{
- PKT_secret_key *sk = NULL;
- int rc;
-
- rc = openpgp_pk_test_algo (k->pubkey_algo, PUBKEY_USAGE_ENC);
- if( rc )
- goto leave;
-
- if( (k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets ) {
- sk = xcalloc (1, sizeof *sk );
- sk->pubkey_algo = k->pubkey_algo; /* we want a pubkey with this algo*/
- if( !(rc = get_seckey( sk, k->keyid )) )
- rc = get_it( k, dek, sk, k->keyid );
- }
- else { /* anonymous receiver: Try all available secret keys */
- void *enum_context = NULL;
- u32 keyid[2];
- char *p;
-
- for(;;) {
- if( sk )
- free_secret_key( sk );
- sk = xcalloc (1, sizeof *sk );
- rc=enum_secret_keys( &enum_context, sk, 1, 0);
- if( rc ) {
- rc = GPG_ERR_NO_SECKEY;
- break;
- }
- if( sk->pubkey_algo != k->pubkey_algo )
- continue;
- keyid_from_sk( sk, keyid );
- log_info(_("anonymous recipient; trying secret key %08lX ...\n"),
- (ulong)keyid[1] );
-
- if(!opt.try_all_secrets && !is_status_enabled())
- {
- p=get_last_passphrase();
- set_next_passphrase(p);
- xfree (p);
- }
-
- rc = check_secret_key( sk, opt.try_all_secrets?1:-1 ); /* ask
- only
- once */
- if( !rc )
- rc = get_it( k, dek, sk, keyid );
- if( !rc ) {
- log_info(_("okay, we are the anonymous recipient.\n") );
- break;
- }
- }
- enum_secret_keys( &enum_context, NULL, 0, 0 ); /* free context */
- }
-
- leave:
- if( sk )
- free_secret_key( sk );
- return rc;
-}
-
-
-static int
-get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid )
-{
- int rc;
- gcry_mpi_t plain_dek = NULL;
- byte *frame = NULL;
- unsigned n, nframe;
- u16 csum, csum2;
- int card = 0;
-
- if (sk->is_protected && sk->protect.s2k.mode == 1002)
- { /* FIXME: Note that we do only support RSA for now. */
- char *rbuf;
- size_t rbuflen;
- char *snbuf;
- unsigned char *indata = NULL;
- unsigned int indatalen;
-
- snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk);
-
- if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &indata, &indatalen,
- enc->data[0]))
- BUG();
-
- rc = agent_scd_pkdecrypt (snbuf, indata, indatalen, &rbuf, &rbuflen);
- xfree (snbuf);
- xfree (indata);
- if (rc)
- goto leave;
-
- frame = rbuf;
- nframe = rbuflen;
- card = 1;
- }
- else
- {
- rc = pk_decrypt (sk->pubkey_algo, &plain_dek, enc->data, sk->skey);
- if( rc )
- goto leave;
- if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, plain_dek))
- BUG();
- gcry_mpi_release (plain_dek); plain_dek = NULL;
- }
-
-
- /* Now get the DEK (data encryption key) from the frame
- *
- * Old versions encode the DEK in in this format (msb is left):
- *
- * 0 1 DEK(16 bytes) CSUM(2 bytes) 0 RND(n bytes) 2
- *
- * Later versions encode the DEK like this:
- *
- * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes)
- *
- * (mpi_get_buffer already removed the leading zero).
- *
- * RND are non-zero randow bytes.
- * A is the cipher algorithm
- * DEK is the encryption key (session key) with length k
- * CSUM
- */
- if( DBG_CIPHER )
- log_printhex ("DEK frame:", frame, nframe );
- n=0;
- if (!card)
- {
- if( n + 7 > nframe )
- { rc = GPG_ERR_WRONG_SECKEY; goto leave; }
- if( frame[n] == 1 && frame[nframe-1] == 2 ) {
- log_info(_("old encoding of the DEK is not supported\n"));
- rc = GPG_ERR_CIPHER_ALGO;
- goto leave;
- }
- if( frame[n] != 2 ) /* somethink is wrong */
- { rc = GPG_ERR_WRONG_SECKEY; goto leave; }
- for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */
- ;
- n++; /* and the zero byte */
- }
-
- if( n + 4 > nframe )
- { rc = GPG_ERR_WRONG_SECKEY; goto leave; }
- dek->keylen = nframe - (n+1) - 2;
- dek->algo = frame[n++];
- if( dek->algo == CIPHER_ALGO_IDEA )
- write_status(STATUS_RSA_OR_IDEA);
- rc = openpgp_cipher_test_algo (dek->algo);
- if( rc ) {
- if( !opt.quiet && gpg_err_code (rc) == GPG_ERR_CIPHER_ALGO ) {
- log_info(_("cipher algorithm %d%s is unknown or disabled\n"),
- dek->algo, dek->algo == CIPHER_ALGO_IDEA? " (IDEA)":"");
- if(dek->algo==CIPHER_ALGO_IDEA)
- idea_cipher_warn(0);
- }
- dek->algo = 0;
- goto leave;
- }
- if( dek->keylen != gcry_cipher_get_algo_keylen (dek->algo) ) {
- rc = GPG_ERR_WRONG_SECKEY;
- goto leave;
- }
-
- /* copy the key to DEK and compare the checksum */
- csum = frame[nframe-2] << 8;
- csum |= frame[nframe-1];
- memcpy( dek->key, frame+n, dek->keylen );
- for( csum2=0, n=0; n < dek->keylen; n++ )
- csum2 += dek->key[n];
- if( csum != csum2 ) {
- rc = GPG_ERR_WRONG_SECKEY;
- goto leave;
- }
- if( DBG_CIPHER )
- log_printhex ("DEK is:", dek->key, dek->keylen );
- /* check that the algo is in the preferences and whether it has expired */
- {
- PKT_public_key *pk = NULL;
- KBNODE pkb = get_pubkeyblock (keyid);
-
- if( !pkb ) {
- rc = -1;
- log_error("oops: public key not found for preference check\n");
- }
- else if( pkb->pkt->pkt.public_key->selfsigversion > 3
- && dek->algo != CIPHER_ALGO_3DES
- && !is_algo_in_prefs( pkb, PREFTYPE_SYM, dek->algo ) ) {
- /* Don't print a note while we are not on verbose mode,
- * the cipher is blowfish and the preferences have twofish
- * listed */
- if( opt.verbose || dek->algo != CIPHER_ALGO_BLOWFISH
- || !is_algo_in_prefs( pkb, PREFTYPE_SYM, CIPHER_ALGO_TWOFISH))
- log_info(_(
- "NOTE: cipher algorithm %d not found in preferences\n"),
- dek->algo );
- }
-
- if (!rc) {
- KBNODE k;
-
- for (k=pkb; k; k = k->next) {
- if (k->pkt->pkttype == PKT_PUBLIC_KEY
- || k->pkt->pkttype == PKT_PUBLIC_SUBKEY){
- u32 aki[2];
- keyid_from_pk(k->pkt->pkt.public_key, aki);
-
- if (aki[0]==keyid[0] && aki[1]==keyid[1]) {
- pk = k->pkt->pkt.public_key;
- break;
- }
- }
- }
- if (!pk)
- BUG ();
- if ( pk->expiredate && pk->expiredate <= make_timestamp() ) {
- log_info(_("NOTE: secret key %08lX expired at %s\n"),
- (ulong)keyid[1], asctimestamp( pk->expiredate) );
- }
- }
-
- if ( pk && pk->is_revoked ) {
- log_info( _("NOTE: key has been revoked") );
- putc( '\n', log_get_stream() );
- show_revocation_reason( pk, 1 );
- }
-
- release_kbnode (pkb);
- rc = 0;
- }
-
-
- leave:
- gcry_mpi_release (plain_dek);
- xfree (frame);
- return rc;
-}
-
-
-/****************
- * Get the session key from the given string.
- * String is supposed to be formatted as this:
- * <algo-id>:<even-number-of-hex-digits>
- */
-int
-get_override_session_key( DEK *dek, const char *string )
-{
- const char *s;
- int i;
-
- if ( !string )
- return GPG_ERR_BAD_KEY;
- dek->algo = atoi(string);
- if ( dek->algo < 1 )
- return GPG_ERR_BAD_KEY;
- if ( !(s = strchr ( string, ':' )) )
- return GPG_ERR_BAD_KEY;
- s++;
- for(i=0; i < DIM(dek->key) && *s; i++, s +=2 ) {
- int c = hextobyte ( s );
- if (c == -1)
- return GPG_ERR_BAD_KEY;
- dek->key[i] = c;
- }
- if ( *s )
- return GPG_ERR_BAD_KEY;
- dek->keylen = i;
- return 0;
-}
-
diff --git a/g10/pubring.asc b/g10/pubring.asc
deleted file mode 100644
index 09b099bfe..000000000
--- a/g10/pubring.asc
+++ /dev/null
@@ -1,458 +0,0 @@
------BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.0.0e (GNU/Linux)
-Comment: For info see http://www.gnupg.org
-
-mQGiBDVBlNMRBADeX96LvyNiop30YPeeCBJZzeqQuQ3yQ+SK3AHoXLQ1qsGHrdoi
-HfHbVV2GfulRq+H/z97vUtA3APE2NZ7HuvBJzhXZCOE93wT59OZV8Pp5ir6TAEYm
-dvPCgvjYmwQvKgvaF0hG4eyvQst7SaevFUGV+jEz5DQhniy+/a2/W7nC/QCg/2SE
-nBeZNJnZauf9cXQ34GnXV68D/1BspMcbrpY/YFXsdLUSbroG0EXGma4jY9UlcRV8
-8cIftxl2jh04l91bvzzCFgSGvFdxVbHWnIgbQ+PQ1cme7SsS3ZFFI3B3zykXGOi8
-shhOT/Gip1Tk4O6MwTyOWdTdnEGSjk+qoVwEMxhY/ZZDd3bbUkymrPK5jtfumreB
-JjqwA/wL5fOdCzLWBev4/Xks2YENg0HVwN3a3iypNNGZOYCWTZKnFX5yel/mqiT0
-uEn1CJ5w29GKxRax/Ua9kr7ftMhpQ8lZdyy4Z/Br0NiU9fgvmWF/2WvOMx+hHf/k
-LRUYewxzOSLfapiM1SOQs/L+29tnu4wfAsezSuFfKjKVZHlx4rQnQnJpYW4gV2Fy
-bmVyIChob21lKSA8d2FybmVyQGxvdGhhci5jb20+iF0EExECAB0FAjZYxf4FCQPf
-GysDCwQDBRUDAgYBAxYCAQIXgAAKCRCQOaC/0TnMTJJUAKC0jAhA3fXI2UCbfZ6J
-Ti3CL0bcMQCgpA7pEUYM7edUlxqFJfWYtBblS5u5Ag0ENUGU1BAIAPZCV7cIfwgX
-cqK61qlC8wXo+VMROU+28W65Szgg2gGnVqMU6Y9AVfPQB8bLQ6mUrfdMZIZJ+AyD
-vWXpF9Sh01D49Vlf3HZSTz09jdvOmeFXklnN/biudE/F/Ha8g8VHMGHOfMlm/xX5
-u/2RXscBqtNbno2gpXI61Brwv0YAWCvl9Ij9WE5J280gtJ3kkQc2azNsOA1FHQ98
-iLMcfFstjvbzySPAQ/ClWxiNjrtVjLhdONM0/XwXV0OjHRhs3jMhLLUq/zzhsSlA
-GBGNfISnCnLWhsQDGcgHKXrKlQzZlp+r0ApQmwJG0wg9ZqRdQZ+cfL2JSyIZJrqr
-ol7DVekyCzsAAgIH/AlcnP6QSKd67ad/1lQpzMEBNyIX0X7//lns6XAGl/+U5Iqx
-i+8sd+oJikFlgVH+n0JD6vq4dO8XCBzUgIi3xV2cuJqj16zVp7JdMXKqIxkDu5Q/
-By3/IL7WWkc06FxyDraigP1Hu3W78l0lySK8yEW+fVlkyzK6irkJ7EFWkSDaZqT2
-IrPd94hoGFEyQOIgkYdy2DHoK00nUd9FzIbhrrz2ZDJIfCMVp2go4oCu6Zk0LxJX
-qTFU7K3SxVNN5jWsOCsPzWLyhKNrgnv8WzVaPKgqgMNdmdykAvC0iSTNat51p8Ad
-4mGtY1nW0aOAiufjBTMUtILfHKsknItj/P2D4seITAQYEQIADAUCNljGDQUJA98b
-OQAKCRCQOaC/0TnMTHKtAJsHojLJup9Niwsutt68U02uyl13BwCgpovl3ebeH41a
-k2Kp37si/9RsdICZAaIENt243BEEAOCNfiVnzetemJ2DpFA51QnnGUihYs0beBQ2
-ptJP47uLlxsZbix2Gg3wDCP7HNgcEWlXc29vrd2oiA9nanKLcJzLYVL0lBBbPVX4
-8PGvRFKvJVHI17LWqpq3aOF8kOSf/4QyRIafWdGzxvAFycAiq2Bs1/B7BeUqmhWO
-3FXs6VNLAKDqqMUc7apbVRFSV6/kbQ8PLTYw0QP/dRwVX9NtBEogFNoSU4jw1sRg
-+nqGQplE9OXESMQO3fiszBkCWghsKk+/O+HcFrIiSAxRPR3y8nXCsaLQEf4WfrD7
-nKFeGWDIqPvi3KJOzuaqZP3DMf4LdfltmM/zHifZo4aBkkIQd6703vBFAYA0lONH
-+W5qyx0ZnYr7XunDqkMD/2JC3cogap2H6IzaHl9oQegGKGwrCErBuJxCeL9i7h/+
-5Wg8ou6TE8kAGf1oMeeWwrWOBxub4xsUqfYk+mKM//O2OkCMfVFQgQQtjy5CtFQx
-X5AErQ4Ukoy8XmNGOAi9ipWpL0450XwNvusaeff4D1ztJbCb+LMkqI9gYEQWSwxF
-tCNKLiBNaWNoYWVsIEFzaGxleSA8amFzaGxleUBhY20ub3JnPohVBBMRAgAVBQI3
-RcCEAwsKAwMVAwIDFgIBAheAAAoJEAcDKpaJBMjiiuQAni3iUNjDvqvOQOlIgz1d
-5ibjHrA8AKDWPy7kZN+W3Leptp3FYTIMTbDpU7kBDQQ23bjuEAQAl1Txo5tRemsP
-8mNmoBlGQx/4EmN61ga/V8iBS7u7MvzI1zktNuHaK7rJItE4ilyGeivXitZ74eGV
-7P2/rbNhWnOo1fMlvLvl8mDNmLD2nJovu4LVFXGhoYdGb75d2YbCCBN5Q/BSYh+l
-b2wd6VewnqMy6A9iGULaAWz10G2IOYMAAwYD/iooRihzfIC6rw6K2kASGRiy/dts
-3w0L9Iu5DsxLFH2tHUpv8fPVDuvGkRfwPuKaTHAvq90/I46/3BBTOOneMaW1+RAL
-hM5f4ytsYNlDDerhRiuGyEjoGtXVjXye/3SwIxISrg0EO7UHNtr4rObQEfF69RcT
-gjzKdO2n2WlP+7/qiEwEGBECAAwFAjdVLZwFCQHwga4ACgkQBwMqlokEyOIEvwCe
-IHFkUaLTPmaZhAOs3yfwDtAC33gAn3f2BoDALaHL1uqu/unWQA1JZRTYmQGiBDfj
-Y5kRBADMfdIcB6LbzfMZAe9+3GMqLgx5fUEhX9GVZIxb3w+ZBGbJGrERMtEigd+S
-Y2xR9TWyhd/eVh80qcgGzA9Fyb6IOdVwN6HxtYdIz4CZP6ZmtSM8jecfbbKsf/Ol
-BJQ6RZlAWNjE6F2r1D/gHpw1ZEl+lSlW3ObCEkeXBC/er/fIowCgwia77SmSgm3b
-GgHEqfFQ8MID6lsD/0h45kDwi3K8WhI6lnZP0zpnNfA6753QaA9NqB8MY36YCVtx
-OhBm7GUCgKyfh9zrTpZWwcBcAQyyB8Ld3K7cWi0uLy+gO2169cRApR0S1l6BlkbO
-9wlv1zoRR1VT2gQCMGw6mjyne99v4Hst7UXV/nXvOsdrxdS5tTkAEL7Alzz0BACc
-imFIsBD1CKqqN0fTdZooVrBZzpn6ZjTgzX1hKr61fuFyPgMkhzutN2jXy8tweCZw
-FmN5XZ9cu7mxAdN9Xmwk7Kl0EGChwZdm7Sx9UTvu9kJnGOQvqtOkWB86Ts+r4fVb
-w65BqcrZZzuMQrUqliM/YVUGazN/w2uyApNPByJUzbQ4TWljaGFlbCBSb3RoIChV
-c2VkIGZvciBrZXkgc2lnbmF0dXJlcykgPG1yb3RoQGdudXBnLm9yZz6IVQQTEQIA
-FQUCN+NjmQMLCgMDFQMCAxYCAQIXgAAKCRDKFfq6GxOtQUZWAJ40vGK1b1f2KN7u
-BHOHLDAHvnuPLwCfXHyq3wGapWGDw6txlP9LMec1jf2JAJQDBRA342hqcwhlf6d9
-2r0BAenKA/d9luNiVpPciTyfM9W4GybmWSlLt0qxrY34WSNL5IOG6P2H335skdAC
-xSUlwBSkD2IzoaQ0LAyGw0jsk8yWhfQqgjWxjZ0zcmKHZJZsMLwtvA4FeOSQuscf
-kYsbA3vZWotYO1o9jyfAZTj0MeALzGEmxBeGUNiKUEnbBU0Lg+c8iEYEEBECAAYF
-AjfjadIACgkQAJxC28xc8YI7iQCfboS4b2tqYvml31ouMT6XPHhTsYMAnRGQId+W
-7mOHlWHvrddjwu8JHms6mQGiBDbYl60RBACxaonXMHpbmyzoQyxn7wYXGpEJZnKc
-IWRc/sE++XSebUZMJOk09qkKhtg1TQ8D0Siv1/EjuqjoKP2f9+EOIW55+55vQsti
-XwevF6pJBFYGGRluQPoFbUilDzCDmismFv0xwIEoOLftxvyvlmmw4Upx3/8TY83f
-dQGzxSDvNbPEtwCguK4ARxZub/SQgLMy6S9/7itEfHcD/RXRVGmz3dDxXtgdAqwV
-mY7RI+FOPQdn+DiFaaTjmqgP+NR6w5v72+jE5cdn/OnYmXQcERXc/4nZgWHdKmso
-eLvLs0hpk9zFhgHkSufCWlo0ZYemaWRYrRI5mukGFIMbPdPEaySNQEqC78Rgj2wm
-FJ2ttbAQlSRi332xTwFbzY4XA/9RppZOE9hGCh+2P4FgtHMgf7L8JUJVgR9tIKUv
-GXjDkSWEqIMeyKeXFoPk5QdxNVM5sRYf6gmV6U3zHUOfEzlOf5GUJyPkmwl9RADE
-6uyk4ySlW2d6+glsM0/Fd9Pyyzb0v6xfAPDFyTYU1X6vUDp0FyzPUijhbrdj4Fwm
-fAVf3LQeTWljaGFlbCBSb3RoIDxtcm90aEBnbnVwZy5vcmc+iFsEExECABsFAjfi
-yIQFCQlnNJ8DCwoDAxUDAgMWAgECF4AACgkQAJxC28xc8YKnHACeMFOdlg4xjXgE
-FzyA7MQFxyXmyuoAnRCcbQ4bvEm/fxaaBFRnJgavm25LiQCVAwUQN+NpSnMIZX+n
-fdq9AQF72gP7ByZG6W8yTz+1nv+CMvGIGLa4otN812X5lXvvIpH7bNgoWWD70xvH
-5GP/Q5e3yUh4aGGN59uOVVQ5uoa3VFYl1ufWt2LvxaSW2q7f0FcvEref/5biu3gx
-2O296DWENYPP3xZtaD+htaDP4h18RFBIvbZz9Ryp9C8myGEPQGcOxw+IRgQQEQIA
-BgUCN+NqjQAKCRDKFfq6GxOtQfhaAJ9bMyNoYhAf3jkeMy1cnXoyr9ZbwQCfeWjK
-xnAa+++nbYVEnuPP2gUdume0Hk1pY2hhZWwgUm90aCA8bXJvdGhAbmVzc2llLmRl
-PohbBBMRAgAbBQI34siUBQkJZzSfAwsKAwMVAwIDFgIBAheAAAoJEACcQtvMXPGC
-iF4AniaC76L0oLBvc0jA40NCXMDz4PX2AJ9RGPnHKf0XmaRXcTOlR8MiH1CeoLkB
-zQQ22JgDEAcAqtpFls8cnLDIh1r6gSRf8sYiv5qd+a8CDd/LWHveWeGCeuBiVbwv
-SG0q9ci13ZRIEtHXi0BVWLBpz/YqQCHJX4Vk2iV6yY7rCo0rFOEzyco+Glssjg1G
-/ZCuVkGo4rpLKqOn6oXq92ojwBNjdYeBOOoZ78jp65gJ3OC0ckYanrRUe3J9bc0W
-lAA+to/Dus91Ivkggu/iH5DEPrf/PQY14t7jxCcxBJCa8XaC04LrXVphPuuRziVe
-gINTU02fdyrZlAyWf+0KZq5rMza1N+NwSxjkxBOzM+lbhA5PSekqHp8AAwUG/12f
-DRpOtZ/GrKoUgkML8urMjxKFD4Hh6l1Wb5NCEe4tIm38yI+C/AwMCY5cDlf03YOZ
-0ThTVjpvQfYT8EJuPbZ+2dGYEroY3OBLetcg6DDh4saKsVU2XSLHyCh2xPzOiusB
-xNPrmvqd63S7JnRSSsEfgwYpKpA/GNMSJyyFpT4vtvK3jOON0v7uobYOBTLRuwj3
-OJMJfyQDa6WyiTJxUvsuQL0MK5cZG7oLUWTK9ZrFPuqzLeZAcpIgJ/QMJ/PnrRnZ
-gUnXEbsnCVZ33NVBtiK/ktS2RTQKcvCNPtnimRqsiEwEGBECAAwFAjbYmAMFCQlm
-AYAACgkQAJxC28xc8YJTTACgmUYdFZGR8pk9NbB4lpnKnum15WUAoIgDLWQA+qb1
-EPtpywwRBvqGOVUPmQGiBDgf7uARBADdNye00iQMSe4RULS0hDKVGNl1CFGzeol+
-AoNkW9bqXD3f9KNrWD11r9tef6C4OMN2fILO7cpD+YZwuHjXv6xSDAoZ31bmsxQn
-N51YhwFhZRh8K/XheaULO9gedCZaXndQ8dvXGC/doKKOo/CNGK8gct+cPPr0N6cu
-FztlgRpbqwCgm8u3ylalEvlWhXOjVYoTnEs04aMEAJVK0ZcYjHUdXWXi+TaDZCJq
-ktk/r2E4M4/EsBTIkuAuy6RvPediVShRQ/CZl0MCQHM17ywdC+PXgOmQLeGbR8m8
-flK9HROJQebHB23/MK2knm/yKgqSJbtoDv23QRfZjNd1aox50uFLvv36CDMhAMQ4
-ENHrBzuj5bMZo8nMELVaBACPlGKAcAO2FP6DpmcJIXDnO+oVHvs4QMzADn+/aBQp
-H3UQASAbu7aH/84SLBUH0h1Z9QNkKLuMtpC0rVHqRsw4d4FmOxoxvOF8hQnICiQr
-2XRMDKZwR/+gH9Vh2XFRi4j/xHH2h787C6bKoOPd6UPJM1HdxNPQlG89fb4hgv/e
-WbQ+TmlpYmUgWXV0YWthIChHTlUvTGludXggb24gU3VwZXJIIFByb2plY3QpIDxn
-bmlpYmVAY2hyb290Lm9yZz6IWwQTEQIAGwUCOB/u4AUJA8JnAAMLCgMDFQMCAxYC
-AQIXgAAKCRDj8lhUEo8OeTsQAJ96XKYFFJuwup2Mce9mDk6EOnEEdACdFp6gwm6x
-T6Hm1FD53oKNgrnafhqIRgQQEQIABgUCOB/w/QAKCRC+6Lh52/bl/+myAJ0UubvN
-9ydWvrdgkKbfokKJTrOC0wCgooxVzceD44Oo/C1kaHjXv5yFQeKIRgQQEQIABgUC
-OClPHgAKCRBd4kmWWwNYol/nAJ0YXC3/sGqBaddoLqoLpo1kapcthACglrEi6n5z
-6OcQO+II4Fe6wFOisYu5AQ0EOB/u8RAEALec6/ux2Py+0Wv/w5J/VmDzUNDOHQJM
-kxTEQbp+vZ80Quf8FoMy8i9PciekoDl+oB8/zQDs92SgqGVD0+y8K9UPIEvmifjr
-oPn+EsIrXf8M7dGGotCtwaiEwDxwmetlQMYLd84XqLj0LgGzdT3/7dMurhUiGZH7
-dpWMfUZAVNjHAAMFA/9iLg3F0Bqi1dVDeCMqOVCOcWKhulFG80il3TwS9Q7SpvJX
-/4yZyoEdyJ/VYm4PakvDUyiy4MuhsvGSwCEyXD4IskEkmlf97jDoBiiktexkjlKI
-vmp7P0XNQMURXFLqDilI9YY2jVAu4XNw+G0G1ImGgzbadbraUl1J1uJtvg+NOYhM
-BBgRAgAMBQI4H+7xBQkDwmcAAAoJEOPyWFQSjw55J58An1UbKjszsK+9Awtz3a+5
-gNiuzdo5AKCE5Pv3w56DMeZLH8GyZkVqo1QsrZkBogQ3KcaNEQQAsRxnSrRpASl8
-e0lOtR3C7I1MoCuivlawh48JzC9WXgA/Pgn+VOLiDDob/zjQoNbBEoG+BHrwq+AC
-CVBQFAiMMNur8u7qY+R4eLWD/KDKaNcydchdKehw0eiy7d9mv0hTHSmkUIgIpy4k
-d+XvsbozP40+/G+yNjGEHvJf3tsO8ocAoP4wWPnUPNwWkuKn41tR3cb2m+ZlA/0Q
-lIn4E3Na3o0AhhuLC3YrJ4X4rHJmUJg+i2mS3lJCM3HPJRCdz/eIlU4WiaBpNPve
-PMEeg5KSluqdYOsCvBa6XsAGm8gxQ2Wzf6ZqsXdBxztjwXqcLeuBKFfuDUlwloYI
-Rie+naIgPasYwu3ABG4peRJmc8aRXJCg39rE8MK4BAP+Pt+NqJQw9S9ykLDDIXDD
-ucH7YOBxfvUo18lPr+iNuPcbXh3fQQoibk4qK0w699YLGD25KizP+FTiCrD2fy9i
-knUplevJkGDTdeDLrAPYVYTM2hryLPcisSP55Yf0GW6SnkFbE5LKYHo5YQF+9rvp
-yUCR4xXm6CXo9m9FKBuuk5i0Hk5pa2xhcyBIZXJuYWV1cyA8bmhAZGYubHRoLnNl
-PohbBBMRAgAbBQI3KcaNBQklmAYAAwsKAwMVAwIDFgIBAheAAAoJEHUPZJXInZM+
-i40AoIykcWzV7PpBoEG4MbTXTNpKBeTIAJ9tJcXW7S/ox+iJGOrBXgSlB7bXnIhG
-BBARAgAGBQI3NDnLAAoJEF3iSZZbA1iipZEAoKm4vkXn0/4KC0aZp5o2U5zyErZe
-AKDF3mdMyHEumx4xSWJyX4TvDZ+3ybkCDQQ3Kc4MEAgAsgkRCXJQLlHgk4Fu1Jk+
-UKEDdMZYufSOGR0D57WxbRtArPqDMox1NqFHGi8Sg88TtDwH6/BnGkYCOuBQidaE
-BPQtl7jeU6fQhXL4kRY3KB50/ChzzUB/G+LsT8COCUIsNDiBQxwEiLTEOMFAqbRA
-ugQhZnUKrf0auZKnB53RPhAuIdGozC+k9+vJl0l76e+JcVr8AL6wWBQO00UbKgp+
-MKiWjFDSYIFtMNrXO9rfHW1n3jW79bvAVyFl9rwEbL0gbSWmaZKXIWI7D11J8aYF
-3ppDk5UsCc0Cs70okV9d58s0PjnTqwAcVxZcyoO81qJVOPesRVJ4jURdGeSBTqNM
-rwADBwgArjJRLMSTveaC2tELGSr7qBioUJ9FbFk0A5D8vH3Xcr34E/m0sgNGJSD3
-qWQNXN0OpH7hKdeiwEPLE8gR/Tnxwgb+r3S0dBViktQPMajdW5S/dJfusTdqBzo2
-LgdZ24lVl1O0ZKci+6SVWt5SBxbAYYtgSEjiGhbWUDdQoC52yNGUQvG9wL5OD1BK
-y94wzKQZi9WV/NdNfJPMjZv+tx3pezfGYTPDnUpP1CoLXY/gre+APwr9yHAg46Hz
-F+DQT+KAWQDTxahEUk9OE86nR3gO0zNN2KzGKb297ikcLWYusW9QQ46X3uIBTYmK
-PZP9l/bR7322tj88GPaKPesZE8rR2ohMBBgRAgAMBQI3Kc4MBQklmAYAAAoJEHUP
-ZJXInZM+GUwAn2qcZ8hOcrD1Bw7zZofZ+xm8wDL/AJ9DJQbxAae5kKnBDG1O28B4
-J0wF45kBogQ14HkWEQQA1qRbEQxVQzxv1QAvAgFoW3nT+BbWAs5fenhmvkWIMunk
-xhB8cIeYaImzmdDK0YioSgQ03ER5O4x5AcVKXiUJKUWqIermAqSCk6W0z8iWD0Vu
-boP8JrAJ6hd5WCWPpzb41OJumi5Xy3RzWdYWq2IOXOVZM2Wt1gnXA7p2PxS+ZqMA
-oKLnKFiDGdQPqKH5zwG488A95X9lA/4mkc0LBxfBIipWEE3HzgkcmNRb0zdxzUGY
-TGrHIYK3i7TZrfq09+jTA1dMbs2tX/nbUdd1oMaKefCqBw3hD50E685bla17TPFh
-NXhBRCCGhH8IGGAg0o6P3B0+QQHJsp7eof/VKgIFN6NeXga+621vkal5eU6jHQ44
-sHHkkkk0fQQAu8a0B2kf4VFHIE4kDraDPgIkhWV2r7efsLJj671NOKBHOMzWB+PK
-0eh0b6Tc34n44lyH6Cmc2F9xUzk7POa/uEi8aPB1z2/NdYeFg6nKTrkN4nYnQtYr
-GG4oPgeX0+DoNHmlRJto+pYMU8PwJA9fCT1K+szRr5p072LImZ7lsk20LlBldGVy
-IEdlcndpbnNraSAoRWxHL0RTQSkgPHBldGVyQGdlcndpbnNraS5kZT6IVwQTEQIA
-FwUCNmGXiwMLBAMFFQMCBgEDFgIBAheAAAoJEJg0ZdshQ5Qir60An1Zl/jBAU7Cx
-XINEaZupk1TmkdiDAKCFGR9orHjfKgw+xEA+idd/Ls0lDohGBBARAgAGBQI3pyH0
-AAoJEF3iSZZbA1iiXRAAnRCydbPV/ipvi0NfEzV9+RC8lBxNAJ9jQwXwCKt0HVc8
-/Y3OVY/WI1LnTbkCDQQ14Hp8EAgAoz58r9ogDLeyaL8NoMXoMhJ0ogHqC0jzt6xa
-zw/h6t0AJE1He5tMF1yVkenXo+sah2oTjrm38fRVXODbACvmn1oP+WLcK7/bG82V
-Ol4Zv0Iu+8X1KzXz2JGae+h0ogNcwyW7CXfPSEVhrCBTY7i7mdnAoyGFoW0yFSvt
-8YcRXdN7GU16tdATfruMV276MuStGwNIWYYfjFtqwFBdaVOpwMfJs2golT7PLEIj
-O2l1u1ZtAI6WvuEzQH4ftzzihmHQXMf4YsvtL5g/8TSJfmfUEFbbKFbU5bIbHzG4
-yj/O8uEBBj7u01oGpu/5UVFTgslvTIEAWx54sfT/oA06PvhsDwADBQf/VWZUn/wC
-/gktKZfh6Aq7RRI2K5bJEXhXE5p0rPWLMQy+v4DPGcuDF3nLg1IZT5mbLUGEh+7n
-zEgUsmLGPqBz54DgjhBxO1DfAfV3HVnYYpL7DO1u4ceCUh2O9PwLnp1+4W2XmND5
-nFrQ6gGChCgwb79/PxQdLEgj9dlf+vrv5SfajmTydiFCZ0+0GZRFDytdIda08TWv
-DabV/41F3T0TSbCMGPWr/TgrfQ6yeyOUpO9lmVbS0u9gKWGAedVOofMYi7Lqp+Pt
-zNQTwd9PKCP/HSjUxmm4xX3yVZuUxUV97ckucB8TOlr9deNnq32jnMuP9DeWpBz4
-05uwoBLYvOGNAYhGBBgRAgAGBQI14Hp8AAoJEJg0ZdshQ5QitJcAn0sn+TIAlbNC
-3YS5YxlYbExg6UnxAJwM+TJoHjFG8+rZ0nW7/vVq6+hHl5kBogQ3zBNgEQQA7vY0
-FBndb1BOSmisOzqCtcqwzP7iMKF+hwEKDqRKrO/oZ7zqMXigROEDb+ar95oSh2EX
-7tETk2b8ga9LA0UxT8nZ8e4eCOOchNggLyX4ZpsyrVTMGwahnjf8KsepIaKqfEnQ
-lzE4KsnLsuC+LKodhDUoInZIn/9bC6cRrCfe/xMAoJdLRTMDNe0+ruy2LtnwQg14
-vRp7BADm9fBrVW89COBepWr/xVQ89mDA23oiAaLrKjiJb8LQg9NpmGa5AFuWBym2
-Y5MzjremPeqmjMfXGyXIu5o+9e1k5DQ72NB/m24FdrYkCW38sinIVVghDtvzLniG
-fOwBL+c0iA0BweBCNuouoJjJegPQbzaliTgcV8ZjuCq4juyp4AQApBN45mj8JIwZ
-wbsNnAmZ4mtv3gR03k20Tk4uCurktNjd0HvU28HOyg/ZehxeoKMd14R/8NZBE39W
-vzJHnAVzfcsmNV1SQS7fSxD2f0FsWYxfF2ErBhwhK3GIuKAujPnlzjT57ZnhzBuH
-cALohJ1izyVOcBwFIAc+mwZSBRAKILq0OFJpY2hhcmQgR3V5IEJyaWdncyAoZ3Bn
-LWxhcCkgPHJnYkBjb25zY29vcC5vdHRhd2Eub24uY2E+iFsEExECABsFAjfME2AF
-CQPCZwADCwoDAxUDAgMWAgECF4AACgkQNmdg8X0u14ixOACfcmzB1f4YZ2yC0jyX
-efVFtbIZ/fMAn35OwFji+uU6/BFLYXnsMlsJMsOMuQENBDfME3QQBADQcXxUkW/f
-6s6S7RXOUIIV9CgHiZpHPV7T23wQhQOOtVjO2akFLryNI6Z6a66JRhS6fRa3+eiL
-9TB0umC8e297dHrzObs43bf5h7sTJB8xHTUI9v4rlMwC8Bk3oghnoCJ820MADttR
-p+CUWMkPaBQoDTJJhyfju66lgxZoycLVMwADBgQApLUhOmpHB+zGMvluBUJgBEja
-Z553bU/gLzRsTCvt1gnIXLjxYXkiKjLyXfym47mXNaGUGWC7b7yaMVjhfnF3bJ5t
-xeIiL7/p3ei17aYOlzXx3MhmuPRhS1IJbXfXChPc7toCqDeSFmnGmVWJZ+zuleTm
-OITYkgt5Lshp/N1NZXKITAQYEQIADAUCN8wTdAUJA8JnAAAKCRA2Z2DxfS7XiApb
-AJ94BeAKtqsshjVPWijCZ/8SBcJogwCggQjLX5KwZzhHASEXQ/oMvAgS6OKZAaIE
-Nuv2vBEEAJttf93iMoIaranZOJ8AR0V0ax+4bTo61nQ392tjaRiPv+9lWuY1O3rv
-pHTzTtXP5Qtz1Uw51jn5rDAA43mwz0+cR93g873ecb41/9LRKF8I9CbmZO6N70Re
-mLdGb4R1FQ2gMHAwIz+Z54esABLQgq1qUZ66k1+TL/3EZRLnRSk3AKD8fayzCfyw
-Vxgy8C67Z35FdBsVGwP9HLfVXrDoAkl3St52A9cIqYKCjWk7Hbv3mdNZIz8pEuhY
-7BlpPeMwP9p5cEqlTMjaQHfefHwm1K7GthihkGAHyWM2iZLZSQzIFPG1ER+feTCA
-VjSSbvoDGyhHbW+uhGYaNwSLQC36+NrC6ULoTq6Uh86Klpa7mJzLAq+b/6XKhR8D
-/jzTElA97kUJEzdpbm5YtqDsu9H16Zdlf+jO59MNi2rcElt3w+thNfucNHVo8fm0
-FGgTpXwNss0Ej4cBXKc8m1ujAWG/hC9s9MMaa1uUgbqngGhZrOvcXXFCJZwoWteW
-K4rqucRx7BAl3hyQwl3KK8TY60Te329VBIcKJyVvb7TFtDFVbHJpayBEaWNrb3cg
-KG9ubGluZSBHbnVQRyB0ZXN0KSA8dWtkQGthbXBzYXguZGs+iQCVAwUQNuwRdSDu
-hu1tZgc9AQEAzwP9HnvIc9zYRmjQEsB44Aik6/pQvrBsSpLNzAWelEaMw6bFHaQT
-1PtMnpFmGxbJR6MBBsWku2armlC8G4EUVn9AR07BtXGVGfn8xsHs4MK77QPO7C/I
-eqOdotrEYr/OmpXMjBHTfB3B/9vu1p4+ubA8jrY/9DKxRLeWtoJcT19Pe/+JARUD
-BRA2744i2gTMWm1DVDsBAQohCACL7/fi/RR7eZc6c0aXEqdytMmAoIg/056jdhwe
-OiJITmXxDwNzaDbofOMWGm2IbDb3XfAU52WmKRsnlUFZFWEmHQurUaApx6xGqQiG
-wJC38sBS+CfbMmhbvWBeu0XI4V/F/wfzpxYCbELULEHsAeDMXCa4TLhKfmZdrde5
-1RJgK+bNZx/HVCwwU5YtGHbyJ/lYDlg8FxxRCPAAb31mSviRJLLrdEwPWWdi9lGr
-G8kp10nnDsfl3mxlItWKAa7ey7ntYi/1glIxSdqgXhfKiXCgZLRC98cQMyj0J3fY
-HXF19fkugPCCx5itawmWLeS7sKAkMKBmsqcWKaYp3oy8WnR7iFsEExECABsFAjbr
-9rwFCQF+UwADCwoDAxUDAgMWAgECF4AACgkQ9u7fIBhLxNmwfgCg6vEPiWfYZ4Bt
-tUvCbLqw7qxl354AoMzEob55S7m8YjrkDP0iimJfHsKliEYEEBECAAYFAjc0ONQA
-CgkQXeJJllsDWKKeoACbB7pifCZOprEAEwLyaJmaSvYOvUkAn1CaMjj9cxhwQxLg
-7X1Db3FTm3PbuQINBDbr92cQCACHpMcXbJWET55YL4vcHhgZnlzdthEHunAp0EG4
-RznS4ESJX7D2Ll2jO74fD25XFQ/6HsvZl+ITZhMMDW5p8lTfniVBPRWRQaVSzjzw
-A0UykQVSf093unT7bSIsGZAMmUymD1ucG5Jh0eHGQq4REmBuvSm6CKh6JRmAJbyk
-TKWhfagX5TN0+mHD+CcFKzsgorYRh7KNlFLB6idtAZxFqdhHXkI64kysMVFt6ZlA
-2CV5LCQy8m1lLc0WuXM58tWDZ84UeBCJfO+5N8EwkS1S4dRWouOxFWx8nJpje0NP
-tb/vyZRQ+JMClVaKOLjmC017k4F8XxVYNqZ7Y5TWmr6sl2WnAAQLB/9iaLQ3eGPG
-9GWv9pp/wAYIYzMiDsokdHXf7gOifZXG1DT3Gn1gXqgJmYP3DQN1l6b7NboH+ekB
-Ua4D1Y9glIf4/HbdCtv6fGFGv2JWDwNWkU1H88ZrDmwAxcOS9vu9D78ElnACrV46
-OOfmc0PnDseZCgGSuAscXU8YM/zLIGFMvmeALzHxPVOLrLp/Ep0+kGNKdEEDV5ht
-5F81uOpTMNkacASAdUqS5iseSjITYbo1sk4j5Fn8pTTn0U9445b/KjKiEH+jbn4x
-fPcC03FaXvMnFP+1nAqLbgFmVJ2ljjgEBbgkDPumsrjIuU2ZgSN9CZZ4tQke/FU0
-7RttYHde48eziEwEGBECAAwFAjbr92cFCQF+UwAACgkQ9u7fIBhLxNmnUACgrtAG
-GLWPUQbGR/6OQa9AZ6xLhnMAn0SZudBARwp97yCM3Wcm433S6xVDmQGiBDWiHh4R
-BAD+l0rg5p9rW4M3sKvmeyzhs2mDxhRKDTVVUnTwpMIR2kIA9pT43No/coPajDvh
-ZTaDM/vSz25IZDZWJ7gEu86RpoEdtr/eK8GuDcgsWvFs5+YpCDwWG2dx39ME7DN+
-SRvEE1xUm4E9G2Nnd2UNtLgg82wgi/ZK4Ih9CYDyo0a9awCgisn3RvZ/MREJmQq1
-+SjJgDx+c2sEAOEnxGYisqIKcOTdPOTTie7o7x+nem2uac7uOW68N+wRWxhGPIxs
-OdueMIa7U94Wg/Ydn4f2WngJpBvKNaHYmW8j1Q5zvZXXpIWRXSvyTR641BceGHNd
-YiR/PiDBJsGQ3ac7n7pwhV4qex3IViRDJWz5Dzr88x+Oju63KtxYurUIBACi7d1r
-UlHr4ok7iBRlWHYXU2hpUIQ8C+UOE1XXT+HB7mZLSRONQnWMyXnqbAAW+EUUX2xp
-b54CevAg4eOilt0es8GZMmU6c0wdUsnMWWqOKHBFFlDIvyI27aZ9quf0yvby63kF
-CanQKc0QnqGXQKzuXbFqBYW2UQrYgjXji8rd8bQnV2VybmVyIEtvY2ggKGdudXBn
-IHNpZykgPGRkOWpuQGdudS5vcmc+iF0EExECAB0FAjZVoKYFCQhtDIgDCwQDBRUD
-AgYBAxYCAQIXgAAKCRBot6uJV1SNzS4+AKCHdeYHMmKQV9mC7REE5Vz6d5rRBgCf
-VMcyRP7dxBwhytmwCDpAcCFvCLSJAV8DBRA1oh5DA28RuP8+qgsQA2MyBR0eiPUo
-vYMz0DUXBbNs5606eaVeTJOn9WqkYGcS9xOKlGd8Xj0IcAKN30st5AsC5hRqr82r
-rUjB5/CuVdbvk+Qkh6ixWCqo+RRrbgf8cKCg1x+lDj9PpeSD/B9UU45ntxYamoXn
-PszxtzU+e73Nkbtrej5rgMK8tgTLkhTAbO8M15Mgtw2yOeDFfiCj4xzDkYryvLiP
-I5p2vYXTVcgYnwpNRnMZBwUghb1PMSXj7AP0P/8wnpb656yIjH2OAkE5is5HvTEs
-2wGUCEXXYKxgLIl9bRPGd2DHfJQ6broxy1RHVmaOrOeDibspx67RRTm3WqbtLiK0
-/nRF0gEjFGxLjQiy92gp6xLRiQsMQdkz0Lwgr0dgSs6JejBlsQPp5nXXkIm9q/hl
-6Cly3Zx3KbAIwO5ZF5NyBciezCxSurg64xmxibNhSknblI0vyG+IRgQQEQIABgUC
-NaInPAAKCRBsfuG4YhzAE37WAJ9Xzmig1DrfnUt/KwfgidkPohJViQCg0T6afKuR
-spWzPAz5TKQpVjd02KmIRgQQEQIABgUCNu1ObAAKCRBd4kmWWwNYomq2AJ9+alN2
-TpVRAhCxP91eqvfEN9HgGgCgrTvpWnB9EKtROr+AT//cujKCyIaZAaIENaIg8xEE
-ALYPe0XNsPjx+inTQ+Izz527ZJnoc6BhWik/4a2bZYENSOQXAMKTDQMv2lLeI0i6
-ceB967MNubhHeVdNeOWYHFSM1UGRfhmZERISho3bp+wVZvVG8GBVwpw34PJjgYU/
-0tDwnJaJ8BzX6j0ecTSTjQPnaUEtdJ/u/gmG9j0218TzAKDihdNoKJEU9IKUiSjd
-GomSuem/VwQArHfaucSiDmY8+zyZbVLLnK6UJMqtsIv1LvAg20xwXoUk2bY8H3tX
-L4UZ8YcoSXYozwALq3cIo5UZJ0q9Of71mI8WLK2iFSYVplpTX0WMClAdkGt3HgVb
-7xtOhGt1mEKeRQjNZ2LteUQrRDD9MTQ+XxcvEN0IpAj4kBJe9bR6HzAD/iecCmGw
-SlHUZZrgqWzv78o79XxDdcuLdl4i2fL7kwEOf9jsDe7hGs27yrdJEmAG9QF9TOF9
-LJFmE1CqkgW+EpKxsY01Wjm0BFJB1R7iPUaUtFRZxYqfgXarmPjql2iBi+cVjLzG
-u+4BSojVAPgP/hhcnIowf4M4edPiICMP1GVjtCFXZXJuZXIgS29jaCA8d2VybmVy
-LmtvY2hAZ3V1Zy5kZT6IWwQTEQIAGwUCNs8JNwUJCCCxRAMLCgMDFQMCAxYCAQIX
-gAAKCRBsfuG4YhzAE2kgAJ92JKU+YcYHoRhX51+4s3fnPIyNEgCfaiWeoyb15xgd
-O6etGiD2MYCWy5mJAHUDBRA1o3cUHRn0wQyYV6UBAT3zAv9HMaPuMWFQKZRTtJyG
-Mo0ID+w/DtLn8z7CMBd5L2+2+RTTY36fgwITehtBziIJC9xrFrQnx+VB2pYvprTR
-SCg6U7a/hf5T6WT9zj887C2UuIWE6pjLNTvwAqvGsSoAIpWJAV8DBRA1oicOA28R
-uP8+qgsQAwfcBR9Iuppp+q1mChXqSYV8oROMFqkTyQJ736IllJ7Q6eGiEMrOpTkY
-oFVyFqOJOEivxR+fWJ8xe+e/Kq02Vv0XANGyKias6mqrDnU2BBWuPXAo7y5wVuDn
-myZS01LP555lNBVilvDsMC/qQrvHe3y0kp4IAbK1EMG3qbsNHCaHLRTwM+U9Z0CY
-nkClbB2gjcC9nbtF3nzoBebowdYytat6eFMrBfYRHAUfZbRN0x6/or+I7WV5gtT+
-GrfVuSxVrGLsK9FN8iXGikiqdL/8BhFntif4BUGdIQdft+UawmT4IlrBL/Owh2hu
-l7UPtx4YqwQibGIZjopFSqBGp+j4VFUdapVxMraQLd/PUwZ78nHgF/IXBzhN3Yrh
-ryCxIGHrN4MN7OWZjO21F945tga1/FnIXsVBVECLiltnC9+/TBV0fE28aVca7EWB
-P+Ix2QWIRgQQEQIABgUCNu1OCwAKCRBd4kmWWwNYonyaAKCxLBsteoVfwn5g5Lug
-9QgVCMV76QCfRgQKXQv9zl4oO7Aa1Qljm9zEM3C5AY0ENs8HCBAGAPc1hCpuXmaT
-DAUbIqS9CFHkihMnilIwAV+L2Dbq5eOPtoemPKx5+6xtZfzzY9/VCVwZCxY9Y5PE
-N9r/twUA478L/FOXv5E4BpX+4R91klt/EZGcNfDl2Ar56FpGJ3iLg4+vxx9m1TV5
-k2nNOUZAVD1L+MoapWhaZFXLMChrhDUcbo7/1Fr1Rfv9j/LkkIJJhqf3G8HzE5Av
-CQVSywUayYZdbmqdiY2bklZJVFAXs1X9zSTGoFc8eOxz6i1ZeMq+GwADBgX/T7o5
-R+SOTlJ72ac/g121f1kFX1dbRkQq2pCI95qTehp1AxdSwG3ur2slFCfi8ZDNUqkF
-XJrsv5mh1yfqq7zS5T6lGT5lOXCDZbAO2wqNZY1VKeeCdcvD2VMeh8XxJfy8y1ZK
-/iE1p8qnokYpA3nFH+JIsdrXk5ceiN3nKk+aDamUkV1sJzeEm5F7QHe60oBKbVGI
-UF4EhGq6daVyeCeK4KhWuPYyiEgyaq5/xJZbR3uRcdW6X5AiGJWJOOQoGvWziEwE
-GBECAAwFAjbPBwgFCQbzyQAACgkQbH7huGIcwBN5FQCggakIOYzLX3lNq2WWgcAk
-SNm7kpoAnA69b3z2E5vxyD3bhggVUDX7j8hruQGNBDWiITwUBgCRCYCU5eLFvzCt
-rzesTWLssIQ0vOW8FlYoFc3g416VkCeeQ6bsipGMyG0pEk3vnOpXIpRpTAMqOl/0
-nkra3vmZLEG2ds1Govdeh2Mcr3c5wBSTPdyLuK4L9vbgkjarhd5Ab+/hhHVWh0zT
-MRDUgLQkKrg+Xf1BnJcl1kKtQW8xxermu41KV3O0GpMUVSIVuTDUW6D9nJcm97YV
-VxuxFcWsHsQS7L6KJT+Rn81WIqTQvhPopEdWwSKuI2UKKJtbX18AAwUF/1Nu/rso
-UwOsupBqf/ShJKh2MNAoMaq2iHspBggo9ep+pPxx533J3kwsXA8p/e3sBYbW5xbb
-HXXwA1iQ9JTXbZROd0+xrHRxjheRofFo3Ck0UKi0ZDRRFKHEo2lypt1+/L7V3ymk
-Rq+A7LGdXUk6QuNkkvArxuDEV1s9ZywkmeO64fc/DPzsLNOA5JhDEw+cjBBzHlu5
-khXk14Qsm1xtt3dFW5or8ZCG3xAmm5dKOLw2XUWKFgOMAJHxNpGUCHnQaYhGBCgR
-AgAGBQI4K/uDAAoJEGx+4bhiHMAT2FMAn1xEe77uraGTGkV+eiTiZGKyh8JOAKDO
-g+M0i5iKJXr7AsHmjXXsw1Y9kIhMBBgRAgAMBQI1oiE8BQkHhM4AAAoJEGx+4bhi
-HMATDfUAoLstR8cg5QtHwSQ3nFCOKEREUFIwAKDID3K3hM+b6jW1o+tNX9dnjb+Y
-MZkAbQIwbYOUAAABAwC7ltmO5vdKssohwzXEZeYvDW2ll3CYD2I+ruiNq0ybxkfF
-Bopq9cxta0OvVML4LK/TH+60f/Fqx9wg2yk9APXyaomdLrXfWyfZ91YtNCfj3ElC
-4XB4qqm0HRn0wQyYV6UABRG0IVdlcm5lciBLb2NoIDx3ZXJuZXIua29jaEBndXVn
-LmRlPokAlQMFEDRfoOmOB31Gi6BmjQEBzwgD/2fHcdDXuRRY+SHvIVESweijstB+
-2/sVRp+FCDjR74Kg576sJHfTJCxtSSmzpaVpelb5z4URGJ/Byi5L9AU7hC75S1Zn
-J+MjBT6VePyk/r0uBrMkU/lMG7lk/y2By3Hll+edjzJsdwn6aoNPiyen4Ch4UGTE
-guxYsLq0HES/UvojiQEVAwUTNECE2gnp+QqKck5FAQH+1Af/QMlYPlLG+5E19qP6
-AilKQUzNkd1TWMenXTS66hGIVwkLVQDi6RCimhnLMq/F7ENA8bSbyyMuncaBz5dH
-4kjfiDp1o64LULcTmN1LW9ctpTAIeLLJZnwxoJLkUbLUYKADKqIBXHMt2B0zRmhF
-OqEjRN+PhI7XCcHeHWHiDeUB58QKMyeoJ/QG/7zLwnNgDN2PVqq2E72C3ye5FOkY
-LcHfWKyBRrn6BdUphAB0LxZujSGk8ohZFbia+zxpWdE8xSBhZbjVGlwLurmS2UTj
-jxByBNiheUD6IC3u5P6psld0OfqnpriZofP0CBP2oTk65r529f/1lsy2kfWrVPYI
-FJXEnIkAlQMFEDQyneGkWMS9SnJfMQEBMBMD/1ADuhhuY9kyN7Oj6DPrDt5SpPQD
-GS0Jtw3yuIPoed+xyzlrEuL2HeaOj1O9urpn8XLN7V21ajkzlqsxnGkOuifbE9UT
-67o2b2vCldCcY4nV5n+U1snMDwNv+RkcEgNa8ANiWkm03UItd7/FpHDQP0FIgbPE
-PwRoBN87I4gaebfRiQCVAwUQNDUSwxRNm5Suj3z1AQGMTAP/UaXXMhPzcjjLxBW0
-AccTdHUtLi+K+rS5PNxxef2nnasEhCdK4GkM9nwJgsP0EZxCG3ZSAIlWIgQ3MK3Z
-AV1Au5pLKolRjFyEZF420wAtiE7V+4lw3FCqNoXDJEFC3BW431kx1wAhDk9VaIHH
-adYcof4ddmMLQOW2cJ7LDEEBW/WJAJUDBRA0M/VQImbGhU33abUBARcoA/9eerDB
-ZGPCuGyEmQBcr24KPJHWv/EZIKl5DM/Ynz1YZZbzLcvEFww34mvY0jCfoVcCKIeF
-FBMKiSKrOMtoVC6cQMKpmhE9hYRStw4E0bcf0BD/stepdVtpwRnG8SDP2Zbmtgyj
-YT/7T4Yt6/0f6N/0NC7E9qfq4ZlpU3uCGGu/44kAlQMFEDQz8kp2sPVxuCQEdQEB
-c5YD/RixvFcLTO1HznbblrO0WMzQc+R4qQ50CmCpWcFMwvVeQHo/bxoxGggNMmuV
-T0bqf7MolZDSJNS96IAN32uf25tYHgERnQaMhmi1aSHvRDh4jxFu8gGVgL6lWit/
-vBDW/BiFBCH6sZJJrGSuSdpecTtaWC8OJGDoKTO9PqAA/HQRiQB1AwUQNDJSx011
-eFs7VOAZAQGdKQL/ea3qD2OP3wVTzXvfjQL1CosX4wyKusBBhdt9u2vOT+KWkiRk
-1o35nIOGuZLHtSFQDY8CVDOkqg6g4sVbOcTl8QUwHA+A4AVDInwTm1m4Bk4oeCIw
-k4Bp6mDdW11g28k/iQEVAgUSNDIWPm/Y4wPDeaMxAQGvBQgAqGhzA/21K7oL/L5S
-5Xz//eO7J8hgvqqGXWd13drNy3bHbKPn7TxilkA3ca24st+6YPZDdSUHLMCqg16Y
-OMyQF8gEkX7ZHWPacVoUpCmSz1uQ3p6W3+u5UCkRpgQN8wBbJx5ZpBBqeq5q/31o
-kaoNjzA2ghEWyR5Ll+U0C87MY7pc7PlNHGCr0ZNOhhtf1jU+H9ag5UyT6exIYim3
-QqWYruiCLSUcim0l3wK7LMW1w/7Q6cWfAFQvl3rGjt3rg6OWg9J4H2h5ukf5JNiR
-ybkupmatUM+OVMRkf93jzU62kbyZpJBHiQZuxxJaLkhpv2RgWib9pbkftwEy/Znm
-jkxlIIkAlQMFEDQvWjh4313xYR8/NQEB37QEAIi9vR9h9ennz8Vi7RNU413h1ZoZ
-jxfEbOpkQAjE/LrZ/L5WiWdoStSiyqCLPoyPpQafiU8nTOr1KmY4RgceJNgxIW4O
-iSMoSvrhc2kqP+skb8A2B4+47Aqjr5fSAVfVfrDMqDGireOguhQ/hf9BOYsM0gs+
-ROdtyLWPtMjRnFlviD8DBRAz8qQSj6lRT5YOKXIRAntSAJ9StSEMBoFvk8iRWpXb
-6+LDNLUWzACfT8iY3IxwvMF6jjCHrbuxQkL7chSJARUDBRA0MMO7569NIyeqD3EB
-ATIAB/4tCPZ1sLWO07g2ZCpiP1HlYpf5PENaXtaasFvhWch7eUe3DksuMEPzB5Gn
-auoQZAkuhEGkoEfrfL3AXtXH+WMm2t7dIcTBD4p3XkeZ+PgJpKiASXDyul9rumXX
-vMxSL4KV7ar+F1ZJ0ycCx2r2au0prPao70hDAzLTy16hrWgvdHSK7+wwaYO5TPCL
-5JDmcB+dHKW72qNUOD0pxbe0uCkkb+gDxeVX28pZEkIIOMMV/eAs5bs/smV+eJqW
-T/EyfVBDo7heF2aeyJj5ecxNOODr88xKF7qEpqazCQ4xhvFY+Yn6+vNCcYfkoZbO
-n0XQAvqfa2Vab9woVIVSaDji/mlPiQB1AwUQNDC233FfeD4HYGBJAQFh6QL/XCgm
-5O3q9kWpgts1MHKoHoh7vxSSQGSP2k7flNP1UB2nv4sKvyGM8eJKApuROIodcTkc
-cM4qXaBuXunMr5kJlvDJPm+NLzKyhtQP2fWI7xGYwiCiB29gm1GFMjdur4amiQEV
-AwUQNDBR9fjDdqGixRdJAQE+mAf+JyqJZEVFwNwZ2hSIMewekC1r7N97p924nqfZ
-Knzn6weFpE80KIJSWtEVzI0XvHlVCOnS+WRxn7zxwrOTbrcEOy0goVbNgUsP5ypZ
-a2/EM546uyyJTvgD0nwA45Q4bP5sGhjh0G63r9Vwov7itFe4RDBGM8ibGnZTr9hH
-o469jpomHSNeavcaUYyEqcr4GbpQmdpJTnn/H0A+fMl7ZHRoaclNx9ZksxihuCRr
-kQvUOb3uRD9lFIhCvNwEardN62dKOKJXmn1TOtyanZvnmWigU5AmGuk6FpsClm3p
-5vvlid64i49fZt9vW5krs2XfUevR4oL0IyUl+qW2HN0DIlDiAYkAlQMFEDQvbv2w
-cgJwUPMhJQEBVBID/iOtS8CQfMxtG0EmrfaeVUU8R/pegBmVWDBULAp8CLTtdfxj
-Vzs/6DXw0RogXMRRl2aFfu1Yp0xhBYjII6Kque/FzAFXY9VNF1peqnPt7ADdeptY
-MppZa8sGn9BBRu9Fsw69z6JkyqvMiVxGcKy3XEpVGr0JHx8Xt6BYdrULiKr2iQB1
-AwUQNC68n6jZR/ntlUftAQFaYgL+NUYEj/sX9M5xq1ORX0SsVPMpNamHO3JBSmZS
-Izjiox5MAqoFOCigAkonuzk5aBy/bRHy1cmDBOxf4mNhzrH8N6IkGvPE70cimDnb
-Fvr+hoZSjIqxtELNZsLuLVavLPAXiQCVAwUQNC6vWocCuHlnLQXBAQHb1gQAugp6
-2aVzDCuz4ntfXsmlGbLY7o5oZXYIKdPP4riOj4imcJh6cSgYFL6OMzeIp9VW/PHo
-2mk8kkdkz5uif5LqOkEuIxgra7p1Yq/LL4YVhWGQeD8hwpmu+ulYoPOw40dVYS36
-PwrHIH9afNhl8Or5O2VIHIWnoQ++9r6gwngFQOyJAJUDBRAzHnkh1sNKtX1rroUB
-AWphBACdhuqm7GHoiXptQ/Y5F6BivCjxr9ch+gPSjaLMhq0kBHVO+TbXyVefVVGV
-gCYvFPjozM8PEVykQAtY//eJ475aGXjF+BOAhl2z0IMkQKCJMExoEDHbcj0jIIMZ
-2/+ptgtbFSyJ2DQ3vvCdbw/1kyPHTPfP+L2u40GWMIYVBbyouokAlQMFEDMe7+UZ
-symln7HG2QEBzMED/3L0DyPK/u6PyAd1AdpjUODTkWTZjZ6XA2ubc6IXXsZWpmCg
-B/24v8jsJ3DIsvUD3Ke55kTr6xV+au+mAkwOQqWUTUWfQCkSrSDlbUJ1VPBzhyTp
-uzjBopte7o3R6XXfcLiC5jY6eCX0QtLGhKpLjTr5uRhf1fYODGsAGXmCByDviQB1
-AgUQMy6UMB0Z9MEMmFelAQHV4AMAjdFUIyFtpTr5jkyZSd3y//0JGO0z9U9hLVxe
-BBCwvdEQxsrpeTtVdqpeKZxHN1GhPCYvgLFZAQlcPh/Gc8u9uO7wVSgJc3zYKFTh
-KpQevdF/rzjTCHfgigf5Iui0qiqBiQCVAwUQMx22bAtzgG/ED06dAQFi0gQAkosq
-TMWy+1eUXbi2azFK3RX5ERf9wlN7mqh7TvwcPXvVWzUARnwRv+4kk3uOWI18q5UP
-is7KH3KYOVeRrPd8bbp6SjhBh82ourTEQUXLBDQiI1V1cZZmwwEdlnAnhFnkXgMB
-NM2q7oBefRHADfYDfGo90wXyrVVL+GihDNpzUwOJAJUDBRAzHUFnOWvfULwOR3EB
-AbOYA/90JIrKmxhwP6quaheFOjjPoxDGEZpGJEOwejEByYj+AgONCRmQS3Bydtub
-A+nm/32DFeG8pe/dnFvGc+QgNW560hK21C2KJj72mhjRlg/na7jz4/MmBAv5k61Q
-7roWi0rwx+R9NSHxpshC8A92zmvo8w/XzVSogC8pJ04jcnY6YokAlQMFEDMdPtta
-9LwlvuSC3QEBvPMD/3TJGroHhHYjHhiEpDZZVszeRQ0cvVI/uLLi5yq3W4F6Jy47
-DF8VckA7mw0bXrOMNACN7Je7uyaU85qvJC2wgoQpFGdFlkjmkAwDAjR+koEysiE8
-FomiOHhvEpEY/SjSS4jj4IPmgV8Vq66XjPw+i7Z0RsPLOIf67yZHxypNiBiYiQCV
-AwUQMxxwpKrq6G7/78D5AQHo2QQAjnp6KxOl6Vvv5rLQ/4rj3OemvF7IUUq34xb2
-5i/BSvGBUpDQVUmhv/qIfWvDqWGZedyM+AlNSfUWPWnP41S8OH+lcERH2g2dGKGl
-7kH1F2BxByZlqREHm2q624wPPA35RLXtXIx06yYjLtJ7b+FCAX6PUgZktZYk5gwj
-doAGrC2JAJUDBRAzGvcCKC6c7f53PGUBAUozA/9l/qKmcqbi8RtLsKQSh3vHds9d
-22zcbkuJPBSoOv2D7i2VLshaQFjq+62uYZGE6nU1WP5sZcBDuWjoX4t4NrffnOG/
-1R9D0t1t9F47D77HJzjvo+J52SN520YHcbT8VoHdPRoEOXPN4tzhvn2GapVVdaAl
-WM0MLlohNH3I9jap9okAdQMFEDMZlUAnyXglSykrxQEBnuwC/jXbFL+jzs2HQCuo
-4gyVrPlUksQCLYZjNnZtw1ca697GV3NhBhSXR9WHLQH+ZWnpTzg2iL3WYSdi9tbP
-s78iY1FSd4EG8H9V700oQG8dlICF5W2VjzR7fByNosKM70WSXYkBFQMFEDMWBsGC
-y1t9eckWHQEBHzMH/jmrsHwSPrA5R055VCTuDzdS0AJ+tuWkqIyqQQpqbost89Hx
-per3MmjLJas/VJv8EheuU3vQ9a8sG2SnlWKLtzFqpk7TCkyq/H3blub0agREbNnY
-hHHTGQFCYJb4lWjWvMjfP+N5jvlLcnDqQPloXfAOgy7W90POoqFrsvhxdpnXgoLr
-zyNNja1O1NRj+Cdv/GmJYNi6sQe43zmXWeA7syLKMw6058joDqEJFKndgSp3Zy/y
-XmObOZ/HC2OJwA3gzEaAu8Pqd1svwGIGznqtTNCn9k1+rMvJPaxglg7PXIJS282h
-mBl9AcJlwmh2GUCswl9/sj+REWTb8SgJUbkFcp6JAJUDBRAwdboVMPfsgxioXMEB
-AQ/LA/9BFTZ9T95P/TtsxeC7lm9imk2mpNQCBEvXk286FQnGFtDodGfBfcH5SeKH
-aUNxFaXr39rDGUtoTE98iAX3qgCElf4V2rzgoHLpuQzCg3U35dfs1rIxlpcSDk5i
-vaHpPV3Sv+mlqWL049y+3bGaZeAnwM6kvGMP2uccS9U6cbhpw4hGBBARAgAGBQI3
-GtRfAAoJEF3iSZZbA1iikWUAoIpSuXzuN/CI63dZtT7RL7c/KtWUAJ929SAtTr9S
-lpSgxMC8Vk1T1i5/SYkBFQMFEzccnFnSJilEzmrGwQEBJxwH/2oauG+JlUC3zBUs
-oWhRQwqo7DdqaPl7sH5oCGDKS4x4CRA23U15NicDI7ox6EizkwCjk0dRr1EeRK+R
-qL1b/2T42B6nynOLhRG2A0BPHRRJLcoL4nKfoPSo/6dIC+3iVliGEl90KZZD5bnO
-NrVJQkRjZL8Ao+9IpmoYh8XjS5xMLEF9oAQqAkA93nVBm56lKmaL1kl+M3dJFtNK
-tVB8de1ZXifDs8HykD42qYVtcseCKxZXhC3UTG5YLNhPvgZKH8WBCr3zcR13hFDx
-uecUmu0MVhvEzoKyBYYt0rrqnyWrxwbv4gSTUWH5ZbgsTjc1SYKZxz6hrPQnfYWz
-NkznlFWJARUDBRM0xL43CdxwOTnzf10BATOCB/0Q6WrpzwPMofjHj54MiGLKVP++
-YfwzdvnsHxVpTZLZ5Ux8ErDsnLmvUGphnLVELZwEkEGRjln7a19h9oL8UYZaV+Ic
-R6tQ06Fb1ldR+q+3nXtBYzGhleXdgJQSKLJkzPF72tvY0DHUB//GUV9IBLQMvfG8
-If/AFsih4iXi96DOtUAbeuIhnMlWwLJFeGjLLsX1u6HSX33xy4bGX6v/UcHbTSSY
-axzb92GR/xpP2Xt332hOFRkDZL52g27HS0UrEJWdAVZbh25KbZEl7C6zX/82OZ5n
-TEziHo20eOS6Nrt2+gLSeA9X5h/+qUx30kTPz2LUPBQyIqLCJkHM8+0q5j9ciQCi
-AwUTNMS+HZFeTizbCJMJAQFrGgRlEAkG1FYU4ufTxsaxhFZy7xv18527Yxpls6mS
-Ci1HL55nJoce6TI+Z34MrLOaiZljeQP3EUgzA+cs1sFRago4qz2wS8McmQ9w0FNQ
-QMz4vVg9CVi1JUVd4EWYvJpA8swDd5b9+AodYFEsfxt9Z3aP+AcWFb10RlVVsNw9
-EhObc6IMnwAOHCEI9vp5FzzFiQCVAwUQNxyr6UyjTSyISdw9AQHf+wP+K+q6hIQ0
-9tkgaYaDLlWKLbuxePXqM4oO72qi70Gkg0PV5nU4l368R6W5xgR8ZkxlQlg85sJ0
-bL6wW/SjMz7pP9hkhNwk0x3IFkGMTYG8i6Gt8Nm7x70dzJoiC+A496PryYC0rvGV
-f+Om8j5uTexBBjb/jpJhAQ/SGqeDeCHheOC0Lldlcm5lciBLb2NoIChtZWluIGFs
-dGVyIGtleSkgPHdrQGNvbXB1dGVyLm9yZz6JAHUDBRM2G2MyHRn0wQyYV6UBASKK
-Av4wzmK7a9Z+g0KH+6W8ffIhzrQo8wDAU9X1WJKzJjS205tx4mmdnAt58yReBc/+
-5HXTI8IKR8IgF+LVXKWAGv5P5AqGhnPMeQSCs1JYdf9MPvbe34jD8wA1LTWFXn9e
-/cWIRgQQEQIABgUCNxrUaQAKCRBd4kmWWwNYovRiAJ9dJBVfjx9lGARoFXmAieYr
-MGDrmwCZAQyO4Wo0ntQ+iq4do9M3/FTFjiCZAaIENu1I6REEAJRGEqcYgXJch5fr
-UYBj2EkDkWAbhRqVXnmiF3PjCEGAPMMYsTddiU7wcKfiCAqKWWXow7BjTJl6Do8R
-T1jdKpPOlBJXqqPYzsyBxLzE6mLps0K7SLJlSKTQqSVRcx0jx78JWYGlAlP0Kh9s
-PV2w/rPh0LrPeOKXT7lZt/DrIhfPAKDL/sVqCrmY3QfvrT8kSKJcgtLWfQP/cfbq
-VNrGjW8am631N3UVA3tWfpgM/T9OjmKmw44NE5XfPJTAXlCV5j7zNMUkDeoPkrFF
-8DvbpYQs4XWYHozDjhR2Q+eI6gZ0wfmhLHqqc2eVVkEG7dT57Wp9DAtCMe7RZfhn
-arTQMqlYtOEa/suiHk0qLo59NsyF8eh68IDNCeYD/Apzonwaq2EQ1OEpfFlp6LcS
-nS34+UGZtTO4BgJdmEjr/QrIPp6bJDstgho+/2oR8yQwuHGJwbS/8ADA4IFEpLdu
-SpzrABho7RuNQcm96bceRY+7Hza3zf7pg/JGdWOb+bC3S4TIpK+3sx3YNWs7eURw
-pGREeJi5/Seic+GXlGzltBpXZXJuZXIgS29jaCA8d2tAZ251cGcub3JnPohbBBMR
-AgAbBQI3Gs+QBQkMyXyAAwsKAwMVAwIDFgIBAheAAAoJEF3iSZZbA1iiXcIAnjv7
-ON5AiwzCLBwm9h9ywufXJQuVAJ9RMq6lpPqnDly6UCKz+kGt0EplyIhGBBARAgAG
-BQI3GtE9AAoJEGx+4bhiHMAThfQAnjcDvBthtHotN89IP590GSKY287xAJ0WhKl9
-j7gWwpVqCD+ofcq0ZQBG1IkAdQMFEDca0WMdGfTBDJhXpQEB0a4C/0AzSj1eSYFs
-4ss2x7xCn0yMPxML+hJdjGnVb0CPJGzzeKpD69pmVsD87nPa53gj0NXi/ADnQvPm
-csVs8dr7K5PxXFOXaJzDm72tnLeJKiTesZfMY7MQ0yYQUhUWogSY8YhGBBARAgAG
-BQI3GtGjAAoJEGi3q4lXVI3NLfgAoISt+x9r02Hl14njSfGmZIjyUrXuAJ9FhxTq
-LUHU1uDZmSSvlKpOcG1pYIhGBBARAgAGBQI3Tx9dAAoJEPbu3yAYS8TZLb4Ani50
-OXjsQCc/gr5G+xZy/yqOqnOWAJ44VlluXNaN6J7yhB9iXtsEGvE+oohGBBARAgAG
-BQI3pyb+AAoJEJg0ZdshQ5QifskAn0stcy37RHy7iB2bFB4rPVNDJaizAJ9hCH+0
-yNTOTisrEHLhS0QufAn3H4hFBBARAgAGBQI34UEzAAoJEDZnYPF9LteIeecAn3eT
-mQldy/AIYuEFvyaF1FPmQdDNAJj3trsO1mAyzs7+PB++rZunMveeiEYEEBECAAYF
-AjgqYg8ACgkQ4/JYVBKPDnkbHQCfRR7qUYmwTxtrf+Fw6hfsYjCy//AAn1eRdkkd
-CExOJPwvrHEtZydSmVA1tAtXZXJuZXIgS29jaIhbBBMRAgAbBQI27UjqBQkMyXyA
-AwsKAwMVAwIDFgIBAheAAAoJEF3iSZZbA1iitdYAn1IJbSJ46kvsBjq8X44hoybD
-ZlbWAKCS2jR5Z+CmMC5WDqNepHXAe3alA4kCHgQQFAMABgUCNy9Z1AAKCRBsTDGl
-sdUVZw3FB/9uDXhYYnQZYw1K6445HRZjNRo23NimItJXIuut5e2jwsE3DNuDOPat
-qZbtGL61gkAcuG25rxmBJ6JuaAG5lqwXx1vWbk03VlwcFcZPKwCOn4qeJxNn06uP
-vkP2jehKYzJFyKwSGv6CSPS1WEZ84A4Lp4pu59W7JgUNUjI7JQEaVbsCl6bMDNh6
-Z+zcN2MefzuWSMcxURI7h8zmu0u5JztwF8v97qWNpZBzlbxLSAgO/RW0vf2kxbgG
-WkprbmvXignLC5Sm9YJm6y8Obtkmepn9aaA4dBSzJi51NE6kYhuWw2DyKoLqG5ak
-ZIFF27ehFBGGSql9V2zPPoEH+cDHTWrbB/9D5T1ch3WPLPFQvVIaBpgx/pB3KMdD
-WjG4Us3HMzoL8zTr23Bs2BcnvVGwMNdXEVl9JONKIfXTQA/372FvmbJxpctQ5dgO
-85IXMcF38uyMU1WusVsOzlfD5wsZUc4iBHkhYB+C7l3U8BlT25BWB0adB+ZmDfzd
-FI/G9Hd+dnPWsc1QaZLrDvHoVVvFrVBTa3fyA1pwjAcBMA9wGnIkt9ejOdumDcAN
-uAIbIOMHCe49ARCRjBFqRtzNGuB7who9lu3Ydg+hSx25cxnIkjzPm2+7ulQPCznW
-dXURfXkFw3f75pjmlTIDUi1poPKZBWagVtALQE0zMw7nd0ycWSjiLjaSiEYEEBEC
-AAYFAjc6+aMACgkQdQ9klcidkz6GiwCdGe0KSP/vSyEZM/GClQXvjMD4RvMAoJwy
-TIdcjPZbQizDeAO3btn2CCwTiEYEEBECAAYFAjc3I8UACgkQ9u7fIBhLxNmHZQCg
-lWbPDznIcnOxdDW+k7YgA9+/n00An1ZjSiJipverUxLEFHAbSBWI0IntiQEVAwUQ
-N0Pe01KAV0R2U0AdAQHIcQf/Ykx+DvUaCLIYlMrEIDKZ3J/aPbJ8frAjvzYkrgFZ
-XhzQT9Xfyr6OkhiyWKFX23yzzDVcrmeIxovCUI7IFY6QM/d5yHr4Y8+18HdyaUva
-FLz3o9ZnVp1AeAJ5CkHzfufnrKPRpOzgvXFqttJVPbaVTAyJTo/Bh0fZGHyeHwW8
-3QhmxuWfac6PveoA1DM1+Wax5QoXVeHhyTzIutF3ivpqaHEBUB9xgVEk3jN0svdy
-aGCS3QANmXMDBecSPB0cfLtK8AmTV5w04D2kWw4lu+fO593Vp+z8Jsbvwj7QkOGD
-vlnY3Crx4qOwqqI7TPP+8bnJZKd1m9aRNbPcPdvXGvUh3YhGBBARAgAGBQI4KmIe
-AAoJEOPyWFQSjw55D5AAoJs5OxzJSdYdKsOjh8jLQxOESOE6AJ4vgpvtNaR384dB
-JxUE7yxNTPT7aA==
-=gKwz
------END PGP PUBLIC KEY BLOCK-----
diff --git a/g10/revoke.c b/g10/revoke.c
deleted file mode 100644
index 161bd2b82..000000000
--- a/g10/revoke.c
+++ /dev/null
@@ -1,690 +0,0 @@
-/* revoke.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <ctype.h>
-
-#include "options.h"
-#include "packet.h"
-#include "errors.h"
-#include "keydb.h"
-#include "memory.h"
-#include "util.h"
-#include "main.h"
-#include "ttyio.h"
-#include "status.h"
-#include "i18n.h"
-
-
-struct revocation_reason_info {
- int code;
- char *desc;
-};
-
-
-int
-revocation_reason_build_cb( PKT_signature *sig, void *opaque )
-{
- struct revocation_reason_info *reason = opaque;
- char *ud = NULL;
- byte *buffer;
- size_t buflen = 1;
-
- if(!reason)
- return 0;
-
- if( reason->desc ) {
- ud = native_to_utf8( reason->desc );
- buflen += strlen(ud);
- }
- buffer = xmalloc ( buflen );
- *buffer = reason->code;
- if( ud ) {
- memcpy(buffer+1, ud, strlen(ud) );
- xfree ( ud );
- }
-
- build_sig_subpkt( sig, SIGSUBPKT_REVOC_REASON, buffer, buflen );
- xfree ( buffer );
- return 0;
-}
-
-/* Outputs a minimal pk (as defined by 2440) from a keyblock. A
- minimal pk consists of the public key packet and a user ID. We try
- and pick a user ID that has a uid signature, and include it if
- possible. */
-static int
-export_minimal_pk(iobuf_t out,KBNODE keyblock,
- PKT_signature *revsig,PKT_signature *revkey)
-{
- KBNODE node;
- PACKET pkt;
- PKT_user_id *uid=NULL;
- PKT_signature *selfsig=NULL;
- u32 keyid[2];
- int rc;
-
- node=find_kbnode(keyblock,PKT_PUBLIC_KEY);
- if(!node)
- {
- log_error(_("key incomplete\n"));
- return GPG_ERR_GENERAL;
- }
-
- keyid_from_pk(node->pkt->pkt.public_key,keyid);
-
- pkt=*node->pkt;
- rc=build_packet(out,&pkt);
- if(rc)
- {
- log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
- return rc;
- }
-
- init_packet(&pkt);
- pkt.pkttype=PKT_SIGNATURE;
-
- /* the revocation itself, if any. 2440 likes this to come first. */
- if(revsig)
- {
- pkt.pkt.signature=revsig;
- rc=build_packet(out,&pkt);
- if(rc)
- {
- log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
- return rc;
- }
- }
-
- /* If a revkey in a 1F sig is present, include it too */
- if(revkey)
- {
- pkt.pkt.signature=revkey;
- rc=build_packet(out,&pkt);
- if(rc)
- {
- log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
- return rc;
- }
- }
-
- while(!selfsig)
- {
- KBNODE signode;
-
- node=find_next_kbnode(node,PKT_USER_ID);
- if(!node)
- {
- /* We're out of user IDs - none were self-signed. */
- if(uid)
- break;
- else
- {
- log_error(_("key %08lX incomplete\n"),(ulong)keyid[1]);
- return GPG_ERR_GENERAL;
- }
- }
-
- if(node->pkt->pkt.user_id->attrib_data)
- continue;
-
- uid=node->pkt->pkt.user_id;
- signode=node;
-
- while((signode=find_next_kbnode(signode,PKT_SIGNATURE)))
- {
- if(keyid[0]==signode->pkt->pkt.signature->keyid[0] &&
- keyid[1]==signode->pkt->pkt.signature->keyid[1] &&
- IS_UID_SIG(signode->pkt->pkt.signature))
- {
- selfsig=signode->pkt->pkt.signature;
- break;
- }
- }
- }
-
- pkt.pkttype=PKT_USER_ID;
- pkt.pkt.user_id=uid;
-
- rc=build_packet(out,&pkt);
- if(rc)
- {
- log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
- return rc;
- }
-
- if(selfsig)
- {
- pkt.pkttype=PKT_SIGNATURE;
- pkt.pkt.signature=selfsig;
-
- rc=build_packet(out,&pkt);
- if(rc)
- {
- log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
- return rc;
- }
- }
-
- return 0;
-}
-
-/****************
- * Generate a revocation certificate for UNAME via a designated revoker
- */
-int
-gen_desig_revoke( const char *uname )
-{
- int rc = 0;
- armor_filter_context_t afx;
- PKT_public_key *pk = NULL;
- PKT_secret_key *sk = NULL;
- PKT_signature *sig = NULL;
- iobuf_t out = NULL;
- struct revocation_reason_info *reason = NULL;
- KEYDB_HANDLE kdbhd;
- KEYDB_SEARCH_DESC desc;
- KBNODE keyblock=NULL,node;
- u32 keyid[2];
- int i,any=0;
-
- if( opt.batch ) {
- log_error(_("sorry, can't do this in batch mode\n"));
- return GPG_ERR_GENERAL;
- }
-
- memset( &afx, 0, sizeof afx);
-
- kdbhd = keydb_new (0);
- classify_user_id (uname, &desc);
- rc = desc.mode? keydb_search (kdbhd, &desc, 1) : GPG_ERR_INV_USER_ID;
- if (rc) {
- log_error (_("key `%s' not found: %s\n"),uname, gpg_strerror (rc));
- goto leave;
- }
-
- rc = keydb_get_keyblock (kdbhd, &keyblock );
- if( rc ) {
- log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) );
- goto leave;
- }
-
- /* To parse the revkeys */
- merge_keys_and_selfsig(keyblock);
-
- /* get the key from the keyblock */
- node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
- if( !node )
- BUG ();
-
- pk=node->pkt->pkt.public_key;
-
- keyid_from_pk(pk,keyid);
-
- /* Are we a designated revoker for this key? */
-
- if(!pk->revkey && pk->numrevkeys)
- BUG();
-
- for(i=0;i<pk->numrevkeys;i++)
- {
- if(sk)
- free_secret_key(sk);
-
- sk=xcalloc (1,sizeof(*sk));
-
- rc=get_seckey_byfprint(sk,pk->revkey[i].fpr,MAX_FINGERPRINT_LEN);
-
- /* We have the revocation key */
- if(!rc)
- {
- PKT_signature *revkey = NULL;
-
- any = 1;
-
- print_pubkey_info (NULL, pk);
- tty_printf ("\n");
-
- tty_printf (_("To be revoked by:\n"));
- print_seckey_info (sk);
-
- if(pk->revkey[i].class&0x40)
- tty_printf(_("(This is a sensitive revocation key)\n"));
- tty_printf("\n");
-
- if( !cpr_get_answer_is_yes("gen_desig_revoke.okay",
- _("Create a revocation certificate for this key? ")) )
- continue;
-
- /* get the reason for the revocation (this is always v4) */
- reason = ask_revocation_reason( 1, 0, 1 );
- if( !reason )
- continue;
-
- rc = check_secret_key( sk, 0 );
- if( rc )
- continue;
-
- if( !opt.armor )
- tty_printf(_("ASCII armored output forced.\n"));
-
- if( (rc = open_outfile( NULL, 0, &out )) )
- goto leave;
-
- afx.what = 1;
- afx.hdrlines = "Comment: A revocation certificate should follow\n";
- iobuf_push_filter( out, armor_filter, &afx );
-
- /* create it */
- rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0,
- 0, 0, 0,
- revocation_reason_build_cb, reason );
- if( rc ) {
- log_error(_("make_keysig_packet failed: %s\n"), gpg_strerror (rc));
- goto leave;
- }
-
- /* Spit out a minimal pk as well, since otherwise there is
- no way to know which key to attach this revocation to.
- Also include the direct key signature that contains
- this revocation key. We're allowed to include
- sensitive revocation keys along with a revocation, as
- this may be the only time the recipient has seen it.
- Note that this means that if we have multiple different
- sensitive revocation keys in a given direct key
- signature, we're going to include them all here. This
- is annoying, but the good outweighs the bad, since
- without including this a sensitive revoker can't really
- do their job. People should not include multiple
- sensitive revocation keys in one signature: 2440 says
- "Note that it may be appropriate to isolate this
- subpacket within a separate signature so that it is not
- combined with other subpackets that need to be
- exported." -dms */
-
- while(!revkey)
- {
- KBNODE signode;
-
- signode=find_next_kbnode(node,PKT_SIGNATURE);
- if(!signode)
- break;
-
- node=signode;
-
- if(keyid[0]==signode->pkt->pkt.signature->keyid[0] &&
- keyid[1]==signode->pkt->pkt.signature->keyid[1] &&
- IS_KEY_SIG(signode->pkt->pkt.signature))
- {
- int j;
-
- for(j=0;j<signode->pkt->pkt.signature->numrevkeys;j++)
- {
- if(pk->revkey[i].class==
- signode->pkt->pkt.signature->revkey[j]->class &&
- pk->revkey[i].algid==
- signode->pkt->pkt.signature->revkey[j]->algid &&
- memcmp(pk->revkey[i].fpr,
- signode->pkt->pkt.signature->revkey[j]->fpr,
- MAX_FINGERPRINT_LEN)==0)
- {
- revkey=signode->pkt->pkt.signature;
- break;
- }
- }
- }
- }
-
- if(!revkey)
- BUG();
-
- rc=export_minimal_pk(out,keyblock,sig,revkey);
- if(rc)
- goto leave;
-
- /* and issue a usage notice */
- tty_printf(_("Revocation certificate created.\n"));
- break;
- }
- }
-
- if(!any)
- log_error(_("no revocation keys found for `%s'\n"),uname);
-
- leave:
- if( pk )
- free_public_key( pk );
- if( sk )
- free_secret_key( sk );
- if( sig )
- free_seckey_enc( sig );
-
- if( rc )
- iobuf_cancel(out);
- else
- iobuf_close(out);
- release_revocation_reason_info( reason );
- return rc;
-}
-
-
-/****************
- * Generate a revocation certificate for UNAME
- */
-int
-gen_revoke( const char *uname )
-{
- int rc = 0;
- armor_filter_context_t afx;
- PACKET pkt;
- PKT_secret_key *sk; /* used as pointer into a kbnode */
- PKT_public_key *pk = NULL;
- PKT_signature *sig = NULL;
- u32 sk_keyid[2];
- iobuf_t out = NULL;
- KBNODE keyblock = NULL, pub_keyblock = NULL;
- KBNODE node;
- KEYDB_HANDLE kdbhd;
- struct revocation_reason_info *reason = NULL;
- KEYDB_SEARCH_DESC desc;
-
- if( opt.batch ) {
- log_error(_("sorry, can't do this in batch mode\n"));
- return GPG_ERR_GENERAL;
- }
-
- memset( &afx, 0, sizeof afx);
- init_packet( &pkt );
-
- /* search the userid:
- * We don't want the whole getkey stuff here but the entire keyblock
- */
- kdbhd = keydb_new (1);
- classify_user_id (uname, &desc);
- rc = desc.mode? keydb_search (kdbhd, &desc, 1) : GPG_ERR_INV_USER_ID;
- if (rc) {
- log_error (_("secret key `%s' not found: %s\n"),
- uname, gpg_strerror (rc));
- goto leave;
- }
-
- rc = keydb_get_keyblock (kdbhd, &keyblock );
- if( rc ) {
- log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) );
- goto leave;
- }
-
- /* get the keyid from the keyblock */
- node = find_kbnode( keyblock, PKT_SECRET_KEY );
- if( !node )
- BUG ();
-
- /* fixme: should make a function out of this stuff,
- * it's used all over the source */
- sk = node->pkt->pkt.secret_key;
- keyid_from_sk( sk, sk_keyid );
- print_seckey_info (sk);
-
- pk = xcalloc (1, sizeof *pk );
-
- /* FIXME: We should get the public key direct from the secret one */
-
- pub_keyblock=get_pubkeyblock(sk_keyid);
- if(!pub_keyblock)
- {
- log_error(_("no corresponding public key: %s\n"), gpg_strerror (rc) );
- goto leave;
- }
-
- node=find_kbnode(pub_keyblock,PKT_PUBLIC_KEY);
- if(!node)
- BUG();
-
- pk=node->pkt->pkt.public_key;
-
- if( cmp_public_secret_key( pk, sk ) ) {
- log_error(_("public key does not match secret key!\n") );
- rc = GPG_ERR_GENERAL;
- goto leave;
- }
-
- tty_printf("\n");
- if( !cpr_get_answer_is_yes("gen_revoke.okay",
- _("Create a revocation certificate for this key? ")) ){
- rc = 0;
- goto leave;
- }
-
- if(sk->version>=4 || opt.force_v4_certs) {
- /* get the reason for the revocation */
- reason = ask_revocation_reason( 1, 0, 1 );
- if( !reason ) { /* user decided to cancel */
- rc = 0;
- goto leave;
- }
- }
-
- switch( is_secret_key_protected( sk ) ) {
- case -1:
- log_error(_("unknown protection algorithm\n"));
- rc = GPG_ERR_PUBKEY_ALGO;
- break;
- case 0:
- tty_printf(_("NOTE: This key is not protected!\n"));
- break;
- default:
- rc = check_secret_key( sk, 0 );
- break;
- }
- if( rc )
- goto leave;
-
-
- if( !opt.armor )
- tty_printf(_("ASCII armored output forced.\n"));
-
- if( (rc = open_outfile( NULL, 0, &out )) )
- goto leave;
-
- afx.what = 1;
- afx.hdrlines = "Comment: A revocation certificate should follow\n";
- iobuf_push_filter( out, armor_filter, &afx );
-
- /* create it */
- rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0,
- opt.force_v4_certs?4:0, 0, 0,
- revocation_reason_build_cb, reason );
- if( rc ) {
- log_error(_("make_keysig_packet failed: %s\n"), gpg_strerror (rc));
- goto leave;
- }
-
- if(PGP2 || PGP6 || PGP7 || PGP8)
- {
- /* Use a minimal pk for PGPx mode, since PGP can't import bare
- revocation certificates. */
- rc=export_minimal_pk(out,pub_keyblock,sig,NULL);
- if(rc)
- goto leave;
- }
- else
- {
- init_packet( &pkt );
- pkt.pkttype = PKT_SIGNATURE;
- pkt.pkt.signature = sig;
-
- rc = build_packet( out, &pkt );
- if( rc ) {
- log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
- goto leave;
- }
- }
-
- /* and issue a usage notice */
- tty_printf(_("Revocation certificate created.\n\n"
-"Please move it to a medium which you can hide away; if Mallory gets\n"
-"access to this certificate he can use it to make your key unusable.\n"
-"It is smart to print this certificate and store it away, just in case\n"
-"your media become unreadable. But have some caution: The print system of\n"
-"your machine might store the data and make it available to others!\n"));
-
- leave:
- if( sig )
- free_seckey_enc( sig );
- release_kbnode( keyblock );
- release_kbnode( pub_keyblock );
- keydb_release (kdbhd);
- if( rc )
- iobuf_cancel(out);
- else
- iobuf_close(out);
- release_revocation_reason_info( reason );
- return rc;
-}
-
-
-
-struct revocation_reason_info *
-ask_revocation_reason( int key_rev, int cert_rev, int hint )
-{
- int code=-1;
- char *description = NULL;
- struct revocation_reason_info *reason;
- const char *text_0 = _("No reason specified");
- const char *text_1 = _("Key has been compromised");
- const char *text_2 = _("Key is superseded");
- const char *text_3 = _("Key is no longer used");
- const char *text_4 = _("User ID is no longer valid");
- const char *code_text = NULL;
-
- do {
- code=-1;
- xfree (description);
- description = NULL;
-
- tty_printf(_("Please select the reason for the revocation:\n"));
- tty_printf( " 0 = %s\n", text_0 );
- if( key_rev )
- tty_printf(" 1 = %s\n", text_1 );
- if( key_rev )
- tty_printf(" 2 = %s\n", text_2 );
- if( key_rev )
- tty_printf(" 3 = %s\n", text_3 );
- if( cert_rev )
- tty_printf(" 4 = %s\n", text_4 );
- tty_printf( " Q = %s\n", _("Cancel") );
- if( hint )
- tty_printf(_("(Probably you want to select %d here)\n"), hint );
-
- while(code==-1) {
- int n;
- char *answer = cpr_get("ask_revocation_reason.code",
- _("Your decision? "));
- trim_spaces( answer );
- cpr_kill_prompt();
- if( *answer == 'q' || *answer == 'Q')
- return NULL; /* cancel */
- if( hint && !*answer )
- n = hint;
- else if(!digitp( answer ) )
- n = -1;
- else
- n = atoi(answer);
- xfree (answer);
- if( n == 0 ) {
- code = 0x00; /* no particular reason */
- code_text = text_0;
- }
- else if( key_rev && n == 1 ) {
- code = 0x02; /* key has been compromised */
- code_text = text_1;
- }
- else if( key_rev && n == 2 ) {
- code = 0x01; /* key is superseded */
- code_text = text_2;
- }
- else if( key_rev && n == 3 ) {
- code = 0x03; /* key is no longer used */
- code_text = text_3;
- }
- else if( cert_rev && n == 4 ) {
- code = 0x20; /* uid is no longer valid */
- code_text = text_4;
- }
- else
- tty_printf(_("Invalid selection.\n"));
- }
-
- tty_printf(_("Enter an optional description; "
- "end it with an empty line:\n") );
- for(;;) {
- char *answer = cpr_get("ask_revocation_reason.text", "> " );
- trim_trailing_ws( answer, strlen(answer) );
- cpr_kill_prompt();
- if( !*answer ) {
- xfree (answer);
- break;
- }
-
- {
- char *p = make_printable_string( answer, strlen(answer), 0 );
- xfree (answer);
- answer = p;
- }
-
- if( !description )
- description = xstrdup (answer);
- else {
- char *p = xmalloc ( strlen(description) + strlen(answer) + 2 );
- strcpy(stpcpy(stpcpy( p, description),"\n"),answer);
- xfree (description);
- description = p;
- }
- xfree (answer);
- }
-
- tty_printf(_("Reason for revocation: %s\n"), code_text );
- if( !description )
- tty_printf(_("(No description given)\n") );
- else
- tty_printf("%s\n", description );
-
- } while( !cpr_get_answer_is_yes("ask_revocation_reason.okay",
- _("Is this okay? ")) );
-
- reason = xmalloc ( sizeof *reason );
- reason->code = code;
- reason->desc = description;
- return reason;
-}
-
-void
-release_revocation_reason_info( struct revocation_reason_info *reason )
-{
- if( reason ) {
- xfree ( reason->desc );
- xfree ( reason );
- }
-}
diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c
deleted file mode 100644
index 7356cb224..000000000
--- a/g10/seckey-cert.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/* seckey-cert.c - secret key certificate packet handling
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "memory.h"
-#include "packet.h"
-#include "mpi.h"
-#include "keydb.h"
-#include "cipher.h"
-#include "main.h"
-#include "options.h"
-#include "i18n.h"
-#include "status.h"
-#include "pkglue.h"
-
-static int
-do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
- int *canceled )
-{
- byte *buffer;
- u16 csum=0;
- int i, res;
- unsigned nbytes;
- gpg_error_t rc;
-
- if( sk->is_protected ) { /* remove the protection */
- DEK *dek = NULL;
- u32 keyid[4]; /* 4! because we need two of them */
- CIPHER_HANDLE cipher_hd=NULL;
- PKT_secret_key *save_sk;
-
- if( sk->protect.s2k.mode == 1001 ) {
- log_info(_("secret key parts are not available\n"));
- return GPG_ERR_GENERAL;
- }
- if( sk->protect.algo == CIPHER_ALGO_NONE )
- BUG();
- if( openpgp_cipher_test_algo( sk->protect.algo ) ) {
- log_info(_("protection algorithm %d%s is not supported\n"),
- sk->protect.algo,sk->protect.algo==1?" (IDEA)":"" );
- if (sk->protect.algo==CIPHER_ALGO_IDEA)
- {
- write_status (STATUS_RSA_OR_IDEA);
- idea_cipher_warn (0);
- }
- return GPG_ERR_CIPHER_ALGO;
- }
- keyid_from_sk( sk, keyid );
- keyid[2] = keyid[3] = 0;
- if( !sk->is_primary ) {
- keyid[2] = sk->main_keyid[0];
- keyid[3] = sk->main_keyid[1];
- }
- dek = passphrase_to_dek( keyid, sk->pubkey_algo, sk->protect.algo,
- &sk->protect.s2k, mode,
- tryagain_text, canceled );
- if (!dek && canceled && *canceled)
- return GPG_ERR_GENERAL;
-
- rc = gcry_cipher_open (&cipher_hd, sk->protect.algo,
- GCRY_CIPHER_MODE_CFB,
- GCRY_CIPHER_SECURE
- | (sk->protect.algo >= 100 ?
- 0 : GCRY_CIPHER_ENABLE_SYNC));
- if (rc)
- log_fatal ("cipher open failed: %s\n", gpg_strerror (rc) );
-
- rc = gcry_cipher_setkey (cipher_hd, dek->key, dek->keylen);
- if (rc)
- log_fatal ("set key failed: %s\n", gpg_strerror (rc) );
-
- xfree (dek);
- save_sk = copy_secret_key( NULL, sk );
- gcry_cipher_setiv (cipher_hd, sk->protect.iv, sk->protect.ivlen);
- csum = 0;
- if( sk->version >= 4 ) {
- int ndata;
- unsigned int ndatabits;
- byte *p, *data;
- u16 csumc = 0;
-
- i = pubkey_get_npkey(sk->pubkey_algo);
- assert( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE ));
- p = gcry_mpi_get_opaque( sk->skey[i], &ndatabits );
- ndata = (ndatabits+7)/8;
- if ( ndata > 1 )
- csumc = p[ndata-2] << 8 | p[ndata-1];
- data = gcry_xmalloc_secure ( ndata );
- gcry_cipher_decrypt( cipher_hd, data, ndata, p, ndata );
- gcry_mpi_release ( sk->skey[i] ); sk->skey[i] = NULL ;
- p = data;
- if (sk->protect.sha1chk) {
- /* This is the new SHA1 checksum method to detect
- tampering with the key as used by the Klima/Rosa
- attack */
- sk->csum = 0;
- csum = 1;
- if( ndata < 20 )
- log_error("not enough bytes for SHA-1 checksum\n");
- else {
- gcry_md_hd_t h;
-
- if ( gcry_md_open (&h, DIGEST_ALGO_SHA1, 1))
- BUG(); /* algo not available */
- gcry_md_write (h, data, ndata - 20);
- gcry_md_final (h);
- if (!memcmp (gcry_md_read (h, DIGEST_ALGO_SHA1),
- data + ndata - 20, 20) ) {
- /* digest does match. We have to keep the old
- style checksum in sk->csum, so that the
- test used for unprotected keys does work.
- This test gets used when we are adding new
- keys. */
- sk->csum = csum = checksum (data, ndata-20);
- }
- gcry_md_close (h);
- }
- }
- else {
- if( ndata < 2 ) {
- log_error("not enough bytes for checksum\n");
- sk->csum = 0;
- csum = 1;
- }
- else {
- csum = checksum( data, ndata-2);
- sk->csum = data[ndata-2] << 8 | data[ndata-1];
- if ( sk->csum != csum ) {
- /* This is a PGP 7.0.0 workaround */
- sk->csum = csumc; /* take the encrypted one */
- }
- }
- }
-
- /* must check it here otherwise the mpi_read_xx would fail
- because the length may have an arbitrary value */
- if( sk->csum == csum ) {
- for( ; i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
- assert( gcry_is_secure( p ) );
- res = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_PGP,
- p, ndata, &nbytes);
- if( res )
- log_bug ("gcry_mpi_scan failed in do_check: %s\n",
- gpg_strerror (res));
- ndata -= nbytes;
- p += nbytes;
- }
- /* Note: at this point ndata should be 2 for a simple
- checksum or 20 for the sha1 digest */
- }
- xfree (data);
- }
- else {
- for(i=pubkey_get_npkey(sk->pubkey_algo);
- i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
- byte *p;
- int ndata;
- unsigned int ndatabits;
-
- assert( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
- p = gcry_mpi_get_opaque( sk->skey[i], &ndatabits );
- ndata = (ndatabits+7)/8;
- assert (ndata >= 2);
- assert (ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2);
- buffer = gcry_xmalloc_secure (ndata);
- gcry_cipher_sync (cipher_hd);
- buffer[0] = p[0];
- buffer[1] = p[1];
- gcry_cipher_decrypt (cipher_hd, buffer+2, ndata-2,
- p+2, ndata-2);
- csum += checksum (buffer, ndata);
- gcry_mpi_release (sk->skey[i]);
- res = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_USG,
- buffer, ndata, &ndata );
- if( res )
- log_bug ("gcry_mpi_scan failed in do_check: %s\n",
- gpg_strerror (res));
-
- assert (sk->skey[i]);
- xfree (buffer);
-/* csum += checksum_mpi (sk->skey[i]); */
- }
- }
- gcry_cipher_close (cipher_hd);
- /* now let's see whether we have used the right passphrase */
- if( csum != sk->csum ) {
- copy_secret_key( sk, save_sk );
- passphrase_clear_cache ( keyid, sk->pubkey_algo );
- free_secret_key( save_sk );
- return gpg_error (GPG_ERR_BAD_PASSPHRASE);
- }
- /* the checksum may fail, so we also check the key itself */
- res = pk_check_secret_key (sk->pubkey_algo, sk->skey);
- if (res) {
- copy_secret_key( sk, save_sk );
- passphrase_clear_cache ( keyid, sk->pubkey_algo );
- free_secret_key( save_sk );
- return gpg_error (GPG_ERR_BAD_PASSPHRASE);
- }
- free_secret_key( save_sk );
- sk->is_protected = 0;
- }
- else { /* not protected, assume it is okay if the checksum is okay */
- csum = 0;
- for(i=pubkey_get_npkey(sk->pubkey_algo);
- i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
- csum += checksum_mpi( sk->skey[i] );
- }
- if( csum != sk->csum )
- return GPG_ERR_CHECKSUM;
- }
-
- return 0;
-}
-
-
-
-/****************
- * Check the secret key
- * Ask up to 3 (or n) times for a correct passphrase
- * If n is negative, disable the key info prompt and make n=abs(n)
- */
-int
-check_secret_key( PKT_secret_key *sk, int n )
-{
- int rc = gpg_error (GPG_ERR_BAD_PASSPHRASE);
- int i,mode;
-
- if (sk && sk->is_protected && sk->protect.s2k.mode == 1002)
- return 0; /* Let the scdaemon handle it. */
-
- if(n<0)
- {
- n=abs(n);
- mode=1;
- }
- else
- mode=0;
-
- if( n < 1 )
- n = (opt.batch && !opt.use_agent)? 1 : 3; /* use the default value */
-
- for(i=0; i < n && gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE; i++ ) {
- int canceled = 0;
- const char *tryagain = NULL;
- if (i) {
- tryagain = N_("Invalid passphrase; please try again");
- log_info (_("%s ...\n"), _(tryagain));
- }
- rc = do_check( sk, tryagain, mode, &canceled );
- if( gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
- && is_status_enabled() ) {
- u32 kid[2];
- char buf[50];
-
- keyid_from_sk( sk, kid );
- sprintf(buf, "%08lX%08lX", (ulong)kid[0], (ulong)kid[1]);
- write_status_text( STATUS_BAD_PASSPHRASE, buf );
- }
- if( have_static_passphrase() || canceled)
- break;
- }
-
- if( !rc )
- write_status( STATUS_GOOD_PASSPHRASE );
-
- return rc;
-}
-
-/****************
- * check whether the secret key is protected.
- * Returns: 0 not protected, -1 on error or the protection algorithm
- * -2 indicates a card stub.
- */
-int
-is_secret_key_protected( PKT_secret_key *sk )
-{
- return sk->is_protected?
- sk->protect.s2k.mode == 1002? -2
- : sk->protect.algo : 0;
-}
-
-
-
-/****************
- * Protect the secret key with the passphrase from DEK
- */
-int
-protect_secret_key( PKT_secret_key *sk, DEK *dek )
-{
- int i,j, rc = 0;
- byte *buffer;
- unsigned nbytes;
- u16 csum;
-
- if( !dek )
- return 0;
-
- if( !sk->is_protected ) { /* okay, apply the protection */
- gcry_cipher_hd_t cipher_hd=NULL;
-
- if( openpgp_cipher_test_algo( sk->protect.algo ) )
- {
- rc = gpg_error (GPG_ERR_CIPHER_ALGO); /* unsupport
- protection
- algorithm */
- }
- else {
- print_cipher_algo_note( sk->protect.algo );
- rc = gcry_cipher_open (&cipher_hd, sk->protect.algo,
- GCRY_CIPHER_MODE_CFB,
- GCRY_CIPHER_SECURE
- | (sk->protect.algo >= 100 ?
- 0 : GCRY_CIPHER_ENABLE_SYNC) );
- if (rc)
- BUG();
- if( gcry_cipher_setkey( cipher_hd, dek->key, dek->keylen ) )
- log_info(_("WARNING: Weak key detected"
- " - please change passphrase again.\n"));
- sk->protect.ivlen = gcry_cipher_get_algo_blklen(sk->protect.algo);
- assert( sk->protect.ivlen <= DIM(sk->protect.iv) );
- if( sk->protect.ivlen != 8 && sk->protect.ivlen != 16 )
- BUG(); /* yes, we are very careful */
- gcry_create_nonce (sk->protect.iv, sk->protect.ivlen);
- gcry_cipher_setiv( cipher_hd, sk->protect.iv, sk->protect.ivlen );
- if( sk->version >= 4 ) {
- unsigned char *bufarr[PUBKEY_MAX_NSKEY];
- unsigned narr[PUBKEY_MAX_NSKEY];
- unsigned nbits[PUBKEY_MAX_NSKEY];
- int ndata=0;
- byte *p, *data;
-
- for(j=0, i = pubkey_get_npkey(sk->pubkey_algo);
- i < pubkey_get_nskey(sk->pubkey_algo); i++, j++ ) {
- assert( !gcry_mpi_get_flag( sk->skey[i],
- GCRYMPI_FLAG_OPAQUE ));
-
- if( gcry_mpi_aprint( GCRYMPI_FMT_USG, bufarr+j,
- narr+j, sk->skey[i]))
- BUG();
-
- nbits[j] = gcry_mpi_get_nbits( sk->skey[i] );
- ndata += narr[j] + 2;
- }
- for( ; j < PUBKEY_MAX_NSKEY; j++ )
- bufarr[j] = NULL;
- ndata += opt.simple_sk_checksum? 2 : 20; /* for checksum */
-
- data = xmalloc_secure ( ndata );
- p = data;
- for(j=0; j < PUBKEY_MAX_NSKEY && bufarr[j]; j++ ) {
- p[0] = nbits[j] >> 8 ;
- p[1] = nbits[j];
- p += 2;
- memcpy(p, bufarr[j], narr[j] );
- p += narr[j];
- xfree (bufarr[j]);
- }
-
- if (opt.simple_sk_checksum) {
- log_info (_("generating the deprecated 16-bit checksum"
- " for secret key protection\n"));
- csum = checksum( data, ndata-2);
- sk->csum = csum;
- *p++ = csum >> 8;
- *p++ = csum;
- sk->protect.sha1chk = 0;
- }
- else {
- gcry_md_hd_t h;
-
- if (gcry_md_open (&h, GCRY_MD_SHA1, 1))
- BUG(); /* algo not available */
- gcry_md_write (h, data, ndata - 20);
- gcry_md_final (h);
- memcpy (p, gcry_md_read (h, GCRY_MD_SHA1), 20);
- p += 20;
- gcry_md_close (h);
- sk->csum = csum = 0;
- sk->protect.sha1chk = 1;
- }
- assert( p == data+ndata );
-
- gcry_cipher_encrypt( cipher_hd, data, ndata, NULL, 0 );
- for(i = pubkey_get_npkey(sk->pubkey_algo);
- i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
- gcry_mpi_release ( sk->skey[i] );
- sk->skey[i] = NULL;
- }
- i = pubkey_get_npkey(sk->pubkey_algo);
- sk->skey[i] = gcry_mpi_set_opaque(NULL, data, ndata*8);
- }
- else {
- csum = 0;
- for(i=pubkey_get_npkey(sk->pubkey_algo);
- i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
- byte *data;
- unsigned int nbits;
-
- csum += checksum_mpi (sk->skey[i]);
- if( gcry_mpi_aprint( GCRYMPI_FMT_USG, &buffer,
- &nbytes, sk->skey[i] ) )
- BUG();
- gcry_cipher_sync (cipher_hd);
- assert (!gcry_mpi_get_flag( sk->skey[i],
- GCRYMPI_FLAG_OPAQUE ));
- data = xmalloc (nbytes+2);
- nbits = gcry_mpi_get_nbits (sk->skey[i]);
- assert (nbytes == (nbits + 7)/8);
- data[0] = nbits >> 8;
- data[1] = nbits;
- gcry_cipher_encrypt (cipher_hd, data+2, nbytes,
- buffer, nbytes);
- xfree ( buffer );
-
- gcry_mpi_release (sk->skey[i]);
- sk->skey[i] = gcry_mpi_set_opaque (NULL, data,
- (nbytes+2)*8);
- }
- sk->csum = csum;
- }
- sk->is_protected = 1;
- gcry_cipher_close( cipher_hd );
- }
- }
- return rc;
-}
diff --git a/g10/seskey.c b/g10/seskey.c
deleted file mode 100644
index be2535ace..000000000
--- a/g10/seskey.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/* seskey.c - make sesssion keys etc.
- * Copyright (C) 1998, 1999, 2000, 2001, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "cipher.h"
-#include "mpi.h"
-#include "main.h"
-#include "i18n.h"
-#include "options.h"
-
-/****************
- * Make a session key and put it into DEK
- */
-void
-make_session_key( DEK *dek )
-{
- gcry_cipher_hd_t chd;
- int i, rc;
-
- dek->keylen = gcry_cipher_get_algo_keylen (dek->algo);
-
- if (gcry_cipher_open (&chd, dek->algo, GCRY_CIPHER_MODE_CFB,
- (GCRY_CIPHER_SECURE
- | (dek->algo >= 100 ?
- 0 : GCRY_CIPHER_ENABLE_SYNC))) )
- BUG();
-
- gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM );
- for (i=0; i < 16; i++ )
- {
- rc = gcry_cipher_setkey (chd, dek->key, dek->keylen);
- if (!rc)
- {
- gcry_cipher_close (chd);
- return;
- }
- if (gpg_err_code (rc) != GPG_ERR_WEAK_KEY)
- BUG();
- log_info (_("weak key created - retrying\n") );
- /* Renew the session key until we get a non-weak key. */
- gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM );
- }
-
- log_fatal (_("cannot avoid weak key for symmetric cipher; "
- "tried %d times!\n"), i);
-}
-
-
-/****************
- * Encode the session key. NBITS is the number of bits which should be used
- * for packing the session key.
- * returns: A mpi with the session key (caller must free)
- */
-gcry_mpi_t
-encode_session_key (DEK *dek, unsigned int nbits)
-{
- int nframe = (nbits+7) / 8;
- byte *p;
- byte *frame;
- int i,n;
- u16 csum;
- gcry_mpi_t a;
-
- /* the current limitation is that we can only use a session key
- * whose length is a multiple of BITS_PER_MPI_LIMB
- * I think we can live with that.
- */
- if( dek->keylen + 7 > nframe || !nframe )
- log_bug("can't encode a %d bit key in a %d bits frame\n",
- dek->keylen*8, nbits );
-
- /* We encode the session key in this way:
- *
- * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes)
- *
- * (But how can we store the leading 0 - the external representaion
- * of MPIs doesn't allow leading zeroes =:-)
- *
- * RND are non-zero random bytes.
- * A is the cipher algorithm
- * DEK is the encryption key (session key) length k depends on the
- * cipher algorithm (20 is used with blowfish160).
- * CSUM is the 16 bit checksum over the DEK
- */
- csum = 0;
- for( p = dek->key, i=0; i < dek->keylen; i++ )
- csum += *p++;
-
- frame = gcry_xmalloc_secure ( nframe );
- n = 0;
- frame[n++] = 0;
- frame[n++] = 2;
- i = nframe - 6 - dek->keylen;
- assert( i > 0 );
- p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
- /* replace zero bytes by new values */
- for(;;) {
- int j, k;
- byte *pp;
-
- /* count the zero bytes */
- for(j=k=0; j < i; j++ )
- if( !p[j] )
- k++;
- if( !k )
- break; /* okay: no zero bytes */
- k += k/128; /* better get some more */
- pp = gcry_random_bytes_secure( k, GCRY_STRONG_RANDOM);
- for(j=0; j < i && k ; j++ )
- if( !p[j] )
- p[j] = pp[--k];
- xfree (pp);
- }
- memcpy( frame+n, p, i );
- xfree (p);
- n += i;
- frame[n++] = 0;
- frame[n++] = dek->algo;
- memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen;
- frame[n++] = csum >>8;
- frame[n++] = csum;
- assert (n == nframe);
-
- if (DBG_CIPHER)
- log_printhex ("encoded session key:", frame, nframe );
-
- if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe))
- BUG();
- xfree (frame);
- return a;
-}
-
-
-static gcry_mpi_t
-do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits,
- const byte *asn, size_t asnlen, int v3compathack )
-{
- int nframe = (nbits+7) / 8;
- byte *frame;
- int i,n;
- gcry_mpi_t a;
-
- if( len + asnlen + 4 > nframe )
- log_bug("can't encode a %d bit MD into a %d bits frame\n",
- (int)(len*8), (int)nbits);
-
- /* We encode the MD in this way:
- *
- * 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
- *
- * PAD consists of FF bytes.
- */
- frame = gcry_md_is_secure (md)? xmalloc_secure (nframe): xmalloc (nframe);
- n = 0;
- frame[n++] = 0;
- frame[n++] = v3compathack? algo : 1; /* block type */
- i = nframe - len - asnlen -3 ;
- assert( i > 1 );
- memset( frame+n, 0xff, i ); n += i;
- frame[n++] = 0;
- memcpy( frame+n, asn, asnlen ); n += asnlen;
- memcpy( frame+n, gcry_md_read (md, algo), len ); n += len;
- assert( n == nframe );
- if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe ))
- BUG();
- xfree (frame);
- return a;
-}
-
-
-/****************
- * Encode a message digest into an MPI.
- * v3compathack is used to work around a bug in old GnuPG versions
- * which did put the algo identifier inseatd of the block type 1 into
- * the encoded value. Setting this flag forces the old behaviour.
- */
-gcry_mpi_t
-encode_md_value (int pubkey_algo, gcry_md_hd_t md, int hash_algo,
- unsigned int nbits, int v3compathack )
-{
- int algo = hash_algo? hash_algo : gcry_md_get_algo (md);
- gcry_mpi_t frame;
-
- if (pubkey_algo == GCRY_PK_DSA)
- {
- size_t n = gcry_md_get_algo_dlen(hash_algo);
- if (n != 20)
- {
- log_error (_("DSA requires the use of a 160 bit hash algorithm\n"));
- return NULL;
- }
- if (gcry_mpi_scan( &frame, GCRYMPI_FMT_USG,
- gcry_md_read (md, hash_algo), n, &n ) )
- BUG();
- }
- else
- {
- gpg_error_t rc;
- byte *asn;
- size_t asnlen;
-
- rc = gcry_md_algo_info( algo, GCRYCTL_GET_ASNOID, NULL, &asnlen);
- if (rc)
- log_fatal("can't get OID of algo %d: %s\n",
- algo, gpg_strerror (rc));
- asn = xmalloc (asnlen);
- if( gcry_md_algo_info( algo, GCRYCTL_GET_ASNOID, asn, &asnlen ) )
- BUG();
- frame = do_encode_md( md, algo, gcry_md_get_algo_dlen( algo ),
- nbits, asn, asnlen, v3compathack );
- xfree (asn);
- }
- return frame;
-}
-
-
-
-
-
-
diff --git a/g10/sig-check.c b/g10/sig-check.c
deleted file mode 100644
index b0c89cba3..000000000
--- a/g10/sig-check.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/* sig-check.c - Check a signature
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "packet.h"
-#include "memory.h"
-#include "mpi.h"
-#include "keydb.h"
-#include "cipher.h"
-#include "main.h"
-#include "status.h"
-#include "i18n.h"
-#include "options.h"
-#include "pkglue.h"
-
-struct cmp_help_context_s {
- PKT_signature *sig;
- MD_HANDLE md;
-};
-
-
-static int do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
- int *r_expired, int *r_revoked, PKT_public_key *ret_pk);
-
-/****************
- * Check the signature which is contained in SIG.
- * The MD_HANDLE should be currently open, so that this function
- * is able to append some data, before finalizing the digest.
- */
-int
-signature_check( PKT_signature *sig, MD_HANDLE digest )
-{
- return signature_check2( sig, digest, NULL, NULL, NULL, NULL );
-}
-
-int
-signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate,
- int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
-{
- PKT_public_key *pk = xcalloc (1, sizeof *pk );
- int rc=0;
-
- /* Sanity check that the md has a context for the hash that the
- sig is expecting. This can happen if a onepass sig header does
- not match the actual sig, and also if the clearsign "Hash:"
- header is missing or does not match the actual sig. */
-
- if(!gcry_md_is_enabled (digest,sig->digest_algo)) {
- log_info(_("WARNING: signature digest conflict in message\n"));
- rc=GPG_ERR_GENERAL;
- }
- else if( get_pubkey( pk, sig->keyid ) )
- rc = GPG_ERR_NO_PUBKEY;
- else if(!pk->is_valid && !pk->is_primary)
- rc=GPG_ERR_BAD_PUBKEY; /* you cannot have a good sig from an
- invalid subkey */
- else {
- if (r_expiredate)
- *r_expiredate = pk->expiredate;
- rc = do_check( pk, sig, digest, r_expired, r_revoked, ret_pk );
- }
-
- free_public_key( pk );
-
- if( !rc && sig->sig_class < 2 && is_status_enabled() ) {
- /* This signature id works best with DLP algorithms because
- * they use a random parameter for every signature. Instead of
- * this sig-id we could have also used the hash of the document
- * and the timestamp, but the drawback of this is, that it is
- * not possible to sign more than one identical document within
- * one second. Some remote batch processing applications might
- * like this feature here */
- gcry_md_hd_t md;
- u32 a = sig->timestamp;
- int i, nsig = pubkey_get_nsig( sig->pubkey_algo );
- byte *p, *buffer;
-
- gcry_md_open (&md, GCRY_MD_RMD160, 0);
- gcry_md_putc( digest, sig->pubkey_algo );
- gcry_md_putc( digest, sig->digest_algo );
- gcry_md_putc( digest, (a >> 24) & 0xff );
- gcry_md_putc( digest, (a >> 16) & 0xff );
- gcry_md_putc( digest, (a >> 8) & 0xff );
- gcry_md_putc( digest, a & 0xff );
- for(i=0; i < nsig; i++ ) {
- size_t n;
- unsigned char *tmp;
-
- if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &tmp, &n, sig->data[i]))
- BUG();
-
- gcry_md_write (md, tmp, n);
- xfree (tmp);
- }
- gcry_md_final( md );
- p = make_radix64_string( gcry_md_read( md, 0 ), 20 );
- buffer = xmalloc ( strlen(p) + 60 );
- sprintf( buffer, "%s %s %lu",
- p, strtimestamp( sig->timestamp ), (ulong)sig->timestamp );
- write_status_text( STATUS_SIG_ID, buffer );
- xfree (buffer);
- xfree (p);
- gcry_md_close(md);
- }
-
- return rc;
-}
-
-
-static int
-do_check_messages( PKT_public_key *pk, PKT_signature *sig,
- int *r_expired, int *r_revoked )
-{
- u32 cur_time;
-
- if (r_expired)
- *r_expired = 0;
- if (r_revoked)
- *r_revoked = 0;
- if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
- log_info(_("key %08lX: this is a PGP generated "
- "ElGamal key which is NOT secure for signatures!\n"),
- (ulong)keyid_from_pk(pk,NULL));
- return GPG_ERR_PUBKEY_ALGO;
- }
-
- if( pk->timestamp > sig->timestamp ) {
- ulong d = pk->timestamp - sig->timestamp;
- log_info( d==1
- ? _("public key %08lX is %lu second newer than the signature\n")
- : _("public key %08lX is %lu seconds newer than the signature\n"),
- (ulong)keyid_from_pk(pk,NULL),d );
- if( !opt.ignore_time_conflict )
- return GPG_ERR_TIME_CONFLICT; /* pubkey newer than signature */
- }
-
- cur_time = make_timestamp();
- if( pk->timestamp > cur_time ) {
- ulong d = pk->timestamp - cur_time;
- log_info( d==1 ? _("key %08lX has been created %lu second "
- "in future (time warp or clock problem)\n")
- : _("key %08lX has been created %lu seconds "
- "in future (time warp or clock problem)\n"),
- (ulong)keyid_from_pk(pk,NULL),d );
- if( !opt.ignore_time_conflict )
- return GPG_ERR_TIME_CONFLICT;
- }
-
- if( pk->expiredate && pk->expiredate < cur_time ) {
- char buf[11];
- if (opt.verbose) {
- u32 tmp_kid[2];
-
- keyid_from_pk( pk, tmp_kid );
- log_info(_("NOTE: signature key %08lX expired %s\n"),
- (ulong)tmp_kid[1], asctimestamp( pk->expiredate ) );
- }
- /* SIGEXPIRED is deprecated. Use KEYEXPIRED. */
- sprintf(buf,"%lu",(ulong)pk->expiredate);
- write_status_text(STATUS_KEYEXPIRED,buf);
- write_status(STATUS_SIGEXPIRED);
- if (r_expired)
- *r_expired = 1;
- }
-
- if(pk->is_revoked && r_revoked)
- *r_revoked=1;
-
- return 0;
-}
-
-
-static int
-do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
- int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
-{
- gcry_mpi_t result = NULL;
- int rc=0;
- struct cmp_help_context_s ctx;
-
- if( (rc=do_check_messages(pk,sig,r_expired,r_revoked)) )
- return rc;
- if( (rc=gcry_md_test_algo(sig->digest_algo)) )
- return rc;
- if( (rc=gcry_pk_test_algo(sig->pubkey_algo)) )
- return rc;
-
- /* make sure the digest algo is enabled (in case of a detached
- signature)*/
- gcry_md_enable( digest, sig->digest_algo );
-
- /* complete the digest */
- if( sig->version >= 4 )
- gcry_md_putc( digest, sig->version );
- gcry_md_putc( digest, sig->sig_class );
- if( sig->version < 4 ) {
- u32 a = sig->timestamp;
- gcry_md_putc( digest, (a >> 24) & 0xff );
- gcry_md_putc( digest, (a >> 16) & 0xff );
- gcry_md_putc( digest, (a >> 8) & 0xff );
- gcry_md_putc( digest, a & 0xff );
- }
- else {
- byte buf[6];
- size_t n;
- gcry_md_putc( digest, sig->pubkey_algo );
- gcry_md_putc( digest, sig->digest_algo );
- if( sig->hashed ) {
- n = sig->hashed->len;
- gcry_md_putc (digest, (n >> 8) );
- gcry_md_putc (digest, n );
- gcry_md_write (digest, sig->hashed->data, n);
- n += 6;
- }
- else {
- /* Two octets for the (empty) length of the hashed
- section. */
- gcry_md_putc (digest, 0);
- gcry_md_putc (digest, 0);
- n = 6;
- }
- /* add some magic */
- buf[0] = sig->version;
- buf[1] = 0xff;
- buf[2] = n >> 24;
- buf[3] = n >> 16;
- buf[4] = n >> 8;
- buf[5] = n;
- gcry_md_write( digest, buf, 6 );
- }
- gcry_md_final (digest);
-
- result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
- mpi_get_nbits(pk->pkey[0]), 0 );
- if (!result)
- return GPG_ERR_GENERAL;
- ctx.sig = sig;
- ctx.md = digest;
- rc = pk_verify ( pk->pubkey_algo, result, sig->data, pk->pkey);
- gcry_mpi_release ( result );
- if( (opt.emulate_bugs & EMUBUG_MDENCODE)
- && gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE
- && is_ELGAMAL(pk->pubkey_algo) ) {
- /* In this case we try again because old GnuPG versions didn't encode
- * the hash right. There is no problem with DSA however */
- result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
- mpi_get_nbits(pk->pkey[0]), (sig->version < 5) );
- if (!result)
- rc = GPG_ERR_GENERAL;
- else {
- ctx.sig = sig;
- ctx.md = digest;
- rc = pk_verify (pk->pubkey_algo, result, sig->data, pk->pkey);
- }
- }
-
- if( !rc && sig->flags.unknown_critical ) {
- log_info(_("assuming bad signature from key %08lX "
- "due to an unknown critical bit\n"),
- (ulong)keyid_from_pk(pk,NULL));
- rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
- }
-
- if(!rc && ret_pk)
- copy_public_key(ret_pk,pk);
-
- return rc;
-}
-
-
-static void
-hash_uid_node( KBNODE unode, MD_HANDLE md, PKT_signature *sig )
-{
- PKT_user_id *uid = unode->pkt->pkt.user_id;
-
- assert( unode->pkt->pkttype == PKT_USER_ID );
- if( uid->attrib_data ) {
- if( sig->version >=4 ) {
- byte buf[5];
- buf[0] = 0xd1; /* packet of type 17 */
- buf[1] = uid->attrib_len >> 24; /* always use 4 length bytes */
- buf[2] = uid->attrib_len >> 16;
- buf[3] = uid->attrib_len >> 8;
- buf[4] = uid->attrib_len;
- gcry_md_write( md, buf, 5 );
- }
- gcry_md_write( md, uid->attrib_data, uid->attrib_len );
- }
- else {
- if( sig->version >=4 ) {
- byte buf[5];
- buf[0] = 0xb4; /* indicates a userid packet */
- buf[1] = uid->len >> 24; /* always use 4 length bytes */
- buf[2] = uid->len >> 16;
- buf[3] = uid->len >> 8;
- buf[4] = uid->len;
- gcry_md_write( md, buf, 5 );
- }
- gcry_md_write( md, uid->name, uid->len );
- }
-}
-
-static void
-cache_sig_result ( PKT_signature *sig, int result )
-{
- if ( !result ) {
- sig->flags.checked = 1;
- sig->flags.valid = 1;
- }
- else if ( gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE ) {
- sig->flags.checked = 1;
- sig->flags.valid = 0;
- }
- else {
- sig->flags.checked = 0;
- sig->flags.valid = 0;
- }
-}
-
-
-/* Check the revocation keys to see if any of them have revoked our
- pk. sig is the revocation sig. pk is the key it is on. This code
- will need to be modified if gpg ever becomes multi-threaded. Note
- that this guarantees that a designated revocation sig will never be
- considered valid unless it is actually valid, as well as being
- issued by a revocation key in a valid direct signature. Note that
- this is written so that a revoked revoker can still issue
- revocations: i.e. If A revokes B, but A is revoked, B is still
- revoked. I'm not completely convinced this is the proper behavior,
- but it matches how PGP does it. -dms */
-
-/* Returns 0 if sig is valid (i.e. pk is revoked), non-0 if not
- revoked */
-int
-check_revocation_keys(PKT_public_key *pk,PKT_signature *sig)
-{
- static int busy=0;
- int i,rc=GPG_ERR_GENERAL;
-
- assert(IS_KEY_REV(sig));
- assert((sig->keyid[0]!=pk->keyid[0]) || (sig->keyid[0]!=pk->keyid[1]));
-
- if(busy)
- {
- /* return -1 (i.e. not revoked), but mark the pk as uncacheable
- as we don't really know its revocation status until it is
- checked directly. */
-
- pk->dont_cache=1;
- return rc;
- }
-
- busy=1;
-
- /* printf("looking at %08lX with a sig from %08lX\n",(ulong)pk->keyid[1],
- (ulong)sig->keyid[1]); */
-
- /* is the issuer of the sig one of our revokers? */
- if( !pk->revkey && pk->numrevkeys )
- BUG();
- else
- for(i=0;i<pk->numrevkeys;i++)
- {
- u32 keyid[2];
-
- keyid_from_fingerprint(pk->revkey[i].fpr,MAX_FINGERPRINT_LEN,keyid);
-
- if(keyid[0]==sig->keyid[0] && keyid[1]==sig->keyid[1])
- {
- gcry_md_hd_t md;
-
- gcry_md_open (&md, sig->digest_algo,0);
- hash_public_key(md,pk);
- rc=signature_check(sig,md);
- cache_sig_result(sig,rc);
- break;
- }
- }
-
- busy=0;
-
- return rc;
-}
-
-/****************
- * check the signature pointed to by NODE. This is a key signature.
- * If the function detects a self-signature, it uses the PK from
- * ROOT and does not read any public key.
- */
-int
-check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
-{
- return check_key_signature2(root, node, NULL, NULL, is_selfsig, NULL, NULL);
-}
-
-/* If check_pk is set, then use it to check the signature in node
- rather than getting it from root or the keydb. If ret_pk is set,
- fill in the public key that was used to verify the signature.
- ret_pk is only meaningful when the verification was successful. */
-/* TODO: add r_revoked here as well. It has the same problems as
- r_expiredate and r_expired and the cache. */
-int
-check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
- PKT_public_key *ret_pk, int *is_selfsig,
- u32 *r_expiredate, int *r_expired )
-{
- MD_HANDLE md;
- PKT_public_key *pk;
- PKT_signature *sig;
- int algo;
- int rc;
-
- if( is_selfsig )
- *is_selfsig = 0;
- if( r_expiredate )
- *r_expiredate = 0;
- if( r_expired )
- *r_expired = 0;
- assert( node->pkt->pkttype == PKT_SIGNATURE );
- assert( root->pkt->pkttype == PKT_PUBLIC_KEY );
-
- pk = root->pkt->pkt.public_key;
- sig = node->pkt->pkt.signature;
- algo = sig->digest_algo;
-
- /* check whether we have cached the result of a previous signature check.*/
- if ( !opt.no_sig_cache ) {
- if (sig->flags.checked) { /*cached status available*/
- if( is_selfsig ) {
- u32 keyid[2];
-
- keyid_from_pk( pk, keyid );
- if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
- *is_selfsig = 1;
- }
- /* BUG: This is wrong for non-self-sigs. Needs to be the
- actual pk */
- if((rc=do_check_messages(pk,sig,r_expired,NULL)))
- return rc;
- return sig->flags.valid? 0 : gpg_error (GPG_ERR_BAD_SIGNATURE);
- }
- }
-
- if( (rc=gcry_md_test_algo(algo)) )
- return rc;
-
- if( sig->sig_class == 0x20 ) { /* key revocation */
- u32 keyid[2];
- keyid_from_pk( pk, keyid );
-
- /* is it a designated revoker? */
- if(keyid[0]!=sig->keyid[0] || keyid[1]!=sig->keyid[1])
- rc=check_revocation_keys(pk,sig);
- else
- {
- gcry_md_open (&md, algo, 0 );
- hash_public_key( md, pk );
- rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
- cache_sig_result ( sig, rc );
- gcry_md_close(md);
- }
- }
- else if( sig->sig_class == 0x28 ) { /* subkey revocation */
- KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
-
- if( snode ) {
- gcry_md_open (&md, algo, 0 );
- hash_public_key( md, pk );
- hash_public_key( md, snode->pkt->pkt.public_key );
- rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
- cache_sig_result ( sig, rc );
- gcry_md_close(md);
- }
- else {
- if (opt.verbose)
- log_info (_("key %08lX: no subkey for subkey "
- "revocation signature\n"),
- (ulong)keyid_from_pk (pk, NULL));
- rc = GPG_ERR_SIG_CLASS;
- }
- }
- else if( sig->sig_class == 0x18 ) { /* key binding */
- KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
-
- if( snode ) {
- if( is_selfsig ) { /* does this make sense????? */
- u32 keyid[2]; /* it should always be a selfsig */
-
- keyid_from_pk( pk, keyid );
- if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
- *is_selfsig = 1;
- }
- gcry_md_open (&md, algo, 0 );
- hash_public_key( md, pk );
- hash_public_key( md, snode->pkt->pkt.public_key );
- rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
- cache_sig_result ( sig, rc );
- gcry_md_close(md);
- }
- else {
- if (opt.verbose)
- log_info(_("key %08lX: no subkey for subkey "
- "binding signature\n"),
- (ulong)keyid_from_pk (pk, NULL));
- rc = GPG_ERR_SIG_CLASS;
- }
- }
- else if( sig->sig_class == 0x1f ) { /* direct key signature */
- gcry_md_open (&md, algo, 0 );
- hash_public_key( md, pk );
- rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
- cache_sig_result ( sig, rc );
- gcry_md_close(md);
- }
- else { /* all other classes */
- KBNODE unode = find_prev_kbnode( root, node, PKT_USER_ID );
-
- if( unode ) {
- u32 keyid[2];
-
- keyid_from_pk( pk, keyid );
- gcry_md_open (&md, algo, 0 );
- hash_public_key( md, pk );
- hash_uid_node( unode, md, sig );
- if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
- {
- if( is_selfsig )
- *is_selfsig = 1;
- rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
- }
- else if (check_pk)
- rc=do_check(check_pk,sig,md,r_expired, NULL, ret_pk);
- else
- rc = signature_check2( sig, md, r_expiredate, r_expired,
- NULL, ret_pk);
-
- cache_sig_result ( sig, rc );
- gcry_md_close(md);
- }
- else {
- if (!opt.quiet)
- log_info ("key %08lX: no user ID for key signature packet "
- "of class %02x\n",
- (ulong)keyid_from_pk (pk, NULL), sig->sig_class );
- rc = GPG_ERR_SIG_CLASS;
- }
- }
-
- return rc;
-}
diff --git a/g10/sign.c b/g10/sign.c
deleted file mode 100644
index cd7615c00..000000000
--- a/g10/sign.c
+++ /dev/null
@@ -1,1412 +0,0 @@
-/* sign.c - sign data
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <unistd.h> /* need sleep() */
-
-#include "options.h"
-#include "packet.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "keydb.h"
-#include "memory.h"
-#include "util.h"
-#include "main.h"
-#include "filter.h"
-#include "ttyio.h"
-#include "trustdb.h"
-#include "status.h"
-#include "i18n.h"
-#include "pkglue.h"
-#include "call-agent.h"
-
-
-#ifdef HAVE_DOSISH_SYSTEM
-#define LF "\r\n"
-void __stdcall Sleep(ulong);
-#define sleep(a) Sleep((a)*1000)
-#else
-#define LF "\n"
-#endif
-
-static int recipient_digest_algo=0;
-
-/****************
- * Create a notation. We assume thIt is assumed that the strings in
- * the STRLISTs of the opt struct are already checked to contain only
- * printable data and have a valid NAME=VALUE format.
- */
-static void
-mk_notation_policy_etc( PKT_signature *sig,
- PKT_public_key *pk, PKT_secret_key *sk )
-{
- const char *string;
- char *s=NULL;
- byte *buf;
- unsigned n1, n2;
- STRLIST nd=NULL,pu=NULL;
- struct expando_args args;
-
- memset(&args,0,sizeof(args));
- args.pk=pk;
- args.sk=sk;
-
- /* It is actually impossible to get here when making a v3 key
- signature since keyedit.c:sign_uids will automatically bump a
- signature with a notation or policy url up to v4, but it is
- good to do these checks anyway. */
-
- /* notation data */
- if(IS_SIG(sig) && opt.sig_notation_data)
- {
- if(sig->version<4)
- log_error(_("can't put notation data into v3 (PGP 2.x style) "
- "signatures\n"));
- else
- nd=opt.sig_notation_data;
- }
- else if( IS_CERT(sig) && opt.cert_notation_data )
- {
- if(sig->version<4)
- log_error(_("can't put notation data into v3 (PGP 2.x style) "
- "key signatures\n"));
- else
- nd=opt.cert_notation_data;
- }
-
- for( ; nd; nd = nd->next ) {
- char *expanded;
-
- string = nd->d;
- s = strchr( string, '=' );
- if( !s )
- BUG(); /* we have already parsed this */
- n1 = s - string;
- s++;
-
- expanded=pct_expando(s,&args);
- if(!expanded)
- {
- log_error(_("WARNING: unable to %%-expand notation "
- "(too large). Using unexpanded.\n"));
- expanded=xstrdup (s);
- }
-
- n2 = strlen(expanded);
- buf = xmalloc ( 8 + n1 + n2 );
- buf[0] = 0x80; /* human readable */
- buf[1] = buf[2] = buf[3] = 0;
- buf[4] = n1 >> 8;
- buf[5] = n1;
- buf[6] = n2 >> 8;
- buf[7] = n2;
- memcpy(buf+8, string, n1 );
- memcpy(buf+8+n1, expanded, n2 );
- build_sig_subpkt( sig, SIGSUBPKT_NOTATION
- | ((nd->flags & 1)? SIGSUBPKT_FLAG_CRITICAL:0),
- buf, 8+n1+n2 );
- xfree (expanded);
- xfree (buf);
- }
-
- /* set policy URL */
- if( IS_SIG(sig) && opt.sig_policy_url )
- {
- if(sig->version<4)
- log_error(_("can't put a policy URL into v3 (PGP 2.x style) "
- "signatures\n"));
- else
- pu=opt.sig_policy_url;
- }
- else if( IS_CERT(sig) && opt.cert_policy_url )
- {
- if(sig->version<4)
- log_error(_("can't put a policy URL into v3 key (PGP 2.x style) "
- "signatures\n"));
- else
- pu=opt.cert_policy_url;
- }
-
- for(;pu;pu=pu->next)
- {
- string = pu->d;
-
- s=pct_expando(string,&args);
- if(!s)
- {
- log_error(_("WARNING: unable to %%-expand policy url "
- "(too large). Using unexpanded.\n"));
- s=xstrdup (string);
- }
-
- build_sig_subpkt(sig,SIGSUBPKT_POLICY|
- ((pu->flags & 1)?SIGSUBPKT_FLAG_CRITICAL:0),
- s,strlen(s));
-
- xfree (s);
- }
-
- /* preferred keyserver URL */
- if( IS_SIG(sig) && opt.sig_keyserver_url )
- {
- if(sig->version<4)
- log_info (_("can't put a preferred keyserver URL "
- "into v3 signatures\n"));
- else
- pu=opt.sig_keyserver_url;
- }
-
- for(;pu;pu=pu->next)
- {
- string = pu->d;
-
- s=pct_expando(string,&args);
- if(!s)
- {
- log_error(_("WARNING: unable to %%-expand preferred keyserver URL"
- " (too large). Using unexpanded.\n"));
- s=xstrdup(string);
- }
-
- build_sig_subpkt(sig,SIGSUBPKT_PREF_KS|
- ((pu->flags & 1)?SIGSUBPKT_FLAG_CRITICAL:0),
- s,strlen(s));
-
- xfree(s);
- }
-}
-
-
-/*
- * Helper to hash a user ID packet.
- */
-static void
-hash_uid (MD_HANDLE md, int sigversion, const PKT_user_id *uid)
-{
- if ( sigversion >= 4 ) {
- byte buf[5];
-
- if(uid->attrib_data) {
- buf[0] = 0xd1; /* indicates an attribute packet */
- buf[1] = uid->attrib_len >> 24; /* always use 4 length bytes */
- buf[2] = uid->attrib_len >> 16;
- buf[3] = uid->attrib_len >> 8;
- buf[4] = uid->attrib_len;
- }
- else {
- buf[0] = 0xb4; /* indicates a userid packet */
- buf[1] = uid->len >> 24; /* always use 4 length bytes */
- buf[2] = uid->len >> 16;
- buf[3] = uid->len >> 8;
- buf[4] = uid->len;
- }
- gcry_md_write( md, buf, 5 );
- }
-
- if(uid->attrib_data)
- gcry_md_write (md, uid->attrib_data, uid->attrib_len );
- else
- gcry_md_write (md, uid->name, uid->len );
-}
-
-
-/*
- * Helper to hash some parts from the signature
- */
-static void
-hash_sigversion_to_magic (MD_HANDLE md, const PKT_signature *sig)
-{
- if (sig->version >= 4)
- gcry_md_putc (md, sig->version);
- gcry_md_putc (md, sig->sig_class);
- if (sig->version < 4) {
- u32 a = sig->timestamp;
- gcry_md_putc (md, (a >> 24) & 0xff );
- gcry_md_putc (md, (a >> 16) & 0xff );
- gcry_md_putc (md, (a >> 8) & 0xff );
- gcry_md_putc (md, a & 0xff );
- }
- else {
- byte buf[6];
- size_t n;
-
- gcry_md_putc (md, sig->pubkey_algo);
- gcry_md_putc (md, sig->digest_algo);
- if (sig->hashed) {
- n = sig->hashed->len;
- gcry_md_putc (md, (n >> 8) );
- gcry_md_putc (md, n );
- gcry_md_write (md, sig->hashed->data, n );
- n += 6;
- }
- else {
- gcry_md_putc (md, 0); /* always hash the length of the subpacket*/
- gcry_md_putc (md, 0);
- n = 6;
- }
- /* add some magic */
- buf[0] = sig->version;
- buf[1] = 0xff;
- buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
- buf[3] = n >> 16;
- buf[4] = n >> 8;
- buf[5] = n;
- gcry_md_write (md, buf, 6);
- }
-}
-
-
-static int
-do_sign( PKT_secret_key *sk, PKT_signature *sig,
- MD_HANDLE md, int digest_algo )
-{
- gcry_mpi_t frame;
- byte *dp;
- int rc;
-
- if( sk->timestamp > sig->timestamp ) {
- ulong d = sk->timestamp - sig->timestamp;
- log_info( d==1 ? _("key has been created %lu second "
- "in future (time warp or clock problem)\n")
- : _("key has been created %lu seconds "
- "in future (time warp or clock problem)\n"), d );
- if( !opt.ignore_time_conflict )
- return GPG_ERR_TIME_CONFLICT;
- }
-
- print_pubkey_algo_note(sk->pubkey_algo);
-
- if( !digest_algo )
- digest_algo = gcry_md_get_algo(md);
-
- print_digest_algo_note( digest_algo );
- dp = gcry_md_read ( md, digest_algo );
- sig->digest_algo = digest_algo;
- sig->digest_start[0] = dp[0];
- sig->digest_start[1] = dp[1];
- if (sk->is_protected && sk->protect.s2k.mode == 1002)
- { /* FIXME: Note that we do only support RSA for now. */
- char *rbuf;
- size_t rbuflen;
- char *snbuf;
-
- snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk);
- rc = agent_scd_pksign (snbuf, digest_algo,
- gcry_md_read (md, digest_algo),
- gcry_md_get_algo_dlen (digest_algo),
- &rbuf, &rbuflen);
- xfree (snbuf);
- if (!rc)
- {
- if (gcry_mpi_scan (&sig->data[0], GCRYMPI_FMT_USG,
- rbuf, rbuflen, NULL))
- BUG ();
- }
- }
- else
- {
- frame = encode_md_value( sk->pubkey_algo, md,
- digest_algo, mpi_get_nbits(sk->skey[0]), 0 );
- if (!frame)
- return GPG_ERR_GENERAL;
- rc = pk_sign( sk->pubkey_algo, sig->data, frame, sk->skey );
- gcry_mpi_release (frame);
- }
- if (!rc && !opt.no_sig_create_check) {
- /* check that the signature verification worked and nothing is
- * fooling us e.g. by a bug in the signature create
- * code or by deliberately introduced faults. */
- PKT_public_key *pk = xcalloc (1,sizeof *pk);
-
- if( get_pubkey( pk, sig->keyid ) )
- rc = GPG_ERR_NO_PUBKEY;
- else {
- frame = encode_md_value (pk->pubkey_algo, md,
- sig->digest_algo,
- mpi_get_nbits(pk->pkey[0]), 0);
- if (!frame)
- rc = GPG_ERR_GENERAL;
- else
- rc = pk_verify (pk->pubkey_algo, frame,
- sig->data, pk->pkey);
- gcry_mpi_release (frame);
- }
- if (rc)
- log_error (_("checking created signature failed: %s\n"),
- gpg_strerror (rc));
- free_public_key (pk);
- }
- if( rc )
- log_error(_("signing failed: %s\n"), gpg_strerror (rc) );
- else {
- if( opt.verbose ) {
- char *ustr = get_user_id_string_printable (sig->keyid);
- log_info(_("%s/%s signature from: \"%s\"\n"),
- gcry_pk_algo_name (sk->pubkey_algo),
- gcry_md_algo_name (sig->digest_algo),
- ustr );
- xfree (ustr);
- }
- }
- return rc;
-}
-
-
-
-int
-complete_sig( PKT_signature *sig, PKT_secret_key *sk, MD_HANDLE md )
-{
- int rc=0;
-
- if( !(rc=check_secret_key( sk, 0 )) )
- rc = do_sign( sk, sig, md, 0 );
- return rc;
-}
-
-static int
-hash_for(int pubkey_algo, int packet_version )
-{
- if( opt.def_digest_algo )
- return opt.def_digest_algo;
- else if( recipient_digest_algo )
- return recipient_digest_algo;
- else if(PGP2 && pubkey_algo == PUBKEY_ALGO_RSA && packet_version < 4 )
- {
- /* Old-style PGP only understands MD5 */
- return DIGEST_ALGO_MD5;
- }
- else if( pubkey_algo == PUBKEY_ALGO_DSA )
- {
- /* We need a 160-bit hash for DSA, so we can't just take the first
- in the pref list */
-
- if(opt.personal_digest_prefs)
- {
- prefitem_t *prefs;
-
- for(prefs=opt.personal_digest_prefs;prefs->type;prefs++)
- if(gcry_md_get_algo_dlen (prefs->value) == 20)
- return prefs->value;
- }
-
- return DIGEST_ALGO_SHA1;
- }
- else if( opt.personal_digest_prefs )
- {
- /* It's not DSA, so we can use whatever the first hash algorithm
- is in the pref list */
- return opt.personal_digest_prefs[0].value;
- }
- else
- return DEFAULT_DIGEST_ALGO;
-}
-
-static int
-only_old_style( SK_LIST sk_list )
-{
- SK_LIST sk_rover = NULL;
- int old_style = 0;
-
- /* if there are only old style capable key we use the old sytle */
- for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
- PKT_secret_key *sk = sk_rover->sk;
- if( sk->pubkey_algo == PUBKEY_ALGO_RSA && sk->version < 4 )
- old_style = 1;
- else
- return 0;
- }
- return old_style;
-}
-
-
-static void
-print_status_sig_created ( PKT_secret_key *sk, PKT_signature *sig, int what )
-{
- byte array[MAX_FINGERPRINT_LEN], *p;
- char buf[100+MAX_FINGERPRINT_LEN*2];
- size_t i, n;
-
- sprintf(buf, "%c %d %d %02x %lu ",
- what, sig->pubkey_algo, sig->digest_algo, sig->sig_class,
- (ulong)sig->timestamp );
-
- fingerprint_from_sk( sk, array, &n );
- p = buf + strlen(buf);
- for(i=0; i < n ; i++ )
- sprintf(p+2*i, "%02X", array[i] );
-
- write_status_text( STATUS_SIG_CREATED, buf );
-}
-
-
-/*
- * Loop over the secret certificates in SK_LIST and build the one pass
- * signature packets. OpenPGP says that the data should be bracket by
- * the onepass-sig and signature-packet; so we build these onepass
- * packet here in reverse order
- */
-static int
-write_onepass_sig_packets (SK_LIST sk_list, iobuf_t out, int sigclass )
-{
- int skcount;
- SK_LIST sk_rover;
-
- for (skcount=0, sk_rover=sk_list; sk_rover; sk_rover = sk_rover->next)
- skcount++;
-
- for (; skcount; skcount--) {
- PKT_secret_key *sk;
- PKT_onepass_sig *ops;
- PACKET pkt;
- int i, rc;
-
- for (i=0, sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
- if (++i == skcount)
- break;
- }
-
- sk = sk_rover->sk;
- ops = xcalloc (1,sizeof *ops);
- ops->sig_class = sigclass;
- ops->digest_algo = hash_for (sk->pubkey_algo, sk->version);
- ops->pubkey_algo = sk->pubkey_algo;
- keyid_from_sk (sk, ops->keyid);
- ops->last = (skcount == 1);
-
- init_packet(&pkt);
- pkt.pkttype = PKT_ONEPASS_SIG;
- pkt.pkt.onepass_sig = ops;
- rc = build_packet (out, &pkt);
- free_packet (&pkt);
- if (rc) {
- log_error ("build onepass_sig packet failed: %s\n",
- gpg_strerror (rc));
- return rc;
- }
- }
-
- return 0;
-}
-
-/*
- * Helper to write the plaintext (literal data) packet
- */
-static int
-write_plaintext_packet (iobuf_t out, iobuf_t inp, const char *fname, int ptmode)
-{
- PKT_plaintext *pt = NULL;
- u32 filesize;
- int rc = 0;
-
- if (!opt.no_literal) {
- if (fname || opt.set_filename) {
- char *s = make_basename (opt.set_filename? opt.set_filename
- : fname
- /*, iobuf_get_real_fname(inp)*/);
- pt = xmalloc (sizeof *pt + strlen(s) - 1);
- pt->namelen = strlen (s);
- memcpy (pt->name, s, pt->namelen);
- xfree (s);
- }
- else { /* no filename */
- pt = xmalloc (sizeof *pt - 1);
- pt->namelen = 0;
- }
- }
-
- /* try to calculate the length of the data */
- if (fname && *fname && !(*fname=='-' && !fname[1])) {
- if( !(filesize = iobuf_get_filelength(inp)) )
- log_info (_("WARNING: `%s' is an empty file\n"), fname);
-
- /* we can't yet encode the length of very large files,
- * so we switch to partial length encoding in this case */
- if (filesize >= IOBUF_FILELENGTH_LIMIT)
- filesize = 0;
-
- /* because the text_filter modifies the length of the
- * data, it is not possible to know the used length
- * without a double read of the file - to avoid that
- * we simple use partial length packets.
- */
- if ( ptmode == 't' )
- filesize = 0;
- }
- else {
- filesize = opt.set_filesize? opt.set_filesize : 0; /* stdin */
- }
-
- if (!opt.no_literal) {
- PACKET pkt;
-
- pt->timestamp = make_timestamp ();
- pt->mode = ptmode;
- pt->len = filesize;
- pt->new_ctb = !pt->len && !RFC1991;
- pt->buf = inp;
- init_packet(&pkt);
- pkt.pkttype = PKT_PLAINTEXT;
- pkt.pkt.plaintext = pt;
- /*cfx.datalen = filesize? calc_packet_length( &pkt ) : 0;*/
- if( (rc = build_packet (out, &pkt)) )
- log_error ("build_packet(PLAINTEXT) failed: %s\n",
- gpg_strerror (rc) );
- pt->buf = NULL;
- }
- else {
- 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 */
- }
- /* fixme: it seems that we never freed pt/pkt */
-
- return rc;
-}
-
-/*
- * Write the signatures from the SK_LIST to OUT. HASH must be a non-finalized
- * hash which will not be changes here.
- */
-static int
-write_signature_packets (SK_LIST sk_list, iobuf_t out, MD_HANDLE hash,
- int sigclass, u32 timestamp, u32 duration,
- int status_letter)
-{
- SK_LIST sk_rover;
-
- /* loop over the secret certificates */
- for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) {
- PKT_secret_key *sk;
- PKT_signature *sig;
- MD_HANDLE md;
- int rc;
-
- sk = sk_rover->sk;
-
- /* build the signature packet */
- sig = xcalloc (1,sizeof *sig);
- if(opt.force_v3_sigs || RFC1991)
- sig->version=3;
- else if(duration || opt.sig_policy_url
- || opt.sig_notation_data || opt.sig_keyserver_url)
- sig->version=4;
- else
- sig->version=sk->version;
- keyid_from_sk (sk, sig->keyid);
- sig->digest_algo = hash_for (sk->pubkey_algo, sk->version);
- sig->pubkey_algo = sk->pubkey_algo;
- if(timestamp)
- sig->timestamp = timestamp;
- else
- sig->timestamp = make_timestamp();
- if(duration)
- sig->expiredate = sig->timestamp+duration;
- sig->sig_class = sigclass;
-
- gcry_md_copy (&md, hash);
-
- if (sig->version >= 4)
- build_sig_subpkt_from_sig (sig);
- mk_notation_policy_etc (sig, NULL, sk);
-
- hash_sigversion_to_magic (md, sig);
- gcry_md_final (md);
-
- rc = do_sign( sk, sig, md, hash_for (sig->pubkey_algo, sk->version) );
- gcry_md_close (md);
-
- if( !rc ) { /* and write it */
- PACKET pkt;
-
- init_packet(&pkt);
- pkt.pkttype = PKT_SIGNATURE;
- pkt.pkt.signature = sig;
- rc = build_packet (out, &pkt);
- if (!rc && is_status_enabled()) {
- print_status_sig_created ( sk, sig, status_letter);
- }
- free_packet (&pkt);
- if (rc)
- log_error ("build signature packet failed: %s\n",
- gpg_strerror (rc) );
- }
- if( rc )
- return rc;;
- }
-
- return 0;
-}
-
-/****************
- * Sign the files whose names are in FILENAME.
- * If DETACHED has the value true,
- * make a detached signature. If FILENAMES->d is NULL read from stdin
- * and ignore the detached mode. Sign the file with all secret keys
- * which can be taken from LOCUSR, if this is NULL, use the default one
- * If ENCRYPTFLAG is true, use REMUSER (or ask if it is NULL) to encrypt the
- * signed data for these users.
- * If OUTFILE is not NULL; this file is used for output and the function
- * does not ask for overwrite permission; output is then always
- * uncompressed, non-armored and in binary mode.
- */
-int
-sign_file( STRLIST filenames, int detached, STRLIST locusr,
- int encryptflag, STRLIST remusr, const char *outfile )
-{
- const char *fname;
- armor_filter_context_t afx;
- compress_filter_context_t zfx;
- md_filter_context_t mfx;
- text_filter_context_t tfx;
- progress_filter_context_t pfx;
- encrypt_filter_context_t efx;
- iobuf_t inp = NULL, out = NULL;
- PACKET pkt;
- int rc = 0;
- PK_LIST pk_list = NULL;
- SK_LIST sk_list = NULL;
- SK_LIST sk_rover = NULL;
- int multifile = 0;
- u32 duration=0;
-
- memset( &afx, 0, sizeof afx);
- memset( &zfx, 0, sizeof zfx);
- memset( &mfx, 0, sizeof mfx);
- memset( &efx, 0, sizeof efx);
- init_packet( &pkt );
-
- if( filenames ) {
- fname = filenames->d;
- multifile = !!filenames->next;
- }
- else
- fname = NULL;
-
- if( fname && filenames->next && (!detached || encryptflag) )
- log_bug("multiple files can only be detached signed");
-
- if(opt.ask_sig_expire && !opt.force_v3_sigs && !opt.batch && !RFC1991)
- duration=ask_expire_interval(1);
-
- if( (rc=build_sk_list( locusr, &sk_list, 1, PUBKEY_USAGE_SIG )) )
- goto leave;
-
- if(PGP2 && !only_old_style(sk_list))
- {
- log_info(_("you can only detach-sign with PGP 2.x style keys "
- "while in --pgp2 mode\n"));
- compliance_failure();
- }
-
- if(encryptflag && (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )))
- goto leave;
-
- /* prepare iobufs */
- if( multifile ) /* have list of filenames */
- inp = NULL; /* we do it later */
- else {
- if( !(inp = iobuf_open(fname)) ) {
- rc = gpg_error_from_errno (errno);
- log_error("can't open %s: %s\n", fname? fname: "[stdin]",
- strerror(errno) );
- goto leave;
- }
-
- handle_progress (&pfx, inp, fname);
- }
-
- if( outfile ) {
- if( !(out = iobuf_create( outfile )) ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("can't create %s: %s\n"), outfile, strerror(errno) );
- goto leave;
- }
- else if( opt.verbose )
- log_info(_("writing to `%s'\n"), outfile );
- }
- else if( (rc = open_outfile( fname, opt.armor? 1: detached? 2:0, &out )))
- goto leave;
-
- /* prepare to calculate the MD over the input */
- if( opt.textmode && !outfile && !multifile )
- {
- memset( &tfx, 0, sizeof tfx);
- iobuf_push_filter( inp, text_filter, &tfx );
- }
-
- gcry_md_open (&mfx.md, 0, 0);
-
- /* If we're encrypting and signing, it is reasonable to pick the
- hash algorithm to use out of the recepient key prefs. */
- if(pk_list)
- {
- if(opt.def_digest_algo)
- {
- if(!opt.expert &&
- select_algo_from_prefs(pk_list,PREFTYPE_HASH,
- opt.def_digest_algo,
- NULL)!=opt.def_digest_algo)
- log_info(_("forcing digest algorithm %s (%d) "
- "violates recipient preferences\n"),
- gcry_md_algo_name (opt.def_digest_algo),
- opt.def_digest_algo);
- }
- else
- {
- int hashlen=0,algo;
-
- /* Of course, if the recipient asks for something
- unreasonable (like a non-160-bit hash for DSA, for
- example), then don't do it. Check all sk's - if any
- are DSA, then the hash must be 160-bit. In the future
- this can be more complex with different hashes for each
- sk, but so long as there is only one signing algorithm
- with hash restrictions, this is ok. -dms */
-
- for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
- if(sk_rover->sk->pubkey_algo==PUBKEY_ALGO_DSA)
- hashlen=20;
-
- if((algo=
- select_algo_from_prefs(pk_list,PREFTYPE_HASH,-1,
- hashlen?&hashlen:NULL))>0)
- recipient_digest_algo=algo;
- }
- }
-
- for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
- PKT_secret_key *sk = sk_rover->sk;
- gcry_md_enable (mfx.md, hash_for(sk->pubkey_algo, sk->version ));
- }
-
- if( !multifile )
- iobuf_push_filter( inp, md_filter, &mfx );
-
- if( detached && !encryptflag && !RFC1991 )
- afx.what = 2;
-
- if( opt.armor && !outfile )
- iobuf_push_filter( out, armor_filter, &afx );
-
- if( encryptflag ) {
- efx.pk_list = pk_list;
- /* fixme: set efx.cfx.datalen if known */
- iobuf_push_filter( out, encrypt_filter, &efx );
- }
-
- if( opt.compress && !outfile && ( !detached || opt.compress_sigs) )
- {
- int compr_algo=opt.def_compress_algo;
-
- /* If not forced by user */
- if(compr_algo==-1)
- {
- /* If we're not encrypting, then select_algo_from_prefs
- will fail and we'll end up with the default. If we are
- encrypting, select_algo_from_prefs cannot fail since
- there is an assumed preference for uncompressed data.
- Still, if it did fail, we'll also end up with the
- default. */
-
- if((compr_algo=
- select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1)
- compr_algo=default_compress_algo();
- }
- else if(!opt.expert && pk_list
- && select_algo_from_prefs(pk_list,PREFTYPE_ZIP,
- compr_algo,NULL)!=compr_algo)
- log_info(_("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 )
- {
- zfx.algo = compr_algo;
- iobuf_push_filter( out, compress_filter, &zfx );
- }
- }
-
- /* Write the one-pass signature packets if needed */
- if (!detached && !RFC1991) {
- rc = write_onepass_sig_packets (sk_list, out,
- opt.textmode && !outfile ? 0x01:0x00);
- if (rc)
- goto leave;
- }
-
- /* setup the inner packet */
- if( detached ) {
- if( multifile ) {
- STRLIST sl;
-
- if( opt.verbose )
- log_info(_("signing:") );
- /* must walk reverse trough this list */
- for( sl = strlist_last(filenames); sl;
- sl = strlist_prev( filenames, sl ) ) {
- if( !(inp = iobuf_open(sl->d)) ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("can't open %s: %s\n"),
- sl->d, strerror(errno) );
- goto leave;
- }
- handle_progress (&pfx, inp, sl->d);
- if( opt.verbose )
- fprintf(stderr, " `%s'", sl->d );
- if(opt.textmode)
- {
- memset( &tfx, 0, sizeof tfx);
- iobuf_push_filter( inp, text_filter, &tfx );
- }
- iobuf_push_filter( inp, md_filter, &mfx );
- while( iobuf_get(inp) != -1 )
- ;
- iobuf_close(inp); inp = NULL;
- }
- if( opt.verbose )
- putc( '\n', stderr );
- }
- else {
- /* read, so that the filter can calculate the digest */
- while( iobuf_get(inp) != -1 )
- ;
- }
- }
- else {
- rc = write_plaintext_packet (out, inp, fname,
- opt.textmode && !outfile ? 't':'b');
- }
-
- /* catch errors from above */
- if (rc)
- goto leave;
-
- /* write the signatures */
- rc = write_signature_packets (sk_list, out, mfx.md,
- opt.textmode && !outfile? 0x01 : 0x00,
- 0, duration, detached ? 'D':'S');
- if( rc )
- goto leave;
-
-
- leave:
- if( rc )
- iobuf_cancel(out);
- else {
- iobuf_close(out);
- if (encryptflag)
- write_status( STATUS_END_ENCRYPTION );
- }
- iobuf_close(inp);
- gcry_md_close ( mfx.md );
- release_sk_list( sk_list );
- release_pk_list( pk_list );
- recipient_digest_algo=0;
- return rc;
-}
-
-
-
-/****************
- * make a clear signature. note that opt.armor is not needed
- */
-int
-clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
-{
- armor_filter_context_t afx;
- progress_filter_context_t pfx;
- MD_HANDLE textmd = NULL;
- iobuf_t inp = NULL, out = NULL;
- PACKET pkt;
- int rc = 0;
- SK_LIST sk_list = NULL;
- SK_LIST sk_rover = NULL;
- int old_style = RFC1991;
- int only_md5 = 0;
- u32 duration=0;
-
- memset( &afx, 0, sizeof afx);
- init_packet( &pkt );
-
- if(opt.ask_sig_expire && !opt.force_v3_sigs && !opt.batch && !RFC1991)
- duration=ask_expire_interval(1);
-
- if( (rc=build_sk_list( locusr, &sk_list, 1, PUBKEY_USAGE_SIG )) )
- goto leave;
-
- if( !old_style && !duration )
- old_style = only_old_style( sk_list );
-
- if(PGP2 && !only_old_style(sk_list))
- {
- log_info(_("you can only clearsign with PGP 2.x style keys "
- "while in --pgp2 mode\n"));
- compliance_failure();
- }
-
- /* prepare iobufs */
- if( !(inp = iobuf_open(fname)) ) {
- rc = gpg_error_from_errno (errno);
- log_error("can't open %s: %s\n", fname? fname: "[stdin]",
- strerror(errno) );
- goto leave;
- }
- handle_progress (&pfx, inp, fname);
-
- if( outfile ) {
- if( !(out = iobuf_create( outfile )) ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("can't create %s: %s\n"), outfile, strerror(errno) );
- goto leave;
- }
- else if( opt.verbose )
- log_info(_("writing to `%s'\n"), outfile );
- }
- else if( (rc = open_outfile( fname, 1, &out )) )
- goto leave;
-
- iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----" LF );
-
- for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
- PKT_secret_key *sk = sk_rover->sk;
- if( hash_for(sk->pubkey_algo, sk->version) == DIGEST_ALGO_MD5 )
- only_md5 = 1;
- else {
- only_md5 = 0;
- break;
- }
- }
-
- if( !(old_style && only_md5) ) {
- const char *s;
- int any = 0;
- byte hashs_seen[256];
-
- memset( hashs_seen, 0, sizeof hashs_seen );
- iobuf_writestr(out, "Hash: " );
- for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
- PKT_secret_key *sk = sk_rover->sk;
- int i = hash_for(sk->pubkey_algo, sk->version);
-
- if( !hashs_seen[ i & 0xff ] ) {
- s = gcry_md_algo_name (i);
- if( s ) {
- hashs_seen[ i & 0xff ] = 1;
- if( any )
- iobuf_put(out, ',' );
- iobuf_writestr(out, s );
- any = 1;
- }
- }
- }
- assert(any);
- iobuf_writestr(out, LF );
- }
-
- if( opt.not_dash_escaped )
- iobuf_writestr( out,
- "NotDashEscaped: You need GnuPG to verify this message" LF );
- iobuf_writestr(out, LF );
-
- gcry_md_open (&textmd, 0, 0);
- for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
- PKT_secret_key *sk = sk_rover->sk;
- gcry_md_enable (textmd, hash_for(sk->pubkey_algo, sk->version));
- }
- if ( DBG_HASHING )
- gcry_md_start_debug ( textmd, "clearsign" );
- copy_clearsig_text( out, inp, textmd, !opt.not_dash_escaped,
- opt.escape_from, (old_style && only_md5) );
- /* fixme: check for read errors */
-
- /* now write the armor */
- afx.what = 2;
- iobuf_push_filter( out, armor_filter, &afx );
-
- /* write the signatures */
- rc=write_signature_packets (sk_list, out, textmd, 0x01, 0, duration, 'C');
- if( rc )
- goto leave;
-
- leave:
- if( rc )
- iobuf_cancel(out);
- else
- iobuf_close(out);
- iobuf_close(inp);
- gcry_md_close ( textmd );
- release_sk_list( sk_list );
- return rc;
-}
-
-/*
- * Sign and conventionally encrypt the given file.
- * FIXME: Far too much code is duplicated - revamp the whole file.
- */
-int
-sign_symencrypt_file (const char *fname, STRLIST locusr)
-{
- armor_filter_context_t afx;
- progress_filter_context_t pfx;
- compress_filter_context_t zfx;
- md_filter_context_t mfx;
- text_filter_context_t tfx;
- cipher_filter_context_t cfx;
- iobuf_t inp = NULL, out = NULL;
- PACKET pkt;
- STRING2KEY *s2k = NULL;
- int rc = 0;
- SK_LIST sk_list = NULL;
- SK_LIST sk_rover = NULL;
- int algo;
- u32 duration=0;
-
- memset( &afx, 0, sizeof afx);
- memset( &zfx, 0, sizeof zfx);
- memset( &mfx, 0, sizeof mfx);
- memset( &tfx, 0, sizeof tfx);
- memset( &cfx, 0, sizeof cfx);
- init_packet( &pkt );
-
- if(opt.ask_sig_expire && !opt.force_v3_sigs && !opt.batch && !RFC1991)
- duration=ask_expire_interval(1);
-
- rc = build_sk_list (locusr, &sk_list, 1, PUBKEY_USAGE_SIG);
- if (rc)
- goto leave;
-
- /* prepare iobufs */
- inp = iobuf_open(fname);
- if( !inp ) {
- rc = gpg_error_from_errno (errno);
- log_error("can't open %s: %s\n", fname? fname: "[stdin]",
- strerror(errno) );
- goto leave;
- }
- handle_progress (&pfx, inp, fname);
-
- /* prepare key */
- s2k = xcalloc (1, sizeof *s2k );
- s2k->mode = RFC1991? 0:opt.s2k_mode;
- s2k->hash_algo = opt.s2k_digest_algo;
-
- algo = default_cipher_algo();
- if (!opt.quiet || !opt.batch)
- log_info (_("%s encryption will be used\n"),
- gcry_cipher_algo_name (algo) );
- cfx.dek = passphrase_to_dek( NULL, 0, algo, s2k, 2, NULL, NULL);
-
- if (!cfx.dek || !cfx.dek->keylen) {
- rc = gpg_error (GPG_ERR_INV_PASSPHRASE);
- log_error(_("error creating passphrase: %s\n"), gpg_strerror (rc) );
- goto leave;
- }
-
- /* now create the outfile */
- rc = open_outfile (fname, opt.armor? 1:0, &out);
- if (rc)
- goto leave;
-
- /* prepare to calculate the MD over the input */
- if (opt.textmode)
- iobuf_push_filter (inp, text_filter, &tfx);
- gcry_md_open (&mfx.md, 0, 0);
-
- for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) {
- PKT_secret_key *sk = sk_rover->sk;
- gcry_md_enable (mfx.md, hash_for (sk->pubkey_algo, sk->version ));
- }
-
- iobuf_push_filter (inp, md_filter, &mfx);
-
- /* Push armor output filter */
- if (opt.armor)
- iobuf_push_filter (out, armor_filter, &afx);
-
- /* Write the symmetric key packet */
- /*(current filters: armor)*/
- if (!RFC1991) {
- PKT_symkey_enc *enc = xcalloc (1, sizeof *enc );
- enc->version = 4;
- enc->cipher_algo = cfx.dek->algo;
- enc->s2k = *s2k;
- pkt.pkttype = PKT_SYMKEY_ENC;
- pkt.pkt.symkey_enc = enc;
- if( (rc = build_packet( out, &pkt )) )
- log_error("build symkey packet failed: %s\n", gpg_strerror (rc) );
- xfree (enc);
- }
-
- /* Push the encryption filter */
- iobuf_push_filter( out, cipher_filter, &cfx );
-
- /* Push the Zip filter */
- if (opt.compress && default_compress_algo())
- {
- zfx.algo = default_compress_algo();
- iobuf_push_filter( out, compress_filter, &zfx );
- }
-
- /* Write the one-pass signature packets */
- /*(current filters: zip - encrypt - armor)*/
- if (!RFC1991) {
- rc = write_onepass_sig_packets (sk_list, out,
- opt.textmode? 0x01:0x00);
- if (rc)
- goto leave;
- }
-
- /* Pipe data through all filters; i.e. write the signed stuff */
- /*(current filters: zip - encrypt - armor)*/
- rc = write_plaintext_packet (out, inp, fname, opt.textmode ? 't':'b');
- if (rc)
- goto leave;
-
- /* Write the signatures */
- /*(current filters: zip - encrypt - armor)*/
- rc = write_signature_packets (sk_list, out, mfx.md,
- opt.textmode? 0x01 : 0x00,
- 0, duration, 'S');
- if( rc )
- goto leave;
-
-
- leave:
- if( rc )
- iobuf_cancel(out);
- else {
- iobuf_close(out);
- write_status( STATUS_END_ENCRYPTION );
- }
- iobuf_close(inp);
- release_sk_list( sk_list );
- gcry_md_close ( mfx.md );
- xfree (cfx.dek);
- xfree (s2k);
- return rc;
-}
-
-
-/****************
- * Create a signature packet for the given public key certificate and
- * the user id and return it in ret_sig. User signature class SIGCLASS
- * user-id is not used (and may be NULL if sigclass is 0x20) If
- * DIGEST_ALGO is 0 the function selects an appropriate one.
- * SIGVERSION gives the minimal required signature packet version;
- * this is needed so that special properties like local sign are not
- * applied (actually: dropped) when a v3 key is used. TIMESTAMP is
- * the timestamp to use for the signature. 0 means "now". */
-int
-make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
- PKT_user_id *uid, PKT_public_key *subpk,
- PKT_secret_key *sk,
- int sigclass, int digest_algo,
- int sigversion, u32 timestamp, u32 duration,
- int (*mksubpkt)(PKT_signature *, void *), void *opaque
- )
-{
- PKT_signature *sig;
- int rc=0;
- MD_HANDLE md;
-
- assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x1F
- || sigclass == 0x20 || sigclass == 0x18
- || sigclass == 0x30 || sigclass == 0x28 );
-
- if (opt.force_v4_certs)
- sigversion = 4;
-
- if (sigversion < sk->version)
- sigversion = sk->version;
-
- /* If you are making a signature on a v4 key using your v3 key, it
- doesn't make sense to generate a v3 sig. After all, no v3-only
- PGP implementation could understand the v4 key in the first
- place. Note that this implies that a signature on an attribute
- uid is usually going to be v4 as well, since they are not
- generally found on v3 keys. */
- if (sigversion < pk->version)
- sigversion = pk->version;
-
- if( !digest_algo )
- {
- /* Basically, this means use SHA1 always unless it's a v3 RSA
- key making a v3 cert (use MD5), or the user specified
- something (use whatever they said). They still must use a
- 160-bit hash with DSA, or the signature will fail. Note
- that this still allows the caller of make_keysig_packet to
- override the user setting if it must. */
-
- if(opt.cert_digest_algo)
- digest_algo=opt.cert_digest_algo;
- else if((sk->pubkey_algo==PUBKEY_ALGO_RSA ||
- sk->pubkey_algo==PUBKEY_ALGO_RSA_S) &&
- pk->version<4 && sigversion < 4)
- digest_algo = DIGEST_ALGO_MD5;
- else
- digest_algo = DIGEST_ALGO_SHA1;
- }
-
- gcry_md_open (&md, digest_algo, 0 );
-
- /* hash the public key certificate and the user id */
- hash_public_key( md, pk );
- if( sigclass == 0x18 || sigclass == 0x28 ) { /* subkey binding/revocation*/
- hash_public_key( md, subpk );
- }
- else if( sigclass != 0x1F && sigclass != 0x20 ) {
- hash_uid (md, sigversion, uid);
- }
- /* and make the signature packet */
- sig = xcalloc (1, sizeof *sig );
- sig->version = sigversion;
- sig->flags.exportable=1;
- sig->flags.revocable=1;
- keyid_from_sk( sk, sig->keyid );
- sig->pubkey_algo = sk->pubkey_algo;
- sig->digest_algo = digest_algo;
- if(timestamp)
- sig->timestamp=timestamp;
- else
- sig->timestamp=make_timestamp();
- if(duration)
- sig->expiredate=sig->timestamp+duration;
- sig->sig_class = sigclass;
- if( sig->version >= 4 )
- build_sig_subpkt_from_sig( sig );
- mk_notation_policy_etc ( sig, pk, sk );
-
- /* Crucial that the call to mksubpkt comes LAST before the calls
- to finalize the sig as that makes it possible for the mksubpkt
- function to get a reliable pointer to the subpacket area. */
- if( sig->version >= 4 && mksubpkt )
- rc = (*mksubpkt)( sig, opaque );
-
- if( !rc ) {
- hash_sigversion_to_magic (md, sig);
- gcry_md_final (md);
-
- rc = complete_sig( sig, sk, md );
- }
-
- gcry_md_close ( md );
- if( rc )
- free_seckey_enc( sig );
- else
- *ret_sig = sig;
- return rc;
-}
-
-
-
-/****************
- * Create a new signature packet based on an existing one.
- * Only user ID signatures are supported for now.
- * TODO: Merge this with make_keysig_packet.
- */
-int
-update_keysig_packet( PKT_signature **ret_sig,
- PKT_signature *orig_sig,
- PKT_public_key *pk,
- PKT_user_id *uid,
- PKT_public_key *subpk,
- PKT_secret_key *sk,
- int (*mksubpkt)(PKT_signature *, void *),
- void *opaque
- )
-{
- PKT_signature *sig;
- int rc=0;
- MD_HANDLE md;
-
- if ((!orig_sig || !pk || !sk)
- || (orig_sig->sig_class >= 0x10 && orig_sig->sig_class <= 0x13 && !uid)
- || (orig_sig->sig_class == 0x18 && !subpk))
- return GPG_ERR_GENERAL;
-
- gcry_md_open (&md, orig_sig->digest_algo, 0);
-
- /* hash the public key certificate and the user id */
- hash_public_key( md, pk );
-
- if( orig_sig->sig_class == 0x18 )
- hash_public_key( md, subpk );
- else
- hash_uid (md, orig_sig->version, uid);
-
- /* create a new signature packet */
- sig = copy_signature (NULL, orig_sig);
-
- /* We need to create a new timestamp so that new sig expiration
- calculations are done correctly... */
- sig->timestamp=make_timestamp();
-
- /* ... but we won't make a timestamp earlier than the existing
- one. */
- while(sig->timestamp<=orig_sig->timestamp)
- {
- sleep(1);
- sig->timestamp=make_timestamp();
- }
-
- /* Note that already expired sigs will remain expired (with a
- duration of 0) since build-packet.c:build_sig_subpkt_from_sig
- detects this case. */
-
- if( sig->version >= 4 )
- {
- /* Put the updated timestamp into the sig. Note that this
- will automagically lower any sig expiration dates to
- correctly correspond to the differences in the timestamps
- (i.e. the duration will shrink). */
- build_sig_subpkt_from_sig( sig );
-
- if (mksubpkt)
- rc = (*mksubpkt)(sig, opaque);
- }
-
- if (!rc) {
- hash_sigversion_to_magic (md, sig);
- gcry_md_final (md);
-
- rc = complete_sig( sig, sk, md );
- }
-
- gcry_md_close (md);
- if( rc )
- free_seckey_enc (sig);
- else
- *ret_sig = sig;
- return rc;
-}
diff --git a/g10/signal.c b/g10/signal.c
deleted file mode 100644
index 9f50fbe3a..000000000
--- a/g10/signal.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/* signal.c - signal handling
- * Copyright (C) 1998, 1999, 2000, 2001, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "options.h"
-#include "errors.h"
-#include "memory.h"
-#include "util.h"
-#include "main.h"
-#include "ttyio.h"
-
-
-static volatile int caught_fatal_sig = 0;
-static volatile int caught_sigusr1 = 0;
-
-static void
-init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign )
-{
-#ifndef HAVE_DOSISH_SYSTEM
-#if defined(HAVE_SIGACTION) && defined(HAVE_STRUCT_SIGACTION)
- struct sigaction oact, nact;
-
- if (check_ign) {
- /* we don't want to change an IGN handler */
- sigaction (sig, NULL, &oact );
- if (oact.sa_handler == SIG_IGN )
- return;
- }
-
- nact.sa_handler = handler;
- sigemptyset (&nact.sa_mask);
- nact.sa_flags = 0;
- sigaction ( sig, &nact, NULL);
-#else
- RETSIGTYPE (*ohandler)(int);
-
- ohandler = signal (sig, handler);
- if (check_ign && ohandler == SIG_IGN) {
- /* Change it back if it was already set to IGN */
- signal (sig, SIG_IGN);
- }
-#endif
-#endif /*!HAVE_DOSISH_SYSTEM*/
-}
-
-static const char *
-get_signal_name( int signum )
-{
-#if defined(SYS_SIGLIST_DECLARED) && defined(NSIG)
- return (signum >= 0 && signum < NSIG) ? sys_siglist[signum] : "?";
-#else
- return "some signal";
-#endif
-}
-
-
-static RETSIGTYPE
-got_fatal_signal( int sig )
-{
- const char *s;
-
- if( caught_fatal_sig )
- raise( sig );
- caught_fatal_sig = 1;
-
- gcry_control (GCRYCTL_TERM_SECMEM );
- /* better don't transtale these messages */
- write(2, "\n", 1 );
- s = "?" /* FIXME: log_get_name()*/; if( s ) write(2, s, strlen(s) );
- write(2, ": ", 2 );
- s = get_signal_name(sig); write(2, s, strlen(s) );
- write(2, " caught ... exiting\n", 20 );
-
- /* reset action to default action and raise signal again */
- init_one_signal (sig, SIG_DFL, 0);
- dotlock_remove_lockfiles ();
-#ifdef __riscos__
- riscos_close_fds ();
-#endif /* __riscos__ */
- raise( sig );
-}
-
-
-static RETSIGTYPE
-got_usr_signal( int sig )
-{
- caught_sigusr1 = 1;
-}
-
-
-void
-init_signals()
-{
-#ifndef HAVE_DOSISH_SYSTEM
- init_one_signal (SIGINT, got_fatal_signal, 1 );
- init_one_signal (SIGHUP, got_fatal_signal, 1 );
- init_one_signal (SIGTERM, got_fatal_signal, 1 );
- init_one_signal (SIGQUIT, got_fatal_signal, 1 );
- init_one_signal (SIGSEGV, got_fatal_signal, 1 );
- init_one_signal (SIGUSR1, got_usr_signal, 0 );
- init_one_signal (SIGPIPE, SIG_IGN, 0 );
-#endif
-}
-
-
-void
-pause_on_sigusr( int which )
-{
-#ifndef HAVE_DOSISH_SYSTEM
-#if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T)
- sigset_t mask, oldmask;
-
- assert( which == 1 );
- sigemptyset( &mask );
- sigaddset( &mask, SIGUSR1 );
-
- sigprocmask( SIG_BLOCK, &mask, &oldmask );
- while( !caught_sigusr1 )
- sigsuspend( &oldmask );
- caught_sigusr1 = 0;
- sigprocmask( SIG_UNBLOCK, &mask, NULL );
-#else
- assert (which == 1);
- sighold (SIGUSR1);
- while (!caught_sigusr1)
- sigpause(SIGUSR1);
- caught_sigusr1 = 0;
- sigrelse(SIGUSR1);
-#endif /*!HAVE_SIGPROCMASK && HAVE_SISET_T*/
-#endif
-}
-
-
-static void
-do_block( int block )
-{
-#ifndef HAVE_DOSISH_SYSTEM
- static int is_blocked;
-#if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T)
- static sigset_t oldmask;
-
- if( block ) {
- sigset_t newmask;
-
- if( is_blocked )
- log_bug("signals are already blocked\n");
- sigfillset( &newmask );
- sigprocmask( SIG_BLOCK, &newmask, &oldmask );
- is_blocked = 1;
- }
- else {
- if( !is_blocked )
- log_bug("signals are not blocked\n");
- sigprocmask( SIG_SETMASK, &oldmask, NULL );
- is_blocked = 0;
- }
-#else /*!HAVE_SIGPROCMASK*/
-
-#if defined(NSIG)
-# define SIGSMAX (NSIG)
-#elif defined(MAXSIG)
-# define SIGSMAX (MAXSIG+1)
-#else
-# error "define SIGSMAX to the number of signals on your platform plus one"
-#endif
-
- static void (*disposition[SIGSMAX])(int);
- int sig;
-
- if( block ) {
- if( is_blocked )
- log_bug("signals are already blocked\n");
- for (sig=1; sig < SIGSMAX; sig++) {
- disposition[sig] = sigset (sig, SIG_HOLD);
- }
- is_blocked = 1;
- }
- else {
- if( !is_blocked )
- log_bug("signals are not blocked\n");
- for (sig=1; sig < SIGSMAX; sig++) {
- sigset (sig, disposition[sig]);
- }
- is_blocked = 0;
- }
-#endif /*!HAVE_SIGPROCMASK*/
-#endif /*HAVE_DOSISH_SYSTEM*/
-}
-
-
-void
-block_all_signals()
-{
- do_block(1);
-}
-
-void
-unblock_all_signals()
-{
- do_block(0);
-}
diff --git a/g10/skclist.c b/g10/skclist.c
deleted file mode 100644
index 67d9eb2f9..000000000
--- a/g10/skclist.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/* skclist.c
- * Copyright (C) 1998, 1999, 2000, 2001 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "options.h"
-#include "packet.h"
-#include "errors.h"
-#include "keydb.h"
-#include "memory.h"
-#include "util.h"
-#include "i18n.h"
-#include "cipher.h"
-
-
-void
-release_sk_list( SK_LIST sk_list )
-{
- SK_LIST sk_rover;
-
- for( ; sk_list; sk_list = sk_rover ) {
- sk_rover = sk_list->next;
- free_secret_key( sk_list->sk );
- xfree ( sk_list );
- }
-}
-
-
-
-static int
-key_present_in_sk_list(SK_LIST sk_list, PKT_secret_key *sk)
-{
- for (; sk_list; sk_list = sk_list->next) {
- if ( !cmp_secret_keys(sk_list->sk, sk) )
- return 0;
- }
- return -1;
-}
-
-static int
-is_duplicated_entry (STRLIST list, STRLIST item)
-{
- for(; list && list != item; list = list->next) {
- if ( !strcmp (list->d, item->d) )
- return 1;
- }
- return 0;
-}
-
-
-int
-build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list,
- int unlock, unsigned int use )
-{
- SK_LIST sk_list = NULL;
- int rc;
-
- if( !locusr ) { /* use the default one */
- PKT_secret_key *sk;
-
- sk = xcalloc (1, sizeof *sk );
- sk->req_usage = use;
- if( (rc = get_seckey_byname( sk, NULL, unlock )) ) {
- free_secret_key( sk ); sk = NULL;
- log_error("no default secret key: %s\n", gpg_strerror (rc) );
- }
- else if( !(rc=openpgp_pk_test_algo (sk->pubkey_algo, use)) ) {
- SK_LIST r;
-
- if( sk->version == 4 && (use & PUBKEY_USAGE_SIG)
- && sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
- log_info("this is a PGP generated "
- "ElGamal key which is NOT secure for signatures!\n");
- free_secret_key( sk ); sk = NULL;
- }
- else {
- r = xmalloc ( sizeof *r );
- r->sk = sk; sk = NULL;
- r->next = sk_list;
- r->mark = 0;
- sk_list = r;
- }
- }
- else {
- free_secret_key( sk ); sk = NULL;
- log_error("invalid default secret key: %s\n", gpg_strerror (rc) );
- }
- }
- else {
- STRLIST locusr_orig = locusr;
- for(; locusr; locusr = locusr->next ) {
- PKT_secret_key *sk;
-
- rc = 0;
- /* Do an early check agains duplicated entries. However this
- * won't catch all duplicates because the user IDs may be
- * specified in different ways.
- */
- if ( is_duplicated_entry ( locusr_orig, locusr ) ) {
- log_error(_("skipped `%s': duplicated\n"), locusr->d );
- continue;
- }
- sk = xcalloc (1, sizeof *sk );
- sk->req_usage = use;
- if( (rc = get_seckey_byname( sk, locusr->d, 0 )) ) {
- free_secret_key( sk ); sk = NULL;
- log_error(_("skipped `%s': %s\n"), locusr->d, gpg_strerror (rc) );
- }
- else if ( key_present_in_sk_list(sk_list, sk) == 0) {
- free_secret_key(sk); sk = NULL;
- log_info(_("skipped: secret key already present\n"));
- }
- else if ( unlock && (rc = check_secret_key( sk, 0 )) ) {
- free_secret_key( sk ); sk = NULL;
- log_error(_("skipped `%s': %s\n"), locusr->d, gpg_strerror (rc) );
- }
- else if( !(rc=openpgp_pk_test_algo (sk->pubkey_algo, use)) ) {
- SK_LIST r;
-
- if( sk->version == 4 && (use & PUBKEY_USAGE_SIG)
- && sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
- log_info(_("skipped `%s': this is a PGP generated "
- "ElGamal key which is not secure for signatures!\n"),
- locusr->d );
- free_secret_key( sk ); sk = NULL;
- }
- else {
- r = xmalloc ( sizeof *r );
- r->sk = sk; sk = NULL;
- r->next = sk_list;
- r->mark = 0;
- sk_list = r;
- }
- }
- else {
- free_secret_key( sk ); sk = NULL;
- log_error("skipped `%s': %s\n", locusr->d, gpg_strerror (rc) );
- }
- }
- }
-
-
- if( !rc && !sk_list ) {
- log_error("no valid signators\n");
- rc = GPG_ERR_NO_USER_ID;
- }
-
- if( rc )
- release_sk_list( sk_list );
- else
- *ret_sk_list = sk_list;
- return rc;
-}
-
diff --git a/g10/status.c b/g10/status.c
deleted file mode 100644
index aa55020be..000000000
--- a/g10/status.c
+++ /dev/null
@@ -1,472 +0,0 @@
-/* status.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2002,
- * 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <signal.h>
-
-#include "gpg.h"
-#include "util.h"
-#include "status.h"
-#include "ttyio.h"
-#include "options.h"
-#include "main.h"
-#include "i18n.h"
-#include "cipher.h" /* for progress functions */
-
-#define CONTROL_D ('D' - 'A' + 1)
-
-
-
-static FILE *statusfp;
-
-
-static void
-progress_cb (void *ctx, const char *what, int printchar, int current, int total)
-{
- char buf[150];
-
- if (printchar == '\n')
- printchar = 'X';
-
- sprintf (buf, "%.20s %c %d %d", what, printchar, current, total);
- write_status_text (STATUS_PROGRESS, buf);
-}
-
-static const char *
-get_status_string ( int no )
-{
- const char *s;
-
- switch( no ) {
- case STATUS_ENTER : s = "ENTER"; break;
- case STATUS_LEAVE : s = "LEAVE"; break;
- case STATUS_ABORT : s = "ABORT"; break;
- case STATUS_GOODSIG: s = "GOODSIG"; break;
- case STATUS_KEYEXPIRED: s = "KEYEXPIRED"; break;
- case STATUS_KEYREVOKED: s = "KEYREVOKED"; break;
- case STATUS_BADSIG : s = "BADSIG"; break;
- case STATUS_ERRSIG : s = "ERRSIG"; break;
- case STATUS_BADARMOR : s = "BADARMOR"; break;
- case STATUS_RSA_OR_IDEA : s= "RSA_OR_IDEA"; break;
- case STATUS_TRUST_UNDEFINED: s = "TRUST_UNDEFINED"; break;
- case STATUS_TRUST_NEVER : s = "TRUST_NEVER"; break;
- case STATUS_TRUST_MARGINAL : s = "TRUST_MARGINAL"; break;
- case STATUS_TRUST_FULLY : s = "TRUST_FULLY"; break;
- case STATUS_TRUST_ULTIMATE : s = "TRUST_ULTIMATE"; break;
- case STATUS_GET_BOOL : s = "GET_BOOL"; break;
- case STATUS_GET_LINE : s = "GET_LINE"; break;
- case STATUS_GET_HIDDEN : s = "GET_HIDDEN"; break;
- case STATUS_GOT_IT : s = "GOT_IT"; break;
- case STATUS_SHM_INFO : s = "SHM_INFO"; break;
- case STATUS_SHM_GET : s = "SHM_GET"; break;
- case STATUS_SHM_GET_BOOL : s = "SHM_GET_BOOL"; break;
- case STATUS_SHM_GET_HIDDEN : s = "SHM_GET_HIDDEN"; break;
- case STATUS_NEED_PASSPHRASE: s = "NEED_PASSPHRASE"; break;
- case STATUS_VALIDSIG : s = "VALIDSIG"; break;
- case STATUS_SIG_ID : s = "SIG_ID"; break;
- case STATUS_ENC_TO : s = "ENC_TO"; break;
- case STATUS_NODATA : s = "NODATA"; break;
- case STATUS_BAD_PASSPHRASE : s = "BAD_PASSPHRASE"; break;
- case STATUS_NO_PUBKEY : s = "NO_PUBKEY"; break;
- case STATUS_NO_SECKEY : s = "NO_SECKEY"; break;
- case STATUS_NEED_PASSPHRASE_SYM: s = "NEED_PASSPHRASE_SYM"; break;
- case STATUS_DECRYPTION_FAILED: s = "DECRYPTION_FAILED"; break;
- case STATUS_DECRYPTION_OKAY: s = "DECRYPTION_OKAY"; break;
- case STATUS_MISSING_PASSPHRASE: s = "MISSING_PASSPHRASE"; break;
- case STATUS_GOOD_PASSPHRASE : s = "GOOD_PASSPHRASE"; break;
- case STATUS_GOODMDC : s = "GOODMDC"; break;
- case STATUS_BADMDC : s = "BADMDC"; break;
- case STATUS_ERRMDC : s = "ERRMDC"; break;
- case STATUS_IMPORTED : s = "IMPORTED"; break;
- case STATUS_IMPORT_OK : s = "IMPORT_OK"; break;
- case STATUS_IMPORT_CHECK : s = "IMPORT_CHECK"; break;
- case STATUS_IMPORT_RES : s = "IMPORT_RES"; break;
- case STATUS_FILE_START : s = "FILE_START"; break;
- case STATUS_FILE_DONE : s = "FILE_DONE"; break;
- case STATUS_FILE_ERROR : s = "FILE_ERROR"; break;
- case STATUS_BEGIN_DECRYPTION:s = "BEGIN_DECRYPTION"; break;
- case STATUS_END_DECRYPTION : s = "END_DECRYPTION"; break;
- case STATUS_BEGIN_ENCRYPTION:s = "BEGIN_ENCRYPTION"; break;
- case STATUS_END_ENCRYPTION : s = "END_ENCRYPTION"; break;
- case STATUS_DELETE_PROBLEM : s = "DELETE_PROBLEM"; break;
- case STATUS_PROGRESS : s = "PROGRESS"; break;
- case STATUS_SIG_CREATED : s = "SIG_CREATED"; break;
- case STATUS_SESSION_KEY : s = "SESSION_KEY"; break;
- case STATUS_NOTATION_NAME : s = "NOTATION_NAME" ; break;
- case STATUS_NOTATION_DATA : s = "NOTATION_DATA" ; break;
- case STATUS_POLICY_URL : s = "POLICY_URL" ; break;
- case STATUS_BEGIN_STREAM : s = "BEGIN_STREAM"; break;
- case STATUS_END_STREAM : s = "END_STREAM"; break;
- case STATUS_KEY_CREATED : s = "KEY_CREATED"; break;
- case STATUS_USERID_HINT : s = "USERID_HINT"; break;
- case STATUS_UNEXPECTED : s = "UNEXPECTED"; break;
- case STATUS_INV_RECP : s = "INV_RECP"; break;
- case STATUS_NO_RECP : s = "NO_RECP"; break;
- case STATUS_ALREADY_SIGNED : s = "ALREADY_SIGNED"; break;
- case STATUS_SIGEXPIRED : s = "SIGEXPIRED deprecated-use-keyexpired-instead"; break;
- case STATUS_EXPSIG : s = "EXPSIG"; break;
- case STATUS_EXPKEYSIG : s = "EXPKEYSIG"; break;
- case STATUS_REVKEYSIG : s = "REVKEYSIG"; break;
- case STATUS_ATTRIBUTE : s = "ATTRIBUTE"; break;
- default: s = "?"; break;
- }
- return s;
-}
-
-void
-set_status_fd ( int fd )
-{
- static int last_fd = -1;
-
- if ( fd != -1 && last_fd == fd )
- return;
-
- if ( statusfp && statusfp != stdout && statusfp != stderr )
- fclose (statusfp);
- statusfp = NULL;
- if ( fd == -1 )
- return;
-
- if( fd == 1 )
- statusfp = stdout;
- else if( fd == 2 )
- statusfp = stderr;
- else
- statusfp = fdopen( fd, "w" );
- if( !statusfp ) {
- log_fatal("can't open fd %d for status output: %s\n",
- fd, strerror(errno));
- }
- last_fd = fd;
- gcry_set_progress_handler (progress_cb, NULL);
-}
-
-int
-is_status_enabled()
-{
- return !!statusfp;
-}
-
-void
-write_status ( int no )
-{
- write_status_text( no, NULL );
-}
-
-void
-write_status_text ( int no, const char *text)
-{
- if( !statusfp )
- return; /* not enabled */
-
- fputs ( "[GNUPG:] ", statusfp );
- fputs ( get_status_string (no), statusfp );
- if( text ) {
- putc ( ' ', statusfp );
- for (; *text; text++) {
- if (*text == '\n')
- fputs ( "\\n", statusfp );
- else if (*text == '\r')
- fputs ( "\\r", statusfp );
- else
- putc ( *(const byte *)text, statusfp );
- }
- }
- putc ('\n',statusfp);
- fflush (statusfp);
-}
-
-
-/*
- * Write a status line with a buffer using %XX escapes. If WRAP is >
- * 0 wrap the line after this length. If STRING is not NULL it will
- * be prepended to the buffer, no escaping is done for string.
- * A wrap of -1 forces spaces not to be encoded as %20.
- */
-void
-write_status_text_and_buffer ( int no, const char *string,
- const char *buffer, size_t len, int wrap )
-{
- const char *s, *text;
- int esc, first;
- int lower_limit = ' ';
- size_t n, count, dowrap;
-
- if( !statusfp )
- return; /* not enabled */
-
- if (wrap == -1) {
- lower_limit--;
- wrap = 0;
- }
-
- text = get_status_string (no);
- count = dowrap = first = 1;
- do {
- if (dowrap) {
- fprintf (statusfp, "[GNUPG:] %s ", text );
- count = dowrap = 0;
- if (first && string) {
- fputs (string, statusfp);
- count += strlen (string);
- }
- first = 0;
- }
- for (esc=0, s=buffer, n=len; n && !esc; s++, n-- ) {
- if ( *s == '%' || *(const byte*)s <= lower_limit
- || *(const byte*)s == 127 )
- esc = 1;
- if ( wrap && ++count > wrap ) {
- dowrap=1;
- break;
- }
- }
- if (esc) {
- s--; n++;
- }
- if (s != buffer)
- fwrite (buffer, s-buffer, 1, statusfp );
- if ( esc ) {
- fprintf (statusfp, "%%%02X", *(const byte*)s );
- s++; n--;
- }
- buffer = s;
- len = n;
- if ( dowrap && len )
- putc ( '\n', statusfp );
- } while ( len );
-
- putc ('\n',statusfp);
- fflush (statusfp);
-}
-
-void
-write_status_buffer ( int no, const char *buffer, size_t len, int wrap )
-{
- write_status_text_and_buffer (no, NULL, buffer, len, wrap);
-}
-
-
-
-static int
-myread(int fd, void *buf, size_t count)
-{
- int rc;
- do {
- rc = read( fd, buf, count );
- } while ( rc == -1 && errno == EINTR );
- if ( !rc && count ) {
- static int eof_emmited=0;
- if ( eof_emmited < 3 ) {
- *(char*)buf = CONTROL_D;
- rc = 1;
- eof_emmited++;
- }
- else { /* Ctrl-D not caught - do something reasonable */
-#ifdef HAVE_DOSISH_SYSTEM
- raise (SIGINT); /* nothing to hangup under DOS */
-#else
- raise (SIGHUP); /* no more input data */
-#endif
- }
- }
- return rc;
-}
-
-
-
-/****************
- * Request a string from the client over the command-fd
- * If bool, returns static string on true (do not free) or NULL for false
- */
-static char *
-do_get_from_fd( const char *keyword, int hidden, int bool )
-{
- int i, len;
- char *string;
-
- write_status_text( bool? STATUS_GET_BOOL :
- hidden? STATUS_GET_HIDDEN : STATUS_GET_LINE, keyword );
-
- for( string = NULL, i = len = 200; ; i++ ) {
- if( i >= len-1 ) {
- char *save = string;
- len += 100;
- string = hidden? xmalloc_secure ( len ) : xmalloc ( len );
- if( save )
- memcpy(string, save, i );
- else
- i=0;
- }
- /* Hmmm: why not use our read_line function here */
- if( myread( opt.command_fd, string+i, 1) != 1 || string[i] == '\n' )
- break;
- else if ( string[i] == CONTROL_D ) {
- /* found ETX - cancel the line and return a sole ETX */
- string[0] = CONTROL_D;
- i=1;
- break;
- }
- }
- string[i] = 0;
-
- write_status( STATUS_GOT_IT );
-
- if( bool ) /* Fixme: is this correct??? */
- return (string[0] == 'Y' || string[0] == 'y') ? "" : NULL;
-
- return string;
-}
-
-
-
-int
-cpr_enabled()
-{
- if( opt.command_fd != -1 )
- return 1;
- return 0;
-}
-
-char *
-cpr_get_no_help( const char *keyword, const char *prompt )
-{
- char *p;
-
- if( opt.command_fd != -1 )
- return do_get_from_fd ( keyword, 0, 0 );
- for(;;) {
- p = tty_get( prompt );
- return p;
- }
-}
-
-char *
-cpr_get( const char *keyword, const char *prompt )
-{
- char *p;
-
- if( opt.command_fd != -1 )
- return do_get_from_fd ( keyword, 0, 0 );
- for(;;) {
- p = tty_get( prompt );
- if( *p=='?' && !p[1] && !(keyword && !*keyword)) {
- xfree (p);
- display_online_help( keyword );
- }
- else
- return p;
- }
-}
-
-
-char *
-cpr_get_utf8( const char *keyword, const char *prompt )
-{
- char *p;
- p = cpr_get( keyword, prompt );
- if( p ) {
- char *utf8 = native_to_utf8( p );
- xfree ( p );
- p = utf8;
- }
- return p;
-}
-
-char *
-cpr_get_hidden( const char *keyword, const char *prompt )
-{
- char *p;
-
- if( opt.command_fd != -1 )
- return do_get_from_fd ( keyword, 1, 0 );
- for(;;) {
- p = tty_get_hidden( prompt );
- if( *p == '?' && !p[1] ) {
- xfree (p);
- display_online_help( keyword );
- }
- else
- return p;
- }
-}
-
-void
-cpr_kill_prompt(void)
-{
- if( opt.command_fd != -1 )
- return;
- tty_kill_prompt();
- return;
-}
-
-int
-cpr_get_answer_is_yes( const char *keyword, const char *prompt )
-{
- int yes;
- char *p;
-
- if( opt.command_fd != -1 )
- return !!do_get_from_fd ( keyword, 0, 1 );
- for(;;) {
- p = tty_get( prompt );
- trim_spaces(p); /* it is okay to do this here */
- if( *p == '?' && !p[1] ) {
- xfree (p);
- display_online_help( keyword );
- }
- else {
- tty_kill_prompt();
- yes = answer_is_yes(p);
- xfree (p);
- return yes;
- }
- }
-}
-
-int
-cpr_get_answer_yes_no_quit( const char *keyword, const char *prompt )
-{
- int yes;
- char *p;
-
- if( opt.command_fd != -1 )
- return !!do_get_from_fd ( keyword, 0, 1 );
- for(;;) {
- p = tty_get( prompt );
- trim_spaces(p); /* it is okay to do this here */
- if( *p == '?' && !p[1] ) {
- xfree (p);
- display_online_help( keyword );
- }
- else {
- tty_kill_prompt();
- yes = answer_is_yes_no_quit(p);
- xfree (p);
- return yes;
- }
- }
-}
diff --git a/g10/status.h b/g10/status.h
deleted file mode 100644
index d8de81080..000000000
--- a/g10/status.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* status.h
- * Copyright (C) 1998, 1999, 2000, 2001 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef G10_STATUS_H
-#define G10_STATUS_H
-
-
-#define STATUS_ENTER 1
-#define STATUS_LEAVE 2
-#define STATUS_ABORT 3
-
-#define STATUS_GOODSIG 4
-#define STATUS_BADSIG 5
-#define STATUS_ERRSIG 6
-
-
-#define STATUS_BADARMOR 7
-
-#define STATUS_RSA_OR_IDEA 8
-#define STATUS_KEYEXPIRED 9
-#define STATUS_KEYREVOKED 10
-
-#define STATUS_TRUST_UNDEFINED 11
-#define STATUS_TRUST_NEVER 12
-#define STATUS_TRUST_MARGINAL 13
-#define STATUS_TRUST_FULLY 14
-#define STATUS_TRUST_ULTIMATE 15
-
-#define STATUS_SHM_INFO 16
-#define STATUS_SHM_GET 17
-#define STATUS_SHM_GET_BOOL 18
-#define STATUS_SHM_GET_HIDDEN 19
-
-#define STATUS_NEED_PASSPHRASE 20
-#define STATUS_VALIDSIG 21
-#define STATUS_SIG_ID 22
-#define STATUS_ENC_TO 23
-#define STATUS_NODATA 24
-#define STATUS_BAD_PASSPHRASE 25
-#define STATUS_NO_PUBKEY 26
-#define STATUS_NO_SECKEY 27
-#define STATUS_NEED_PASSPHRASE_SYM 28
-#define STATUS_DECRYPTION_FAILED 29
-#define STATUS_DECRYPTION_OKAY 30
-#define STATUS_MISSING_PASSPHRASE 31
-#define STATUS_GOOD_PASSPHRASE 32
-#define STATUS_GOODMDC 33
-#define STATUS_BADMDC 34
-#define STATUS_ERRMDC 35
-#define STATUS_IMPORTED 36
-#define STATUS_IMPORT_RES 37
-#define STATUS_FILE_START 38
-#define STATUS_FILE_DONE 39
-#define STATUS_FILE_ERROR 40
-
-#define STATUS_BEGIN_DECRYPTION 41
-#define STATUS_END_DECRYPTION 42
-#define STATUS_BEGIN_ENCRYPTION 43
-#define STATUS_END_ENCRYPTION 44
-
-#define STATUS_DELETE_PROBLEM 45
-#define STATUS_GET_BOOL 46
-#define STATUS_GET_LINE 47
-#define STATUS_GET_HIDDEN 48
-#define STATUS_GOT_IT 49
-#define STATUS_PROGRESS 50
-#define STATUS_SIG_CREATED 51
-#define STATUS_SESSION_KEY 52
-#define STATUS_NOTATION_NAME 53
-#define STATUS_NOTATION_DATA 54
-#define STATUS_POLICY_URL 55
-#define STATUS_BEGIN_STREAM 56
-#define STATUS_END_STREAM 57
-#define STATUS_KEY_CREATED 58
-#define STATUS_USERID_HINT 59
-#define STATUS_UNEXPECTED 60
-#define STATUS_INV_RECP 61
-#define STATUS_NO_RECP 62
-#define STATUS_ALREADY_SIGNED 63
-#define STATUS_SIGEXPIRED 64
-#define STATUS_EXPSIG 65
-#define STATUS_EXPKEYSIG 66
-#define STATUS_ATTRIBUTE 67
-#define STATUS_IMPORT_OK 68
-#define STATUS_IMPORT_CHECK 69
-#define STATUS_REVKEYSIG 70
-
-/*-- status.c --*/
-void set_status_fd ( int fd );
-int is_status_enabled ( void );
-void write_status ( int no );
-void write_status_text ( int no, const char *text );
-void write_status_buffer ( int no,
- const char *buffer, size_t len, int wrap );
-void write_status_text_and_buffer ( int no, const char *text,
- const char *buffer, size_t len, int wrap );
-
-int cpr_enabled(void);
-char *cpr_get( const char *keyword, const char *prompt );
-char *cpr_get_no_help( const char *keyword, const char *prompt );
-char *cpr_get_utf8( const char *keyword, const char *prompt );
-char *cpr_get_hidden( const char *keyword, const char *prompt );
-void cpr_kill_prompt(void);
-int cpr_get_answer_is_yes( const char *keyword, const char *prompt );
-int cpr_get_answer_yes_no_quit( const char *keyword, const char *prompt );
-
-
-#endif /*G10_STATUS_H*/
diff --git a/g10/tdbdump.c b/g10/tdbdump.c
deleted file mode 100644
index 5eb482959..000000000
--- a/g10/tdbdump.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* tdbdump.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2003 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "gpg.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "keydb.h"
-#include "memory.h"
-#include "util.h"
-#include "trustdb.h"
-#include "options.h"
-#include "packet.h"
-#include "main.h"
-#include "i18n.h"
-#include "tdbio.h"
-
-
-#define HEXTOBIN(x) ( (x) >= '0' && (x) <= '9' ? ((x)-'0') : \
- (x) >= 'A' && (x) <= 'F' ? ((x)-'A'+10) : ((x)-'a'+10))
-
-
-/****************
- * Wirte a record but die on error
- */
-static void
-write_record( TRUSTREC *rec )
-{
- int rc = tdbio_write_record( rec );
- if( !rc )
- return;
- log_error(_("trust record %lu, type %d: write failed: %s\n"),
- rec->recnum, rec->rectype, gpg_strerror (rc) );
- tdbio_invalid();
-}
-
-
-/****************
- * Dump the entire trustdb or only the entries of one key.
- */
-void
-list_trustdb( const char *username )
-{
- TRUSTREC rec;
-
- init_trustdb();
- /* for now we ignore the user ID */
- if (1) {
- ulong recnum;
- int i;
-
- printf("TrustDB: %s\n", tdbio_get_dbname() );
- for(i=9+strlen(tdbio_get_dbname()); i > 0; i-- )
- putchar('-');
- putchar('\n');
- for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ )
- tdbio_dump_record( &rec, stdout );
- }
-}
-
-
-
-
-
-/****************
- * Print a list of all defined owner trust value.
- */
-void
-export_ownertrust()
-{
- TRUSTREC rec;
- ulong recnum;
- int i;
- byte *p;
-
- init_trustdb();
- printf(_("# List of assigned trustvalues, created %s\n"
- "# (Use \"gpg --import-ownertrust\" to restore them)\n"),
- asctimestamp( make_timestamp() ) );
- for(recnum=0; !tdbio_read_record( recnum, &rec, 0); recnum++ ) {
- if( rec.rectype == RECTYPE_TRUST ) {
- if( !rec.r.trust.ownertrust )
- continue;
- p = rec.r.trust.fingerprint;
- for(i=0; i < 20; i++, p++ )
- printf("%02X", *p );
- printf(":%u:\n", (unsigned int)rec.r.trust.ownertrust );
- }
- }
-}
-
-
-void
-import_ownertrust( const char *fname )
-{
- FILE *fp;
- int is_stdin=0;
- char line[256];
- char *p;
- size_t n, fprlen;
- unsigned int otrust;
- byte fpr[20];
- int any = 0;
- int rc;
-
- init_trustdb();
- if( !fname || (*fname == '-' && !fname[1]) ) {
- fp = stdin;
- fname = "[stdin]";
- is_stdin = 1;
- }
- else if( !(fp = fopen( fname, "r" )) ) {
- log_error ( _("can't open `%s': %s\n"), fname, strerror(errno) );
- return;
- }
-
- while( fgets( line, DIM(line)-1, fp ) ) {
- TRUSTREC rec;
-
- if( !*line || *line == '#' )
- continue;
- n = strlen(line);
- if( line[n-1] != '\n' ) {
- log_error (_("\b%s: line too long\n"), fname );
- /* ... or last line does not have a LF */
- break; /* can't continue */
- }
- for(p = line; *p && *p != ':' ; p++ )
- if( !hexdigitp (p) )
- break;
- if( *p != ':' ) {
- log_error (_("\b%s: error: missing colon\n"), fname );
- continue;
- }
- fprlen = p - line;
- if( fprlen != 32 && fprlen != 40 ) {
- log_error (_("\b%s: error: invalid fingerprint\n"), fname );
- continue;
- }
- if( sscanf(p, ":%u:", &otrust ) != 1 ) {
- log_error (_("\b%s: error: no ownertrust value\n"), fname );
- continue;
- }
- if( !otrust )
- continue; /* no otrust defined - no need to update or insert */
- /* convert the ascii fingerprint to binary */
- for(p=line, fprlen=0; fprlen < 20 && *p != ':'; p += 2 )
- fpr[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]);
- while (fprlen < 20)
- fpr[fprlen++] = 0;
-
- rc = tdbio_search_trust_byfpr (fpr, &rec);
- if( !rc ) { /* found: update */
- if (rec.r.trust.ownertrust != otrust)
- {
- if( rec.r.trust.ownertrust )
- log_info("changing ownertrust from %u to %u\n",
- rec.r.trust.ownertrust, otrust );
- else
- log_info("setting ownertrust to %u\n", otrust );
- rec.r.trust.ownertrust = otrust;
- write_record (&rec );
- any = 1;
- }
- }
- else if( rc == -1 ) { /* not found: insert */
- log_info("inserting ownertrust of %u\n", otrust );
- memset (&rec, 0, sizeof rec);
- rec.recnum = tdbio_new_recnum ();
- rec.rectype = RECTYPE_TRUST;
- memcpy (rec.r.trust.fingerprint, fpr, 20);
- rec.r.trust.ownertrust = otrust;
- write_record (&rec );
- any = 1;
- }
- else /* error */
- log_error (_("\b%s: error finding trust record: %s\n"),
- fname, gpg_strerror (rc));
- }
- if( ferror(fp) )
- log_error (_("\b%s: read error: %s\n"), fname, strerror(errno) );
- if( !is_stdin )
- fclose(fp);
-
- if (any)
- {
- revalidation_mark ();
- rc = tdbio_sync ();
- if (rc)
- log_error (_("trustdb: sync failed: %s\n"), gpg_strerror (rc) );
- }
-
-}
-
-
diff --git a/g10/tdbio.c b/g10/tdbio.c
deleted file mode 100644
index 75687a3b0..000000000
--- a/g10/tdbio.c
+++ /dev/null
@@ -1,1636 +0,0 @@
-/* tdbio.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "gpg.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "memory.h"
-#include "util.h"
-#include "options.h"
-#include "main.h"
-#include "i18n.h"
-#include "trustdb.h"
-#include "tdbio.h"
-
-#if defined(HAVE_DOSISH_SYSTEM)
-#define ftruncate chsize
-#endif
-
-#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
-#define MY_O_BINARY O_BINARY
-#else
-#define MY_O_BINARY 0
-#endif
-
-
-/****************
- * Yes, this is a very simple implementation. We should really
- * use a page aligned buffer and read complete pages.
- * To implement a simple trannsaction system, this is sufficient.
- */
-typedef struct cache_ctrl_struct *CACHE_CTRL;
-struct cache_ctrl_struct {
- CACHE_CTRL next;
- struct {
- unsigned used:1;
- unsigned dirty:1;
- } flags;
- ulong recno;
- char data[TRUST_RECORD_LEN];
-};
-
-#define MAX_CACHE_ENTRIES_SOFT 200 /* may be increased while in a */
-#define MAX_CACHE_ENTRIES_HARD 10000 /* transaction to this one */
-static CACHE_CTRL cache_list;
-static int cache_entries;
-static int cache_is_dirty;
-
-/* a type used to pass infomation to cmp_krec_fpr */
-struct cmp_krec_fpr_struct {
- int pubkey_algo;
- const char *fpr;
- int fprlen;
-};
-
-/* a type used to pass infomation to cmp_[s]dir */
-struct cmp_xdir_struct {
- int pubkey_algo;
- u32 keyid[2];
-};
-
-
-static char *db_name;
-static DOTLOCK lockhandle;
-static int is_locked;
-static int db_fd = -1;
-static int in_transaction;
-
-static void open_db(void);
-static void migrate_from_v2 (void);
-
-
-
-/*************************************
- ************* record cache **********
- *************************************/
-
-/****************
- * Get the data from therecord cache and return a
- * pointer into that cache. Caller should copy
- * the return data. NULL is returned on a cache miss.
- */
-static const char *
-get_record_from_cache( ulong recno )
-{
- CACHE_CTRL r;
-
- for( r = cache_list; r; r = r->next ) {
- if( r->flags.used && r->recno == recno )
- return r->data;
- }
- return NULL;
-}
-
-
-static int
-write_cache_item( CACHE_CTRL r )
-{
- int n;
- gpg_error_t rc;
-
- if( lseek( db_fd, r->recno * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("trustdb rec %lu: lseek failed: %s\n"),
- r->recno, strerror(errno) );
- return rc;
- }
- n = write( db_fd, r->data, TRUST_RECORD_LEN);
- if( n != TRUST_RECORD_LEN ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("trustdb rec %lu: write failed (n=%d): %s\n"),
- r->recno, n, strerror(errno) );
- return rc;
- }
- r->flags.dirty = 0;
- return 0;
-}
-
-/****************
- * Put data into the cache. This function may flush the
- * some cache entries if there is not enough space available.
- */
-int
-put_record_into_cache( ulong recno, const char *data )
-{
- CACHE_CTRL r, unused;
- int dirty_count = 0;
- int clean_count = 0;
-
- /* see whether we already cached this one */
- for( unused = NULL, r = cache_list; r; r = r->next ) {
- if( !r->flags.used ) {
- if( !unused )
- unused = r;
- }
- else if( r->recno == recno ) {
- if( !r->flags.dirty ) {
- /* Hmmm: should we use a a copy and compare? */
- if( memcmp(r->data, data, TRUST_RECORD_LEN ) ) {
- r->flags.dirty = 1;
- cache_is_dirty = 1;
- }
- }
- memcpy( r->data, data, TRUST_RECORD_LEN );
- return 0;
- }
- if( r->flags.used ) {
- if( r->flags.dirty )
- dirty_count++;
- else
- clean_count++;
- }
- }
- /* not in the cache: add a new entry */
- if( unused ) { /* reuse this entry */
- r = unused;
- r->flags.used = 1;
- r->recno = recno;
- memcpy( r->data, data, TRUST_RECORD_LEN );
- r->flags.dirty = 1;
- cache_is_dirty = 1;
- cache_entries++;
- return 0;
- }
- /* see whether we reached the limit */
- if( cache_entries < MAX_CACHE_ENTRIES_SOFT ) { /* no */
- r = xmalloc ( sizeof *r );
- r->flags.used = 1;
- r->recno = recno;
- memcpy( r->data, data, TRUST_RECORD_LEN );
- r->flags.dirty = 1;
- r->next = cache_list;
- cache_list = r;
- cache_is_dirty = 1;
- cache_entries++;
- return 0;
- }
- /* cache is full: discard some clean entries */
- if( clean_count ) {
- int n = clean_count / 3; /* discard a third of the clean entries */
- if( !n )
- n = 1;
- for( unused = NULL, r = cache_list; r; r = r->next ) {
- if( r->flags.used && !r->flags.dirty ) {
- if( !unused )
- unused = r;
- r->flags.used = 0;
- cache_entries--;
- if( !--n )
- break;
- }
- }
- assert( unused );
- r = unused;
- r->flags.used = 1;
- r->recno = recno;
- memcpy( r->data, data, TRUST_RECORD_LEN );
- r->flags.dirty = 1;
- cache_is_dirty = 1;
- cache_entries++;
- return 0;
- }
- /* no clean entries: have to flush some dirty entries */
- if( in_transaction ) {
- /* but we can't do this while in a transaction
- * we increase the cache size instead */
- if( cache_entries < MAX_CACHE_ENTRIES_HARD ) { /* no */
- if( opt.debug && !(cache_entries % 100) )
- log_debug("increasing tdbio cache size\n");
- r = xmalloc ( sizeof *r );
- r->flags.used = 1;
- r->recno = recno;
- memcpy( r->data, data, TRUST_RECORD_LEN );
- r->flags.dirty = 1;
- r->next = cache_list;
- cache_list = r;
- cache_is_dirty = 1;
- cache_entries++;
- return 0;
- }
- log_info(_("trustdb transaction too large\n"));
- return GPG_ERR_RESOURCE_LIMIT;
- }
- if( dirty_count ) {
- int n = dirty_count / 5; /* discard some dirty entries */
- if( !n )
- n = 1;
- if( !is_locked ) {
- if( make_dotlock( lockhandle, -1 ) )
- log_fatal("can't acquire lock - giving up\n");
- else
- is_locked = 1;
- }
- for( unused = NULL, r = cache_list; r; r = r->next ) {
- if( r->flags.used && r->flags.dirty ) {
- int rc = write_cache_item( r );
- if( rc )
- return rc;
- if( !unused )
- unused = r;
- r->flags.used = 0;
- cache_entries--;
- if( !--n )
- break;
- }
- }
- if( !opt.lock_once ) {
- if( !release_dotlock( lockhandle ) )
- is_locked = 0;
- }
- assert( unused );
- r = unused;
- r->flags.used = 1;
- r->recno = recno;
- memcpy( r->data, data, TRUST_RECORD_LEN );
- r->flags.dirty = 1;
- cache_is_dirty = 1;
- cache_entries++;
- return 0;
- }
- BUG();
-}
-
-
-int
-tdbio_is_dirty()
-{
- return cache_is_dirty;
-}
-
-
-/****************
- * Flush the cache. This cannot be used while in a transaction.
- */
-int
-tdbio_sync()
-{
- CACHE_CTRL r;
- int did_lock = 0;
-
- if( db_fd == -1 )
- open_db();
- if( in_transaction )
- log_bug("tdbio: syncing while in transaction\n");
-
- if( !cache_is_dirty )
- return 0;
-
- if( !is_locked ) {
- if( make_dotlock( lockhandle, -1 ) )
- log_fatal("can't acquire lock - giving up\n");
- else
- is_locked = 1;
- did_lock = 1;
- }
- for( r = cache_list; r; r = r->next ) {
- if( r->flags.used && r->flags.dirty ) {
- int rc = write_cache_item( r );
- if( rc )
- return rc;
- }
- }
- cache_is_dirty = 0;
- if( did_lock && !opt.lock_once ) {
- if( !release_dotlock( lockhandle ) )
- is_locked = 0;
- }
-
- return 0;
-}
-
-
-#if 0
-/* The transaction code is disabled in the 1.2.x branch, as it is not
- yet used. It will be enabled in 1.3.x. */
-
-/****************
- * Simple transactions system:
- * Everything between begin_transaction and end/cancel_transaction
- * is not immediatly written but at the time of end_transaction.
- *
- */
-int
-tdbio_begin_transaction()
-{
- int rc;
-
- if( in_transaction )
- log_bug("tdbio: nested transactions\n");
- /* flush everything out */
- rc = tdbio_sync();
- if( rc )
- return rc;
- in_transaction = 1;
- return 0;
-}
-
-int
-tdbio_end_transaction()
-{
- int rc;
-
- if( !in_transaction )
- log_bug("tdbio: no active transaction\n");
- if( !is_locked ) {
- if( make_dotlock( lockhandle, -1 ) )
- log_fatal("can't acquire lock - giving up\n");
- else
- is_locked = 1;
- }
-#warning block_all_signals is not yet available in ../common/signals.c
- /* block_all_signals(); */
- in_transaction = 0;
- rc = tdbio_sync();
-/* unblock_all_signals(); */
- if( !opt.lock_once ) {
- if( !release_dotlock( lockhandle ) )
- is_locked = 0;
- }
- return rc;
-}
-
-int
-tdbio_cancel_transaction()
-{
- CACHE_CTRL r;
-
- if( !in_transaction )
- log_bug("tdbio: no active transaction\n");
-
- /* remove all dirty marked entries, so that the original ones
- * are read back the next time */
- if( cache_is_dirty ) {
- for( r = cache_list; r; r = r->next ) {
- if( r->flags.used && r->flags.dirty ) {
- r->flags.used = 0;
- cache_entries--;
- }
- }
- cache_is_dirty = 0;
- }
-
- in_transaction = 0;
- return 0;
-}
-
-#endif /* transaction code */
-
-
-
-/********************************************************
- **************** cached I/O functions ******************
- ********************************************************/
-
-static void
-cleanup(void)
-{
- if( is_locked ) {
- if( !release_dotlock(lockhandle) )
- is_locked = 0;
- }
-}
-
-/* Caller must sync */
-int
-tdbio_update_version_record (void)
-{
- TRUSTREC rec;
- int rc;
-
- memset( &rec, 0, sizeof rec );
-
- rc=tdbio_read_record( 0, &rec, RECTYPE_VER);
- if(rc==0)
- {
- rec.r.ver.created = make_timestamp();
- rec.r.ver.marginals = opt.marginals_needed;
- rec.r.ver.completes = opt.completes_needed;
- rec.r.ver.cert_depth = opt.max_cert_depth;
- rec.r.ver.trust_model = opt.trust_model;
- rc=tdbio_write_record(&rec);
- }
-
- return rc;
-}
-
-static int
-create_version_record (void)
-{
- TRUSTREC rec;
- int rc;
-
- memset( &rec, 0, sizeof rec );
- rec.r.ver.version = 3;
- rec.r.ver.created = make_timestamp();
- rec.r.ver.marginals = opt.marginals_needed;
- rec.r.ver.completes = opt.completes_needed;
- rec.r.ver.cert_depth = opt.max_cert_depth;
- if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
- rec.r.ver.trust_model = opt.trust_model;
- else
- rec.r.ver.trust_model = TM_PGP;
- rec.rectype = RECTYPE_VER;
- rec.recnum = 0;
- rc = tdbio_write_record( &rec );
- if( !rc )
- tdbio_sync();
- return rc;
-}
-
-
-
-int
-tdbio_set_dbname( const char *new_dbname, int create )
-{
- char *fname;
- static int initialized = 0;
-
- if( !initialized ) {
- atexit( cleanup );
- initialized = 1;
- }
-
- if(new_dbname==NULL)
- fname=make_filename(opt.homedir,"trustdb" EXTSEP_S "gpg", NULL);
- else if (*new_dbname != DIRSEP_C )
- {
- if (strchr(new_dbname, DIRSEP_C) )
- fname = make_filename (new_dbname, NULL);
- else
- fname = make_filename (opt.homedir, new_dbname, NULL);
- }
- else
- fname = xstrdup (new_dbname);
-
- if( access( fname, R_OK ) ) {
- if( errno != ENOENT ) {
- log_error( _("%s: can't access: %s\n"), fname, strerror(errno) );
- xfree (fname);
- return GPG_ERR_TRUSTDB;
- }
- if( create ) {
- FILE *fp;
- TRUSTREC rec;
- int rc;
- char *p = strrchr( fname, DIRSEP_C );
- mode_t oldmask;
-
- assert(p);
- *p = 0;
- if( access( fname, F_OK ) ) {
- try_make_homedir( fname );
- log_fatal( _("%s: directory does not exist!\n"), fname );
- }
- *p = DIRSEP_C;
-
- xfree (db_name);
- db_name = fname;
-#ifdef __riscos__
- if( !lockhandle )
- lockhandle = create_dotlock( db_name );
- if( !lockhandle )
- log_fatal( _("%s: can't create lock\n"), db_name );
- if( make_dotlock( lockhandle, -1 ) )
- log_fatal( _("%s: can't make lock\n"), db_name );
-#endif /* __riscos__ */
- oldmask=umask(077);
- fp =fopen( fname, "wb" );
- umask(oldmask);
- if( !fp )
- log_fatal( _("%s: can't create: %s\n"), fname, strerror(errno) );
- fclose(fp);
- db_fd = open( db_name, O_RDWR | MY_O_BINARY );
- if( db_fd == -1 )
- log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
-
-#ifndef __riscos__
- if( !lockhandle )
- lockhandle = create_dotlock( db_name );
- if( !lockhandle )
- log_fatal( _("%s: can't create lock\n"), db_name );
-#endif /* !__riscos__ */
-
- rc = create_version_record ();
- if( rc )
- log_fatal( _("%s: failed to create version record: %s"),
- fname, gpg_strerror (rc));
- /* and read again to check that we are okay */
- if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
- log_fatal( _("%s: invalid trustdb created\n"), db_name );
-
- if( !opt.quiet )
- log_info(_("%s: trustdb created\n"), db_name);
-
- return 0;
- }
- }
- xfree (db_name);
- db_name = fname;
- return 0;
-}
-
-
-const char *
-tdbio_get_dbname()
-{
- return db_name;
-}
-
-
-
-static void
-open_db()
-{
- byte buf[10];
- int n;
- TRUSTREC rec;
-
- assert( db_fd == -1 );
-
- if (!lockhandle )
- lockhandle = create_dotlock( db_name );
- if (!lockhandle )
- log_fatal( _("%s: can't create lock\n"), db_name );
-#ifdef __riscos__
- if (make_dotlock( lockhandle, -1 ) )
- log_fatal( _("%s: can't make lock\n"), db_name );
-#endif /* __riscos__ */
- db_fd = open (db_name, O_RDWR | MY_O_BINARY );
- if (db_fd == -1 && errno == EACCES) {
- db_fd = open (db_name, O_RDONLY | MY_O_BINARY );
- if (db_fd != -1)
- log_info (_("NOTE: trustdb not writable\n"));
- }
- if ( db_fd == -1 )
- log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
-
- /* check whether we need to do a version migration */
- do
- n = read (db_fd, buf, 5);
- while (n==-1 && errno == EINTR);
- if (n == 5 && !memcmp (buf, "\x01gpg\x02", 5))
- {
- migrate_from_v2 ();
- }
-
- /* read the version record */
- if (tdbio_read_record (0, &rec, RECTYPE_VER ) )
- log_fatal( _("%s: invalid trustdb\n"), db_name );
-}
-
-
-/****************
- * Make a hashtable: type 0 = trust hash
- */
-static void
-create_hashtable( TRUSTREC *vr, int type )
-{
- TRUSTREC rec;
- off_t offset;
- ulong recnum;
- int i, n, rc;
-
- offset = lseek( db_fd, 0, SEEK_END );
- if( offset == -1 )
- log_fatal("trustdb: lseek to end failed: %s\n", strerror(errno) );
- recnum = offset / TRUST_RECORD_LEN;
- assert(recnum); /* this is will never be the first record */
-
- if( !type )
- vr->r.ver.trusthashtbl = recnum;
-
- /* Now write the records */
- n = (256+ITEMS_PER_HTBL_RECORD-1) / ITEMS_PER_HTBL_RECORD;
- for(i=0; i < n; i++, recnum++ ) {
- memset( &rec, 0, sizeof rec );
- rec.rectype = RECTYPE_HTBL;
- rec.recnum = recnum;
- rc = tdbio_write_record( &rec );
- if( rc )
- log_fatal( _("%s: failed to create hashtable: %s\n"),
- db_name, gpg_strerror (rc));
- }
- /* update the version record */
- rc = tdbio_write_record( vr );
- if( !rc )
- rc = tdbio_sync();
- if( rc )
- log_fatal( _("%s: error updating version record: %s\n"),
- db_name, gpg_strerror (rc));
-}
-
-
-int
-tdbio_db_matches_options()
-{
- static int yes_no = -1;
-
- if( yes_no == -1 )
- {
- TRUSTREC vr;
- int rc;
-
- rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
- if( rc )
- log_fatal( _("%s: error reading version record: %s\n"),
- db_name, gpg_strerror (rc) );
-
- yes_no = vr.r.ver.marginals == opt.marginals_needed
- && vr.r.ver.completes == opt.completes_needed
- && vr.r.ver.cert_depth == opt.max_cert_depth
- && vr.r.ver.trust_model == opt.trust_model;
- }
-
- return yes_no;
-}
-
-byte
-tdbio_read_model(void)
-{
- TRUSTREC vr;
- int rc;
-
- rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
- if( rc )
- log_fatal( _("%s: error reading version record: %s\n"),
- db_name, gpg_strerror (rc) );
- return vr.r.ver.trust_model;
-}
-
-/****************
- * Return the nextstamp value.
- */
-ulong
-tdbio_read_nextcheck ()
-{
- TRUSTREC vr;
- int rc;
-
- rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
- if( rc )
- log_fatal( _("%s: error reading version record: %s\n"),
- db_name, gpg_strerror (rc) );
- return vr.r.ver.nextcheck;
-}
-
-/* Return true when the stamp was actually changed. */
-int
-tdbio_write_nextcheck (ulong stamp)
-{
- TRUSTREC vr;
- int rc;
-
- rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
- if( rc )
- log_fatal( _("%s: error reading version record: %s\n"),
- db_name, gpg_strerror (rc) );
-
- if (vr.r.ver.nextcheck == stamp)
- return 0;
-
- vr.r.ver.nextcheck = stamp;
- rc = tdbio_write_record( &vr );
- if( rc )
- log_fatal( _("%s: error writing version record: %s\n"),
- db_name, gpg_strerror (rc) );
- return 1;
-}
-
-
-
-/****************
- * Return the record number of the trusthash tbl or create a new one.
- */
-static ulong
-get_trusthashrec(void)
-{
- static ulong trusthashtbl; /* record number of the trust hashtable */
-
- if( !trusthashtbl ) {
- TRUSTREC vr;
- int rc;
-
- rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
- if( rc )
- log_fatal( _("%s: error reading version record: %s\n"),
- db_name, gpg_strerror (rc) );
- if( !vr.r.ver.trusthashtbl )
- create_hashtable( &vr, 0 );
-
- trusthashtbl = vr.r.ver.trusthashtbl;
- }
- return trusthashtbl;
-}
-
-
-
-/****************
- * Update a hashtable.
- * table gives the start of the table, key and keylen is the key,
- * newrecnum is the record number to insert.
- */
-static int
-upd_hashtable( ulong table, byte *key, int keylen, ulong newrecnum )
-{
- TRUSTREC lastrec, rec;
- ulong hashrec, item;
- int msb;
- int level=0;
- int rc, i;
-
- hashrec = table;
- next_level:
- msb = key[level];
- hashrec += msb / ITEMS_PER_HTBL_RECORD;
- rc = tdbio_read_record( hashrec, &rec, RECTYPE_HTBL );
- if( rc ) {
- log_error ("upd_hashtable in `%s': read failed: %s\n", db_name,
- gpg_strerror (rc) );
- return rc;
- }
-
- item = rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
- if( !item ) { /* insert a new item into the hash table */
- rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = newrecnum;
- rc = tdbio_write_record( &rec );
- if( rc ) {
- log_error ("upd_hashtable in `%s': write htbl failed: %s\n",
- db_name, gpg_strerror (rc) );
- return rc;
- }
- }
- else if( item != newrecnum ) { /* must do an update */
- lastrec = rec;
- rc = tdbio_read_record( item, &rec, 0 );
- if( rc ) {
- log_error( "upd_hashtable: read item failed: %s\n",
- gpg_strerror (rc) );
- return rc;
- }
-
- if( rec.rectype == RECTYPE_HTBL ) {
- hashrec = item;
- level++;
- if( level >= keylen ) {
- log_error( "hashtable has invalid indirections.\n");
- return GPG_ERR_TRUSTDB;
- }
- goto next_level;
- }
- else if( rec.rectype == RECTYPE_HLST ) { /* extend list */
- /* see whether the key is already in this list */
- for(;;) {
- for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
- if( rec.r.hlst.rnum[i] == newrecnum ) {
- return 0; /* okay, already in the list */
- }
- }
- if( rec.r.hlst.next ) {
- rc = tdbio_read_record( rec.r.hlst.next,
- &rec, RECTYPE_HLST);
- if( rc ) {
- log_error( "upd_hashtable: read hlst failed: %s\n",
- gpg_strerror (rc) );
- return rc;
- }
- }
- else
- break; /* not there */
- }
- /* find the next free entry and put it in */
- for(;;) {
- for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
- if( !rec.r.hlst.rnum[i] ) {
- rec.r.hlst.rnum[i] = newrecnum;
- rc = tdbio_write_record( &rec );
- if( rc )
- log_error( "upd_hashtable: write hlst failed: %s\n",
- gpg_strerror (rc) );
- return rc; /* done */
- }
- }
- if( rec.r.hlst.next ) {
- rc = tdbio_read_record( rec.r.hlst.next,
- &rec, RECTYPE_HLST );
- if( rc ) {
- log_error( "upd_hashtable: read hlst failed: %s\n",
- gpg_strerror (rc) );
- return rc;
- }
- }
- else { /* add a new list record */
- rec.r.hlst.next = item = tdbio_new_recnum();
- rc = tdbio_write_record( &rec );
- if( rc ) {
- log_error( "upd_hashtable: write hlst failed: %s\n",
- gpg_strerror (rc) );
- return rc;
- }
- memset( &rec, 0, sizeof rec );
- rec.rectype = RECTYPE_HLST;
- rec.recnum = item;
- rec.r.hlst.rnum[0] = newrecnum;
- rc = tdbio_write_record( &rec );
- if( rc )
- log_error( "upd_hashtable: write ext hlst failed: %s\n",
- gpg_strerror (rc) );
- return rc; /* done */
- }
- } /* end loop over hlst slots */
- }
- else if( rec.rectype == RECTYPE_TRUST ) { /* insert a list record */
- if( rec.recnum == newrecnum ) {
- return 0;
- }
- item = rec.recnum; /* save number of key record */
- memset( &rec, 0, sizeof rec );
- rec.rectype = RECTYPE_HLST;
- rec.recnum = tdbio_new_recnum();
- rec.r.hlst.rnum[0] = item; /* old keyrecord */
- rec.r.hlst.rnum[1] = newrecnum; /* and new one */
- rc = tdbio_write_record( &rec );
- if( rc ) {
- log_error( "upd_hashtable: write new hlst failed: %s\n",
- gpg_strerror (rc) );
- return rc;
- }
- /* update the hashtable record */
- lastrec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = rec.recnum;
- rc = tdbio_write_record( &lastrec );
- if( rc )
- log_error( "upd_hashtable: update htbl failed: %s\n",
- gpg_strerror (rc) );
- return rc; /* ready */
- }
- else {
- log_error( "hashtbl %lu: %lu/%d points to an invalid record %lu\n",
- table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item);
- list_trustdb(NULL);
- return GPG_ERR_TRUSTDB;
- }
- }
-
- return 0;
-}
-
-
-/****************
- * Drop an entry from a hashtable
- * table gives the start of the table, key and keylen is the key,
- */
-static int
-drop_from_hashtable( ulong table, byte *key, int keylen, ulong recnum )
-{
- TRUSTREC rec;
- ulong hashrec, item;
- int msb;
- int level=0;
- int rc, i;
-
- hashrec = table;
- next_level:
- msb = key[level];
- hashrec += msb / ITEMS_PER_HTBL_RECORD;
- rc = tdbio_read_record( hashrec, &rec, RECTYPE_HTBL );
- if( rc ) {
- log_error ("drop_from_hashtable `%s': read failed: %s\n",
- db_name, gpg_strerror (rc) );
- return rc;
- }
-
- item = rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
- if( !item ) /* not found - forget about it */
- return 0;
-
- if( item == recnum ) { /* tables points direct to the record */
- rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = 0;
- rc = tdbio_write_record( &rec );
- if( rc )
- log_error ("drop_from_hashtable `%s': write htbl failed: %s\n",
- db_name, gpg_strerror (rc) );
- return rc;
- }
-
- rc = tdbio_read_record( item, &rec, 0 );
- if( rc ) {
- log_error( "drop_from_hashtable: read item failed: %s\n",
- gpg_strerror (rc) );
- return rc;
- }
-
- if( rec.rectype == RECTYPE_HTBL ) {
- hashrec = item;
- level++;
- if( level >= keylen ) {
- log_error( "hashtable has invalid indirections.\n");
- return GPG_ERR_TRUSTDB;
- }
- goto next_level;
- }
-
- if( rec.rectype == RECTYPE_HLST ) {
- for(;;) {
- for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
- if( rec.r.hlst.rnum[i] == recnum ) {
- rec.r.hlst.rnum[i] = 0; /* drop */
- rc = tdbio_write_record( &rec );
- if( rc )
- log_error ("drop_from_hashtable `%s': "
- "write htbl failed: %s\n",
- db_name, gpg_strerror (rc) );
- return rc;
- }
- }
- if( rec.r.hlst.next ) {
- rc = tdbio_read_record( rec.r.hlst.next,
- &rec, RECTYPE_HLST);
- if( rc ) {
- log_error( "drop_from_hashtable: read hlst failed: %s\n",
- gpg_strerror (rc) );
- return rc;
- }
- }
- else
- return 0; /* key not in table */
- }
- }
-
- log_error( "hashtbl %lu: %lu/%d points to wrong record %lu\n",
- table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item);
- return GPG_ERR_TRUSTDB;
-}
-
-
-
-/****************
- * Lookup a record via the hashtable tablewith key/keylen and return the
- * result in rec. cmp() should return if the record is the desired one.
- * Returns -1 if not found, 0 if found or another errocode
- */
-static int
-lookup_hashtable( ulong table, const byte *key, size_t keylen,
- int (*cmpfnc)(void*, const TRUSTREC *), void *cmpdata,
- TRUSTREC *rec )
-{
- int rc;
- ulong hashrec, item;
- int msb;
- int level=0;
-
- hashrec = table;
- next_level:
- msb = key[level];
- hashrec += msb / ITEMS_PER_HTBL_RECORD;
- rc = tdbio_read_record( hashrec, rec, RECTYPE_HTBL );
- if( rc ) {
- log_error ("lookup_hashtable in `%s' failed: %s\n",
- db_name, gpg_strerror (rc) );
- return rc;
- }
-
- item = rec->r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
- if( !item )
- return -1; /* not found */
-
- rc = tdbio_read_record( item, rec, 0 );
- if( rc ) {
- log_error ("hashtable `%s' read failed: %s\n",
- db_name, gpg_strerror (rc) );
- return rc;
- }
- if( rec->rectype == RECTYPE_HTBL ) {
- hashrec = item;
- level++;
- if( level >= keylen ) {
- log_error ("hashtable `%s' has invalid indirections\n", db_name);
- return GPG_ERR_TRUSTDB;
- }
- goto next_level;
- }
- else if( rec->rectype == RECTYPE_HLST ) {
- for(;;) {
- int i;
-
- for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
- if( rec->r.hlst.rnum[i] ) {
- TRUSTREC tmp;
-
- rc = tdbio_read_record( rec->r.hlst.rnum[i], &tmp, 0 );
- if( rc ) {
- log_error( "lookup_hashtable: read item failed: %s\n",
- gpg_strerror (rc) );
- return rc;
- }
- if( (*cmpfnc)( cmpdata, &tmp ) ) {
- *rec = tmp;
- return 0;
- }
- }
- }
- if( rec->r.hlst.next ) {
- rc = tdbio_read_record( rec->r.hlst.next, rec, RECTYPE_HLST );
- if( rc ) {
- log_error( "lookup_hashtable: read hlst failed: %s\n",
- gpg_strerror (rc) );
- return rc;
- }
- }
- else
- return -1; /* not found */
- }
- }
-
-
- if( (*cmpfnc)( cmpdata, rec ) )
- return 0; /* really found */
-
- return -1; /* no: not found */
-}
-
-
-/****************
- * Update the trust hashtbl or create the table if it does not exist
- */
-static int
-update_trusthashtbl( TRUSTREC *tr )
-{
- return upd_hashtable( get_trusthashrec(),
- tr->r.trust.fingerprint, 20, tr->recnum );
-}
-
-
-
-void
-tdbio_dump_record( TRUSTREC *rec, FILE *fp )
-{
- int i;
- ulong rnum = rec->recnum;
-
- fprintf(fp, "rec %5lu, ", rnum );
-
- switch( rec->rectype ) {
- case 0: fprintf(fp, "blank\n");
- break;
- case RECTYPE_VER: fprintf(fp,
- "version, td=%lu, f=%lu, m/c/d=%d/%d/%d tm=%d nc=%lu (%s)\n",
- rec->r.ver.trusthashtbl,
- rec->r.ver.firstfree,
- rec->r.ver.marginals,
- rec->r.ver.completes,
- rec->r.ver.cert_depth,
- rec->r.ver.trust_model,
- rec->r.ver.nextcheck,
- strtimestamp(rec->r.ver.nextcheck)
- );
- break;
- case RECTYPE_FREE: fprintf(fp, "free, next=%lu\n", rec->r.free.next );
- break;
- case RECTYPE_HTBL:
- fprintf(fp, "htbl,");
- for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ )
- fprintf(fp, " %lu", rec->r.htbl.item[i] );
- putc('\n', fp);
- break;
- case RECTYPE_HLST:
- fprintf(fp, "hlst, next=%lu,", rec->r.hlst.next );
- for(i=0; i < ITEMS_PER_HLST_RECORD; i++ )
- fprintf(fp, " %lu", rec->r.hlst.rnum[i] );
- putc('\n', fp);
- break;
- case RECTYPE_TRUST:
- fprintf(fp, "trust ");
- for(i=0; i < 20; i++ )
- fprintf(fp, "%02X", rec->r.trust.fingerprint[i] );
- fprintf (fp, ", ot=%d, d=%d, vl=%lu\n", rec->r.trust.ownertrust,
- rec->r.trust.depth, rec->r.trust.validlist);
- break;
- case RECTYPE_VALID:
- fprintf(fp, "valid ");
- for(i=0; i < 20; i++ )
- fprintf(fp, "%02X", rec->r.valid.namehash[i] );
- fprintf (fp, ", v=%d, next=%lu\n", rec->r.valid.validity,
- rec->r.valid.next);
- break;
- default:
- fprintf(fp, "unknown type %d\n", rec->rectype );
- break;
- }
-}
-
-/****************
- * read the record with number recnum
- * returns: -1 on error, 0 on success
- */
-int
-tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
-{
- byte readbuf[TRUST_RECORD_LEN];
- const byte *buf, *p;
- int rc = 0;
- int n, i;
-
- if( db_fd == -1 )
- open_db();
- buf = get_record_from_cache( recnum );
- if( !buf ) {
- if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("trustdb: lseek failed: %s\n"), strerror(errno) );
- return rc;
- }
- n = read( db_fd, readbuf, TRUST_RECORD_LEN);
- if( !n ) {
- return -1; /* eof */
- }
- else if( n != TRUST_RECORD_LEN ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("trustdb: read failed (n=%d): %s\n"), n,
- strerror(errno) );
- return rc;
- }
- buf = readbuf;
- }
- rec->recnum = recnum;
- rec->dirty = 0;
- p = buf;
- rec->rectype = *p++;
- if( expected && rec->rectype != expected ) {
- log_error("%lu: read expected rec type %d, got %d\n",
- recnum, expected, rec->rectype );
- return GPG_ERR_TRUSTDB;
- }
- p++; /* skip reserved byte */
- switch( rec->rectype ) {
- case 0: /* unused (free) record */
- break;
- case RECTYPE_VER: /* version record */
- if( memcmp(buf+1, "gpg", 3 ) ) {
- log_error( _("%s: not a trustdb file\n"), db_name );
- rc = GPG_ERR_TRUSTDB;
- }
- p += 2; /* skip "gpg" */
- rec->r.ver.version = *p++;
- rec->r.ver.marginals = *p++;
- rec->r.ver.completes = *p++;
- rec->r.ver.cert_depth = *p++;
- rec->r.ver.trust_model = *p++;
- p += 3;
- rec->r.ver.created = buftoulong(p); p += 4;
- rec->r.ver.nextcheck = buftoulong(p); p += 4;
- p += 4;
- p += 4;
- rec->r.ver.firstfree =buftoulong(p); p += 4;
- p += 4;
- rec->r.ver.trusthashtbl =buftoulong(p); p += 4;
- if( recnum ) {
- log_error( _("%s: version record with recnum %lu\n"), db_name,
- (ulong)recnum );
- rc = GPG_ERR_TRUSTDB;
- }
- else if( rec->r.ver.version != 3 ) {
- log_error( _("%s: invalid file version %d\n"), db_name,
- rec->r.ver.version );
- rc = GPG_ERR_TRUSTDB;
- }
- break;
- case RECTYPE_FREE:
- rec->r.free.next = buftoulong(p); p += 4;
- break;
- case RECTYPE_HTBL:
- for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) {
- rec->r.htbl.item[i] = buftoulong(p); p += 4;
- }
- break;
- case RECTYPE_HLST:
- rec->r.hlst.next = buftoulong(p); p += 4;
- for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
- rec->r.hlst.rnum[i] = buftoulong(p); p += 4;
- }
- break;
- case RECTYPE_TRUST:
- memcpy( rec->r.trust.fingerprint, p, 20); p+=20;
- rec->r.trust.ownertrust = *p++;
- rec->r.trust.depth = *p++;
- rec->r.trust.min_ownertrust = *p++;
- p++;
- rec->r.trust.validlist = buftoulong(p); p += 4;
- break;
- case RECTYPE_VALID:
- memcpy( rec->r.valid.namehash, p, 20); p+=20;
- rec->r.valid.validity = *p++;
- rec->r.valid.next = buftoulong(p); p += 4;
- rec->r.valid.full_count = *p++;
- rec->r.valid.marginal_count = *p++;
- break;
- default:
- log_error( "%s: invalid record type %d at recnum %lu\n",
- db_name, rec->rectype, (ulong)recnum );
- rc = GPG_ERR_TRUSTDB;
- break;
- }
-
- return rc;
-}
-
-/****************
- * Write the record at RECNUM
- */
-int
-tdbio_write_record( TRUSTREC *rec )
-{
- byte buf[TRUST_RECORD_LEN], *p;
- int rc = 0;
- int i;
- ulong recnum = rec->recnum;
-
- if( db_fd == -1 )
- open_db();
-
- memset(buf, 0, TRUST_RECORD_LEN);
- p = buf;
- *p++ = rec->rectype; p++;
- switch( rec->rectype ) {
- case 0: /* unused record */
- break;
- case RECTYPE_VER: /* version record */
- if( recnum )
- BUG();
- memcpy(p-1, "gpg", 3 ); p += 2;
- *p++ = rec->r.ver.version;
- *p++ = rec->r.ver.marginals;
- *p++ = rec->r.ver.completes;
- *p++ = rec->r.ver.cert_depth;
- *p++ = rec->r.ver.trust_model;
- p += 3;
- ulongtobuf(p, rec->r.ver.created); p += 4;
- ulongtobuf(p, rec->r.ver.nextcheck); p += 4;
- p += 4;
- p += 4;
- ulongtobuf(p, rec->r.ver.firstfree ); p += 4;
- p += 4;
- ulongtobuf(p, rec->r.ver.trusthashtbl ); p += 4;
- break;
-
- case RECTYPE_FREE:
- ulongtobuf(p, rec->r.free.next); p += 4;
- break;
-
-
- case RECTYPE_HTBL:
- for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) {
- ulongtobuf( p, rec->r.htbl.item[i]); p += 4;
- }
- break;
-
- case RECTYPE_HLST:
- ulongtobuf( p, rec->r.hlst.next); p += 4;
- for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) {
- ulongtobuf( p, rec->r.hlst.rnum[i]); p += 4;
- }
- break;
-
- case RECTYPE_TRUST:
- memcpy( p, rec->r.trust.fingerprint, 20); p += 20;
- *p++ = rec->r.trust.ownertrust;
- *p++ = rec->r.trust.depth;
- *p++ = rec->r.trust.min_ownertrust;
- p++;
- ulongtobuf( p, rec->r.trust.validlist); p += 4;
- break;
-
- case RECTYPE_VALID:
- memcpy( p, rec->r.valid.namehash, 20); p += 20;
- *p++ = rec->r.valid.validity;
- ulongtobuf( p, rec->r.valid.next); p += 4;
- *p++ = rec->r.valid.full_count;
- *p++ = rec->r.valid.marginal_count;
- break;
-
- default:
- BUG();
- }
-
- rc = put_record_into_cache( recnum, buf );
- if( rc )
- ;
- else if( rec->rectype == RECTYPE_TRUST )
- rc = update_trusthashtbl( rec );
-
- return rc;
-}
-
-int
-tdbio_delete_record( ulong recnum )
-{
- TRUSTREC vr, rec;
- int rc;
-
- /* Must read the record fist, so we can drop it from the hash tables */
- rc = tdbio_read_record( recnum, &rec, 0 );
- if( rc )
- ;
- else if( rec.rectype == RECTYPE_TRUST ) {
- rc = drop_from_hashtable( get_trusthashrec(),
- rec.r.trust.fingerprint, 20, rec.recnum );
- }
-
- if( rc )
- return rc;
-
- /* now we can chnage it to a free record */
- rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
- if( rc )
- log_fatal( _("%s: error reading version record: %s\n"),
- db_name, gpg_strerror (rc) );
-
- rec.recnum = recnum;
- rec.rectype = RECTYPE_FREE;
- rec.r.free.next = vr.r.ver.firstfree;
- vr.r.ver.firstfree = recnum;
- rc = tdbio_write_record( &rec );
- if( !rc )
- rc = tdbio_write_record( &vr );
- return rc;
-}
-
-/****************
- * create a new record and return its record number
- */
-ulong
-tdbio_new_recnum()
-{
- off_t offset;
- ulong recnum;
- TRUSTREC vr, rec;
- int rc;
-
- /* look for unused records */
- rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
- if( rc )
- log_fatal( _("%s: error reading version record: %s\n"),
- db_name, gpg_strerror (rc) );
- if( vr.r.ver.firstfree ) {
- recnum = vr.r.ver.firstfree;
- rc = tdbio_read_record( recnum, &rec, RECTYPE_FREE );
- if( rc ) {
- log_error( _("%s: error reading free record: %s\n"),
- db_name, gpg_strerror (rc) );
- return rc;
- }
- /* update dir record */
- vr.r.ver.firstfree = rec.r.free.next;
- rc = tdbio_write_record( &vr );
- if( rc ) {
- log_error( _("%s: error writing dir record: %s\n"),
- db_name, gpg_strerror (rc) );
- return rc;
- }
- /*zero out the new record */
- memset( &rec, 0, sizeof rec );
- rec.rectype = 0; /* unused record */
- rec.recnum = recnum;
- rc = tdbio_write_record( &rec );
- if( rc )
- log_fatal(_("%s: failed to zero a record: %s\n"),
- db_name, gpg_strerror (rc));
- }
- else { /* not found, append a new record */
- offset = lseek( db_fd, 0, SEEK_END );
- if( offset == -1 )
- log_fatal("trustdb: lseek to end failed: %s\n", strerror(errno) );
- recnum = offset / TRUST_RECORD_LEN;
- assert(recnum); /* this is will never be the first record */
- /* we must write a record, so that the next call to this function
- * returns another recnum */
- memset( &rec, 0, sizeof rec );
- rec.rectype = 0; /* unused record */
- rec.recnum = recnum;
- rc = 0;
- if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("trustdb rec %lu: lseek failed: %s\n"),
- recnum, strerror(errno) );
- }
- else {
- int n = write( db_fd, &rec, TRUST_RECORD_LEN);
- if( n != TRUST_RECORD_LEN ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("trustdb rec %lu: write failed (n=%d): %s\n"),
- recnum, n, strerror(errno) );
- }
- }
-
- if( rc )
- log_fatal(_("%s: failed to append a record: %s\n"),
- db_name, gpg_strerror (rc));
- }
- return recnum ;
-}
-
-
-
-static int
-cmp_trec_fpr ( void *fpr, const TRUSTREC *rec )
-{
- return rec->rectype == RECTYPE_TRUST
- && !memcmp( rec->r.trust.fingerprint, fpr, 20);
-}
-
-
-int
-tdbio_search_trust_byfpr( const byte *fingerprint, TRUSTREC *rec )
-{
- int rc;
-
- /* locate the trust record using the hash table */
- rc = lookup_hashtable( get_trusthashrec(), fingerprint, 20,
- cmp_trec_fpr, (void*)fingerprint, rec );
- return rc;
-}
-
-int
-tdbio_search_trust_bypk (PKT_public_key *pk, TRUSTREC *rec)
-{
- byte fingerprint[MAX_FINGERPRINT_LEN];
- size_t fingerlen;
-
- fingerprint_from_pk( pk, fingerprint, &fingerlen );
- for (; fingerlen < 20; fingerlen++ )
- fingerprint[fingerlen] = 0;
- return tdbio_search_trust_byfpr (fingerprint, rec);
-}
-
-
-
-void
-tdbio_invalid(void)
-{
- log_error(_(
- "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n") );
- g10_exit(2);
-}
-
-/*
- * Migrate the trustdb as just up to gpg 1.0.6 (trustdb version 2)
- * to the 2.1 version as used with 1.0.6b - This is pretty trivial as needs
- * only to scan the tdb and insert new the new trust records. The old ones are
- * obsolte from now on
- */
-static void
-migrate_from_v2 ()
-{
- TRUSTREC rec;
- int i, n;
- struct {
- ulong keyrecno;
- byte ot;
- byte okay;
- byte fpr[20];
- } *ottable;
- int ottable_size, ottable_used;
- byte oldbuf[40];
- ulong recno;
- int rc, count;
-
- ottable_size = 5;
- ottable = xmalloc (ottable_size * sizeof *ottable);
- ottable_used = 0;
-
- /* We have some restrictions here. We can't use the version record
- * and we can't use any of the old hashtables because we dropped the
- * code. So we first collect all ownertrusts and then use a second
- * pass fo find the associated keys. We have to do this all without using
- * the regular record read functions.
- */
-
- /* get all the ownertrusts */
- if (lseek (db_fd, 0, SEEK_SET ) == -1 )
- log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno));
- for (recno=0;;recno++)
- {
- do
- n = read (db_fd, oldbuf, 40);
- while (n==-1 && errno == EINTR);
- if (!n)
- break; /* eof */
- if (n != 40)
- log_fatal ("migrate_vfrom_v2: read error or short read\n");
-
- if (*oldbuf != 2)
- continue;
-
- /* v2 dir record */
- if (ottable_used == ottable_size)
- {
- ottable_size += 1000;
- ottable = xrealloc (ottable, ottable_size * sizeof *ottable);
- }
- ottable[ottable_used].keyrecno = buftoulong (oldbuf+6);
- ottable[ottable_used].ot = oldbuf[18];
- ottable[ottable_used].okay = 0;
- memset (ottable[ottable_used].fpr,0, 20);
- if (ottable[ottable_used].keyrecno && ottable[ottable_used].ot)
- ottable_used++;
- }
- log_info ("found %d ownertrust records\n", ottable_used);
-
- /* Read again and find the fingerprints */
- if (lseek (db_fd, 0, SEEK_SET ) == -1 )
- log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno));
- for (recno=0;;recno++)
- {
- do
- n = read (db_fd, oldbuf, 40);
- while (n==-1 && errno == EINTR);
- if (!n)
- break; /* eof */
- if (n != 40)
- log_fatal ("migrate_from_v2: read error or short read\n");
-
- if (*oldbuf != 3)
- continue;
-
- /* v2 key record */
- for (i=0; i < ottable_used; i++)
- {
- if (ottable[i].keyrecno == recno)
- {
- memcpy (ottable[i].fpr, oldbuf+20, 20);
- ottable[i].okay = 1;
- break;
- }
- }
- }
-
- /* got everything - create the v3 trustdb */
- if (ftruncate (db_fd, 0))
- log_fatal ("can't truncate `%s': %s\n", db_name, strerror (errno) );
- if (create_version_record ())
- log_fatal ("failed to recreate version record of `%s'\n", db_name);
-
- /* access the hash table, so it is store just after the version record,
- * this is not needed put a dump is more pretty */
- get_trusthashrec ();
-
- /* And insert the old ownertrust values */
- count = 0;
- for (i=0; i < ottable_used; i++)
- {
- if (!ottable[i].okay)
- continue;
-
- memset (&rec, 0, sizeof rec);
- rec.recnum = tdbio_new_recnum ();
- rec.rectype = RECTYPE_TRUST;
- memcpy(rec.r.trust.fingerprint, ottable[i].fpr, 20);
- rec.r.trust.ownertrust = ottable[i].ot;
- if (tdbio_write_record (&rec))
- log_fatal ("failed to write trust record of `%s'\n", db_name);
- count++;
- }
-
- revalidation_mark ();
- rc = tdbio_sync ();
- if (rc)
- log_fatal ("failed to sync `%s'\n", db_name);
- log_info ("migrated %d version 2 ownertrusts\n", count);
- xfree (ottable);
-}
diff --git a/g10/tdbio.h b/g10/tdbio.h
deleted file mode 100644
index 708e06d2b..000000000
--- a/g10/tdbio.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* tdbio.h - Trust database I/O functions
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef G10_TDBIO_H
-#define G10_TDBIO_H
-
-#include "host2net.h"
-
-#define TRUST_RECORD_LEN 40
-#define SIGS_PER_RECORD ((TRUST_RECORD_LEN-10)/5)
-#define ITEMS_PER_HTBL_RECORD ((TRUST_RECORD_LEN-2)/4)
-#define ITEMS_PER_HLST_RECORD ((TRUST_RECORD_LEN-6)/5)
-#define ITEMS_PER_PREF_RECORD (TRUST_RECORD_LEN-10)
-#if ITEMS_PER_PREF_RECORD % 2
-#error ITEMS_PER_PREF_RECORD must be even
-#endif
-#define MAX_LIST_SIGS_DEPTH 20
-
-
-#define RECTYPE_VER 1
-#define RECTYPE_HTBL 10
-#define RECTYPE_HLST 11
-#define RECTYPE_TRUST 12
-#define RECTYPE_VALID 13
-#define RECTYPE_FREE 254
-
-
-struct trust_record {
- int rectype;
- int mark;
- int dirty; /* for now only used internal by functions */
- struct trust_record *next; /* help pointer to build lists in memory */
- ulong recnum;
- union {
- struct { /* version record: */
- byte version; /* should be 3 */
- byte marginals;
- byte completes;
- byte cert_depth;
- byte trust_model;
- ulong created; /* timestamp of trustdb creation */
- ulong nextcheck; /* timestamp of next scheduled check */
- ulong reserved;
- ulong reserved2;
- ulong firstfree;
- ulong reserved3;
- ulong trusthashtbl;
- } ver;
- struct { /* free record */
- ulong next;
- } free;
- struct {
- ulong item[ITEMS_PER_HTBL_RECORD];
- } htbl;
- struct {
- ulong next;
- ulong rnum[ITEMS_PER_HLST_RECORD]; /* of another record */
- } hlst;
- struct {
- byte fingerprint[20];
- byte ownertrust;
- byte depth;
- ulong validlist;
- byte min_ownertrust;
- } trust;
- struct {
- byte namehash[20];
- ulong next;
- byte validity;
- byte full_count;
- byte marginal_count;
- } valid;
- } r;
-};
-typedef struct trust_record TRUSTREC;
-
-/*-- tdbio.c --*/
-int tdbio_update_version_record(void);
-int tdbio_set_dbname( const char *new_dbname, int create );
-const char *tdbio_get_dbname(void);
-void tdbio_dump_record( TRUSTREC *rec, FILE *fp );
-int tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected );
-int tdbio_write_record( TRUSTREC *rec );
-int tdbio_db_matches_options(void);
-byte tdbio_read_model(void);
-ulong tdbio_read_nextcheck (void);
-int tdbio_write_nextcheck (ulong stamp);
-int tdbio_is_dirty(void);
-int tdbio_sync(void);
-int tdbio_begin_transaction(void);
-int tdbio_end_transaction(void);
-int tdbio_cancel_transaction(void);
-int tdbio_delete_record( ulong recnum );
-ulong tdbio_new_recnum(void);
-int tdbio_search_trust_byfpr(const byte *fingerprint, TRUSTREC *rec );
-int tdbio_search_trust_bypk(PKT_public_key *pk, TRUSTREC *rec );
-
-void tdbio_invalid(void);
-
-#endif /*G10_TDBIO_H*/
diff --git a/g10/textfilter.c b/g10/textfilter.c
deleted file mode 100644
index a3ea4b138..000000000
--- a/g10/textfilter.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/* textfilter.c
- * Copyright (C) 1998, 1999, 2000, 2001 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "gpg.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "memory.h"
-#include "util.h"
-#include "filter.h"
-#include "i18n.h"
-#include "options.h"
-
-#ifdef HAVE_DOSISH_SYSTEM
-#define LF "\r\n"
-#else
-#define LF "\n"
-#endif
-
-#define MAX_LINELEN 19995 /* a little bit smaller than in armor.c */
- /* to make sure that a warning is displayed while */
- /* creating a message */
-
-static unsigned
-len_without_trailing_chars( byte *line, unsigned len, const char *trimchars )
-{
- byte *p, *mark;
- unsigned n;
-
- for(mark=NULL, p=line, n=0; n < len; n++, p++ ) {
- if( strchr( trimchars, *p ) ) {
- if( !mark )
- mark = p;
- }
- else
- mark = NULL;
- }
-
- return mark? (mark - line) : len;
-}
-
-unsigned
-len_without_trailing_ws( byte *line, unsigned len )
-{
- return len_without_trailing_chars( line, len, " \t\r\n" );
-}
-
-
-
-
-static int
-standard( text_filter_context_t *tfx, iobuf_t a,
- byte *buf, size_t size, size_t *ret_len)
-{
- int rc=0;
- size_t len = 0;
- unsigned maxlen;
-
- assert( size > 10 );
- size -= 2; /* reserve 2 bytes to append CR,LF */
- while( !rc && len < size ) {
- int lf_seen;
-
- while( len < size && tfx->buffer_pos < tfx->buffer_len )
- buf[len++] = tfx->buffer[tfx->buffer_pos++];
- if( len >= size )
- continue;
-
- /* read the next line */
- maxlen = MAX_LINELEN;
- tfx->buffer_pos = 0;
- tfx->buffer_len = iobuf_read_line( a, &tfx->buffer,
- &tfx->buffer_size, &maxlen );
- if( !maxlen )
- tfx->truncated++;
- if( !tfx->buffer_len ) {
- if( !len )
- rc = -1; /* eof */
- break;
- }
- lf_seen = tfx->buffer[tfx->buffer_len-1] == '\n';
- tfx->buffer_len = trim_trailing_ws( tfx->buffer, tfx->buffer_len );
- if( lf_seen ) {
- tfx->buffer[tfx->buffer_len++] = '\r';
- tfx->buffer[tfx->buffer_len++] = '\n';
- }
- }
- *ret_len = len;
- return rc;
-}
-
-
-
-
-/****************
- * The filter is used to make canonical text: Lines are terminated by
- * CR, LF, trailing white spaces are removed.
- */
-int
-text_filter( void *opaque, int control,
- iobuf_t a, byte *buf, size_t *ret_len)
-{
- size_t size = *ret_len;
- text_filter_context_t *tfx = opaque;
- int rc=0;
-
- if( control == IOBUFCTRL_UNDERFLOW ) {
- rc = standard( tfx, a, buf, size, ret_len );
- }
- else if( control == IOBUFCTRL_FREE ) {
- if( tfx->truncated )
- log_error(_("can't handle text lines longer than %d characters\n"),
- MAX_LINELEN );
- xfree ( tfx->buffer );
- tfx->buffer = NULL;
- }
- else if( control == IOBUFCTRL_DESC )
- *(char**)buf = "text_filter";
- return rc;
-}
-
-
-/****************
- * Copy data from INP to OUT and do some escaping if requested.
- * md is updated as required by rfc2440
- */
-int
-copy_clearsig_text( iobuf_t out, iobuf_t inp, MD_HANDLE md,
- int escape_dash, int escape_from, int pgp2mode )
-{
- unsigned maxlen;
- byte *buffer = NULL; /* malloced buffer */
- unsigned bufsize; /* and size of this buffer */
- unsigned n;
- int truncated = 0;
- int pending_lf = 0;
-
- if( !opt.pgp2_workarounds )
- pgp2mode = 0;
-
- if( !escape_dash )
- escape_from = 0;
-
- for(;;) {
- maxlen = MAX_LINELEN;
- n = iobuf_read_line( inp, &buffer, &bufsize, &maxlen );
- if( !maxlen )
- truncated++;
-
- if( !n )
- break; /* read_line has returned eof */
-
- /* update the message digest */
- if( escape_dash ) {
- if( pending_lf ) {
- gcry_md_putc( md, '\r' );
- gcry_md_putc( md, '\n' );
- }
- gcry_md_write( md, buffer,
- len_without_trailing_chars( buffer, n,
- pgp2mode? " \r\n":" \t\r\n"));
- }
- else
- gcry_md_write( md, buffer, n );
- pending_lf = buffer[n-1] == '\n';
-
- /* write the output */
- if( ( escape_dash && *buffer == '-')
- || ( escape_from && n > 4 && !memcmp(buffer, "From ", 5 ) ) ) {
- iobuf_put( out, '-' );
- iobuf_put( out, ' ' );
- }
-
-#if 0 /*defined(HAVE_DOSISH_SYSTEM)*/
- /* We don't use this anymore because my interpretation of rfc2440 7.1
- * is that there is no conversion needed. If one decides to
- * clearsign a unix file on a DOS box he will get a mixed line endings.
- * If at some point it turns out, that a conversion is a nice feature
- * we can make an option out of it.
- */
- /* make sure the lines do end in CR,LF */
- if( n > 1 && ( (buffer[n-2] == '\r' && buffer[n-1] == '\n' )
- || (buffer[n-2] == '\n' && buffer[n-1] == '\r'))) {
- iobuf_write( out, buffer, n-2 );
- iobuf_put( out, '\r');
- iobuf_put( out, '\n');
- }
- else if( n && buffer[n-1] == '\n' ) {
- iobuf_write( out, buffer, n-1 );
- iobuf_put( out, '\r');
- iobuf_put( out, '\n');
- }
- else
- iobuf_write( out, buffer, n );
-
-#else
- iobuf_write( out, buffer, n );
-#endif
- }
-
- /* at eof */
- if( !pending_lf ) { /* make sure that the file ends with a LF */
- iobuf_writestr( out, LF );
- if( !escape_dash )
- gcry_md_putc( md, '\n' );
- }
-
- if( truncated )
- log_info(_("input line longer than %d characters\n"), MAX_LINELEN );
-
- return 0; /* okay */
-}
diff --git a/g10/trustdb.c b/g10/trustdb.c
deleted file mode 100644
index b3a2b369e..000000000
--- a/g10/trustdb.c
+++ /dev/null
@@ -1,2158 +0,0 @@
-/* trustdb.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
- * 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#ifndef DISABLE_REGEX
-#include <sys/types.h>
-#ifdef USE_GNU_REGEX
-#include "_regex.h"
-#else
-#include <regex.h>
-#endif
-#endif /* !DISABLE_REGEX */
-
-#include "gpg.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "keydb.h"
-#include "memory.h"
-#include "util.h"
-#include "options.h"
-#include "packet.h"
-#include "main.h"
-#include "i18n.h"
-#include "tdbio.h"
-#include "trustdb.h"
-
-
-/*
- * A structure to store key identification as well as some stuff needed
- * for validation
- */
-struct key_item {
- struct key_item *next;
- unsigned int ownertrust,min_ownertrust;
- byte trust_depth;
- byte trust_value;
- char *trust_regexp;
- u32 kid[2];
-};
-
-
-typedef struct key_item **KeyHashTable; /* see new_key_hash_table() */
-
-/*
- * Structure to keep track of keys, this is used as an array wherre
- * the item right after the last one has a keyblock set to NULL.
- * Maybe we can drop this thing and replace it by key_item
- */
-struct key_array {
- KBNODE keyblock;
-};
-
-
-/* control information for the trust DB */
-static struct {
- int init;
- int level;
- char *dbname;
-} trustdb_args;
-
-/* some globals */
-static struct key_item *user_utk_list; /* temp. used to store --trusted-keys */
-static struct key_item *utk_list; /* all ultimately trusted keys */
-
-static int pending_check_trustdb;
-
-static int validate_keys (int interactive);
-
-
-/**********************************************
- ************* some helpers *******************
- **********************************************/
-
-static struct key_item *
-new_key_item (void)
-{
- struct key_item *k;
-
- k = xcalloc (1,sizeof *k);
- return k;
-}
-
-static void
-release_key_items (struct key_item *k)
-{
- struct key_item *k2;
-
- for (; k; k = k2)
- {
- k2 = k->next;
- xfree (k->trust_regexp);
- xfree (k);
- }
-}
-
-/*
- * For fast keylook up we need a hash table. Each byte of a KeyIDs
- * should be distributed equally over the 256 possible values (except
- * for v3 keyIDs but we consider them as not important here). So we
- * can just use 10 bits to index a table of 1024 key items.
- * Possible optimization: Don not use key_items but other hash_table when the
- * duplicates lists gets too large.
- */
-static KeyHashTable
-new_key_hash_table (void)
-{
- struct key_item **tbl;
-
- tbl = xcalloc (1,1024 * sizeof *tbl);
- return tbl;
-}
-
-static void
-release_key_hash_table (KeyHashTable tbl)
-{
- int i;
-
- if (!tbl)
- return;
- for (i=0; i < 1024; i++)
- release_key_items (tbl[i]);
- xfree (tbl);
-}
-
-/*
- * Returns: True if the keyID is in the given hash table
- */
-static int
-test_key_hash_table (KeyHashTable tbl, u32 *kid)
-{
- struct key_item *k;
-
- for (k = tbl[(kid[1] & 0x03ff)]; k; k = k->next)
- if (k->kid[0] == kid[0] && k->kid[1] == kid[1])
- return 1;
- return 0;
-}
-
-/*
- * Add a new key to the hash table. The key is identified by its key ID.
- */
-static void
-add_key_hash_table (KeyHashTable tbl, u32 *kid)
-{
- struct key_item *k, *kk;
-
- for (k = tbl[(kid[1] & 0x03ff)]; k; k = k->next)
- if (k->kid[0] == kid[0] && k->kid[1] == kid[1])
- return; /* already in table */
-
- kk = new_key_item ();
- kk->kid[0] = kid[0];
- kk->kid[1] = kid[1];
- kk->next = tbl[(kid[1] & 0x03ff)];
- tbl[(kid[1] & 0x03ff)] = kk;
-}
-
-/*
- * Release a key_array
- */
-static void
-release_key_array ( struct key_array *keys )
-{
- struct key_array *k;
-
- if (keys) {
- for (k=keys; k->keyblock; k++)
- release_kbnode (k->keyblock);
- xfree (keys);
- }
-}
-
-
-/*********************************************
- ********** Initialization *****************
- *********************************************/
-
-
-
-/*
- * Used to register extra ultimately trusted keys - this has to be done
- * before initializing the validation module.
- * FIXME: Should be replaced by a function to add those keys to the trustdb.
- */
-void
-register_trusted_key( const char *string )
-{
- KEYDB_SEARCH_DESC desc;
- struct key_item *k;
-
- if (classify_user_id (string, &desc) != KEYDB_SEARCH_MODE_LONG_KID ) {
- log_error(_("`%s' is not a valid long keyID\n"), string );
- return;
- }
-
- k = new_key_item ();
- k->kid[0] = desc.u.kid[0];
- k->kid[1] = desc.u.kid[1];
- k->next = user_utk_list;
- user_utk_list = k;
-}
-
-/*
- * Helper to add a key to the global list of ultimately trusted keys.
- * Retruns: true = inserted, false = already in in list.
- */
-static int
-add_utk (u32 *kid)
-{
- struct key_item *k;
-
- for (k = utk_list; k; k = k->next)
- {
- if (k->kid[0] == kid[0] && k->kid[1] == kid[1])
- {
- return 0;
- }
- }
-
- k = new_key_item ();
- k->kid[0] = kid[0];
- k->kid[1] = kid[1];
- k->ownertrust = TRUST_ULTIMATE;
- k->next = utk_list;
- utk_list = k;
- if( opt.verbose > 1 )
- log_info(_("key %08lX: accepted as trusted key\n"), (ulong)kid[1]);
- return 1;
-}
-
-
-/****************
- * Verify that all our secret keys are usable and put them into the utk_list.
- */
-static void
-verify_own_keys(void)
-{
- TRUSTREC rec;
- ulong recnum;
- int rc;
- struct key_item *k;
-
- if (utk_list)
- return;
-
- /* scan the trustdb to find all ultimately trusted keys */
- for (recnum=1; !tdbio_read_record (recnum, &rec, 0); recnum++ )
- {
- if ( rec.rectype == RECTYPE_TRUST
- && (rec.r.trust.ownertrust & TRUST_MASK) == TRUST_ULTIMATE)
- {
- byte *fpr = rec.r.trust.fingerprint;
- int fprlen;
- u32 kid[2];
-
- /* Problem: We do only use fingerprints in the trustdb but
- * we need the keyID here to indetify the key; we can only
- * use that ugly hack to distinguish between 16 and 20
- * butes fpr - it does not work always so we better change
- * the whole validation code to only work with
- * fingerprints */
- fprlen = (!fpr[16] && !fpr[17] && !fpr[18] && !fpr[19])? 16:20;
- keyid_from_fingerprint (fpr, fprlen, kid);
- if (!add_utk (kid))
- log_info(_("key %08lX occurs more than once in the trustdb\n"),
- (ulong)kid[1]);
- }
- }
-
- /* Put any --trusted-key keys into the trustdb */
- for (k = user_utk_list; k; k = k->next)
- {
- if ( add_utk (k->kid) )
- { /* not yet in trustDB as ultimately trusted */
- PKT_public_key pk;
-
- memset (&pk, 0, sizeof pk);
- rc = get_pubkey (&pk, k->kid);
- if (rc) {
- log_info(_("key %08lX: no public key for trusted key - skipped\n"),
- (ulong)k->kid[1] );
- }
- else {
- update_ownertrust (&pk,
- ((get_ownertrust (&pk) & ~TRUST_MASK)
- | TRUST_ULTIMATE ));
- release_public_key_parts (&pk);
- }
- log_info (_("key %08lX marked as ultimately trusted\n"),
- (ulong)k->kid[1]);
- }
- }
-
-
- /* release the helper table table */
- release_key_items (user_utk_list);
- user_utk_list = NULL;
- return;
-}
-
-
-/*********************************************
- *********** TrustDB stuff *******************
- *********************************************/
-
-/*
- * Read a record but die if it does not exist
- */
-static void
-read_record (ulong recno, TRUSTREC *rec, int rectype )
-{
- int rc = tdbio_read_record (recno, rec, rectype);
- if (rc)
- {
- log_error(_("trust record %lu, req type %d: read failed: %s\n"),
- recno, rec->rectype, gpg_strerror (rc) );
- tdbio_invalid();
- }
- if (rectype != rec->rectype)
- {
- log_error(_("trust record %lu is not of requested type %d\n"),
- rec->recnum, rectype);
- tdbio_invalid();
- }
-}
-
-/*
- * Write a record and die on error
- */
-static void
-write_record (TRUSTREC *rec)
-{
- int rc = tdbio_write_record (rec);
- if (rc)
- {
- log_error(_("trust record %lu, type %d: write failed: %s\n"),
- rec->recnum, rec->rectype, gpg_strerror (rc) );
- tdbio_invalid();
- }
-}
-
-/*
- * sync the TrustDb and die on error
- */
-static void
-do_sync(void)
-{
- int rc = tdbio_sync ();
- if(rc)
- {
- log_error (_("trustdb: sync failed: %s\n"), gpg_strerror (rc) );
- g10_exit(2);
- }
-}
-
-static const char *
-trust_model_string(void)
-{
- switch(opt.trust_model)
- {
- case TM_PGP: return "PGP";
- case TM_CLASSIC: return "classic";
- case TM_ALWAYS: return "always";
- default: return "unknown";
- }
-}
-
-/****************
- * Perform some checks over the trustdb
- * level 0: only open the db
- * 1: used for initial program startup
- */
-int
-setup_trustdb( int level, const char *dbname )
-{
- /* just store the args */
- if( trustdb_args.init )
- return 0;
- trustdb_args.level = level;
- trustdb_args.dbname = dbname? xstrdup (dbname): NULL;
- return 0;
-}
-
-void
-init_trustdb()
-{
- int rc=0;
- int level = trustdb_args.level;
- const char* dbname = trustdb_args.dbname;
-
- if( trustdb_args.init )
- return;
-
- trustdb_args.init = 1;
-
- if ( !level || level==1)
- {
- rc = tdbio_set_dbname( dbname, !!level );
- if( !rc )
- {
- if( !level )
- return;
-
- /* verify that our own keys are in the trustDB
- * or move them to the trustdb. */
- verify_own_keys();
-
- /* should we check whether there is no other ultimately trusted
- * key in the database? */
- }
- }
- else
- BUG();
- if( rc )
- log_fatal("can't init trustdb: %s\n", gpg_strerror (rc) );
-
- if(opt.trust_model==TM_AUTO)
- {
- /* Try and set the trust model off of whatever the trustdb says
- it is. */
- opt.trust_model=tdbio_read_model();
-
- /* Sanity check this ;) */
- if(opt.trust_model!=TM_PGP && opt.trust_model!=TM_CLASSIC)
- {
- log_info(_("unable to use unknown trust model (%d) - "
- "assuming %s trust model\n"),opt.trust_model,"PGP");
- opt.trust_model=TM_PGP;
- }
-
- if(opt.verbose)
- log_info(_("using %s trust model\n"),trust_model_string());
- }
-
- if((opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
- && !tdbio_db_matches_options())
- pending_check_trustdb=1;
-}
-
-
-
-
-/***********************************************
- ************* Print helpers ****************
- ***********************************************/
-
-/****************
- * This function returns a letter for a trustvalue Trust flags
- * are ignore.
- */
-static int
-trust_letter (unsigned int value)
-{
- switch( (value & TRUST_MASK) )
- {
- case TRUST_UNKNOWN: return '-';
- case TRUST_EXPIRED: return 'e';
- case TRUST_UNDEFINED: return 'q';
- case TRUST_NEVER: return 'n';
- case TRUST_MARGINAL: return 'm';
- case TRUST_FULLY: return 'f';
- case TRUST_ULTIMATE: return 'u';
- default: return '?';
- }
-}
-
-/* The strings here are similar to those in
- pkclist.c:do_edit_ownertrust() */
-const char *
-trust_value_to_string (unsigned int value)
-{
- switch( (value & TRUST_MASK) )
- {
- case TRUST_UNKNOWN: return _("unknown");
- case TRUST_EXPIRED: return _("expired");
- case TRUST_UNDEFINED: return _("undefined");
- case TRUST_NEVER: return _("never");
- case TRUST_MARGINAL: return _("marginal");
- case TRUST_FULLY: return _("full");
- case TRUST_ULTIMATE: return _("ultimate");
- default: return "err";
- }
-}
-
-int
-string_to_trust_value (const char *str)
-{
- if(ascii_strcasecmp(str,"undefined")==0)
- return TRUST_UNDEFINED;
- else if(ascii_strcasecmp(str,"never")==0)
- return TRUST_NEVER;
- else if(ascii_strcasecmp(str,"marginal")==0)
- return TRUST_MARGINAL;
- else if(ascii_strcasecmp(str,"full")==0)
- return TRUST_FULLY;
- else if(ascii_strcasecmp(str,"ultimate")==0)
- return TRUST_ULTIMATE;
- else
- return -1;
-}
-
-/****************
- * Recreate the WoT but do not ask for new ownertrusts. Special
- * feature: In batch mode and without a forced yes, this is only done
- * when a check is due. This can be used to run the check from a crontab
- */
-void
-check_trustdb ()
-{
- init_trustdb();
- if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
- {
- if (opt.batch && !opt.answer_yes)
- {
- ulong scheduled;
-
- scheduled = tdbio_read_nextcheck ();
- if (!scheduled)
- {
- log_info (_("no need for a trustdb check\n"));
- return;
- }
-
- if (scheduled > make_timestamp ())
- {
- log_info (_("next trustdb check due at %s\n"),
- strtimestamp (scheduled));
- return;
- }
- }
-
- validate_keys (0);
- }
- else
- log_info (_("no need for a trustdb check with \"%s\" trust model\n"),
- trust_model_string());
-}
-
-
-/*
- * Recreate the WoT.
- */
-void
-update_trustdb()
-{
- init_trustdb();
- if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
- validate_keys (1);
- else
- log_info (_("no need for a trustdb update with \"%s\" trust model\n"),
- trust_model_string());
-}
-
-void
-revalidation_mark (void)
-{
- init_trustdb();
- /* we simply set the time for the next check to 1 (far back in 1970)
- * so that a --update-trustdb will be scheduled */
- if (tdbio_write_nextcheck (1))
- do_sync ();
- pending_check_trustdb = 1;
-}
-
-int
-trustdb_pending_check(void)
-{
- return pending_check_trustdb;
-}
-
-void
-read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck,
- byte *marginals,byte *completes,byte *cert_depth)
-{
- TRUSTREC opts;
-
- init_trustdb();
-
- read_record(0,&opts,RECTYPE_VER);
-
- if(trust_model)
- *trust_model=opts.r.ver.trust_model;
- if(created)
- *created=opts.r.ver.created;
- if(nextcheck)
- *nextcheck=opts.r.ver.nextcheck;
- if(marginals)
- *marginals=opts.r.ver.marginals;
- if(completes)
- *completes=opts.r.ver.completes;
- if(cert_depth)
- *cert_depth=opts.r.ver.cert_depth;
-}
-
-
-
-/***********************************************
- *********** Ownertrust et al. ****************
- ***********************************************/
-
-static int
-read_trust_record (PKT_public_key *pk, TRUSTREC *rec)
-{
- int rc;
-
- init_trustdb();
- rc = tdbio_search_trust_bypk (pk, rec);
- if (rc == -1)
- return -1; /* no record yet */
- if (rc)
- {
- log_error ("trustdb: searching trust record failed: %s\n",
- gpg_strerror (rc));
- return rc;
- }
-
- if (rec->rectype != RECTYPE_TRUST)
- {
- log_error ("trustdb: record %lu is not a trust record\n",
- rec->recnum);
- return GPG_ERR_TRUSTDB;
- }
-
- return 0;
-}
-
-/****************
- * Return the assigned ownertrust value for the given public key.
- * The key should be the primary key.
- */
-unsigned int
-get_ownertrust ( PKT_public_key *pk)
-{
- TRUSTREC rec;
- int rc;
-
- rc = read_trust_record (pk, &rec);
- if (rc == -1)
- return TRUST_UNKNOWN; /* no record yet */
- if (rc)
- {
- tdbio_invalid ();
- return rc; /* actually never reached */
- }
-
- return rec.r.trust.ownertrust;
-}
-
-unsigned int
-get_min_ownertrust (PKT_public_key *pk)
-{
- TRUSTREC rec;
- int rc;
-
- rc = read_trust_record (pk, &rec);
- if (rc == -1)
- return TRUST_UNKNOWN; /* no record yet */
- if (rc)
- {
- tdbio_invalid ();
- return rc; /* actually never reached */
- }
-
- return rec.r.trust.min_ownertrust;
-}
-
-/*
- * Same as get_ownertrust but this takes the minimum ownertrust value
- * into into account, and will bump up the value as needed.
- */
-static int
-get_ownertrust_with_min (PKT_public_key *pk)
-{
- unsigned int otrust,otrust_min;
-
- otrust = (get_ownertrust (pk) & TRUST_MASK);
- otrust_min = get_min_ownertrust (pk);
- if(otrust<otrust_min)
- {
- /* If the trust that the user has set is less than the trust
- that was calculated from a trust signature chain, use the
- higher of the two. We do this here and not in
- get_ownertrust since the underlying ownertrust should not
- really be set - just the appearance of the ownertrust. */
-
- otrust=otrust_min;
- }
-
- return otrust;
-}
-
-/*
- * Same as get_ownertrust but return a trust letter instead of an
- * value. This takes the minimum ownertrust value into account.
- */
-int
-get_ownertrust_info (PKT_public_key *pk)
-{
- return trust_letter(get_ownertrust_with_min(pk));
-}
-
-/*
- * Same as get_ownertrust but return a trust string instead of an
- * value. This takes the minimum ownertrust value into account.
- */
-const char *
-get_ownertrust_string (PKT_public_key *pk)
-{
- return trust_value_to_string(get_ownertrust_with_min(pk));
-}
-
-/*
- * Set the trust value of the given public key to the new value.
- * The key should be a primary one.
- */
-void
-update_ownertrust (PKT_public_key *pk, unsigned int new_trust )
-{
- TRUSTREC rec;
- int rc;
-
- rc = read_trust_record (pk, &rec);
- if (!rc)
- {
- if (DBG_TRUST)
- log_debug ("update ownertrust from %u to %u\n",
- (unsigned int)rec.r.trust.ownertrust, new_trust );
- if (rec.r.trust.ownertrust != new_trust)
- {
- rec.r.trust.ownertrust = new_trust;
- write_record( &rec );
- revalidation_mark ();
- do_sync ();
- }
- }
- else if (rc == -1)
- { /* no record yet - create a new one */
- size_t dummy;
-
- if (DBG_TRUST)
- log_debug ("insert ownertrust %u\n", new_trust );
-
- memset (&rec, 0, sizeof rec);
- rec.recnum = tdbio_new_recnum ();
- rec.rectype = RECTYPE_TRUST;
- fingerprint_from_pk (pk, rec.r.trust.fingerprint, &dummy);
- rec.r.trust.ownertrust = new_trust;
- write_record (&rec);
- revalidation_mark ();
- do_sync ();
- rc = 0;
- }
- else
- {
- tdbio_invalid ();
- }
-}
-
-static void
-update_min_ownertrust (u32 *kid, unsigned int new_trust )
-{
- PKT_public_key *pk;
- TRUSTREC rec;
- int rc;
-
- pk = xcalloc (1,sizeof *pk);
- rc = get_pubkey (pk, kid);
- if (rc)
- {
- log_error (_("public key %08lX not found: %s\n"),
- (ulong)kid[1], gpg_strerror (rc) );
- return;
- }
-
- rc = read_trust_record (pk, &rec);
- if (!rc)
- {
- if (DBG_TRUST)
- log_debug ("key %08lX: update min_ownertrust from %u to %u\n",
- (ulong)kid[1],(unsigned int)rec.r.trust.min_ownertrust,
- new_trust );
- if (rec.r.trust.min_ownertrust != new_trust)
- {
- rec.r.trust.min_ownertrust = new_trust;
- write_record( &rec );
- revalidation_mark ();
- do_sync ();
- }
- }
- else if (rc == -1)
- { /* no record yet - create a new one */
- size_t dummy;
-
- if (DBG_TRUST)
- log_debug ("insert min_ownertrust %u\n", new_trust );
-
- memset (&rec, 0, sizeof rec);
- rec.recnum = tdbio_new_recnum ();
- rec.rectype = RECTYPE_TRUST;
- fingerprint_from_pk (pk, rec.r.trust.fingerprint, &dummy);
- rec.r.trust.min_ownertrust = new_trust;
- write_record (&rec);
- revalidation_mark ();
- do_sync ();
- rc = 0;
- }
- else
- {
- tdbio_invalid ();
- }
-}
-
-/* Clear the ownertrust and min_ownertrust values. Return true if a
- change actually happened. */
-int
-clear_ownertrusts (PKT_public_key *pk)
-{
- TRUSTREC rec;
- int rc;
-
- rc = read_trust_record (pk, &rec);
- if (!rc)
- {
- if (DBG_TRUST)
- {
- log_debug ("clearing ownertrust (old value %u)\n",
- (unsigned int)rec.r.trust.ownertrust);
- log_debug ("clearing min_ownertrust (old value %u)\n",
- (unsigned int)rec.r.trust.min_ownertrust);
- }
- if (rec.r.trust.ownertrust || rec.r.trust.min_ownertrust)
- {
- rec.r.trust.ownertrust = 0;
- rec.r.trust.min_ownertrust = 0;
- write_record( &rec );
- revalidation_mark ();
- do_sync ();
- return 1;
- }
- }
- else if (rc != -1)
- {
- tdbio_invalid ();
- }
- return 0;
-}
-
-/*
- * Note: Caller has to do a sync
- */
-static void
-update_validity (PKT_public_key *pk, PKT_user_id *uid,
- int depth, int validity)
-{
- TRUSTREC trec, vrec;
- int rc;
- ulong recno;
-
- namehash_from_uid(uid);
-
- rc = read_trust_record (pk, &trec);
- if (rc && rc != -1)
- {
- tdbio_invalid ();
- return;
- }
- if (rc == -1) /* no record yet - create a new one */
- {
- size_t dummy;
-
- rc = 0;
- memset (&trec, 0, sizeof trec);
- trec.recnum = tdbio_new_recnum ();
- trec.rectype = RECTYPE_TRUST;
- fingerprint_from_pk (pk, trec.r.trust.fingerprint, &dummy);
- trec.r.trust.ownertrust = 0;
- }
-
- /* locate an existing one */
- recno = trec.r.trust.validlist;
- while (recno)
- {
- read_record (recno, &vrec, RECTYPE_VALID);
- if ( !memcmp (vrec.r.valid.namehash, uid->namehash, 20) )
- break;
- recno = vrec.r.valid.next;
- }
-
- if (!recno) /* insert a new validity record */
- {
- memset (&vrec, 0, sizeof vrec);
- vrec.recnum = tdbio_new_recnum ();
- vrec.rectype = RECTYPE_VALID;
- memcpy (vrec.r.valid.namehash, uid->namehash, 20);
- vrec.r.valid.next = trec.r.trust.validlist;
- trec.r.trust.validlist = vrec.recnum;
- }
- vrec.r.valid.validity = validity;
- vrec.r.valid.full_count = uid->help_full_count;
- vrec.r.valid.marginal_count = uid->help_marginal_count;
- write_record (&vrec);
- trec.r.trust.depth = depth;
- write_record (&trec);
-}
-
-
-/* reset validity for all user IDs. Caller must sync. */
-static int
-clear_validity (PKT_public_key *pk)
-{
- TRUSTREC trec, vrec;
- int rc;
- ulong recno;
- int any = 0;
-
- rc = read_trust_record (pk, &trec);
- if (rc && rc != -1)
- {
- tdbio_invalid ();
- return 0;
- }
- if (rc == -1) /* no record yet - no need to clear it then ;-) */
- return 0;
-
- /* Clear minimum ownertrust, if any */
- if(trec.r.trust.min_ownertrust)
- {
- trec.r.trust.min_ownertrust=0;
- write_record(&trec);
- }
-
- recno = trec.r.trust.validlist;
- while (recno)
- {
- read_record (recno, &vrec, RECTYPE_VALID);
- if ((vrec.r.valid.validity & TRUST_MASK)
- || vrec.r.valid.marginal_count || vrec.r.valid.full_count)
- {
- vrec.r.valid.validity &= ~TRUST_MASK;
- vrec.r.valid.marginal_count = vrec.r.valid.full_count = 0;
- write_record (&vrec);
- any = 1;
- }
- recno = vrec.r.valid.next;
- }
-
- return any;
-}
-
-/***********************************************
- ********* Query trustdb values **************
- ***********************************************/
-
-/* Return true if key is disabled */
-int
-cache_disabled_value(PKT_public_key *pk)
-{
- int rc;
- TRUSTREC trec;
- int disabled=0;
-
- if(pk->is_disabled)
- return (pk->is_disabled==2);
-
- init_trustdb();
-
- rc = read_trust_record (pk, &trec);
- if (rc && rc != -1)
- {
- tdbio_invalid ();
- goto leave;
- }
- if (rc == -1) /* no record found, so assume not disabled */
- goto leave;
-
- if(trec.r.trust.ownertrust & TRUST_FLAG_DISABLED)
- disabled=1;
-
- /* Cache it for later so we don't need to look at the trustdb every
- time */
- if(disabled)
- pk->is_disabled=2;
- else
- pk->is_disabled=1;
-
- leave:
- return disabled;
-}
-
-/*
- * Return the validity information for PK. If the namehash is not
- * NULL, the validity of the corresponsing user ID is returned,
- * otherwise, a reasonable value for the entire key is returned.
- */
-unsigned int
-get_validity (PKT_public_key *pk, PKT_user_id *uid)
-{
- static int did_nextcheck;
- TRUSTREC trec, vrec;
- int rc;
- ulong recno;
- unsigned int validity;
- u32 kid[2];
- PKT_public_key *main_pk;
-
- if(uid)
- namehash_from_uid(uid);
-
- init_trustdb ();
- if (!did_nextcheck
- && (opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC))
- {
- ulong scheduled;
-
- did_nextcheck = 1;
- scheduled = tdbio_read_nextcheck ();
- if (scheduled && scheduled <= make_timestamp ())
- {
- if (opt.no_auto_check_trustdb)
- {
- pending_check_trustdb = 1;
- log_info (_("please do a --check-trustdb\n"));
- }
- else
- {
- log_info (_("checking the trustdb\n"));
- validate_keys (0);
- }
- }
- }
-
- keyid_from_pk (pk, kid);
- if (pk->main_keyid[0] != kid[0] || pk->main_keyid[1] != kid[1])
- { /* this is a subkey - get the mainkey */
- main_pk = xcalloc (1,sizeof *main_pk);
- rc = get_pubkey (main_pk, pk->main_keyid);
- if (rc)
- {
- log_error ("error getting main key %08lX of subkey %08lX: %s\n",
- (ulong)pk->main_keyid[1], (ulong)kid[1], gpg_strerror (rc));
- validity = TRUST_UNKNOWN;
- goto leave;
- }
- }
- else
- main_pk = pk;
-
- rc = read_trust_record (main_pk, &trec);
- if (rc && rc != -1)
- {
- tdbio_invalid ();
- return 0;
- }
- if (rc == -1) /* no record found */
- {
- validity = TRUST_UNKNOWN;
- goto leave;
- }
-
- /* loop over all user IDs */
- recno = trec.r.trust.validlist;
- validity = 0;
- while (recno)
- {
- read_record (recno, &vrec, RECTYPE_VALID);
-
- if(uid)
- {
- /* If a user ID is given we return the validity for that
- user ID ONLY. If the namehash is not found, then there
- is no validity at all (i.e. the user ID wasn't
- signed). */
- if(memcmp(vrec.r.valid.namehash,uid->namehash,20)==0)
- {
- validity=(vrec.r.valid.validity & TRUST_MASK);
- break;
- }
- }
- else
- {
- /* If no namehash is given, we take the maximum validity
- over all user IDs */
- if ( validity < (vrec.r.valid.validity & TRUST_MASK) )
- validity = (vrec.r.valid.validity & TRUST_MASK);
- }
-
- recno = vrec.r.valid.next;
- }
-
- if ( (trec.r.trust.ownertrust & TRUST_FLAG_DISABLED) )
- {
- validity |= TRUST_FLAG_DISABLED;
- pk->is_disabled=2;
- }
- else
- pk->is_disabled=1;
-
- leave:
- /* set some flags direct from the key */
- if (main_pk->is_revoked)
- validity |= TRUST_FLAG_REVOKED;
- if (main_pk != pk && pk->is_revoked)
- validity |= TRUST_FLAG_SUB_REVOKED;
- /* Note: expiration is a trust value and not a flag - don't know why
- * I initially designed it that way */
- if (main_pk->has_expired || pk->has_expired)
- validity = (validity & ~TRUST_MASK) | TRUST_EXPIRED;
-
- if (pending_check_trustdb)
- validity |= TRUST_FLAG_PENDING_CHECK;
-
- if (main_pk != pk)
- free_public_key (main_pk);
- return validity;
-}
-
-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 );
-}
-
-const char *
-get_validity_string (PKT_public_key *pk, PKT_user_id *uid)
-{
- int trustlevel;
-
- trustlevel = get_validity (pk, uid);
- if( trustlevel & TRUST_FLAG_REVOKED )
- return _("revoked");
- return trust_value_to_string(trustlevel);
-}
-
-static void
-get_validity_counts (PKT_public_key *pk, PKT_user_id *uid)
-{
- TRUSTREC trec, vrec;
- ulong recno;
-
- if(pk==NULL || uid==NULL)
- BUG();
-
- namehash_from_uid(uid);
-
- uid->help_marginal_count=uid->help_full_count=0;
-
- init_trustdb ();
-
- if(read_trust_record (pk, &trec)!=0)
- return;
-
- /* loop over all user IDs */
- recno = trec.r.trust.validlist;
- while (recno)
- {
- read_record (recno, &vrec, RECTYPE_VALID);
-
- if(memcmp(vrec.r.valid.namehash,uid->namehash,20)==0)
- {
- uid->help_marginal_count=vrec.r.valid.marginal_count;
- uid->help_full_count=vrec.r.valid.full_count;
- /* printf("Fetched marginal %d, full %d\n",uid->help_marginal_count,uid->help_full_count); */
- break;
- }
-
- recno = vrec.r.valid.next;
- }
-}
-
-void
-list_trust_path( const char *username )
-{
-}
-
-/****************
- * Enumerate all keys, which are needed to build all trust paths for
- * the given key. This function does not return the key itself or
- * the ultimate key (the last point in cerificate chain). Only
- * certificate chains which ends up at an ultimately trusted key
- * are listed. If ownertrust or validity is not NULL, the corresponding
- * value for the returned LID is also returned in these variable(s).
- *
- * 1) create a void pointer and initialize it to NULL
- * 2) pass this void pointer by reference to this function.
- * Set lid to the key you want to enumerate and pass it by reference.
- * 3) call this function as long as it does not return -1
- * to indicate EOF. LID does contain the next key used to build the web
- * 4) Always call this function a last time with LID set to NULL,
- * so that it can free its context.
- *
- * Returns: -1 on EOF or the level of the returned LID
- */
-int
-enum_cert_paths( void **context, ulong *lid,
- unsigned *ownertrust, unsigned *validity )
-{
- return -1;
-}
-
-
-/****************
- * Print the current path
- */
-void
-enum_cert_paths_print( void **context, FILE *fp,
- int refresh, ulong selected_lid )
-{
- return;
-}
-
-
-
-/****************************************
- *********** NEW NEW NEW ****************
- ****************************************/
-
-static int
-ask_ownertrust (u32 *kid,int minimum)
-{
- PKT_public_key *pk;
- int rc;
- int ot;
-
- pk = xcalloc (1,sizeof *pk);
- rc = get_pubkey (pk, kid);
- if (rc)
- {
- log_error (_("public key %08lX not found: %s\n"),
- (ulong)kid[1], gpg_strerror (rc) );
- return TRUST_UNKNOWN;
- }
-
- if(opt.force_ownertrust)
- {
- log_info("force trust for key %08lX%08lX to %s\n",
- (ulong)kid[0],(ulong)kid[1],
- trust_value_to_string(opt.force_ownertrust));
- update_ownertrust(pk,opt.force_ownertrust);
- ot=opt.force_ownertrust;
- }
- else
- {
- ot=edit_ownertrust(pk,0);
- if(ot>0)
- ot = get_ownertrust (pk);
- else if(ot==0)
- ot = minimum?minimum:TRUST_UNDEFINED;
- else
- ot = -1; /* quit */
- }
-
- free_public_key( pk );
-
- return ot;
-}
-
-
-static void
-mark_keyblock_seen (KeyHashTable tbl, KBNODE node)
-{
- for ( ;node; node = node->next )
- if (node->pkt->pkttype == PKT_PUBLIC_KEY
- || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
- {
- u32 aki[2];
-
- keyid_from_pk (node->pkt->pkt.public_key, aki);
- add_key_hash_table (tbl, aki);
- }
-}
-
-
-static void
-dump_key_array (int depth, struct key_array *keys)
-{
- struct key_array *kar;
-
- for (kar=keys; kar->keyblock; kar++)
- {
- KBNODE node = kar->keyblock;
- u32 kid[2];
-
- keyid_from_pk(node->pkt->pkt.public_key, kid);
- printf ("%d:%08lX%08lX:K::%c::::\n",
- depth, (ulong)kid[0], (ulong)kid[1], '?');
-
- for (; node; node = node->next)
- {
- if (node->pkt->pkttype == PKT_USER_ID)
- {
- int len = node->pkt->pkt.user_id->len;
-
- if (len > 30)
- len = 30;
- printf ("%d:%08lX%08lX:U:::%c:::",
- depth, (ulong)kid[0], (ulong)kid[1],
- (node->flag & 4)? 'f':
- (node->flag & 2)? 'm':
- (node->flag & 1)? 'q':'-');
- print_string (stdout, node->pkt->pkt.user_id->name, len, ':');
- putchar (':');
- putchar ('\n');
- }
- }
- }
-}
-
-
-static void
-store_validation_status (int depth, KBNODE keyblock, KeyHashTable stored)
-{
- KBNODE node;
- int status;
- int any = 0;
-
- for (node=keyblock; node; node = node->next)
- {
- if (node->pkt->pkttype == PKT_USER_ID)
- {
- PKT_user_id *uid = node->pkt->pkt.user_id;
- if (node->flag & 4)
- status = TRUST_FULLY;
- else if (node->flag & 2)
- status = TRUST_MARGINAL;
- else if (node->flag & 1)
- status = TRUST_UNDEFINED;
- else
- status = 0;
-
- if (status)
- {
- update_validity (keyblock->pkt->pkt.public_key,
- uid, depth, status);
-
- mark_keyblock_seen(stored,keyblock);
-
- any = 1;
- }
- }
- }
-
- if (any)
- do_sync ();
-}
-
-/*
- * check whether the signature sig is in the klist k
- */
-static struct key_item *
-is_in_klist (struct key_item *k, PKT_signature *sig)
-{
- for (; k; k = k->next)
- {
- if (k->kid[0] == sig->keyid[0] && k->kid[1] == sig->keyid[1])
- return k;
- }
- return NULL;
-}
-
-/*
- * Mark the signature of the given UID which are used to certify it.
- * To do this, we first revmove all signatures which are not valid and
- * from the remain ones we look for the latest one. If this is not a
- * certification revocation signature we mark the signature by setting
- * node flag bit 8. Note that flag bits 9 and 10 are used for internal
- * purposes.
- */
-static void
-mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode,
- u32 *main_kid, struct key_item *klist,
- u32 curtime, u32 *next_expire)
-{
- KBNODE node;
- PKT_signature *sig;
-
- /* first check all signatures */
- for (node=uidnode->next; node; node = node->next)
- {
- node->flag &= ~(1<<8 | 1<<9 | 1<<10);
- if (node->pkt->pkttype == PKT_USER_ID
- || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
- break; /* ready */
- if (node->pkt->pkttype != PKT_SIGNATURE)
- continue;
-
- sig = node->pkt->pkt.signature;
- if (sig->keyid[0] == main_kid[0] && sig->keyid[1] == main_kid[1])
- continue; /* ignore self-signatures */
- if (!IS_UID_SIG(sig) && !IS_UID_REV(sig))
- continue; /* we only look at these signature classes */
- if (!is_in_klist (klist, sig))
- continue; /* no need to check it then */
- if (check_key_signature (keyblock, node, NULL))
- continue; /* ignore invalid signatures */
- node->flag |= 1<<9;
- }
- /* reset the remaining flags */
- for (; node; node = node->next)
- node->flag &= ~(1<<8 | 1<<9 | 1 << 10);
-
- /* kbnode flag usage: bit 9 is here set for signatures to consider,
- * bit 10 will be set by the loop to keep track of keyIDs already
- * processed, bit 8 will be set for the usable signatures */
-
- /* for each cert figure out the latest valid one */
- for (node=uidnode->next; node; node = node->next)
- {
- KBNODE n, signode;
- u32 kid[2];
- u32 sigdate;
-
- if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
- break;
- if ( !(node->flag & (1<<9)) )
- continue; /* not a node to look at */
- if ( (node->flag & (1<<10)) )
- continue; /* signature with a keyID already processed */
- node->flag |= (1<<10); /* mark this node as processed */
- sig = node->pkt->pkt.signature;
- signode = node;
- sigdate = sig->timestamp;
- kid[0] = sig->keyid[0]; kid[1] = sig->keyid[1];
- for (n=uidnode->next; n; n = n->next)
- {
- if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY)
- break;
- if ( !(n->flag & (1<<9)) )
- continue;
- if ( (n->flag & (1<<10)) )
- continue; /* shortcut already processed signatures */
- sig = n->pkt->pkt.signature;
- if (kid[0] != sig->keyid[0] || kid[1] != sig->keyid[1])
- continue;
- n->flag |= (1<<10); /* mark this node as processed */
-
- /* If signode is nonrevocable and unexpired and n isn't,
- then take signode (skip). It doesn't matter which is
- older: if signode was older then we don't want to take n
- as signode is nonrevocable. If n was older then we're
- automatically fine. */
-
- if(((IS_UID_SIG(signode->pkt->pkt.signature) &&
- !signode->pkt->pkt.signature->flags.revocable &&
- (signode->pkt->pkt.signature->expiredate==0 ||
- signode->pkt->pkt.signature->expiredate>curtime))) &&
- (!(IS_UID_SIG(n->pkt->pkt.signature) &&
- !n->pkt->pkt.signature->flags.revocable &&
- (n->pkt->pkt.signature->expiredate==0 ||
- n->pkt->pkt.signature->expiredate>curtime))))
- continue;
-
- /* If n is nonrevocable and unexpired and signode isn't,
- then take n. Again, it doesn't matter which is older: if
- n was older then we don't want to take signode as n is
- nonrevocable. If signode was older then we're
- automatically fine. */
-
- if((!(IS_UID_SIG(signode->pkt->pkt.signature) &&
- !signode->pkt->pkt.signature->flags.revocable &&
- (signode->pkt->pkt.signature->expiredate==0 ||
- signode->pkt->pkt.signature->expiredate>curtime))) &&
- ((IS_UID_SIG(n->pkt->pkt.signature) &&
- !n->pkt->pkt.signature->flags.revocable &&
- (n->pkt->pkt.signature->expiredate==0 ||
- n->pkt->pkt.signature->expiredate>curtime))))
- {
- signode = n;
- sigdate = sig->timestamp;
- continue;
- }
-
- /* At this point, if it's newer, it goes in as the only
- remaining possibilities are signode and n are both either
- revocable or expired or both nonrevocable and unexpired.
- If the timestamps are equal take the later ordered
- packet, presuming that the key packets are hopefully in
- their original order. */
-
- if (sig->timestamp >= sigdate)
- {
- signode = n;
- sigdate = sig->timestamp;
- }
- }
- sig = signode->pkt->pkt.signature;
- if (IS_UID_SIG (sig))
- { /* this seems to be a usable one which is not revoked.
- * Just need to check whether there is an expiration time,
- * We do the expired certification after finding a suitable
- * certification, the assumption is that a signator does not
- * want that after the expiration of his certificate the
- * system falls back to an older certification which has a
- * different expiration time */
- const byte *p;
- u32 expire;
-
- p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_EXPIRE, NULL );
- expire = p? sig->timestamp + buffer_to_u32(p) : 0;
-
- if (expire==0 || expire > curtime )
- {
- signode->flag |= (1<<8); /* yeah, found a good cert */
- if (expire && expire < *next_expire)
- *next_expire = expire;
- }
- }
- }
-}
-
-/* Used by validate_one_keyblock to confirm a regexp within a trust
- signature. Returns 1 for match, and 0 for no match or regex
- error. */
-static int
-check_regexp(const char *expr,const char *string)
-{
-#ifdef DISABLE_REGEX
- /* When DISABLE_REGEX is defined, assume all regexps do not
- match. */
- return 0;
-#elif defined(__riscos__)
- return riscos_check_regexp(expr, string, DBG_TRUST);
-#else
- int ret;
- regex_t pat;
-
- if(regcomp(&pat,expr,REG_ICASE|REG_NOSUB|REG_EXTENDED)!=0)
- return 0;
-
- ret=regexec(&pat,string,0,NULL,0);
-
- regfree(&pat);
-
- if(DBG_TRUST)
- log_debug("regexp \"%s\" on \"%s\": %s\n",expr,string,ret==0?"YES":"NO");
-
- return (ret==0);
-#endif
-}
-
-/*
- * Return true if the key is signed by one of the keys in the given
- * key ID list. User IDs with a valid signature are marked by node
- * flags as follows:
- * flag bit 0: There is at least one signature
- * 1: There is marginal confidence that this is a legitimate uid
- * 2: There is full confidence that this is a legitimate uid.
- * 8: Used for internal purposes.
- * 9: Ditto (in mark_usable_uid_certs())
- * 10: Ditto (ditto)
- * This function assumes that all kbnode flags are cleared on entry.
- */
-static int
-validate_one_keyblock (KBNODE kb, struct key_item *klist,
- u32 curtime, u32 *next_expire)
-{
- struct key_item *kr;
- KBNODE node, uidnode=NULL;
- PKT_user_id *uid=NULL;
- PKT_public_key *pk = kb->pkt->pkt.public_key;
- u32 main_kid[2];
- int issigned=0, any_signed = 0;
-
- keyid_from_pk(pk, main_kid);
- for (node=kb; node; node = node->next)
- {
- /* A bit of discussion here: is it better for the web of trust
- to be built among only self-signed uids? On the one hand, a
- self-signed uid is a statement that the key owner definitely
- intended that uid to be there, but on the other hand, a
- signed (but not self-signed) uid does carry trust, of a sort,
- even if it is a statement being made by people other than the
- key owner "through" the uids on the key owner's key. I'm
- going with the latter. However, if the user ID was
- explicitly revoked, or passively allowed to expire, that
- should stop validity through the user ID until it is
- resigned. -dshaw */
-
- if (node->pkt->pkttype == PKT_USER_ID
- && !node->pkt->pkt.user_id->is_revoked
- && !node->pkt->pkt.user_id->is_expired)
- {
- if (uidnode && issigned)
- {
- if (uid->help_full_count >= opt.completes_needed
- || uid->help_marginal_count >= opt.marginals_needed )
- uidnode->flag |= 4;
- else if (uid->help_full_count || uid->help_marginal_count)
- uidnode->flag |= 2;
- uidnode->flag |= 1;
- any_signed = 1;
- }
- uidnode = node;
- uid=uidnode->pkt->pkt.user_id;
-
- /* If the selfsig is going to expire... */
- if(uid->expiredate && uid->expiredate<*next_expire)
- *next_expire = uid->expiredate;
-
- issigned = 0;
- get_validity_counts(pk,uid);
- mark_usable_uid_certs (kb, uidnode, main_kid, klist,
- curtime, next_expire);
- }
- else if (node->pkt->pkttype == PKT_SIGNATURE
- && (node->flag & (1<<8)) && uid)
- {
- /* Note that we are only seeing unrevoked sigs here */
- PKT_signature *sig = node->pkt->pkt.signature;
-
- kr = is_in_klist (klist, sig);
- /* If the trust_regexp does not match, it's as if the sig
- did not exist. This is safe for non-trust sigs as well
- since we don't accept a regexp on the sig unless it's a
- trust sig. */
- if (kr && (kr->trust_regexp==NULL || opt.trust_model!=TM_PGP ||
- (uidnode && check_regexp(kr->trust_regexp,
- uidnode->pkt->pkt.user_id->name))))
- {
- if(DBG_TRUST && opt.trust_model==TM_PGP && sig->trust_depth)
- log_debug("trust sig on %s, sig depth is %d, kr depth is %d\n",
- uidnode->pkt->pkt.user_id->name,sig->trust_depth,
- kr->trust_depth);
-
- /* Are we part of a trust sig chain? We always favor
- the latest trust sig, rather than the greater or
- lesser trust sig or value. I could make a decent
- argument for any of these cases, but this seems to be
- what PGP does, and I'd like to be compatible. -dms */
- if(opt.trust_model==TM_PGP && sig->trust_depth
- && pk->trust_timestamp<=sig->timestamp
- && (sig->trust_depth<=kr->trust_depth
- || kr->ownertrust==TRUST_ULTIMATE))
- {
- /* If we got here, we know that:
-
- this is a trust sig.
-
- it's a newer trust sig than any previous trust
- sig on this key (not uid).
-
- it is legal in that it was either generated by an
- ultimate key, or a key that was part of a trust
- chain, and the depth does not violate the
- original trust sig.
-
- if there is a regexp attached, it matched
- successfully.
- */
-
- if(DBG_TRUST)
- log_debug("replacing trust value %d with %d and "
- "depth %d with %d\n",
- pk->trust_value,sig->trust_value,
- pk->trust_depth,sig->trust_depth);
-
- pk->trust_value=sig->trust_value;
- pk->trust_depth=sig->trust_depth-1;
-
- /* If the trust sig contains a regexp, record it
- on the pk for the next round. */
- if(sig->trust_regexp)
- pk->trust_regexp=sig->trust_regexp;
- }
-
- if (kr->ownertrust == TRUST_ULTIMATE)
- uid->help_full_count = opt.completes_needed;
- else if (kr->ownertrust == TRUST_FULLY)
- uid->help_full_count++;
- else if (kr->ownertrust == TRUST_MARGINAL)
- uid->help_marginal_count++;
- issigned = 1;
- }
- }
- }
-
- if (uidnode && issigned)
- {
- if (uid->help_full_count >= opt.completes_needed
- || uid->help_marginal_count >= opt.marginals_needed )
- uidnode->flag |= 4;
- else if (uid->help_full_count || uid->help_marginal_count)
- uidnode->flag |= 2;
- uidnode->flag |= 1;
- any_signed = 1;
- }
-
- return any_signed;
-}
-
-
-static int
-search_skipfnc (void *opaque, u32 *kid)
-{
- return test_key_hash_table ((KeyHashTable)opaque, kid);
-}
-
-
-/*
- * Scan all keys and return a key_array of all suitable keys from
- * kllist. The caller has to pass keydb handle so that we don't use
- * to create our own. Returns either a key_array or NULL in case of
- * an error. No results found are indicated by an empty array.
- * Caller hast to release the returned array.
- */
-static struct key_array *
-validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
- struct key_item *klist, u32 curtime, u32 *next_expire)
-{
- KBNODE keyblock = NULL;
- struct key_array *keys = NULL;
- size_t nkeys, maxkeys;
- int rc;
- KEYDB_SEARCH_DESC desc;
-
- maxkeys = 1000;
- keys = xmalloc ((maxkeys+1) * sizeof *keys);
- nkeys = 0;
-
- rc = keydb_search_reset (hd);
- if (rc)
- {
- log_error ("keydb_search_reset failed: %s\n", gpg_strerror (rc));
- xfree (keys);
- return NULL;
- }
-
- memset (&desc, 0, sizeof desc);
- desc.mode = KEYDB_SEARCH_MODE_FIRST;
- desc.skipfnc = search_skipfnc;
- desc.skipfncvalue = full_trust;
- rc = keydb_search (hd, &desc, 1);
- if (rc == -1)
- {
- keys[nkeys].keyblock = NULL;
- return keys;
- }
- if (rc)
- {
- log_error ("keydb_search_first failed: %s\n", gpg_strerror (rc));
- xfree (keys);
- return NULL;
- }
-
- desc.mode = KEYDB_SEARCH_MODE_NEXT; /* change mode */
- do
- {
- PKT_public_key *pk;
-
- rc = keydb_get_keyblock (hd, &keyblock);
- if (rc)
- {
- log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
- xfree (keys);
- return NULL;
- }
-
- if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
- {
- log_debug ("ooops: invalid pkttype %d encountered\n",
- keyblock->pkt->pkttype);
- dump_kbnode (keyblock);
- release_kbnode(keyblock);
- continue;
- }
-
- /* prepare the keyblock for further processing */
- merge_keys_and_selfsig (keyblock);
- clear_kbnode_flags (keyblock);
- pk = keyblock->pkt->pkt.public_key;
- if (pk->has_expired || pk->is_revoked)
- {
- /* it does not make sense to look further at those keys */
- mark_keyblock_seen (full_trust, keyblock);
- }
- else if (validate_one_keyblock (keyblock, klist, curtime, next_expire))
- {
- KBNODE node;
-
- if (pk->expiredate && pk->expiredate >= curtime
- && pk->expiredate < *next_expire)
- *next_expire = pk->expiredate;
-
- if (nkeys == maxkeys) {
- maxkeys += 1000;
- keys = xrealloc (keys, (maxkeys+1) * sizeof *keys);
- }
- keys[nkeys++].keyblock = keyblock;
-
- /* Optimization - if all uids are fully trusted, then we
- never need to consider this key as a candidate again. */
-
- for (node=keyblock; node; node = node->next)
- if (node->pkt->pkttype == PKT_USER_ID && !(node->flag & 4))
- break;
-
- if(node==NULL)
- mark_keyblock_seen (full_trust, keyblock);
-
- keyblock = NULL;
- }
-
- release_kbnode (keyblock);
- keyblock = NULL;
- }
- while ( !(rc = keydb_search (hd, &desc, 1)) );
- if (rc && rc != -1)
- {
- log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
- xfree (keys);
- return NULL;
- }
-
- keys[nkeys].keyblock = NULL;
- return keys;
-}
-
-/* Caller must sync */
-static void
-reset_trust_records (KEYDB_HANDLE hd, KeyHashTable exclude)
-{
- int rc;
- KBNODE keyblock = NULL;
- KEYDB_SEARCH_DESC desc;
- int count = 0, nreset = 0;
-
- rc = keydb_search_reset (hd);
- if (rc)
- {
- log_error ("keydb_search_reset failed: %s\n", gpg_strerror (rc));
- return;
- }
-
- memset (&desc, 0, sizeof desc);
- desc.mode = KEYDB_SEARCH_MODE_FIRST;
- if(exclude)
- {
- desc.skipfnc = search_skipfnc;
- desc.skipfncvalue = exclude;
- }
- rc = keydb_search (hd, &desc, 1);
- if (rc && rc != -1 )
- log_error ("keydb_search_first failed: %s\n", gpg_strerror (rc));
- else if (!rc)
- {
- desc.mode = KEYDB_SEARCH_MODE_NEXT; /* change mode */
- do
- {
- rc = keydb_get_keyblock (hd, &keyblock);
- if (rc)
- {
- log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
- break;
- }
- count++;
-
- if (keyblock->pkt->pkttype == PKT_PUBLIC_KEY) /* paranoid assertion*/
- {
- nreset += clear_validity (keyblock->pkt->pkt.public_key);
- release_kbnode (keyblock);
- }
- }
- while ( !(rc = keydb_search (hd, &desc, 1)) );
- if (rc && rc != -1)
- log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
- }
- if (opt.verbose)
- log_info (_("%d keys processed (%d validity counts cleared)\n"),
- count, nreset);
-}
-
-/*
- * Run the key validation procedure.
- *
- * This works this way:
- * Step 1: Find all ultimately trusted keys (UTK).
- * mark them all as seen and put them into klist.
- * Step 2: loop max_cert_times
- * Step 3: if OWNERTRUST of any key in klist is undefined
- * ask user to assign ownertrust
- * Step 4: Loop over all keys in the keyDB which are not marked seen
- * Step 5: if key is revoked or expired
- * mark key as seen
- * continue loop at Step 4
- * Step 6: For each user ID of that key signed by a key in klist
- * Calculate validity by counting trusted signatures.
- * Set validity of user ID
- * Step 7: If any signed user ID was found
- * mark key as seen
- * End Loop
- * Step 8: Build a new klist from all fully trusted keys from step 6
- * End Loop
- * Ready
- *
- */
-static int
-validate_keys (int interactive)
-{
- int rc = 0;
- int quit=0;
- struct key_item *klist = NULL;
- struct key_item *k;
- struct key_array *keys = NULL;
- struct key_array *kar;
- KEYDB_HANDLE kdb = NULL;
- KBNODE node;
- int depth;
- int key_count;
- int ot_unknown, ot_undefined, ot_never, ot_marginal, ot_full, ot_ultimate;
- KeyHashTable stored,used,full_trust;
- u32 start_time, next_expire;
-
- start_time = make_timestamp ();
- next_expire = 0xffffffff; /* set next expire to the year 2106 */
- stored = new_key_hash_table ();
- used = new_key_hash_table ();
- full_trust = new_key_hash_table ();
- /* Fixme: Instead of always building a UTK list, we could just build it
- * here when needed */
- if (!utk_list)
- {
- log_info (_("no ultimately trusted keys found\n"));
- goto leave;
- }
-
- kdb = keydb_new (0);
-
- reset_trust_records (kdb,NULL);
-
- /* mark all UTKs as used and fully_trusted and set validity to
- ultimate */
- for (k=utk_list; k; k = k->next)
- {
- KBNODE keyblock;
- PKT_public_key *pk;
-
- keyblock = get_pubkeyblock (k->kid);
- if (!keyblock)
- {
- log_error (_("public key of ultimately"
- " trusted key %08lX not found\n"), (ulong)k->kid[1]);
- continue;
- }
- mark_keyblock_seen (used, keyblock);
- mark_keyblock_seen (stored, keyblock);
- mark_keyblock_seen (full_trust, keyblock);
- pk = keyblock->pkt->pkt.public_key;
- for (node=keyblock; node; node = node->next)
- {
- if (node->pkt->pkttype == PKT_USER_ID)
- update_validity (pk, node->pkt->pkt.user_id, 0, TRUST_ULTIMATE);
- }
- if ( pk->expiredate && pk->expiredate >= start_time
- && pk->expiredate < next_expire)
- next_expire = pk->expiredate;
-
- release_kbnode (keyblock);
- do_sync ();
- }
-
- klist = utk_list;
-
- log_info(_("%d marginal(s) needed, %d complete(s) needed, %s trust model\n"),
- opt.marginals_needed,opt.completes_needed,trust_model_string());
-
- for (depth=0; depth < opt.max_cert_depth; depth++)
- {
- /* See whether we should assign ownertrust values to the keys in
- utk_list. */
- ot_unknown = ot_undefined = ot_never = 0;
- ot_marginal = ot_full = ot_ultimate = 0;
- for (k=klist; k; k = k->next)
- {
- int min=0;
-
- /* 120 and 60 are as per RFC2440 */
- if(k->trust_value>=120)
- min=TRUST_FULLY;
- else if(k->trust_value>=60)
- min=TRUST_MARGINAL;
-
- if(min!=k->min_ownertrust)
- update_min_ownertrust(k->kid,min);
-
- if (interactive && k->ownertrust == TRUST_UNKNOWN)
- {
- k->ownertrust = ask_ownertrust (k->kid,min);
-
- if (k->ownertrust == -1)
- {
- quit=1;
- goto leave;
- }
- }
-
- /* This can happen during transition from an old trustdb
- before trust sigs. It can also happen if a user uses two
- different versions of GnuPG or changes the --trust-model
- setting. */
- if(k->ownertrust<min)
- {
- if(DBG_TRUST)
- log_debug("key %08lX: "
- "overriding ownertrust \"%s\" with \"%s\"\n",
- (ulong)k->kid[1],
- trust_value_to_string(k->ownertrust),
- trust_value_to_string(min));
-
- k->ownertrust=min;
- }
-
- if (k->ownertrust == TRUST_UNKNOWN)
- ot_unknown++;
- else if (k->ownertrust == TRUST_UNDEFINED)
- ot_undefined++;
- else if (k->ownertrust == TRUST_NEVER)
- ot_never++;
- else if (k->ownertrust == TRUST_MARGINAL)
- ot_marginal++;
- else if (k->ownertrust == TRUST_FULLY)
- ot_full++;
- else if (k->ownertrust == TRUST_ULTIMATE)
- ot_ultimate++;
- }
-
- /* Find all keys which are signed by a key in kdlist */
- keys = validate_key_list (kdb, full_trust, klist,
- start_time, &next_expire);
- if (!keys)
- {
- log_error ("validate_key_list failed\n");
- rc = GPG_ERR_GENERAL;
- goto leave;
- }
-
- for (key_count=0, kar=keys; kar->keyblock; kar++, key_count++)
- ;
-
- /* Store the calculated valididation status somewhere */
- if (opt.verbose > 1)
- dump_key_array (depth, keys);
-
- for (kar=keys; kar->keyblock; kar++)
- store_validation_status (depth, kar->keyblock, stored);
-
- log_info (_("checking at depth %d valid=%d"
- " ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%d\n"),
- depth, key_count, ot_unknown, ot_undefined,
- ot_never, ot_marginal, ot_full, ot_ultimate );
-
- /* Build a new kdlist from all fully valid keys in KEYS */
- if (klist != utk_list)
- release_key_items (klist);
- klist = NULL;
- for (kar=keys; kar->keyblock; kar++)
- {
- for (node=kar->keyblock; node; node = node->next)
- {
- if (node->pkt->pkttype == PKT_USER_ID && (node->flag & 4))
- {
- u32 kid[2];
-
- /* have we used this key already? */
- keyid_from_pk (kar->keyblock->pkt->pkt.public_key, kid);
- if(test_key_hash_table(used,kid)==0)
- {
- /* Normally we add both the primary and subkey
- ids to the hash via mark_keyblock_seen, but
- since we aren't using this hash as a skipfnc,
- that doesn't matter here. */
- add_key_hash_table (used,kid);
- k = new_key_item ();
- k->kid[0]=kid[0];
- k->kid[1]=kid[1];
- k->ownertrust =
- (get_ownertrust (kar->keyblock->pkt->pkt.public_key)
- & TRUST_MASK);
- k->min_ownertrust =
- get_min_ownertrust(kar->keyblock->pkt->pkt.public_key);
- k->trust_depth=
- kar->keyblock->pkt->pkt.public_key->trust_depth;
- k->trust_value=
- kar->keyblock->pkt->pkt.public_key->trust_value;
- if(kar->keyblock->pkt->pkt.public_key->trust_regexp)
- k->trust_regexp=
- xstrdup (kar->keyblock->pkt->
- pkt.public_key->trust_regexp);
- k->next = klist;
- klist = k;
- break;
- }
- }
- }
- }
- release_key_array (keys);
- keys = NULL;
- if (!klist)
- break; /* no need to dive in deeper */
- }
-
- leave:
- keydb_release (kdb);
- release_key_array (keys);
- release_key_items (klist);
- release_key_hash_table (full_trust);
- release_key_hash_table (used);
- release_key_hash_table (stored);
- if (!rc && !quit) /* mark trustDB as checked */
- {
- if (next_expire == 0xffffffff || next_expire < start_time )
- tdbio_write_nextcheck (0);
- else
- {
- tdbio_write_nextcheck (next_expire);
- log_info (_("next trustdb check due at %s\n"),
- strtimestamp (next_expire));
- }
-
- if(tdbio_update_version_record()!=0)
- {
- log_error(_("unable to update trustdb version record: "
- "write failed: %s\n"), gpg_strerror (rc));
- tdbio_invalid();
- }
-
- do_sync ();
- pending_check_trustdb = 0;
- }
-
- return rc;
-}
diff --git a/g10/trustdb.h b/g10/trustdb.h
deleted file mode 100644
index 414c37702..000000000
--- a/g10/trustdb.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* trustdb.h - Trust database
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
- * 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef G10_TRUSTDB_H
-#define G10_TRUSTDB_H
-
-
-/* Trust values must be sorted in ascending order */
-#define TRUST_MASK 15
-#define TRUST_UNKNOWN 0 /* o: not yet calculated/assigned */
-#define TRUST_EXPIRED 1 /* e: calculation may be invalid */
-#define TRUST_UNDEFINED 2 /* q: not enough information for calculation */
-#define TRUST_NEVER 3 /* n: never trust this pubkey */
-#define TRUST_MARGINAL 4 /* m: marginally trusted */
-#define TRUST_FULLY 5 /* f: fully trusted */
-#define TRUST_ULTIMATE 6 /* u: ultimately trusted */
-/* trust values not covered by the mask */
-#define TRUST_FLAG_REVOKED 32 /* r: revoked */
-#define TRUST_FLAG_SUB_REVOKED 64 /* r: revoked but for subkeys */
-#define TRUST_FLAG_DISABLED 128 /* d: key/uid disabled */
-#define TRUST_FLAG_PENDING_CHECK 256 /* a check-trustdb is pending */
-
-/*-- trustdb.c --*/
-void register_trusted_key( const char *string );
-void check_trustdb (void);
-void update_trustdb (void);
-int setup_trustdb( int level, const char *dbname );
-void init_trustdb( void );
-void sync_trustdb( void );
-
-const char *trust_value_to_string (unsigned int value);
-int string_to_trust_value (const char *str);
-
-void revalidation_mark (void);
-int trustdb_pending_check(void);
-
-int cache_disabled_value(PKT_public_key *pk);
-
-unsigned int get_validity (PKT_public_key *pk, PKT_user_id *uid);
-int get_validity_info (PKT_public_key *pk, PKT_user_id *uid);
-const char *get_validity_string (PKT_public_key *pk, PKT_user_id *uid);
-
-void list_trust_path( const char *username );
-int enum_cert_paths( void **context, ulong *lid,
- unsigned *ownertrust, unsigned *validity );
-void enum_cert_paths_print( void **context, FILE *fp,
- int refresh, ulong selected_lid );
-
-void read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck,
- byte *marginals,byte *completes,byte *cert_depth);
-
-unsigned int get_ownertrust (PKT_public_key *pk);
-unsigned int get_min_ownertrust (PKT_public_key *pk);
-int get_ownertrust_info (PKT_public_key *pk);
-const char *get_ownertrust_string (PKT_public_key *pk);
-
-void update_ownertrust (PKT_public_key *pk, unsigned int new_trust );
-int clear_ownertrusts (PKT_public_key *pk);
-
-/*-- tdbdump.c --*/
-void list_trustdb(const char *username);
-void export_ownertrust(void);
-void import_ownertrust(const char *fname);
-
-/*-- pkclist.c --*/
-int edit_ownertrust (PKT_public_key *pk, int mode );
-
-#endif /*G10_TRUSTDB_H*/
diff --git a/g10/verify.c b/g10/verify.c
deleted file mode 100644
index cfa373637..000000000
--- a/g10/verify.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/* verify.c - verify signed data
- * Copyright (C) 1998, 1999, 2000, 2001 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 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <unistd.h> /* for isatty() */
-
-#include "options.h"
-#include "packet.h"
-#include "errors.h"
-#include "iobuf.h"
-#include "keydb.h"
-#include "memory.h"
-#include "util.h"
-#include "main.h"
-#include "status.h"
-#include "filter.h"
-#include "ttyio.h"
-#include "i18n.h"
-
-
-
-/****************
- * Assume that the input is a signature and verify it without
- * generating any output. With no arguments, the signature packet
- * is read from stdin (it may be a detached signature when not
- * used in batch mode). If only a sigfile is given, it may be a complete
- * signature or a detached signature in which case the signed stuff
- * is expected from stdin. With more than 1 argument, the first should
- * be a detached signature and the remaining files are the signed stuff.
- */
-
-int
-verify_signatures( int nfiles, char **files )
-{
- iobuf_t fp;
- armor_filter_context_t afx;
- progress_filter_context_t pfx;
- const char *sigfile;
- int i, rc;
- STRLIST sl;
-
- memset( &afx, 0, sizeof afx);
- /* decide whether we should handle a detached or a normal signature,
- * which is needed so that the code later can hash the correct data and
- * not have a normal signature act as detached signature and ignoring the
- * indended signed material from the 2nd file or stdin.
- * 1. gpg <file - normal
- * 2. gpg file - normal (or detached)
- * 3. gpg file <file2 - detached
- * 4. gpg file file2 - detached
- * The question is how decide between case 2 and 3? The only way
- * we can do it is by reading one byte from stdin and the unget
- * it; the problem here is that we may be reading from the
- * terminal (which could be detected using isatty() but won't work
- * when under contol of a pty using program (e.g. expect)) and
- * might get us in trouble when stdin is used for another purpose
- * (--passphrase-fd 0). So we have to break with the behaviour
- * prior to gpg 1.0.4 by assuming that case 3 is a normal
- * signature (where file2 is ignored and require for a detached
- * signature to indicate signed material comes from stdin by using
- * case 4 with a file2 of "-".
- *
- * Actually we don't have to change anything here but can handle
- * that all quite easily in mainproc.c
- */
-
-
- sigfile = nfiles? *files : NULL;
-
- /* open the signature file */
- fp = iobuf_open(sigfile);
- if( !fp ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("can't open `%s': %s\n"),
- print_fname_stdin(sigfile), strerror (errno));
- return rc;
- }
- handle_progress (&pfx, fp, sigfile);
-
- if( !opt.no_armor && use_armor_filter( fp ) )
- iobuf_push_filter( fp, armor_filter, &afx );
-
- sl = NULL;
- for(i=1 ; i < nfiles; i++ )
- add_to_strlist( &sl, files[i] );
- rc = proc_signature_packets( NULL, fp, sl, sigfile );
- free_strlist(sl);
- iobuf_close(fp);
- if( afx.no_openpgp_data && rc == -1 ) {
- log_error(_("the signature could not be verified.\n"
- "Please remember that the signature file (.sig or .asc)\n"
- "should be the first file given on the command line.\n") );
- rc = 0;
- }
-
- return rc;
-}
-
-
-void
-print_file_status( int status, const char *name, int what )
-{
- char *p = xmalloc (strlen(name)+10);
- sprintf(p, "%d %s", what, name );
- write_status_text( status, p );
- xfree (p);
-}
-
-
-static int
-verify_one_file( const char *name )
-{
- iobuf_t fp;
- armor_filter_context_t afx;
- progress_filter_context_t pfx;
- int rc;
-
- print_file_status( STATUS_FILE_START, name, 1 );
- fp = iobuf_open(name);
- if( !fp ) {
- rc = gpg_error_from_errno (errno);
- log_error(_("can't open `%s': %s\n"),
- print_fname_stdin(name), strerror (errno));
- print_file_status( STATUS_FILE_ERROR, name, 1 );
- return rc;
- }
- handle_progress (&pfx, fp, name);
-
- if( !opt.no_armor ) {
- if( use_armor_filter( fp ) ) {
- memset( &afx, 0, sizeof afx);
- iobuf_push_filter( fp, armor_filter, &afx );
- }
- }
-
- rc = proc_signature_packets( NULL, fp, NULL, name );
- iobuf_close(fp);
- write_status( STATUS_FILE_DONE );
- return rc;
-}
-
-/****************
- * Verify each file given in the files array or read the names of the
- * files from stdin.
- * Note: This function can not handle detached signatures.
- */
-int
-verify_files( int nfiles, char **files )
-{
- int i;
-
- if( !nfiles ) { /* read the filenames from stdin */
- 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 GPG_ERR_GENERAL;
- }
- /* This code does not work on MSDOS but how cares there are
- * also no script languages available. We don't strip any
- * spaces, so that we can process nearly all filenames */
- line[strlen(line)-1] = 0;
- verify_one_file( line );
- }
-
- }
- else { /* take filenames from the array */
- for(i=0; i < nfiles; i++ )
- verify_one_file( files[i] );
- }
- return 0;
-}