From 69161803cbf55ca2f34c6ea5d2172d13f74cc0e6 Mon Sep 17 00:00:00 2001 From: Repo Admin Date: Thu, 12 Sep 2002 13:13:41 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'STABLE-BRANCH-1-2'. --- agent/ChangeLog | 410 ----- agent/Makefile.am | 62 - agent/agent.h | 195 --- agent/cache.c | 285 ---- agent/call-scd.c | 592 ------- agent/command.c | 697 --------- agent/divert-scd.c | 305 ---- agent/findkey.c | 350 ----- agent/genkey.c | 200 --- agent/gpg-agent.c | 908 ----------- agent/keyformat.txt | 163 -- agent/learncard.c | 380 ----- agent/minip12.c | 1146 -------------- agent/minip12.h | 32 - agent/pkdecrypt.c | 138 -- agent/pksign.c | 183 --- agent/protect-tool.c | 977 ------------ agent/protect.c | 967 ------------ agent/query.c | 460 ------ agent/sexp-parse.h | 98 -- agent/simple-pwquery.c | 485 ------ agent/simple-pwquery.h | 69 - agent/trans.c | 42 - agent/trustlist.c | 304 ---- assuan/ChangeLog | 250 --- assuan/Makefile.am | 49 - assuan/assuan-buffer.c | 443 ------ assuan/assuan-client.c | 225 --- assuan/assuan-connect.c | 54 - assuan/assuan-defs.h | 144 -- assuan/assuan-handler.c | 708 --------- assuan/assuan-inquire.c | 239 --- assuan/assuan-listen.c | 132 -- assuan/assuan-pipe-connect.c | 288 ---- assuan/assuan-pipe-server.c | 124 -- assuan/assuan-socket-connect.c | 150 -- assuan/assuan-socket-server.c | 169 -- assuan/assuan-util.c | 210 --- assuan/assuan.h | 234 --- assuan/mkerrors | 71 - common/ChangeLog | 139 -- common/Makefile.am | 52 - common/README | 14 - common/cryptmiss.c | 39 - common/errors.h | 192 --- common/fopencookie.c | 37 - common/fseeko.c | 40 - common/ftello.c | 45 - common/gettime.c | 87 -- common/i18n.h | 47 - common/maperror.c | 271 ---- common/mkdtemp.c | 99 -- common/mkerrors | 72 - common/mkerrtok | 67 - common/signal.c | 226 --- common/sysutils.c | 206 --- common/sysutils.h | 30 - common/util.h | 117 -- common/vasprintf.c | 169 -- kbx/ChangeLog | 102 -- kbx/Makefile.am | 53 - kbx/kbxutil.c | 338 ---- kbx/keybox-blob.c | 1007 ------------ kbx/keybox-defs.h | 179 --- kbx/keybox-dump.c | 346 ---- kbx/keybox-errors.c | 47 - kbx/keybox-file.c | 102 -- kbx/keybox-init.c | 127 -- kbx/keybox-search-desc.h | 72 - kbx/keybox-search.c | 810 ---------- kbx/keybox-update.c | 433 ----- kbx/keybox-util.c | 72 - kbx/keybox.h | 125 -- kbx/mkerrors | 71 - scd/ChangeLog | 91 -- scd/Makefile.am | 42 - scd/card-common.h | 73 - scd/card-dinsig.c | 256 --- scd/card-p15.c | 498 ------ scd/card.c | 540 ------- scd/command.c | 651 -------- scd/scdaemon.c | 633 -------- scd/scdaemon.h | 104 -- sm/ChangeLog | 734 --------- sm/Makefile.am | 57 - sm/base64.c | 624 -------- sm/call-agent.c | 751 --------- sm/call-dirmngr.c | 495 ------ sm/certchain.c | 773 --------- sm/certcheck.c | 289 ---- sm/certdump.c | 457 ------ sm/certlist.c | 313 ---- sm/certreqgen.c | 699 --------- sm/decrypt.c | 502 ------ sm/delete.c | 165 -- sm/encrypt.c | 549 ------- sm/export.c | 248 --- sm/fingerprint.c | 271 ---- sm/gpgsm.c | 1388 ----------------- sm/gpgsm.h | 261 ---- sm/import.c | 349 ----- sm/keydb.c | 1282 --------------- sm/keydb.h | 73 - sm/keylist.c | 616 -------- sm/misc.c | 32 - sm/server.c | 1057 ------------- sm/sign.c | 622 -------- sm/verify.c | 510 ------ .../567064FE6D14A17B2D811ABB407728BC558AA455 | 18 - tests/ChangeLog | 52 - tests/Makefile.am | 78 - tests/asschk.c | 1046 ------------- tests/cert_cci_sphinx_ca.pem | 18 - tests/cert_cci_test_wzs.pem | 4 - tests/cert_cci_test_zs.pem | 16 - tests/cert_cci_user02.pem | 17 - tests/cert_cci_user03.pem | 17 - tests/cert_cci_user04.pem | 17 - tests/cert_cci_user06.pem | 17 - tests/cert_cci_user07.pem | 17 - tests/cert_testpki_testpca.pem | 21 - tests/crl_testpki_testpca.pem | 18 - tests/inittests | 96 -- tests/key_g10code_pete1.pem | 18 - tests/key_g10code_theo1.pem | 21 - tests/runtest | 5 - ...100C27173EF6E9C4E9A25D3D69F86D37A4F939.key | 18 - ...6D17B4B94BBE8304926C016D2C5C7805EB6705.key | 10 - tests/samplekeys/cert_g10code_enconly_1.pem | 26 - tests/samplekeys/cert_g10code_pete1.pem | 24 - tests/samplekeys/cert_g10code_test1.pem | 19 - tests/samplekeys/cert_g10code_test_ca.pem | 27 - tests/samplekeys/cert_g10code_theo1.pem | 40 - tests/skey_g10code_test1.pem | 19 - tests/sm-sign+verify | 73 - tests/sm-verify | 114 -- tests/text-1.dsig.pem | 27 - tests/text-1.osig-bad.pem | 45 - tests/text-1.osig-badusage.pem | 75 - tests/text-1.osig.pem | 48 - tests/text-1.txt | 17 - tests/text-2.osig-bad.pem | 28 - tests/text-2.osig.pem | 29 - tests/text-2.txt | 2 - tests/text-3.txt | 2 - 145 files changed, 36915 deletions(-) delete mode 100644 agent/ChangeLog delete mode 100644 agent/Makefile.am delete mode 100644 agent/agent.h delete mode 100644 agent/cache.c delete mode 100644 agent/call-scd.c delete mode 100644 agent/command.c delete mode 100644 agent/divert-scd.c delete mode 100644 agent/findkey.c delete mode 100644 agent/genkey.c delete mode 100644 agent/gpg-agent.c delete mode 100644 agent/keyformat.txt delete mode 100644 agent/learncard.c delete mode 100644 agent/minip12.c delete mode 100644 agent/minip12.h delete mode 100644 agent/pkdecrypt.c delete mode 100644 agent/pksign.c delete mode 100644 agent/protect-tool.c delete mode 100644 agent/protect.c delete mode 100644 agent/query.c delete mode 100644 agent/sexp-parse.h delete mode 100644 agent/simple-pwquery.c delete mode 100644 agent/simple-pwquery.h delete mode 100644 agent/trans.c delete mode 100644 agent/trustlist.c delete mode 100644 assuan/ChangeLog delete mode 100644 assuan/Makefile.am delete mode 100644 assuan/assuan-buffer.c delete mode 100644 assuan/assuan-client.c delete mode 100644 assuan/assuan-connect.c delete mode 100644 assuan/assuan-defs.h delete mode 100644 assuan/assuan-handler.c delete mode 100644 assuan/assuan-inquire.c delete mode 100644 assuan/assuan-listen.c delete mode 100644 assuan/assuan-pipe-connect.c delete mode 100644 assuan/assuan-pipe-server.c delete mode 100644 assuan/assuan-socket-connect.c delete mode 100644 assuan/assuan-socket-server.c delete mode 100644 assuan/assuan-util.c delete mode 100644 assuan/assuan.h delete mode 100755 assuan/mkerrors delete mode 100644 common/ChangeLog delete mode 100644 common/Makefile.am delete mode 100644 common/README delete mode 100644 common/cryptmiss.c delete mode 100644 common/errors.h delete mode 100644 common/fopencookie.c delete mode 100644 common/fseeko.c delete mode 100644 common/ftello.c delete mode 100644 common/gettime.c delete mode 100644 common/i18n.h delete mode 100644 common/maperror.c delete mode 100644 common/mkdtemp.c delete mode 100755 common/mkerrors delete mode 100755 common/mkerrtok delete mode 100644 common/signal.c delete mode 100644 common/sysutils.c delete mode 100644 common/sysutils.h delete mode 100644 common/util.h delete mode 100644 common/vasprintf.c delete mode 100644 kbx/ChangeLog delete mode 100644 kbx/Makefile.am delete mode 100644 kbx/kbxutil.c delete mode 100644 kbx/keybox-blob.c delete mode 100644 kbx/keybox-defs.h delete mode 100644 kbx/keybox-dump.c delete mode 100644 kbx/keybox-errors.c delete mode 100644 kbx/keybox-file.c delete mode 100644 kbx/keybox-init.c delete mode 100644 kbx/keybox-search-desc.h delete mode 100644 kbx/keybox-search.c delete mode 100644 kbx/keybox-update.c delete mode 100644 kbx/keybox-util.c delete mode 100644 kbx/keybox.h delete mode 100755 kbx/mkerrors delete mode 100644 scd/ChangeLog delete mode 100644 scd/Makefile.am delete mode 100644 scd/card-common.h delete mode 100644 scd/card-dinsig.c delete mode 100644 scd/card-p15.c delete mode 100644 scd/card.c delete mode 100644 scd/command.c delete mode 100644 scd/scdaemon.c delete mode 100644 scd/scdaemon.h delete mode 100644 sm/ChangeLog delete mode 100644 sm/Makefile.am delete mode 100644 sm/base64.c delete mode 100644 sm/call-agent.c delete mode 100644 sm/call-dirmngr.c delete mode 100644 sm/certchain.c delete mode 100644 sm/certcheck.c delete mode 100644 sm/certdump.c delete mode 100644 sm/certlist.c delete mode 100644 sm/certreqgen.c delete mode 100644 sm/decrypt.c delete mode 100644 sm/delete.c delete mode 100644 sm/encrypt.c delete mode 100644 sm/export.c delete mode 100644 sm/fingerprint.c delete mode 100644 sm/gpgsm.c delete mode 100644 sm/gpgsm.h delete mode 100644 sm/import.c delete mode 100644 sm/keydb.c delete mode 100644 sm/keydb.h delete mode 100644 sm/keylist.c delete mode 100644 sm/misc.c delete mode 100644 sm/server.c delete mode 100644 sm/sign.c delete mode 100644 sm/verify.c delete mode 100644 tests/567064FE6D14A17B2D811ABB407728BC558AA455 delete mode 100644 tests/ChangeLog delete mode 100644 tests/Makefile.am delete mode 100644 tests/asschk.c delete mode 100644 tests/cert_cci_sphinx_ca.pem delete mode 100644 tests/cert_cci_test_wzs.pem delete mode 100644 tests/cert_cci_test_zs.pem delete mode 100644 tests/cert_cci_user02.pem delete mode 100644 tests/cert_cci_user03.pem delete mode 100644 tests/cert_cci_user04.pem delete mode 100644 tests/cert_cci_user06.pem delete mode 100644 tests/cert_cci_user07.pem delete mode 100644 tests/cert_testpki_testpca.pem delete mode 100644 tests/crl_testpki_testpca.pem delete mode 100755 tests/inittests delete mode 100644 tests/key_g10code_pete1.pem delete mode 100644 tests/key_g10code_theo1.pem delete mode 100755 tests/runtest delete mode 100644 tests/samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key delete mode 100644 tests/samplekeys/8D6D17B4B94BBE8304926C016D2C5C7805EB6705.key delete mode 100644 tests/samplekeys/cert_g10code_enconly_1.pem delete mode 100644 tests/samplekeys/cert_g10code_pete1.pem delete mode 100644 tests/samplekeys/cert_g10code_test1.pem delete mode 100644 tests/samplekeys/cert_g10code_test_ca.pem delete mode 100644 tests/samplekeys/cert_g10code_theo1.pem delete mode 100644 tests/skey_g10code_test1.pem delete mode 100644 tests/sm-sign+verify delete mode 100644 tests/sm-verify delete mode 100644 tests/text-1.dsig.pem delete mode 100644 tests/text-1.osig-bad.pem delete mode 100644 tests/text-1.osig-badusage.pem delete mode 100644 tests/text-1.osig.pem delete mode 100644 tests/text-1.txt delete mode 100644 tests/text-2.osig-bad.pem delete mode 100644 tests/text-2.osig.pem delete mode 100644 tests/text-2.txt delete mode 100644 tests/text-3.txt diff --git a/agent/ChangeLog b/agent/ChangeLog deleted file mode 100644 index c718380de..000000000 --- a/agent/ChangeLog +++ /dev/null @@ -1,410 +0,0 @@ -2002-09-09 Werner Koch - - * gpg-agent.c (create_private_keys_directory) - (create_directories): New. - (main): Try to create a home directory. - -2002-09-04 Neal H. Walfield - - * gpg-agent.c (main): Use sigaction, not signal. - -2002-09-03 Neal H. Walfield - - * findkey.c: Include . - (agent_write_private_key): Prefer POSIX compatibity, open and - fdopen, over the simplicity of GNU extensions, fopen(file, "x"). - -2002-08-22 Werner Koch - - * query.c (agent_askpin): Provide the default desc text depending - on the pininfo. Do the basic PIN verification only when - min_digits is set. - -2002-08-21 Werner Koch - - * query.c (agent_askpin): Hack to show the right default prompt. - (agent_get_passphrase): Ditto. - - * trans.c: Removed and replaced all usages with standard _() - - * divert-scd.c (getpin_cb): Pass a more descritive text to the - pinentry. - - * Makefile.am: Renamed the binary protect-tool to gpg-protect-tool. - * protect-tool.c: Removed the note about internal use only. - - * gpg-agent.c (main): New option --daemon so that the program is - not accidently started in the background. - -2002-08-16 Werner Koch - - * call-scd.c (learn_status_cb): Handle CERTINFO status. - (agent_card_learn): Add args for certinfo cb. - * learncard.c (release_certinfo,certinfo_cb): New. - (send_cert_back): New. With factored out code from .. - (agent_handle_learn): here. Return certinfo stuff. - -2002-07-26 Werner Koch - - * gpg-agent.c (main): New option --ignore-cache-for-signing. - * command.c (option_handler): New server option - use-cache-for-signing defaulting to true. - (cmd_pksign): handle global and per session option. - * findkey.c (agent_key_from_file, unprotect): New arg - ignore_cache. Changed all callers. - * pksign.c (agent_pksign): Likewise. - -2002-06-29 Werner Koch - - * query.c (start_pinentry): Use GNUPG_DERAULT_PINENTRY. - * call-scd.c (start_scd): Use GNUPG_DEFAULT_SCDAEMON. - -2002-06-28 Werner Koch - - * protect-tool.c (export_p12_file): New. - (main): New command --p12-export. - * minip12.c (create_final,p12_build,compute_tag_length): New. - (store_tag_length): New. - -2002-06-27 Werner Koch - - * minip12.c (crypt_block): Renamed from decrypt_block, add arg to - allow encryption. - - * Makefile.am (pkglib_PROGRAMS): Put protect-tool there. - - * findkey.c (agent_write_private_key,agent_key_from_file) - (agent_key_available): Use GNUPG_PRIVATE_KEYS_DIR constant. - * gpg-agent.c (main): Use GNUPG_DEFAULT_HOMEDIR constant. - - * protect-tool.c (store_private_key): New. - (import_p12_file): Store the new file if requested. - (main): New options --force and --store. - - * gpg-agent.c (main): Set a global flag when running detached. - * query.c (start_pinentry): Pass the list of FD to keep in the - child when not running detached. - * call-scd.c (start_scd): Ditto. - -2002-06-26 Werner Koch - - * command.c (cmd_istrusted, cmd_listtrusted, cmd_marktrusted) - (cmd_pksign, cmd_pkdecrypt, cmd_genkey, cmd_get_passphrase) - (cmd_learn): Print an error message for a failed operation. - - * simple-pwquery.c, simple-pwquery.h: New. - * protect-tool. (get_passphrase): New, used to get a passphrase - from the agent if none was given on the command line. - -2002-06-25 Werner Koch - - * protect-tool.c (rsa_key_check): New. - (import_p12_file): New. - (main): New command --p12-import. - * minip12.c, minip12.h: New. - -2002-06-24 Werner Koch - - * protect-tool.c (read_file): New. - (read_key): Factored most code out to read_file. - -2002-06-17 Werner Koch - - * agent.h: Add a callback function to the pin_entry_info structure. - * query.c (agent_askpin): Use the callback to check for a correct - PIN. Removed the start_err_text argument because it is not - anymore needed; changed callers. - * findkey.c (unprotect): Replace our own check loop by a callback. - (try_unprotect_cb): New. - * genkey.c (reenter_compare_cb): New. - (agent_genkey): Use this callback here. Fixed setting of the pi2 - variable and a segv in case of an empty PIN. - - * divert-scd.c (getpin_cb): Removed some unused stuff and - explained what we still have to change. - -2002-06-12 Werner Koch - - * gpg-agent.c (main): New option --disable-pth. - -2002-06-11 Werner Koch - - * protect-tool.c: Add command --show-keygrip - (show_keygrip): New. - -2002-05-23 Werner Koch - - * call-scd.c: Seirialized all scdaeom access when using Pth. - - * cache.c: Made the cache Pth-thread-safe. - (agent_unlock_cache_entry): New. - * findkey.c (unprotect): Unlock the returned cache value. - * command.c (cmd_get_passphrase): Ditto. - - * gpg-agent.c (main): Register pth_read/write with Assuan. - -2002-05-22 Werner Koch - - * query.c: Serialized all pinentry access when using Pth. - - * gpg-agent.c (handle_signal,start_connection_thread) - (handle_connections): New - (main): Use the new Pth stuff to allow concurrent connections. - * command.c (start_command_handler): Add new arg FD so that the - fucntion can also be used for an already connected socket. - * Makefile.am: Link with Pth. - -2002-05-14 Werner Koch - - * cache.c (housekeeping, agent_put_cache): Use our time() wrapper. - -2002-04-26 Werner Koch - - * cache.c (agent_put_cache): Reinitialize the creation time and - the ttl when reusing a slot. - - * call-scd.c (start_scd): Print debug messages only with debug - flags set. - * query.c (start_pinentry): Ditto. - -2002-04-25 Marcus Brinkmann - - * agent.h (agent_get_confirmation): Replace paramter prompt with - two parameters ok and cancel. - * query.c (agent_get_confirmation): Likewise. Implement this. - * trustlist.c (agent_marktrusted): Fix invocation of - agent_get_confirmation. - * divert-scd.c (ask_for_card): Likewise. - -2002-04-24 Marcus Brinkmann - - * agent.h (struct opt): Add members display, ttyname, ttytype, - lc_ctype, and lc_messages. - * gpg-agent.c (enum cmd_and_opt_values): Add oDisplay, oTTYname, - oTTYtype, oLCctype, and LCmessages. - (main): Handle these options. - * command.c (option_handler): New function. - (register_commands): Register option handler. - * query.c (start_pinentry): Pass the various display and tty - options to the pinentry. - -2002-04-05 Werner Koch - - * protect-tool.c (show_file): New. Used as default action. - -2002-03-28 Werner Koch - - * divert-scd.c (encode_md_for_card): Don't do the pkcs-1 padding, - the scdaemon should take care of it. - (ask_for_card): Hack to not display the trailing zero. - -2002-03-11 Werner Koch - - * learncard.c (kpinfo_cb): Remove the content restrictions from - the keyID. - -2002-03-06 Werner Koch - - * learncard.c: New. - * divert-scd.c (ask_for_card): The serial number is binary so - convert it to hex here. - * findkey.c (agent_write_private_key): New. - * genkey.c (store_key): And use it here. - - * pkdecrypt.c (agent_pkdecrypt): Changed the way the diversion is done. - * divert-scd.c (divert_pkdecrypt): Changed interface and - implemented it. - -2002-03-05 Werner Koch - - * call-scd.c (inq_needpin): New. - (agent_card_pksign): Add getpin_cb args. - (agent_card_pkdecrypt): New. - -2002-03-04 Werner Koch - - * pksign.c (agent_pksign): Changed how the diversion is done. - * divert-scd.c (divert_pksign): Changed interface and implemented it. - (encode_md_for_card): New. - * call-scd.c (agent_card_pksign): New. - -2002-02-28 Werner Koch - - * pksign.c (agent_pksign): Detect whether a Smartcard is to be - used and divert the operation in this case. - * pkdecrypt.c (agent_pkdecrypt): Likewise - * findkey.c (agent_key_from_file): Add optional arg shadow_info - and have it return information about a shadowed key. - * protect.c (agent_get_shadow_info): New. - - * protect.c (snext,sskip,smatch): Moved to - * sexp-parse.h: new file. - * divert-scd.c: New. - -2002-02-27 Werner Koch - - * protect.c (agent_shadow_key): New. - - * command.c (cmd_learn): New command LEARN. - * gpg-agent.c: New option --scdaemon-program. - * call-scd.c (start_scd): New. Based on query.c - * query.c: Add 2 more arguments to all uses of assuan_transact. - -2002-02-18 Werner Koch - - * findkey.c (unprotect): Show an error message for a bad passphrase. - - * command.c (cmd_marktrusted): Implemented. - * trustlist.c (agent_marktrusted): New. - (open_list): Add APPEND arg. - - * query.c (agent_get_confirmation): New. - -2002-02-06 Werner Koch - - * cache.c (housekeeping): Fixed linking in the remove case. - -2002-02-01 Werner Koch - - * gpg-agent.c: New option --default-cache-ttl. - * cache.c (agent_put_cache): Use it. - - * cache.c: Add a few debug outputs. - - * protect.c (agent_private_key_type): New. - * agent.h: Add PRIVATE_KEY_ enums. - * findkey.c (agent_key_from_file): Use it to decide whether we - have to unprotect a key. - (unprotect): Cache the passphrase. - - * findkey.c (agent_key_from_file,agent_key_available): The key - files do now require a ".key" suffix to make a script's life - easier. - * genkey.c (store_key): Ditto. - -2002-01-31 Werner Koch - - * genkey.c (store_key): Protect the key. - (agent_genkey): Ask for the passphrase. - * findkey.c (unprotect): Actually unprotect the key. - * query.c (agent_askpin): Add an optional start_err_text. - -2002-01-30 Werner Koch - - * protect.c: New. - (hash_passphrase): Based on the GnuPG 1.0.6 version. - * protect-tool.c: New - -2002-01-29 Werner Koch - - * findkey.c (agent_key_available): New. - * command.c (cmd_havekey): New. - (register_commands): And register new command. - -2002-01-20 Werner Koch - - * command.c (cmd_get_passphrase): Remove the plus signs. - - * query.c (start_pinentry): Send no-grab option to pinentry - * gpg-agent.c (main): Move variable grab as no_grab to agent.h. - -2002-01-19 Werner Koch - - * gpg-agent.c (main): Disable core dumps. - - * cache.c: New. - * command.c (cmd_get_passphrase): Use the cache. - (cmd_clear_passphrase): Ditto. - - * gpg-agent.c: Removed unused cruft and implement the socket - based server. - (my_strusage): Take bug report address from configure.ac. - * command.c (start_command_handler): Add an argument to start as - regular server. - (start_command_handler): Enable Assuan logging. - -2002-01-15 Werner Koch - - * trustlist.c: New. - * command.c (cmd_istrusted, cmd_listtrusted, cmd_marktrusted): New. - -2002-01-07 Werner Koch - - * genkey.c: Store the secret part and return the public part. - -2002-01-03 Werner Koch - - * command.c (cmd_get_passphrase): New. - (cmd_clear_passphrase): New. - * query.c (agent_get_passphrase): New. - -2002-01-02 Werner Koch - - * genkey.c: New. - * command.c (cmd_genkey): New. - - * command.c (rc_to_assuan_status): Removed and changed all callers - to use map_to_assuan_status. - -2001-12-19 Werner Koch - - * keyformat.txt: New. - -2001-12-19 Marcus Brinkmann - - * query.c (start_pinentry): Add new argument to assuan_pipe_connect. - -2001-12-18 Werner Koch - - * Makefile.am: Use LIBGCRYPT macros - -2001-12-14 Werner Koch - - * gpg-agent.c (main): New option --batch. New option --debug-wait - n, so that it is possible to attach gdb when used in server mode. - * query.c (agent_askpin): Don't ask in batch mode. - - * command.c: Removed the conversion macros as they are now in - ../common/util.h. - -2001-12-14 Marcus Brinkmann - - * query.c (LINELENGTH): Removed. - (agent_askpin): Use ASSUAN_LINELENGTH, not LINELENGTH. - -2001-11-19 Werner Koch - - * gpg-agent.c: Removed all GUI code, removed code for old - protocol. New code to use the Assuan protocol as a server and - also to communicate with a new ask-passphrase utility. - -2000-11-22 Werner Koch - - * gpg-agent.c (main): csh support by Dan Winship, new options --sh - and --csh and set default by consulting $SHELL. - -Mon Aug 21 17:59:17 CEST 2000 Werner Koch - - * gpg-agent.c (passphrase_dialog): Cleanup the window and added the - user supplied text to the window. - (main): Fixed segv in gtk_init when used without a command to start. - - * gpg-agent.c: --flush option. - (req_flush): New. - (req_clear_passphrase): Implemented. - -Fri Aug 18 14:27:14 CEST 2000 Werner Koch - - * gpg-agent.c: New. - * Makefile.am: New. - - - Copyright 2001, 2002 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/agent/Makefile.am b/agent/Makefile.am deleted file mode 100644 index 89000cf35..000000000 --- a/agent/Makefile.am +++ /dev/null @@ -1,62 +0,0 @@ -# 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 - -## Process this file with automake to produce Makefile.in - -localedir = $(datadir)/locale -INCLUDES = -I../intl -DLOCALEDIR=\"$(localedir)\" - -bin_PROGRAMS = gpg-agent -pkglib_PROGRAMS = gpg-protect-tool - -AM_CPPFLAGS = -I$(top_srcdir)/common $(LIBGCRYPT_CFLAGS) $(PTH_CFLAGS) -LDFLAGS = @LDFLAGS@ - -gpg_agent_SOURCES = \ - gpg-agent.c agent.h \ - command.c \ - query.c \ - cache.c \ - trans.c \ - findkey.c \ - pksign.c \ - pkdecrypt.c \ - genkey.c \ - protect.c \ - trustlist.c \ - divert-scd.c \ - call-scd.c \ - learncard.c \ - sexp-parse.h - - -gpg_agent_LDADD = ../jnlib/libjnlib.a ../assuan/libassuan.a \ - ../common/libcommon.a $(LIBGCRYPT_LIBS) $(PTH_LIBS) - -gpg_protect_tool_SOURCES = \ - protect-tool.c \ - protect.c \ - minip12.c minip12.h \ - simple-pwquery.c simple-pwquery.h - -gpg_protect_tool_LDADD = ../jnlib/libjnlib.a \ - ../common/libcommon.a $(LIBGCRYPT_LIBS) - - - - diff --git a/agent/agent.h b/agent/agent.h deleted file mode 100644 index 51ab19800..000000000 --- a/agent/agent.h +++ /dev/null @@ -1,195 +0,0 @@ -/* agent.h - Global definitions for the agent - * 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 AGENT_H -#define AGENT_H - -#include -#include "../common/util.h" -#include "../common/errors.h" - -#define MAX_DIGEST_LEN 24 - -/* A large struct name "opt" to keep global flags */ -struct { - unsigned int debug; /* debug flags (DBG_foo_VALUE) */ - int verbose; /* verbosity level */ - int quiet; /* be as quiet as possible */ - int dry_run; /* don't change any persistent data */ - int batch; /* batch mode */ - const char *homedir; /* configuration directory name */ - const char *pinentry_program; - char *display; - char *ttyname; - char *ttytype; - char *lc_ctype; - char *lc_messages; - const char *scdaemon_program; - int no_grab; /* don't let the pinentry grab the keyboard */ - unsigned long def_cache_ttl; - - int running_detached; /* we are running detached from the tty. */ - - int ignore_cache_for_signing; - -} opt; - - -#define DBG_COMMAND_VALUE 1 /* debug commands i/o */ -#define DBG_MPI_VALUE 2 /* debug mpi details */ -#define DBG_CRYPTO_VALUE 4 /* debug low level crypto */ -#define DBG_MEMORY_VALUE 32 /* debug memory allocation stuff */ -#define DBG_CACHE_VALUE 64 /* debug the caching */ -#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */ -#define DBG_HASHING_VALUE 512 /* debug hashing operations */ -#define DBG_ASSUAN_VALUE 1024 - -#define DBG_COMMAND (opt.debug & DBG_COMMAND_VALUE) -#define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE) -#define DBG_MEMORY (opt.debug & DBG_MEMORY_VALUE) -#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE) -#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE) -#define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE) - -struct server_local_s; - -struct server_control_s { - struct server_local_s *server_local; - struct { - int algo; - unsigned char value[MAX_DIGEST_LEN]; - int valuelen; - } digest; - char keygrip[20]; - int have_keygrip; - -}; -typedef struct server_control_s *CTRL; - - -struct pin_entry_info_s { - int min_digits; /* min. number of digits required or 0 for freeform entry */ - int max_digits; /* max. number of allowed digits allowed*/ - int max_tries; - int failed_tries; - int (*check_cb)(struct pin_entry_info_s *); /* CB used to check the PIN */ - void *check_cb_arg; /* optional argument which might be of use in the CB */ - const char *cb_errtext; /* used by the cb to displaye a specific error */ - size_t max_length; /* allocated length of the buffer */ - char pin[1]; -}; - - -enum { - PRIVATE_KEY_UNKNOWN = 0, - PRIVATE_KEY_CLEAR = 1, - PRIVATE_KEY_PROTECTED = 2, - PRIVATE_KEY_SHADOWED = 3 -}; - -/*-- gpg-agent.c --*/ -void agent_exit (int rc); /* also implemented in other tools */ - -/*-- command.c --*/ -void start_command_handler (int, int); - -/*-- findkey.c --*/ -int agent_write_private_key (const unsigned char *grip, - const void *buffer, size_t length, int force); -GCRY_SEXP agent_key_from_file (const unsigned char *grip, - unsigned char **shadow_info, int ignore_cache); -int agent_key_available (const unsigned char *grip); - -/*-- query.c --*/ -int agent_askpin (const char *desc_text, struct pin_entry_info_s *pininfo); -int agent_get_passphrase (char **retpass, - const char *desc, const char *prompt, - const char *errtext); -int agent_get_confirmation (const char *desc, const char *ok, - const char *cancel); - -/*-- cache.c --*/ -int agent_put_cache (const char *key, const char *data, int ttl); -const char *agent_get_cache (const char *key, void **cache_id); -void agent_unlock_cache_entry (void **cache_id); - - -/*-- pksign.c --*/ -int agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache); - -/*-- pkdecrypt.c --*/ -int agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen, - FILE *outfp); - -/*-- genkey.c --*/ -int agent_genkey (CTRL ctrl, - const char *keyparam, size_t keyparmlen, FILE *outfp); - -/*-- protect.c --*/ -int agent_protect (const unsigned char *plainkey, const char *passphrase, - unsigned char **result, size_t *resultlen); -int agent_unprotect (const unsigned char *protectedkey, const char *passphrase, - unsigned char **result, size_t *resultlen); -int agent_private_key_type (const unsigned char *privatekey); -int agent_shadow_key (const unsigned char *pubkey, - const unsigned char *shadow_info, - unsigned char **result); -int agent_get_shadow_info (const unsigned char *shadowkey, - unsigned char const **shadow_info); - - -/*-- trustlist.c --*/ -int agent_istrusted (const char *fpr); -int agent_listtrusted (void *assuan_context); -int agent_marktrusted (const char *name, const char *fpr, int flag); - - -/*-- divert-scd.c --*/ -int divert_pksign (const unsigned char *digest, size_t digestlen, int algo, - const unsigned char *shadow_info, unsigned char **r_sig); -int divert_pkdecrypt (const unsigned char *cipher, - const unsigned char *shadow_info, - char **r_buf, size_t *r_len); - -/*-- call-scd.c --*/ -int agent_card_learn (void (*kpinfo_cb)(void*, const char *), - void *kpinfo_cb_arg, - void (*certinfo_cb)(void*, const char *), - void *certinfo_cb_arg); -int agent_card_serialno (char **r_serialno); -int agent_card_pksign (const char *keyid, - int (*getpin_cb)(void *, const char *, char*, size_t), - void *getpin_cb_arg, - const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen); -int agent_card_pkdecrypt (const char *keyid, - int (*getpin_cb)(void *, const char *, char*,size_t), - void *getpin_cb_arg, - const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen); -int agent_card_readcert (const char *id, char **r_buf, size_t *r_buflen); -int agent_card_readkey (const char *id, unsigned char **r_buf); - - -/*-- learncard.c --*/ -int agent_handle_learn (void *assuan_context); - - -#endif /*AGENT_H*/ diff --git a/agent/cache.c b/agent/cache.c deleted file mode 100644 index 4b18ad30f..000000000 --- a/agent/cache.c +++ /dev/null @@ -1,285 +0,0 @@ -/* cache.c - keep a cache of passphrases - * Copyright (C) 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 - -#include -#include -#include -#include -#include - -#include "agent.h" - -struct secret_data_s { - int totallen; /* this includes the padding */ - int datalen; /* actual data length */ - char data[1]; -}; - -typedef struct cache_item_s *ITEM; -struct cache_item_s { - ITEM next; - time_t created; - time_t accessed; - int ttl; /* max. lifetime given in seonds */ - int lockcount; - struct secret_data_s *pw; - char key[1]; -}; - - -static ITEM thecache; - - -static void -release_data (struct secret_data_s *data) -{ - xfree (data); -} - -static struct secret_data_s * -new_data (const void *data, size_t length) -{ - struct secret_data_s *d; - int total; - - /* we pad the data to 32 bytes so that it get more complicated - finding something out by watching allocation patterns. This is - usally not possible but we better assume nothing about our - secure storage provider*/ - total = length + 32 - (length % 32); - - d = gcry_malloc_secure (sizeof d + total - 1); - if (d) - { - d->totallen = total; - d->datalen = length; - memcpy (d->data, data, length); - } - return d; -} - - -/* check whether there are items to expire */ -static void -housekeeping (void) -{ - ITEM r, rprev; - time_t current = gnupg_get_time (); - - /* first expire the actual data */ - for (r=thecache; r; r = r->next) - { - if (!r->lockcount && r->pw && r->accessed + r->ttl < current) - { - if (DBG_CACHE) - log_debug (" expired `%s' (%ds after last access)\n", - r->key, r->ttl); - release_data (r->pw); - r->pw = NULL; - r->accessed = current; - } - } - - /* second, make sure that we also remove them based on the created stamp so - that the user has to enter it from time to time. We do this every hour */ - for (r=thecache; r; r = r->next) - { - if (!r->lockcount && r->pw && r->created + 60*60 < current) - { - if (DBG_CACHE) - log_debug (" expired `%s' (1h after creation)\n", r->key); - release_data (r->pw); - r->pw = NULL; - r->accessed = current; - } - } - - /* third, make sure that we don't have too many items in the list. - Expire old and unused entries after 30 minutes */ - for (rprev=NULL, r=thecache; r; ) - { - if (!r->pw && r->accessed + 60*30 < current) - { - if (r->lockcount) - { - log_error ("can't remove unused cache entry `%s' due to" - " lockcount=%d\n", - r->key, r->lockcount); - r->accessed += 60*10; /* next error message in 10 minutes */ - rprev = r; - r = r->next; - } - else - { - ITEM r2 = r->next; - if (DBG_CACHE) - log_debug (" removed `%s' (slot not used for 30m)\n", r->key); - xfree (r); - if (!rprev) - thecache = r2; - else - rprev->next = r2; - r = r2; - } - } - else - { - rprev = r; - r = r->next; - } - } -} - - - -/* Store DATA of length DATALEN in the cache under KEY and mark it - with a maximum lifetime of TTL seconds. If there is already data - under this key, it will be replaced. Using a DATA of NULL deletes - the entry */ -int -agent_put_cache (const char *key, const char *data, int ttl) -{ - ITEM r; - - if (DBG_CACHE) - log_debug ("agent_put_cache `%s'\n", key); - housekeeping (); - - if (ttl < 1) - ttl = opt.def_cache_ttl; - if (!ttl) - return 0; - - for (r=thecache; r; r = r->next) - { - if (!r->lockcount && !strcmp (r->key, key)) - break; - } - if (r) - { /* replace */ - if (r->pw) - { - release_data (r->pw); - r->pw = NULL; - } - if (data) - { - r->created = r->accessed = gnupg_get_time (); - r->ttl = ttl; - r->pw = new_data (data, strlen (data)+1); - if (!r->pw) - log_error ("out of core while allocating new cache item\n"); - } - } - else if (data) - { /* simply insert */ - r = xtrycalloc (1, sizeof *r + strlen (key)); - if (!r) - log_error ("out of core while allocating new cache control\n"); - else - { - strcpy (r->key, key); - r->created = r->accessed = gnupg_get_time (); - r->ttl = ttl; - r->pw = new_data (data, strlen (data)+1); - if (!r->pw) - { - log_error ("out of core while allocating new cache item\n"); - xfree (r); - } - else - { - r->next = thecache; - thecache = r; - } - } - } - return 0; -} - - -/* Try to find an item in the cache */ -const char * -agent_get_cache (const char *key, void **cache_id) -{ - ITEM r; - - if (DBG_CACHE) - log_debug ("agent_get_cache `%s'...\n", key); - housekeeping (); - - /* first try to find one with no locks - this is an updated cache - entry: We might have entries with a lockcount and without a - lockcount. */ - for (r=thecache; r; r = r->next) - { - if (!r->lockcount && r->pw && !strcmp (r->key, key)) - { - /* put_cache does only put strings into the cache, so we - don't need the lengths */ - r->accessed = gnupg_get_time (); - if (DBG_CACHE) - log_debug ("... hit\n"); - r->lockcount++; - *cache_id = r; - return r->pw->data; - } - } - /* again, but this time get even one with a lockcount set */ - for (r=thecache; r; r = r->next) - { - if (r->pw && !strcmp (r->key, key)) - { - r->accessed = gnupg_get_time (); - if (DBG_CACHE) - log_debug ("... hit (locked)\n"); - r->lockcount++; - *cache_id = r; - return r->pw->data; - } - } - if (DBG_CACHE) - log_debug ("... miss\n"); - - *cache_id = NULL; - return NULL; -} - - -void -agent_unlock_cache_entry (void **cache_id) -{ - ITEM r; - - for (r=thecache; r; r = r->next) - { - if (r == *cache_id) - { - if (!r->lockcount) - log_error ("trying to unlock non-locked cache entry `%s'\n", - r->key); - else - r->lockcount--; - return; - } - } -} diff --git a/agent/call-scd.c b/agent/call-scd.c deleted file mode 100644 index a9123daca..000000000 --- a/agent/call-scd.c +++ /dev/null @@ -1,592 +0,0 @@ -/* call-scd.c - fork of the scdaemon to do SC operations - * 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 - */ - -/* Fixme: For now we have serialized all access to the scdaemon which - make sense becuase the scdaemon can't handle concurrent connections - right now. We should however keep a list of connections and lock - just that connection - it migth make sense to implemtn parts of - this in Assuan.*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef USE_GNU_PTH -# include -#endif - -#include "agent.h" -#include "../assuan/assuan.h" - -#ifdef _POSIX_OPEN_MAX -#define MAX_OPEN_FDS _POSIX_OPEN_MAX -#else -#define MAX_OPEN_FDS 20 -#endif - -static ASSUAN_CONTEXT scd_ctx = NULL; -#ifdef USE_GNU_PTH -static pth_mutex_t scd_lock = PTH_MUTEX_INIT; -#endif - -/* callback parameter for learn card */ -struct learn_parm_s { - void (*kpinfo_cb)(void*, const char *); - void *kpinfo_cb_arg; - void (*certinfo_cb)(void*, const char *); - void *certinfo_cb_arg; -}; - -struct inq_needpin_s { - ASSUAN_CONTEXT ctx; - int (*getpin_cb)(void *, const char *, char*, size_t); - void *getpin_cb_arg; -}; - -struct membuf { - size_t len; - size_t size; - char *buf; - int out_of_core; -}; - - - -/* A simple implementation of a dynamic buffer. Use init_membuf() to - create a buffer, put_membuf to append bytes and get_membuf to - release and return the buffer. Allocation errors are detected but - only returned at the final get_membuf(), this helps not to clutter - the code with out of core checks. */ - -static void -init_membuf (struct membuf *mb, int initiallen) -{ - mb->len = 0; - mb->size = initiallen; - mb->out_of_core = 0; - mb->buf = xtrymalloc (initiallen); - if (!mb->buf) - mb->out_of_core = 1; -} - -static void -put_membuf (struct membuf *mb, const void *buf, size_t len) -{ - if (mb->out_of_core) - return; - - if (mb->len + len >= mb->size) - { - char *p; - - mb->size += len + 1024; - p = xtryrealloc (mb->buf, mb->size); - if (!p) - { - mb->out_of_core = 1; - return; - } - mb->buf = p; - } - memcpy (mb->buf + mb->len, buf, len); - mb->len += len; -} - -static void * -get_membuf (struct membuf *mb, size_t *len) -{ - char *p; - - if (mb->out_of_core) - { - xfree (mb->buf); - mb->buf = NULL; - return NULL; - } - - p = mb->buf; - *len = mb->len; - mb->buf = NULL; - mb->out_of_core = 1; /* don't allow a reuse */ - return p; -} - - - - -static int -unlock_scd (int rc) -{ -#ifdef USE_GNU_PTH - if (!pth_mutex_release (&scd_lock)) - { - log_error ("failed to release the SCD lock\n"); - if (!rc) - rc = GNUPG_Internal_Error; - } -#endif - return rc; -} - -/* Fork off the SCdaemon if this has not already been done */ -static int -start_scd (void) -{ - int rc; - const char *pgmname; - ASSUAN_CONTEXT ctx; - const char *argv[3]; - int no_close_list[3]; - int i; - -#ifdef USE_GNU_PTH - if (!pth_mutex_acquire (&scd_lock, 0, NULL)) - { - log_error ("failed to acquire the SCD lock\n"); - return GNUPG_Internal_Error; - } -#endif - - if (scd_ctx) - return 0; /* No need to serialize things because the agent is - expected to tun as a single-thread (or may be in - future using libpth) */ - - if (opt.verbose) - log_info ("no running SCdaemon - starting it\n"); - - if (fflush (NULL)) - { - log_error ("error flushing pending output: %s\n", strerror (errno)); - return unlock_scd (seterr (Write_Error)); - } - - if (!opt.scdaemon_program || !*opt.scdaemon_program) - opt.scdaemon_program = GNUPG_DEFAULT_SCDAEMON; - if ( !(pgmname = strrchr (opt.scdaemon_program, '/'))) - pgmname = opt.scdaemon_program; - else - pgmname++; - - argv[0] = pgmname; - argv[1] = "--server"; - argv[2] = NULL; - - i=0; - if (!opt.running_detached) - { - 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 pinentry and perform initial handshaking */ - rc = assuan_pipe_connect (&ctx, opt.scdaemon_program, (char**)argv, - no_close_list); - if (rc) - { - log_error ("can't connect to the SCdaemon: %s\n", - assuan_strerror (rc)); - return unlock_scd (seterr (No_Scdaemon)); - } - scd_ctx = ctx; - - if (DBG_ASSUAN) - log_debug ("connection to SCdaemon established\n"); - return 0; -} - - - -static AssuanError -learn_status_cb (void *opaque, const char *line) -{ - struct learn_parm_s *parm = opaque; - const char *keyword = line; - int keywordlen; - - for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) - ; - while (spacep (line)) - line++; - if (keywordlen == 8 && !memcmp (keyword, "CERTINFO", keywordlen)) - { - parm->certinfo_cb (parm->certinfo_cb_arg, line); - } - else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen)) - { - parm->kpinfo_cb (parm->kpinfo_cb_arg, line); - } - else if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen)) - { - log_debug ("learn_status_cb: serialno `%s'\n", line); - } - else - log_debug ("learn_status_cb: ignoring `%.*s'\n", keywordlen, keyword); - - return 0; -} - -/* Perform the learn command and return a list of all private keys - stored on the card. */ -int -agent_card_learn (void (*kpinfo_cb)(void*, const char *), - void *kpinfo_cb_arg, - void (*certinfo_cb)(void*, const char *), - void *certinfo_cb_arg) -{ - int rc; - struct learn_parm_s parm; - - rc = start_scd (); - if (rc) - return rc; - - memset (&parm, 0, sizeof parm); - parm.kpinfo_cb = kpinfo_cb; - parm.kpinfo_cb_arg = kpinfo_cb_arg; - parm.certinfo_cb = certinfo_cb; - parm.certinfo_cb_arg = certinfo_cb_arg; - rc = assuan_transact (scd_ctx, "LEARN --force", - NULL, NULL, NULL, NULL, - learn_status_cb, &parm); - if (rc) - return unlock_scd (map_assuan_err (rc)); - - return unlock_scd (0); -} - - - -static AssuanError -get_serialno_cb (void *opaque, const char *line) -{ - char **serialno = opaque; - const char *keyword = line; - const char *s; - int keywordlen, n; - - for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) - ; - while (spacep (line)) - line++; - - if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen)) - { - if (*serialno) - return ASSUAN_Unexpected_Status; - for (n=0,s=line; hexdigitp (s); s++, n++) - ; - if (!n || (n&1)|| !(spacep (s) || !*s) ) - return ASSUAN_Invalid_Status; - *serialno = xtrymalloc (n+1); - if (!*serialno) - return ASSUAN_Out_Of_Core; - memcpy (*serialno, line, n); - (*serialno)[n] = 0; - } - - return 0; -} - -/* Return the serial number of the card or an appropriate error. The - serial number is returned as a hexstring. */ -int -agent_card_serialno (char **r_serialno) -{ - int rc; - char *serialno = NULL; - - rc = start_scd (); - if (rc) - return rc; - - /* Hmm, do we really need this reset - scddaemon should do this or - we can do this if we for some reason figure out that the - operation might have failed due to a missing RESET. Hmmm, I feel - this is really SCdaemon's duty */ - rc = assuan_transact (scd_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_scd (map_assuan_err (rc)); - - rc = assuan_transact (scd_ctx, "SERIALNO", - NULL, NULL, NULL, NULL, - get_serialno_cb, &serialno); - if (rc) - { - xfree (serialno); - return unlock_scd (map_assuan_err (rc)); - } - *r_serialno = serialno; - return unlock_scd (0); -} - - -static AssuanError -membuf_data_cb (void *opaque, const void *buffer, size_t length) -{ - struct membuf *data = opaque; - - if (buffer) - put_membuf (data, buffer, length); - return 0; -} - -/* Handle the NEEDPIN inquiry. */ -static AssuanError -inq_needpin (void *opaque, const char *line) -{ - struct inq_needpin_s *parm = opaque; - char *pin; - size_t pinlen; - int rc; - - if (!(!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7]))) - { - log_error ("unsupported inquiry `%s'\n", line); - return ASSUAN_Inquire_Unknown; - } - line += 7; - - pinlen = 90; - pin = gcry_malloc_secure (pinlen); - if (!pin) - return ASSUAN_Out_Of_Core; - - rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen); - if (rc) - rc = ASSUAN_Canceled; - if (!rc) - rc = assuan_send_data (parm->ctx, pin, pinlen); - xfree (pin); - - return rc; -} - - - -/* Create a signature using the current card */ -int -agent_card_pksign (const char *keyid, - int (*getpin_cb)(void *, const char *, char*, size_t), - void *getpin_cb_arg, - const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen) -{ - int rc, i; - char *p, line[ASSUAN_LINELENGTH]; - struct membuf data; - struct inq_needpin_s inqparm; - size_t len; - unsigned char *sigbuf; - size_t sigbuflen; - - *r_buf = NULL; - rc = start_scd (); - if (rc) - return rc; - - if (indatalen*2 + 50 > DIM(line)) - return unlock_scd (seterr (General_Error)); - - sprintf (line, "SETDATA "); - p = line + strlen (line); - for (i=0; i < indatalen ; i++, p += 2 ) - sprintf (p, "%02X", indata[i]); - rc = assuan_transact (scd_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_scd (map_assuan_err (rc)); - - init_membuf (&data, 1024); - inqparm.ctx = scd_ctx; - inqparm.getpin_cb = getpin_cb; - inqparm.getpin_cb_arg = getpin_cb_arg; - snprintf (line, DIM(line)-1, "PKSIGN %s", keyid); - line[DIM(line)-1] = 0; - rc = assuan_transact (scd_ctx, line, - membuf_data_cb, &data, - inq_needpin, &inqparm, - NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return unlock_scd (map_assuan_err (rc)); - } - sigbuf = get_membuf (&data, &sigbuflen); - - /* create an S-expression from it which is formatted like this: - "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" */ - *r_buflen = 21 + 11 + sigbuflen + 4; - *r_buf = xtrymalloc (*r_buflen); - if (!*r_buf) - { - xfree (*r_buf); - return unlock_scd (GNUPG_Out_Of_Core); - } - p = stpcpy (*r_buf, "(7:sig-val(3:rsa(1:s" ); - sprintf (p, "%u:", (unsigned int)sigbuflen); - p += strlen (p); - memcpy (p, sigbuf, sigbuflen); - p += sigbuflen; - strcpy (p, ")))"); - xfree (sigbuf); - - assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL)); - return unlock_scd (0); -} - -/* Decipher INDATA using the current card. Note that the returned value is */ -int -agent_card_pkdecrypt (const char *keyid, - int (*getpin_cb)(void *, const char *, char*, size_t), - void *getpin_cb_arg, - const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen) -{ - int rc, i; - char *p, line[ASSUAN_LINELENGTH]; - struct membuf data; - struct inq_needpin_s inqparm; - size_t len; - - *r_buf = NULL; - rc = start_scd (); - if (rc) - return rc; - - /* FIXME: use secure memory where appropriate */ - if (indatalen*2 + 50 > DIM(line)) - return unlock_scd (seterr (General_Error)); - - sprintf (line, "SETDATA "); - p = line + strlen (line); - for (i=0; i < indatalen ; i++, p += 2 ) - sprintf (p, "%02X", indata[i]); - rc = assuan_transact (scd_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_scd (map_assuan_err (rc)); - - init_membuf (&data, 1024); - inqparm.ctx = scd_ctx; - inqparm.getpin_cb = getpin_cb; - inqparm.getpin_cb_arg = getpin_cb_arg; - snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid); - line[DIM(line)-1] = 0; - rc = assuan_transact (scd_ctx, line, - membuf_data_cb, &data, - inq_needpin, &inqparm, - NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return unlock_scd (map_assuan_err (rc)); - } - *r_buf = get_membuf (&data, r_buflen); - if (!*r_buf) - return unlock_scd (GNUPG_Out_Of_Core); - - return unlock_scd (0); -} - - - -/* Read a certificate with ID into R_BUF and R_BUFLEN. */ -int -agent_card_readcert (const char *id, char **r_buf, size_t *r_buflen) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - struct membuf data; - size_t len; - - *r_buf = NULL; - rc = start_scd (); - if (rc) - return rc; - - init_membuf (&data, 1024); - snprintf (line, DIM(line)-1, "READCERT %s", id); - line[DIM(line)-1] = 0; - rc = assuan_transact (scd_ctx, line, - membuf_data_cb, &data, - NULL, NULL, - NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return unlock_scd (map_assuan_err (rc)); - } - *r_buf = get_membuf (&data, r_buflen); - if (!*r_buf) - return unlock_scd (GNUPG_Out_Of_Core); - - return unlock_scd (0); -} - - - -/* Read a key with ID and return it in an allocate buffer pointed to - by r_BUF as a valid S-expression. */ -int -agent_card_readkey (const char *id, unsigned char **r_buf) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - struct membuf data; - size_t len, buflen; - - *r_buf = NULL; - rc = start_scd (); - if (rc) - return rc; - - init_membuf (&data, 1024); - snprintf (line, DIM(line)-1, "READKEY %s", id); - line[DIM(line)-1] = 0; - rc = assuan_transact (scd_ctx, line, - membuf_data_cb, &data, - NULL, NULL, - NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return unlock_scd (map_assuan_err (rc)); - } - *r_buf = get_membuf (&data, &buflen); - if (!*r_buf) - return unlock_scd (GNUPG_Out_Of_Core); - - if (!gcry_sexp_canon_len (*r_buf, buflen, NULL, NULL)) - { - xfree (*r_buf); *r_buf = NULL; - return unlock_scd (GNUPG_Invalid_Value); - } - - return unlock_scd (0); -} - - - diff --git a/agent/command.c b/agent/command.c deleted file mode 100644 index 55ee8b84a..000000000 --- a/agent/command.c +++ /dev/null @@ -1,697 +0,0 @@ -/* command.c - gpg-agent command handler - * 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 - */ - -/* FIXME: we should not use the default assuan buffering but setup - some buffering in secure mempory to protect session keys etc. */ - -#include -#include -#include -#include -#include -#include -#include - -#include "agent.h" -#include "../assuan/assuan.h" - -/* maximum allowed size of the inquired ciphertext */ -#define MAXLEN_CIPHERTEXT 4096 -/* maximum allowed size of the key parameters */ -#define MAXLEN_KEYPARAM 1024 - -#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t)) - - -#if MAX_DIGEST_LEN < 20 -#error MAX_DIGEST_LEN shorter than keygrip -#endif - -/* Data used to associate an Assuan context with local server data */ -struct server_local_s { - ASSUAN_CONTEXT assuan_ctx; - int message_fd; - int use_cache_for_signing; -}; - - - - - -static void -reset_notify (ASSUAN_CONTEXT ctx) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - memset (ctrl->keygrip, 0, 20); - ctrl->have_keygrip = 0; - ctrl->digest.valuelen = 0; -} - - -/* Check whether the option NAME appears in LINE */ -static int -has_option (const char *line, const char *name) -{ - const char *s; - int n = strlen (name); - - s = strstr (line, name); - return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); -} - - - - -/* ISTRUSTED - - Return OK when we have an entry with this fingerprint in our - trustlist */ -static int -cmd_istrusted (ASSUAN_CONTEXT ctx, char *line) -{ - int rc, n, i; - char *p; - char fpr[41]; - - /* parse the fingerprint value */ - for (p=line,n=0; hexdigitp (p); p++, n++) - ; - if (*p || !(n == 40 || n == 32)) - return set_error (Parameter_Error, "invalid fingerprint"); - i = 0; - if (n==32) - { - strcpy (fpr, "00000000"); - i += 8; - } - for (p=line; i < 40; p++, i++) - fpr[i] = *p >= 'a'? (*p & 0xdf): *p; - fpr[i] = 0; - rc = agent_istrusted (fpr); - if (!rc) - return 0; - else if (rc == -1) - return ASSUAN_Not_Trusted; - else - { - log_error ("command is_trusted failed: %s\n", gnupg_strerror (rc)); - return map_to_assuan_status (rc); - } -} - -/* LISTTRUSTED - - List all entries from the trustlist */ -static int -cmd_listtrusted (ASSUAN_CONTEXT ctx, char *line) -{ - int rc = agent_listtrusted (ctx); - if (rc) - log_error ("command listtrusted failed: %s\n", gnupg_strerror (rc)); - return map_to_assuan_status (rc); -} - - -/* MARKTRUSTED - - Store a new key in into the trustlist*/ -static int -cmd_marktrusted (ASSUAN_CONTEXT ctx, char *line) -{ - int rc, n, i; - char *p; - char fpr[41]; - int flag; - - /* parse the fingerprint value */ - for (p=line,n=0; hexdigitp (p); p++, n++) - ; - if (!spacep (p) || !(n == 40 || n == 32)) - return set_error (Parameter_Error, "invalid fingerprint"); - i = 0; - if (n==32) - { - strcpy (fpr, "00000000"); - i += 8; - } - for (p=line; i < 40; p++, i++) - fpr[i] = *p >= 'a'? (*p & 0xdf): *p; - fpr[i] = 0; - - while (spacep (p)) - p++; - flag = *p++; - if ( (flag != 'S' && flag != 'P') || !spacep (p) ) - return set_error (Parameter_Error, "invalid flag - must be P or S"); - while (spacep (p)) - p++; - - rc = agent_marktrusted (p, fpr, flag); - if (rc) - log_error ("command marktrusted failed: %s\n", gnupg_strerror (rc)); - return map_to_assuan_status (rc); -} - - - - -/* HAVEKEY - - Return success when the secret key is available */ -static int -cmd_havekey (ASSUAN_CONTEXT ctx, char *line) -{ - int n; - char *p; - unsigned char buf[20]; - - /* parse the hash value */ - for (p=line,n=0; hexdigitp (p); p++, n++) - ; - if (*p) - return set_error (Parameter_Error, "invalid hexstring"); - if ((n&1)) - return set_error (Parameter_Error, "odd number of digits"); - n /= 2; - if (n != 20) - return set_error (Parameter_Error, "invalid length of keygrip"); - - for (p=line, n=0; n < 20; p += 2, n++) - buf[n] = xtoi_2 (p); - - if (agent_key_available (buf)) - return ASSUAN_No_Secret_Key; - - return 0; -} - - -/* SIGKEY - SETKEY - - Set the key used for a sign or decrypt operation */ -static int -cmd_sigkey (ASSUAN_CONTEXT ctx, char *line) -{ - int n; - char *p; - CTRL ctrl = assuan_get_pointer (ctx); - unsigned char *buf; - - /* parse the hash value */ - for (p=line,n=0; hexdigitp (p); p++, n++) - ; - if (*p) - return set_error (Parameter_Error, "invalid hexstring"); - if ((n&1)) - return set_error (Parameter_Error, "odd number of digits"); - n /= 2; - if (n != 20) - return set_error (Parameter_Error, "invalid length of keygrip"); - - buf = ctrl->keygrip; - for (p=line, n=0; n < 20; p += 2, n++) - buf[n] = xtoi_2 (p); - ctrl->have_keygrip = 1; - return 0; -} - -/* SETHASH - - The client can use this command to tell the server about the data - (which usually is a hash) to be signed. */ -static int -cmd_sethash (ASSUAN_CONTEXT ctx, char *line) -{ - int n; - char *p; - CTRL ctrl = assuan_get_pointer (ctx); - unsigned char *buf; - char *endp; - int algo; - - /* parse the algo number and check it */ - algo = (int)strtoul (line, &endp, 10); - for (line = endp; *line == ' ' || *line == '\t'; line++) - ; - if (!algo || gcry_md_test_algo (algo)) - return set_error (Unsupported_Algorithm, NULL); - ctrl->digest.algo = algo; - - /* parse the hash value */ - for (p=line,n=0; hexdigitp (p); p++, n++) - ; - if (*p) - return set_error (Parameter_Error, "invalid hexstring"); - if ((n&1)) - return set_error (Parameter_Error, "odd number of digits"); - n /= 2; - if (n != 16 && n != 20 && n != 24 && n != 32) - return set_error (Parameter_Error, "unsupported length of hash"); - if (n > MAX_DIGEST_LEN) - return set_error (Parameter_Error, "hash value to long"); - - buf = ctrl->digest.value; - ctrl->digest.valuelen = n; - for (p=line, n=0; n < ctrl->digest.valuelen; p += 2, n++) - buf[n] = xtoi_2 (p); - for (; n < ctrl->digest.valuelen; n++) - buf[n] = 0; - return 0; -} - - -/* PKSIGN - - Perform the actual sign operation. Neither input nor output are - sensitive to eavesdropping */ -static int -cmd_pksign (ASSUAN_CONTEXT ctx, char *line) -{ - int rc; - int ignore_cache = 0; - CTRL ctrl = assuan_get_pointer (ctx); - - if (opt.ignore_cache_for_signing) - ignore_cache = 1; - else if (!ctrl->server_local->use_cache_for_signing) - ignore_cache = 1; - - rc = agent_pksign (ctrl, assuan_get_data_fp (ctx), ignore_cache); - if (rc) - log_error ("command pksign failed: %s\n", gnupg_strerror (rc)); - return map_to_assuan_status (rc); -} - -/* PKDECRYPT - - Perform the actual decrypt operation. Input is not - sensitive to eavesdropping */ -static int -cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line) -{ - int rc; - CTRL ctrl = assuan_get_pointer (ctx); - char *value; - size_t valuelen; - - /* First inquire the data to decrypt */ - rc = assuan_inquire (ctx, "CIPHERTEXT", - &value, &valuelen, MAXLEN_CIPHERTEXT); - if (rc) - return rc; - - rc = agent_pkdecrypt (ctrl, value, valuelen, assuan_get_data_fp (ctx)); - xfree (value); - if (rc) - log_error ("command pkdecrypt failed: %s\n", gnupg_strerror (rc)); - return map_to_assuan_status (rc); -} - - -/* GENKEY - - Generate a new key, store the secret part and return the public - part. Here is an example transaction: - - C: GENKEY - S: INQUIRE KEYPARM - C: D (genkey (rsa (nbits 1024))) - C: END - S: D (public-key - S: D (rsa (n 326487324683264) (e 10001))) - S OK key created -*/ - -static int -cmd_genkey (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - char *value; - size_t valuelen; - - /* First inquire the parameters */ - rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM); - if (rc) - return rc; - - rc = agent_genkey (ctrl, value, valuelen, assuan_get_data_fp (ctx)); - xfree (value); - if (rc) - log_error ("command genkey failed: %s\n", gnupg_strerror (rc)); - return map_to_assuan_status (rc); -} - - -static void -plus_to_blank (char *s) -{ - for (; *s; s++) - { - if (*s == '+') - *s = ' '; - } -} - -/* GET_PASSPHRASE [ ] - - This function is usually used to ask for a passphrase to be used - for conventional encryption, but may also be used by programs which - need specal handling of passphrases. This command uses a syntax - which helps clients to use the agent with minimum effort. The - agent either returns with an error or with a OK followed by the hex - encoded passphrase. Note that the length of the strings is - implicitly limited by the maximum length of a command. -*/ - -static int -cmd_get_passphrase (ASSUAN_CONTEXT ctx, char *line) -{ - int rc; - const char *pw; - char *response; - char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL; - char *p; - void *cache_marker; - - /* parse the stuff */ - for (p=line; *p == ' '; p++) - ; - cacheid = p; - p = strchr (cacheid, ' '); - if (p) - { - *p++ = 0; - while (*p == ' ') - p++; - errtext = p; - p = strchr (errtext, ' '); - if (p) - { - *p++ = 0; - while (*p == ' ') - p++; - prompt = p; - p = strchr (prompt, ' '); - if (p) - { - *p++ = 0; - while (*p == ' ') - p++; - desc = p; - p = strchr (desc, ' '); - if (p) - *p = 0; /* ignore garbage */ - } - } - } - if (!cacheid || !*cacheid || strlen (cacheid) > 50) - return set_error (Parameter_Error, "invalid length of cacheID"); - if (!desc) - return set_error (Parameter_Error, "no description given"); - - if (!strcmp (cacheid, "X")) - cacheid = NULL; - if (!strcmp (errtext, "X")) - errtext = NULL; - if (!strcmp (prompt, "X")) - prompt = NULL; - if (!strcmp (desc, "X")) - desc = NULL; - - /* Note: we store the hexified versions in the cache. */ - pw = cacheid ? agent_get_cache (cacheid, &cache_marker) : NULL; - if (pw) - { - assuan_begin_confidential (ctx); - rc = assuan_set_okay_line (ctx, pw); - agent_unlock_cache_entry (&cache_marker); - } - else - { - /* Note, that we only need to replace the + characters and - should leave the other escaping in place because the escaped - string is send verbatim to the pinentry which does the - unescaping (but not the + replacing) */ - if (errtext) - plus_to_blank (errtext); - if (prompt) - plus_to_blank (prompt); - if (desc) - plus_to_blank (desc); - - rc = agent_get_passphrase (&response, desc, prompt, errtext); - if (!rc) - { - if (cacheid) - agent_put_cache (cacheid, response, 0); - assuan_begin_confidential (ctx); - rc = assuan_set_okay_line (ctx, response); - xfree (response); - } - } - - if (rc) - log_error ("command get_passphrase failed: %s\n", gnupg_strerror (rc)); - return map_to_assuan_status (rc); -} - - -/* CLEAR_PASSPHRASE - - may be used to invalidate the cache entry for a passphrase. The - function returns with OK even when there is no cached passphrase. -*/ - -static int -cmd_clear_passphrase (ASSUAN_CONTEXT ctx, char *line) -{ - char *cacheid = NULL; - char *p; - - /* parse the stuff */ - for (p=line; *p == ' '; p++) - ; - cacheid = p; - p = strchr (cacheid, ' '); - if (p) - *p = 0; /* ignore garbage */ - if (!cacheid || !*cacheid || strlen (cacheid) > 50) - return set_error (Parameter_Error, "invalid length of cacheID"); - - agent_put_cache (cacheid, NULL, 0); - return 0; -} - - -/* LEARN [--send] - - Learn something about the currently inserted smartcard. With - --send the new certificates are send back. */ -static int -cmd_learn (ASSUAN_CONTEXT ctx, char *line) -{ - int rc; - - rc = agent_handle_learn (has_option (line, "--send")? ctx : NULL); - if (rc) - log_error ("command learn failed: %s\n", gnupg_strerror (rc)); - return map_to_assuan_status (rc); -} - - - -static int -option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - /* FIXME: We should not change opt. here. It is not a problem right - now but as soon as we are allowing concurrent connections we mess - things up */ - if (!strcmp (key, "display")) - { - if (opt.display) - free (opt.display); - opt.display = strdup (value); - if (!opt.display) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "ttyname")) - { - if (opt.ttyname) - free (opt.ttyname); - opt.ttyname = strdup (value); - if (!opt.ttyname) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "ttytype")) - { - if (opt.ttytype) - free (opt.ttytype); - opt.ttytype = strdup (value); - if (!opt.ttytype) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "lc-ctype")) - { - if (opt.lc_ctype) - free (opt.lc_ctype); - opt.lc_ctype = strdup (value); - if (!opt.lc_ctype) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "lc-messages")) - { - if (opt.lc_messages) - free (opt.lc_messages); - opt.lc_messages = strdup (value); - if (!opt.lc_messages) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "use-cache-for-signing")) - ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0; - else - return ASSUAN_Invalid_Option; - - return 0; -} - - -/* Tell the assuan library about our commands */ -static int -register_commands (ASSUAN_CONTEXT ctx) -{ - static struct { - const char *name; - int cmd_id; - int (*handler)(ASSUAN_CONTEXT, char *line); - } table[] = { - { "ISTRUSTED", 0, cmd_istrusted }, - { "HAVEKEY", 0, cmd_havekey }, - { "SIGKEY", 0, cmd_sigkey }, - { "SETKEY", 0, cmd_sigkey }, - { "SETHASH", 0, cmd_sethash }, - { "PKSIGN", 0, cmd_pksign }, - { "PKDECRYPT", 0, cmd_pkdecrypt }, - { "GENKEY", 0, cmd_genkey }, - { "GET_PASSPHRASE",0, cmd_get_passphrase }, - { "CLEAR_PASSPHRASE",0, cmd_clear_passphrase }, - { "LISTTRUSTED", 0, cmd_listtrusted }, - { "MARKTRUSTED", 0, cmd_marktrusted }, - { "LEARN", 0, cmd_learn }, - { "", ASSUAN_CMD_INPUT, NULL }, - { "", ASSUAN_CMD_OUTPUT, NULL }, - { NULL } - }; - int i, j, rc; - - for (i=j=0; table[i].name; i++) - { - rc = assuan_register_command (ctx, - table[i].cmd_id? table[i].cmd_id - : (ASSUAN_CMD_USER + j++), - table[i].name, table[i].handler); - if (rc) - return rc; - } - assuan_register_reset_notify (ctx, reset_notify); - assuan_register_option_handler (ctx, option_handler); - return 0; -} - - -/* Startup the server. If LISTEN_FD and FD is given as -1, this is a simple - piper server, otherwise it is a regular server */ -void -start_command_handler (int listen_fd, int fd) -{ - int rc; - ASSUAN_CONTEXT ctx; - struct server_control_s ctrl; - - memset (&ctrl, 0, sizeof ctrl); - - if (listen_fd == -1 && fd == -1) - { - int filedes[2]; - - filedes[0] = 0; - filedes[1] = 1; - rc = assuan_init_pipe_server (&ctx, filedes); - } - else if (listen_fd != -1) - { - rc = assuan_init_socket_server (&ctx, listen_fd); - } - else - { - rc = assuan_init_connected_socket_server (&ctx, fd); - } - if (rc) - { - log_error ("failed to initialize the server: %s\n", - assuan_strerror(rc)); - agent_exit (2); - } - rc = register_commands (ctx); - if (rc) - { - log_error ("failed to register commands with Assuan: %s\n", - assuan_strerror(rc)); - agent_exit (2); - } - - assuan_set_pointer (ctx, &ctrl); - ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local); - ctrl.server_local->assuan_ctx = ctx; - ctrl.server_local->message_fd = -1; - ctrl.server_local->use_cache_for_signing = 1; - - if (DBG_ASSUAN) - assuan_set_log_stream (ctx, log_get_stream ()); - - for (;;) - { - rc = assuan_accept (ctx); - if (rc == -1) - { - break; - } - else if (rc) - { - log_info ("Assuan accept problem: %s\n", assuan_strerror (rc)); - break; - } - - rc = assuan_process (ctx); - if (rc) - { - log_info ("Assuan processing failed: %s\n", assuan_strerror (rc)); - continue; - } - } - - - assuan_deinit_server (ctx); -} - diff --git a/agent/divert-scd.c b/agent/divert-scd.c deleted file mode 100644 index 40b6bcfa3..000000000 --- a/agent/divert-scd.c +++ /dev/null @@ -1,305 +0,0 @@ -/* divert-scd.c - divert operations to the scdaemon - * Copyright (C) 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include "agent.h" -#include "sexp-parse.h" -#include "i18n.h" - - -static int -ask_for_card (const unsigned char *shadow_info, char **r_kid) -{ - int rc, i; - const unsigned char *s; - size_t n; - char *serialno; - int no_card = 0; - char *desc; - char *want_sn, *want_kid; - int want_sn_displen; - - *r_kid = NULL; - s = shadow_info; - if (*s != '(') - return GNUPG_Invalid_Sexp; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - want_sn = xtrymalloc (n*2+1); - if (!want_sn) - return GNUPG_Out_Of_Core; - for (i=0; i < n; i++) - sprintf (want_sn+2*i, "%02X", s[i]); - s += n; - /* We assume that a 20 byte serial number is a standard one which - seems to have the property to have a zero in the last nibble. We - don't display this '0' because it may confuse the user */ - want_sn_displen = strlen (want_sn); - if (want_sn_displen == 20 && want_sn[19] == '0') - want_sn_displen--; - - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - want_kid = xtrymalloc (n+1); - if (!want_kid) - { - xfree (want_sn); - return GNUPG_Out_Of_Core; - } - memcpy (want_kid, s, n); - want_kid[n] = 0; - - for (;;) - { - rc = agent_card_serialno (&serialno); - if (!rc) - { - log_debug ("detected card with S/N %s\n", serialno); - i = strcmp (serialno, want_sn); - xfree (serialno); - serialno = NULL; - if (!i) - { - xfree (want_sn); - *r_kid = want_kid; - return 0; /* yes, we have the correct card */ - } - } - else if (rc == GNUPG_Card_Not_Present) - { - log_debug ("no card present\n"); - rc = 0; - no_card = 1; - } - else - { - log_error ("error accesing card: %s\n", gnupg_strerror (rc)); - } - - if (!rc) - { - if (asprintf (&desc, - "%s:%%0A%%0A" - " \"%.*s\"", - no_card? "Please insert the card with serial number" - : "Please remove the current card and " - "insert the one with serial number", - want_sn_displen, want_sn) < 0) - { - rc = GNUPG_Out_Of_Core; - } - else - { - rc = agent_get_confirmation (desc, NULL, NULL); - free (desc); - } - } - if (rc) - { - xfree (want_sn); - xfree (want_kid); - return rc; - } - } -} - - -/* Put the DIGEST into an DER encoded comtainer and return it in R_VAL. */ -static int -encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo, - unsigned char **r_val, size_t *r_len) -{ - byte *frame; - byte asn[100]; - size_t asnlen; - - asnlen = DIM(asn); - if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen)) - { - log_error ("no object identifier for algo %d\n", algo); - return GNUPG_Internal_Error; - } - - frame = xtrymalloc (asnlen + digestlen); - if (!frame) - return GNUPG_Out_Of_Core; - memcpy (frame, asn, asnlen); - memcpy (frame+asnlen, digest, digestlen); - if (DBG_CRYPTO) - log_printhex ("encoded hash:", frame, asnlen+digestlen); - - *r_val = frame; - *r_len = asnlen+digestlen; - return 0; -} - - -/* Callback used to ask for the PIN which should be set into BUF. The - buf has been allocated by the caller and is of size MAXBUF which - includes the terminating null. The function should return an UTF-8 - string with the passphrase, the buffer may optionally be padded - with arbitrary characters */ -static int -getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf) -{ - struct pin_entry_info_s *pi; - int rc; - char *desc; - - assert (!opaque); - - if (maxbuf < 2) - return GNUPG_Invalid_Value; - - - /* FIXME: keep PI and TRIES in OPAQUE. Frankly this is a whole - mess because we should call the card's verify function from the - pinentry check pin CB. */ - pi = gcry_calloc_secure (1, sizeof (*pi) + 100); - pi->max_length = maxbuf-1; - pi->min_digits = 0; /* we want a real passphrase */ - pi->max_digits = 8; - pi->max_tries = 3; - - if ( asprintf (&desc, _("Please enter the PIN%s%s%s to unlock the card"), - info? " (`":"", - info? info:"", - info? "')":"") < 0) - desc = NULL; - rc = agent_askpin (desc?desc:info, pi); - free (desc); - if (!rc) - { - strncpy (buf, pi->pin, maxbuf-1); - buf[maxbuf-1] = 0; - } - xfree (pi); - return rc; -} - - - - -int -divert_pksign (const unsigned char *digest, size_t digestlen, int algo, - const unsigned char *shadow_info, unsigned char **r_sig) -{ - int rc; - char *kid; - size_t siglen; - char *sigval; - unsigned char *data; - size_t ndata; - - rc = ask_for_card (shadow_info, &kid); - if (rc) - return rc; - - rc = encode_md_for_card (digest, digestlen, algo, - &data, &ndata); - if (rc) - return rc; - - rc = agent_card_pksign (kid, getpin_cb, NULL, - data, ndata, &sigval, &siglen); - if (!rc) - *r_sig = sigval; - xfree (data); - xfree (kid); - - return rc; -} - - -/* Decrypt the the value given asn an S-expression in CIPHER using the - key identified by SHADOW_INFO and return the plaintext in an - allocated buffer in R_BUF. */ -int -divert_pkdecrypt (const unsigned char *cipher, - const unsigned char *shadow_info, - char **r_buf, size_t *r_len) -{ - int rc; - char *kid; - const unsigned char *s; - size_t n; - const unsigned char *ciphertext; - size_t ciphertextlen; - char *plaintext; - size_t plaintextlen; - - s = cipher; - if (*s != '(') - return GNUPG_Invalid_Sexp; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - if (!smatch (&s, n, "enc-val")) - return GNUPG_Unknown_Sexp; - if (*s != '(') - return GNUPG_Unknown_Sexp; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - if (!smatch (&s, n, "rsa")) - return GNUPG_Unsupported_Algorithm; - if (*s != '(') - return GNUPG_Unknown_Sexp; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - if (!smatch (&s, n, "a")) - return GNUPG_Unknown_Sexp; - n = snext (&s); - if (!n) - return GNUPG_Unknown_Sexp; - ciphertext = s; - ciphertextlen = n; - - rc = ask_for_card (shadow_info, &kid); - if (rc) - return rc; - - rc = agent_card_pkdecrypt (kid, getpin_cb, NULL, - ciphertext, ciphertextlen, - &plaintext, &plaintextlen); - if (!rc) - { - *r_buf = plaintext; - *r_len = plaintextlen; - } - xfree (kid); - return rc; -} diff --git a/agent/findkey.c b/agent/findkey.c deleted file mode 100644 index 8ec230fa0..000000000 --- a/agent/findkey.c +++ /dev/null @@ -1,350 +0,0 @@ -/* findkey.c - locate the secret key - * Copyright (C) 2001,02 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "agent.h" - -/* Helper to pass data to the check callback of the unprotect function. */ -struct try_unprotect_arg_s { - const unsigned char *protected_key; - unsigned char *unprotected_key; -}; - - - -int -agent_write_private_key (const unsigned char *grip, - const void *buffer, size_t length, int force) -{ - int i; - char *fname; - FILE *fp; - char hexgrip[40+4+1]; - - for (i=0; i < 20; i++) - sprintf (hexgrip+2*i, "%02X", grip[i]); - strcpy (hexgrip+40, ".key"); - - fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL); - if (force) - fp = fopen (fname, "wb"); - else - { - int fd; - - if (!access (fname, F_OK)) - { - log_error ("secret key file `%s' already exists\n", fname); - xfree (fname); - return seterr (General_Error); - } - - /* We would like to create FNAME but only if it does not already - exist. We cannot make this guarantee just using POSIX (GNU - provides the "x" opentype for fopen, however, this is not - portable). Thus, we use the more flexible open function and - then use fdopen to obtain a stream. - - The mode parameter to open is what fopen uses. It will be - combined with the process' umask automatically. */ - fd = open (fname, O_CREAT | O_EXCL | O_RDWR, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - if (fd < 0) - fp = 0; - else - { - fp = fdopen (fd, "wb"); - if (! fp) - close (fd); - } - } - - if (!fp) - { - log_error ("can't create `%s': %s\n", fname, strerror (errno)); - xfree (fname); - return seterr (File_Create_Error); - } - - if (fwrite (buffer, length, 1, fp) != 1) - { - log_error ("error writing `%s': %s\n", fname, strerror (errno)); - fclose (fp); - remove (fname); - xfree (fname); - return seterr (File_Create_Error); - } - if ( fclose (fp) ) - { - log_error ("error closing `%s': %s\n", fname, strerror (errno)); - remove (fname); - xfree (fname); - return seterr (File_Create_Error); - } - - xfree (fname); - return 0; -} - - -/* Callback function to try the unprotection from the passpharse query - code. */ -static int -try_unprotect_cb (struct pin_entry_info_s *pi) -{ - struct try_unprotect_arg_s *arg = pi->check_cb_arg; - size_t dummy; - - assert (!arg->unprotected_key); - return agent_unprotect (arg->protected_key, pi->pin, - &arg->unprotected_key, &dummy); -} - - -/* Unprotect the canconical encoded S-expression key in KEYBUF. GRIP - should be the hex encoded keygrip of that key to be used with the - cahing mechanism. */ -static int -unprotect (unsigned char **keybuf, const unsigned char *grip, int ignore_cache) -{ - struct pin_entry_info_s *pi; - struct try_unprotect_arg_s arg; - int rc, i; - unsigned char *result; - size_t resultlen; - char hexgrip[40+1]; - - for (i=0; i < 20; i++) - sprintf (hexgrip+2*i, "%02X", grip[i]); - hexgrip[40] = 0; - - /* first try to get it from the cache - if there is none or we can't - unprotect it, we fall back to ask the user */ - if (!ignore_cache) - { - void *cache_marker; - const char *pw = agent_get_cache (hexgrip, &cache_marker); - if (pw) - { - rc = agent_unprotect (*keybuf, pw, &result, &resultlen); - agent_unlock_cache_entry (&cache_marker); - if (!rc) - { - xfree (*keybuf); - *keybuf = result; - return 0; - } - rc = 0; - } - } - - pi = gcry_calloc_secure (1, sizeof (*pi) + 100); - pi->max_length = 100; - pi->min_digits = 0; /* we want a real passphrase */ - pi->max_digits = 8; - pi->max_tries = 3; - pi->check_cb = try_unprotect_cb; - arg.protected_key = *keybuf; - arg.unprotected_key = NULL; - pi->check_cb_arg = &arg; - - rc = agent_askpin (NULL, pi); - if (!rc) - { - assert (arg.unprotected_key); - agent_put_cache (hexgrip, pi->pin, 0); - xfree (*keybuf); - *keybuf = arg.unprotected_key; - } - xfree (pi); - return rc; -} - - - -/* Return the secret key as an S-Exp after locating it using the grip. - Returns NULL if key is not available or the operation should be - diverted to a token. In the latter case shadow_info will point to - an allocated S-Expression with the shadow_info part from the file. - With IGNORE_CACHE passed as true the passphrase is not taken from - the cache.*/ -GCRY_SEXP -agent_key_from_file (const unsigned char *grip, unsigned char **shadow_info, - int ignore_cache) -{ - int i, rc; - char *fname; - FILE *fp; - struct stat st; - unsigned char *buf; - size_t len, buflen, erroff; - GCRY_SEXP s_skey; - char hexgrip[40+4+1]; - - if (shadow_info) - *shadow_info = NULL; - - for (i=0; i < 20; i++) - sprintf (hexgrip+2*i, "%02X", grip[i]); - strcpy (hexgrip+40, ".key"); - - fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL); - fp = fopen (fname, "rb"); - if (!fp) - { - log_error ("can't open `%s': %s\n", fname, strerror (errno)); - xfree (fname); - return NULL; - } - - if (fstat (fileno(fp), &st)) - { - log_error ("can't stat `%s': %s\n", fname, strerror (errno)); - xfree (fname); - fclose (fp); - return NULL; - } - - buflen = st.st_size; - buf = xmalloc (buflen+1); - if (fread (buf, buflen, 1, fp) != 1) - { - log_error ("error reading `%s': %s\n", fname, strerror (errno)); - xfree (fname); - fclose (fp); - xfree (buf); - return NULL; - } - - rc = gcry_sexp_sscan (&s_skey, &erroff, buf, buflen); - xfree (fname); - fclose (fp); - xfree (buf); - if (rc) - { - log_error ("failed to build S-Exp (off=%u): %s\n", - (unsigned int)erroff, gcry_strerror (rc)); - return NULL; - } - len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0); - assert (len); - buf = xtrymalloc (len); - if (!buf) - { - gcry_sexp_release (s_skey); - return NULL; - } - len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, buf, len); - assert (len); - gcry_sexp_release (s_skey); - - switch (agent_private_key_type (buf)) - { - case PRIVATE_KEY_CLEAR: - break; /* no unprotection needed */ - case PRIVATE_KEY_PROTECTED: - rc = unprotect (&buf, grip, ignore_cache); - if (rc) - log_error ("failed to unprotect the secret key: %s\n", - gnupg_strerror (rc)); - break; - case PRIVATE_KEY_SHADOWED: - if (shadow_info) - { - const unsigned char *s; - size_t n; - - rc = agent_get_shadow_info (buf, &s); - if (!rc) - { - n = gcry_sexp_canon_len (s, 0, NULL,NULL); - assert (n); - *shadow_info = xtrymalloc (n); - if (!*shadow_info) - rc = GNUPG_Out_Of_Core; - else - { - memcpy (*shadow_info, s, n); - rc = 0; - } - } - if (rc) - log_error ("get_shadow_info failed: %s\n", gnupg_strerror (rc)); - } - rc = -1; /* ugly interface: we return an error but keep a value - in shadow_info. */ - break; - default: - log_error ("invalid private key format\n"); - rc = GNUPG_Bad_Secret_Key; - break; - } - if (rc) - { - xfree (buf); - return NULL; - } - - /* arggg FIXME: does scan support secure memory? */ - rc = gcry_sexp_sscan (&s_skey, &erroff, - buf, gcry_sexp_canon_len (buf, 0, NULL, NULL)); - xfree (buf); - if (rc) - { - log_error ("failed to build S-Exp (off=%u): %s\n", - (unsigned int)erroff, gcry_strerror (rc)); - return NULL; - } - - return s_skey; -} - -/* Return the secret key as an S-Exp after locating it using the grip. - Returns NULL if key is not available. 0 = key is available */ -int -agent_key_available (const unsigned char *grip) -{ - int i; - char *fname; - char hexgrip[40+4+1]; - - for (i=0; i < 20; i++) - sprintf (hexgrip+2*i, "%02X", grip[i]); - strcpy (hexgrip+40, ".key"); - - fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL); - i = !access (fname, R_OK)? 0 : -1; - xfree (fname); - return i; -} - - - diff --git a/agent/genkey.c b/agent/genkey.c deleted file mode 100644 index dccac94da..000000000 --- a/agent/genkey.c +++ /dev/null @@ -1,200 +0,0 @@ -/* pksign.c - Generate a keypair - * Copyright (C) 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 -#include -#include -#include -#include -#include -#include - -#include "agent.h" -#include "i18n.h" - -static int -store_key (GCRY_SEXP private, const char *passphrase) -{ - int rc; - char *buf; - size_t len; - unsigned char grip[20]; - - if ( !gcry_pk_get_keygrip (private, grip) ) - { - log_error ("can't calculate keygrip\n"); - return seterr (General_Error); - } - - len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, NULL, 0); - assert (len); - buf = gcry_malloc_secure (len); - if (!buf) - return seterr (Out_Of_Core); - len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, buf, len); - assert (len); - - if (passphrase) - { - unsigned char *p; - - rc = agent_protect (buf, passphrase, &p, &len); - if (rc) - { - xfree (buf); - return rc; - } - xfree (buf); - buf = p; - } - - rc = agent_write_private_key (grip, buf, len, 0); - xfree (buf); - return rc; -} - -/* Callback function to compare the first entered PIN with the one - currently beeing entered. */ -static int -reenter_compare_cb (struct pin_entry_info_s *pi) -{ - const char *pin1 = pi->check_cb_arg; - - if (!strcmp (pin1, pi->pin)) - return 0; /* okay */ - pi->cb_errtext = _("does not match - try again"); - return -1; -} - - - -/* Generate a new keypair according to the parameters given in - KEYPARAM */ -int -agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen, - FILE *outfp) -{ - GCRY_SEXP s_keyparam, s_key, s_private, s_public; - struct pin_entry_info_s *pi, *pi2; - int rc; - size_t len; - char *buf; - - rc = gcry_sexp_sscan (&s_keyparam, NULL, keyparam, keyparamlen); - if (rc) - { - log_error ("failed to convert keyparam: %s\n", gcry_strerror (rc)); - return seterr (Invalid_Data); - } - - /* Get the passphrase now, cause key generation may take a while. */ - { - const char *text1 = _("Please enter the passphrase to%0A" - "to protect your new key"); - const char *text2 = _("Please re-enter this passphrase"); - - pi = gcry_calloc_secure (2, sizeof (*pi) + 100); - pi2 = pi + (sizeof *pi + 100); - pi->max_length = 100; - pi->max_tries = 3; - pi2->max_length = 100; - pi2->max_tries = 3; - pi2->check_cb = reenter_compare_cb; - pi2->check_cb_arg = pi->pin; - - rc = agent_askpin (text1, pi); - if (!rc) - rc = agent_askpin (text2, pi2); - if (rc) - return rc; - if (!*pi->pin) - { - xfree (pi); - pi = NULL; /* User does not want a passphrase. */ - } - } - - rc = gcry_pk_genkey (&s_key, s_keyparam ); - gcry_sexp_release (s_keyparam); - if (rc) - { - log_error ("key generation failed: %s\n", gcry_strerror (rc)); - xfree (pi); - return map_gcry_err (rc); - } - - /* break out the parts */ - s_private = gcry_sexp_find_token (s_key, "private-key", 0); - if (!s_private) - { - log_error ("key generation failed: invalid return value\n"); - gcry_sexp_release (s_key); - xfree (pi); - return seterr (Invalid_Data); - } - s_public = gcry_sexp_find_token (s_key, "public-key", 0); - if (!s_public) - { - log_error ("key generation failed: invalid return value\n"); - gcry_sexp_release (s_private); - gcry_sexp_release (s_key); - xfree (pi); - return seterr (Invalid_Data); - } - gcry_sexp_release (s_key); s_key = NULL; - - /* store the secret key */ - log_debug ("storing private key\n"); - rc = store_key (s_private, pi? pi->pin:NULL); - xfree (pi); pi = NULL; - gcry_sexp_release (s_private); - if (rc) - { - gcry_sexp_release (s_public); - return rc; - } - - /* return the public key */ - log_debug ("returning public key\n"); - len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, NULL, 0); - assert (len); - buf = xmalloc (len); - if (!buf) - { - gcry_sexp_release (s_private); - gcry_sexp_release (s_public); - return seterr (Out_Of_Core); - } - len = gcry_sexp_sprint (s_public, GCRYSEXP_FMT_CANON, buf, len); - assert (len); - if (fwrite (buf, len, 1, outfp) != 1) - { - log_error ("error writing public key: %s\n", strerror (errno)); - gcry_sexp_release (s_private); - gcry_sexp_release (s_public); - xfree (buf); - return seterr (File_Create_Error); - } - gcry_sexp_release (s_public); - xfree (buf); - - return 0; -} - diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c deleted file mode 100644 index c99fc4afc..000000000 --- a/agent/gpg-agent.c +++ /dev/null @@ -1,908 +0,0 @@ -/* gpg-agent.c - The GnuPG Agent - * Copyright (C) 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef USE_GNU_PTH -# include -#endif - -#include - -#define JNLIB_NEED_LOG_LOGV -#include "agent.h" -#include "../assuan/assuan.h" /* malloc hooks */ - -#include "i18n.h" -#include "sysutils.h" - - -enum cmd_and_opt_values -{ aNull = 0, - oCsh = 'c', - oQuiet = 'q', - oSh = 's', - oVerbose = 'v', - - oNoVerbose = 500, - oOptions, - oDebug, - oDebugAll, - oDebugWait, - oNoGreeting, - oNoOptions, - oHomedir, - oNoDetach, - oNoGrab, - oLogFile, - oServer, - oDaemon, - oBatch, - - oPinentryProgram, - oDisplay, - oTTYname, - oTTYtype, - oLCctype, - oLCmessages, - oScdaemonProgram, - oDefCacheTTL, - oDisablePth, - - oIgnoreCacheForSigning, - -aTest }; - - - -static ARGPARSE_OPTS opts[] = { - - { 301, NULL, 0, N_("@Options:\n ") }, - - { oServer, "server", 0, N_("run in server mode (foreground)") }, - { oDaemon, "daemon", 0, N_("run in daemon mode (background)") }, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, - { oSh, "sh", 0, N_("sh-style command output") }, - { oCsh, "csh", 0, N_("csh-style command output") }, - { oOptions, "options" , 2, N_("read options from file")}, - { oDebug, "debug" ,4|16, N_("set debugging flags")}, - { oDebugAll, "debug-all" ,0, N_("enable full debugging")}, - { oDebugWait,"debug-wait",1, "@"}, - { oNoDetach, "no-detach" ,0, N_("do not detach from the console")}, - { oNoGrab, "no-grab" ,0, N_("do not grab keyboard and mouse")}, - { oLogFile, "log-file" ,2, N_("use a log file for the server")}, - { oDisablePth, "disable-pth", 0, N_("do not allow multiple connections")}, - - { oPinentryProgram, "pinentry-program", 2 , "path to PIN Entry program" }, - { oDisplay, "display", 2, "set the display" }, - { oTTYname, "ttyname", 2, "set the tty terminal node name" }, - { oTTYtype, "ttytype", 2, "set the tty terminal type" }, - { oLCctype, "lc-ctype", 2, "set the tty LC_CTYPE value" }, - { oLCmessages, "lc-messages", 2, "set the tty LC_MESSAGES value" }, - - { oScdaemonProgram, "scdaemon-program", 2 , "path to SCdaemon program" }, - { oDefCacheTTL, "default-cache-ttl", 4, - "|N|expire cached PINs after N seconds"}, - { oIgnoreCacheForSigning, "ignore-cache-for-signing", 0, - "do not use the PIN cache when signing"}, - - {0} -}; - - -static volatile int caught_fatal_sig = 0; - -/* flag to indicate that a shutdown was requested */ -static int shutdown_pending; - - -/* It is possible that we are currently running under setuid permissions */ -static int maybe_setuid = 1; - -/* Name of the communication socket */ -static char socket_name[128]; - -static void create_directories (void); -#ifdef USE_GNU_PTH -static void handle_connections (int listen_fd); -#endif - - - -static const char * -my_strusage (int level) -{ - const char *p; - switch (level) - { - case 11: p = "gpg-agent (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; - case 1: - case 40: p = _("Usage: gpg-agent [options] (-h for help)"); - break; - case 41: p = _("Syntax: gpg-agent [options] [command [args]]\n" - "Secret key management for GnuPG\n"); - break; - - default: p = NULL; - } - return p; -} - - - -static void -i18n_init (void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file( PACKAGE ); -#else -#ifdef ENABLE_NLS - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); -#endif -#endif -} - - - -/* Used by gcry for logging */ -static void -my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) -{ - /* translate the log levels */ - switch (level) - { - case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break; - case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break; - case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break; - case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break; - case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break; - case GCRY_LOG_BUG: level = JNLIB_LOG_BUG; break; - case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break; - default: level = JNLIB_LOG_ERROR; break; - } - log_logv (level, fmt, arg_ptr); -} - - -static void -cleanup (void) -{ - if (*socket_name) - { - char *p; - - remove (socket_name); - p = strrchr (socket_name, '/'); - if (p) - { - *p = 0; - rmdir (socket_name); - *p = '/'; - } - *socket_name = 0; - } -} - - -static RETSIGTYPE -cleanup_sh (int sig) -{ - if (caught_fatal_sig) - raise (sig); - caught_fatal_sig = 1; - - /* gcry_control( GCRYCTL_TERM_SECMEM );*/ - cleanup (); - -#ifndef HAVE_DOSISH_SYSTEM - { /* reset action to default action and raise signal again */ - struct sigaction nact; - nact.sa_handler = SIG_DFL; - sigemptyset( &nact.sa_mask ); - nact.sa_flags = 0; - sigaction( sig, &nact, NULL); - } -#endif - raise( sig ); -} - -int -main (int argc, char **argv ) -{ - ARGPARSE_ARGS pargs; - int orig_argc; - int may_coredump; - char **orig_argv; - FILE *configfp = NULL; - char *configname = NULL; - const char *shell; - unsigned configlineno; - int parse_debug = 0; - int default_config =1; - int greeting = 0; - int nogreeting = 0; - int pipe_server = 0; - int is_daemon = 0; - int nodetach = 0; - int csh_style = 0; - char *logfile = NULL; - int debug_wait = 0; - int disable_pth = 0; - - set_strusage (my_strusage); - gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - /* Please note that we may running SUID(ROOT), so be very CAREFUL - when adding any stuff between here and the call to INIT_SECMEM() - somewhere after the option parsing */ - log_set_prefix ("gpg-agent", 1|4); - i18n_init (); - - /* check that the libraries are suitable. Do it here because - the option parsing 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) ); - } - - assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); -#ifdef USE_GNU_PTH - assuan_set_io_func (pth_read, pth_write); -#endif - - gcry_set_log_handler (my_gcry_logger, NULL); - gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); - - may_coredump = disable_core_dumps (); - - shell = getenv ("SHELL"); - if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") ) - csh_style = 1; - - opt.homedir = getenv("GNUPGHOME"); - if (!opt.homedir || !*opt.homedir) - opt.homedir = GNUPG_DEFAULT_HOMEDIR; - opt.def_cache_ttl = 10*60; /* default to 10 minutes */ - - - /* 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) - opt.homedir = pargs.r.ret_str; - } - - /* initialize the secure memory. */ - gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); - maybe_setuid = 0; - - /* - Now we are now working under our real uid - */ - - - if (default_config) - configname = make_filename (opt.homedir, "gpg-agent.conf", NULL ); - - argc = orig_argc; - argv = orig_argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - next_pass: - if (configname) - { - 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) ); - 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 oQuiet: opt.quiet = 1; break; - case oVerbose: opt.verbose++; break; - case oBatch: opt.batch=1; break; - - case oDebug: opt.debug |= pargs.r.ret_ulong; break; - case oDebugAll: opt.debug = ~0; break; - case oDebugWait: debug_wait = pargs.r.ret_int; 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 oNoGreeting: nogreeting = 1; break; - case oNoVerbose: opt.verbose = 0; break; - case oNoOptions: break; /* no-options */ - case oHomedir: opt.homedir = pargs.r.ret_str; break; - case oNoDetach: nodetach = 1; break; - case oNoGrab: opt.no_grab = 1; break; - case oLogFile: logfile = pargs.r.ret_str; break; - case oCsh: csh_style = 1; break; - case oSh: csh_style = 0; break; - case oServer: pipe_server = 1; break; - case oDaemon: is_daemon = 1; break; - case oDisablePth: disable_pth = 1; break; - - case oPinentryProgram: opt.pinentry_program = pargs.r.ret_str; break; - case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break; - case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break; - case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break; - case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break; - case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break; - case oScdaemonProgram: opt.scdaemon_program = pargs.r.ret_str; break; - case oDefCacheTTL: opt.def_cache_ttl = pargs.r.ret_ulong; break; - - case oIgnoreCacheForSigning: opt.ignore_cache_for_signing = 1; break; - - default : pargs.err = configfp? 1:2; break; - } - } - if (configfp) - { - fclose( configfp ); - configfp = NULL; - xfree(configname); - configname = NULL; - goto next_pass; - } - xfree (configname); - configname = NULL; - if (log_get_errorcount(0)) - 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 - log_info ("NOTE: this is a development version!\n"); -#endif - - - if (atexit (cleanup)) - { - log_error ("atexit failed\n"); - cleanup (); - exit (1); - } - - create_directories (); - - if (debug_wait && pipe_server) - { - log_debug ("waiting for debugger - my pid is %u .....\n", - (unsigned int)getpid()); - sleep (debug_wait); - log_debug ("... okay\n"); - } - - /* now start with logging to a file if this is desired */ - if (logfile) - { - log_set_file (logfile); - log_set_prefix (NULL, 1|2|4); - } - - - if (pipe_server) - { /* this is the simple pipe based server */ - start_command_handler (-1, -1); - } - else if (!is_daemon) - { - log_info (_("please use the option `--daemon'" - " to run the program in the background\n")); - } - else - { /* regular server mode */ - int fd; - pid_t pid; - int len; - struct sockaddr_un serv_addr; - char *p; - - *socket_name = 0; - snprintf (socket_name, DIM(socket_name)-1, - "/tmp/gpg-XXXXXX/S.gpg-agent"); - socket_name[DIM(socket_name)-1] = 0; - p = strrchr (socket_name, '/'); - if (!p) - BUG (); - *p = 0;; - if (!mkdtemp(socket_name)) - { - log_error ("can't create directory `%s': %s\n", - socket_name, strerror(errno) ); - exit (1); - } - *p = '/'; - - if (strchr (socket_name, ':') ) - { - log_error ("colons are not allowed in the socket name\n"); - exit (1); - } - if (strlen (socket_name)+1 >= sizeof serv_addr.sun_path ) - { - log_error ("name of socket too long\n"); - exit (1); - } - - - fd = socket (AF_UNIX, SOCK_STREAM, 0); - if (fd == -1) - { - log_error ("can't create socket: %s\n", strerror(errno) ); - exit (1); - } - - memset (&serv_addr, 0, sizeof serv_addr); - serv_addr.sun_family = AF_UNIX; - strcpy (serv_addr.sun_path, socket_name); - len = (offsetof (struct sockaddr_un, sun_path) - + strlen(serv_addr.sun_path) + 1); - - if (bind (fd, (struct sockaddr*)&serv_addr, len) == -1) - { - log_error ("error binding socket to `%s': %s\n", - serv_addr.sun_path, strerror (errno) ); - close (fd); - exit (1); - } - - if (listen (fd, 5 ) == -1) - { - log_error ("listen() failed: %s\n", strerror (errno)); - close (fd); - exit (1); - } - - if (opt.verbose) - log_info ("listening on socket `%s'\n", socket_name ); - - - fflush (NULL); - pid = fork (); - if (pid == (pid_t)-1) - { - log_fatal ("fork failed: %s\n", strerror (errno) ); - exit (1); - } - else if (pid) - { /* we are the parent */ - char *infostr; - - close (fd); - - /* create the info string: :: */ - if (asprintf (&infostr, "GPG_AGENT_INFO=%s:%lu:1", - socket_name, (ulong)pid ) < 0) - { - log_error ("out of core\n"); - kill (pid, SIGTERM); - exit (1); - } - *socket_name = 0; /* don't let cleanup() remove the socket - - the child should do this from now on */ - if (argc) - { /* run the program given on the commandline */ - if (putenv (infostr)) - { - log_error ("failed to set environment: %s\n", - strerror (errno) ); - kill (pid, SIGTERM ); - exit (1); - } - execvp (argv[0], argv); - log_error ("failed to run the command: %s\n", strerror (errno)); - kill (pid, SIGTERM); - exit (1); - } - else - { - /* print the environment string, so that the caller can use - shell's eval to set it */ - if (csh_style) - { - *strchr (infostr, '=') = ' '; - printf ( "setenv %s\n", infostr); - } - else - { - printf ( "%s; export GPG_AGENT_INFO;\n", infostr); - } - free (infostr); - exit (0); - } - /*NEVER REACHED*/ - } /* end parent */ - - - /* this is the child */ - - /* detach from tty and put process into a new session */ - if (!nodetach ) - { - int i; - - /* close stdin, stdout and stderr unless it is the log stream */ - for (i=0; i <= 2; i++) - { - if ( log_get_fd () != i) - close (i); - } - if (setsid() == -1) - { - log_error ("setsid() failed: %s\n", strerror(errno) ); - cleanup (); - exit (1); - } - opt.running_detached = 1; - } - - if (chdir("/")) - { - log_error ("chdir to / failed: %s\n", strerror (errno)); - exit (1); - } - - -#ifdef USE_GNU_PTH - if (!disable_pth) - { - struct sigaction sa; - - if (!pth_init ()) - { - log_error ("failed to initialize the Pth library\n"); - exit (1); - } - - sa.sa_handler = SIG_IGN; - sigemptyset (&sa.sa_mask); - sa.sa_flags = 0; - sigaction (SIGPIPE, &sa, NULL); - handle_connections (fd); - } - else -#endif /*!USE_GNU_PTH*/ - /* setup signals */ - { - struct sigaction oact, nact; - - nact.sa_handler = cleanup_sh; - sigemptyset (&nact.sa_mask); - nact.sa_flags = 0; - - sigaction (SIGHUP, NULL, &oact); - if (oact.sa_handler != SIG_IGN) - sigaction (SIGHUP, &nact, NULL); - sigaction( SIGTERM, NULL, &oact ); - if (oact.sa_handler != SIG_IGN) - sigaction (SIGTERM, &nact, NULL); - nact.sa_handler = SIG_IGN; - sigaction (SIGPIPE, &nact, NULL); - sigaction (SIGINT, &nact, NULL); - - start_command_handler (fd, -1); - } - close (fd); - } - - return 0; -} - -void -agent_exit (int rc) -{ - /*FIXME: update_random_seed_file();*/ -#if 1 - /* at this time a bit annoying */ - 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 ); -#endif - gcry_control (GCRYCTL_TERM_SECMEM ); - rc = rc? rc : log_get_errorcount(0)? 2 : 0; - exit (rc); -} - - -static void -reread_configuration (void) -{ - /* FIXME: Move parts of the option parsing to here. */ -} - - -static void -create_private_keys_directory (const char *home) -{ - char *fname; - struct stat statbuf; - - fname = make_filename (home, GNUPG_PRIVATE_KEYS_DIR, NULL); - if (stat (fname, &statbuf) && errno == ENOENT) - { - if (mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR )) - log_error (_("can't create directory `%s': %s\n"), - fname, strerror(errno) ); - else if (!opt.quiet) - log_info (_("directory `%s' created\n"), fname); - } - xfree (fname); -} - -/* 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 home directory is used. To cope - with HOME, we compare only the suffix if we see that the default - homedir does start with a tilde. We don't stop here in case of - problems because other functions will throw an error anyway.*/ -static void -create_directories (void) -{ - struct stat statbuf; - const char *defhome = GNUPG_DEFAULT_HOMEDIR; - char *home; - - home = make_filename (opt.homedir, NULL); - if ( stat (home, &statbuf) ) - { - if (errno == ENOENT) - { - if ( (*defhome == '~' - && (strlen (home) >= strlen (defhome+1) - && !strcmp (home + strlen(home) - - strlen (defhome+1), defhome+1))) - || (*defhome != '~' && !strcmp (home, defhome) ) - ) - { - if (mkdir (home, S_IRUSR|S_IWUSR|S_IXUSR )) - log_error (_("can't create directory `%s': %s\n"), - home, strerror(errno) ); - else - { - if (!opt.quiet) - log_info (_("directory `%s' created\n"), home); - create_private_keys_directory (home); - } - } - } - else - log_error ("error stat-ing `%s': %s\n", home, strerror (errno)); - } - else if ( !S_ISDIR(statbuf.st_mode)) - { - log_error ("can't use `%s' as home directory\n", home); - } - else /* exists and is a directory. */ - { - create_private_keys_directory (home); - } - xfree (home); -} - - - -#ifdef USE_GNU_PTH -static void -handle_signal (int signo) -{ - switch (signo) - { - case SIGHUP: - log_info ("SIGHUP received - re-reading configuration\n"); - reread_configuration (); - break; - - case SIGUSR1: - if (opt.verbose < 5) - opt.verbose++; - log_info ("SIGUSR1 received - verbosity set to %d\n", opt.verbose); - break; - - case SIGUSR2: - if (opt.verbose) - opt.verbose--; - log_info ("SIGUSR2 received - verbosity set to %d\n", opt.verbose ); - break; - - case SIGTERM: - if (!shutdown_pending) - log_info ("SIGTERM received - shutting down ...\n"); - else - log_info ("SIGTERM received - still %ld running threads\n", - pth_ctrl( PTH_CTRL_GETTHREADS )); - shutdown_pending++; - if (shutdown_pending > 2) - { - log_info ("shutdown forced\n"); - log_info ("%s %s stopped\n", strusage(11), strusage(13) ); - cleanup (); - agent_exit (0); - } - break; - - case SIGINT: - log_info ("SIGINT received - immediate shutdown\n"); - log_info( "%s %s stopped\n", strusage(11), strusage(13)); - cleanup (); - agent_exit (0); - break; - - default: - log_info ("signal %d received - no action defined\n", signo); - } -} - - -static void * -start_connection_thread (void *arg) -{ - int fd = (int)arg; - - if (opt.verbose) - log_info ("handler for fd %d started\n", fd); - start_command_handler (-1, fd); - if (opt.verbose) - log_info ("handler for fd %d terminated\n", fd); - - return NULL; -} - - -static void -handle_connections (int listen_fd) -{ - pth_attr_t tattr; - pth_event_t ev; - sigset_t sigs; - int signo; - struct sockaddr_un paddr; - socklen_t plen = sizeof( paddr ); - int fd; - - tattr = pth_attr_new(); - pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); - pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 32*1024); - pth_attr_set (tattr, PTH_ATTR_NAME, "gpg-agent"); - - sigemptyset (&sigs ); - sigaddset (&sigs, SIGHUP); - sigaddset (&sigs, SIGUSR1); - sigaddset (&sigs, SIGUSR2); - sigaddset (&sigs, SIGINT); - sigaddset (&sigs, SIGTERM); - ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); - - for (;;) - { - if (shutdown_pending) - { - if (pth_ctrl (PTH_CTRL_GETTHREADS) == 1) - break; /* ready */ - - /* Do not accept anymore connections and wait for existing - connections to terminate */ - signo = 0; - pth_wait (ev); - if (pth_event_occurred (ev) && signo) - handle_signal (signo); - continue; - } - - fd = pth_accept_ev (listen_fd, (struct sockaddr *)&paddr, &plen, ev); - if (fd == -1) - { - if (pth_event_occurred (ev)) - { - handle_signal (signo); - continue; - } - log_error ("accept failed: %s - waiting 1s\n", strerror (errno)); - pth_sleep(1); - continue; - } - - if (!pth_spawn (tattr, start_connection_thread, (void*)fd)) - { - log_error ("error spawning connection handler: %s\n", - strerror (errno) ); - close (fd); - } - } - - pth_event_free (ev, PTH_FREE_ALL); - cleanup (); - log_info ("%s %s stopped\n", strusage(11), strusage(13)); -} -#endif /*USE_GNU_PTH*/ diff --git a/agent/keyformat.txt b/agent/keyformat.txt deleted file mode 100644 index 6c0bd8b83..000000000 --- a/agent/keyformat.txt +++ /dev/null @@ -1,163 +0,0 @@ -keyformat.txt (wk 2001-12-18) ------------------------------ - - -Some notes on the format of the secret keys used with gpg-agent. - -Location of keys -================ -The secret keys[1] are stored on a per file basis in a directory below -the ~/.gnupg home directory. This directory is named - - private-keys-v1.d - -and should have permissions 700. - -The secret keys are stored in files with a name matching the -hexadecimal representation of the keygrip[2]. - -Unprotected Private Key Format -============================== -The content of the file is an S-Expression like the ones used with -Libgcrypt. Here is an example of an unprotected file: - -(private-key - (rsa - (n #00e0ce9..[some bytes not shown]..51#) - (e #010001#) - (d #046129F..[some bytes not shown]..81#) - (p #00e861b..[some bytes not shown]..f1#) - (q #00f7a7c..[some bytes not shown]..61#) - (u #304559a..[some bytes not shown]..9b#) - ) - (uri http://foo.bar x-foo:whatever_you_want) -) - -Actually this form should not be used for regular purposes and only -accepted by gpg-agent with the configuration option: ---allow-non-canonical-key-format. The regular way to represent the -keys is in canonical representation[3]: - -(private-key - (rsa - (n #00e0ce9..[some bytes not shown]..51#) - (e #010001#) - (d #046129F..[some bytes not shown]..81#) - (p #00e861b..[some bytes not shown]..f1#) - (q #00f7a7c..[some bytes not shown]..61#) - (u #304559a..[some bytes not shown]..9b#) - ) - (uri http://foo.bar x-foo:whatever_you_want) -) - - -Protected Private Key Format -============================== -A protected key is like this: - -(protected-private-key - (rsa - (n #00e0ce9..[some bytes not shown]..51#) - (e #010001#) - (protected mode (parms) encrypted_octet_string) - ) - (uri http://foo.bar x-foo:whatever_you_want) -) - - -In this scheme the encrypted_octet_string is encrypted according to -the algorithm described after the keyword protected; most protection -algorithms need some parameters, which are given in a list before the -encrypted_octet_string. The result of the decryption process is a -list of the secret key parameters. - -The only available protection mode for now is - - openpgp-s2k3-sha1-aes-cbc - -which describes an algorithm using using AES in CBC mode for -encryption, SHA-1 for integrity protection and the String to Key -algorithm 3 from OpenPGP (rfc2440). - -Example: - -(protected openpgp-s2k3-sha1-aes-cbc - ((sha1 16byte_salt no_of_iterations) 16byte_iv) - encrypted_octet_string -) - -The encrypted_octet string should yield this S-Exp (in canonical -representation) after decryption: - -( - ( - (d #046129F..[some bytes not shown]..81#) - (p #00e861b..[some bytes not shown]..f1#) - (q #00f7a7c..[some bytes not shown]..61#) - (u #304559a..[some bytes not shown]..9b#) - ) - (hash sha1 #...[hashvalue]...#) -) - -For padding reasons, random bytes are appended to this list - they can -easily be stripped by looking for the end of the list. - -The hash is calculated on the concatenation of the public key and -secret key parameter lists: i.e it is required to hash the -concatenation of these 6 canonical encoded lists for RSA, including -the parenthesis and the algorithm keyword. - -(rsa - (n #00e0ce9..[some bytes not shown]..51#) - (e #010001#) - (d #046129F..[some bytes not shown]..81#) - (p #00e861b..[some bytes not shown]..f1#) - (q #00f7a7c..[some bytes not shown]..61#) - (u #304559a..[some bytes not shown]..9b#) -) - -After decryption the hash must be recalculated and compared against -the stored one - If they don't match the integrity of the key is not -given. - - -Shadowed Private Key Format -============================ -To keep track of keys stored on IC cards we use a third format for -private kyes which are called shadow keys as they are only a reference -to keys stored on a token: - -(shadowed-private-key - (rsa - (n #00e0ce9..[some bytes not shown]..51#) - (e #010001#) - (shadowed protocol (info)) - ) - (uri http://foo.bar x-foo:whatever_you_want) -) - -The currently used protocol is "ti-v1" (token info version 1). The -second list with the information has this layout: - -(card_serial_number id_string_of_key) - -More items may be added to the list. - - - - - - -Notes: -====== -[1] I usually use the terms private and secret key exchangeable but prefer the -term secret key because it can be visually be better distinguished -from the term public key. - -[2] The keygrip is a unique identifier for a key pair, it is -independent of any protocol, so that the same key can be ised with -different protocols. PKCS-15 calls this a subjectKeyHash; it can be -calculate using Libgcrypt's gcry_pk_get_keygrip(). - -[3] Even when canonical representation are required we will show the -S-expression here in a more readable representation. diff --git a/agent/learncard.c b/agent/learncard.c deleted file mode 100644 index 93229f4cf..000000000 --- a/agent/learncard.c +++ /dev/null @@ -1,380 +0,0 @@ -/* learncard.c - Handle the LEARN command - * Copyright (C) 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include "agent.h" -#include "../assuan/assuan.h" - -struct keypair_info_s { - struct keypair_info_s *next; - int no_cert; - char *id; /* points into grip */ - char hexgrip[1]; -}; -typedef struct keypair_info_s *KEYPAIR_INFO; - -struct kpinfo_cb_parm_s { - int error; - KEYPAIR_INFO info; -}; - - -struct certinfo_s { - struct certinfo_s *next; - int type; - int done; - char id[1]; -}; -typedef struct certinfo_s *CERTINFO; - -struct certinfo_cb_parm_s { - int error; - CERTINFO info; -}; - - -static void -release_keypair_info (KEYPAIR_INFO info) -{ - while (info) - { - KEYPAIR_INFO tmp = info->next; - xfree (info); - info = tmp; - } -} - -static void -release_certinfo (CERTINFO info) -{ - while (info) - { - CERTINFO tmp = info->next; - xfree (info); - info = tmp; - } -} - - - -/* This callback is used by agent_card_leanr and passed the content of - all KEYPAIRINFO lines. It merely stores this data away */ -static void -kpinfo_cb (void *opaque, const char *line) -{ - struct kpinfo_cb_parm_s *parm = opaque; - KEYPAIR_INFO item; - char *p; - - if (parm->error) - return; /* no need to gather data after an error coccured */ - item = xtrycalloc (1, sizeof *item + strlen (line)); - if (!item) - { - parm->error = GNUPG_Out_Of_Core; - return; - } - strcpy (item->hexgrip, line); - for (p = item->hexgrip; hexdigitp (p); p++) - ; - if (p == item->hexgrip && *p == 'X' && spacep (p+1)) - { - item->no_cert = 1; - p++; - } - else if ((p - item->hexgrip) != 40 || !spacep (p)) - { /* not a 20 byte hex keygrip or not followed by a space */ - parm->error = GNUPG_Invalid_Response; - xfree (item); - return; - } - *p++ = 0; - while (spacep (p)) - p++; - item->id = p; - while (*p && !spacep (p)) - p++; - if (p == item->id) - { /* invalid ID string */ - parm->error = GNUPG_Invalid_Response; - xfree (item); - return; - } - *p = 0; /* ignore trailing stuff */ - - /* store it */ - item->next = parm->info; - parm->info = item; -} - - -/* This callback is used by agent_card_leanr and passed the content of - all CERTINFO lines. It merely stores this data away */ -static void -certinfo_cb (void *opaque, const char *line) -{ - struct certinfo_cb_parm_s *parm = opaque; - CERTINFO item; - int type; - char *p, *pend; - - if (parm->error) - return; /* no need to gather data after an error coccured */ - - type = strtol (line, &p, 10); - while (spacep (p)) - p++; - for (pend = p; *pend && !spacep (pend); pend++) - ; - if (p == pend || !*p) - { - parm->error = GNUPG_Invalid_Response; - return; - } - *pend = 0; /* ignore trailing stuff */ - - item = xtrycalloc (1, sizeof *item + strlen (p)); - if (!item) - { - parm->error = GNUPG_Out_Of_Core; - return; - } - item->type = type; - strcpy (item->id, p); - /* store it */ - item->next = parm->info; - parm->info = item; -} - - -/* Create an S-expression with the shadow info. */ -static unsigned char * -make_shadow_info (const char *serialno, const char *idstring) -{ - const char *s; - unsigned char *info, *p; - char numbuf[21]; - int n; - - for (s=serialno, n=0; *s && s[1]; s += 2) - n++; - - info = p = xtrymalloc (1 + 21 + n - + 21 + strlen (idstring) + 1 + 1); - *p++ = '('; - sprintf (numbuf, "%d:", n); - p = stpcpy (p, numbuf); - for (s=serialno; *s && s[1]; s += 2) - *p++ = xtoi_2 (s); - sprintf (numbuf, "%d:", strlen (idstring)); - p = stpcpy (p, numbuf); - p = stpcpy (p, idstring); - *p++ = ')'; - *p = 0; - return info; -} - -static int -send_cert_back (const char *id, void *assuan_context) -{ - int rc; - char *derbuf; - size_t derbuflen; - - rc = agent_card_readcert (id, &derbuf, &derbuflen); - if (rc) - { - log_error ("error reading certificate: %s\n", - gnupg_strerror (rc)); - return rc; - } - - rc = assuan_send_data (assuan_context, derbuf, derbuflen); - xfree (derbuf); - if (!rc) - rc = assuan_send_data (assuan_context, NULL, 0); - if (!rc) - rc = assuan_write_line (assuan_context, "END"); - if (rc) - { - log_error ("sending certificate failed: %s\n", - assuan_strerror (rc)); - return map_assuan_err (rc); - } - return 0; -} - -/* Perform the learn operation. If ASSUAN_CONTEXT is not NULL all new - certificates are send via Assuan */ -int -agent_handle_learn (void *assuan_context) -{ - int rc; - struct kpinfo_cb_parm_s parm; - struct certinfo_cb_parm_s cparm; - char *serialno = NULL; - KEYPAIR_INFO item; - unsigned char grip[20]; - char *p; - int i; - static int certtype_list[] = { - 101, /* trusted */ - 102, /* useful */ - 100, /* regular */ - -1 /* end of list */ - }; - - - memset (&parm, 0, sizeof parm); - memset (&cparm, 0, sizeof cparm); - - /* Check whether a card is present and get the serial number */ - rc = agent_card_serialno (&serialno); - if (rc) - goto leave; - - /* now gather all the availabe info */ - rc = agent_card_learn (kpinfo_cb, &parm, certinfo_cb, &cparm); - if (!rc && (parm.error || cparm.error)) - rc = parm.error? parm.error : cparm.error; - if (rc) - { - log_debug ("agent_card_learn failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - - log_info ("card has S/N: %s\n", serialno); - - /* Write out the certificates in a standard order. */ - for (i=0; certtype_list[i] != -1; i++) - { - CERTINFO citem; - for (citem = cparm.info; citem; citem = citem->next) - { - if (certtype_list[i] != citem->type) - continue; - - if (opt.verbose) - log_info (" id: %s (type=%d)\n", - citem->id, citem->type); - - if (assuan_context) - { - rc = send_cert_back (citem->id, assuan_context); - if (rc) - goto leave; - citem->done = 1; - } - } - } - - for (item = parm.info; item; item = item->next) - { - unsigned char *pubkey, *shdkey; - size_t n; - - if (opt.verbose) - log_info (" id: %s (grip=%s)\n", item->id, item->hexgrip); - - if (item->no_cert) - continue; /* no public key yet available */ - - for (p=item->hexgrip, i=0; i < 20; p += 2, i++) - grip[i] = xtoi_2 (p); - - if (!agent_key_available (grip)) - continue; - - /* unknown - store it */ - rc = agent_card_readkey (item->id, &pubkey); - if (rc) - { - log_debug ("agent_card_readkey failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - - { - unsigned char *shadow_info = make_shadow_info (serialno, item->id); - if (!shadow_info) - { - rc = GNUPG_Out_Of_Core; - xfree (pubkey); - goto leave; - } - rc = agent_shadow_key (pubkey, shadow_info, &shdkey); - xfree (shadow_info); - } - xfree (pubkey); - if (rc) - { - log_error ("shadowing the key failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - n = gcry_sexp_canon_len (shdkey, 0, NULL, NULL); - assert (n); - - rc = agent_write_private_key (grip, shdkey, n, 0); - xfree (shdkey); - if (rc) - { - log_error ("error writing key: %s\n", gnupg_strerror (rc)); - goto leave; - } - - if (opt.verbose) - log_info ("stored\n"); - - if (assuan_context) - { - CERTINFO citem; - - /* only send the certificate if we have not done so before */ - for (citem = cparm.info; citem; citem = citem->next) - { - if (!strcmp (citem->id, item->id)) - break; - } - if (!citem) - { - rc = send_cert_back (item->id, assuan_context); - if (rc) - goto leave; - } - } - } - - - leave: - xfree (serialno); - release_keypair_info (parm.info); - release_certinfo (cparm.info); - return rc; -} - - diff --git a/agent/minip12.c b/agent/minip12.c deleted file mode 100644 index d8d47336c..000000000 --- a/agent/minip12.c +++ /dev/null @@ -1,1146 +0,0 @@ -/* minip12.c - A minilam pkcs-12 implementation. - * Copyright (C) 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 - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include - -#undef TEST - -#ifdef TEST -#include -#include -#include -#endif - -#include "../jnlib/logging.h" -#include "minip12.h" - -#ifndef DIM -#define DIM(v) (sizeof(v)/sizeof((v)[0])) -#endif - -enum -{ - UNIVERSAL = 0, - APPLICATION = 1, - CONTEXT = 2, - PRIVATE = 3 -}; - - -enum -{ - TAG_NONE = 0, - TAG_BOOLEAN = 1, - TAG_INTEGER = 2, - TAG_BIT_STRING = 3, - TAG_OCTET_STRING = 4, - TAG_NULL = 5, - TAG_OBJECT_ID = 6, - TAG_OBJECT_DESCRIPTOR = 7, - TAG_EXTERNAL = 8, - TAG_REAL = 9, - TAG_ENUMERATED = 10, - TAG_EMBEDDED_PDV = 11, - TAG_UTF8_STRING = 12, - TAG_REALTIVE_OID = 13, - TAG_SEQUENCE = 16, - TAG_SET = 17, - TAG_NUMERIC_STRING = 18, - TAG_PRINTABLE_STRING = 19, - TAG_TELETEX_STRING = 20, - TAG_VIDEOTEX_STRING = 21, - TAG_IA5_STRING = 22, - TAG_UTC_TIME = 23, - TAG_GENERALIZED_TIME = 24, - TAG_GRAPHIC_STRING = 25, - TAG_VISIBLE_STRING = 26, - TAG_GENERAL_STRING = 27, - TAG_UNIVERSAL_STRING = 28, - TAG_CHARACTER_STRING = 29, - TAG_BMP_STRING = 30 -}; - - -static unsigned char const oid_data[9] = { - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 }; -static unsigned char const oid_encryptedData[9] = { - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06 }; -static unsigned char const oid_pkcs_12_pkcs_8ShroudedKeyBag[11] = { - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x0A, 0x01, 0x02 }; -static unsigned char const oid_pbeWithSHAAnd3_KeyTripleDES_CBC[10] = { - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03 }; - -static unsigned char const oid_rsaEncryption[9] = { - 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 }; - - -static unsigned char const data_3desiter1024[30] = { - 0x30, 0x1C, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86, - 0xF7, 0x0D, 0x01, 0x0C, 0x01, 0x03, 0x30, 0x0E, - 0x04, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0x02, 0x02, 0x04, 0x00 }; -#define DATA_3DESITER1024_SALT_OFF 18 - - -struct buffer_s -{ - unsigned char *buffer; - size_t length; -}; - - -struct tag_info -{ - int class; - int is_constructed; - unsigned long tag; - unsigned long length; /* length part of the TLV */ - int nhdr; - int ndef; /* It is an indefinite length */ -}; - - -/* Parse the buffer at the address BUFFER which is of SIZE and return - the tag and the length part from the TLV triplet. Update BUFFER - and SIZE on success. */ -static int -parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti) -{ - int c; - unsigned long tag; - const unsigned char *buf = *buffer; - size_t length = *size; - - ti->length = 0; - ti->ndef = 0; - ti->nhdr = 0; - - /* Get the tag */ - if (!length) - return -1; /* premature eof */ - c = *buf++; length--; - ti->nhdr++; - - ti->class = (c & 0xc0) >> 6; - ti->is_constructed = !!(c & 0x20); - tag = c & 0x1f; - - if (tag == 0x1f) - { - tag = 0; - do - { - tag <<= 7; - if (!length) - return -1; /* premature eof */ - c = *buf++; length--; - ti->nhdr++; - tag |= c & 0x7f; - } - while (c & 0x80); - } - ti->tag = tag; - - /* Get the length */ - if (!length) - return -1; /* prematureeof */ - c = *buf++; length--; - ti->nhdr++; - - if ( !(c & 0x80) ) - ti->length = c; - else if (c == 0x80) - ti->ndef = 1; - else if (c == 0xff) - return -1; /* forbidden length value */ - else - { - unsigned long len = 0; - int count = c & 0x7f; - - for (; count; count--) - { - len <<= 8; - if (!length) - return -1; /* premature_eof */ - c = *buf++; length--; - ti->nhdr++; - len |= c & 0xff; - } - ti->length = len; - } - - if (ti->class == UNIVERSAL && !ti->tag) - ti->length = 0; - - if (ti->length > length) - return -1; /* data larger than buffer. */ - - *buffer = buf; - *size = length; - return 0; -} - - -static int -string_to_key (int id, char *salt, int iter, const char *pw, - int req_keylen, unsigned char *keybuf) -{ - int rc, i, j; - GcryMDHd md; - GcryMPI num_b1 = NULL; - int pwlen; - unsigned char hash[20], buf_b[64], buf_i[128], *p; - size_t cur_keylen; - size_t n; - - cur_keylen = 0; - pwlen = strlen (pw); - if (pwlen > 63/2) - { - log_error ("password too long\n"); - return -1; - } - - /* Store salt and password in BUF_I */ - p = buf_i; - for(i=0; i < 64; i++) - *p++ = salt [i%8]; - for(i=j=0; i < 64; i += 2) - { - *p++ = 0; - *p++ = pw[j]; - if (++j > pwlen) /* Note, that we include the trailing zero */ - j = 0; - } - - for (;;) - { - md = gcry_md_open (GCRY_MD_SHA1, 0); - if (!md) - { - log_error ( "gcry_md_open failed: %s\n", gcry_strerror (-1)); - return -1; - } - for(i=0; i < 64; i++) - gcry_md_putc (md, id); - gcry_md_write (md, buf_i, 128); - memcpy (hash, gcry_md_read (md, 0), 20); - gcry_md_close (md); - for (i=1; i < iter; i++) - gcry_md_hash_buffer (GCRY_MD_SHA1, hash, hash, 20); - - for (i=0; i < 20 && cur_keylen < req_keylen; i++) - keybuf[cur_keylen++] = hash[i]; - if (cur_keylen == req_keylen) - { - gcry_mpi_release (num_b1); - return 0; /* ready */ - } - - /* need more bytes. */ - for(i=0; i < 64; i++) - buf_b[i] = hash[i % 20]; - n = 64; - rc = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, &n); - if (rc) - { - log_error ( "gcry_mpi_scan failed: %s\n", gcry_strerror (rc)); - return -1; - } - gcry_mpi_add_ui (num_b1, num_b1, 1); - for (i=0; i < 128; i += 64) - { - GcryMPI num_ij; - - n = 64; - rc = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, &n); - if (rc) - { - log_error ( "gcry_mpi_scan failed: %s\n", - gcry_strerror (rc)); - return -1; - } - gcry_mpi_add (num_ij, num_ij, num_b1); - gcry_mpi_clear_highbit (num_ij, 64*8); - n = 64; - rc = gcry_mpi_print (GCRYMPI_FMT_USG, buf_i + i, &n, num_ij); - if (rc) - { - log_error ( "gcry_mpi_print failed: %s\n", - gcry_strerror (rc)); - return -1; - } - gcry_mpi_release (num_ij); - } - } -} - - -static int -set_key_iv (GcryCipherHd chd, char *salt, int iter, const char *pw) -{ - unsigned char keybuf[24]; - int rc; - - if (string_to_key (1, salt, iter, pw, 24, keybuf)) - return -1; - rc = gcry_cipher_setkey (chd, keybuf, 24); - if (rc) - { - log_error ( "gcry_cipher_setkey failed: %s\n", gcry_strerror (rc)); - return -1; - } - - if (string_to_key (2, salt, iter, pw, 8, keybuf)) - return -1; - rc = gcry_cipher_setiv (chd, keybuf, 8); - if (rc) - { - log_error ("gcry_cipher_setiv failed: %s\n", gcry_strerror (rc)); - return -1; - } - return 0; -} - - -static void -crypt_block (unsigned char *buffer, size_t length, char *salt, int iter, - const char *pw, int encrypt) -{ - GcryCipherHd chd; - int rc; - - chd = gcry_cipher_open (GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0); - if (!chd) - { - log_error ( "gcry_cipher_open failed: %s\n", gcry_strerror(-1)); - return; - } - if (set_key_iv (chd, salt, iter, pw)) - goto leave; - - rc = encrypt? gcry_cipher_encrypt (chd, buffer, length, NULL, 0) - : gcry_cipher_decrypt (chd, buffer, length, NULL, 0); - - if (rc) - { - log_error ( "en/de-crytion failed: %s\n", gcry_strerror (rc)); - goto leave; - } - -/* { */ -/* FILE *fp = fopen("inner.der", "wb"); */ -/* fwrite (buffer, 1, length, fp); */ -/* fclose (fp); */ -/* } */ - - leave: - gcry_cipher_close (chd); -} - - - - -static int -parse_bag_encrypted_data (const unsigned char *buffer, size_t length, - int startoffset) -{ - struct tag_info ti; - const unsigned char *p = buffer; - size_t n = length; - const char *where; - - where = "start"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class != CONTEXT || ti.tag) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.tag != TAG_SEQUENCE) - goto bailout; - - where = "bag.encryptedData.version"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 0) - goto bailout; - p++; n--; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.tag != TAG_SEQUENCE) - goto bailout; - - where = "bag.encryptedData.data"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data) - || memcmp (p, oid_data, DIM(oid_data))) - goto bailout; - p += DIM(oid_data); - n -= DIM(oid_data); - - /* fixme: continue parsing */ - - return 0; - bailout: - log_error ("encrptedData error at \"%s\", offset %u\n", - where, (p - buffer)+startoffset); - return -1; -} - -static GcryMPI * -parse_bag_data (const unsigned char *buffer, size_t length, int startoffset, - const char *pw) -{ - int rc; - struct tag_info ti; - const unsigned char *p = buffer; - size_t n = length; - const char *where; - char salt[8]; - unsigned int iter; - int len; - unsigned char *plain = NULL; - GcryMPI *result = NULL; - int result_count, i; - - where = "start"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class != CONTEXT || ti.tag) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_OCTET_STRING) - goto bailout; - - where = "data.outerseqs"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - - where = "data.objectidentifier"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_OBJECT_ID - || ti.length != DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag) - || memcmp (p, oid_pkcs_12_pkcs_8ShroudedKeyBag, - DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag))) - goto bailout; - p += DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag); - n -= DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag); - - where = "shrouded,outerseqs"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class != CONTEXT || ti.tag) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_OBJECT_ID - || ti.length != DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC) - || memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC, - DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC))) - goto bailout; - p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC); - n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC); - - where = "3des-params"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_OCTET_STRING || ti.length != 8 ) - goto bailout; - memcpy (salt, p, 8); - p += 8; - n -= 8; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_INTEGER || !ti.length ) - goto bailout; - for (iter=0; ti.length; ti.length--) - { - iter <<= 8; - iter |= (*p++) & 0xff; - n--; - } - - where = "3des-ciphertext"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_OCTET_STRING || !ti.length ) - goto bailout; - - log_info ("%lu bytes of 3DES encrypted text\n", ti.length); - - plain = gcry_malloc_secure (ti.length); - if (!plain) - { - log_error ("error allocating decryption buffer\n"); - goto bailout; - } - memcpy (plain, p, ti.length); - crypt_block (plain, ti.length, salt, iter, pw, 0); - n = ti.length; - startoffset = 0; - buffer = p = plain; - - where = "decrypted-text"; - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER - || ti.length != 1 || *p) - goto bailout; - p++; n--; - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - len = ti.length; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (len < ti.nhdr) - goto bailout; - len -= ti.nhdr; - if (ti.class || ti.tag != TAG_OBJECT_ID - || ti.length != DIM(oid_rsaEncryption) - || memcmp (p, oid_rsaEncryption, - DIM(oid_rsaEncryption))) - goto bailout; - p += DIM (oid_rsaEncryption); - n -= DIM (oid_rsaEncryption); - if (len < ti.length) - goto bailout; - len -= ti.length; - if (n < len) - goto bailout; - p += len; - n -= len; - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_OCTET_STRING) - goto bailout; - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - len = ti.length; - - result = gcry_calloc (10, sizeof *result); - if (!result) - { - log_error ( "error allocating result array\n"); - goto bailout; - } - result_count = 0; - - where = "reading.key-parameters"; - for (result_count=0; len && result_count < 9;) - { - int dummy_n; - - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER) - goto bailout; - if (len < ti.nhdr) - goto bailout; - len -= ti.nhdr; - if (len < ti.length) - goto bailout; - len -= ti.length; - dummy_n = ti.length; - if (!result_count && ti.length == 1 && !*p) - ; /* ignore the very first one if it is a 0 */ - else - { - rc = gcry_mpi_scan (result+result_count, GCRYMPI_FMT_USG, p, - &dummy_n); - if (rc) - { - log_error ("error parsing key parameter: %s\n", - gcry_strerror (rc)); - goto bailout; - } - result_count++; - } - p += ti.length; - n -= ti.length; - } - if (len) - goto bailout; - - return result; - - bailout: - gcry_free (plain); - if (result) - { - for (i=0; result[i]; i++) - gcry_mpi_release (result[i]); - gcry_free (result); - } - log_error ( "data error at \"%s\", offset %u\n", - where, (p - buffer) + startoffset); - return NULL; -} - - -/* Parse a PKCS12 object and return an array of MPI representing the - secret key parameters. This is a very limited inplementation in - that it is only able to look for 3DES encoded enctyptedData and - tries to extract the first private key object it finds. In case of - an error NULL is returned. */ -GcryMPI * -p12_parse (const unsigned char *buffer, size_t length, const char *pw) -{ - struct tag_info ti; - const unsigned char *p = buffer; - size_t n = length; - const char *where; - int bagseqlength, len; - - where = "pfx"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.tag != TAG_SEQUENCE) - goto bailout; - - where = "pfxVersion"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 3) - goto bailout; - p++; n--; - - where = "authSave"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data) - || memcmp (p, oid_data, DIM(oid_data))) - goto bailout; - p += DIM(oid_data); - n -= DIM(oid_data); - - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class != CONTEXT || ti.tag) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class != UNIVERSAL || ti.tag != TAG_OCTET_STRING) - goto bailout; - - where = "bags"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE) - goto bailout; - bagseqlength = ti.length; - while (bagseqlength) - { - /*log_debug ( "at offset %u\n", (p - buffer));*/ - where = "bag-sequence"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class != UNIVERSAL || ti.tag != TAG_SEQUENCE) - goto bailout; - - if (bagseqlength < ti.nhdr) - goto bailout; - bagseqlength -= ti.nhdr; - if (bagseqlength < ti.length) - goto bailout; - bagseqlength -= ti.length; - len = ti.length; - - if (parse_tag (&p, &n, &ti)) - goto bailout; - len -= ti.nhdr; - if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_encryptedData) - && !memcmp (p, oid_encryptedData, DIM(oid_encryptedData))) - { - p += DIM(oid_encryptedData); - n -= DIM(oid_encryptedData); - len -= DIM(oid_encryptedData); - where = "bag.encryptedData"; - if (parse_bag_encrypted_data (p, n, (p - buffer))) - goto bailout; - } - else if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_data) - && !memcmp (p, oid_data, DIM(oid_data))) - { - p += DIM(oid_data); - n -= DIM(oid_data); - len -= DIM(oid_data); - return parse_bag_data (p, n, (p-buffer), pw); - } - else - log_info ( "unknown bag type - skipped\n"); - - if (len < 0 || len > n) - goto bailout; - p += len; - n -= len; - } - - return NULL; - bailout: - log_error ("error at \"%s\", offset %u\n", where, (p - buffer)); - return NULL; -} - - - -static size_t -compute_tag_length (size_t n) -{ - int needed = 0; - - if (n < 128) - needed += 2; /* tag and one length byte */ - else if (n < 256) - needed += 3; /* tag, number of length bytes, 1 length byte */ - else if (n < 65536) - needed += 4; /* tag, number of length bytes, 2 length bytes */ - else - { - log_error ("object too larger to encode\n"); - return 0; - } - return needed; -} - -static unsigned char * -store_tag_length (unsigned char *p, int tag, size_t n) -{ - if (tag == TAG_SEQUENCE) - tag |= 0x20; /* constructed */ - - *p++ = tag; - if (n < 128) - *p++ = n; - else if (n < 256) - { - *p++ = 0x81; - *p++ = n; - } - else if (n < 65536) - { - *p++ = 0x82; - *p++ = n >> 8; - *p++ = n; - } - - return p; -} - - -/* Create the final PKCS-12 object from the sequences contained in - SEQLIST. That array is terminated with an NULL object */ -static unsigned char * -create_final (struct buffer_s *sequences, size_t *r_length) -{ - int i; - size_t needed = 0; - size_t n, outseqlen, notsooutseqlen, out0taglen, octstrlen, inseqlen; - unsigned char *result, *p; - size_t resultlen; - - for (i=0; sequences[i].buffer; i++) - needed += sequences[i].length; - /* This goes into a sequences. */ - inseqlen = needed; - n = compute_tag_length (needed); - needed += n; - /* And encapsulate all in an octet string. */ - octstrlen = needed; - n = compute_tag_length (needed); - needed += n; - /* And tag it with [0]. */ - out0taglen = needed; - n = compute_tag_length (needed); - needed += n; - /* Prepend an data OID. */ - needed += 2 + DIM (oid_data); - /* This all into a sequences. */ - notsooutseqlen = needed; - n = compute_tag_length (needed); - needed += n; - /* Prepend the version integer 3. */ - needed += 3; - /* And the final sequence. */ - outseqlen = needed; - n = compute_tag_length (needed); - needed += n; - - result = gcry_malloc (needed); - if (!result) - { - log_error ("error allocating buffer\n"); - return NULL; - } - p = result; - - /* Store the very outer sequence. */ - p = store_tag_length (p, TAG_SEQUENCE, outseqlen); - /* Store the version integer 3. */ - *p++ = TAG_INTEGER; - *p++ = 1; - *p++ = 3; - /* Store another sequence. */ - p = store_tag_length (p, TAG_SEQUENCE, notsooutseqlen); - /* Store the data OID. */ - p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data)); - memcpy (p, oid_data, DIM (oid_data)); - p += DIM (oid_data); - /* Next comes a context tag. */ - p = store_tag_length (p, 0xa0, out0taglen); - /* And an octet string. */ - p = store_tag_length (p, TAG_OCTET_STRING, octstrlen); - /* And the inner sequence. */ - p = store_tag_length (p, TAG_SEQUENCE, inseqlen); - /* And append all the buffers. */ - for (i=0; sequences[i].buffer; i++) - { - memcpy (p, sequences[i].buffer, sequences[i].length); - p += sequences[i].length; - } - - /* Ready. */ - resultlen = p - result; - if (needed != resultlen) - log_debug ("length mismatch: %u, %u\n", needed, resultlen); - - *r_length = resultlen; - return result; -} - - -/* Expect the RSA key parameters in KPARMS and a password in - PW. Create a PKCS structure from it and return it as well as the - length in R_LENGTH; return NULL in case of an error. */ -unsigned char * -p12_build (GcryMPI *kparms, const char *pw, size_t *r_length) -{ - int rc, i; - size_t needed, n; - unsigned char *plain, *p, *cipher; - size_t plainlen, cipherlen; - size_t outseqlen, oidseqlen, octstrlen, inseqlen; - size_t out0taglen, in0taglen, outoctstrlen; - size_t aseq1len, aseq2len, aseq3len; - char salt[8]; - - needed = 3; /* The version(?) integer of value 0. */ - for (i=0; kparms[i]; i++) - { - n = 0; - rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, &n, kparms[i]); - if (rc) - { - log_error ("error formatting parameter: %s\n", gcry_strerror (rc)); - return NULL; - } - needed += n; - n = compute_tag_length (n); - if (!n) - return NULL; - needed += n; - } - if (i != 8) - { - log_error ("invalid paramters for p12_build\n"); - return NULL; - } - /* Now this all goes into a sequence. */ - inseqlen = needed; - n = compute_tag_length (needed); - if (!n) - return NULL; - needed += n; - /* Encapsulate all into an octet string. */ - octstrlen = needed; - n = compute_tag_length (needed); - if (!n) - return NULL; - needed += n; - /* Prepend the object identifier sequence. */ - oidseqlen = 2 + DIM (oid_rsaEncryption) + 2; - needed += 2 + oidseqlen; - /* The version number. */ - needed += 3; - /* And finally put the whole thing into a sequence. */ - outseqlen = needed; - n = compute_tag_length (needed); - if (!n) - return NULL; - needed += n; - - /* allocate 8 extra bytes for padding */ - plain = gcry_malloc_secure (needed+8); - if (!plain) - { - log_error ("error allocating encryption buffer\n"); - return NULL; - } - - /* And now fill the plaintext buffer. */ - p = plain; - p = store_tag_length (p, TAG_SEQUENCE, outseqlen); - /* Store version. */ - *p++ = TAG_INTEGER; - *p++ = 1; - *p++ = 0; - /* Store object identifier sequence. */ - p = store_tag_length (p, TAG_SEQUENCE, oidseqlen); - p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_rsaEncryption)); - memcpy (p, oid_rsaEncryption, DIM (oid_rsaEncryption)); - p += DIM (oid_rsaEncryption); - *p++ = TAG_NULL; - *p++ = 0; - /* Start with the octet string. */ - p = store_tag_length (p, TAG_OCTET_STRING, octstrlen); - p = store_tag_length (p, TAG_SEQUENCE, inseqlen); - /* Store the key parameters. */ - *p++ = TAG_INTEGER; - *p++ = 1; - *p++ = 0; - for (i=0; kparms[i]; i++) - { - n = 0; - rc = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, &n, kparms[i]); - if (rc) - { - log_error ("oops: error formatting parameter: %s\n", - gcry_strerror (rc)); - gcry_free (plain); - return NULL; - } - p = store_tag_length (p, TAG_INTEGER, n); - - n = plain + needed - p; - rc = gcry_mpi_print (GCRYMPI_FMT_STD, p, &n, kparms[i]); - if (rc) - { - log_error ("oops: error storing parameter: %s\n", - gcry_strerror (rc)); - gcry_free (plain); - return NULL; - } - p += n; - } - - plainlen = p - plain; - assert (needed == plainlen); - /* Append some pad characters; we already allocated extra space. */ - n = 8 - plainlen % 8; - for (;(plainlen % 8); plainlen++) - *p++ = n; - - { - FILE *fp = fopen("inner-out.der", "wb"); - fwrite (plain, 1, plainlen, fp); - fclose (fp); - } - - - /* Encrypt it and prepend a lot of stupid things. */ - gcry_randomize (salt, 8, GCRY_STRONG_RANDOM); - crypt_block (plain, plainlen, salt, 1024, pw, 1); - /* the data goes into an octet string. */ - needed = compute_tag_length (plainlen); - needed += plainlen; - /* we prepend the the algorithm identifier (we use a pre-encoded one)*/ - needed += DIM (data_3desiter1024); - /* we put a sequence around. */ - aseq3len = needed; - needed += compute_tag_length (needed); - /* Prepend it with a [0] tag. */ - in0taglen = needed; - needed += compute_tag_length (needed); - /* Prepend that shroudedKeyBag OID. */ - needed += 2 + DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag); - /* Put it all into two sequence. */ - aseq2len = needed; - needed += compute_tag_length ( needed); - aseq1len = needed; - needed += compute_tag_length (needed); - /* This all goes into an octet string. */ - outoctstrlen = needed; - needed += compute_tag_length (needed); - /* Prepend it with a [0] tag. */ - out0taglen = needed; - needed += compute_tag_length (needed); - /* Prepend the data OID. */ - needed += 2 + DIM (oid_data); - /* And a sequence. */ - outseqlen = needed; - needed += compute_tag_length (needed); - - cipher = gcry_malloc (needed); - if (!cipher) - { - log_error ("error allocating buffer\n"); - gcry_free (plain); - return NULL; - } - p = cipher; - /* Store the first sequence. */ - p = store_tag_length (p, TAG_SEQUENCE, outseqlen); - /* Store the data OID. */ - p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_data)); - memcpy (p, oid_data, DIM (oid_data)); - p += DIM (oid_data); - /* Next comes a context tag. */ - p = store_tag_length (p, 0xa0, out0taglen); - /* And an octet string. */ - p = store_tag_length (p, TAG_OCTET_STRING, outoctstrlen); - /* Two sequences. */ - p = store_tag_length (p, TAG_SEQUENCE, aseq1len); - p = store_tag_length (p, TAG_SEQUENCE, aseq2len); - /* Store the shroudedKeyBag OID. */ - p = store_tag_length (p, TAG_OBJECT_ID, - DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag)); - memcpy (p, oid_pkcs_12_pkcs_8ShroudedKeyBag, - DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag)); - p += DIM (oid_pkcs_12_pkcs_8ShroudedKeyBag); - /* Next comes a context tag. */ - p = store_tag_length (p, 0xa0, in0taglen); - /* And a sequence. */ - p = store_tag_length (p, TAG_SEQUENCE, aseq3len); - /* Now for the pre-encoded algorithm indentifier and the salt. */ - memcpy (p, data_3desiter1024, DIM (data_3desiter1024)); - memcpy (p + DATA_3DESITER1024_SALT_OFF, salt, 8); - p += DIM (data_3desiter1024); - /* And finally the octet string with the encrypted data. */ - p = store_tag_length (p, TAG_OCTET_STRING, plainlen); - memcpy (p, plain, plainlen); - p += plainlen; - cipherlen = p - cipher; - - if (needed != cipherlen) - log_debug ("length mismatch: %u, %u\n", needed, cipherlen); - gcry_free (plain); - - { - struct buffer_s seqlist[2]; - - seqlist[0].buffer = cipher; - seqlist[0].length = cipherlen; - seqlist[1].buffer = NULL; - seqlist[1].length = 0; - - cipher = create_final (seqlist, &cipherlen); - gcry_free (seqlist[0].buffer); - } - - *r_length = cipherlen; - return cipher; -} - - -#ifdef TEST -int -main (int argc, char **argv) -{ - FILE *fp; - struct stat st; - char *buf; - size_t buflen; - GcryMPI *result; - - if (argc != 3) - { - fprintf (stderr, "usage: testp12 file passphrase\n"); - return 1; - } - - gcry_control (GCRYCTL_DISABLE_SECMEM, NULL); - gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL); - - fp = fopen (argv[1], "rb"); - if (!fp) - { - fprintf (stderr, "can't open `%s': %s\n", argv[1], strerror (errno)); - return 1; - } - - if (fstat (fileno(fp), &st)) - { - fprintf (stderr, "can't stat `%s': %s\n", argv[1], strerror (errno)); - return 1; - } - - buflen = st.st_size; - buf = gcry_malloc (buflen+1); - if (!buf || fread (buf, buflen, 1, fp) != 1) - { - fprintf (stderr, "error reading `%s': %s\n", argv[1], strerror (errno)); - return 1; - } - fclose (fp); - - result = p12_parse (buf, buflen, argv[2]); - if (result) - { - int i, rc; - char *buf; - - for (i=0; result[i]; i++) - { - rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, (void**)&buf, - NULL, result[i]); - if (rc) - printf ("%d: [error printing number: %s]\n", - i, gcry_strerror (rc)); - else - { - printf ("%d: %s\n", i, buf); - gcry_free (buf); - } - } - } - - return 0; - -} -#endif /* TEST */ diff --git a/agent/minip12.h b/agent/minip12.h deleted file mode 100644 index 8573a2db0..000000000 --- a/agent/minip12.h +++ /dev/null @@ -1,32 +0,0 @@ -/* minip12.h - Global definitions for the minimal pkcs-12 implementation. - * Copyright (C) 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 MINIP12_H -#define MINIP12_H - -#include - -GcryMPI *p12_parse (const unsigned char *buffer, size_t length, - const char *pw); - -unsigned char *p12_build (GcryMPI *kparms, const char *pw, size_t *r_length); - - -#endif /*MINIP12_H*/ diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c deleted file mode 100644 index 6add3d467..000000000 --- a/agent/pkdecrypt.c +++ /dev/null @@ -1,138 +0,0 @@ -/* pkdecrypt.c - public key decryption (well, acually using a secret key) - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "agent.h" - - -/* DECRYPT the stuff in ciphertext which is expected to be a S-Exp. - Try to get the key from CTRL and write the decoded stuff back to - OUTFP. */ -int -agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen, - FILE *outfp) -{ - GCRY_SEXP s_skey = NULL, s_cipher = NULL, s_plain = NULL; - unsigned char *shadow_info = NULL; - int rc; - char *buf = NULL; - size_t len; - - if (!ctrl->have_keygrip) - { - log_error ("speculative decryption not yet supported\n"); - rc = seterr (No_Secret_Key); - goto leave; - } - - rc = gcry_sexp_sscan (&s_cipher, NULL, ciphertext, ciphertextlen); - if (rc) - { - log_error ("failed to convert ciphertext: %s\n", gcry_strerror (rc)); - rc = seterr (Invalid_Data); - goto leave; - } - - if (DBG_CRYPTO) - { - log_printhex ("keygrip:", ctrl->keygrip, 20); - log_printhex ("cipher: ", ciphertext, ciphertextlen); - } - s_skey = agent_key_from_file (ctrl->keygrip, &shadow_info, 0); - if (!s_skey && !shadow_info) - { - log_error ("failed to read the secret key\n"); - rc = seterr (No_Secret_Key); - goto leave; - } - - if (!s_skey) - { /* divert operation to the smartcard */ - - if (!gcry_sexp_canon_len (ciphertext, ciphertextlen, NULL, NULL)) - { - rc = GNUPG_Invalid_Sexp; - goto leave; - } - - rc = divert_pkdecrypt (ciphertext, shadow_info, &buf, &len ); - if (rc) - { - log_error ("smartcard decryption failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - /* FIXME: don't use buffering and change the protocol to return - a complete S-expression and not just a part. */ - fprintf (outfp, "%u:", (unsigned int)len); - fwrite (buf, 1, len, outfp); - putc (0, outfp); - } - else - { /* no smartcard, but a private key */ - if (DBG_CRYPTO) - { - log_debug ("skey: "); - gcry_sexp_dump (s_skey); - } - - rc = gcry_pk_decrypt (&s_plain, s_cipher, s_skey); - if (rc) - { - log_error ("decryption failed: %s\n", gcry_strerror (rc)); - rc = map_gcry_err (rc); - goto leave; - } - - if (DBG_CRYPTO) - { - log_debug ("plain: "); - gcry_sexp_dump (s_plain); - } - len = gcry_sexp_sprint (s_plain, GCRYSEXP_FMT_CANON, NULL, 0); - assert (len); - buf = xmalloc (len); - len = gcry_sexp_sprint (s_plain, GCRYSEXP_FMT_CANON, buf, len); - assert (len); - /* FIXME: we must make sure that no buffering takes place or we are - in full control of the buffer memory (easy to do) - should go - into assuan. */ - fwrite (buf, 1, len, outfp); - } - - - leave: - gcry_sexp_release (s_skey); - gcry_sexp_release (s_plain); - gcry_sexp_release (s_cipher); - xfree (buf); - xfree (shadow_info); - return rc; -} - - diff --git a/agent/pksign.c b/agent/pksign.c deleted file mode 100644 index 2acc63dd9..000000000 --- a/agent/pksign.c +++ /dev/null @@ -1,183 +0,0 @@ -/* pksign.c - public key signing (well, acually using a secret key) - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "agent.h" - - -static int -do_encode_md (const unsigned char *digest, size_t digestlen, int algo, - unsigned int nbits, GCRY_MPI *r_val) -{ - int nframe = (nbits+7) / 8; - byte *frame; - int i, n; - byte asn[100]; - size_t asnlen; - - asnlen = DIM(asn); - if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen)) - { - log_error ("no object identifier for algo %d\n", algo); - return GNUPG_Internal_Error; - } - - if (digestlen + asnlen + 4 > nframe ) - { - log_error ("can't encode a %d bit MD into a %d bits frame\n", - (int)(digestlen*8), (int)nbits); - return GNUPG_Internal_Error; - } - - /* We encode the MD in this way: - * - * 0 1 PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes) - * - * PAD consists of FF bytes. - */ - frame = xtrymalloc (nframe); - if (!frame) - return GNUPG_Out_Of_Core; - n = 0; - frame[n++] = 0; - frame[n++] = 1; /* block type */ - i = nframe - digestlen - 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, digest, digestlen ); n += digestlen; - assert ( n == nframe ); - if (DBG_CRYPTO) - log_printhex ("encoded hash:", frame, nframe); - - gcry_mpi_scan (r_val, GCRYMPI_FMT_USG, frame, &nframe); - xfree (frame); - return 0; -} - - -/* SIGN whatever information we have accumulated in CTRL and write it - back to OUTFP. */ -int -agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache) -{ - GCRY_SEXP s_skey = NULL, s_hash = NULL, s_sig = NULL; - GCRY_MPI frame = NULL; - unsigned char *shadow_info = NULL; - int rc; - char *buf = NULL; - size_t len; - - if (!ctrl->have_keygrip) - return seterr (No_Secret_Key); - - s_skey = agent_key_from_file (ctrl->keygrip, &shadow_info, ignore_cache); - if (!s_skey && !shadow_info) - { - log_error ("failed to read the secret key\n"); - rc = seterr (No_Secret_Key); - goto leave; - } - - if (!s_skey) - { /* divert operation to the smartcard */ - unsigned char *sigbuf; - - rc = divert_pksign (ctrl->digest.value, - ctrl->digest.valuelen, - ctrl->digest.algo, - shadow_info, &sigbuf); - if (rc) - { - log_error ("smartcard signing failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - len = gcry_sexp_canon_len (sigbuf, 0, NULL, NULL); - assert (len); - buf = sigbuf; - } - else - { /* no smartcard, but a private key */ - - /* put the hash into a sexp */ - rc = do_encode_md (ctrl->digest.value, - ctrl->digest.valuelen, - ctrl->digest.algo, - gcry_pk_get_nbits (s_skey), - &frame); - if (rc) - goto leave; - if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) ) - BUG (); - - if (DBG_CRYPTO) - { - log_debug ("skey: "); - gcry_sexp_dump (s_skey); - } - - /* sign */ - rc = gcry_pk_sign (&s_sig, s_hash, s_skey); - if (rc) - { - log_error ("signing failed: %s\n", gcry_strerror (rc)); - rc = map_gcry_err (rc); - goto leave; - } - - if (DBG_CRYPTO) - { - log_debug ("result: "); - gcry_sexp_dump (s_sig); - } - - len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, NULL, 0); - assert (len); - buf = xmalloc (len); - len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, buf, len); - assert (len); - } - - /* FIXME: we must make sure that no buffering takes place or we are - in full control of the buffer memory (easy to do) - should go - into assuan. */ - fwrite (buf, 1, len, outfp); - - leave: - gcry_sexp_release (s_skey); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_sig); - gcry_mpi_release (frame); - xfree (buf); - xfree (shadow_info); - return rc; -} - - diff --git a/agent/protect-tool.c b/agent/protect-tool.c deleted file mode 100644 index 1d706ea2b..000000000 --- a/agent/protect-tool.c +++ /dev/null @@ -1,977 +0,0 @@ -/* protect-tool.c - A tool to test the secret key protection - * Copyright (C) 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define JNLIB_NEED_LOG_LOGV -#include "agent.h" -#include "minip12.h" -#include "simple-pwquery.h" -#include "i18n.h" - -enum cmd_and_opt_values -{ aNull = 0, - oVerbose = 'v', - oArmor = 'a', - oPassphrase = 'P', - - oProtect = 'p', - oUnprotect = 'u', - - oNoVerbose = 500, - oShadow, - oShowShadowInfo, - oShowKeygrip, - - oP12Import, - oP12Export, - oStore, - oForce, - -aTest }; - -struct rsa_secret_key_s - { - MPI n; /* public modulus */ - MPI e; /* public exponent */ - MPI d; /* exponent */ - MPI p; /* prime p. */ - MPI q; /* prime q. */ - MPI u; /* inverse of p mod q. */ - }; - - -static int opt_armor; -static int opt_store; -static int opt_force; -static const char *passphrase; - -static const char *get_passphrase (void); -static int store_private_key (const unsigned char *grip, - const void *buffer, size_t length, int force); - - -static ARGPARSE_OPTS opts[] = { - - { 301, NULL, 0, N_("@Options:\n ") }, - - { oVerbose, "verbose", 0, "verbose" }, - { oArmor, "armor", 0, "write output in advanced format" }, - { oPassphrase, "passphrase", 2, "|STRING|use passphrase STRING" }, - { oProtect, "protect", 256, "protect a private key"}, - { oUnprotect, "unprotect", 256, "unprotect a private key"}, - { oShadow, "shadow", 256, "create a shadow entry for a priblic key"}, - { oShowShadowInfo, "show-shadow-info", 256, "return the shadow info"}, - { oShowKeygrip, "show-keygrip", 256, "show the \"keygrip\""}, - - { oP12Import, "p12-import", 256, "import a PKCS-12 encoded private key"}, - { oP12Export, "p12-export", 256, "export a private key PKCS-12 encoded"}, - { oStore, "store", 0, "store the created key in the appropriate place"}, - { oForce, "force", 0, "force overwriting"}, - {0} -}; - -static const char * -my_strusage (int level) -{ - const char *p; - switch (level) - { - case 11: p = "gpg-protect-tool (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; - case 1: - case 40: p = _("Usage: gpg-protect-tool [options] (-h for help)\n"); - break; - case 41: p = _("Syntax: gpg-protect-tool [options] [args]]\n" - "Secret key maintenance tool\n"); - break; - - default: p = NULL; - } - return p; -} - - - -static void -i18n_init (void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file( PACKAGE ); -#else -#ifdef ENABLE_NLS - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); -#endif -#endif -} - - - -/* Used by gcry for logging */ -static void -my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) -{ - /* translate the log levels */ - switch (level) - { - case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break; - case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break; - case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break; - case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break; - case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break; - case GCRY_LOG_BUG: level = JNLIB_LOG_BUG; break; - case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break; - default: level = JNLIB_LOG_ERROR; break; } - log_logv (level, fmt, arg_ptr); -} - - -/* static void */ -/* print_mpi (const char *text, GcryMPI a) */ -/* { */ -/* char *buf; */ -/* void *bufaddr = &buf; */ -/* int rc; */ - -/* rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); */ -/* if (rc) */ -/* log_info ("%s: [error printing number: %s]\n", text, gcry_strerror (rc)); */ -/* else */ -/* { */ -/* log_info ("%s: %s\n", text, buf); */ -/* gcry_free (buf); */ -/* } */ -/* } */ - - - -static unsigned char * -make_canonical (const char *fname, const char *buf, size_t buflen) -{ - int rc; - size_t erroff, len; - GCRY_SEXP sexp; - unsigned char *result; - - rc = gcry_sexp_sscan (&sexp, &erroff, buf, buflen); - if (rc) - { - log_error ("invalid S-Expression in `%s' (off=%u): %s\n", - fname, (unsigned int)erroff, gcry_strerror (rc)); - return NULL; - } - len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0); - assert (len); - result = xmalloc (len); - len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, result, len); - assert (len); - gcry_sexp_release (sexp); - return result; -} - -static char * -make_advanced (const unsigned char *buf, size_t buflen) -{ - int rc; - size_t erroff, len; - GCRY_SEXP sexp; - unsigned char *result; - - rc = gcry_sexp_sscan (&sexp, &erroff, buf, buflen); - if (rc) - { - log_error ("invalid canonical S-Expression (off=%u): %s\n", - (unsigned int)erroff, gcry_strerror (rc)); - return NULL; - } - len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0); - assert (len); - result = xmalloc (len); - len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, result, len); - assert (len); - gcry_sexp_release (sexp); - return result; -} - - -static char * -read_file (const char *fname, size_t *r_length) -{ - FILE *fp; - struct stat st; - char *buf; - size_t buflen; - - fp = fopen (fname, "rb"); - if (!fp) - { - log_error ("can't open `%s': %s\n", fname, strerror (errno)); - return NULL; - } - - if (fstat (fileno(fp), &st)) - { - log_error ("can't stat `%s': %s\n", fname, strerror (errno)); - fclose (fp); - return NULL; - } - - buflen = st.st_size; - buf = xmalloc (buflen+1); - if (fread (buf, buflen, 1, fp) != 1) - { - log_error ("error reading `%s': %s\n", fname, strerror (errno)); - fclose (fp); - xfree (buf); - return NULL; - } - fclose (fp); - - *r_length = buflen; - return buf; -} - - -static unsigned char * -read_key (const char *fname) -{ - char *buf; - size_t buflen; - unsigned char *key; - - buf = read_file (fname, &buflen); - key = make_canonical (fname, buf, buflen); - xfree (buf); - return key; -} - - - -static void -read_and_protect (const char *fname) -{ - int rc; - unsigned char *key; - unsigned char *result; - size_t resultlen; - - key = read_key (fname); - if (!key) - return; - - rc = agent_protect (key, get_passphrase (), &result, &resultlen); - xfree (key); - if (rc) - { - log_error ("protecting the key failed: %s\n", gnupg_strerror (rc)); - return; - } - - if (opt_armor) - { - char *p = make_advanced (result, resultlen); - xfree (result); - if (!p) - return; - result = p; - resultlen = strlen (p); - } - - fwrite (result, resultlen, 1, stdout); - xfree (result); -} - - -static void -read_and_unprotect (const char *fname) -{ - int rc; - unsigned char *key; - unsigned char *result; - size_t resultlen; - - key = read_key (fname); - if (!key) - return; - - rc = agent_unprotect (key, get_passphrase (), &result, &resultlen); - xfree (key); - if (rc) - { - log_error ("unprotecting the key failed: %s\n", gnupg_strerror (rc)); - return; - } - - if (opt_armor) - { - char *p = make_advanced (result, resultlen); - xfree (result); - if (!p) - return; - result = p; - resultlen = strlen (p); - } - - fwrite (result, resultlen, 1, stdout); - xfree (result); -} - - - -static void -read_and_shadow (const char *fname) -{ - int rc; - unsigned char *key; - unsigned char *result; - size_t resultlen; - - key = read_key (fname); - if (!key) - return; - - rc = agent_shadow_key (key, "(8:313233342:43)", &result); - xfree (key); - if (rc) - { - log_error ("shadowing the key failed: %s\n", gnupg_strerror (rc)); - return; - } - resultlen = gcry_sexp_canon_len (result, 0, NULL,NULL); - assert (resultlen); - - if (opt_armor) - { - char *p = make_advanced (result, resultlen); - xfree (result); - if (!p) - return; - result = p; - resultlen = strlen (p); - } - - fwrite (result, resultlen, 1, stdout); - xfree (result); -} - -static void -show_shadow_info (const char *fname) -{ - int rc; - unsigned char *key; - const unsigned char *info; - size_t infolen; - - key = read_key (fname); - if (!key) - return; - - rc = agent_get_shadow_info (key, &info); - xfree (key); - if (rc) - { - log_error ("get_shadow_info failed: %s\n", gnupg_strerror (rc)); - return; - } - infolen = gcry_sexp_canon_len (info, 0, NULL,NULL); - assert (infolen); - - if (opt_armor) - { - char *p = make_advanced (info, infolen); - if (!p) - return; - fwrite (p, strlen (p), 1, stdout); - xfree (p); - } - else - fwrite (info, infolen, 1, stdout); -} - - -static void -show_file (const char *fname) -{ - unsigned char *key; - size_t keylen; - char *p; - - key = read_key (fname); - if (!key) - return; - - keylen = gcry_sexp_canon_len (key, 0, NULL,NULL); - assert (keylen); - - p = make_advanced (key, keylen); - xfree (key); - if (p) - { - fwrite (p, strlen (p), 1, stdout); - xfree (p); - } -} - -static void -show_keygrip (const char *fname) -{ - unsigned char *key; - GcrySexp private; - unsigned char grip[20]; - int i; - - key = read_key (fname); - if (!key) - return; - - if (gcry_sexp_new (&private, key, 0, 0)) - { - log_error ("gcry_sexp_new failed\n"); - return; - } - xfree (key); - - if (!gcry_pk_get_keygrip (private, grip)) - { - log_error ("can't calculate keygrip\n"); - return; - } - gcry_sexp_release (private); - - for (i=0; i < 20; i++) - printf ("%02X", grip[i]); - putchar ('\n'); -} - - -static int -rsa_key_check (struct rsa_secret_key_s *skey) -{ - int err = 0; - MPI t = gcry_mpi_snew (0); - MPI t1 = gcry_mpi_snew (0); - MPI t2 = gcry_mpi_snew (0); - MPI phi = gcry_mpi_snew (0); - - /* check that n == p * q */ - gcry_mpi_mul (t, skey->p, skey->q); - if (gcry_mpi_cmp( t, skey->n) ) - { - log_error ("RSA oops: n != p * q\n"); - err++; - } - - /* check that p is less than q */ - if (gcry_mpi_cmp (skey->p, skey->q) > 0) - { - GcryMPI tmp; - - log_info ("swapping secret primes\n"); - tmp = gcry_mpi_copy (skey->p); - gcry_mpi_set (skey->p, skey->q); - gcry_mpi_set (skey->q, tmp); - gcry_mpi_release (tmp); - /* and must recompute u of course */ - gcry_mpi_invm (skey->u, skey->p, skey->q); - } - - /* check that e divides neither p-1 nor q-1 */ - gcry_mpi_sub_ui (t, skey->p, 1 ); - gcry_mpi_div (NULL, t, t, skey->e, 0); - if (!gcry_mpi_cmp_ui( t, 0) ) - { - log_error ("RSA oops: e divides p-1\n"); - err++; - } - gcry_mpi_sub_ui (t, skey->q, 1); - gcry_mpi_div (NULL, t, t, skey->e, 0); - if (!gcry_mpi_cmp_ui( t, 0)) - { - log_info ( "RSA oops: e divides q-1\n" ); - err++; - } - - /* check that d is correct. */ - gcry_mpi_sub_ui (t1, skey->p, 1); - gcry_mpi_sub_ui (t2, skey->q, 1); - gcry_mpi_mul (phi, t1, t2); - gcry_mpi_invm (t, skey->e, phi); - if (gcry_mpi_cmp (t, skey->d)) - { /* no: try universal exponent. */ - gcry_mpi_gcd (t, t1, t2); - gcry_mpi_div (t, NULL, phi, t, 0); - gcry_mpi_invm (t, skey->e, t); - if (gcry_mpi_cmp (t, skey->d)) - { - log_error ("RSA oops: bad secret exponent\n"); - err++; - } - } - - /* check for correctness of u */ - gcry_mpi_invm (t, skey->p, skey->q); - if (gcry_mpi_cmp (t, skey->u)) - { - log_info ( "RSA oops: bad u parameter\n"); - err++; - } - - if (err) - log_info ("RSA secret key check failed\n"); - - gcry_mpi_release (t); - gcry_mpi_release (t1); - gcry_mpi_release (t2); - gcry_mpi_release (phi); - - return err? -1:0; -} - - -static void -import_p12_file (const char *fname) -{ - char *buf; - unsigned char *result; - size_t buflen, resultlen; - int i; - int rc; - GcryMPI *kparms; - struct rsa_secret_key_s sk; - GcrySexp s_key; - unsigned char *key; - unsigned char grip[20]; - - /* fixme: we should release some stuff on error */ - - buf = read_file (fname, &buflen); - if (!buf) - return; - - kparms = p12_parse (buf, buflen, get_passphrase ()); - xfree (buf); - if (!kparms) - { - log_error ("error parsing or decrypting the PKCS-1 file\n"); - return; - } - for (i=0; kparms[i]; i++) - ; - if (i != 8) - { - log_error ("invalid structure of private key\n"); - return; - } - - -/* print_mpi (" n", kparms[0]); */ -/* print_mpi (" e", kparms[1]); */ -/* print_mpi (" d", kparms[2]); */ -/* print_mpi (" p", kparms[3]); */ -/* print_mpi (" q", kparms[4]); */ -/* print_mpi ("dmp1", kparms[5]); */ -/* print_mpi ("dmq1", kparms[6]); */ -/* print_mpi (" u", kparms[7]); */ - - sk.n = kparms[0]; - sk.e = kparms[1]; - sk.d = kparms[2]; - sk.q = kparms[3]; - sk.p = kparms[4]; - sk.u = kparms[7]; - if (rsa_key_check (&sk)) - return; -/* print_mpi (" n", sk.n); */ -/* print_mpi (" e", sk.e); */ -/* print_mpi (" d", sk.d); */ -/* print_mpi (" p", sk.p); */ -/* print_mpi (" q", sk.q); */ -/* print_mpi (" u", sk.u); */ - - /* Create an S-expresion from the parameters. */ - rc = gcry_sexp_build (&s_key, NULL, - "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", - sk.n, sk.e, sk.d, sk.p, sk.q, sk.u, NULL); - for (i=0; i < 8; i++) - gcry_mpi_release (kparms[i]); - gcry_free (kparms); - if (rc) - { - log_error ("failed to created S-expression from key: %s\n", - gcry_strerror (rc)); - return; - } - - /* Compute the keygrip. */ - if (!gcry_pk_get_keygrip (s_key, grip)) - { - log_error ("can't calculate keygrip\n"); - return; - } - log_info ("keygrip: "); - for (i=0; i < 20; i++) - log_printf ("%02X", grip[i]); - log_printf ("\n"); - - /* convert to canonical encoding */ - buflen = gcry_sexp_sprint (s_key, GCRYSEXP_FMT_CANON, NULL, 0); - assert (buflen); - key = gcry_xmalloc_secure (buflen); - buflen = gcry_sexp_sprint (s_key, GCRYSEXP_FMT_CANON, key, buflen); - assert (buflen); - gcry_sexp_release (s_key); - - - rc = agent_protect (key, get_passphrase (), &result, &resultlen); - xfree (key); - if (rc) - { - log_error ("protecting the key failed: %s\n", gnupg_strerror (rc)); - return; - } - - if (opt_armor) - { - char *p = make_advanced (result, resultlen); - xfree (result); - if (!p) - return; - result = p; - resultlen = strlen (p); - } - - if (opt_store) - store_private_key (grip, result, resultlen, opt_force); - else - fwrite (result, resultlen, 1, stdout); - - xfree (result); -} - - - -static GcryMPI * -sexp_to_kparms (GCRY_SEXP sexp) -{ - GcrySexp list, l2; - const char *name; - const char *s; - size_t n; - int i, idx; - const char *elems; - GcryMPI *array; - - list = gcry_sexp_find_token (sexp, "private-key", 0 ); - if(!list) - return NULL; - l2 = gcry_sexp_cadr (list); - gcry_sexp_release (list); - list = l2; - name = gcry_sexp_nth_data (list, 0, &n); - if(!name || n != 3 || memcmp (name, "rsa", 3)) - { - gcry_sexp_release (list); - return NULL; - } - - /* Paramter names used with RSA. */ - elems = "nedpqu"; - array = xcalloc (strlen(elems) + 1, sizeof *array); - for (idx=0, s=elems; *s; s++, idx++ ) - { - l2 = gcry_sexp_find_token (list, s, 1); - if (!l2) - { - for (i=0; i -#include -#include -#include -#include -#include -#include -#include -#include - -#include "agent.h" - -#include "sexp-parse.h" - -#define PROT_CIPHER GCRY_CIPHER_AES -#define PROT_CIPHER_STRING "aes" -#define PROT_CIPHER_KEYLEN (128/8) - - -/* A table containing the information needed to create a protected - private key */ -static struct { - const char *algo; - const char *parmlist; - int prot_from, prot_to; -} protect_info[] = { - { "rsa", "nedpqu", 2, 5 }, - { NULL } -}; - - -static int -hash_passphrase (const char *passphrase, int hashalgo, - int s2kmode, - const unsigned char *s2ksalt, unsigned long s2kcount, - unsigned char *key, size_t keylen); - - - -/* Calculate the MIC for a private key S-Exp. SHA1HASH should pint to - a 20 byte buffer. This function is suitable for any algorithms. */ -static int -calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash) -{ - const unsigned char *hash_begin, *hash_end; - const unsigned char *s; - size_t n; - - s = plainkey; - if (*s != '(') - return GNUPG_Invalid_Sexp; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - if (!smatch (&s, n, "private-key")) - return GNUPG_Unknown_Sexp; - if (*s != '(') - return GNUPG_Unknown_Sexp; - hash_begin = s; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - s += n; /* skip over the algorithm name */ - - while (*s == '(') - { - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - s += n; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - s += n; - if ( *s != ')' ) - return GNUPG_Invalid_Sexp; - s++; - } - if (*s != ')') - return GNUPG_Invalid_Sexp; - s++; - hash_end = s; - - gcry_md_hash_buffer (GCRY_MD_SHA1, sha1hash, - hash_begin, hash_end - hash_begin); - - return 0; -} - - - -/* Encrypt the parameter block starting at PROTBEGIN with length - PROTLEN using the utf8 encoded key PASSPHRASE and return the entire - encrypted block in RESULT or ereturn with an error code. SHA1HASH - is the 20 byte SHA-1 hash required for the integrity code. - - The parameter block is expected to be an incomplete S-Expression of - the form (example in advanced format): - - (d #046129F..[some bytes not shown]..81#) - (p #00e861b..[some bytes not shown]..f1#) - (q #00f7a7c..[some bytes not shown]..61#) - (u #304559a..[some bytes not shown]..9b#) - - the returned block is the S-Expression: - - (protected mode (parms) encrypted_octet_string) - -*/ -static int -do_encryption (const char *protbegin, size_t protlen, - const char *passphrase, const unsigned char *sha1hash, - unsigned char **result, size_t *resultlen) -{ - GCRY_CIPHER_HD hd; - const char *modestr = "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc"; - int blklen, enclen, outlen; - char *iv = NULL; - int rc = 0; - char *outbuf = NULL; - char *p; - int saltpos, ivpos, encpos; - - hd = gcry_cipher_open (PROT_CIPHER, GCRY_CIPHER_MODE_CBC, - GCRY_CIPHER_SECURE); - if (!hd) - return map_gcry_err (gcry_errno()); - - - /* We need to work on a copy of the data because this makes it - easier to add the trailer and the padding and more important we - have to prefix the text with 2 parenthesis, so we have to - allocate enough space for: - - (()(4:hash4:sha120:)) + padding - - We always append a full block of random bytes as padding but - encrypt only what is needed for a full blocksize */ - blklen = gcry_cipher_get_algo_blklen (PROT_CIPHER); - outlen = 2 + protlen + 2 + 6 + 6 + 23 + 2 + blklen; - enclen = outlen/blklen * blklen; - outbuf = gcry_malloc_secure (outlen); - if (!outbuf) - rc = GNUPG_Out_Of_Core; - if (!rc) - { - /* allocate random bytes to be used as IV, padding and s2k salt*/ - iv = gcry_random_bytes (blklen*2+8, GCRY_WEAK_RANDOM); - if (!iv) - rc = GNUPG_Out_Of_Core; - else - rc = gcry_cipher_setiv (hd, iv, blklen); - } - if (!rc) - { - unsigned char *key; - size_t keylen = PROT_CIPHER_KEYLEN; - - key = gcry_malloc_secure (keylen); - if (!key) - rc = GNUPG_Out_Of_Core; - else - { - rc = hash_passphrase (passphrase, GCRY_MD_SHA1, - 3, iv+2*blklen, 96, key, keylen); - if (!rc) - rc = gcry_cipher_setkey (hd, key, keylen); - xfree (key); - } - } - if (!rc) - { - p = outbuf; - *p++ = '('; - *p++ = '('; - memcpy (p, protbegin, protlen); - p += protlen; - memcpy (p, ")(4:hash4:sha120:", 17); - p += 17; - memcpy (p, sha1hash, 20); - p += 20; - *p++ = ')'; - *p++ = ')'; - memcpy (p, iv+blklen, blklen); - p += blklen; - assert ( p - outbuf == outlen); - rc = gcry_cipher_encrypt (hd, outbuf, enclen, NULL, 0); - } - gcry_cipher_close (hd); - if (rc) - { - xfree (iv); - xfree (outbuf); - return rc; - } - - /* Now allocate the buffer we want to return. This is - - (protected openpgp-s2k3-sha1-aes-cbc - ((sha1 salt no_of_iterations) 16byte_iv) - encrypted_octet_string) - - in canoncical format of course. We use asprintf and %n modifier - and spaces as palceholders. */ - asprintf (&p, - "(9:protected%d:%s((4:sha18:%n_8bytes_2:96)%d:%n%*s)%d:%n%*s)", - (int)strlen (modestr), modestr, - &saltpos, - blklen, &ivpos, blklen, "", - enclen, &encpos, enclen, ""); - if (p) - { /* asprintf does not use out malloc system */ - char *psave = p; - p = xtrymalloc (strlen (psave)+1); - if (p) - strcpy (p, psave); - free (psave); - } - if (!p) - { - xfree (iv); - xfree (outbuf); - return GNUPG_Out_Of_Core; - } - *resultlen = strlen (p); - *result = p; - memcpy (p+saltpos, iv+2*blklen, 8); - memcpy (p+ivpos, iv, blklen); - memcpy (p+encpos, outbuf, enclen); - xfree (iv); - xfree (outbuf); - return 0; -} - - - -/* Protect the key encoded in canonical format in plainkey. We assume - a valid S-Exp here. */ -int -agent_protect (const unsigned char *plainkey, const char *passphrase, - unsigned char **result, size_t *resultlen) -{ - int rc; - const unsigned char *s; - const unsigned char *hash_begin, *hash_end; - const unsigned char *prot_begin, *prot_end, *real_end; - size_t n; - int c, infidx, i; - unsigned char hashvalue[20]; - unsigned char *protected; - size_t protectedlen; - int depth = 0; - unsigned char *p; - - s = plainkey; - if (*s != '(') - return GNUPG_Invalid_Sexp; - depth++; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - if (!smatch (&s, n, "private-key")) - return GNUPG_Unknown_Sexp; - if (*s != '(') - return GNUPG_Unknown_Sexp; - depth++; - hash_begin = s; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - - for (infidx=0; protect_info[infidx].algo - && !smatch (&s, n, protect_info[infidx].algo); infidx++) - ; - if (!protect_info[infidx].algo) - return GNUPG_Unsupported_Algorithm; - - prot_begin = prot_end = NULL; - for (i=0; (c=protect_info[infidx].parmlist[i]); i++) - { - if (i == protect_info[infidx].prot_from) - prot_begin = s; - if (*s != '(') - return GNUPG_Invalid_Sexp; - depth++; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - if (n != 1 || c != *s) - return GNUPG_Invalid_Sexp; - s += n; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - s +=n; /* skip value */ - if (*s != ')') - return GNUPG_Invalid_Sexp; - depth--; - if (i == protect_info[infidx].prot_to) - prot_end = s; - s++; - } - if (*s != ')' || !prot_begin || !prot_end ) - return GNUPG_Invalid_Sexp; - depth--; - hash_end = s; - s++; - /* skip to the end of the S-exp */ - assert (depth == 1); - rc = sskip (&s, &depth); - if (rc) - return rc; - assert (!depth); - real_end = s-1; - - gcry_md_hash_buffer (GCRY_MD_SHA1, hashvalue, - hash_begin, hash_end - hash_begin + 1); - - rc = do_encryption (prot_begin, prot_end - prot_begin + 1, - passphrase, hashvalue, - &protected, &protectedlen); - if (rc) - return rc; - - /* Now create the protected version of the key. Note that the 10 - extra bytes are for for the inserted "protected-" string (the - beginning of the plaintext reads: "((11:private-key(" ). */ - *resultlen = (10 - + (prot_begin-plainkey) - + protectedlen - + (real_end-prot_end)); - *result = p = xtrymalloc (*resultlen); - if (!p) - { - xfree (protected); - return GNUPG_Out_Of_Core; - } - memcpy (p, "(21:protected-", 14); - p += 14; - memcpy (p, plainkey+4, prot_begin - plainkey - 4); - p += prot_begin - plainkey - 4; - memcpy (p, protected, protectedlen); - p += protectedlen; - memcpy (p, prot_end+1, real_end - prot_end); - p += real_end - prot_end; - assert ( p - *result == *resultlen); - xfree (protected); - return 0; -} - - -/* Do the actual decryption and check the return list for consistency. */ -static int -do_decryption (const unsigned char *protected, size_t protectedlen, - const char *passphrase, - const unsigned char *s2ksalt, unsigned long s2kcount, - const unsigned char *iv, size_t ivlen, - unsigned char **result) -{ - int rc = 0; - int blklen; - GCRY_CIPHER_HD hd; - unsigned char *outbuf; - size_t reallen; - - blklen = gcry_cipher_get_algo_blklen (PROT_CIPHER); - if (protectedlen < 4 || (protectedlen%blklen)) - return GNUPG_Corrupted_Protection; - - hd = gcry_cipher_open (PROT_CIPHER, GCRY_CIPHER_MODE_CBC, - GCRY_CIPHER_SECURE); - if (!hd) - return map_gcry_err (gcry_errno()); - - outbuf = gcry_malloc_secure (protectedlen); - if (!outbuf) - rc = GNUPG_Out_Of_Core; - if (!rc) - rc = gcry_cipher_setiv (hd, iv, ivlen); - if (!rc) - { - unsigned char *key; - size_t keylen = PROT_CIPHER_KEYLEN; - - key = gcry_malloc_secure (keylen); - if (!key) - rc = GNUPG_Out_Of_Core; - else - { - rc = hash_passphrase (passphrase, GCRY_MD_SHA1, - 3, s2ksalt, s2kcount, key, keylen); - if (!rc) - rc = gcry_cipher_setkey (hd, key, keylen); - xfree (key); - } - } - if (!rc) - rc = gcry_cipher_decrypt (hd, outbuf, protectedlen, - protected, protectedlen); - gcry_cipher_close (hd); - if (rc) - { - xfree (outbuf); - return rc; - } - /* do a quick check first */ - if (*outbuf != '(' && outbuf[1] != '(') - { - xfree (outbuf); - return GNUPG_Bad_Passphrase; - } - /* check that we have a consistent S-Exp */ - reallen = gcry_sexp_canon_len (outbuf, protectedlen, NULL, NULL); - if (!reallen || (reallen + blklen < protectedlen) ) - { - xfree (outbuf); - return GNUPG_Bad_Passphrase; - } - *result = outbuf; - return 0; -} - - -/* Merge the parameter list contained in CLEARTEXT with the original - protect lists PROTECTEDKEY by replacing the list at REPLACEPOS. - Return the new list in RESULT and the MIC value in the 20 byte - buffer SHA1HASH. */ -static int -merge_lists (const unsigned char *protectedkey, - size_t replacepos, - const unsigned char *cleartext, - unsigned char *sha1hash, unsigned char **result) -{ - size_t n, newlistlen; - unsigned char *newlist, *p; - const unsigned char *s; - const unsigned char *startpos, *endpos; - int i, rc; - - if (replacepos < 26) - return GNUPG_Bug; - - /* Estimate the required size of the resulting list. We have a large - safety margin of >20 bytes (MIC hash from CLEARTEXT and the - removed "protected-" */ - newlistlen = gcry_sexp_canon_len (protectedkey, 0, NULL, NULL); - if (!newlistlen) - return GNUPG_Bug; - n = gcry_sexp_canon_len (cleartext, 0, NULL, NULL); - if (!n) - return GNUPG_Bug; - newlistlen += n; - newlist = gcry_malloc_secure (newlistlen); - if (!newlist) - return GNUPG_Out_Of_Core; - - /* Copy the initial segment */ - strcpy (newlist, "(11:private-key"); - p = newlist + 15; - memcpy (p, protectedkey+15+10, replacepos-15-10); - p += replacepos-15-10; - - /* copy the cleartext */ - s = cleartext; - if (*s != '(' && s[1] != '(') - return GNUPG_Bug; /*we already checked this */ - s += 2; - startpos = s; - while ( *s == '(' ) - { - s++; - n = snext (&s); - if (!n) - goto invalid_sexp; - s += n; - n = snext (&s); - if (!n) - goto invalid_sexp; - s += n; - if ( *s != ')' ) - goto invalid_sexp; - s++; - } - if ( *s != ')' ) - goto invalid_sexp; - endpos = s; - s++; - /* short intermezzo: Get the MIC */ - if (*s != '(') - goto invalid_sexp; - s++; - n = snext (&s); - if (!smatch (&s, n, "hash")) - goto invalid_sexp; - n = snext (&s); - if (!smatch (&s, n, "sha1")) - goto invalid_sexp; - n = snext (&s); - if (n != 20) - goto invalid_sexp; - memcpy (sha1hash, s, 20); - s += n; - if (*s != ')') - goto invalid_sexp; - /* end intermezzo */ - - /* append the parameter list */ - memcpy (p, startpos, endpos - startpos); - p += endpos - startpos; - - /* skip overt the protected list element in the original list */ - s = protectedkey + replacepos; - assert (*s == '('); - s++; - i = 1; - rc = sskip (&s, &i); - if (rc) - goto failure; - startpos = s; - i = 2; /* we are inside this level */ - rc = sskip (&s, &i); - if (rc) - goto failure; - assert (s[-1] == ')'); - endpos = s; /* one behind the end of the list */ - - /* append the rest */ - memcpy (p, startpos, endpos - startpos); - p += endpos - startpos; - - /* ready */ - *result = newlist; - return 0; - - failure: - xfree (newlist); - return rc; - - invalid_sexp: - xfree (newlist); - return GNUPG_Invalid_Sexp; -} - - - -/* Unprotect the key encoded in canonical format. We assume a valid - S-Exp here. */ -int -agent_unprotect (const unsigned char *protectedkey, const char *passphrase, - unsigned char **result, size_t *resultlen) -{ - int rc; - const unsigned char *s; - size_t n; - int infidx, i; - unsigned char sha1hash[20], sha1hash2[20]; - const unsigned char *s2ksalt; - unsigned long s2kcount; - const unsigned char *iv; - const unsigned char *prot_begin; - unsigned char *cleartext; - unsigned char *final; - - s = protectedkey; - if (*s != '(') - return GNUPG_Invalid_Sexp; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - if (!smatch (&s, n, "protected-private-key")) - return GNUPG_Unknown_Sexp; - if (*s != '(') - return GNUPG_Unknown_Sexp; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - - for (infidx=0; protect_info[infidx].algo - && !smatch (&s, n, protect_info[infidx].algo); infidx++) - ; - if (!protect_info[infidx].algo) - return GNUPG_Unsupported_Algorithm; - - /* now find the list with the protected information. Here is an - example for such a list: - (protected openpgp-s2k3-sha1-aes-cbc - ((sha1 ) ) - ) - */ - for (;;) - { - if (*s != '(') - return GNUPG_Invalid_Sexp; - prot_begin = s; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - if (smatch (&s, n, "protected")) - break; - s += n; - i = 1; - rc = sskip (&s, &i); - if (rc) - return rc; - } - /* found */ - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - if (!smatch (&s, n, "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc")) - return GNUPG_Unsupported_Protection; - if (*s != '(' || s[1] != '(') - return GNUPG_Invalid_Sexp; - s += 2; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - if (!smatch (&s, n, "sha1")) - return GNUPG_Unsupported_Protection; - n = snext (&s); - if (n != 8) - return GNUPG_Corrupted_Protection; - s2ksalt = s; - s += n; - n = snext (&s); - if (!n) - return GNUPG_Corrupted_Protection; - /* We expect a list close as next, so we can simply use strtoul() - here. We might want to check that we only have digits - but this - is nothing we should worry about */ - if (s[n] != ')' ) - return GNUPG_Invalid_Sexp; - s2kcount = strtoul (s, NULL, 10); - if (!s2kcount) - return GNUPG_Corrupted_Protection; - s += n; - s++; /* skip list end */ - - n = snext (&s); - if (n != 16) /* Wrong blocksize for IV (we support ony aes-128) */ - return GNUPG_Corrupted_Protection; - iv = s; - s += n; - if (*s != ')' ) - return GNUPG_Invalid_Sexp; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - - rc = do_decryption (s, n, - passphrase, s2ksalt, s2kcount, - iv, 16, - &cleartext); - if (rc) - return rc; - - rc = merge_lists (protectedkey, prot_begin-protectedkey, cleartext, - sha1hash, &final); - xfree (cleartext); - if (rc) - return rc; - - rc = calculate_mic (final, sha1hash2); - if (!rc && memcmp (sha1hash, sha1hash2, 20)) - rc = GNUPG_Corrupted_Protection; - if (rc) - { - xfree (final); - return rc; - } - - *result = final; - *resultlen = gcry_sexp_canon_len (final, 0, NULL, NULL); - return 0; -} - -/* Check the type of the private key, this is one of the constants: - PRIVATE_KEY_UNKNOWN if we can't figure out the type (this is the - value 0), PRIVATE_KEY_CLEAR for an unprotected private key. - PRIVATE_KEY_PROTECTED for an protected private key or - PRIVATE_KEY_SHADOWED for a sub key where the secret parts are stored - elsewhere. */ -int -agent_private_key_type (const unsigned char *privatekey) -{ - const unsigned char *s; - size_t n; - - s = privatekey; - if (*s != '(') - return PRIVATE_KEY_UNKNOWN; - s++; - n = snext (&s); - if (!n) - return PRIVATE_KEY_UNKNOWN; - if (smatch (&s, n, "protected-private-key")) - return PRIVATE_KEY_PROTECTED; - if (smatch (&s, n, "shadowed-private-key")) - return PRIVATE_KEY_SHADOWED; - if (smatch (&s, n, "private-key")) - return PRIVATE_KEY_CLEAR; - return PRIVATE_KEY_UNKNOWN; -} - - - -/* Transform a passphrase into a suitable key of length KEYLEN and - store this key in the caller provided buffer KEY. The caller must - provide an HASHALGO, a valid S2KMODE (see rfc-2440) and depending on - that mode an S2KSALT of 8 random bytes and an S2KCOUNT (a suitable - value is 96). - - Returns an error code on failure. */ -static int -hash_passphrase (const char *passphrase, int hashalgo, - int s2kmode, - const unsigned char *s2ksalt, - unsigned long s2kcount, - unsigned char *key, size_t keylen) -{ - GCRY_MD_HD md; - int pass, i; - int used = 0; - int pwlen = strlen (passphrase); - - if ( (s2kmode != 0 && s2kmode != 1 && s2kmode != 3) - || !hashalgo || !keylen || !key || !passphrase) - return GNUPG_Invalid_Value; - if ((s2kmode == 1 ||s2kmode == 3) && !s2ksalt) - return GNUPG_Invalid_Value; - - md = gcry_md_open (hashalgo, GCRY_MD_FLAG_SECURE); - if (!md) - return map_gcry_err (gcry_errno()); - - for (pass=0; used < keylen; pass++) - { - if (pass) - { - gcry_md_reset (md); - for (i=0; i < pass; i++) /* preset the hash context */ - gcry_md_putc (md, 0); - } - - if (s2kmode == 1 || s2kmode == 3) - { - int len2 = pwlen + 8; - unsigned long count = len2; - - if (s2kmode == 3) - { - count = (16ul + (s2kcount & 15)) << ((s2kcount >> 4) + 6); - if (count < len2) - count = len2; - } - - while (count > len2) - { - gcry_md_write (md, s2ksalt, 8); - gcry_md_write (md, passphrase, pwlen); - count -= len2; - } - if (count < 8) - gcry_md_write (md, s2ksalt, count); - else - { - gcry_md_write (md, s2ksalt, 8); - count -= 8; - gcry_md_write (md, passphrase, count); - } - } - else - gcry_md_write (md, passphrase, pwlen); - - gcry_md_final (md); - i = gcry_md_get_algo_dlen (hashalgo); - if (i > keylen - used) - i = keylen - used; - memcpy (key+used, gcry_md_read (md, hashalgo), i); - used += i; - } - gcry_md_close(md); - return 0; -} - - - -/* Create a shadow key from a public key. We use the shadow protocol - "ti-v1" and insert the S-expressionn SHADOW_INFO. The resulting - S-expression is returned in an allocated buffer RESULT will point - to. The input parameters are expected to be valid canonilized - S-expressions */ -int -agent_shadow_key (const unsigned char *pubkey, - const unsigned char *shadow_info, - unsigned char **result) -{ - const unsigned char *s; - const unsigned char *point; - size_t n; - int depth = 0; - unsigned char *p; - size_t pubkey_len = gcry_sexp_canon_len (pubkey, 0, NULL,NULL); - size_t shadow_info_len = gcry_sexp_canon_len (shadow_info, 0, NULL,NULL); - - if (!pubkey_len || !shadow_info_len) - return GNUPG_Invalid_Value; - s = pubkey; - if (*s != '(') - return GNUPG_Invalid_Sexp; - depth++; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - if (!smatch (&s, n, "public-key")) - return GNUPG_Unknown_Sexp; - if (*s != '(') - return GNUPG_Unknown_Sexp; - depth++; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - s += n; /* skip over the algorithm name */ - - while (*s != ')') - { - if (*s != '(') - return GNUPG_Invalid_Sexp; - depth++; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - s += n; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - s +=n; /* skip value */ - if (*s != ')') - return GNUPG_Invalid_Sexp; - depth--; - s++; - } - point = s; /* insert right before the point */ - depth--; - s++; - assert (depth == 1); - - /* calculate required length by taking in account: the "shadowed-" - prefix, the "shadowed", "t1-v1" as well as some parenthesis */ - n = 12 + pubkey_len + 1 + 3+8 + 2+5 + shadow_info_len + 1; - *result = p = xtrymalloc (n); - if (!p) - return GNUPG_Out_Of_Core; - p = stpcpy (p, "(20:shadowed-private-key"); - /* (10:public-key ...)*/ - memcpy (p, pubkey+14, point - (pubkey+14)); - p += point - (pubkey+14); - p = stpcpy (p, "(8:shadowed5:t1-v1"); - memcpy (p, shadow_info, shadow_info_len); - p += shadow_info_len; - *p++ = ')'; - memcpy (p, point, pubkey_len - (point - pubkey)); - p += pubkey_len - (point - pubkey); - - return 0; -} - -/* Parse a canonical encoded shadowed key and return a pointer to the - inner list with the shadow_info */ -int -agent_get_shadow_info (const unsigned char *shadowkey, - unsigned char const **shadow_info) -{ - const unsigned char *s; - size_t n; - int depth = 0; - - s = shadowkey; - if (*s != '(') - return GNUPG_Invalid_Sexp; - depth++; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - if (!smatch (&s, n, "shadowed-private-key")) - return GNUPG_Unknown_Sexp; - if (*s != '(') - return GNUPG_Unknown_Sexp; - depth++; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - s += n; /* skip over the algorithm name */ - - for (;;) - { - if (*s == ')') - return GNUPG_Unknown_Sexp; - if (*s != '(') - return GNUPG_Invalid_Sexp; - depth++; - s++; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - if (smatch (&s, n, "shadowed")) - break; - s += n; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - s +=n; /* skip value */ - if (*s != ')') - return GNUPG_Invalid_Sexp; - depth--; - s++; - } - /* found the shadowed list, s points to the protocol */ - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - if (smatch (&s, n, "t1-v1")) - { - if (*s != '(') - return GNUPG_Invalid_Sexp; - *shadow_info = s; - } - else - return GNUPG_Unsupported_Protocol; - return 0; -} - diff --git a/agent/query.c b/agent/query.c deleted file mode 100644 index c461a55ce..000000000 --- a/agent/query.c +++ /dev/null @@ -1,460 +0,0 @@ -/* query.c - fork of the pinentry to query stuff from the user - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef USE_GNU_PTH -# include -#endif - -#include "agent.h" -#include "i18n.h" -#include "../assuan/assuan.h" - -#ifdef _POSIX_OPEN_MAX -#define MAX_OPEN_FDS _POSIX_OPEN_MAX -#else -#define MAX_OPEN_FDS 20 -#endif - -static ASSUAN_CONTEXT entry_ctx = NULL; -#ifdef USE_GNU_PTH -static pth_mutex_t entry_lock = PTH_MUTEX_INIT; -#endif - -/* data to be passed to our callbacks */ -struct entry_parm_s { - int lines; - size_t size; - char *buffer; -}; - - - - -static int -unlock_pinentry (int rc) -{ -#ifdef USE_GNU_PTH - if (!pth_mutex_release (&entry_lock)) - { - log_error ("failed to release the entry lock\n"); - if (!rc) - rc = GNUPG_Internal_Error; - } -#endif - return rc; -} - -/* Fork off the pin entry if this has not already been done. Note, - that this function must always be used to aquire the lock for the - pinentry - we will serialize _all_ pinentry calls. - */ -static int -start_pinentry (void) -{ - int rc; - const char *pgmname; - ASSUAN_CONTEXT ctx; - const char *argv[5]; - int no_close_list[3]; - int i; - -#ifdef USE_GNU_PTH - if (!pth_mutex_acquire (&entry_lock, 0, NULL)) - { - log_error ("failed to acquire the entry lock\n"); - return GNUPG_Internal_Error; - } -#endif - - if (entry_ctx) - return 0; - - if (opt.verbose) - log_info ("no running PIN Entry - starting it\n"); - - if (fflush (NULL)) - { - log_error ("error flushing pending output: %s\n", strerror (errno)); - return unlock_pinentry (seterr (Write_Error)); - } - - if (!opt.pinentry_program || !*opt.pinentry_program) - opt.pinentry_program = GNUPG_DEFAULT_PINENTRY; - if ( !(pgmname = strrchr (opt.pinentry_program, '/'))) - pgmname = opt.pinentry_program; - else - pgmname++; - - /* FIXME: We must do this thread specific */ - argv[0] = pgmname; - if (opt.display) - { - argv[1] = "--display"; - argv[2] = opt.display; - argv[3] = NULL; - } - else - argv[1] = NULL; - - i=0; - if (!opt.running_detached) - { - 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 pinentry and perform initial handshaking */ - rc = assuan_pipe_connect (&ctx, opt.pinentry_program, (char**)argv, - no_close_list); - if (rc) - { - log_error ("can't connect to the PIN entry module: %s\n", - assuan_strerror (rc)); - return unlock_pinentry (seterr (No_PIN_Entry)); - } - entry_ctx = ctx; - - if (DBG_ASSUAN) - log_debug ("connection to PIN entry established\n"); - - rc = assuan_transact (entry_ctx, - opt.no_grab? "OPTION no-grab":"OPTION grab", - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (map_assuan_err (rc)); - if (opt.ttyname) - { - char *optstr; - if (asprintf (&optstr, "OPTION ttyname=%s", opt.ttyname) < 0 ) - return unlock_pinentry (GNUPG_Out_Of_Core); - rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return unlock_pinentry (map_assuan_err (rc)); - } - if (opt.ttytype) - { - char *optstr; - if (asprintf (&optstr, "OPTION ttytype=%s", opt.ttytype) < 0 ) - return unlock_pinentry (GNUPG_Out_Of_Core); - rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - if (rc) - return unlock_pinentry (map_assuan_err (rc)); - } - if (opt.lc_ctype) - { - char *optstr; - if (asprintf (&optstr, "OPTION lc-ctype=%s", opt.lc_ctype) < 0 ) - return unlock_pinentry (GNUPG_Out_Of_Core); - rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - if (rc) - return unlock_pinentry (map_assuan_err (rc)); - } - if (opt.lc_messages) - { - char *optstr; - if (asprintf (&optstr, "OPTION lc-messages=%s", opt.lc_messages) < 0 ) - return unlock_pinentry (GNUPG_Out_Of_Core); - rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - if (rc) - return unlock_pinentry (map_assuan_err (rc)); - } - return 0; -} - - -static AssuanError -getpin_cb (void *opaque, const void *buffer, size_t length) -{ - struct entry_parm_s *parm = opaque; - - if (!buffer) - return 0; - - /* we expect the pin to fit on one line */ - if (parm->lines || length >= parm->size) - return ASSUAN_Too_Much_Data; - - /* fixme: we should make sure that the assuan buffer is allocated in - secure memory or read the response byte by byte */ - memcpy (parm->buffer, buffer, length); - parm->buffer[length] = 0; - parm->lines++; - return 0; -} - - -static int -all_digitsp( const char *s) -{ - for (; *s && *s >= '0' && *s <= '9'; s++) - ; - return !*s; -} - - - -/* Call the Entry and ask for the PIN. We do check for a valid PIN - number here and repeat it as long as we have invalid formed - numbers. */ -int -agent_askpin (const char *desc_text, struct pin_entry_info_s *pininfo) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - struct entry_parm_s parm; - const char *errtext = NULL; - int is_pin = 0; - - if (opt.batch) - return 0; /* fixme: we should return BAD PIN */ - - if (!pininfo || pininfo->max_length < 1) - return seterr (Invalid_Value); - if (!desc_text && pininfo->min_digits) - desc_text = _("Please enter your PIN, so that the secret key " - "can be unlocked for this session"); - else if (!desc_text) - desc_text = _("Please enter your passphrase, so that the secret key " - "can be unlocked for this session"); - - is_pin = desc_text && strstr (desc_text, "PIN"); - - rc = start_pinentry (); - if (rc) - return rc; - - snprintf (line, DIM(line)-1, "SETDESC %s", desc_text); - line[DIM(line)-1] = 0; - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (map_assuan_err (rc)); - - rc = assuan_transact (entry_ctx, - is_pin? "SETPROMPT PIN:" - : "SETPROMPT Passphrase:", - NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (map_assuan_err (rc)); - - for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++) - { - memset (&parm, 0, sizeof parm); - parm.size = pininfo->max_length; - parm.buffer = pininfo->pin; - - if (errtext) - { - /* fixme: should we show the try count? It must be translated */ - snprintf (line, DIM(line)-1, "SETERROR %s (try %d of %d)", - errtext, pininfo->failed_tries+1, pininfo->max_tries); - line[DIM(line)-1] = 0; - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (map_assuan_err (rc)); - errtext = NULL; - } - - rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, - NULL, NULL, NULL, NULL); - if (rc == ASSUAN_Too_Much_Data) - errtext = is_pin? _("PIN too long") - : _("Passphrase too long"); - else if (rc) - return unlock_pinentry (map_assuan_err (rc)); - - if (!errtext && pininfo->min_digits) - { - /* do some basic checks on the entered PIN. */ - if (!all_digitsp (pininfo->pin)) - errtext = _("Invalid characters in PIN"); - else if (pininfo->max_digits - && strlen (pininfo->pin) > pininfo->max_digits) - errtext = _("PIN too long"); - else if (strlen (pininfo->pin) < pininfo->min_digits) - errtext = _("PIN too short"); - } - - if (!errtext && pininfo->check_cb) - { - /* More checks by utilizing the optional callback. */ - pininfo->cb_errtext = NULL; - rc = pininfo->check_cb (pininfo); - if (rc == -1 && pininfo->cb_errtext) - errtext = pininfo->cb_errtext; - else if (rc == GNUPG_Bad_Passphrase || rc == GNUPG_Bad_PIN) - errtext = (is_pin? _("Bad PIN") - : _("Bad Passphrase")); - else if (rc) - return unlock_pinentry (map_assuan_err (rc)); - } - - if (!errtext) - return unlock_pinentry (0); /* okay, got a PIN or passphrase */ - } - - return unlock_pinentry (pininfo->min_digits? GNUPG_Bad_PIN - : GNUPG_Bad_Passphrase); -} - - - -/* Ask for the passphrase using the supplied arguments. The - passphrase is returned in RETPASS as an hex encoded string to be - freed by the caller */ -int -agent_get_passphrase (char **retpass, const char *desc, const char *prompt, - const char *errtext) -{ - - int rc; - char line[ASSUAN_LINELENGTH]; - struct entry_parm_s parm; - unsigned char *p, *hexstring; - int i; - - *retpass = NULL; - if (opt.batch) - return GNUPG_Bad_Passphrase; - - rc = start_pinentry (); - if (rc) - return rc; - - if (!prompt) - prompt = desc && strstr (desc, "PIN")? "PIN": _("Passphrase"); - - - if (desc) - snprintf (line, DIM(line)-1, "SETDESC %s", desc); - else - snprintf (line, DIM(line)-1, "RESET"); - line[DIM(line)-1] = 0; - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (map_assuan_err (rc)); - - snprintf (line, DIM(line)-1, "SETPROMPT %s", prompt); - line[DIM(line)-1] = 0; - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (map_assuan_err (rc)); - - if (errtext) - { - snprintf (line, DIM(line)-1, "SETERROR %s", errtext); - line[DIM(line)-1] = 0; - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (map_assuan_err (rc)); - } - - memset (&parm, 0, sizeof parm); - parm.size = ASSUAN_LINELENGTH/2 - 5; - parm.buffer = gcry_malloc_secure (parm.size+10); - if (!parm.buffer) - return unlock_pinentry (seterr (Out_Of_Core)); - - assuan_begin_confidential (entry_ctx); - rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, NULL, NULL, NULL, NULL); - if (rc) - { - xfree (parm.buffer); - return unlock_pinentry (map_assuan_err (rc)); - } - - hexstring = gcry_malloc_secure (strlen (parm.buffer)*2+1); - if (!hexstring) - { - xfree (parm.buffer); - return unlock_pinentry (seterr (Out_Of_Core)); - } - - for (i=0, p=parm.buffer; *p; p++, i += 2) - sprintf (hexstring+i, "%02X", *p); - - xfree (parm.buffer); - *retpass = hexstring; - return unlock_pinentry (0); -} - - - -/* Pop up the PIN-entry, display the text and the prompt and ask the - user to confirm this. We return 0 for success, ie. the used - confirmed it, GNUPG_Not_Confirmed for what the text says or an - other error. */ -int -agent_get_confirmation (const char *desc, const char *ok, const char *cancel) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - - rc = start_pinentry (); - if (rc) - return rc; - - if (desc) - snprintf (line, DIM(line)-1, "SETDESC %s", desc); - else - snprintf (line, DIM(line)-1, "RESET"); - line[DIM(line)-1] = 0; - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (map_assuan_err (rc)); - - if (ok) - { - snprintf (line, DIM(line)-1, "SETOK %s", ok); - line[DIM(line)-1] = 0; - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (map_assuan_err (rc)); - } - if (cancel) - { - snprintf (line, DIM(line)-1, "SETCANCEL %s", cancel); - line[DIM(line)-1] = 0; - rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return unlock_pinentry (map_assuan_err (rc)); - } - - rc = assuan_transact (entry_ctx, "CONFIRM", NULL, NULL, NULL, NULL, NULL, NULL); - return unlock_pinentry (map_assuan_err (rc)); -} - - - diff --git a/agent/sexp-parse.h b/agent/sexp-parse.h deleted file mode 100644 index 6baca08cf..000000000 --- a/agent/sexp-parse.h +++ /dev/null @@ -1,98 +0,0 @@ -/* sexp-parse.h - S-Exp helper functions - * Copyright (C) 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 SEXP_PARSE_H -#define SEXP_PARSE_H - -#include "../common/util.h" - -/* Return the length of the next S-Exp part and update the pointer to - the first data byte. 0 is return on error */ -static inline size_t -snext (unsigned char const **buf) -{ - const unsigned char *s; - int n; - - s = *buf; - for (n=0; *s && *s != ':' && digitp (s); s++) - n = n*10 + atoi_1 (s); - if (!n || *s != ':') - return 0; /* we don't allow empty lengths */ - *buf = s+1; - return n; -} - -/* Skip over the S-Expression BUF points to and update BUF to point to - the chacter right behind. DEPTH gives the initial number of open - lists and may be passed as a positive number to skip over the - remainder of an S-Expression if the current position is somewhere - in an S-Expression. The function may return an error code if it - encounters an impossible conditions */ -static inline int -sskip (unsigned char const **buf, int *depth) -{ - const unsigned char *s = *buf; - size_t n; - int d = *depth; - - while (d > 0) - { - if (*s == '(') - { - d++; - s++; - } - else if (*s == ')') - { - d--; - s++; - } - else - { - if (!d) - return GNUPG_Invalid_Sexp; - n = snext (&s); - if (!n) - return GNUPG_Invalid_Sexp; - s += n; - } - } - *buf = s; - *depth = d; - return 0; -} - - -/* Check whether the the string at the address BUF points to matches - the token. Return true on match and update BUF to point behind the - token. */ -static inline int -smatch (unsigned char const **buf, size_t buflen, const char *token) -{ - size_t toklen = strlen (token); - - if (buflen != toklen || memcmp (*buf, token, toklen)) - return 0; - *buf += toklen; - return 1; -} - -#endif /*SEXP_PARSE_H*/ diff --git a/agent/simple-pwquery.c b/agent/simple-pwquery.c deleted file mode 100644 index 5bb08afec..000000000 --- a/agent/simple-pwquery.c +++ /dev/null @@ -1,485 +0,0 @@ -/* simple-pwquery.c - A simple password query cleint for gpg-agent - * Copyright (C) 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 - */ - -/* This module is intended as a standalone client implementation to - gpg-agent's GET_PASSPHRASE command. In particular it does not use - the Assuan library and can only cope with an already running - gpg-agent. Some stuff is configurable in the header file. */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LOCALE_H -#include -#endif - -#define SIMPLE_PWQUERY_IMPLEMENTATION 1 -#include "simple-pwquery.h" - -#if defined(SPWQ_USE_LOGGING) && !defined(HAVE_JNLIB_LOGGING) -# undef SPWQ_USE_LOGGING -#endif - -#ifndef _ -#define _(a) (a) -#endif - -#if !defined (hexdigitp) && !defined (xtoi_2) -#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)) -#endif - - -/* Write NBYTES of BUF to file descriptor FD. */ -static int -writen (int fd, const void *buf, size_t nbytes) -{ - size_t nleft = nbytes; - int nwritten; - - while (nleft > 0) - { - nwritten = write( fd, buf, nleft ); - if (nwritten < 0) - { - if (errno == EINTR) - nwritten = 0; - else { -#ifdef SPWQ_USE_LOGGING - log_error ("write failed: %s\n", strerror (errno)); -#endif - return SPWQ_IO_ERROR; - } - } - nleft -= nwritten; - buf = (const char*)buf + nwritten; - } - - return 0; -} - - -/* Read an entire line and return number of bytes read. */ -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 -(SPWQ_IO_ERROR); - } - else if (!n) - { - return -(SPWQ_PROTOCOL_ERROR); /* 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 simple implementation, so - it is okay to forget about pending bytes */ - } - } - - return nread; -} - - -/* Send an option to the agent */ -static int -agent_send_option (int fd, const char *name, const char *value) -{ - char buf[200]; - int nread; - char *line; - int i; - - line = spwq_malloc (7 + strlen (name) + 1 + strlen (value) + 2); - if (!line) - return SPWQ_OUT_OF_CORE; - strcpy (stpcpy (stpcpy (stpcpy ( - stpcpy (line, "OPTION "), name), "="), value), "\n"); - i = writen (fd, line, strlen (line)); - spwq_free (line); - if (i) - return i; - - /* get response */ - nread = readline (fd, buf, DIM(buf)-1); - if (nread < 0) - return -nread; - if (nread < 3) - return SPWQ_PROTOCOL_ERROR; - - if (buf[0] == 'O' && buf[1] == 'K' && (buf[2] == ' ' || buf[2] == '\n')) - return 0; /* okay */ - - return SPWQ_ERR_RESPONSE; -} - - -/* Send all available options to the agent. */ -static int -agent_send_all_options (int fd) -{ - char *dft_display = NULL; - char *dft_ttyname = NULL; - char *dft_ttytype = NULL; - int rc = 0; - - dft_display = getenv ("DISPLAY"); - if (dft_display) - { - if ((rc = agent_send_option (fd, "display", dft_display))) - return rc; - } - - if (ttyname (1)) - dft_ttyname = ttyname (1); - if (dft_ttyname) - { - if ((rc=agent_send_option (fd, "ttyname", dft_ttyname))) - return rc; - } - - dft_ttytype = getenv ("TERM"); - if (dft_ttyname && dft_ttytype) - { - if ((rc = agent_send_option (fd, "ttytype", dft_ttytype))) - return rc; - } - -#if defined(HAVE_SETLOCALE) - { - char *old_lc = NULL; - char *dft_lc = NULL; - -#if defined(LC_CTYPE) - old_lc = setlocale (LC_CTYPE, NULL); - if (old_lc) - { - char *p = spwq_malloc (strlen (old_lc)+1); - if (!p) - return SPWQ_OUT_OF_CORE; - strcpy (p, old_lc); - old_lc = p; - } - dft_lc = setlocale (LC_CTYPE, ""); - if (dft_ttyname && dft_lc) - rc = agent_send_option (fd, "lc-ctype", dft_lc); - if (old_lc) - { - setlocale (LC_CTYPE, old_lc); - spwq_free (old_lc); - } - if (rc) - return rc; -#endif - -#if defined(LC_MESSAGES) - old_lc = setlocale (LC_MESSAGES, NULL); - if (old_lc) - { - char *p = spwq_malloc (strlen (old_lc)+1); - if (!p) - return SPWQ_OUT_OF_CORE; - strcpy (p, old_lc); - old_lc = p; - } - dft_lc = setlocale (LC_MESSAGES, ""); - if (dft_ttyname && dft_lc) - rc = agent_send_option (fd, "lc-messages", dft_lc); - if (old_lc) - { - setlocale (LC_MESSAGES, old_lc); - spwq_free (old_lc); - } - if (rc) - return rc; -#endif - } -#endif /*HAVE_SETLOCALE*/ - - return 0; -} - - - -/* Try to open a connection to the agent, send all options and return - the file descriptor for the connection. Return -1 in case of - error. */ -static int -agent_open (int *rfd) -{ - int rc; - int fd; - char *infostr, *p; - struct sockaddr_un client_addr; - size_t len; - int prot; - char line[200]; - int nread; - - *rfd = -1; - infostr = getenv ( "GPG_AGENT_INFO" ); - if ( !infostr ) - { -#ifdef SPWQ_USE_LOGGING - log_error (_("gpg-agent is not available in this session\n")); -#endif - return SPWQ_NO_AGENT; - } - - if ( !(p = strchr ( infostr, ':')) || p == infostr - || (p-infostr)+1 >= sizeof client_addr.sun_path ) - { -#ifdef SPWQ_USE_LOGGING - log_error ( _("malformed GPG_AGENT_INFO environment variable\n")); -#endif - return SPWQ_NO_AGENT; - } - *p++ = 0; - - while (*p && *p != ':') - p++; - prot = *p? atoi (p+1) : 0; - if ( prot != 1) - { -#ifdef SPWQ_USE_LOGGING - log_error (_("gpg-agent protocol version %d is not supported\n"),prot); -#endif - return SPWQ_PROTOCOL_ERROR; - } - - if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 ) - { -#ifdef SPWQ_USE_LOGGING - log_error ("can't create socket: %s\n", strerror(errno) ); -#endif - return SPWQ_SYS_ERROR; - } - - 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) - { -#ifdef SPWQ_USE_LOGGING - log_error ( _("can't connect to `%s': %s\n"), infostr, strerror (errno)); -#endif - close (fd ); - return SPWQ_IO_ERROR; - } - - nread = readline (fd, line, DIM(line)); - if (nread < 3 || !(line[0] == 'O' && line[1] == 'K' - && (line[2] == '\n' || line[2] == ' ')) ) - { -#ifdef SPWQ_USE_LOGGING - log_error ( _("communication problem with gpg-agent\n")); -#endif - close (fd ); - return SPWQ_PROTOCOL_ERROR; - } - - rc = agent_send_all_options (fd); - if (rc) - { -#ifdef SPWQ_USE_LOGGING - log_error (_("problem setting the gpg-agent options\n")); -#endif - close (fd); - return rc; - } - - *rfd = fd; - return 0; -} - - -/* Copy text to BUFFER and escape as required. Return a poiinter to - the end of the new buffer. NOte that BUFFER must be large enough - to keep the entire text; allocataing it 3 times the size of TEXT - is sufficient. */ -static char * -copy_and_escape (char *buffer, const char *text) -{ - int i; - char *p = buffer; - - for (i=0; text[i]; i++) - { - if (text[i] < ' ' || text[i] == '+') - { - sprintf (p, "%%%02X", text[i]); - p += 3; - } - else if (text[i] == ' ') - *p++ = '+'; - else - *p++ = text[i]; - } - return p; -} - - -/* Ask the gpg-agent for a passphrase and present the user with a - DESCRIPTION, a PROMPT and optiaonlly with a TRYAGAIN extra text. - If a CACHEID is not NULL it is used to locate the passphrase in in - the cache and store it under this ID. If ERRORCODE is not NULL it - should point a variable receiving an errorcode; thsi errocode might - be 0 if the user canceled the operation. The function returns NULL - to indicate an error. */ -char * -simple_pwquery (const char *cacheid, - const char *tryagain, - const char *prompt, - const char *description, - int *errorcode) -{ - int fd = -1; - int nread; - char *result = NULL; - char *pw = NULL; - char *p; - int rc, i; - - rc = agent_open (&fd); - if (rc) - goto leave; - - if (!cacheid) - cacheid = "X"; - if (!tryagain) - tryagain = "X"; - if (!prompt) - prompt = "X"; - if (!description) - description = "X"; - - { - char *line; - /* We allocate 3 times the needed space so that there is enough - space for escaping. */ - line = spwq_malloc (15 - + 3*strlen (cacheid) + 1 - + 3*strlen (tryagain) + 1 - + 3*strlen (prompt) + 1 - + 3*strlen (description) + 1 - + 2); - if (!line) - { - rc = SPWQ_OUT_OF_CORE; - goto leave; - } - strcpy (line, "GET_PASSPHRASE "); - p = line+15; - p = copy_and_escape (p, cacheid); - *p++ = ' '; - p = copy_and_escape (p, tryagain); - *p++ = ' '; - p = copy_and_escape (p, prompt); - *p++ = ' '; - p = copy_and_escape (p, description); - *p++ = '\n'; - rc = writen (fd, line, p - line); - spwq_free (line); - if (rc) - goto leave; - } - - /* get response */ - pw = spwq_secure_malloc (500); - nread = readline (fd, pw, 499); - if (nread < 0) - { - rc = -nread; - goto leave; - } - if (nread < 3) - { - rc = SPWQ_PROTOCOL_ERROR; - goto leave; - } - - 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 */ - result = pw; - pw = NULL; - } - else if (nread > 7 && !memcmp (pw, "ERR 111", 7) - && (pw[7] == ' ' || pw[7] == '\n') ) - { -#ifdef SPWQ_USE_LOGGING - log_info (_("canceled by user\n") ); -#endif - *errorcode = 0; /* canceled */ - } - else - { -#ifdef SPWQ_USE_LOGGING - log_error (_("problem with the agent\n")); -#endif - rc = SPWQ_ERR_RESPONSE; - } - - leave: - if (errorcode) - *errorcode = rc; - if (fd != -1) - close (fd); - if (pw) - spwq_free (pw); - return result; -} diff --git a/agent/simple-pwquery.h b/agent/simple-pwquery.h deleted file mode 100644 index a1b276ff6..000000000 --- a/agent/simple-pwquery.h +++ /dev/null @@ -1,69 +0,0 @@ -/* simple-pwquery.c - A simple password query cleint for gpg-agent - * Copyright (C) 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 SIMPLE_PWQUERY_H -#define SIMPLE_PWQUERY_H - -#ifdef SIMPLE_PWQUERY_IMPLEMENTATION /* Begin configuration stuff. */ - -/* Include whatever files you need. */ -#include -#include "../jnlib/logging.h" - -/* Try to write error message using the standard log mechanism. The - current implementation requires that the HAVE_JNLIB_LOGGING is also - defined. */ -#define SPWQ_USE_LOGGING 1 - -/* Memory allocation functions used by the implementation. Note, that - the returned value is expected to be freed with - spwq_secure_free. */ -#define spwq_malloc(a) gcry_malloc (a) -#define spwq_free(a) gcry_free (a) -#define spwq_secure_malloc(a) gcry_malloc_secure (a) -#define spwq_secure_free(a) gcry_free (a) - - -#endif /*SIMPLE_PWQUERY_IMPLEMENTATION*/ /* End configuration stuff. */ - - -/* Ask the gpg-agent for a passphrase and present the user with a - DESCRIPTION, a PROMPT and optiaonlly with a TRYAGAIN extra text. - If a CACHEID is not NULL it is used to locate the passphrase in in - the cache and store it under this ID. If ERRORCODE is not NULL it - should point a variable receiving an errorcode; thsi errocode might - be 0 if the user canceled the operation. The function returns NULL - to indicate an error. */ -char *simple_pwquery (const char *cacheid, - const char *tryagain, - const char *prompt, - const char *description, - int *errorcode); - - -#define SPWQ_OUT_OF_CORE 1 -#define SPWQ_IO_ERROR 2 -#define SPWQ_PROTOCOL_ERROR 3 -#define SPWQ_ERR_RESPONSE 4 -#define SPWQ_NO_AGENT 5 -#define SPWQ_SYS_ERROR 6 -#define SPWQ_GENERAL_ERROR 7 - -#endif /*SIMPLE_PWQUERY_H*/ diff --git a/agent/trans.c b/agent/trans.c deleted file mode 100644 index 7fa5e3d6b..000000000 --- a/agent/trans.c +++ /dev/null @@ -1,42 +0,0 @@ -/* trans.c - translatable strings - * 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 - */ - -/* To avoid any problems with the gettext implementation (there used - to be some vulnerabilities in the last years and the use of - external files is a minor security problem in itself), we use our - own simple translation stuff */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "agent.h" - -const char * -trans (const char *text) -{ - return text; -} diff --git a/agent/trustlist.c b/agent/trustlist.c deleted file mode 100644 index b6545f7de..000000000 --- a/agent/trustlist.c +++ /dev/null @@ -1,304 +0,0 @@ -/* trustlist.c - Maintain the list of trusted keys - * Copyright (C) 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include "agent.h" -#include "../assuan/assuan.h" /* fixme: need a way to avoid assuan - calls here */ - -static const char headerblurb[] = -"# This is the list of trusted keys. Comments like this one and empty\n" -"# lines are allowed but keep in mind that the entire file is integrity\n" -"# protected by the use of a MAC, so changing the file does not make\n" -"# much sense without the knowledge of the MAC key. Lines do have a\n" -"# length limit but this is not serious limitation as the format of the\n" -"# entries is fixed and checked by gpg-agent: A non-comment line starts\n" -"# with optional white spaces, followed by exactly 40 hex character,\n" -"# optioanlly followed by a flag character which my either be 'P', 'S'\n" -"# or '*'. Additional data delimited with by a white space is ignored.\n" -"\n"; - - -static FILE *trustfp; - - -static int -open_list (int append) -{ - char *fname; - - fname = make_filename (opt.homedir, "trustlist.txt", NULL); - trustfp = fopen (fname, append? "a+":"r"); - if (!trustfp && errno == ENOENT) - { - trustfp = fopen (fname, "wx"); - if (!trustfp) - { - log_error ("can't create `%s': %s\n", fname, strerror (errno)); - xfree (fname); - return seterr (File_Create_Error); - } - fputs (headerblurb, trustfp); - fclose (trustfp); - trustfp = fopen (fname, append? "a+":"r"); - } - - if (!trustfp) - { - log_error ("can't open `%s': %s\n", fname, strerror (errno)); - xfree (fname); - return seterr (File_Open_Error); - } - - /*FIXME: check the MAC */ - - return 0; -} - - - -/* Read the trustlist and return entry by entry. KEY must point to a - buffer of at least 41 characters. KEYFLAG does return either 'P', - 'S' or '*'. - - Reading a valid entry return 0, EOF returns -1 any other error - returns the appropriate error code. */ -static int -read_list (char *key, int *keyflag) -{ - int rc; - int c, i; - char *p, line[256]; - - if (!trustfp) - { - rc = open_list (0); - if (rc) - return rc; - } - - do - { - if (!fgets (line, DIM(line)-1, trustfp) ) - { - if (feof (trustfp)) - return -1; - return GNUPG_Read_Error; - } - - if (!*line || line[strlen(line)-1] != '\n') - { - /* eat until end of line */ - while ( (c=getc (trustfp)) != EOF && c != '\n') - ; - return *line? GNUPG_Line_Too_Long: GNUPG_Incomplete_Line; - } - - /* Allow for emty lines and spaces */ - for (p=line; spacep (p); p++) - ; - } - while (!*p || *p == '\n' || *p == '#'); - - for (i=0; hexdigitp (p+i) && i < 40; i++) - key[i] = p[i] >= 'a'? (p[i] & 0xdf): p[i]; - key[i] = 0; - if (i!=40 || !(spacep (p+i) || p[i] == '\n')) - { - log_error ("invalid formatted fingerprint in trustlist\n"); - return GNUPG_Bad_Data; - } - assert (p[i]); - if (p[i] == '\n') - *keyflag = '*'; - else - { - i++; - if ( p[i] == 'P' || p[i] == 'p') - *keyflag = 'P'; - else if ( p[i] == 'S' || p[i] == 's') - *keyflag = 'S'; - else if ( p[i] == '*') - *keyflag = '*'; - else - { - log_error ("invalid keyflag in trustlist\n"); - return GNUPG_Bad_Data; - } - i++; - if ( !(spacep (p+i) || p[i] == '\n')) - { - log_error ("invalid keyflag in trustlist\n"); - return GNUPG_Bad_Data; - } - } - - return 0; -} - -/* check whether the given fpr is in our trustdb. We expect FPR to be - an all uppercase hexstring of 40 characters. */ -int -agent_istrusted (const char *fpr) -{ - int rc; - static char key[41]; - int keyflag; - - if (trustfp) - rewind (trustfp); - while (!(rc=read_list (key, &keyflag))) - { - if (!strcmp (key, fpr)) - return 0; - } - if (rc != -1) - { - /* error in the trustdb - close it to give the user a chance for - correction */ - fclose (trustfp); - trustfp = NULL; - } - return rc; -} - - -/* write all trust entries to FP */ -int -agent_listtrusted (void *assuan_context) -{ - int rc; - static char key[51]; - int keyflag; - - if (trustfp) - rewind (trustfp); - while (!(rc=read_list (key, &keyflag))) - { - key[40] = ' '; - key[41] = keyflag; - key[42] = '\n'; - assuan_send_data (assuan_context, key, 43); - assuan_send_data (assuan_context, NULL, 0); /* flush */ - } - if (rc == -1) - rc = 0; - if (rc) - { - /* error in the trustdb - close it to give the user a chance for - correction */ - fclose (trustfp); - trustfp = NULL; - } - return rc; -} - - -/* Insert the given fpr into our trustdb. We expect FPR to be an all - uppercase hexstring of 40 characters. FLAG is either 'P' or 'C'. - This function does first check whether that key has alreay ben put - into the trustdb and returns success in this case. Before a FPR - actually gets inserted, the user is asked by means of the pin-entry - whether this is actual wants he want to do. -*/ -int -agent_marktrusted (const char *name, const char *fpr, int flag) -{ - int rc; - static char key[41]; - int keyflag; - char *desc; - - if (trustfp) - rewind (trustfp); - while (!(rc=read_list (key, &keyflag))) - { - if (!strcmp (key, fpr)) - return 0; - } - fclose (trustfp); - trustfp = NULL; - if (rc != -1) - return rc; /* error in the trustdb */ - - /* insert a new one */ - if (asprintf (&desc, - "Please verify that the certificate identified as:%%0A" - " \"%s\"%%0A" - "has the fingerprint:%%0A" - " %s", name, fpr) < 0 ) - return GNUPG_Out_Of_Core; - rc = agent_get_confirmation (desc, "Correct", "No"); - free (desc); - if (rc) - return rc; - - if (asprintf (&desc, - "Do you ultimately trust%%0A" - " \"%s\"%%0A" - "to correctly certify user certificates?", - name) < 0 ) - return GNUPG_Out_Of_Core; - rc = agent_get_confirmation (desc, "Yes", "No"); - free (desc); - if (rc) - return rc; - - /* now check again to avoid duplicates. Also open in append mode now */ - rc = open_list (1); - if (rc) - return rc; - rewind (trustfp); - while (!(rc=read_list (key, &keyflag))) - { - if (!strcmp (key, fpr)) - return 0; - } - if (rc != -1) - { - fclose (trustfp); - trustfp = NULL; - return rc; /* error in the trustdb */ - } - rc = 0; - - /* append the key */ - fflush (trustfp); - fputs ("\n# ", trustfp); - print_sanitized_string (trustfp, name, 0); - fprintf (trustfp, "\n%s %c\n", fpr, flag); - if (ferror (trustfp)) - rc = GNUPG_Write_Error; - - /* close because we are in append mode */ - if (fclose (trustfp)) - rc = GNUPG_File_Error; - trustfp = NULL; - return rc; -} diff --git a/assuan/ChangeLog b/assuan/ChangeLog deleted file mode 100644 index 670f7ef75..000000000 --- a/assuan/ChangeLog +++ /dev/null @@ -1,250 +0,0 @@ -2002-08-16 Werner Koch - - * assuan.h: Renamed Bad_Certificate_Path to Bad_Certificate_Chain. - -2002-07-30 Werner Koch - - Changed the license from GPL to LGPL. - -2002-07-23 Werner Koch - - * assuan-handler.c (_IO_cookie_io_functions_t): Define it here if - it does not exists. - -2002-06-27 Werner Koch - - * assuan-pipe-connect.c (assuan_pipe_connect): No special handling - for the log_fd and stderr. Connect stderr to /dev/null if it - should not be retained. - -2002-06-26 Werner Koch - - * assuan-buffer.c (assuan_write_line): Make sure we never - accidently print an extra LF. - -2002-05-23 Werner Koch - - * assuan-util.c (assuan_set_io_func): New. - * assuan-buffer.c (writen, readline): Use the new functions - instead of pth. - * assuan-socket-server.c (accept_connection): Don't use the - pth_accept - using the assuan included accept code would be a bad - idea within Pth so we don't need a replacement function. - -2002-05-22 Werner Koch - - * assuan-socket-server.c (assuan_init_connected_socket_server): New. - (accept_connection): Factored most code out to.. - (accept_connection_bottom): .. new function. - -2002-04-04 Werner Koch - - * assuan-buffer.c (my_log_prefix): New. Use it for all i/o debug - output. - -2002-03-06 Werner Koch - - * assuan-client.c (_assuan_read_from_server): Detect END. - (assuan_transact): Pass it to the data callback. - -2002-02-27 Werner Koch - - * assuan-client.c (assuan_transact): Add 2 more arguments to - support status lines. Passing NULL yields the old behaviour. - - * assuan-handler.c (process_request): Flush data lines send - without using the data fp. - -2002-02-14 Werner Koch - - * assuan-inquire.c (assuan_inquire): Check for a cancel command - and return ASSUAN_Canceled. Allow for non-data inquiry. - - * assuan.h: Add a few token specific error codes. - -2002-02-13 Werner Koch - - * assuan-defs.h (assuan_context_s): New var CLIENT_PID. - * assuan-pipe-server.c (_assuan_new_context): set default value. - * assuan-socket-server.c (accept_connection): get the actual pid. - -2002-02-12 Werner Koch - - * assuan-buffer.c (writen,readline) [USE_GNU_PT]: Use pth_read/write. - * assuan-socket-server.c (accept_connection) [USE_GNU_PTH]: Ditto. - -2002-02-01 Marcus Brinkmann - - * Makefile.am (MOSTLYCLEANFILES): New variable. - -2002-01-23 Werner Koch - - * assuan-socket-connect.c (LOGERRORX): and removed typo. - -2002-01-22 Marcus Brinkmann - - * assuan-socket-connect.c (LOGERRORX): Reverse arguments to fputs. - -2002-01-21 Werner Koch - - * assuan-connect.c: Move all except assuan_get_pid to... - * assuan-pipe-connect.c: this. - (assuan_pipe_disconnect): Removed. - (do_finish, do_deinit): New - (assuan_pipe_connect): and set them into the context. - * assuan-socket-connect.c: New. - - * assuan-util.c (_assuan_log_sanitized_string): New. - - * assuan-pipe-server.c (assuan_init_pipe_server): Factored most - code out to ... - (_assuan_new_context): new func. - (_assuan_release_context): New - * assuan-connect.c (assuan_pipe_connect): Use the new functions. - -2002-01-20 Werner Koch - - * assuan.h: Added Invalid Option error code. - - * assuan-handler.c (std_handler_option): New. - (std_cmd_tbl): Add OPTION as standard command. - (assuan_register_option_handler): New. - (dispatch_command): Use case insensitive matching as a fallback. - (my_strcasecmp): New. - -2002-01-19 Werner Koch - - * assuan-buffer.c (_assuan_read_line): Add output logging. - (assuan_write_line): Ditto. - (_assuan_cookie_write_data): Ditto. - (_assuan_cookie_write_flush): Ditto. - * assuan-util.c (_assuan_log_print_buffer): New. - (assuan_set_log_stream): New. - (assuan_begin_confidential): New. - (assuan_end_confidential): New. - - * assuan-defs.h: Add a few handler variables. - * assuan-pipe-server.c (assuan_deinit_pipe_server): Removed. - (deinit_pipe_server): New. - (assuan_deinit_server): New. Changed all callers to use this. - * assuan-listen.c (assuan_accept): Use the accept handler. - * assuan-handler.c (process_request): Use the close Handler. - * assuan-socket-server.c: New. - -2002-01-14 Werner Koch - - * assuan-client.c (_assuan_read_from_server): Skip spaces after - the keyword. - -2002-01-03 Werner Koch - - * assuan-handler.c (assuan_set_okay_line): New. - (process_request): And use it here. - -2002-01-02 Werner Koch - - * assuan-inquire.c (init_membuf,put_membuf,get_membuf): Apply a - hidden 0 behind the buffer so that the buffer can be used as a - string in certain contexts. - -2001-12-14 Marcus Brinkmann - - * assuan-connect.c (assuan_pipe_connect): New argument - FD_CHILD_LIST. Don't close those fds. - * assuan.h: Likewise for prototype. - -2001-12-14 Werner Koch - - * assuan-listen.c (assuan_close_input_fd): New. - (assuan_close_output_fd): New. - * assuan-handler.c (std_handler_reset): Always close them after a - reset command. - (std_handler_bye): Likewise. - -2001-12-14 Marcus Brinkmann - - * assuan-buffer.c (_assuan_read_line): New variable ATTICLEN, use - it to save the length of the attic line. - Rediddle the code a bit to make it more clear what happens. - -2001-12-14 Marcus Brinkmann - - * assuan-defs.h (LINELENGTH): Define as ASSUAN_LINELENGTH. - assuan.h: Define ASSUAN_LINELENGTH. - -2001-12-13 Marcus Brinkmann - - * assuan-buffer.c (assuan_read_line): Fix order of execution to - get correct return values. - -2001-12-13 Werner Koch - - * assuan-handler.c (assuan_get_active_fds): Fixed silly bug, - pretty obvious that nobody ever tested this function. - -2001-12-12 Werner Koch - - * assuan-connect.c (assuan_pipe_connect): Implemented the inital - handshake. - * assuan-client.c (read_from_server): Renamed to - (_assuan_read_from_server): this and made external. - - * assuan-listen.c (assuan_set_hello_line): New. - (assuan_accept): Use a custom hello line is available. - - * assuan-buffer.c (assuan_read_line): New. - (assuan_pending_line): New. - (_assuan_write_line): Renamed to .. - (assuan_write_line): this, made public and changed all callers. - -2001-12-04 Werner Koch - - * assuan-connect.c (assuan_pipe_connect): Add more error reporting. - * assuan-client.c: New. - - * assuan-inquire.c: New. - * assuan-handler.c (process_request): Check for nested invocations. - -2001-11-27 Werner Koch - - * assuan-handler.c (assuan_register_input_notify): New. - (assuan_register_output_notify): New. - -2001-11-26 Werner Koch - - * assuan.h: Added more status codes. - -2001-11-25 Werner Koch - - * assuan-handler.c (assuan_register_bye_notify) - (assuan_register_reset_notify) - (assuan_register_cancel_notify): New and call them from the - standard handlers. - (assuan_process): Moved bulk of function to .. - (process_request): .. new. - (assuan_process_next): One shot version of above. - (assuan_get_active_fds): New. - -2001-11-24 Werner Koch - - * assuan-connect.c (assuan_get_pid): New. - - * assuan-buffer.c (_assuan_read_line): Deal with reads of more - than a line. - * assuan-defs.h: Add space in the context for this. - - - *********************************************************** - * Please note that Assuan is maintained as part of GnuPG. * - * You may find it source-copied in other packages. * - *********************************************************** - - Copyright 2001, 2002 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/assuan/Makefile.am b/assuan/Makefile.am deleted file mode 100644 index 71560c9e3..000000000 --- a/assuan/Makefile.am +++ /dev/null @@ -1,49 +0,0 @@ -# Assuan Makefile -# Copyright (C) 2001, 2002 Free Software Foundation, Inc. -# -# This file is part of Assuan. -# -# Assuan is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as -# published by the Free Software Foundation; either version 2.1 of -# the License, or (at your option) any later version. -# -# Assuan 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser 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 = mkerrors -INCLUDES = -I.. -I$(top_srcdir)/include -BUILT_SOURCES = assuan-errors.c -MOSTLYCLEANFILES = assuan-errors.c - -noinst_LIBRARIES = libassuan.a - - -#libassuan_a_LDFLAGS = -libassuan_a_SOURCES = \ - assuan.h \ - assuan-defs.h \ - assuan-util.c \ - assuan-errors.c \ - assuan-buffer.c \ - assuan-handler.c \ - assuan-inquire.c \ - assuan-listen.c \ - assuan-connect.c \ - assuan-client.c \ - assuan-pipe-server.c \ - assuan-socket-server.c \ - assuan-pipe-connect.c \ - assuan-socket-connect.c - - -assuan-errors.c : assuan.h - $(srcdir)/mkerrors < $(srcdir)/assuan.h > assuan-errors.c diff --git a/assuan/assuan-buffer.c b/assuan/assuan-buffer.c deleted file mode 100644 index df5057543..000000000 --- a/assuan/assuan-buffer.c +++ /dev/null @@ -1,443 +0,0 @@ -/* assuan-buffer.c - read and send data - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of Assuan. - * - * Assuan is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Assuan 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser 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 -#include -#include -#include -#include -#include -#include -#include "assuan-defs.h" - -#ifdef HAVE_JNLIB_LOGGING -#include "../jnlib/logging.h" -#endif - - -static const char * -my_log_prefix (void) -{ -#ifdef HAVE_JNLIB_LOGGING - return log_get_prefix (NULL); -#else - return ""; -#endif -} - - -static int -writen ( int fd, const char *buffer, size_t length ) -{ - while (length) - { - int nwritten = _assuan_write_wrapper? - _assuan_write_wrapper (fd, buffer, length): - write (fd, buffer, length); - - if (nwritten < 0) - { - if (errno == EINTR) - continue; - return -1; /* write error */ - } - length -= nwritten; - buffer += nwritten; - } - return 0; /* okay */ -} - -/* read an entire line */ -static int -readline (int fd, char *buf, size_t buflen, int *r_nread, int *eof) -{ - size_t nleft = buflen; - char *p; - - *eof = 0; - *r_nread = 0; - while (nleft > 0) - { - int n = _assuan_read_wrapper? - _assuan_read_wrapper (fd, buf, nleft): - read (fd, buf, nleft); - - if (n < 0) - { - if (errno == EINTR) - continue; - return -1; /* read error */ - } - else if (!n) - { - *eof = 1; - break; /* allow incomplete lines */ - } - p = buf; - nleft -= n; - buf += n; - *r_nread += n; - - for (; n && *p != '\n'; n--, p++) - ; - if (n) - break; /* at least one full line available - that's enough for now */ - } - - return 0; -} - - -int -_assuan_read_line (ASSUAN_CONTEXT ctx) -{ - char *line = ctx->inbound.line; - int n, nread, atticlen; - int rc; - - if (ctx->inbound.eof) - return -1; - - atticlen = ctx->inbound.attic.linelen; - if (atticlen) - { - memcpy (line, ctx->inbound.attic.line, atticlen); - ctx->inbound.attic.linelen = 0; - for (n=0; n < atticlen && line[n] != '\n'; n++) - ; - if (n < atticlen) - { - rc = 0; /* found another line in the attic */ - nread = atticlen; - atticlen = 0; - } - else - { /* read the rest */ - assert (atticlen < LINELENGTH); - rc = readline (ctx->inbound.fd, line + atticlen, - LINELENGTH - atticlen, &nread, &ctx->inbound.eof); - } - } - else - rc = readline (ctx->inbound.fd, line, LINELENGTH, - &nread, &ctx->inbound.eof); - if (rc) - { - if (ctx->log_fp) - fprintf (ctx->log_fp, "%s[%p] <- [Error: %s]\n", - my_log_prefix (), ctx, strerror (errno)); - return ASSUAN_Read_Error; - } - if (!nread) - { - assert (ctx->inbound.eof); - if (ctx->log_fp) - fprintf (ctx->log_fp, "%s[%p] <- [EOF]\n", my_log_prefix (),ctx); - return -1; - } - - ctx->inbound.attic.pending = 0; - nread += atticlen; - for (n=0; n < nread; n++) - { - if (line[n] == '\n') - { - if (n+1 < nread) - { - char *s, *d; - int i; - - n++; - /* we have to copy the rest because the handlers are - allowed to modify the passed buffer */ - for (d=ctx->inbound.attic.line, s=line+n, i=nread-n; i; i--) - { - if (*s=='\n') - ctx->inbound.attic.pending = 1; - *d++ = *s++; - } - ctx->inbound.attic.linelen = nread-n; - n--; - } - if (n && line[n-1] == '\r') - n--; - line[n] = 0; - ctx->inbound.linelen = n; - if (ctx->log_fp) - { - fprintf (ctx->log_fp, "%s[%p] <- ", my_log_prefix (), ctx); - if (ctx->confidential) - fputs ("[Confidential data not shown]", ctx->log_fp); - else - _assuan_log_print_buffer (ctx->log_fp, - ctx->inbound.line, - ctx->inbound.linelen); - putc ('\n', ctx->log_fp); - } - return 0; - } - } - - if (ctx->log_fp) - fprintf (ctx->log_fp, "%s[%p] <- [Invalid line]\n", my_log_prefix (), ctx); - *line = 0; - ctx->inbound.linelen = 0; - return ctx->inbound.eof? ASSUAN_Line_Not_Terminated : ASSUAN_Line_Too_Long; -} - - -/* Read the next line from the client or server and return a pointer - to a buffer with holding that line. linelen returns the length of - the line. This buffer is valid until another read operation is - done on this buffer. The caller is allowed to modify this buffer. - He should only use the buffer if the function returns without an - error. - - Returns: 0 on success or an assuan error code - See also: assuan_pending_line(). -*/ -AssuanError -assuan_read_line (ASSUAN_CONTEXT ctx, char **line, size_t *linelen) -{ - AssuanError err; - - if (!ctx) - return ASSUAN_Invalid_Value; - - err = _assuan_read_line (ctx); - *line = ctx->inbound.line; - *linelen = ctx->inbound.linelen; - return err; -} - - -/* Return true when a full line is pending for a read, without the need - for actual IO */ -int -assuan_pending_line (ASSUAN_CONTEXT ctx) -{ - return ctx && ctx->inbound.attic.pending; -} - - -AssuanError -assuan_write_line (ASSUAN_CONTEXT ctx, const char *line ) -{ - int rc; - size_t len; - const char *s; - - if (!ctx) - return ASSUAN_Invalid_Value; - - /* Make sure that we never take a LF from the user - this might - violate the protocol. */ - s = strchr (line, '\n'); - len = s? (s-line) : strlen (line); - - /* fixme: we should do some kind of line buffering. */ - if (ctx->log_fp) - { - fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx); - if (s) - fputs ("[supplied line contained a LF]", ctx->log_fp); - if (ctx->confidential) - fputs ("[Confidential data not shown]", ctx->log_fp); - else - _assuan_log_print_buffer (ctx->log_fp, line, len); - putc ('\n', ctx->log_fp); - } - - rc = writen (ctx->outbound.fd, line, len); - if (rc) - rc = ASSUAN_Write_Error; - if (!rc) - { - rc = writen (ctx->outbound.fd, "\n", 1); - if (rc) - rc = ASSUAN_Write_Error; - } - - return rc; -} - - - -/* Write out the data in buffer as datalines with line wrapping and - percent escaping. This fucntion is used for GNU's custom streams */ -int -_assuan_cookie_write_data (void *cookie, const char *buffer, size_t size) -{ - ASSUAN_CONTEXT ctx = cookie; - char *line; - size_t linelen; - - if (ctx->outbound.data.error) - return 0; - - line = ctx->outbound.data.line; - linelen = ctx->outbound.data.linelen; - line += linelen; - while (size) - { - /* insert data line header */ - if (!linelen) - { - *line++ = 'D'; - *line++ = ' '; - linelen += 2; - } - - /* copy data, keep some space for the CRLF and to escape one character */ - while (size && linelen < LINELENGTH-2-2) - { - if (*buffer == '%' || *buffer == '\r' || *buffer == '\n') - { - sprintf (line, "%%%02X", *(unsigned char*)buffer); - line += 3; - linelen += 3; - buffer++; - } - else - { - *line++ = *buffer++; - linelen++; - } - size--; - } - - if (linelen >= LINELENGTH-2-2) - { - if (ctx->log_fp) - { - fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx); - if (ctx->confidential) - fputs ("[Confidential data not shown]", ctx->log_fp); - else - _assuan_log_print_buffer (ctx->log_fp, - ctx->outbound.data.line, - linelen); - putc ('\n', ctx->log_fp); - } - *line++ = '\n'; - linelen++; - if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen)) - { - ctx->outbound.data.error = ASSUAN_Write_Error; - return 0; - } - line = ctx->outbound.data.line; - linelen = 0; - } - } - - ctx->outbound.data.linelen = linelen; - return 0; -} - - -/* Write out any buffered data - This fucntion is used for GNU's custom streams */ -int -_assuan_cookie_write_flush (void *cookie) -{ - ASSUAN_CONTEXT ctx = cookie; - char *line; - size_t linelen; - - if (ctx->outbound.data.error) - return 0; - - line = ctx->outbound.data.line; - linelen = ctx->outbound.data.linelen; - line += linelen; - if (linelen) - { - if (ctx->log_fp) - { - fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx); - if (ctx->confidential) - fputs ("[Confidential data not shown]", ctx->log_fp); - else - _assuan_log_print_buffer (ctx->log_fp, - ctx->outbound.data.line, - linelen); - putc ('\n', ctx->log_fp); - } - *line++ = '\n'; - linelen++; - if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen)) - { - ctx->outbound.data.error = ASSUAN_Write_Error; - return 0; - } - ctx->outbound.data.linelen = 0; - } - return 0; -} - - -/** - * assuan_send_data: - * @ctx: An assuan context - * @buffer: Data to send or NULL to flush - * @length: length of the data to send/ - * - * This function may be used by the server or the client to send data - * lines. The data will be escaped as required by the Assuan protocol - * and may get buffered until a line is full. To force sending the - * data out @buffer may be passed as NULL (in which case @length must - * also be 0); however when used by a client this flush operation does - * also send the terminating "END" command to terminate the reponse on - * a INQUIRE response. However, when assuan_transact() is used, this - * function takes care of sending END itself. - * - * Return value: 0 on success or an error code - **/ - -AssuanError -assuan_send_data (ASSUAN_CONTEXT ctx, const void *buffer, size_t length) -{ - if (!ctx) - return ASSUAN_Invalid_Value; - if (!buffer && length) - return ASSUAN_Invalid_Value; - - if (!buffer) - { /* flush what we have */ - _assuan_cookie_write_flush (ctx); - if (ctx->outbound.data.error) - return ctx->outbound.data.error; - if (!ctx->is_server) - return assuan_write_line (ctx, "END"); - } - else - { - _assuan_cookie_write_data (ctx, buffer, length); - if (ctx->outbound.data.error) - return ctx->outbound.data.error; - } - - return 0; -} - - - - diff --git a/assuan/assuan-client.c b/assuan/assuan-client.c deleted file mode 100644 index d5c0ec819..000000000 --- a/assuan/assuan-client.c +++ /dev/null @@ -1,225 +0,0 @@ -/* assuan-client.c - client functions - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of Assuan. - * - * Assuan is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Assuan 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser 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 -#include -#include -#include -#include -#include - -#include "assuan-defs.h" - -#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)) - - -AssuanError -_assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off) -{ - char *line; - int linelen; - AssuanError rc; - - *okay = 0; - *off = 0; - do - { - rc = _assuan_read_line (ctx); - if (rc) - return rc; - line = ctx->inbound.line; - linelen = ctx->inbound.linelen; - } - while (*line == '#' || !linelen); - - if (linelen >= 1 - && line[0] == 'D' && line[1] == ' ') - { - *okay = 2; /* data line */ - *off = 2; - } - else if (linelen >= 1 - && line[0] == 'S' - && (line[1] == '\0' || line[1] == ' ')) - { - *okay = 4; - *off = 1; - while (line[*off] == ' ') - ++*off; - } - else if (linelen >= 2 - && line[0] == 'O' && line[1] == 'K' - && (line[2] == '\0' || line[2] == ' ')) - { - *okay = 1; - *off = 2; - while (line[*off] == ' ') - ++*off; - } - else if (linelen >= 3 - && line[0] == 'E' && line[1] == 'R' && line[2] == 'R' - && (line[3] == '\0' || line[3] == ' ')) - { - *okay = 0; - *off = 3; - while (line[*off] == ' ') - ++*off; - } - else if (linelen >= 7 - && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q' - && line[3] == 'U' && line[4] == 'I' && line[5] == 'R' - && line[6] == 'E' - && (line[7] == '\0' || line[7] == ' ')) - { - *okay = 3; - *off = 7; - while (line[*off] == ' ') - ++*off; - } - else if (linelen >= 3 - && line[0] == 'E' && line[1] == 'N' && line[2] == 'D' - && (line[3] == '\0' || line[3] == ' ')) - { - *okay = 5; /* end line */ - *off = 3; - } - else - rc = ASSUAN_Invalid_Response; - return rc; -} - - - -/** - * assuan_transact: - * @ctx: The Assuan context - * @command: Coimmand line to be send to server - * @data_cb: Callback function for data lines - * @data_cb_arg: first argument passed to @data_cb - * @inquire_cb: Callback function for a inquire response - * @inquire_cb_arg: first argument passed to @inquire_cb - * @status_cb: Callback function for a status response - * @status_cb_arg: first argument passed to @status_cb - * - * FIXME: Write documentation - * - * Return value: 0 on success or error code. The error code may be - * the one one returned by the server in error lines or from the - * callback functions. - **/ -AssuanError -assuan_transact (ASSUAN_CONTEXT ctx, - const char *command, - AssuanError (*data_cb)(void *, const void *, size_t), - void *data_cb_arg, - AssuanError (*inquire_cb)(void*, const char *), - void *inquire_cb_arg, - AssuanError (*status_cb)(void*, const char *), - void *status_cb_arg) -{ - int rc, okay, off; - unsigned char *line; - int linelen; - - rc = assuan_write_line (ctx, command); - if (rc) - return rc; - - again: - rc = _assuan_read_from_server (ctx, &okay, &off); - if (rc) - return rc; /* error reading from server */ - - line = ctx->inbound.line + off; - linelen = ctx->inbound.linelen - off; - - if (!okay) - { - rc = atoi (line); - if (rc < 100) - rc = ASSUAN_Server_Fault; - } - else if (okay == 2) - { - if (!data_cb) - rc = ASSUAN_No_Data_Callback; - else - { - unsigned char *s, *d; - - for (s=d=line; linelen; linelen--) - { - if (*s == '%' && linelen > 2) - { /* handle escaping */ - s++; - *d++ = xtoi_2 (s); - s += 2; - linelen -= 2; - } - else - *d++ = *s++; - } - *d = 0; /* add a hidden string terminator */ - rc = data_cb (data_cb_arg, line, d - line); - if (!rc) - goto again; - } - } - else if (okay == 3) - { - if (!inquire_cb) - { - assuan_write_line (ctx, "END"); /* get out of inquire mode */ - _assuan_read_from_server (ctx, &okay, &off); /* dummy read */ - rc = ASSUAN_No_Inquire_Callback; - } - else - { - rc = inquire_cb (inquire_cb_arg, line); - if (!rc) - rc = assuan_send_data (ctx, NULL, 0); /* flush and send END */ - if (!rc) - goto again; - } - } - else if (okay == 4) - { - if (status_cb) - rc = status_cb (status_cb_arg, line); - if (!rc) - goto again; - } - else if (okay == 5) - { - if (!data_cb) - rc = ASSUAN_No_Data_Callback; - else - { - rc = data_cb (data_cb_arg, NULL, 0); - if (!rc) - goto again; - } - } - - return rc; -} - diff --git a/assuan/assuan-connect.c b/assuan/assuan-connect.c deleted file mode 100644 index 009aaab43..000000000 --- a/assuan/assuan-connect.c +++ /dev/null @@ -1,54 +0,0 @@ -/* assuan-connect.c - Establish a connection (client) - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of Assuan. - * - * Assuan is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Assuan 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser 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 - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "assuan-defs.h" - -/* Disconnect and release the context CTX. */ -void -assuan_disconnect (ASSUAN_CONTEXT ctx) -{ - if (ctx) - { - assuan_write_line (ctx, "BYE"); - ctx->finish_handler (ctx); - ctx->deinit_handler (ctx); - ctx->deinit_handler = NULL; - _assuan_release_context (ctx); - } -} - -pid_t -assuan_get_pid (ASSUAN_CONTEXT ctx) -{ - return ctx ? ctx->pid : -1; -} diff --git a/assuan/assuan-defs.h b/assuan/assuan-defs.h deleted file mode 100644 index 3e408b179..000000000 --- a/assuan/assuan-defs.h +++ /dev/null @@ -1,144 +0,0 @@ -/* assuan-defs.c - Internal definitions to Assuan - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of Assuan. - * - * Assuan is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Assuan 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser 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 ASSUAN_DEFS_H -#define ASSUAN_DEFS_H - -#include -#include "assuan.h" - -#define LINELENGTH ASSUAN_LINELENGTH - -struct cmdtbl_s { - const char *name; - int cmd_id; - int (*handler)(ASSUAN_CONTEXT, char *line); -}; - -struct assuan_context_s { - AssuanError err_no; - const char *err_str; - int os_errno; /* last system error number used with certain error codes*/ - - int confidential; - int is_server; /* set if this is context belongs to a server */ - int in_inquire; - char *hello_line; - char *okay_line; /* see assan_set_okay_line() */ - - void *user_pointer; /* for assuan_[gs]et_pointer () */ - - FILE *log_fp; - - struct { - int fd; - int eof; - char line[LINELENGTH]; - int linelen; /* w/o CR, LF - might not be the same as - strlen(line) due to embedded nuls. However a nul - is always written at this pos */ - struct { - char line[LINELENGTH]; - int linelen ; - int pending; /* i.e. at least one line is available in the attic */ - } attic; - } inbound; - - struct { - int fd; - struct { - FILE *fp; - char line[LINELENGTH]; - int linelen; - int error; - } data; - } outbound; - - int pipe_mode; /* We are in pipe mode, i.e. we can handle just one - connection and must terminate then */ - pid_t pid; /* In pipe mode, the pid of the child server process. - In socket mode, the pid of the server */ - int listen_fd; /* The fd we are listening on (used by socket servers) */ - int connected_fd; /* helper */ - - pid_t client_pid; /* for a socket server the PID of the client or -1 - if not available */ - - void (*deinit_handler)(ASSUAN_CONTEXT); - int (*accept_handler)(ASSUAN_CONTEXT); - int (*finish_handler)(ASSUAN_CONTEXT); - - struct cmdtbl_s *cmdtbl; - size_t cmdtbl_used; /* used entries */ - size_t cmdtbl_size; /* allocated size of table */ - - void (*bye_notify_fnc)(ASSUAN_CONTEXT); - void (*reset_notify_fnc)(ASSUAN_CONTEXT); - void (*cancel_notify_fnc)(ASSUAN_CONTEXT); - int (*option_handler_fnc)(ASSUAN_CONTEXT,const char*, const char*); - void (*input_notify_fnc)(ASSUAN_CONTEXT, const char *); - void (*output_notify_fnc)(ASSUAN_CONTEXT, const char *); - - int input_fd; /* set by INPUT command */ - int output_fd; /* set by OUTPUT command */ - -}; - - - -/*-- assuan-pipe-server.c --*/ -int _assuan_new_context (ASSUAN_CONTEXT *r_ctx); -void _assuan_release_context (ASSUAN_CONTEXT ctx); - - -/*-- assuan-handler.c --*/ -int _assuan_register_std_commands (ASSUAN_CONTEXT ctx); - -/*-- assuan-buffer.c --*/ -int _assuan_read_line (ASSUAN_CONTEXT ctx); -int _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size); -int _assuan_cookie_write_flush (void *cookie); - -/*-- assuan-client.c --*/ -AssuanError _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off); - - -/*-- assuan-util.c --*/ -extern ssize_t (*_assuan_read_wrapper)(int,void*,size_t); -extern ssize_t (*_assuan_write_wrapper)(int,const void*,size_t); - -void *_assuan_malloc (size_t n); -void *_assuan_calloc (size_t n, size_t m); -void *_assuan_realloc (void *p, size_t n); -void _assuan_free (void *p); - -#define xtrymalloc(a) _assuan_malloc ((a)) -#define xtrycalloc(a,b) _assuan_calloc ((a),(b)) -#define xtryrealloc(a,b) _assuan_realloc((a),(b)) -#define xfree(a) _assuan_free ((a)) - -#define set_error(c,e,t) assuan_set_error ((c), ASSUAN_ ## e, (t)) - -void _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length); -void _assuan_log_sanitized_string (const char *string); - - -#endif /*ASSUAN_DEFS_H*/ - diff --git a/assuan/assuan-handler.c b/assuan/assuan-handler.c deleted file mode 100644 index 6ddfe8899..000000000 --- a/assuan/assuan-handler.c +++ /dev/null @@ -1,708 +0,0 @@ -/* assuan-handler.c - dispatch commands - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of Assuan. - * - * Assuan is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Assuan 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser 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 -#include -#include -#include - -#include "assuan-defs.h" - -#define spacep(p) (*(p) == ' ' || *(p) == '\t') -#define digitp(a) ((a) >= '0' && (a) <= '9') - - -#if !HAVE_FOPENCOOKIE -/* Provide structure for our dummy replacement function. Usually this - is defined in ../common/util.h but assuan should be self - contained. */ -/* Fixme: Remove fopencoookie :-(( */ -typedef struct -{ - ssize_t (*read)(void*,char*,size_t); - ssize_t (*write)(void*,const char*,size_t); - int (*seek)(void*,off_t*,int); - int (*close)(void*); -} _IO_cookie_io_functions_t; -typedef _IO_cookie_io_functions_t cookie_io_functions_t; -FILE *fopencookie (void *cookie, const char *opentype, - cookie_io_functions_t funclist); -#endif /*!HAVE_FOPENCOOKIE*/ - - - - -static int -dummy_handler (ASSUAN_CONTEXT ctx, char *line) -{ - return set_error (ctx, Server_Fault, "no handler registered"); -} - - -static int -std_handler_nop (ASSUAN_CONTEXT ctx, char *line) -{ - return 0; /* okay */ -} - -static int -std_handler_cancel (ASSUAN_CONTEXT ctx, char *line) -{ - if (ctx->cancel_notify_fnc) - ctx->cancel_notify_fnc (ctx); - return set_error (ctx, Not_Implemented, NULL); -} - -static int -std_handler_option (ASSUAN_CONTEXT ctx, char *line) -{ - char *key, *value, *p; - - for (key=line; spacep (key); key++) - ; - if (!*key) - return set_error (ctx, Syntax_Error, "argument required"); - if (*key == '=') - return set_error (ctx, Syntax_Error, "no option name given"); - for (value=key; *value && !spacep (value) && *value != '='; value++) - ; - if (*value) - { - if (spacep (value)) - *value++ = 0; /* terminate key */ - for (; spacep (value); value++) - ; - if (*value == '=') - { - *value++ = 0; /* terminate key */ - for (; spacep (value); value++) - ; - if (!*value) - return set_error (ctx, Syntax_Error, "option argument expected"); - } - if (*value) - { - for (p = value + strlen(value) - 1; p > value && spacep (p); p--) - ; - if (p > value) - *++p = 0; /* strip trailing spaces */ - } - } - - if (*key == '-' && key[1] == '-' && key[2]) - key += 2; /* the double dashes are optional */ - if (*key == '-') - return set_error (ctx, Syntax_Error, - "option should not begin with one dash"); - - if (ctx->option_handler_fnc) - return ctx->option_handler_fnc (ctx, key, value); - return 0; -} - -static int -std_handler_bye (ASSUAN_CONTEXT ctx, char *line) -{ - if (ctx->bye_notify_fnc) - ctx->bye_notify_fnc (ctx); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - return -1; /* pretty simple :-) */ -} - -static int -std_handler_auth (ASSUAN_CONTEXT ctx, char *line) -{ - return set_error (ctx, Not_Implemented, NULL); -} - -static int -std_handler_reset (ASSUAN_CONTEXT ctx, char *line) -{ - if (ctx->reset_notify_fnc) - ctx->reset_notify_fnc (ctx); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - return 0; -} - -static int -std_handler_end (ASSUAN_CONTEXT ctx, char *line) -{ - return set_error (ctx, Not_Implemented, NULL); -} - -static int -parse_cmd_input_output (ASSUAN_CONTEXT ctx, char *line, int *rfd) -{ - char *endp; - - if (strncmp (line, "FD=", 3)) - return set_error (ctx, Syntax_Error, "FD= expected"); - line += 3; - if (!digitp (*line)) - return set_error (ctx, Syntax_Error, "number required"); - *rfd = strtoul (line, &endp, 10); - /* remove that argument so that a notify handler won't see it */ - memset (line, ' ', endp? (endp-line):strlen(line)); - - if (*rfd == ctx->inbound.fd) - return set_error (ctx, Parameter_Conflict, "fd same as inbound fd"); - if (*rfd == ctx->outbound.fd) - return set_error (ctx, Parameter_Conflict, "fd same as outbound fd"); - return 0; -} - -/* Format is INPUT FD= */ -static int -std_handler_input (ASSUAN_CONTEXT ctx, char *line) -{ - int rc, fd; - - rc = parse_cmd_input_output (ctx, line, &fd); - if (rc) - return rc; - ctx->input_fd = fd; - if (ctx->input_notify_fnc) - ctx->input_notify_fnc (ctx, line); - return 0; -} - -/* Format is OUTPUT FD= */ -static int -std_handler_output (ASSUAN_CONTEXT ctx, char *line) -{ - int rc, fd; - - rc = parse_cmd_input_output (ctx, line, &fd); - if (rc) - return rc; - ctx->output_fd = fd; - if (ctx->output_notify_fnc) - ctx->output_notify_fnc (ctx, line); - return 0; -} - - - - - -/* This is a table with the standard commands and handler for them. - The table is used to initialize a new context and assuciate strings - and handlers with cmd_ids */ -static struct { - const char *name; - int cmd_id; - int (*handler)(ASSUAN_CONTEXT, char *line); - int always; /* always initialize this command */ -} std_cmd_table[] = { - { "NOP", ASSUAN_CMD_NOP, std_handler_nop, 1 }, - { "CANCEL", ASSUAN_CMD_CANCEL, std_handler_cancel, 1 }, - { "OPTION", ASSUAN_CMD_OPTION, std_handler_option, 1 }, - { "BYE", ASSUAN_CMD_BYE, std_handler_bye, 1 }, - { "AUTH", ASSUAN_CMD_AUTH, std_handler_auth, 1 }, - { "RESET", ASSUAN_CMD_RESET, std_handler_reset, 1 }, - { "END", ASSUAN_CMD_END, std_handler_end, 1 }, - - { "INPUT", ASSUAN_CMD_INPUT, std_handler_input }, - { "OUTPUT", ASSUAN_CMD_OUTPUT, std_handler_output }, - { "OPTION", ASSUAN_CMD_OPTION, std_handler_option, 1 }, - { NULL } -}; - - -/** - * assuan_register_command: - * @ctx: the server context - * @cmd_id: An ID value for the command - * @cmd_name: A string with the command name - * @handler: The handler function to be called - * - * Register a handler to be used for a given command. - * - * The @cmd_name must be %NULL or an empty string for all @cmd_ids - * below %ASSUAN_CMD_USER because predefined values are used. - * - * Return value: - **/ -int -assuan_register_command (ASSUAN_CONTEXT ctx, - int cmd_id, const char *cmd_name, - int (*handler)(ASSUAN_CONTEXT, char *)) -{ - int i; - - if (cmd_name && !*cmd_name) - cmd_name = NULL; - - if (cmd_id < ASSUAN_CMD_USER) - { - if (cmd_name) - return ASSUAN_Invalid_Value; /* must be NULL for these values*/ - - for (i=0; std_cmd_table[i].name; i++) - { - if (std_cmd_table[i].cmd_id == cmd_id) - { - cmd_name = std_cmd_table[i].name; - if (!handler) - handler = std_cmd_table[i].handler; - break; - } - } - if (!std_cmd_table[i].name) - return ASSUAN_Invalid_Value; /* not a pre-registered one */ - } - - if (!handler) - handler = dummy_handler; - - if (!cmd_name) - return ASSUAN_Invalid_Value; - -/* fprintf (stderr, "DBG-assuan: registering %d as `%s'\n", cmd_id, cmd_name); */ - - if (!ctx->cmdtbl) - { - ctx->cmdtbl_size = 50; - ctx->cmdtbl = xtrycalloc ( ctx->cmdtbl_size, sizeof *ctx->cmdtbl); - if (!ctx->cmdtbl) - return ASSUAN_Out_Of_Core; - ctx->cmdtbl_used = 0; - } - else if (ctx->cmdtbl_used >= ctx->cmdtbl_size) - { - struct cmdtbl_s *x; - - x = xtryrealloc ( ctx->cmdtbl, (ctx->cmdtbl_size+10) * sizeof *x); - if (!x) - return ASSUAN_Out_Of_Core; - ctx->cmdtbl = x; - ctx->cmdtbl_size += 50; - } - - ctx->cmdtbl[ctx->cmdtbl_used].name = cmd_name; - ctx->cmdtbl[ctx->cmdtbl_used].cmd_id = cmd_id; - ctx->cmdtbl[ctx->cmdtbl_used].handler = handler; - ctx->cmdtbl_used++; - return 0; -} - -int -assuan_register_bye_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT)) -{ - if (!ctx) - return ASSUAN_Invalid_Value; - ctx->bye_notify_fnc = fnc; - return 0; -} - -int -assuan_register_reset_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT)) -{ - if (!ctx) - return ASSUAN_Invalid_Value; - ctx->reset_notify_fnc = fnc; - return 0; -} - -int -assuan_register_cancel_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT)) -{ - if (!ctx) - return ASSUAN_Invalid_Value; - ctx->cancel_notify_fnc = fnc; - return 0; -} - -int -assuan_register_option_handler (ASSUAN_CONTEXT ctx, - int (*fnc)(ASSUAN_CONTEXT, - const char*, const char*)) -{ - if (!ctx) - return ASSUAN_Invalid_Value; - ctx->option_handler_fnc = fnc; - return 0; -} - -int -assuan_register_input_notify (ASSUAN_CONTEXT ctx, - void (*fnc)(ASSUAN_CONTEXT, const char *)) -{ - if (!ctx) - return ASSUAN_Invalid_Value; - ctx->input_notify_fnc = fnc; - return 0; -} - -int -assuan_register_output_notify (ASSUAN_CONTEXT ctx, - void (*fnc)(ASSUAN_CONTEXT, const char *)) -{ - if (!ctx) - return ASSUAN_Invalid_Value; - ctx->output_notify_fnc = fnc; - return 0; -} - - -/* Helper to register the standards commands */ -int -_assuan_register_std_commands (ASSUAN_CONTEXT ctx) -{ - int i, rc; - - for (i=0; std_cmd_table[i].name; i++) - { - if (std_cmd_table[i].always) - { - rc = assuan_register_command (ctx, std_cmd_table[i].cmd_id, - NULL, NULL); - if (rc) - return rc; - } - } - return 0; -} - - - -/* Process the special data lines. The "D " has already been removed - from the line. As all handlers this function may modify the line. */ -static int -handle_data_line (ASSUAN_CONTEXT ctx, char *line, int linelen) -{ - return set_error (ctx, Not_Implemented, NULL); -} - -/* like ascii_strcasecmp but assume that B is already uppercase */ -static int -my_strcasecmp (const char *a, const char *b) -{ - if (a == b) - return 0; - - for (; *a && *b; a++, b++) - { - if (((*a >= 'a' && *a <= 'z')? (*a&~0x20):*a) != *b) - break; - } - return *a == *b? 0 : (((*a >= 'a' && *a <= 'z')? (*a&~0x20):*a) - *b); -} - -/* Parse the line, break out the command, find it in the command - table, remove leading and white spaces from the arguments, all the - handler with the argument line and return the error */ -static int -dispatch_command (ASSUAN_CONTEXT ctx, char *line, int linelen) -{ - char *p; - const char *s; - int shift, i; - - if (*line == 'D' && line[1] == ' ') /* divert to special handler */ - return handle_data_line (ctx, line+2, linelen-2); - - for (p=line; *p && *p != ' ' && *p != '\t'; p++) - ; - if (p==line) - return set_error (ctx, Invalid_Command, "leading white-space"); - if (*p) - { /* Skip over leading WS after the keyword */ - *p++ = 0; - while ( *p == ' ' || *p == '\t') - p++; - } - shift = p - line; - - for (i=0; (s=ctx->cmdtbl[i].name); i++) - { - if (!strcmp (line, s)) - break; - } - if (!s) - { /* and try case insensitive */ - for (i=0; (s=ctx->cmdtbl[i].name); i++) - { - if (!my_strcasecmp (line, s)) - break; - } - } - if (!s) - return set_error (ctx, Unknown_Command, NULL); - line += shift; - linelen -= shift; - -/* fprintf (stderr, "DBG-assuan: processing %s `%s'\n", s, line); */ - return ctx->cmdtbl[i].handler (ctx, line); -} - - - - -static int -process_request (ASSUAN_CONTEXT ctx) -{ - int rc; - - if (ctx->in_inquire) - return ASSUAN_Nested_Commands; - - rc = _assuan_read_line (ctx); - if (rc) - return rc; - if (*ctx->inbound.line == '#' || !ctx->inbound.linelen) - return 0; /* comment line - ignore */ - - ctx->outbound.data.error = 0; - ctx->outbound.data.linelen = 0; - /* dispatch command and return reply */ - rc = dispatch_command (ctx, ctx->inbound.line, ctx->inbound.linelen); - /* check from data write errors */ - if (ctx->outbound.data.fp) - { /* Flush the data lines */ - fclose (ctx->outbound.data.fp); - ctx->outbound.data.fp = NULL; - if (!rc && ctx->outbound.data.error) - rc = ctx->outbound.data.error; - } - else /* flush any data send w/o using the data fp */ - { - assuan_send_data (ctx, NULL, 0); - if (!rc && ctx->outbound.data.error) - rc = ctx->outbound.data.error; - } - /* Error handling */ - if (!rc) - { - rc = assuan_write_line (ctx, ctx->okay_line? ctx->okay_line : "OK"); - } - else if (rc == -1) - { /* No error checking because the peer may have already disconnect */ - assuan_write_line (ctx, "OK closing connection"); - ctx->finish_handler (ctx); - } - else - { - char errline[256]; - - if (rc < 100) - sprintf (errline, "ERR %d server fault (%.50s)", - ASSUAN_Server_Fault, assuan_strerror (rc)); - else - { - const char *text = ctx->err_no == rc? ctx->err_str:NULL; - - sprintf (errline, "ERR %d %.50s%s%.100s", - rc, assuan_strerror (rc), text? " - ":"", text?text:""); - } - rc = assuan_write_line (ctx, errline); - } - - ctx->confidential = 0; - if (ctx->okay_line) - { - xfree (ctx->okay_line); - ctx->okay_line = NULL; - } - return rc; -} - -/** - * assuan_process: - * @ctx: assuan context - * - * This fucntion is used to handle the assuan protocol after a - * connection has been established using assuan_accept(). This is the - * main protocol handler. - * - * Return value: 0 on success or an error code if the assuan operation - * failed. Note, that no error is returned for operational errors. - **/ -int -assuan_process (ASSUAN_CONTEXT ctx) -{ - int rc; - - do { - rc = process_request (ctx); - } while (!rc); - - if (rc == -1) - rc = 0; - - return rc; -} - - -/** - * assuan_process_next: - * @ctx: Assuan context - * - * Same as assuan_process() but the user has to provide the outer - * loop. He should loop as long as the return code is zero and stop - * otherwise; -1 is regular end. - * - * See also: assuan_get_active_fds() - * Return value: -1 for end of server, 0 on success or an error code - **/ -int -assuan_process_next (ASSUAN_CONTEXT ctx) -{ - return process_request (ctx); -} - - -/** - * assuan_get_active_fds: - * @ctx: Assuan context - * @what: 0 for read fds, 1 for write fds - * @fdarray: Caller supplied array to store the FDs - * @fdarraysize: size of that array - * - * Return all active filedescriptors for the given context. This - * function can be used to select on the fds and call - * assuan_process_next() if there is an active one. The first fd in - * the array is the one used for the command connection. - * - * Note, that write FDs are not yet supported. - * - * Return value: number of FDs active and put into @fdarray or -1 on - * error which is most likely a too small fdarray. - **/ -int -assuan_get_active_fds (ASSUAN_CONTEXT ctx, int what, - int *fdarray, int fdarraysize) -{ - int n = 0; - - if (!ctx || fdarraysize < 2 || what < 0 || what > 1) - return -1; - - if (!what) - { - if (ctx->inbound.fd != -1) - fdarray[n++] = ctx->inbound.fd; - } - else - { - if (ctx->outbound.fd != -1) - fdarray[n++] = ctx->outbound.fd; - if (ctx->outbound.data.fp) - fdarray[n++] = fileno (ctx->outbound.data.fp); - } - - return n; -} - -/* Return a FP to be used for data output. The FILE pointer is valid - until the end of a handler. So a close is not needed. Assuan does - all the buffering needed to insert the status line as well as the - required line wappping and quoting for data lines. - - We use GNU's custom streams here. There should be an alternative - implementaion for systems w/o a glibc, a simple implementation - could use a child process */ -FILE * -assuan_get_data_fp (ASSUAN_CONTEXT ctx) -{ - cookie_io_functions_t cookie_fnc; - - if (ctx->outbound.data.fp) - return ctx->outbound.data.fp; - - cookie_fnc.read = NULL; - cookie_fnc.write = _assuan_cookie_write_data; - cookie_fnc.seek = NULL; - cookie_fnc.close = _assuan_cookie_write_flush; - - ctx->outbound.data.fp = fopencookie (ctx, "wb", cookie_fnc); - ctx->outbound.data.error = 0; - return ctx->outbound.data.fp; -} - - -/* Set the text used for the next OK reponse. This string is - automatically reset to NULL after the next command. */ -AssuanError -assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line) -{ - if (!ctx) - return ASSUAN_Invalid_Value; - if (!line) - { - xfree (ctx->okay_line); - ctx->okay_line = NULL; - } - else - { - /* FIXME: we need to use gcry_is_secure() to test whether - we should allocate the entire line in secure memory */ - char *buf = xtrymalloc (3+strlen(line)+1); - if (!buf) - return ASSUAN_Out_Of_Core; - strcpy (buf, "OK "); - strcpy (buf+3, line); - xfree (ctx->okay_line); - ctx->okay_line = buf; - } - return 0; -} - - - -void -assuan_write_status (ASSUAN_CONTEXT ctx, const char *keyword, const char *text) -{ - char buffer[256]; - char *helpbuf; - size_t n; - - if ( !ctx || !keyword) - return; - if (!text) - text = ""; - - n = 2 + strlen (keyword) + 1 + strlen (text) + 1; - if (n < sizeof (buffer)) - { - strcpy (buffer, "S "); - strcat (buffer, keyword); - if (*text) - { - strcat (buffer, " "); - strcat (buffer, text); - } - assuan_write_line (ctx, buffer); - } - else if ( (helpbuf = xtrymalloc (n)) ) - { - strcpy (helpbuf, "S "); - strcat (helpbuf, keyword); - if (*text) - { - strcat (helpbuf, " "); - strcat (helpbuf, text); - } - assuan_write_line (ctx, helpbuf); - xfree (helpbuf); - } -} diff --git a/assuan/assuan-inquire.c b/assuan/assuan-inquire.c deleted file mode 100644 index 197e21019..000000000 --- a/assuan/assuan-inquire.c +++ /dev/null @@ -1,239 +0,0 @@ -/* assuan-inquire.c - handle inquire stuff - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of Assuan. - * - * Assuan is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Assuan 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser 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 -#include -#include -#include - -#include "assuan-defs.h" - -#define digitp(a) ((a) >= '0' && (a) <= '9') -#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)) - - -struct membuf { - size_t len; - size_t size; - char *buf; - int out_of_core; - int too_large; - size_t maxlen; -}; - - - -/* A simple implemnation of a dynamic buffer. Use init_membuf() to - create a buffer, put_membuf to append bytes and get_membuf to - release and return the buffer. Allocation errors are detected but - only returned at the final get_membuf(), this helps not to clutter - the code with out of core checks. */ - -static void -init_membuf (struct membuf *mb, int initiallen, size_t maxlen) -{ - mb->len = 0; - mb->size = initiallen; - mb->out_of_core = 0; - mb->too_large = 0; - mb->maxlen = maxlen; - /* we need to allocate one byte more for get_membuf */ - mb->buf = xtrymalloc (initiallen+1); - if (!mb->buf) - mb->out_of_core = 1; -} - -static void -put_membuf (struct membuf *mb, const void *buf, size_t len) -{ - if (mb->out_of_core || mb->too_large) - return; - - if (mb->maxlen && mb->len + len > mb->maxlen) - { - mb->too_large = 1; - return; - } - - if (mb->len + len >= mb->size) - { - char *p; - - mb->size += len + 1024; - /* we need to allocate one byte more for get_membuf */ - p = xtryrealloc (mb->buf, mb->size+1); - if (!p) - { - mb->out_of_core = 1; - return; - } - mb->buf = p; - } - memcpy (mb->buf + mb->len, buf, len); - mb->len += len; -} - -static void * -get_membuf (struct membuf *mb, size_t *len) -{ - char *p; - - if (mb->out_of_core || mb->too_large) - { - xfree (mb->buf); - mb->buf = NULL; - return NULL; - } - - mb->buf[mb->len] = 0; /* there is enough space for the hidden eos */ - p = mb->buf; - *len = mb->len; - mb->buf = NULL; - mb->out_of_core = 1; /* don't allow a reuse */ - return p; -} - -static void -free_membuf (struct membuf *mb) -{ - xfree (mb->buf); - mb->buf = NULL; -} - - -/** - * assuan_inquire: - * @ctx: An assuan context - * @keyword: The keyword used for the inquire - * @r_buffer: Returns an allocated buffer - * @r_length: Returns the length of this buffer - * @maxlen: If not 0, the size limit of the inquired data. - * - * A Server may use this to Send an inquire. r_buffer, r_length and - * maxlen may all be NULL/0 to indicate that no real data is expected. - * - * Return value: 0 on success or an ASSUAN error code - **/ -AssuanError -assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword, - char **r_buffer, size_t *r_length, size_t maxlen) -{ - AssuanError rc; - struct membuf mb; - char cmdbuf[100]; - unsigned char *line, *p; - int linelen; - int nodataexpected; - - if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf))) - return ASSUAN_Invalid_Value; - nodataexpected = !r_buffer && !r_length && !maxlen; - if (!nodataexpected && (!r_buffer || !r_length)) - return ASSUAN_Invalid_Value; - if (!ctx->is_server) - return ASSUAN_Not_A_Server; - if (ctx->in_inquire) - return ASSUAN_Nested_Commands; - - ctx->in_inquire = 1; - if (nodataexpected) - memset (&mb, 0, sizeof mb); /* avoid compiler warnings */ - else - init_membuf (&mb, maxlen? maxlen:1024, maxlen); - - strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword); - rc = assuan_write_line (ctx, cmdbuf); - if (rc) - goto leave; - - for (;;) - { - do - { - rc = _assuan_read_line (ctx); - if (rc) - goto leave; - line = ctx->inbound.line; - linelen = ctx->inbound.linelen; - } - while (*line == '#' || !linelen); - if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D' - && (!line[3] || line[3] == ' ')) - break; /* END command received*/ - if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N') - { - rc = ASSUAN_Canceled; - goto leave; - } - if (line[0] != 'D' || line[1] != ' ' || nodataexpected) - { - rc = ASSUAN_Unexpected_Command; - goto leave; - } - if (linelen < 3) - continue; - line += 2; - linelen -= 2; - - p = line; - while (linelen) - { - for (;linelen && *p != '%'; linelen--, p++) - ; - put_membuf (&mb, line, p-line); - if (linelen > 2) - { /* handle escaping */ - unsigned char tmp[1]; - p++; - *tmp = xtoi_2 (p); - p += 2; - linelen -= 3; - put_membuf (&mb, tmp, 1); - } - line = p; - } - if (mb.too_large) - { - rc = ASSUAN_Too_Much_Data; - goto leave; - } - } - - if (!nodataexpected) - { - *r_buffer = get_membuf (&mb, r_length); - if (!*r_buffer) - rc = ASSUAN_Out_Of_Core; - } - - leave: - if (!nodataexpected) - free_membuf (&mb); - ctx->in_inquire = 0; - return rc; -} - - - - - - diff --git a/assuan/assuan-listen.c b/assuan/assuan-listen.c deleted file mode 100644 index 3d4ee5f60..000000000 --- a/assuan/assuan-listen.c +++ /dev/null @@ -1,132 +0,0 @@ -/* assuan-listen.c - Wait for a connection (server) - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of Assuan. - * - * Assuan is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Assuan 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser 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 -#include -#include -#include -#include - -#include "assuan-defs.h" - -AssuanError -assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line) -{ - if (!ctx) - return ASSUAN_Invalid_Value; - if (!line) - { - xfree (ctx->hello_line); - ctx->hello_line = NULL; - } - else - { - char *buf = xtrymalloc (3+strlen(line)+1); - if (!buf) - return ASSUAN_Out_Of_Core; - strcpy (buf, "OK "); - strcpy (buf+3, line); - xfree (ctx->hello_line); - ctx->hello_line = buf; - } - return 0; -} - - -/** - * assuan_accept: - * @ctx: context - * - * Cancel any existing connectiion and wait for a connection from a - * client. The initial handshake is performed which may include an - * initial authentication or encryption negotiation. - * - * Return value: 0 on success or an error if the connection could for - * some reason not be established. - **/ -AssuanError -assuan_accept (ASSUAN_CONTEXT ctx) -{ - int rc; - - if (!ctx) - return ASSUAN_Invalid_Value; - - if (ctx->pipe_mode > 1) - return -1; /* second invocation for pipemode -> terminate */ - ctx->finish_handler (ctx); - - rc = ctx->accept_handler (ctx); - if (rc) - return rc; - - /* send the hello */ - rc = assuan_write_line (ctx, ctx->hello_line? ctx->hello_line - : "OK Your orders please"); - if (rc) - return rc; - - if (ctx->pipe_mode) - ctx->pipe_mode = 2; - - return 0; -} - - - -int -assuan_get_input_fd (ASSUAN_CONTEXT ctx) -{ - return ctx? ctx->input_fd : -1; -} - - -int -assuan_get_output_fd (ASSUAN_CONTEXT ctx) -{ - return ctx? ctx->output_fd : -1; -} - - -/* Close the fd descriptor set by the command INPUT FD=n. We handle - this fd inside assuan so that we can do some initial checks */ -AssuanError -assuan_close_input_fd (ASSUAN_CONTEXT ctx) -{ - if (!ctx || ctx->input_fd == -1) - return ASSUAN_Invalid_Value; - close (ctx->input_fd); - ctx->input_fd = -1; - return 0; -} - -/* Close the fd descriptor set by the command OUTPUT FD=n. We handle - this fd inside assuan so that we can do some initial checks */ -AssuanError -assuan_close_output_fd (ASSUAN_CONTEXT ctx) -{ - if (!ctx || ctx->output_fd == -1) - return ASSUAN_Invalid_Value; - - close (ctx->output_fd); - ctx->output_fd = -1; - return 0; -} - diff --git a/assuan/assuan-pipe-connect.c b/assuan/assuan-pipe-connect.c deleted file mode 100644 index 0cb48ca1a..000000000 --- a/assuan/assuan-pipe-connect.c +++ /dev/null @@ -1,288 +0,0 @@ -/* assuan-pipe-connect.c - Establish a pipe connection (client) - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of Assuan. - * - * Assuan is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Assuan 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser 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 - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "assuan-defs.h" - -#ifdef _POSIX_OPEN_MAX -#define MAX_OPEN_FDS _POSIX_OPEN_MAX -#else -#define MAX_OPEN_FDS 20 -#endif - -#ifdef HAVE_JNLIB_LOGGING -#include "../jnlib/logging.h" -#define LOGERROR1(a,b) log_error ((a), (b)) -#else -#define LOGERROR1(a,b) fprintf (stderr, (a), (b)) -#endif - - - -static int -writen ( int fd, const char *buffer, size_t length ) -{ - while (length) - { - int nwritten = write (fd, buffer, length); - - if (nwritten < 0) - { - if (errno == EINTR) - continue; - return -1; /* write error */ - } - length -= nwritten; - buffer += nwritten; - } - return 0; /* okay */ -} - - -static int -do_finish (ASSUAN_CONTEXT ctx) -{ - if (ctx->inbound.fd != -1) - { - close (ctx->inbound.fd); - ctx->inbound.fd = -1; - } - if (ctx->outbound.fd != -1) - { - close (ctx->outbound.fd); - ctx->outbound.fd = -1; - } - if (ctx->pid != -1) - { - waitpid (ctx->pid, NULL, 0); /* FIXME Check return value. */ - ctx->pid = -1; - } - return 0; -} - -static void -do_deinit (ASSUAN_CONTEXT ctx) -{ - do_finish (ctx); -} - - - -/* Connect to a server over a pipe, creating the assuan context and - returning it in CTX. The server filename is NAME, the argument - vector in ARGV. FD_CHILD_LIST is a -1 terminated list of file - descriptors not to close in the child. */ -AssuanError -assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[], - int *fd_child_list) -{ - static int fixed_signals = 0; - AssuanError err; - int rp[2]; - int wp[2]; - - if (!ctx || !name || !argv || !argv[0]) - return ASSUAN_Invalid_Value; - - if (!fixed_signals) - { - struct sigaction act; - - sigaction (SIGPIPE, NULL, &act); - if (act.sa_handler == SIG_DFL) - { - act.sa_handler = SIG_IGN; - sigemptyset (&act.sa_mask); - act.sa_flags = 0; - sigaction (SIGPIPE, &act, NULL); - } - fixed_signals = 1; - /* FIXME: This is not MT safe */ - } - - if (pipe (rp) < 0) - return ASSUAN_General_Error; - - if (pipe (wp) < 0) - { - close (rp[0]); - close (rp[1]); - return ASSUAN_General_Error; - } - - err = _assuan_new_context (ctx); - if (err) - { - close (rp[0]); - close (rp[1]); - close (wp[0]); - close (wp[1]); - return err; - } - (*ctx)->pipe_mode = 1; - (*ctx)->inbound.fd = rp[0]; /* Our inbound is read end of read pipe. */ - (*ctx)->outbound.fd = wp[1]; /* Our outbound is write end of write pipe. */ - (*ctx)->deinit_handler = do_deinit; - (*ctx)->finish_handler = do_finish; - - (*ctx)->pid = fork (); - if ((*ctx)->pid < 0) - { - close (rp[0]); - close (rp[1]); - close (wp[0]); - close (wp[1]); - _assuan_release_context (*ctx); - return ASSUAN_General_Error; - } - - if ((*ctx)->pid == 0) - { - int i, n; - char errbuf[512]; - int *fdp; - - /* Close all files which will not be duped and are not in the - fd_child_list. */ - n = sysconf (_SC_OPEN_MAX); - if (n < 0) - n = MAX_OPEN_FDS; - for (i=0; i < n; i++) - { - fdp = fd_child_list; - if (fdp) - { - while (*fdp != -1 && *fdp != i) - fdp++; - } - - if (!(fdp && *fdp != -1) - && i != rp[1] && i != wp[0]) - close(i); - } - errno = 0; - - /* Dup stderr to /dev/null unless it is in the list of FDs to be - passed to the child. */ - fdp = fd_child_list; - if (fdp) - { - for (; *fdp != -1 && *fdp != STDERR_FILENO; fdp++) - ; - } - if (!fdp || *fdp == -1) - { - int fd = open ("/dev/null", O_WRONLY); - if (fd == -1) - { - LOGERROR1 ("can't open `/dev/null': %s\n", strerror (errno)); - _exit (4); - } - if (dup2 (fd, STDERR_FILENO) == -1) - { - LOGERROR1 ("dup2(dev/null, 2) failed: %s\n", strerror (errno)); - _exit (4); - } - close (fd); - } - - /* Dup handles and to stdin/stdout and exec. */ - if (rp[1] != STDOUT_FILENO) - { - if (dup2 (rp[1], STDOUT_FILENO) == -1) - { - LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno)); - _exit (4); - } - close (rp[1]); - } - if (wp[0] != STDIN_FILENO) - { - if (dup2 (wp[0], STDIN_FILENO) == -1) - { - LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno)); - _exit (4); - } - close (wp[0]); - } - - execv (name, argv); - /* oops - use the pipe to tell the parent about it */ - snprintf (errbuf, sizeof(errbuf)-1, "ERR %d can't exec `%s': %.50s\n", - ASSUAN_Problem_Starting_Server, name, strerror (errno)); - errbuf[sizeof(errbuf)-1] = 0; - writen (1, errbuf, strlen (errbuf)); - _exit (4); - } - - close (rp[1]); - close (wp[0]); - - /* initial handshake */ - { - int okay, off; - - err = _assuan_read_from_server (*ctx, &okay, &off); - if (err) - { - LOGERROR1 ("can't connect server: %s\n", assuan_strerror (err)); - } - else if (okay != 1) - { - LOGERROR1 ("can't connect server: `%s'\n", (*ctx)->inbound.line); - err = ASSUAN_Connect_Failed; - } - } - - if (err) - { - assuan_disconnect (*ctx); - *ctx = NULL; - } - - return err; -} - - - - - - - - - - - - - - diff --git a/assuan/assuan-pipe-server.c b/assuan/assuan-pipe-server.c deleted file mode 100644 index 82bb3228a..000000000 --- a/assuan/assuan-pipe-server.c +++ /dev/null @@ -1,124 +0,0 @@ -/* assuan-pipe-server.c - Assuan server working over a pipe - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of Assuan. - * - * Assuan is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Assuan 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser 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 -#include -#include - -#include "assuan-defs.h" - -static void -deinit_pipe_server (ASSUAN_CONTEXT ctx) -{ - /* nothing to do for this simple server */ -} - -static int -accept_connection (ASSUAN_CONTEXT ctx) -{ - /* This is a NOP for a pipe server */ - return 0; -} - -static int -finish_connection (ASSUAN_CONTEXT ctx) -{ - /* This is a NOP for a pipe server */ - return 0; -} - - -/* Create a new context. Note that the handlers are set up for a pipe - server/client - this way we don't need extra dummy functions */ -int -_assuan_new_context (ASSUAN_CONTEXT *r_ctx) -{ - ASSUAN_CONTEXT ctx; - int rc; - - *r_ctx = NULL; - ctx = xtrycalloc (1, sizeof *ctx); - if (!ctx) - return ASSUAN_Out_Of_Core; - ctx->input_fd = -1; - ctx->output_fd = -1; - - ctx->inbound.fd = -1; - ctx->outbound.fd = -1; - - ctx->listen_fd = -1; - ctx->client_pid = (pid_t)-1; - /* use the pipe server handler as a default */ - ctx->deinit_handler = deinit_pipe_server; - ctx->accept_handler = accept_connection; - ctx->finish_handler = finish_connection; - - rc = _assuan_register_std_commands (ctx); - if (rc) - xfree (ctx); - else - *r_ctx = ctx; - return rc; -} - - - -int -assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2]) -{ - int rc; - - rc = _assuan_new_context (r_ctx); - if (!rc) - { - ASSUAN_CONTEXT ctx = *r_ctx; - - ctx->is_server = 1; - ctx->inbound.fd = filedes[0]; - ctx->outbound.fd = filedes[1]; - ctx->pipe_mode = 1; - } - return rc; -} - - -void -_assuan_release_context (ASSUAN_CONTEXT ctx) -{ - if (ctx) - { - xfree (ctx->hello_line); - xfree (ctx->okay_line); - xfree (ctx); - } -} - -void -assuan_deinit_server (ASSUAN_CONTEXT ctx) -{ - if (ctx) - { - /* We use this function pointer to avoid linking other server - when not needed but still allow for a generic deinit function */ - ctx->deinit_handler (ctx); - ctx->deinit_handler = NULL; - _assuan_release_context (ctx); - } -} diff --git a/assuan/assuan-socket-connect.c b/assuan/assuan-socket-connect.c deleted file mode 100644 index 53f4a02d0..000000000 --- a/assuan/assuan-socket-connect.c +++ /dev/null @@ -1,150 +0,0 @@ -/* assuan-socket-connect.c - Assuan socket based client - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of Assuan. - * - * Assuan is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Assuan 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser 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 -#include -#include -#include -#include -#include -#include -#include - -#include "assuan-defs.h" - -#ifdef HAVE_JNLIB_LOGGING -#include "../jnlib/logging.h" -#define LOGERROR(a) log_error ((a)) -#define LOGERROR1(a,b) log_error ((a), (b)) -#define LOGERROR2(a,b,c) log_error ((a), (b), (c)) -#define LOGERRORX(a) log_printf ((a)) -#else -#define LOGERROR(a) fprintf (stderr, (a)) -#define LOGERROR1(a,b) fprintf (stderr, (a), (b)) -#define LOGERROR2(a,b,c) fprintf (stderr, (a), (b), (c)) -#define LOGERRORX(a) fputs ((a), stderr) -#endif - - - -static int -do_finish (ASSUAN_CONTEXT ctx) -{ - if (ctx->inbound.fd != -1) - { - close (ctx->inbound.fd); - } - ctx->inbound.fd = -1; - ctx->outbound.fd = -1; - return 0; -} - -static void -do_deinit (ASSUAN_CONTEXT ctx) -{ - do_finish (ctx); -} - - - -/* Make a connection to the Unix domain socket NAME and return a new - Assuan context in CTX. SERVER_PID is currently not used but may - becode handy in future. */ -AssuanError -assuan_socket_connect (ASSUAN_CONTEXT *r_ctx, - const char *name, pid_t server_pid) -{ - AssuanError err; - ASSUAN_CONTEXT ctx; - int fd; - struct sockaddr_un srvr_addr; - size_t len; - - if (!r_ctx || !name) - return ASSUAN_Invalid_Value; - *r_ctx = NULL; - - /* we require that the name starts with a slash, so that we can - alter reuse this function for other socket types */ - if (*name != '/') - return ASSUAN_Invalid_Value; - if (strlen (name)+1 >= sizeof srvr_addr.sun_path) - return ASSUAN_Invalid_Value; - - err = _assuan_new_context (&ctx); - if (err) - return err; - ctx->pid = server_pid; /* save it in case we need it later */ - ctx->deinit_handler = do_deinit; - ctx->finish_handler = do_finish; - - fd = socket (AF_UNIX, SOCK_STREAM, 0); - if (fd == -1) - { - LOGERROR1 ("can't create socket: %s\n", strerror (errno)); - _assuan_release_context (ctx); - return ASSUAN_General_Error; - } - - memset (&srvr_addr, 0, sizeof srvr_addr ); - srvr_addr.sun_family = AF_UNIX; - strcpy (srvr_addr.sun_path, name); - len = (offsetof (struct sockaddr_un, sun_path) - + strlen (srvr_addr.sun_path) + 1); - - if (connect (fd, (struct sockaddr*)&srvr_addr, len) == -1) - { - LOGERROR2 ("can't connect to `%s': %s\n", name, strerror (errno)); - _assuan_release_context (ctx); - close (fd ); - return ASSUAN_Connect_Failed; - } - - ctx->inbound.fd = fd; - ctx->outbound.fd = fd; - - /* initial handshake */ - { - int okay, off; - - err = _assuan_read_from_server (ctx, &okay, &off); - if (err) - { - LOGERROR1 ("can't connect server: %s\n", assuan_strerror (err)); - } - else if (okay != 1) - { - LOGERROR ("can't connect server: `"); - _assuan_log_sanitized_string (ctx->inbound.line); - LOGERRORX ("'\n"); - err = ASSUAN_Connect_Failed; - } - } - - if (err) - { - assuan_disconnect (ctx); - } - else - *r_ctx = ctx; - return 0; -} - - diff --git a/assuan/assuan-socket-server.c b/assuan/assuan-socket-server.c deleted file mode 100644 index bfa9cfa79..000000000 --- a/assuan/assuan-socket-server.c +++ /dev/null @@ -1,169 +0,0 @@ -/* assuan-socket-server.c - Assuan socket based server - * Copyright (C) 2002 Free Software Foundation, Inc. - * - * This file is part of Assuan. - * - * Assuan is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Assuan 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser 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 -#include -#include -#include -#include -#include -#include - -#include "assuan-defs.h" - -static int -accept_connection_bottom (ASSUAN_CONTEXT ctx) -{ - int fd = ctx->connected_fd; - - ctx->client_pid = (pid_t)-1; -#ifdef HAVE_SO_PEERCRED - { - struct ucred cr; - int cl = sizeof cr; - - if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) ) - ctx->client_pid = cr.pid; - } -#endif - - ctx->inbound.fd = fd; - ctx->inbound.eof = 0; - ctx->inbound.linelen = 0; - ctx->inbound.attic.linelen = 0; - ctx->inbound.attic.pending = 0; - - ctx->outbound.fd = fd; - ctx->outbound.data.linelen = 0; - ctx->outbound.data.error = 0; - - ctx->confidential = 0; - - return 0; -} - - -static int -accept_connection (ASSUAN_CONTEXT ctx) -{ - int fd; - struct sockaddr_un clnt_addr; - size_t len = sizeof clnt_addr; - - ctx->client_pid = (pid_t)-1; - fd = accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len ); - if (fd == -1) - { - ctx->os_errno = errno; - return ASSUAN_Accept_Failed; - } - - ctx->connected_fd = fd; - return accept_connection_bottom (ctx); -} - -static int -finish_connection (ASSUAN_CONTEXT ctx) -{ - if (ctx->inbound.fd != -1) - { - close (ctx->inbound.fd); - } - ctx->inbound.fd = -1; - ctx->outbound.fd = -1; - return 0; -} - - -static void -deinit_socket_server (ASSUAN_CONTEXT ctx) -{ - finish_connection (ctx); -} - - - -/* Initialize a server for the socket LISTEN_FD which has already be - put into listen mode */ -int -assuan_init_socket_server (ASSUAN_CONTEXT *r_ctx, int listen_fd) -{ - ASSUAN_CONTEXT ctx; - int rc; - - *r_ctx = NULL; - ctx = xtrycalloc (1, sizeof *ctx); - if (!ctx) - return ASSUAN_Out_Of_Core; - ctx->is_server = 1; - ctx->input_fd = -1; - ctx->output_fd = -1; - - ctx->inbound.fd = -1; - ctx->outbound.fd = -1; - - ctx->listen_fd = listen_fd; - ctx->connected_fd = -1; - ctx->deinit_handler = deinit_socket_server; - ctx->accept_handler = accept_connection; - ctx->finish_handler = finish_connection; - - rc = _assuan_register_std_commands (ctx); - if (rc) - xfree (ctx); - else - *r_ctx = ctx; - return rc; -} - -/* Initialize a server using the already accepted socket FD. */ -int -assuan_init_connected_socket_server (ASSUAN_CONTEXT *r_ctx, int fd) -{ - ASSUAN_CONTEXT ctx; - int rc; - - *r_ctx = NULL; - ctx = xtrycalloc (1, sizeof *ctx); - if (!ctx) - return ASSUAN_Out_Of_Core; - ctx->is_server = 1; - ctx->pipe_mode = 1; /* we wan't a second accept to indicate EOF */ - ctx->input_fd = -1; - ctx->output_fd = -1; - - ctx->inbound.fd = -1; - ctx->outbound.fd = -1; - - ctx->listen_fd = -1; - ctx->connected_fd = fd; - ctx->deinit_handler = deinit_socket_server; - ctx->accept_handler = accept_connection_bottom; - ctx->finish_handler = finish_connection; - - rc = _assuan_register_std_commands (ctx); - if (rc) - xfree (ctx); - else - *r_ctx = ctx; - return rc; -} - - diff --git a/assuan/assuan-util.c b/assuan/assuan-util.c deleted file mode 100644 index a335b09f7..000000000 --- a/assuan/assuan-util.c +++ /dev/null @@ -1,210 +0,0 @@ -/* assuan-util.c - Utility functions for Assuan - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of Assuan. - * - * Assuan is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Assuan 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser 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 -#include -#include -#include - -#include "assuan-defs.h" - -#ifdef HAVE_JNLIB_LOGGING -#include "../jnlib/logging.h" -#endif - -ssize_t (*_assuan_read_wrapper)(int,void*,size_t) = NULL; -ssize_t (*_assuan_write_wrapper)(int,const void*,size_t) = NULL; - - -static void *(*alloc_func)(size_t n) = malloc; -static void *(*realloc_func)(void *p, size_t n) = realloc; -static void (*free_func)(void*) = free; - - - -void -assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), - void *(*new_realloc_func)(void *p, size_t n), - void (*new_free_func)(void*) ) -{ - alloc_func = new_alloc_func; - realloc_func = new_realloc_func; - free_func = new_free_func; -} - -void * -_assuan_malloc (size_t n) -{ - return alloc_func (n); -} - -void * -_assuan_realloc (void *a, size_t n) -{ - return realloc_func (a, n); -} - -void * -_assuan_calloc (size_t n, size_t m) -{ - void *p = _assuan_malloc (n*m); - if (p) - memset (p, 0, n* m); - return p; -} - -void -_assuan_free (void *p) -{ - if (p) - free_func (p); -} - -/* For use with Pth it is required to have special read and write - functions. We can't assume an ELF based system so we have to - explicitly set them if we are going to use Pth. */ -void -assuan_set_io_func (ssize_t (*r)(int,void*,size_t), - ssize_t (*w)(int,const void*,size_t)) -{ - _assuan_read_wrapper = r; - _assuan_write_wrapper = w; -} - - - -/* Store the error in the context so that the error sending function - can take out a descriptive text. Inside the assuan code, use the - macro set_error instead of this function. */ -int -assuan_set_error (ASSUAN_CONTEXT ctx, int err, const char *text) -{ - ctx->err_no = err; - ctx->err_str = text; - return err; -} - -void -assuan_set_pointer (ASSUAN_CONTEXT ctx, void *pointer) -{ - if (ctx) - ctx->user_pointer = pointer; -} - -void * -assuan_get_pointer (ASSUAN_CONTEXT ctx) -{ - return ctx? ctx->user_pointer : NULL; -} - - -void -assuan_set_log_stream (ASSUAN_CONTEXT ctx, FILE *fp) -{ - if (ctx) - { - if (ctx->log_fp) - fflush (ctx->log_fp); - ctx->log_fp = fp; - } -} - - -void -assuan_begin_confidential (ASSUAN_CONTEXT ctx) -{ - if (ctx) - { - ctx->confidential = 1; - } -} - -void -assuan_end_confidential (ASSUAN_CONTEXT ctx) -{ - if (ctx) - { - ctx->confidential = 0; - } -} - -void -_assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length) -{ - const unsigned char *s; - int n; - - for (n=length,s=buffer; n; n--, s++) - { - if (*s < ' ' || (*s >= 0x7f && *s <= 0xa0)) - break; - } - s = buffer; - if (!n && *s != '[') - fwrite (buffer, length, 1, fp); - else - { - putc ('[', fp); - for (n=0; n < length; n++, s++) - fprintf (fp, " %02x", *s); - putc (' ', fp); - putc (']', fp); - } -} - - -/* print a user supplied string after filtering out potential bad - characters*/ -void -_assuan_log_sanitized_string (const char *string) -{ - const unsigned char *s = string; -#ifdef HAVE_JNLIB_LOGGING - FILE *fp = log_get_stream (); -#else - FILE *fp = stderr; -#endif - - for (; *s; s++) - { - if (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)) - { - putc ('\\', fp); - if (*s == '\n') - putc ('n', fp); - else if (*s == '\r') - putc ('r', fp); - else if (*s == '\f') - putc ('f', fp); - else if (*s == '\v') - putc ('v', fp); - else if (*s == '\b') - putc ('b', fp); - else if (!*s) - putc ('0', fp); - else - fprintf (fp, "x%02x", *s ); - } - else - putc (*s, fp); - } -} - - diff --git a/assuan/assuan.h b/assuan/assuan.h deleted file mode 100644 index 51f648a3a..000000000 --- a/assuan/assuan.h +++ /dev/null @@ -1,234 +0,0 @@ -/* assuan.c - Definitions for the Assuan protocol - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. - * - * This file is part of Assuan. - * - * Assuan is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Assuan 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser 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 ASSUAN_H -#define ASSUAN_H - -#include -#include -#include /* for ssize_t */ - -#ifdef __cplusplus -extern "C" { -#if 0 - } -#endif -#endif - -typedef enum { - ASSUAN_No_Error = 0, - ASSUAN_General_Error = 1, - ASSUAN_Out_Of_Core = 2, - ASSUAN_Invalid_Value = 3, - ASSUAN_Timeout = 4, - ASSUAN_Read_Error = 5, - ASSUAN_Write_Error = 6, - ASSUAN_Problem_Starting_Server = 7, - ASSUAN_Not_A_Server = 8, - ASSUAN_Not_A_Client = 9, - ASSUAN_Nested_Commands = 10, - ASSUAN_Invalid_Response = 11, - ASSUAN_No_Data_Callback = 12, - ASSUAN_No_Inquire_Callback = 13, - ASSUAN_Connect_Failed = 14, - ASSUAN_Accept_Failed = 15, - - /* error codes above 99 are meant as status codes */ - ASSUAN_Not_Implemented = 100, - ASSUAN_Server_Fault = 101, - ASSUAN_Invalid_Command = 102, - ASSUAN_Unknown_Command = 103, - ASSUAN_Syntax_Error = 104, - ASSUAN_Parameter_Error = 105, - ASSUAN_Parameter_Conflict = 106, - ASSUAN_Line_Too_Long = 107, - ASSUAN_Line_Not_Terminated = 108, - ASSUAN_No_Input = 109, - ASSUAN_No_Output = 110, - ASSUAN_Canceled = 111, - ASSUAN_Unsupported_Algorithm = 112, - ASSUAN_Server_Resource_Problem = 113, - ASSUAN_Server_IO_Error = 114, - ASSUAN_Server_Bug = 115, - ASSUAN_No_Data_Available = 116, - ASSUAN_Invalid_Data = 117, - ASSUAN_Unexpected_Command = 118, - ASSUAN_Too_Much_Data = 119, - ASSUAN_Inquire_Unknown = 120, - ASSUAN_Inquire_Error = 121, - ASSUAN_Invalid_Option = 122, - ASSUAN_Invalid_Index = 123, - ASSUAN_Unexpected_Status = 124, - ASSUAN_Unexpected_Data = 125, - ASSUAN_Invalid_Status = 126, - - ASSUAN_Not_Confirmed = 128, - - ASSUAN_Bad_Certificate = 201, - ASSUAN_Bad_Certificate_Chain = 202, - ASSUAN_Missing_Certificate = 203, - ASSUAN_Bad_Signature = 204, - ASSUAN_No_Agent = 205, - ASSUAN_Agent_Error = 206, - ASSUAN_No_Public_Key = 207, - ASSUAN_No_Secret_Key = 208, - ASSUAN_Invalid_Name = 209, - - ASSUAN_Cert_Revoked = 301, - ASSUAN_No_CRL_For_Cert = 302, - ASSUAN_CRL_Too_Old = 303, - ASSUAN_Not_Trusted = 304, - - ASSUAN_Card_Error = 401, - ASSUAN_Invalid_Card = 402, - ASSUAN_No_PKCS15_App = 403, - ASSUAN_Card_Not_Present = 404, - ASSUAN_Invalid_Id = 405 - -} AssuanError; - -/* This is a list of pre-registered ASSUAN commands */ -typedef enum { - ASSUAN_CMD_NOP = 0, - ASSUAN_CMD_CANCEL, /* cancel the current request */ - ASSUAN_CMD_BYE, - ASSUAN_CMD_AUTH, - ASSUAN_CMD_RESET, - ASSUAN_CMD_OPTION, - ASSUAN_CMD_DATA, - ASSUAN_CMD_END, - ASSUAN_CMD_INPUT, - ASSUAN_CMD_OUTPUT, - - ASSUAN_CMD_USER = 256 /* Other commands should be used with this offset*/ -} AssuanCommand; - -#define ASSUAN_LINELENGTH 1002 /* 1000 + [CR,]LF */ - -struct assuan_context_s; -typedef struct assuan_context_s *ASSUAN_CONTEXT; - -/*-- assuan-handler.c --*/ -int assuan_register_command (ASSUAN_CONTEXT ctx, - int cmd_id, const char *cmd_string, - int (*handler)(ASSUAN_CONTEXT, char *)); -int assuan_register_bye_notify (ASSUAN_CONTEXT ctx, - void (*fnc)(ASSUAN_CONTEXT)); -int assuan_register_reset_notify (ASSUAN_CONTEXT ctx, - void (*fnc)(ASSUAN_CONTEXT)); -int assuan_register_cancel_notify (ASSUAN_CONTEXT ctx, - void (*fnc)(ASSUAN_CONTEXT)); -int assuan_register_input_notify (ASSUAN_CONTEXT ctx, - void (*fnc)(ASSUAN_CONTEXT, const char *)); -int assuan_register_output_notify (ASSUAN_CONTEXT ctx, - void (*fnc)(ASSUAN_CONTEXT, const char *)); - -int assuan_register_option_handler (ASSUAN_CONTEXT ctx, - int (*fnc)(ASSUAN_CONTEXT, - const char*, const char*)); - -int assuan_process (ASSUAN_CONTEXT ctx); -int assuan_process_next (ASSUAN_CONTEXT ctx); -int assuan_get_active_fds (ASSUAN_CONTEXT ctx, int what, - int *fdarray, int fdarraysize); - - -FILE *assuan_get_data_fp (ASSUAN_CONTEXT ctx); -AssuanError assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line); -void assuan_write_status (ASSUAN_CONTEXT ctx, - const char *keyword, const char *text); - - -/*-- assuan-listen.c --*/ -AssuanError assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line); -AssuanError assuan_accept (ASSUAN_CONTEXT ctx); -int assuan_get_input_fd (ASSUAN_CONTEXT ctx); -int assuan_get_output_fd (ASSUAN_CONTEXT ctx); -AssuanError assuan_close_input_fd (ASSUAN_CONTEXT ctx); -AssuanError assuan_close_output_fd (ASSUAN_CONTEXT ctx); - - -/*-- assuan-pipe-server.c --*/ -int assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2]); -void assuan_deinit_server (ASSUAN_CONTEXT ctx); - -/*-- assuan-socket-server.c --*/ -int assuan_init_socket_server (ASSUAN_CONTEXT *r_ctx, int listen_fd); -int assuan_init_connected_socket_server (ASSUAN_CONTEXT *r_ctx, int fd); - - -/*-- assuan-pipe-connect.c --*/ -AssuanError assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, - char *const argv[], int *fd_child_list); -/*-- assuan-socket-connect.c --*/ -AssuanError assuan_socket_connect (ASSUAN_CONTEXT *ctx, const char *name, - pid_t server_pid); - -/*-- assuan-connect.c --*/ -void assuan_disconnect (ASSUAN_CONTEXT ctx); -pid_t assuan_get_pid (ASSUAN_CONTEXT ctx); - -/*-- assuan-client.c --*/ -AssuanError -assuan_transact (ASSUAN_CONTEXT ctx, - const char *command, - AssuanError (*data_cb)(void *, const void *, size_t), - void *data_cb_arg, - AssuanError (*inquire_cb)(void*, const char *), - void *inquire_cb_arg, - AssuanError (*status_cb)(void*, const char *), - void *status_cb_arg); - - -/*-- assuan-inquire.c --*/ -AssuanError assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword, - char **r_buffer, size_t *r_length, size_t maxlen); - -/*-- assuan-buffer.c --*/ -AssuanError assuan_read_line (ASSUAN_CONTEXT ctx, - char **line, size_t *linelen); -int assuan_pending_line (ASSUAN_CONTEXT ctx); -AssuanError assuan_write_line (ASSUAN_CONTEXT ctx, const char *line ); -AssuanError assuan_send_data (ASSUAN_CONTEXT ctx, - const void *buffer, size_t length); - - -/*-- assuan-util.c --*/ -void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), - void *(*new_realloc_func)(void *p, size_t n), - void (*new_free_func)(void*) ); -void assuan_set_io_func (ssize_t (*r)(int,void*,size_t), - ssize_t (*w)(int,const void*,size_t)); -void assuan_set_log_stream (ASSUAN_CONTEXT ctx, FILE *fp); -int assuan_set_error (ASSUAN_CONTEXT ctx, int err, const char *text); -void assuan_set_pointer (ASSUAN_CONTEXT ctx, void *pointer); -void *assuan_get_pointer (ASSUAN_CONTEXT ctx); - -void assuan_begin_confidential (ASSUAN_CONTEXT ctx); -void assuan_end_confidential (ASSUAN_CONTEXT ctx); - -/*-- assuan-errors.c (built) --*/ -const char *assuan_strerror (AssuanError err); - - -#ifdef __cplusplus -} -#endif -#endif /*ASSUAN_H*/ diff --git a/assuan/mkerrors b/assuan/mkerrors deleted file mode 100755 index d0c59ff38..000000000 --- a/assuan/mkerrors +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/sh -# mkerrors - Extract error strings from assuan.h -# and create C source for assuan_strerror -# Copyright (C) 2001, 2002 Free Software Foundation, Inc. -# -# This file is part of Assuan. -# -# Assuan is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as -# published by the Free Software Foundation; either version 2.1 of -# the License, or (at your option) any later version. -# -# Assuan 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser 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 - -cat < -#include "assuan.h" - -/** - * assuan_strerror: - * @err: Error code - * - * This function returns a textual representaion of the given - * errorcode. If this is an unknown value, a string with the value - * is returned (Beware: it is hold in a static buffer). - * - * Return value: String with the error description. - **/ -const char * -assuan_strerror (AssuanError err) -{ - const char *s; - static char buf[25]; - - switch (err) - { -EOF - -awk ' -/ASSUAN_No_Error/ { okay=1 } -!okay {next} -/}/ { exit 0 } -/ASSUAN_[A-Za-z_]*/ { print_code($1) } - - -function print_code( s ) -{ -printf " case %s: s=\"", s ; -gsub(/_/, " ", s ); -printf "%s\"; break;\n", tolower(substr(s,8)); -} -' - -cat < - - * vasprintf.c (vasprintf) [va_copy]: Use va_copy. - [!va_copy && __va_copy]: Use __va_copy. - [!va_copy && !__va_copy]: Only now fall back to using memcpy. - -2002-08-21 Werner Koch - - * errors.h: Added STATUS_IMPORT_PROBLEM. - -2002-08-20 Werner Koch - - * vasprintf.c: Hack to handle NULL for %s. - -2002-08-09 Werner Koch - - * signal.c: New. Taken from GnuPG 1.1.91. - -2002-07-23 Werner Koch - - * util.h (_IO_cookie_io_functions_t): Fixed typo. Noted by - Richard Lefebvre. - -2002-07-22 Werner Koch - - * fseeko.c, ftello.c: New. - -2002-06-28 Werner Koch - - * maperror.c (map_to_assuan_status): Map more errorcodes to Bad - Certificate. - -2002-06-26 Werner Koch - - * maperror.c (map_to_assuan_status): Map EOF to No_Data_Available. - -2002-06-10 Werner Koch - - * errors.h (gnupg_error_token): Add new prototype. - (STATUS_ERROR): New. - - * mkerrtok: New. - * Makefile.am: Use it to create the new error token function. - -2002-06-04 Werner Koch - - * maperror.c (map_to_assuan_status): Map Bad_CA_Certificate. - -2002-05-23 Werner Koch - - * no-pth.c, Makefile.am: Removed. - -2002-05-22 Werner Koch - - * mkdtemp.c: Replaced byte by unsigned char because it is no longer - defined in gcrypt.h. - -2002-05-21 Werner Koch - - * maperror.c (map_gcry_err): Add libgcrypt's new S-expression errors. - (map_ksba_err): Add a few mappings. - -2002-05-14 Werner Koch - - * gettime.c: New. - -2002-05-03 Werner Koch - - * errors.h: Added STARUS_EXPSIG and STATUS_EXPKEYSIG. - -2002-04-15 Werner Koch - - * cryptmiss.c: New. - -2002-02-14 Werner Koch - - * maperror.c: Add more assuan<->gnupg mappings. - -2002-02-12 Werner Koch - - * fopencookie.c: Dummy function. - - * vasprintf.c: New. Taken from binutils-2.9.1 and dropped all non - ANSI-C stuff. Merged with asprintf version. - - * no-pth.c: New. - -2002-01-23 Werner Koch - - * mkdtemp.c: Copied from gnupg-1.0.6c and changed to use libgcrypt. - -2002-01-19 Werner Koch - - * sysutils.c: New. This is the misc.c file from gnupg 1.0.6 with - the OpenPGP stuff removed. - * sysutils.h: New. - -2002-01-15 Werner Koch - - * maperror.c: Add mapping for Not_Trusted. - -2002-01-11 Werner Koch - - * maperror.c (map_assuan_err): Codes for CRL - -2002-01-08 Werner Koch - - * util.h (spacep): New. - -2002-01-02 Werner Koch - - * maperror.c (map_to_assuan_status): New. Merged from ../agent - and ../sm. - -2001-12-20 Werner Koch - - * maperror.c (map_gcry_err): Add some mappings. - -2001-12-18 Werner Koch - - * Makefile.am (AM_CPPFLAGS): Include flags for gcrypt and ksba - -2001-12-14 Werner Koch - - * util.h (digitp, hexdigitp): New ctype like macros. - (atoi_1,atoi_2,atoi_4,xtoi_1,xtoi_2): New. - - - Copyright 2001, 2002 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/common/Makefile.am b/common/Makefile.am deleted file mode 100644 index 8f8209afd..000000000 --- a/common/Makefile.am +++ /dev/null @@ -1,52 +0,0 @@ -# Makefile for common gnupg modules -# 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 - -## Process this file with automake to produce Makefile.in - -EXTRA_DIST = mkerrors mkerrtok -#INCLUDES = -BUILT_SOURCES = errors.c - -noinst_LIBRARIES = libcommon.a - -AM_CPPFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) - -libcommon_a_SOURCES = \ - util.h i18n.h \ - errors.c errors.h \ - maperror.c \ - sysutils.c sysutils.h \ - cryptmiss.c \ - gettime.c \ - signal.c - - -libcommon_a_LIBADD = @LIBOBJS@ - -errors.c : errors.h mkerrors mkerrtok - $(srcdir)/mkerrors < $(srcdir)/errors.h > errors.c - $(srcdir)/mkerrtok < $(srcdir)/errors.h >> errors.c - - - - - - - - diff --git a/common/README b/common/README deleted file mode 100644 index d3927d869..000000000 --- a/common/README +++ /dev/null @@ -1,14 +0,0 @@ -Stuff used by several modules of GnuPG. This way we can share error -codes and serveral other things. - - -These directories use it: - -gpg -sm -agent - -These directories don't use it: - -assuan -kbx \ No newline at end of file diff --git a/common/cryptmiss.c b/common/cryptmiss.c deleted file mode 100644 index ae639db1d..000000000 --- a/common/cryptmiss.c +++ /dev/null @@ -1,39 +0,0 @@ -/* cryptmiss.c - Missing functions in libgcrypt - * Copyright (C) 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 -#include -#include -#include -#include -#include - -#include "util.h" - -char * -gcry_strdup (const char *string) -{ - char *p; - - p = gcry_malloc (strlen (string)+1); - if (p) - strcpy (p, string); - return p; -} diff --git a/common/errors.h b/common/errors.h deleted file mode 100644 index c28149fb6..000000000 --- a/common/errors.h +++ /dev/null @@ -1,192 +0,0 @@ -/* errors.h - Globally used error codes - * 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 GNUPG_COMMON_ERRORS_H -#define GNUPG_COMMON_ERRORS_H - -#include "util.h" - -/* Error numbers */ -enum { - GNUPG_EOF = -1, - GNUPG_No_Error = 0, - GNUPG_General_Error = 1, - GNUPG_Out_Of_Core = 2, - GNUPG_Invalid_Value = 3, - GNUPG_IO_Error = 4, - GNUPG_Resource_Limit = 5, - GNUPG_Internal_Error = 6, - GNUPG_Bad_Certificate = 7, - GNUPG_Bad_Certificate_Chain = 8, - GNUPG_Missing_Certificate = 9, - GNUPG_No_Data = 10, - GNUPG_Bad_Signature = 11, - GNUPG_Not_Implemented = 12, - GNUPG_Conflict = 13, - GNUPG_Bug = 14, - GNUPG_Read_Error = 15, - GNUPG_Write_Error = 16, - GNUPG_Incomplete_Line = 17, - GNUPG_Invalid_Response = 18, - GNUPG_No_Agent = 19, - GNUPG_Agent_Error = 20, - GNUPG_No_Public_Key = 21, - GNUPG_No_Secret_Key = 22, - GNUPG_File_Open_Error = 23, - GNUPG_File_Create_Error = 24, - GNUPG_File_Error = 25, - GNUPG_Not_Supported = 26, - GNUPG_Invalid_Data = 27, - GNUPG_Assuan_Server_Fault = 28, - GNUPG_Assuan_Error = 29, /* catch all assuan error */ - GNUPG_Invalid_Session_Key = 30, - GNUPG_Invalid_Sexp = 31, - GNUPG_Unsupported_Algorithm = 32, - GNUPG_No_PIN_Entry = 33, - GNUPG_PIN_Entry_Error = 34, - GNUPG_Bad_PIN = 35, - GNUPG_Bad_Passphrase = 36, - GNUPG_Invalid_Name = 37, - GNUPG_Bad_Public_Key = 38, - GNUPG_Bad_Secret_Key = 39, - GNUPG_Bad_Data = 40, - GNUPG_Invalid_Parameter = 41, - GNUPG_Tribute_to_D_A = 42, - GNUPG_No_Dirmngr = 43, - GNUPG_Dirmngr_Error = 44, - GNUPG_Certificate_Revoked = 45, - GNUPG_No_CRL_Known = 46, - GNUPG_CRL_Too_Old = 47, - GNUPG_Line_Too_Long = 48, - GNUPG_Not_Trusted = 49, - GNUPG_Canceled = 50, - GNUPG_Bad_CA_Certificate = 51, - GNUPG_Certificate_Expired = 52, - GNUPG_Certificate_Too_Young = 53, - GNUPG_Unsupported_Certificate = 54, - GNUPG_Unknown_Sexp = 55, - GNUPG_Unsupported_Protection = 56, - GNUPG_Corrupted_Protection = 57, - GNUPG_Ambiguous_Name = 58, - GNUPG_Card_Error = 59, - GNUPG_Card_Reset = 60, - GNUPG_Card_Removed = 61, - GNUPG_Invalid_Card = 62, - GNUPG_Card_Not_Present = 63, - GNUPG_No_PKCS15_App = 64, - GNUPG_Not_Confirmed = 65, - GNUPG_Configuration_Error = 66, - GNUPG_No_Policy_Match = 67, - GNUPG_Invalid_Index = 68, - GNUPG_Invalid_Id = 69, - GNUPG_No_Scdaemon = 70, - GNUPG_Scdaemon_Error = 71, - GNUPG_Unsupported_Protocol = 72, - GNUPG_Bad_PIN_Method = 73, - GNUPG_Card_Not_Initialized = 74, - GNUPG_Unsupported_Operation = 75, - GNUPG_Wrong_Key_Usage = 76, -}; - -/* Status codes - fixme: should go into another file */ -enum { - STATUS_ENTER, - STATUS_LEAVE, - STATUS_ABORT, - STATUS_GOODSIG, - STATUS_BADSIG, - STATUS_ERRSIG, - STATUS_BADARMOR, - STATUS_RSA_OR_IDEA, - STATUS_SIGEXPIRED, - STATUS_KEYREVOKED, - STATUS_TRUST_UNDEFINED, - STATUS_TRUST_NEVER, - STATUS_TRUST_MARGINAL, - STATUS_TRUST_FULLY, - STATUS_TRUST_ULTIMATE, - - STATUS_SHM_INFO, - STATUS_SHM_GET, - STATUS_SHM_GET_BOOL, - STATUS_SHM_GET_HIDDEN, - - STATUS_NEED_PASSPHRASE, - STATUS_VALIDSIG, - STATUS_SIG_ID, - STATUS_ENC_TO, - STATUS_NODATA, - STATUS_BAD_PASSPHRASE, - STATUS_NO_PUBKEY, - STATUS_NO_SECKEY, - STATUS_NEED_PASSPHRASE_SYM, - STATUS_DECRYPTION_FAILED, - STATUS_DECRYPTION_OKAY, - STATUS_MISSING_PASSPHRASE, - STATUS_GOOD_PASSPHRASE, - STATUS_GOODMDC, - STATUS_BADMDC, - STATUS_ERRMDC, - STATUS_IMPORTED, - STATUS_IMPORT_PROBLEM, - STATUS_IMPORT_RES, - STATUS_FILE_START, - STATUS_FILE_DONE, - STATUS_FILE_ERROR, - - STATUS_BEGIN_DECRYPTION, - STATUS_END_DECRYPTION, - STATUS_BEGIN_ENCRYPTION, - STATUS_END_ENCRYPTION, - - STATUS_DELETE_PROBLEM, - STATUS_GET_BOOL, - STATUS_GET_LINE, - STATUS_GET_HIDDEN, - STATUS_GOT_IT, - STATUS_PROGRESS, - STATUS_SIG_CREATED, - STATUS_SESSION_KEY, - STATUS_NOTATION_NAME, - STATUS_NOTATION_DATA, - STATUS_POLICY_URL, - STATUS_BEGIN_STREAM, - STATUS_END_STREAM, - STATUS_KEY_CREATED, - STATUS_USERID_HIN, - STATUS_UNEXPECTED, - STATUS_INV_RECP, - STATUS_NO_RECP, - STATUS_ALREADY_SIGNED, - - STATUS_EXPSIG, - STATUS_EXPKEYSIG, - - STATUS_TRUNCATED, - STATUS_ERROR -}; - - -/*-- errors.c (build by mkerror and mkerrtok) --*/ -const char *gnupg_strerror (int err); -const char *gnupg_error_token (int err); - - -#endif /*GNUPG_COMMON_ERRORS_H*/ diff --git a/common/fopencookie.c b/common/fopencookie.c deleted file mode 100644 index 7862b9a0d..000000000 --- a/common/fopencookie.c +++ /dev/null @@ -1,37 +0,0 @@ -/* fopencookie.c - Dummy glibc replacement - * Copyright (C) 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 - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include - -#include "util.h" - -FILE * -fopencookie (void *cookie, const char *opentype, - cookie_io_functions_t funclist) -{ - errno = ENOSYS; - return NULL; -} - - diff --git a/common/fseeko.c b/common/fseeko.c deleted file mode 100644 index f151b09ec..000000000 --- a/common/fseeko.c +++ /dev/null @@ -1,40 +0,0 @@ -/* fseeko.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 - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include - -int -fseeko (FILE *stream, off_t off, int whence) -{ - return fseek (stream, off, whence); -} - - - - - - - - - - diff --git a/common/ftello.c b/common/ftello.c deleted file mode 100644 index e3141900d..000000000 --- a/common/ftello.c +++ /dev/null @@ -1,45 +0,0 @@ -/* ftello.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 - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include - -off_t -ftello (FILE *stream) -{ - long int off; - - off = ftell (stream); - if (off == -1) - return (off_t)-1; - return off; -} - - - - - - - - - - diff --git a/common/gettime.c b/common/gettime.c deleted file mode 100644 index 6f656c8e4..000000000 --- a/common/gettime.c +++ /dev/null @@ -1,87 +0,0 @@ -/* gettime.c - Wrapper for time functions - * Copyright (C) 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 -#include -#include - -#include "util.h" - -static unsigned long timewarp; -static enum { NORMAL = 0, FROZEN, FUTURE, PAST } timemode; - -/* Wrapper for the time(3). We use this here so we can fake the time - for tests */ -time_t -gnupg_get_time () -{ - time_t current = time (NULL); - if (timemode == NORMAL) - return current; - else if (timemode == FROZEN) - return timewarp; - else if (timemode == FUTURE) - return current + timewarp; - else - return current - timewarp; -} - -/* set the time to NEWTIME so that gnupg_get_time returns a time - starting with this one. With FREEZE set to 1 the returned time - will never change. Just for completeness, a value of (time_t)-1 - for NEWTIME gets you back to rality. Note that this is obviously - not thread-safe but this is not required. */ -void -gnupg_set_time (time_t newtime, int freeze) -{ - time_t current = time (NULL); - - if ( newtime == (time_t)-1 || current == newtime) - { - timemode = NORMAL; - timewarp = 0; - } - else if (freeze) - { - timemode = FROZEN; - timewarp = current; - } - else if (newtime > current) - { - timemode = FUTURE; - timewarp = newtime - current; - } - else - { - timemode = PAST; - timewarp = current - newtime; - } -} - -/* Returns true when we are in timewarp mode */ -int -gnupg_faked_time_p (void) -{ - return timemode; -} - - - - diff --git a/common/i18n.h b/common/i18n.h deleted file mode 100644 index 0e13dca4d..000000000 --- a/common/i18n.h +++ /dev/null @@ -1,47 +0,0 @@ -/* i18n.h - * Copyright (C) 1998, 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 GNUPG_COMMON_I18N_H -#define GNUPG_COMMON_I18N_H - -#ifdef USE_SIMPLE_GETTEXT - int set_gettext_file( const char *filename ); - const char *gettext( const char *msgid ); -# define _(a) gettext (a) -# define N_(a) (a) -#else -# ifdef HAVE_LOCALE_H -# include -# endif -# ifdef ENABLE_NLS -# include -# define _(a) gettext (a) -# ifdef gettext_noop -# define N_(a) gettext_noop (a) -# else -# define N_(a) (a) -# endif -# else -# define _(a) (a) -# define N_(a) (a) -# endif -#endif /*!USE_SIMPLE_GETTEXT*/ - -#endif /*GNUPG_COMMON_I18N_H*/ diff --git a/common/maperror.c b/common/maperror.c deleted file mode 100644 index ab03669ae..000000000 --- a/common/maperror.c +++ /dev/null @@ -1,271 +0,0 @@ -/* maperror.c - Error mapping - * 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 -#include -#include -#include -#include -#include -#include - -#include - -#include "util.h" -#include "errors.h" -#include "../assuan/assuan.h" - -/* Note: we might want to wrap this in a macro to get our hands on - the line and file where the error occured */ -int -map_ksba_err (int err) -{ - switch (err) - { - case -1: - case 0: - break; - - case KSBA_Out_Of_Core: err = GNUPG_Out_Of_Core; break; - case KSBA_Invalid_Value: err = GNUPG_Invalid_Value; break; - case KSBA_Not_Implemented: err = GNUPG_Not_Implemented; break; - case KSBA_Conflict: err = GNUPG_Conflict; break; - case KSBA_Read_Error: err = GNUPG_Read_Error; break; - case KSBA_Write_Error: err = GNUPG_Write_Error; break; - case KSBA_No_Data: err = GNUPG_No_Data; break; - case KSBA_Bug: err = GNUPG_Bug; break; - case KSBA_Unsupported_Algorithm: err = GNUPG_Unsupported_Algorithm; break; - case KSBA_Invalid_Index: err = GNUPG_Invalid_Index; break; - case KSBA_Invalid_Sexp: err = GNUPG_Invalid_Sexp; break; - case KSBA_Unknown_Sexp: err = GNUPG_Unknown_Sexp; break; - - default: - err = seterr (General_Error); - break; - } - return err; -} - - -int -map_gcry_err (int err) -{ - switch (err) - { - case GCRYERR_EOF: - case -1: - err = -1; - break; - - case 0: - break; - - case GCRYERR_WRONG_PK_ALGO: - case GCRYERR_INV_PK_ALGO: - case GCRYERR_INV_MD_ALGO: - case GCRYERR_INV_CIPHER_ALGO: - err = GNUPG_Unsupported_Algorithm; - break; - case GCRYERR_INV_KEYLEN: - case GCRYERR_WEAK_KEY: - case GCRYERR_BAD_PUBLIC_KEY: err = GNUPG_Bad_Public_Key; break; - case GCRYERR_BAD_SECRET_KEY: err = GNUPG_Bad_Secret_Key; break; - case GCRYERR_BAD_SIGNATURE: err = GNUPG_Bad_Signature; break; - - case GCRYERR_BAD_MPI: - err = GNUPG_Bad_Data; - break; - - case GCRYERR_INV_ARG: - case GCRYERR_INV_OP: - case GCRYERR_INTERNAL: - case GCRYERR_INV_CIPHER_MODE: - err = GNUPG_Invalid_Value; - break; - - case GCRYERR_SELFTEST: - err = GNUPG_Bug; - break; - - case GCRYERR_SEXP_INV_LEN_SPEC : - case GCRYERR_SEXP_STRING_TOO_LONG : - case GCRYERR_SEXP_UNMATCHED_PAREN : - case GCRYERR_SEXP_NOT_CANONICAL : - case GCRYERR_SEXP_BAD_CHARACTER : - case GCRYERR_SEXP_BAD_QUOTATION : - case GCRYERR_SEXP_ZERO_PREFIX : - case GCRYERR_SEXP_NESTED_DH : - case GCRYERR_SEXP_UNMATCHED_DH : - case GCRYERR_SEXP_UNEXPECTED_PUNC : - case GCRYERR_SEXP_BAD_HEX_CHAR : - case GCRYERR_SEXP_ODD_HEX_NUMBERS : - case GCRYERR_SEXP_BAD_OCT_CHAR : - err = GNUPG_Invalid_Sexp; - break; - - case GCRYERR_NO_MEM: err = GNUPG_Out_Of_Core; break; - - case GCRYERR_NOT_IMPL: err = GNUPG_Not_Implemented; break; - case GCRYERR_CONFLICT: err = GNUPG_Conflict; break; - - case GCRYERR_INV_OBJ: /* an object is not valid */ - case GCRYERR_TOO_SHORT: /* provided buffer too short */ - case GCRYERR_TOO_LARGE: /* object is too large */ - case GCRYERR_NO_OBJ: /* Missing item in an object */ - default: - err = seterr (General_Error); - break; - } - return err; -} - -int -map_kbx_err (int err) -{ - switch (err) - { - case -1: - case 0: - break; - - default: - err = seterr (General_Error); - break; - } - return err; -} - - -int -map_assuan_err (int err) -{ - switch (err) - { - case -1: - case 0: - break; - - case ASSUAN_Canceled: err = GNUPG_Canceled; break; - case ASSUAN_Invalid_Index: err = GNUPG_Invalid_Index; break; - - case ASSUAN_Not_Implemented: err = GNUPG_Not_Implemented; break; - case ASSUAN_Server_Fault: err = GNUPG_Assuan_Server_Fault; break; - case ASSUAN_No_Public_Key: err = GNUPG_No_Public_Key; break; - case ASSUAN_No_Secret_Key: err = GNUPG_No_Secret_Key; break; - - case ASSUAN_Cert_Revoked: err = GNUPG_Certificate_Revoked; break; - case ASSUAN_No_CRL_For_Cert: err = GNUPG_No_CRL_Known; break; - case ASSUAN_CRL_Too_Old: err = GNUPG_CRL_Too_Old; break; - - case ASSUAN_Not_Trusted: err = GNUPG_Not_Trusted; break; - - case ASSUAN_Card_Error: err = GNUPG_Card_Error; break; - case ASSUAN_Invalid_Card: err = GNUPG_Invalid_Card; break; - case ASSUAN_No_PKCS15_App: err = GNUPG_No_PKCS15_App; break; - case ASSUAN_Card_Not_Present: err= GNUPG_Card_Not_Present; break; - case ASSUAN_Not_Confirmed: err = GNUPG_Not_Confirmed; break; - case ASSUAN_Invalid_Id: err = GNUPG_Invalid_Id; break; - - default: - err = err < 100? GNUPG_Assuan_Server_Fault : GNUPG_Assuan_Error; - break; - } - return err; -} - -/* Map GNUPG_xxx error codes to Assuan status codes */ -int -map_to_assuan_status (int rc) -{ - switch (rc) - { - case -1: - rc = ASSUAN_No_Data_Available; - break; - case 0: break; - case GNUPG_Bad_CA_Certificate: - case GNUPG_Bad_Certificate: - case GNUPG_Wrong_Key_Usage: - case GNUPG_Certificate_Revoked: - case GNUPG_No_CRL_Known: - case GNUPG_CRL_Too_Old: - case GNUPG_No_Policy_Match: - case GNUPG_Certificate_Expired: - rc = ASSUAN_Bad_Certificate; - break; - case GNUPG_Bad_Certificate_Chain: rc = ASSUAN_Bad_Certificate_Chain; break; - case GNUPG_Missing_Certificate: rc = ASSUAN_Missing_Certificate; break; - case GNUPG_No_Data: rc = ASSUAN_No_Data_Available; break; - case GNUPG_Bad_Signature: rc = ASSUAN_Bad_Signature; break; - case GNUPG_Not_Implemented: rc = ASSUAN_Not_Implemented; break; - case GNUPG_No_Agent: rc = ASSUAN_No_Agent; break; - case GNUPG_Agent_Error: rc = ASSUAN_Agent_Error; break; - case GNUPG_No_Public_Key: rc = ASSUAN_No_Public_Key; break; - case GNUPG_No_Secret_Key: rc = ASSUAN_No_Secret_Key; break; - case GNUPG_Invalid_Data: rc = ASSUAN_Invalid_Data; break; - case GNUPG_Invalid_Name: rc = ASSUAN_Invalid_Name; break; - case GNUPG_Not_Trusted: rc = ASSUAN_Not_Trusted; break; - case GNUPG_Canceled: rc = ASSUAN_Canceled; break; - case GNUPG_Invalid_Index: rc = ASSUAN_Invalid_Index; break; - - case GNUPG_Card_Error: - case GNUPG_Card_Reset: - rc = ASSUAN_Card_Error; - break; - case GNUPG_Card_Removed: - case GNUPG_Card_Not_Present: - rc = ASSUAN_Card_Not_Present; - break; - case GNUPG_Invalid_Card: rc = ASSUAN_Invalid_Card; break; - case GNUPG_No_PKCS15_App: rc = ASSUAN_No_PKCS15_App; break; - case GNUPG_Not_Confirmed: rc = ASSUAN_Not_Confirmed; break; - case GNUPG_Invalid_Id: rc = ASSUAN_Invalid_Id; break; - - case GNUPG_Bad_PIN: - case GNUPG_Bad_Passphrase: - rc = ASSUAN_No_Secret_Key; - break; - - case GNUPG_Read_Error: - case GNUPG_Write_Error: - case GNUPG_IO_Error: - rc = ASSUAN_Server_IO_Error; - break; - case GNUPG_Out_Of_Core: - case GNUPG_Resource_Limit: - rc = ASSUAN_Server_Resource_Problem; - break; - case GNUPG_Bug: - case GNUPG_Internal_Error: - rc = ASSUAN_Server_Bug; - break; - default: - rc = ASSUAN_Server_Fault; - break; - } - return rc; -} - - - - - - - diff --git a/common/mkdtemp.c b/common/mkdtemp.c deleted file mode 100644 index 5347b9cb4..000000000 --- a/common/mkdtemp.c +++ /dev/null @@ -1,99 +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 -#include -#include -#include -#include -#include -#include -#include - -#ifdef MKDIR_TAKES_ONE_ARG -# undef mkdir -# define mkdir(a,b) mkdir(a) -#endif - -char *mkdtemp(char *template) -{ - int attempts,idx,count=0; - unsigned char *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++) - { - int remaining=count; - char *marker=ch; - unsigned char *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 = gcry_random_bytes (4*remaining, GCRY_WEAK_RANDOM); - - 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); - - gcry_free (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/common/mkerrors b/common/mkerrors deleted file mode 100755 index 5a1ef33da..000000000 --- a/common/mkerrors +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/sh -# mkerrors - Extract error strings from errors.h -# and create C source for gnupg_strerror -# 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 - -cat < -#include -#include "errors.h" - -/** - * gnupg_strerror: - * @err: Error code - * - * This function returns a textual representaion of the given - * errorcode. If this is an unknown value, a string with the value - * is returned (Beware: it is hold in a static buffer). - * - * Return value: String with the error description. - **/ -const char * -gnupg_strerror (int err) -{ - const char *s; - static char buf[25]; - - switch (err) - { -EOF - -awk ' -/GNUPG_No_Error/ { okay=1 } -!okay {next} -/}/ { exit 0 } -/GNUPG_[A-Za-z_]*/ { print_code($1) } - - -function print_code( s ) -{ -printf " case %s: s=\"", s ; -gsub(/_/, " ", s ); -printf "%s\"; break;\n", tolower(substr(s,7)); -} -' - -cat < -#include -#include -#include -#include -#include -#include -#include - -#include "util.h" - - -static volatile int caught_fatal_sig = 0; -static volatile int caught_sigusr1 = 0; -static void (*cleanup_fnc)(void); - - -static void -init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign ) -{ -#ifndef HAVE_DOSISH_SYSTEM -# ifdef HAVE_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; - - if (cleanup_fnc) - cleanup_fnc (); - /* better don't translate these messages */ - write (2, "\n", 1 ); - s = log_get_prefix (NULL); - 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); - /* fixme: remove_lockfiles ();*/ -#ifdef __riscos__ - close_fds (); -#endif /* __riscos__ */ - raise( sig ); -} - - -static RETSIGTYPE -got_usr_signal (int sig) -{ - caught_sigusr1 = 1; -} - - -void -gnupg_init_signals (int mode, void (*fast_cleanup)(void)) -{ - assert (!mode); - - cleanup_fnc = fast_cleanup; -#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 -gnupg_pause_on_sigusr (int which) -{ -#ifndef HAVE_DOSISH_SYSTEM -# ifdef HAVE_SIGPROCMASK - 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; - sigrelease(SIGUSR1); -# endif /*!HAVE_SIGPROCMASK*/ -#endif -} - - -static void -do_block( int block ) -{ -#ifndef HAVE_DOSISH_SYSTEM - static int is_blocked; -#ifdef HAVE_SIGPROCMASK - 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*/ - static void (*disposition[MAXSIG])(); - int sig; - - if (block) - { - if (is_blocked) - log_bug("signals are already blocked\n"); - for (sig=1; sig < MAXSIG; 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 < MAXSIG; sig++) { - sigset (sig, disposition[sig]); - } - is_blocked = 0; - } -#endif /*!HAVE_SIGPROCMASK*/ -#endif /*HAVE_DOSISH_SYSTEM*/ -} - - -void -gnupg_block_all_signals () -{ - do_block(1); -} - -void -gnupg_unblock_all_signals () -{ - do_block(0); -} diff --git a/common/sysutils.c b/common/sysutils.c deleted file mode 100644 index 6eb40b125..000000000 --- a/common/sysutils.c +++ /dev/null @@ -1,206 +0,0 @@ -/* sysutils.c - system helpers - * 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 -#include -#include -#include -#include -#include -#ifdef HAVE_STAT -#include -#endif -#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2 - #include - #include -#endif -#ifdef HAVE_SETRLIMIT - #include - #include - #include -#endif -#include "util.h" -#include "i18n.h" - -#include "sysutils.h" - -#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2 -#warning using trap_unaligned -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 (void) -{ - #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 -} - - - -/* 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; -} - - -#if 0 /* not yet needed */ -int -check_permissions(const char *path,int extension,int checkonly) -{ -#if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM) - char *tmppath; - struct stat statbuf; - int ret=1; - int isdir=0; - - if(opt.no_perm_warn) - return 0; - - if(extension && path[0]!=DIRSEP_C) - { - if(strchr(path,DIRSEP_C)) - tmppath=make_filename(path,NULL); - else - tmppath=make_filename(GNUPG_LIBDIR,path,NULL); - } - else - tmppath=m_strdup(path); - - /* It's okay if the file doesn't exist */ - if(stat(tmppath,&statbuf)!=0) - { - ret=0; - goto end; - } - - isdir=S_ISDIR(statbuf.st_mode); - - /* Per-user files must be owned by the user. Extensions must be - owned by the user or root. */ - if((!extension && statbuf.st_uid != getuid()) || - (extension && statbuf.st_uid!=0 && statbuf.st_uid!=getuid())) - { - if(!checkonly) - log_info(_("Warning: unsafe ownership on %s \"%s\"\n"), - isdir?"directory":extension?"extension":"file",path); - goto end; - } - - /* This works for both directories and files - basically, we don't - care what the owner permissions are, so long as the group and - other permissions are 0 for per-user files, and non-writable for - extensions. */ - if((extension && (statbuf.st_mode & (S_IWGRP|S_IWOTH)) !=0) || - (!extension && (statbuf.st_mode & (S_IRWXG|S_IRWXO)) != 0)) - { - char *dir; - - /* However, if the directory the directory/file is in is owned - by the user and is 700, then this is not a problem. - 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,&statbuf)==0 && statbuf.st_uid==getuid() && - S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & (S_IRWXG|S_IRWXO))==0) - { - xfree (dir); - ret=0; - goto end; - } - - m_free(dir); - - if(!checkonly) - log_info(_("Warning: unsafe permissions on %s \"%s\"\n"), - isdir?"directory":extension?"extension":"file",path); - goto end; - } - - ret=0; - - end: - m_free(tmppath); - - return ret; - -#endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */ - - return 0; -} -#endif diff --git a/common/sysutils.h b/common/sysutils.h deleted file mode 100644 index f2054d468..000000000 --- a/common/sysutils.h +++ /dev/null @@ -1,30 +0,0 @@ -/* sysutils.h - System utility functions for Gnupg - * Copyright (C) 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 GNUPG_COMMON_SYSUTILS_H -#define GNUPG_COMMON_SYSUTILS_H - -void trap_unaligned (void); -int disable_core_dumps (void); -const unsigned char *get_session_marker (size_t *rlen); -int check_permissions (const char *path,int extension,int checkonly); - - -#endif /*GNUPG_COMMON_SYSUTILS_H*/ diff --git a/common/util.h b/common/util.h deleted file mode 100644 index a863f2078..000000000 --- a/common/util.h +++ /dev/null @@ -1,117 +0,0 @@ -/* util.h - Utility functions for Gnupg - * 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 - */ - -#ifndef GNUPG_COMMON_UTIL_H -#define GNUPG_COMMON_UTIL_H - -#include /* we need this for the memory function protos */ -#include /* we need time_t */ - -/* to pass hash functions to libksba we need to cast it */ -#define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write) - -/* get all the stuff from jnlib */ -#include "../jnlib/logging.h" -#include "../jnlib/argparse.h" -#include "../jnlib/stringhelp.h" -#include "../jnlib/mischelp.h" -#include "../jnlib/strlist.h" -#include "../jnlib/dotlock.h" - -/* handy malloc macros - use only them */ -#define xtrymalloc(a) gcry_malloc ((a)) -#define xtrycalloc(a,b) gcry_calloc ((a),(b)) -#define xtryrealloc(a,b) gcry_realloc ((a),(b)) -#define xtrystrdup(a) gcry_strdup ((a)) -#define xfree(a) gcry_free ((a)) - -#define xmalloc(a) gcry_xmalloc ((a)) -#define xcalloc(a,b) gcry_xcalloc ((a),(b)) -#define xrealloc(a,b) gcry_xrealloc ((a),(b)) -#define xstrdup(a) gcry_xstrdup ((a)) - -#define seterr(a) (GNUPG_ ## a) - -/*-- maperror.c --*/ -int map_ksba_err (int err); -int map_gcry_err (int err); -int map_kbx_err (int err); -int map_assuan_err (int err); -int map_to_assuan_status (int rc); - -/*-- gettime.c --*/ -time_t gnupg_get_time (void); -void gnupg_set_time (time_t newtime, int freeze); -int gnupg_faked_time_p (void); - -/*-- signal.c --*/ -void gnupg_init_signals (int mode, void (*fast_cleanup)(void)); -void gnupg_pause_on_sigusr (int which); -void gnupg_block_all_signals (void); -void gnupg_unblock_all_signals (void); - - -/*-- replacement functions from funcname.c --*/ -#if !HAVE_VASPRINTF -#include -int vasprintf (char **result, const char *format, va_list *args); -int asprintf (char **result, const char *format, ...); -#endif - -#if !HAVE_FOPENCOOKIE -typedef struct -{ - ssize_t (*read)(void*,char*,size_t); - ssize_t (*write)(void*,const char*,size_t); - int (*seek)(void*,off_t*,int); - int (*close)(void*); -} _IO_cookie_io_functions_t; -typedef _IO_cookie_io_functions_t cookie_io_functions_t; -FILE *fopencookie (void *cookie, const char *opentype, - cookie_io_functions_t funclist); -#endif /*!HAVE_FOPENCOOKIE*/ - - - -/*-- some macros to replace ctype ones and avoid locale problems --*/ -#define spacep(p) (*(p) == ' ' || *(p) == '\t') -#define digitp(p) (*(p) >= '0' && *(p) <= '9') -#define hexdigitp(a) (digitp (a) \ - || (*(a) >= 'A' && *(a) <= 'F') \ - || (*(a) >= 'a' && *(a) <= 'f')) -/* the atoi macros assume that the buffer has only valid digits */ -#define atoi_1(p) (*(p) - '0' ) -#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) -#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) -#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)) - - - -#endif /*GNUPG_COMMON_UTIL_H*/ - - - - - - - - diff --git a/common/vasprintf.c b/common/vasprintf.c deleted file mode 100644 index 2af2d3a20..000000000 --- a/common/vasprintf.c +++ /dev/null @@ -1,169 +0,0 @@ -/* Like vsprintf but provides a pointer to malloc'd storage, which must - be freed by the caller. - Copyright (C) 1994, 2002 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include - -#ifdef TEST -int global_total_width; -#endif - -int -vasprintf (char **result, const char *format, va_list *args) -{ - const char *p = format; - /* Add one to make sure that it is never zero, which might cause malloc - to return NULL. */ - int total_width = strlen (format) + 1; - va_list ap; - -#ifdef va_copy - va_copy (ap, args); -#else -#ifdef __va_copy - __va_copy (ap, args); -#else - memcpy (&ap, args, sizeof (va_list)); -#endif /* __va_copy */ -#endif /* va_copy */ - - while (*p != '\0') - { - if (*p++ == '%') - { - while (strchr ("-+ #0", *p)) - ++p; - if (*p == '*') - { - ++p; - total_width += abs (va_arg (ap, int)); - } - else - total_width += strtoul (p, (char**)&p, 10); - if (*p == '.') - { - ++p; - if (*p == '*') - { - ++p; - total_width += abs (va_arg (ap, int)); - } - else - total_width += strtoul (p, (char**)&p, 10); - } - while (strchr ("hlL", *p)) - ++p; - /* Should be big enough for any format specifier except %s - and floats. */ - total_width += 30; - switch (*p) - { - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - case 'c': - (void) va_arg (ap, int); - break; - case 'f': - case 'e': - case 'E': - case 'g': - case 'G': - (void) va_arg (ap, double); - /* Since an ieee double can have an exponent of 307, we'll - make the buffer wide enough to cover the gross case. */ - total_width += 307; - break; - case 's': - { - char *tmp = va_arg (ap, char *); - if (tmp) - total_width += strlen (tmp); - else /* in case the vsprintf does prints a text */ - total_width += 25; /* e.g. "(null pointer reference)" */ - } - break; - case 'p': - case 'n': - (void) va_arg (ap, char *); - break; - } - } - } -#ifdef TEST - global_total_width = total_width; -#endif - *result = malloc (total_width); - if (*result != NULL) - return vsprintf (*result, format, *args); - else - return 0; -} - - -int -asprintf (char **buf, const char *fmt, ...) -{ - int status; - va_list ap; - - va_start (ap, fmt); - status = vasprintf (buf, fmt, ap); - va_end (ap); - return status; -} - - -#ifdef TEST -void -checkit (const char* format, ...) -{ - va_list args; - char *result; - - va_start (args, format); - vasprintf (&result, format, args); - if (strlen (result) < global_total_width) - printf ("PASS: "); - else - printf ("FAIL: "); - printf ("%d %s\n", global_total_width, result); -} - -int -main (void) -{ - checkit ("%d", 0x12345678); - checkit ("%200d", 5); - checkit ("%.300d", 6); - checkit ("%100.150d", 7); - checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\ -777777777777777777333333333333366666666666622222222222777777777777733333"); - checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx"); -} -#endif /* TEST */ diff --git a/kbx/ChangeLog b/kbx/ChangeLog deleted file mode 100644 index 351ec5d13..000000000 --- a/kbx/ChangeLog +++ /dev/null @@ -1,102 +0,0 @@ -2002-08-10 Werner Koch - - * keybox-search.c (blob_cmp_fpr_part): New. - (has_short_kid, has_long_kid): Implemented. - -2002-07-22 Werner Koch - - * keybox-defs.h: New BLOBTYPTE_EMPTY. - * keybox-dump.c (_keybox_dump_blob): Handle new type. - * keybox-file.c (_keybox_read_blob): Skip over empty blobs. Store - the file offset. - * keybox-blob.c (_keybox_new_blob): Add new arg OFF. - (_keybox_get_blob_fileoffset): New. - * keybox-update.c (keybox_delete): Implemented. - -2002-06-19 Werner Koch - - * keybox-init.c (keybox_set_ephemeral): New. - * keybox-blob.c (create_blob_header): Store epheermal flag. - (_keybox_create_x509_blob): Pass epheermal flag on. - * keybox-update.c (keybox_insert_cert): Ditto. - * keybox-search.c (blob_get_blob_flags): New. - (keybox_search): Ignore ephemeral blobs when not in ephemeral mode. - - * keybox-dump.c (_keybox_dump_blob): Print blob flags as strings. - -2002-02-25 Werner Koch - - * keybox-search.c (blob_cmp_mail): Use case-insensitive compare - because mail addresses are in general case insensitive (well - RFC2822 allows for case sensitive mailbox parts, but this is in - general considired a Bad Thing). Add additional substr parameter - to allow for substring matches within the mail address. Change - all callers to pass this along. - (blob_cmp_name): Likewise but do the case-insensitive search only - in sub string mode. - (keybox_search): Implement MAILSUB and SUBSTR mode. - -2002-01-21 Werner Koch - - * keybox-search.c (keybox_search): Allow KEYDB_SEARCH_MODE_FPR20. - -2002-01-15 Werner Koch - - * keybox-search.c (blob_cmp_fpr): New. - (has_fingerprint): Implemented; - -2001-12-20 Werner Koch - - * keybox-blob.c (_keybox_create_x509_blob): Skip the leading - parenthesis of the serial number's S-exp. - (_keybox_create_x509_blob): And fixed length calculation. - (create_blob_header): Don't add an offset when writing the serial. - -2001-12-18 Werner Koch - - * Makefile.am (AM_CPPFLAGS): Add flags for libksba - - * keybox-blob.c (_keybox_create_x509_blob): Use - gcry_sexp_canon_len to get the length of the serial number. - (_keybox_release_blob): Need to use a new serialbuf to free the memory. - -2001-12-17 Werner Koch - - * keybox-search.c: Changed the way the serial number is - represented. - -2001-12-15 Werner Koch - - * keybox-search.c (blob_cmp_name): There is no terminating 0 stored - for the uid; fixed length compare. - -2001-12-14 Werner Koch - - * keybox-blob.c (x509_email_kludge): New. - (_keybox_create_x509_blob): Insert an extra email address if the - subject's DN has an email part. - * keybox-defs.h: Added the xtoi_2 and digitp macros. - -2001-12-13 Werner Koch - - * keybox-search.c (blob_cmp_name): Kludge to allow searching for - more than one name. - (has_subject_or_alt): New. - (blob_cmp_mail): New. - (has_mail): New. - (keybox_search): Implemented exact search and exact mail search. - - * kbx/keybox-blob.c (_keybox_create_x509_blob): Insert alternate - names. - - - Copyright 2001 g10 Code GmbH - - 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. - \ No newline at end of file diff --git a/kbx/Makefile.am b/kbx/Makefile.am deleted file mode 100644 index 4e7170379..000000000 --- a/kbx/Makefile.am +++ /dev/null @@ -1,53 +0,0 @@ -# Keybox Makefile -# 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 - -## Process this file with automake to produce Makefile.in - -localedir = $(datadir)/locale -INCLUDES = -I../intl -DLOCALEDIR=\"$(localedir)\" - -EXTRA_DIST = mkerrors -AM_CPPFLAGS = $(KSBA_CFLAGS) $(LIBGCRYPT_CLFAGS) -BUILT_SOURCES = keybox-errors.c - -noinst_LIBRARIES = libkeybox.a -bin_PROGRAMS = kbxutil - -common_sources = \ - keybox.h keybox-defs.h keybox-search-desc.h \ - keybox-util.c \ - keybox-errors.c \ - keybox-init.c \ - keybox-blob.c \ - keybox-file.c \ - keybox-search.c \ - keybox-update.c \ - keybox-dump.c - - -libkeybox_a_SOURCES = $(common_sources) - -kbxutil_SOURCES = kbxutil.c $(common_sources) -kbxutil_LDADD = ../jnlib/libjnlib.a $(KSBA_LIBS) $(LIBGCRYPT_LIBS) - -keybox-errors.c : keybox.h mkerrors - $(srcdir)/mkerrors < $(srcdir)/keybox.h > keybox-errors.c - - - diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c deleted file mode 100644 index b733b81c8..000000000 --- a/kbx/kbxutil.c +++ /dev/null @@ -1,338 +0,0 @@ -/* kbxutil.c - The Keybox utility - * Copyright (C) 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 -#include -#include -#include -#include -#include -#include - -#include - -#include "../jnlib/logging.h" -#include "../jnlib/argparse.h" -#include "../jnlib/stringhelp.h" -#include "../common/i18n.h" -#include "keybox-defs.h" - -enum cmd_and_opt_values { - aNull = 0, - oArmor = 'a', - oDryRun = 'n', - oOutput = 'o', - oQuiet = 'q', - oVerbose = 'v', - - aNoSuchCmd = 500, /* force other values not to be a letter */ - aFindByFpr, - aFindByKid, - aFindByUid, - - oDebug, - oDebugAll, - - oNoArmor, - - - aTest -}; - - -static ARGPARSE_OPTS opts[] = { - { 300, NULL, 0, N_("@Commands:\n ") }, - - { aFindByFpr, "find-by-fpr", 0, "|FPR| find key using it's fingerprnt" }, - { aFindByKid, "find-by-kid", 0, "|KID| find key using it's keyid" }, - { aFindByUid, "find-by-uid", 0, "|NAME| find key by user name" }, - - { 301, NULL, 0, N_("@\nOptions:\n ") }, - - { oArmor, "armor", 0, N_("create ascii armored output")}, - { oArmor, "armour", 0, "@" }, - { oOutput, "output", 2, N_("use as output file")}, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, - { oDryRun, "dry-run", 0, N_("do not make any changes") }, - - { oDebug, "debug" ,4|16, N_("set debugging flags")}, - { oDebugAll, "debug-all" ,0, N_("enable full debugging")}, - - {0} /* end of list */ -}; - - -void myexit (int rc); - -int keybox_errors_seen = 0; - - -static const char * -my_strusage( int level ) -{ - const char *p; - switch( level ) { - case 11: p = "kbxutil (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = - _("Please report bugs to " PACKAGE_BUGREPORT ".\n"); - break; - case 1: - case 40: p = - _("Usage: kbxutil [options] [files] (-h for help)"); - break; - case 41: p = - _("Syntax: kbxutil [options] [files]\n" - "list, export, import Keybox data\n"); - break; - - - default: p = NULL; - } - return p; -} - - -static void -i18n_init(void) -{ - #ifdef USE_SIMPLE_GETTEXT - set_gettext_file( PACKAGE ); - #else - #ifdef ENABLE_NLS - #ifdef HAVE_LC_MESSAGES - setlocale( LC_TIME, "" ); - setlocale( LC_MESSAGES, "" ); - #else - setlocale( LC_ALL, "" ); - #endif - bindtextdomain( PACKAGE, LOCALEDIR ); - textdomain( PACKAGE ); - #endif - #endif -} - - -/* static void */ -/* wrong_args( const char *text ) */ -/* { */ -/* log_error("usage: kbxutil %s\n", text); */ -/* myexit ( 1 ); */ -/* } */ - - -#if 0 -static int -hextobyte( const byte *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; -} -#endif - -#if 0 -static char * -format_fingerprint ( const char *s ) -{ - int i, c; - byte fpr[20]; - - for (i=0; i < 20 && *s; ) { - if ( *s == ' ' || *s == '\t' ) { - s++; - continue; - } - c = hextobyte(s); - if (c == -1) { - return NULL; - } - fpr[i++] = c; - s += 2; - } - return gcry_xstrdup ( fpr ); -} -#endif - -#if 0 -static int -format_keyid ( const char *s, u32 *kid ) -{ - char helpbuf[9]; - switch ( strlen ( s ) ) { - case 8: - kid[0] = 0; - kid[1] = strtoul( s, NULL, 16 ); - return 10; - - case 16: - mem2str( helpbuf, s, 9 ); - kid[0] = strtoul( helpbuf, NULL, 16 ); - kid[1] = strtoul( s+8, NULL, 16 ); - return 11; - } - return 0; /* error */ -} -#endif - - -int -main( int argc, char **argv ) -{ - ARGPARSE_ARGS pargs; - enum cmd_and_opt_values cmd = 0; - - set_strusage( my_strusage ); - /*log_set_name("kbxutil"); fixme */ -#if 0 - /* check that the libraries are suitable. Do it here because - * the option parse may need services of the library */ - if ( !gcry_check_version ( "1.1.4" ) ) - { - log_fatal(_("libgcrypt is too old (need %s, have %s)\n"), - "1.1.4", gcry_check_version(NULL) ); - } -#endif - - /*create_dotlock(NULL); register locking cleanup */ - i18n_init(); - - /* We need to use the gcry malloc function because jnlib does use them */ - keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free ); - - - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - while (arg_parse( &pargs, opts) ) - { - switch (pargs.r_opt) - { - case oVerbose: - /*opt.verbose++;*/ - /*gcry_control( GCRYCTL_SET_VERBOSITY, (int)opt.verbose );*/ - break; - case oDebug: - /*opt.debug |= pargs.r.ret_ulong; */ - break; - case oDebugAll: - /*opt.debug = ~0;*/ - break; - - case aFindByFpr: - case aFindByKid: - case aFindByUid: - cmd = pargs.r_opt; - break; - - default: - pargs.err = 2; - break; - } - } - if (log_get_errorcount(0) ) - myexit(2); - - if (!cmd) - { /* default is to list a KBX file */ - if (!argc) - _keybox_dump_file (NULL, stdout); - else - { - for (; argc; argc--, argv++) - _keybox_dump_file (*argv, stdout); - } - } -#if 0 - else if ( cmd == aFindByFpr ) { - char *fpr; - if ( argc != 2 ) - wrong_args ("kbxfile foingerprint"); - fpr = format_fingerprint ( argv[1] ); - if ( !fpr ) - log_error ("invalid formatted fingerprint\n"); - else { - kbxfile_search_by_fpr ( argv[0], fpr ); - gcry_free ( fpr ); - } - } - else if ( cmd == aFindByKid ) { - u32 kid[2]; - int mode; - - if ( argc != 2 ) - wrong_args ("kbxfile short-or-long-keyid"); - mode = format_keyid ( argv[1], kid ); - if ( !mode ) - log_error ("invalid formatted keyID\n"); - else { - kbxfile_search_by_kid ( argv[0], kid, mode ); - } - } - else if ( cmd == aFindByUid ) { - if ( argc != 2 ) - wrong_args ("kbxfile userID"); - kbxfile_search_by_uid ( argv[0], argv[1] ); - } -#endif - else - log_error ("unsupported action\n"); - - myexit(0); - return 8; /*NEVER REACHED*/ -} - - -void -myexit( int rc ) -{ - /* 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 ); */ - rc = rc? rc : log_get_errorcount(0)? 2 : - keybox_errors_seen? 1 : 0; - exit(rc ); -} - - diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c deleted file mode 100644 index 48e2b5b87..000000000 --- a/kbx/keybox-blob.c +++ /dev/null @@ -1,1007 +0,0 @@ -/* keybox-blob.c - KBX Blob handling - * Copyright (C) 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 - */ - - -/* The keybox data formats - -The KeyBox uses an augmented OpenPGP/X.509 key format. This makes -random access to a keyblock/Certificate easier and also gives the -opportunity to store additional information (e.g. the fingerprint) -along with the key. All integers are stored in network byte order, -offsets are counted from the beginning of the Blob. - -The first record of a plain KBX file has a special format: - - u32 length of the first record - byte Blob type (1) - byte version number (1) - byte reserved - byte reserved - u32 magic 'KBXf' - byte pgp_marginals used for validity calculation of this file - byte pgp_completes ditto. - byte pgp_cert_depth ditto. - -The OpenPGP and X.509 blob are verry similiar, things which are -X.509 specific are noted like [X.509: xxx] - - u32 length of this blob (including these 4 bytes) - byte Blob type (2) [X509: 3] - byte version number of this blob type (1) - u16 Blob flags - bit 0 = contains secret key material - bit 1 = ephemeral blob (e.g. used while quering external resources) - - u32 offset to the OpenPGP keyblock or X509 DER encoded certificate - u32 and its length - u16 number of keys (at least 1!) [X509: always 1] - u16 size of additional key information - n times: - b20 The keys fingerprint - (fingerprints are always 20 bytes, MD5 left padded with zeroes) - u32 offset to the n-th key's keyID (a keyID is always 8 byte) - or 0 if not known which is the case opnly for X509. - u16 special key flags - bit 0 = - u16 reserved - u16 size of serialnumber(may be zero) - n u16 (see above) bytes of serial number - u16 number of user IDs - u16 size of additional user ID information - n times: - u32 offset to the n-th user ID - u32 length of this user ID. - u16 special user ID flags. - bit 0 = - byte validity - byte reserved - [For X509, the first user ID is the ISsuer, the second the subject - and the others are subjectAltNames] - u16 number of signatures - u16 size of signature information (4) - u32 expiration time of signature with some special values: - 0x00000000 = not checked - 0x00000001 = missing key - 0x00000002 = bad signature - 0x10000000 = valid and expires at some date in 1978. - 0xffffffff = valid and does not expire - u8 assigned ownertrust [X509: no used] - u8 all_validity [X509: no used] - u16 reserved - u32 recheck_after - u32 Newest timestamp in the keyblock (useful for KS syncronsiation?) - u32 Blob created at - u32 size of reserved space (not including this field) - reserved space - - Here we might want to put other data - - Here comes the keyblock - - maybe we put a signature here later. - - b16 MD5 checksum (useful for KS syncronisation), we might also want to use - a mac here. - b4 resevered - -*/ - - -#include -#include -#include -#include -#include -#include -#include - -#ifdef KEYBOX_WITH_OPENPGP -/* include stuff to parse the packets */ -#endif -#ifdef KEYBOX_WITH_X509 -#include -#endif - -#include "keybox-defs.h" - - -/* special values of the signature status */ -#define SF_NONE(a) ( !(a) ) -#define SF_NOKEY(a) ((a) & (1<<0)) -#define SF_BAD(a) ((a) & (1<<1)) -#define SF_VALID(a) ((a) & (1<<29)) - - -struct membuf { - size_t len; - size_t size; - char *buf; - int out_of_core; -}; - - -/* #if MAX_FINGERPRINT_LEN < 20 */ -/* #error fingerprints are 20 bytes */ -/* #endif */ - -struct keyboxblob_key { - char fpr[20]; - u32 off_kid; - ulong off_kid_addr; - u16 flags; -}; -struct keyboxblob_uid { - ulong off_addr; - char *name; /* used only with x509 */ - u32 len; - u16 flags; - byte validity; -}; - -struct keyid_list { - struct keyid_list *next; - int seqno; - byte kid[8]; -}; - -struct fixup_list { - struct fixup_list *next; - u32 off; - u32 val; -}; - - -struct keyboxblob { - byte *blob; - size_t bloblen; - off_t fileoffset; - - /* stuff used only by keybox_create_blob */ - unsigned char *serialbuf; - const unsigned char *serial; - size_t seriallen; - int nkeys; - struct keyboxblob_key *keys; - int nuids; - struct keyboxblob_uid *uids; - int nsigs; - u32 *sigs; - struct fixup_list *fixups; - int fixup_out_of_core; - - struct keyid_list *temp_kids; - struct membuf bufbuf; /* temporary store for the blob */ - struct membuf *buf; -}; - - - -/* A simple implemnation of a dynamic buffer. Use init_membuf() to - create a buffer, put_membuf to append bytes and get_membuf to - release and return the buffer. Allocation errors are detected but - only returned at the final get_membuf(), this helps not to clutter - the code with out of core checks. */ - -static void -init_membuf (struct membuf *mb, int initiallen) -{ - mb->len = 0; - mb->size = initiallen; - mb->out_of_core = 0; - mb->buf = xtrymalloc (initiallen); - if (!mb->buf) - mb->out_of_core = 1; -} - -static void -put_membuf (struct membuf *mb, const void *buf, size_t len) -{ - if (mb->out_of_core) - return; - - if (mb->len + len >= mb->size) - { - char *p; - - mb->size += len + 1024; - p = xtryrealloc (mb->buf, mb->size); - if (!p) - { - mb->out_of_core = 1; - return; - } - mb->buf = p; - } - memcpy (mb->buf + mb->len, buf, len); - mb->len += len; -} - -static void * -get_membuf (struct membuf *mb, size_t *len) -{ - char *p; - - if (mb->out_of_core) - { - xfree (mb->buf); - mb->buf = NULL; - return NULL; - } - - p = mb->buf; - *len = mb->len; - mb->buf = NULL; - mb->out_of_core = 1; /* don't allow a reuse */ - return p; -} - - -static void -put8 (struct membuf *mb, byte a ) -{ - put_membuf (mb, &a, 1); -} - -static void -put16 (struct membuf *mb, u16 a ) -{ - unsigned char tmp[2]; - tmp[0] = a>>8; - tmp[1] = a; - put_membuf (mb, tmp, 2); -} - -static void -put32 (struct membuf *mb, u32 a ) -{ - unsigned char tmp[4]; - tmp[0] = a>>24; - tmp[1] = a>>16; - tmp[2] = a>>8; - tmp[3] = a; - put_membuf (mb, tmp, 4); -} - - -/* Store a value in the fixup list */ -static void -add_fixup (KEYBOXBLOB blob, u32 off, u32 val) -{ - struct fixup_list *fl; - - if (blob->fixup_out_of_core) - return; - - fl = xtrycalloc(1, sizeof *fl); - if (!fl) - blob->fixup_out_of_core = 1; - else - { - fl->off = off; - fl->val = val; - fl->next = blob->fixups; - blob->fixups = fl; - } -} - - -/* - Some wrappers -*/ - -static u32 -make_timestamp (void) -{ - return time(NULL); -} - - - -#ifdef KEYBOX_WITH_OPENPGP -/* - OpenPGP specific stuff -*/ - - -/* - We must store the keyid at some place because we can't calculate the - offset yet. This is only used for v3 keyIDs. Function returns an - index value for later fixup or -1 for out of core. The value must be - a non-zero value */ -static int -pgp_temp_store_kid (KEYBOXBLOB blob, PKT_public_key *pk) -{ - struct keyid_list *k, *r; - - k = xtrymalloc (sizeof *k); - if (!k) - return -1; - k->kid[0] = pk->keyid[0] >> 24 ; - k->kid[1] = pk->keyid[0] >> 16 ; - k->kid[2] = pk->keyid[0] >> 8 ; - k->kid[3] = pk->keyid[0] ; - k->kid[4] = pk->keyid[0] >> 24 ; - k->kid[5] = pk->keyid[0] >> 16 ; - k->kid[6] = pk->keyid[0] >> 8 ; - k->kid[7] = pk->keyid[0] ; - k->seqno = 0; - k->next = blob->temp_kids; - blob->temp_kids = k; - for (r=k; r; r = r->next) - k->seqno++; - - return k->seqno; -} - -static int -pgp_create_key_part (KEYBOXBLOB blob, KBNODE keyblock) -{ - KBNODE node; - size_t fprlen; - int n; - - for (n=0, 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; - char tmp[20]; - - fingerprint_from_pk (pk, tmp , &fprlen); - memcpy (blob->keys[n].fpr, tmp, 20); - if ( fprlen != 20 ) /*v3 fpr - shift right and fill with zeroes*/ - { - assert (fprlen == 16); - memmove (blob->keys[n].fpr+4, blob->keys[n].fpr, 16); - memset (blob->keys[n].fpr, 0, 4); - blob->keys[n].off_kid = pgp_temp_store_kid (blob, pk); - } - else - { - blob->keys[n].off_kid = 0; /* will be fixed up later */ - } - blob->keys[n].flags = 0; - n++; - } - else if ( node->pkt->pkttype == PKT_SECRET_KEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) - { - never_reached (); /* actually not yet implemented */ - } - } - assert (n == blob->nkeys); - return 0; -} - -static int -pgp_create_uid_part (KEYBOXBLOB blob, KBNODE keyblock) -{ - KBNODE node; - int n; - - for (n=0, node = keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_USER_ID) - { - PKT_user_id *u = node->pkt->pkt.user_id; - - blob->uids[n].len = u->len; - blob->uids[n].flags = 0; - blob->uids[n].validity = 0; - n++; - } - } - assert (n == blob->nuids); - return 0; -} - -static int -pgp_create_sig_part (KEYBOXBLOB blob, KBNODE keyblock) -{ - KBNODE node; - int n; - - for (n=0, node = keyblock; node; node = node->next) - { - if (node->pkt->pkttype == PKT_SIGNATURE) - { - PKT_signature *sig = node->pkt->pkt.signature; - - blob->sigs[n] = 0; /* FIXME: check the signature here */ - n++; - } - } - assert( n == blob->nsigs ); - return 0; -} - -static int -pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock) -{ - struct membuf *a = blob->buf; - KBNODE node; - int rc; - int n; - u32 kbstart = a->len; - - add_fixup (blob, kbstart); - - for (n = 0, node = keyblock; node; node = node->next) - { - rc = build_packet ( a, node->pkt ); - if ( rc ) { - gpg_log_error ("build_packet(%d) for keyboxblob failed: %s\n", - node->pkt->pkttype, gpg_errstr(rc) ); - return GPGERR_WRITE_FILE; - } - if ( node->pkt->pkttype == PKT_USER_ID ) - { - PKT_user_id *u = node->pkt->pkt.user_id; - /* build_packet has set the offset of the name into u ; - * now we can do the fixup */ - add_fixup (blob, blob->uids[n].off_addr, u->stored_at); - n++; - } - } - assert (n == blob->nuids); - - add_fixup (blob, a->len - kbstart); - return 0; -} - -#endif /*KEYBOX_WITH_OPENPGP*/ - - -#ifdef KEYBOX_WITH_X509 -/* - X.509 specific stuff - */ - -/* Write the raw certificate out */ -static int -x509_create_blob_cert (KEYBOXBLOB blob, KsbaCert cert) -{ - struct membuf *a = blob->buf; - const unsigned char *image; - size_t length; - u32 kbstart = a->len; - - /* Store our offset for later fixup */ - add_fixup (blob, 8, kbstart); - - image = ksba_cert_get_image (cert, &length); - if (!image) - return KEYBOX_General_Error; - put_membuf (a, image, length); - - add_fixup (blob, 12, a->len - kbstart); - return 0; -} - -#endif /*KEYBOX_WITH_X509*/ - -/* Write a stored keyID out to the buffer */ -static void -write_stored_kid (KEYBOXBLOB blob, int seqno) -{ - struct keyid_list *r; - - for ( r = blob->temp_kids; r; r = r->next ) - { - if (r->seqno == seqno ) - { - put_membuf (blob->buf, r->kid, 8); - return; - } - } - never_reached (); -} - -/* Release a list of key IDs */ -static void -release_kid_list (struct keyid_list *kl) -{ - struct keyid_list *r, *r2; - - for ( r = kl; r; r = r2 ) - { - r2 = r->next; - xfree (r); - } -} - - - -static int -create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral) -{ - struct membuf *a = blob->buf; - int i; - - put32 ( a, 0 ); /* blob length, needs fixup */ - put8 ( a, blobtype); - put8 ( a, 1 ); /* blob type version */ - put16 ( a, as_ephemeral? 2:0 ); /* blob flags */ - - put32 ( a, 0 ); /* offset to the raw data, needs fixup */ - put32 ( a, 0 ); /* length of the raw data, needs fixup */ - - put16 ( a, blob->nkeys ); - put16 ( a, 20 + 4 + 2 + 2 ); /* size of key info */ - for ( i=0; i < blob->nkeys; i++ ) - { - put_membuf (a, blob->keys[i].fpr, 20); - blob->keys[i].off_kid_addr = a->len; - put32 ( a, 0 ); /* offset to keyid, fixed up later */ - put16 ( a, blob->keys[i].flags ); - put16 ( a, 0 ); /* reserved */ - } - - put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/ - if (blob->serial) - put_membuf (a, blob->serial, blob->seriallen); - - put16 ( a, blob->nuids ); - put16 ( a, 4 + 4 + 2 + 1 + 1 ); /* size of uid info */ - for (i=0; i < blob->nuids; i++) - { - blob->uids[i].off_addr = a->len; - put32 ( a, 0 ); /* offset to userid, fixed up later */ - put32 ( a, blob->uids[i].len ); - put16 ( a, blob->uids[i].flags ); - put8 ( a, 0 ); /* validity */ - put8 ( a, 0 ); /* reserved */ - } - - put16 ( a, blob->nsigs ); - put16 ( a, 4 ); /* size of sig info */ - for (i=0; i < blob->nsigs; i++) - { - put32 ( a, blob->sigs[i]); - } - - put8 ( a, 0 ); /* assigned ownertrust */ - put8 ( a, 0 ); /* validity of all user IDs */ - put16 ( a, 0 ); /* reserved */ - put32 ( a, 0 ); /* time of next recheck */ - put32 ( a, 0 ); /* newest timestamp (none) */ - put32 ( a, make_timestamp() ); /* creation time */ - put32 ( a, 0 ); /* size of reserved space */ - /* reserved space (which is currently of size 0) */ - - /* space where we write keyIDs and and other stuff so that the - pointers can actually point to somewhere */ - if (blobtype == BLOBTYPE_PGP) - { - /* We need to store the keyids for all pgp v3 keys because those key - IDs are not part of the fingerprint. While we are doing that, we - fixup all the keyID offsets */ - for (i=0; i < blob->nkeys; i++ ) - { - if (blob->keys[i].off_kid) - { /* this is a v3 one */ - add_fixup (blob, blob->keys[i].off_kid_addr, a->len); - write_stored_kid (blob, blob->keys[i].off_kid); - } - else - { /* the better v4 key IDs - just store an offset 8 bytes back */ - add_fixup (blob, blob->keys[i].off_kid_addr, - blob->keys[i].off_kid_addr - 8); - } - } - } - - if (blobtype == BLOBTYPE_X509) - { - /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to - the utf-8 string represenation of them */ - for (i=0; i < blob->nuids; i++ ) - { - if (blob->uids[i].name) - { /* this is a v3 one */ - add_fixup (blob, blob->uids[i].off_addr, a->len); - put_membuf (blob->buf, blob->uids[i].name, blob->uids[i].len); - } - } - } - - return 0; -} - - - -static int -create_blob_trailer (KEYBOXBLOB blob) -{ - return 0; -} - - -static int -create_blob_finish (KEYBOXBLOB blob) -{ - struct membuf *a = blob->buf; - byte *p; - char *pp; - int i; - size_t n; - - /* write a placeholder for the checksum */ - for (i = 0; i < 16; i++ ) - put32 (a, 0); /* Hmmm: why put32() ?? */ - - /* get the memory area */ - p = get_membuf (a, &n); - if (!p) - return KEYBOX_Out_Of_Core; - assert (n >= 20); - - /* fixup the length */ - add_fixup (blob, 0, n); - - /* do the fixups */ - if (blob->fixup_out_of_core) - return KEYBOX_Out_Of_Core; - - { - struct fixup_list *fl; - for (fl = blob->fixups; fl; fl = fl->next) - { - assert (fl->off+4 <= n); - p[fl->off+0] = fl->val >> 24; - p[fl->off+1] = fl->val >> 16; - p[fl->off+2] = fl->val >> 8; - p[fl->off+3] = fl->val; - } - } - - /* calculate and store the MD5 checksum */ - gcry_md_hash_buffer (GCRY_MD_MD5, p + n - 16, p, n - 16); - - pp = xtrymalloc (n); - if ( !pp ) - return KEYBOX_Out_Of_Core; - memcpy (pp , p, n); - blob->blob = pp; - blob->bloblen = n; - - return 0; -} - - -#ifdef KEYBOX_WITH_OPENPGP - -int -_keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock, int as_ephemeral) -{ - int rc = 0; - KBNODE node; - KEYBOXBLOB blob; - - *r_blob = NULL; - blob = xtrycalloc (1, sizeof *blob); - if( !blob ) - return KEYBOX_Out_Of_Core; - - /* fixme: Do some sanity checks on the keyblock */ - - /* count userids and keys so that we can allocate the arrays */ - for (node = keyblock; node; node = node->next) - { - switch (node->pkt->pkttype) - { - case PKT_PUBLIC_KEY: - case PKT_SECRET_KEY: - case PKT_PUBLIC_SUBKEY: - case PKT_SECRET_SUBKEY: blob->nkeys++; break; - case PKT_USER_ID: blob->nuids++; break; - case PKT_SIGNATURE: blob->nsigs++; break; - default: break; - } - } - - blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys ); - blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids ); - blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs ); - if (!blob->keys || !blob->uids || !blob->sigs) - { - rc = KEYBOX_Out_Of_Core; - goto leave; - } - - rc = pgp_create_key_part ( blob, keyblock ); - if (rc) - goto leave; - rc = pgp_create_uid_part ( blob, keyblock ); - if (rc) - goto leave; - rc = pgp_create_sig_part ( blob, keyblock ); - if (rc) - goto leave; - - init_membuf (&blob->bufbuf, 1024); - blob->buf = &blob->bufbuf; - rc = create_blob_header (blob, BLOBTYPE_OPENPGP, as_ephemeral); - if (rc) - goto leave; - rc = pgp_create_blob_keyblock (blob, keyblock); - if (rc) - goto leave; - rc = create_blob_trailer (blob); - if (rc) - goto leave; - rc = create_blob_finish ( blob ); - if (rc) - goto leave; - - - leave: - release_kid_list (blob->temp_kids); - blob->temp_kids = NULL; - if (rc) - { - keybox_release_blob (blob); - *r_blob = NULL; - } - else - { - *r_blob = blob; - } - return rc; -} -#endif /*KEYBOX_WITH_OPENPGP*/ - -#ifdef KEYBOX_WITH_X509 - -/* return an allocated string with the email address extracted from a - DN */ -static char * -x509_email_kludge (const char *name) -{ - const unsigned char *p; - unsigned char *buf; - int n; - - if (strncmp (name, "1.2.840.113549.1.9.1=#", 22)) - return NULL; - /* This looks pretty much like an email address in the subject's DN - we use this to add an additional user ID entry. This way, - openSSL generated keys get a nicer and usable listing */ - name += 22; - for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++) - ; - if (*p != '#' || !n) - return NULL; - buf = xtrymalloc (n+3); - if (!buf) - return NULL; /* oops, out of core */ - *buf = '<'; - for (n=1, p=name; *p != '#'; p +=2, n++) - buf[n] = xtoi_2 (p); - buf[n++] = '>'; - buf[n] = 0; - return buf; -} - - - -/* Note: We should move calculation of the digest into libksba and - remove that parameter */ -int -_keybox_create_x509_blob (KEYBOXBLOB *r_blob, KsbaCert cert, - unsigned char *sha1_digest, int as_ephemeral) -{ - int i, rc = 0; - KEYBOXBLOB blob; - unsigned char *p; - unsigned char **names = NULL; - size_t max_names; - - *r_blob = NULL; - blob = xtrycalloc (1, sizeof *blob); - if( !blob ) - return KEYBOX_Out_Of_Core; - - p = ksba_cert_get_serial (cert); - if (p) - { - size_t n, len; - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (n < 2) - { - xfree (p); - return KEYBOX_General_Error; - } - blob->serialbuf = p; - p++; n--; /* skip '(' */ - for (len=0; n && *p && *p != ':' && digitp (p); n--, p++) - len = len*10 + atoi_1 (p); - if (*p != ':') - { - xfree (blob->serialbuf); - blob->serialbuf = NULL; - return KEYBOX_General_Error; - } - p++; - blob->serial = p; - blob->seriallen = len; - } - - blob->nkeys = 1; - - /* create list of names */ - blob->nuids = 0; - max_names = 100; - names = xtrymalloc (max_names * sizeof *names); - if (!names) - { - rc = KEYBOX_Out_Of_Core; - goto leave; - } - p = ksba_cert_get_issuer (cert, 0); - if (!p) - { - rc = KEYBOX_Missing_Value; - goto leave; - } - names[blob->nuids++] = p; - for (i=0; (p = ksba_cert_get_subject (cert, i)); i++) - { - - if (blob->nuids >= max_names) - { - unsigned char **tmp; - - max_names += 100; - tmp = xtryrealloc (names, max_names * sizeof *names); - if (!tmp) - { - rc = KEYBOX_Out_Of_Core; - goto leave; - } - } - names[blob->nuids++] = p; - if (!i && (p=x509_email_kludge (p))) - names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/ - } - - /* space for signature information */ - blob->nsigs = 1; - - blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys ); - blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids ); - blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs ); - if (!blob->keys || !blob->uids || !blob->sigs) - { - rc = KEYBOX_Out_Of_Core; - goto leave; - } - - memcpy (blob->keys[0].fpr, sha1_digest, 20); - blob->keys[0].off_kid = 0; /* We don't have keyids */ - blob->keys[0].flags = 0; - - /* issuer and subject names */ - for (i=0; i < blob->nuids; i++) - { - blob->uids[i].name = names[i]; - blob->uids[i].len = strlen(names[i]); - names[i] = NULL; - blob->uids[i].flags = 0; - blob->uids[i].validity = 0; - } - xfree (names); - names = NULL; - - /* signatures */ - blob->sigs[0] = 0; /* not yet checked */ - - /* Create a temporary buffer for further processing */ - init_membuf (&blob->bufbuf, 1024); - blob->buf = &blob->bufbuf; - /* write out what we already have */ - rc = create_blob_header (blob, BLOBTYPE_X509, as_ephemeral); - if (rc) - goto leave; - rc = x509_create_blob_cert (blob, cert); - if (rc) - goto leave; - rc = create_blob_trailer (blob); - if (rc) - goto leave; - rc = create_blob_finish ( blob ); - if (rc) - goto leave; - - - leave: - release_kid_list (blob->temp_kids); - blob->temp_kids = NULL; - if (blob && names) - { - for (i=0; i < blob->nuids; i++) - xfree (names[i]); - } - xfree (names); - if (rc) - { - _keybox_release_blob (blob); - *r_blob = NULL; - } - else - { - *r_blob = blob; - } - return rc; -} -#endif /*KEYBOX_WITH_X509*/ - - - -int -_keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen, off_t off) -{ - KEYBOXBLOB blob; - - *r_blob = NULL; - blob = xtrycalloc (1, sizeof *blob); - if (!blob) - return KEYBOX_Out_Of_Core; - - blob->blob = image; - blob->bloblen = imagelen; - blob->fileoffset = off; - *r_blob = blob; - return 0; -} - -void -_keybox_release_blob (KEYBOXBLOB blob) -{ - int i; - if (!blob) - return; - /* hmmm: release membuf here?*/ - xfree (blob->keys ); - xfree (blob->serialbuf); - for (i=0; i < blob->nuids; i++) - xfree (blob->uids[i].name); - xfree (blob->uids ); - xfree (blob->sigs ); - xfree (blob->blob ); - xfree (blob ); -} - - - -const char * -_keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n ) -{ - *n = blob->bloblen; - return blob->blob; -} - -off_t -_keybox_get_blob_fileoffset (KEYBOXBLOB blob) -{ - return blob->fileoffset; -} - diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h deleted file mode 100644 index 1c66020f7..000000000 --- a/kbx/keybox-defs.h +++ /dev/null @@ -1,179 +0,0 @@ -/* keybox-defs.h - interal Keybox defintions - * 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 KEYBOX_DEFS_H -#define KEYBOX_DEFS_H 1 - -#include /* off_t */ -#include "keybox.h" - -#ifndef HAVE_BYTE_TYPEDEF -typedef unsigned char byte; /* fixme */ -#endif -#ifndef HAVE_U16_TYPEDEF -typedef unsigned short u16; /* fixme */ -#endif -#ifndef HAVE_U32_TYPEDEF -typedef unsigned int u32; /* fixme */ -#endif - -enum { - BLOBTYPE_EMPTY = 0, - BLOBTYPE_HEADER = 1, - BLOBTYPE_PGP = 2, - BLOBTYPE_X509 = 3 -}; - - -typedef struct keyboxblob *KEYBOXBLOB; - - -typedef struct keybox_name *KB_NAME; -typedef struct keybox_name const * CONST_KB_NAME; -struct keybox_name { - struct keybox_name *next; - int secret; - /*DOTLOCK lockhd;*/ - int is_locked; - int did_full_scan; - char fname[1]; -}; - - - -struct keybox_handle { - CONST_KB_NAME kb; - int secret; /* this is for a secret keybox */ - FILE *fp; - int eof; - int error; - int ephemeral; - struct { - KEYBOXBLOB blob; - 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; -}; - - -/* Don't know whether this is needed: */ -/* static struct { */ -/* const char *homedir; */ -/* int dry_run; */ -/* int quiet; */ -/* int verbose; */ -/* int preserve_permissions; */ -/* } keybox_opt; */ - - -/*-- keybox-blob.c --*/ -#ifdef KEYBOX_WITH_OPENPGP - /* fixme */ -#endif /*KEYBOX_WITH_OPENPGP*/ -#ifdef KEYBOX_WITH_X509 -int _keybox_create_x509_blob (KEYBOXBLOB *r_blob, KsbaCert cert, - unsigned char *sha1_digest, int as_ephemeral); -#endif /*KEYBOX_WITH_X509*/ - -int _keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen, - off_t off); -void _keybox_release_blob (KEYBOXBLOB blob); -const char *_keybox_get_blob_image (KEYBOXBLOB blob, size_t *n); -off_t _keybox_get_blob_fileoffset (KEYBOXBLOB blob); - -/*-- keybox-file.c --*/ -int _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp); -int _keybox_write_blob (KEYBOXBLOB blob, FILE *fp); - -/*-- keybox-dump.c --*/ -int _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp); -int _keybox_dump_file (const char *filename, FILE *outfp); - - -/*-- keybox-util.c --*/ -void *_keybox_malloc (size_t n); -void *_keybox_calloc (size_t n, size_t m); -void *_keybox_realloc (void *p, size_t n); -void _keybox_free (void *p); - -#define xtrymalloc(a) _keybox_malloc ((a)) -#define xtrycalloc(a,b) _keybox_calloc ((a),(b)) -#define xtryrealloc(a,b) _keybox_realloc((a),(b)) -#define xfree(a) _keybox_free ((a)) - - -#define DIM(v) (sizeof(v)/sizeof((v)[0])) -#define DIMof(type,member) DIM(((type *)0)->member) -#ifndef STR - #define STR(v) #v -#endif -#define STR2(v) STR(v) - -/* - a couple of handy macros -*/ - -#define return_if_fail(expr) do { \ - if (!(expr)) { \ - fprintf (stderr, "%s:%d: assertion `%s' failed\n", \ - __FILE__, __LINE__, #expr ); \ - return; \ - } } while (0) -#define return_null_if_fail(expr) do { \ - if (!(expr)) { \ - fprintf (stderr, "%s:%d: assertion `%s' failed\n", \ - __FILE__, __LINE__, #expr ); \ - return NULL; \ - } } while (0) -#define return_val_if_fail(expr,val) do { \ - if (!(expr)) { \ - fprintf (stderr, "%s:%d: assertion `%s' failed\n", \ - __FILE__, __LINE__, #expr ); \ - return (val); \ - } } while (0) -#define never_reached() do { \ - fprintf (stderr, "%s:%d: oops; should never get here\n", \ - __FILE__, __LINE__ ); \ - } while (0) - - -/* some macros to replace ctype ones and avoid locale problems */ -#define digitp(p) (*(p) >= '0' && *(p) <= '9') -#define hexdigitp(a) (digitp (a) \ - || (*(a) >= 'A' && *(a) <= 'F') \ - || (*(a) >= 'a' && *(a) <= 'f')) -/* the atoi macros assume that the buffer has only valid digits */ -#define atoi_1(p) (*(p) - '0' ) -#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) -#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) -#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)) - - -#endif /*KEYBOX_DEFS_H*/ - - diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c deleted file mode 100644 index 4fb3a4eb2..000000000 --- a/kbx/keybox-dump.c +++ /dev/null @@ -1,346 +0,0 @@ -/* keybox-dump.c - Debug helpers - * 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 - */ - -#include -#include -#include -#include -#include - -#include "keybox-defs.h" - -static ulong -get32 (const byte *buffer) -{ - ulong a; - a = *buffer << 24; - a |= buffer[1] << 16; - a |= buffer[2] << 8; - a |= buffer[3]; - return a; -} - -static ulong -get16 (const byte *buffer) -{ - ulong a; - a = *buffer << 8; - a |= buffer[1]; - return a; -} - -void -print_string (FILE *fp, const byte *p, size_t n, int delim) -{ - for ( ; n; n--, p++ ) - { - if (*p < 0x20 || (*p >= 0x7f && *p < 0xa0) || *p == delim) - { - putc('\\', fp); - if( *p == '\n' ) - putc('n', fp); - else if( *p == '\r' ) - putc('r', fp); - else if( *p == '\f' ) - putc('f', fp); - else if( *p == '\v' ) - putc('v', fp); - else if( *p == '\b' ) - putc('b', fp); - else if( !*p ) - putc('0', fp); - else - fprintf(fp, "x%02x", *p ); - } - else - putc(*p, fp); - } -} - - -static int -dump_header_blob (const byte *buffer, size_t length, FILE *fp) -{ - fprintf (fp, "Version: %d\n", buffer[5]); - if ( memcmp (buffer+8, "KBXf", 4)) - fprintf (fp, "[Error: invalid magic number]\n"); - return 0; -} - - -/* Dump one block to FP */ -int -_keybox_dump_blob (KEYBOXBLOB blob, FILE *fp) -{ - const byte *buffer; - size_t length; - int type; - ulong n, nkeys, keyinfolen; - ulong nuids, uidinfolen; - ulong nsigs, siginfolen; - ulong rawdata_off, rawdata_len; - ulong nserial; - const byte *p; - - buffer = _keybox_get_blob_image (blob, &length); - - if (length < 40) - { - fprintf (fp, "[blob too short]\n"); - return -1; - } - - n = get32( buffer ); - if (n > length) - fprintf (fp, "[blob larger than length - output truncated]\n"); - else - length = n; /* ignore the rest */ - - fprintf (fp, "Length: %lu\n", n ); - type = buffer[4]; - switch (type) - { - case BLOBTYPE_EMPTY: - fprintf (fp, "Type: Empty\n"); - return 0; - - case BLOBTYPE_HEADER: - fprintf (fp, "Type: Header\n"); - return dump_header_blob (buffer, length, fp); - case BLOBTYPE_PGP: - fprintf (fp, "Type: OpenPGP\n"); - break; - case BLOBTYPE_X509: - fprintf (fp, "Type: X.509\n"); - break; - default: - fprintf (fp, "Type: %d\n", type); - fprintf (fp, "[can't dump this blob type]\n"); - return 0; - } - fprintf (fp, "Version: %d\n", buffer[5]); - - n = get16 (buffer + 6); - fprintf( fp, "Blob-Flags: %04lX", n); - if (n) - { - int any = 0; - - fputs (" (", fp); - if ((n & 1)) - { - fputs ("secret", fp); - any++; - } - if ((n & 2)) - { - if (any) - putc (',', fp); - fputs ("ephemeral", fp); - any++; - } - putc (')', fp); - } - putc ('\n', fp); - - rawdata_off = get32 (buffer + 8); - rawdata_len = get32 (buffer + 12); - - fprintf( fp, "Data-Offset: %lu\n", rawdata_off ); - fprintf( fp, "Data-Length: %lu\n", rawdata_len ); - - nkeys = get16 (buffer + 16); - fprintf (fp, "Key-Count: %lu\n", nkeys ); - if (!nkeys) - fprintf (fp, "[Error: no keys]\n"); - if (nkeys > 1 && type == BLOBTYPE_X509) - fprintf (fp, "[Error: only one key allowed for X509]\n"); - - keyinfolen = get16 (buffer + 18 ); - fprintf (fp, "Key-Info-Length: %lu\n", keyinfolen); - /* fixme: check bounds */ - p = buffer + 20; - for (n=0; n < nkeys; n++, p += keyinfolen) - { - int i; - ulong kidoff, kflags; - - fprintf (fp, "Key-Fpr[%lu]: ", n ); - for (i=0; i < 20; i++ ) - fprintf (fp, "%02X", p[i]); - kidoff = get32 (p + 20); - fprintf (fp, "\nKey-Kid-Off[%lu]: %lu\n", n, kidoff ); - fprintf (fp, "Key-Kid[%lu]: ", n ); - /* fixme: check bounds */ - for (i=0; i < 8; i++ ) - fprintf (fp, "%02X", buffer[kidoff+i] ); - kflags = get16 (p + 24 ); - fprintf( fp, "\nKey-Flags[%lu]: %04lX\n", n, kflags); - } - - /* serial number */ - fputs ("Serial-No: ", fp); - nserial = get16 (p); - p += 2; - if (!nserial) - fputs ("none", fp); - else - { - for (; nserial; nserial--, p++) - fprintf (fp, "%02X", *p); - } - putc ('\n', fp); - - /* user IDs */ - nuids = get16 (p); - fprintf (fp, "Uid-Count: %lu\n", nuids ); - uidinfolen = get16 (p + 2); - fprintf (fp, "Uid-Info-Length: %lu\n", uidinfolen); - /* fixme: check bounds */ - p += 4; - for (n=0; n < nuids; n++, p += uidinfolen) - { - ulong uidoff, uidlen, uflags; - - uidoff = get32( p ); - uidlen = get32( p+4 ); - if (type == BLOBTYPE_X509 && !n) - { - fprintf (fp, "Issuer-Off: %lu\n", uidoff ); - fprintf (fp, "Issuer-Len: %lu\n", uidlen ); - fprintf (fp, "Issuer: \""); - } - else if (type == BLOBTYPE_X509 && n == 1) - { - fprintf (fp, "Subject-Off: %lu\n", uidoff ); - fprintf (fp, "Subject-Len: %lu\n", uidlen ); - fprintf (fp, "Subject: \""); - } - else - { - fprintf (fp, "Uid-Off[%lu]: %lu\n", n, uidoff ); - fprintf (fp, "Uid-Len[%lu]: %lu\n", n, uidlen ); - fprintf (fp, "Uid[%lu]: \"", n ); - } - print_string (fp, buffer+uidoff, uidlen, '\"'); - fputs ("\"\n", fp); - uflags = get16 (p + 8); - if (type == BLOBTYPE_X509 && !n) - { - fprintf (fp, "Issuer-Flags: %04lX\n", uflags ); - fprintf (fp, "Issuer-Validity: %d\n", p[10] ); - } - else if (type == BLOBTYPE_X509 && n == 1) - { - fprintf (fp, "Subject-Flags: %04lX\n", uflags ); - fprintf (fp, "Subject-Validity: %d\n", p[10] ); - } - else - { - fprintf (fp, "Uid-Flags[%lu]: %04lX\n", n, uflags ); - fprintf (fp, "Uid-Validity[%lu]: %d\n", n, p[10] ); - } - } - - nsigs = get16 (p); - fprintf (fp, "Sig-Count: %lu\n", nsigs ); - siginfolen = get16 (p + 2); - fprintf (fp, "Sig-Info-Length: %lu\n", siginfolen ); - /* fixme: check bounds */ - p += 4; - for (n=0; n < nsigs; n++, p += siginfolen) - { - ulong sflags; - - sflags = get32 (p); - fprintf (fp, "Sig-Expire[%lu]: ", n ); - if (!sflags) - fputs ("[not checked]", fp); - else if (sflags == 1 ) - fputs ("[missing key]", fp); - else if (sflags == 2 ) - fputs ("[bad signature]", fp); - else if (sflags < 0x10000000) - fprintf (fp, "[bad flag %0lx]", sflags); - else if (sflags == 0xffffffff) - fputs ("0", fp ); - else - fputs ("a time"/*strtimestamp( sflags )*/, fp ); - putc ('\n', fp ); - } - - fprintf (fp, "Ownertrust: %d\n", p[0] ); - fprintf (fp, "All-Validity: %d\n", p[1] ); - p += 4; - n = get32 (p); p += 4; - fprintf (fp, "Recheck-After: %s\n", /*n? strtimestamp(n) :*/ "0" ); - n = get32 (p ); p += 4; - fprintf( fp, "Latest-Timestamp: %s\n", "0"/*strtimestamp(n)*/ ); - n = get32 (p ); p += 4; - fprintf (fp, "Created-At: %s\n", "0"/*strtimestamp(n)*/ ); - n = get32 (p ); p += 4; - fprintf (fp, "Reserved-Space: %lu\n", n ); - - /* check that the keyblock is at the correct offset and other bounds */ - /*fprintf (fp, "Blob-Checksum: [MD5-hash]\n");*/ - return 0; -} - - - -int -_keybox_dump_file (const char *filename, FILE *outfp) -{ - FILE *fp; - KEYBOXBLOB blob; - int rc; - unsigned long count = 0; - - if (!filename) - { - filename = "-"; - fp = stdin; - } - else - fp = fopen (filename, "rb"); - if (!fp) - { - fprintf (outfp, "can't open `%s': %s\n", filename, strerror(errno)); - return KEYBOX_File_Error; - } - - while ( !(rc = _keybox_read_blob (&blob, fp)) ) - { - fprintf (outfp, "BEGIN-RECORD: %lu\n", count ); - _keybox_dump_blob (blob, outfp); - _keybox_release_blob (blob); - fprintf (outfp, "END-RECORD\n"); - count++; - } - if (rc == -1) - rc = 0; - if (rc) - fprintf (outfp, "error reading `%s': %s\n", filename, - rc == KEYBOX_Read_Error? keybox_strerror(rc):strerror (errno)); - - if (fp != stdin) - fclose (fp); - return rc; -} diff --git a/kbx/keybox-errors.c b/kbx/keybox-errors.c deleted file mode 100644 index e11efc10b..000000000 --- a/kbx/keybox-errors.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Generated automatically by mkerrors */ -/* Do not edit! */ - -#include -#include "keybox-defs.h" - -/** - * keybox_strerror: - * @err: Error code - * - * This function returns a textual representaion of the given - * errorcode. If this is an unknown value, a string with the value - * is returned (Beware: it is hold in a static buffer). - * - * Return value: String with the error description. - **/ -const char * -keybox_strerror (KeyboxError err) -{ - const char *s; - static char buf[25]; - - switch (err) - { - case KEYBOX_No_Error: s="no error"; break; - case KEYBOX_General_Error: s="general error"; break; - case KEYBOX_Out_Of_Core: s="out of core"; break; - case KEYBOX_Invalid_Value: s="invalid value"; break; - case KEYBOX_Timeout: s="timeout"; break; - case KEYBOX_Read_Error: s="read error"; break; - case KEYBOX_Write_Error: s="write error"; break; - case KEYBOX_File_Error: s="file error"; break; - case KEYBOX_Blob_Too_Short: s="blob too short"; break; - case KEYBOX_Blob_Too_Large: s="blob too large"; break; - case KEYBOX_Invalid_Handle: s="invalid handle"; break; - case KEYBOX_File_Create_Error: s="file create error"; break; - case KEYBOX_File_Open_Error: s="file open error"; break; - case KEYBOX_File_Close_Error: s="file close error"; break; - case KEYBOX_Nothing_Found: s="nothing found"; break; - case KEYBOX_Wrong_Blob_Type: s="wrong blob type"; break; - case KEYBOX_Missing_Value: s="missing value"; break; - default: sprintf (buf, "ec=%d", err ); s=buf; break; - } - - return s; -} - diff --git a/kbx/keybox-file.c b/kbx/keybox-file.c deleted file mode 100644 index bbbf78e3c..000000000 --- a/kbx/keybox-file.c +++ /dev/null @@ -1,102 +0,0 @@ -/* keybox-file.c - file oeprations - * 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 - */ - -#include -#include -#include -#include - -#include "keybox-defs.h" - -/* Read a block at the current postion and return it in r_blob. - r_blob may be NULL to simply skip the current block */ -int -_keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp) -{ - char *image; - size_t imagelen = 0; - int c1, c2, c3, c4, type; - int rc; - off_t off; - - again: - *r_blob = NULL; - off = ftello (fp); - if (off == (off_t)-1) - return KEYBOX_Read_Error; - - if ((c1 = getc (fp)) == EOF - || (c2 = getc (fp)) == EOF - || (c3 = getc (fp)) == EOF - || (c4 = getc (fp)) == EOF - || (type = getc (fp)) == EOF) - { - if ( c1 == EOF && !ferror (fp) ) - return -1; /* eof */ - return KEYBOX_Read_Error; - } - - imagelen = (c1 << 24) | (c2 << 16) | (c3 << 8 ) | c4; - if (imagelen > 500000) /* sanity check */ - return KEYBOX_Blob_Too_Large; - - if (imagelen < 5) - return KEYBOX_Blob_Too_Short; - - if (!type) - { - /* special treatment for empty blobs. */ - if (fseek (fp, imagelen-5, SEEK_CUR)) - return KEYBOX_Read_Error; - goto again; - } - - image = xtrymalloc (imagelen); - if (!image) - return KEYBOX_Out_Of_Core; - - image[0] = c1; image[1] = c2; image[2] = c3; image[3] = c4; image[4] = type; - if (fread (image+5, imagelen-5, 1, fp) != 1) - { - xfree (image); - return KEYBOX_Read_Error; - } - - rc = r_blob? _keybox_new_blob (r_blob, image, imagelen, off) : 0; - if (rc || !r_blob) - xfree (image); - return rc; -} - - -/* Write the block to the current file position */ -int -_keybox_write_blob (KEYBOXBLOB blob, FILE *fp) -{ - const char *image; - size_t length; - - image = _keybox_get_blob_image (blob, &length); - if (fwrite (image, length, 1, fp) != 1) - { - return KEYBOX_Write_Error; - } - return 0; -} diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c deleted file mode 100644 index b1d279999..000000000 --- a/kbx/keybox-init.c +++ /dev/null @@ -1,127 +0,0 @@ -/* keybox-init.c - Initalization of the library - * 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 - */ - -#include -#include -#include -#include -#include -#include - -#include "keybox-defs.h" - -#define compare_filenames strcmp - -static KB_NAME kb_names; - - -/* - Register a filename for plain keybox files. Returns a pointer to be - used to create a handles etc or NULL to indicate that it has already - been registered */ -void * -keybox_register_file (const char *fname, int secret) -{ - KB_NAME kr; - - for (kr=kb_names; kr; kr = kr->next) - { - if ( !compare_filenames (kr->fname, fname) ) - return NULL; /* already registered */ - } - - kr = xtrymalloc (sizeof *kr + strlen (fname)); - if (!kr) - return NULL; - 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 = kb_names; - kb_names = kr; - - /* create the offset table the first time a function here is used */ -/* if (!kb_offtbl) */ -/* kb_offtbl = new_offset_hash_table (); */ - - return kr; -} - -int -keybox_is_writable (void *token) -{ - KB_NAME r = token; - - return r? !access (r->fname, W_OK) : 0; -} - - - -/* Create a new handle for the resource associated with TOKEN. SECRET - is just a cross-check. - - The returned handle must be released using keybox_release (). */ -KEYBOX_HANDLE -keybox_new (void *token, int secret) -{ - KEYBOX_HANDLE hd; - KB_NAME resource = token; - - assert (resource && !resource->secret == !secret); - hd = xtrycalloc (1, sizeof *hd); - if (hd) - { - hd->kb = resource; - hd->secret = !!secret; - } - return hd; -} - -void -keybox_release (KEYBOX_HANDLE hd) -{ - if (!hd) - return; - _keybox_release_blob (hd->found.blob); - xfree (hd->word_match.name); - xfree (hd->word_match.pattern); - xfree (hd); -} - - -const char * -keybox_get_resource_name (KEYBOX_HANDLE hd) -{ - if (!hd || !hd->kb) - return NULL; - return hd->kb->fname; -} - -int -keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes) -{ - if (!hd) - return KEYBOX_Invalid_Handle; - hd->ephemeral = yes; - return 0; -} - diff --git a/kbx/keybox-search-desc.h b/kbx/keybox-search-desc.h deleted file mode 100644 index 4be59c27d..000000000 --- a/kbx/keybox-search-desc.h +++ /dev/null @@ -1,72 +0,0 @@ -/* keybox-search-desc.h - Keybox serch description - * 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 file is a temporary kludge until we can come up with solution - to share this description between keybox and the application - specific keydb -*/ - -#ifndef KEYBOX_SEARCH_DESC_H -#define KEYBOX_SEARCH_DESC_H 1 - -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_ISSUER, - KEYDB_SEARCH_MODE_ISSUER_SN, - KEYDB_SEARCH_MODE_SN, - KEYDB_SEARCH_MODE_SUBJECT, - KEYDB_SEARCH_MODE_FIRST, - KEYDB_SEARCH_MODE_NEXT -} KeydbSearchMode; - -struct keydb_search_desc { - KeydbSearchMode mode; - int (*skipfnc)(void *,void*); /* used to be: void*, u32* */ - void *skipfncvalue; - const unsigned char *sn; - int snlen; /* -1 := sn is a hex string */ - union { - const char *name; - unsigned char fpr[24]; - unsigned char kid[8]; - } u; -}; - - -struct keydb_search_desc; -typedef struct keydb_search_desc KEYDB_SEARCH_DESC; - -typedef struct keydb_search_desc KEYBOX_SEARCH_DESC; - - - -#endif /*KEYBOX_SEARCH_DESC_H*/ diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c deleted file mode 100644 index 126364f5b..000000000 --- a/kbx/keybox-search.c +++ /dev/null @@ -1,810 +0,0 @@ -/* keybox-search.c - Search operations - * 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 -#include -#include -#include -#include - -#include "../jnlib/stringhelp.h" /* ascii_xxxx() */ -#include "keybox-defs.h" - -#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)) - -struct sn_array_s { - int snlen; - unsigned char *sn; -}; - - - -static ulong -get32 (const byte *buffer) -{ - ulong a; - a = *buffer << 24; - a |= buffer[1] << 16; - a |= buffer[2] << 8; - a |= buffer[3]; - return a; -} - -static ulong -get16 (const byte *buffer) -{ - ulong a; - a = *buffer << 8; - a |= buffer[1]; - return a; -} - - - -static int -blob_get_type (KEYBOXBLOB blob) -{ - const unsigned char *buffer; - size_t length; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return -1; /* blob too short */ - - return buffer[4]; -} - -static unsigned int -blob_get_blob_flags (KEYBOXBLOB blob) -{ - const unsigned char *buffer; - size_t length; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 8) - return 0; /* oops */ - - return get16 (buffer + 6); -} - - -static int -blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen) -{ - const unsigned char *buffer; - size_t length; - size_t pos, off; - size_t nkeys, keyinfolen; - size_t nserial; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return 0; /* blob too short */ - - /*keys*/ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return 0; /* invalid blob */ - pos = 20 + keyinfolen*nkeys; - if (pos+2 > length) - return 0; /* out of bounds */ - - /*serial*/ - nserial = get16 (buffer+pos); - off = pos + 2; - if (off+nserial > length) - return 0; /* out of bounds */ - - return nserial == snlen && !memcmp (buffer+off, sn, snlen); -} - - -static int -blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr) -{ - const unsigned char *buffer; - size_t length; - size_t pos, off; - size_t nkeys, keyinfolen; - int idx; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return 0; /* blob too short */ - - /*keys*/ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return 0; /* invalid blob */ - pos = 20; - if (pos + keyinfolen*nkeys > length) - return 0; /* out of bounds */ - - for (idx=0; idx < nkeys; idx++) - { - off = pos + idx*keyinfolen; - if (!memcmp (buffer + off, fpr, 20)) - return 1; /* found */ - } - return 0; /* not found */ -} - -static int -blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr, - int fproff, int fprlen) -{ - const unsigned char *buffer; - size_t length; - size_t pos, off; - size_t nkeys, keyinfolen; - int idx; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return 0; /* blob too short */ - - /*keys*/ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return 0; /* invalid blob */ - pos = 20; - if (pos + keyinfolen*nkeys > length) - return 0; /* out of bounds */ - - for (idx=0; idx < nkeys; idx++) - { - off = pos + idx*keyinfolen; - if (!memcmp (buffer + off + fproff, fpr, fprlen)) - return 1; /* found */ - } - return 0; /* not found */ -} - - -static int -blob_cmp_name (KEYBOXBLOB blob, int idx, - const char *name, size_t namelen, int substr) -{ - const unsigned char *buffer; - size_t length; - size_t pos, off, len; - size_t nkeys, keyinfolen; - size_t nuids, uidinfolen; - size_t nserial; - - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return 0; /* blob too short */ - - /*keys*/ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return 0; /* invalid blob */ - pos = 20 + keyinfolen*nkeys; - if (pos+2 > length) - return 0; /* out of bounds */ - - /*serial*/ - nserial = get16 (buffer+pos); - pos += 2 + nserial; - if (pos+4 > length) - return 0; /* out of bounds */ - - /* user ids*/ - nuids = get16 (buffer + pos); pos += 2; - uidinfolen = get16 (buffer + pos); pos += 2; - if (uidinfolen < 12 /* should add a: || nuidinfolen > MAX_UIDINFOLEN */) - return 0; /* invalid blob */ - if (pos + uidinfolen*nuids > length) - return 0; /* out of bounds */ - - if (idx < 0) - { /* compare all names starting with that (negated) index */ - idx = -idx; - - for ( ;idx < nuids; idx++) - { - size_t mypos = pos; - - mypos += idx*uidinfolen; - off = get32 (buffer+mypos); - len = get32 (buffer+mypos+4); - if (off+len > length) - return 0; /* error: better stop here out of bounds */ - if (len < 2) - continue; /* empty name or 0 not stored */ - len--; - if (substr) - { - if (ascii_memcasemem (buffer+off, len, name, namelen)) - return 1; /* found */ - } - else - { - if (len == namelen && !memcmp (buffer+off, name, len)) - return 1; /* found */ - } - } - return 0; /* not found */ - } - else - { - if (idx > nuids) - return 0; /* no user ID with that idx */ - pos += idx*uidinfolen; - off = get32 (buffer+pos); - len = get32 (buffer+pos+4); - if (off+len > length) - return 0; /* out of bounds */ - if (len < 1) - return 0; /* empty name */ - - if (substr) - { - return !!ascii_memcasemem (buffer+off, len, name, namelen); - } - else - { - return len == namelen && !memcmp (buffer+off, name, len); - } - } -} - - -/* compare all email addresses of the subject. With SUBSTR given as - True a substring search is done in the mail address */ -static int -blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen, int substr) -{ - const unsigned char *buffer; - size_t length; - size_t pos, off, len; - size_t nkeys, keyinfolen; - size_t nuids, uidinfolen; - size_t nserial; - int idx; - - /* fixme: this code is common to blob_cmp_mail */ - buffer = _keybox_get_blob_image (blob, &length); - if (length < 40) - return 0; /* blob too short */ - - /*keys*/ - nkeys = get16 (buffer + 16); - keyinfolen = get16 (buffer + 18 ); - if (keyinfolen < 28) - return 0; /* invalid blob */ - pos = 20 + keyinfolen*nkeys; - if (pos+2 > length) - return 0; /* out of bounds */ - - /*serial*/ - nserial = get16 (buffer+pos); - pos += 2 + nserial; - if (pos+4 > length) - return 0; /* out of bounds */ - - /* user ids*/ - nuids = get16 (buffer + pos); pos += 2; - uidinfolen = get16 (buffer + pos); pos += 2; - if (uidinfolen < 12 /* should add a: || nuidinfolen > MAX_UIDINFOLEN */) - return 0; /* invalid blob */ - if (pos + uidinfolen*nuids > length) - return 0; /* out of bounds */ - - if (namelen < 1) - return 0; - - for (idx=1 ;idx < nuids; idx++) - { - size_t mypos = pos; - - mypos += idx*uidinfolen; - off = get32 (buffer+mypos); - len = get32 (buffer+mypos+4); - if (off+len > length) - return 0; /* error: better stop here out of bounds */ - if (len < 2 || buffer[off] != '<') - continue; /* empty name or trailing 0 not stored */ - len--; /* one back */ - if ( len < 3 || buffer[off+len] != '>') - continue; /* not a proper email address */ - len--; - if (substr) - { - if (ascii_memcasemem (buffer+off+1, len, name, namelen)) - return 1; /* found */ - } - else - { - if (len == namelen && !ascii_memcasecmp (buffer+off+1, name, len)) - return 1; /* found */ - } - } - return 0; /* not found */ -} - - - - -/* - The has_foo functions are used as helpers for search -*/ -static int -has_short_kid (KEYBOXBLOB blob, const unsigned char *kid) -{ - return blob_cmp_fpr_part (blob, kid+4, 16, 4); -} - -static int -has_long_kid (KEYBOXBLOB blob, const unsigned char *kid) -{ - return blob_cmp_fpr_part (blob, kid, 12, 8); -} - -static int -has_fingerprint (KEYBOXBLOB blob, const unsigned char *fpr) -{ - return blob_cmp_fpr (blob, fpr); -} - - -static int -has_issuer (KEYBOXBLOB blob, const char *name) -{ - size_t namelen; - - return_val_if_fail (name, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - - namelen = strlen (name); - return blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0); -} - -static int -has_issuer_sn (KEYBOXBLOB blob, const char *name, - const unsigned char *sn, int snlen) -{ - size_t namelen; - - return_val_if_fail (name, 0); - return_val_if_fail (sn, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - - namelen = strlen (name); - - return (blob_cmp_sn (blob, sn, snlen) - && blob_cmp_name (blob, 0 /* issuer */, name, namelen, 0)); -} - -static int -has_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen) -{ - return_val_if_fail (sn, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - return blob_cmp_sn (blob, sn, snlen); -} - -static int -has_subject (KEYBOXBLOB blob, const char *name) -{ - size_t namelen; - - return_val_if_fail (name, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - - namelen = strlen (name); - return blob_cmp_name (blob, 1 /* subject */, name, namelen, 0); -} - -static int -has_subject_or_alt (KEYBOXBLOB blob, const char *name, int substr) -{ - size_t namelen; - - return_val_if_fail (name, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - - namelen = strlen (name); - return blob_cmp_name (blob, -1 /* all subject names*/, name, - namelen, substr); -} - - -static int -has_mail (KEYBOXBLOB blob, const char *name, int substr) -{ - size_t namelen; - - return_val_if_fail (name, 0); - - if (blob_get_type (blob) != BLOBTYPE_X509) - return 0; - - namelen = strlen (name); - if (namelen && name[namelen-1] == '>') - namelen--; - return blob_cmp_mail (blob, name, namelen, substr); -} - - -static void -release_sn_array (struct sn_array_s *array, size_t size) -{ - size_t n; - - for (n=0; n < size; n++) - xfree (array[n].sn); - xfree (array); -} - - -/* - - The search API - -*/ - -int -keybox_search_reset (KEYBOX_HANDLE hd) -{ - if (!hd) - return KEYBOX_Invalid_Value; - - if (hd->found.blob) - { - _keybox_release_blob (hd->found.blob); - hd->found.blob = NULL; - } - - if (hd->fp) - { - fclose (hd->fp); - hd->fp = NULL; - } - hd->error = 0; - hd->eof = 0; - return 0; -} - - -/* Note: When in ephemeral mode the search function does visit all - blobs but in standard mode, blobs flagged as ephemeral are ignored. */ -int -keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) -{ - int rc; - size_t n; - int need_words, any_skip; - KEYBOXBLOB blob = NULL; - struct sn_array_s *sn_array = NULL; - - if (!hd) - return KEYBOX_Invalid_Value; - - /* clear last found result */ - if (hd->found.blob) - { - _keybox_release_blob (hd->found.blob); - hd->found.blob = NULL; - } - - if (hd->error) - return hd->error; /* still in error state */ - if (hd->eof) - return -1; /* still EOF */ - - /* figure out what information we need */ - need_words = any_skip = 0; - for (n=0; n < ndesc; n++) - { - switch (desc[n].mode) - { - case KEYDB_SEARCH_MODE_WORDS: - need_words = 1; - break; - case KEYDB_SEARCH_MODE_FIRST: - /* always restart the search in this mode */ - keybox_search_reset (hd); - break; - default: - break; - } - if (desc[n].skipfnc) - any_skip = 1; - if (desc[n].snlen == -1 && !sn_array) - { - sn_array = xtrycalloc (ndesc, sizeof *sn_array); - if (!sn_array) - return (hd->error = KEYBOX_Out_Of_Core); - } - } - - if (!hd->fp) - { - hd->fp = fopen (hd->kb->fname, "rb"); - if (!hd->fp) - { - xfree (sn_array); - return (hd->error = KEYBOX_File_Open_Error); - } - } - - /* kludge: we need to convert an SN given as hexstring to it's - binary representation - in some cases we are not able to store it - in the search descriptor, because due to its usgae it is not - possible to free allocated memory */ - if (sn_array) - { - const unsigned char *s; - int i, odd; - size_t snlen; - - for (n=0; n < ndesc; n++) - { - if (!desc[n].sn) - ; - else if (desc[n].snlen == -1) - { - unsigned char *sn; - - s = desc[n].sn; - for (i=0; *s && *s != '/'; s++, i++) - ; - odd = (i & 1); - snlen = (i+1)/2; - sn_array[n].sn = xtrymalloc (snlen); - if (!sn_array[n].sn) - { - release_sn_array (sn_array, n); - return (hd->error = KEYBOX_Out_Of_Core); - } - sn_array[n].snlen = snlen; - sn = sn_array[n].sn; - s = desc[n].sn; - if (odd) - { - *sn++ = xtoi_1 (s); - s++; - } - for (; *s && *s != '/'; s += 2) - *sn++ = xtoi_2 (s); - } - else - { - const unsigned char *sn; - - sn = desc[n].sn; - snlen = desc[n].snlen; - sn_array[n].sn = xtrymalloc (snlen); - if (!sn_array[n].sn) - { - release_sn_array (sn_array, n); - return (hd->error = KEYBOX_Out_Of_Core); - } - sn_array[n].snlen = snlen; - memcpy (sn_array[n].sn, sn, snlen); - } - } - } - - - for (;;) - { - unsigned int blobflags; - - _keybox_release_blob (blob); blob = NULL; - rc = _keybox_read_blob (&blob, hd->fp); - if (rc) - break; - - blobflags = blob_get_blob_flags (blob); - if (!hd->ephemeral && (blobflags & 2)) - continue; /* not in ephemeral mode but blob is flagged ephemeral */ - - for (n=0; n < ndesc; n++) - { - switch (desc[n].mode) - { - case KEYDB_SEARCH_MODE_NONE: - never_reached (); - break; - case KEYDB_SEARCH_MODE_EXACT: - if (has_subject_or_alt (blob, desc[n].u.name, 0)) - goto found; - break; - case KEYDB_SEARCH_MODE_MAIL: - if (has_mail (blob, desc[n].u.name, 0)) - goto found; - break; - case KEYDB_SEARCH_MODE_MAILSUB: - if (has_mail (blob, desc[n].u.name, 1)) - goto found; - break; - case KEYDB_SEARCH_MODE_SUBSTR: - if (has_subject_or_alt (blob, desc[n].u.name, 1)) - goto found; - break; - case KEYDB_SEARCH_MODE_MAILEND: - case KEYDB_SEARCH_MODE_WORDS: - never_reached (); /* not yet implemented */ - break; - case KEYDB_SEARCH_MODE_ISSUER: - if (has_issuer (blob, desc[n].u.name)) - goto found; - break; - case KEYDB_SEARCH_MODE_ISSUER_SN: - if (has_issuer_sn (blob, desc[n].u.name, - sn_array? sn_array[n].sn : desc[n].sn, - sn_array? sn_array[n].snlen : desc[n].snlen)) - goto found; - break; - case KEYDB_SEARCH_MODE_SN: - if (has_sn (blob, sn_array? sn_array[n].sn : desc[n].sn, - sn_array? sn_array[n].snlen : desc[n].snlen)) - goto found; - break; - case KEYDB_SEARCH_MODE_SUBJECT: - if (has_subject (blob, desc[n].u.name)) - goto found; - break; - case KEYDB_SEARCH_MODE_SHORT_KID: - if (has_short_kid (blob, desc[n].u.kid)) - goto found; - break; - case KEYDB_SEARCH_MODE_LONG_KID: - if (has_long_kid (blob, desc[n].u.kid)) - goto found; - break; - case KEYDB_SEARCH_MODE_FPR: - case KEYDB_SEARCH_MODE_FPR20: - if (has_fingerprint (blob, desc[n].u.fpr)) - goto found; - break; - case KEYDB_SEARCH_MODE_FIRST: - goto found; - break; - case KEYDB_SEARCH_MODE_NEXT: - goto found; - break; - default: - rc = KEYBOX_Invalid_Value; - goto found; - } - } - continue; - found: - for (n=any_skip?0:ndesc; n < ndesc; n++) - { -/* if (desc[n].skipfnc */ -/* && desc[n].skipfnc (desc[n].skipfncvalue, aki)) */ -/* break; */ - } - if (n == ndesc) - break; /* got it */ - } - - if (!rc) - { - hd->found.blob = blob; - } - else if (rc == -1) - { - _keybox_release_blob (blob); - hd->eof = 1; - } - else - { - _keybox_release_blob (blob); - hd->error = rc; - } - - if (sn_array) - release_sn_array (sn_array, ndesc); - - return rc; -} - - - - -/* - Functions to return a certificate or a keyblock. To be used after - a successful search operation. -*/ -#ifdef KEYBOX_WITH_X509 -/* - Return the last found cert. Caller must free it. - */ -int -keybox_get_cert (KEYBOX_HANDLE hd, KsbaCert *r_cert) -{ - const unsigned char *buffer; - size_t length; - size_t cert_off, cert_len; - KsbaReader reader = NULL; - KsbaCert cert = NULL; - int rc; - - if (!hd) - return KEYBOX_Invalid_Value; - if (!hd->found.blob) - return KEYBOX_Nothing_Found; - - if (blob_get_type (hd->found.blob) != BLOBTYPE_X509) - return KEYBOX_Wrong_Blob_Type; - - buffer = _keybox_get_blob_image (hd->found.blob, &length); - if (length < 40) - return KEYBOX_Blob_Too_Short; - cert_off = get32 (buffer+8); - cert_len = get32 (buffer+12); - if (cert_off+cert_len > length) - return KEYBOX_Blob_Too_Short; - - reader = ksba_reader_new (); - if (!reader) - return KEYBOX_Out_Of_Core; - rc = ksba_reader_set_mem (reader, buffer+cert_off, cert_len); - if (rc) - { - ksba_reader_release (reader); - /* fixme: need to map the error codes */ - return KEYBOX_General_Error; - } - - cert = ksba_cert_new (); - if (!cert) - { - ksba_reader_release (reader); - return KEYBOX_Out_Of_Core; - } - - rc = ksba_cert_read_der (cert, reader); - if (rc) - { - ksba_cert_release (cert); - ksba_reader_release (reader); - /* fixme: need to map the error codes */ - return KEYBOX_General_Error; - } - - *r_cert = cert; - ksba_reader_release (reader); - return 0; -} - -#endif /*KEYBOX_WITH_X509*/ diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c deleted file mode 100644 index 8b189bbed..000000000 --- a/kbx/keybox-update.c +++ /dev/null @@ -1,433 +0,0 @@ -/* keybox-update.c - keybox update 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 - */ - -#include -#include -#include -#include -#include -#include - -#include "keybox-defs.h" - -#define EXTSEP_S "." - - -static int -create_tmp_file (const char *template, - char **r_bakfname, char **r_tmpfname, FILE **r_fp) -{ - char *bakfname, *tmpfname; - - *r_bakfname = NULL; - *r_tmpfname = NULL; - -# ifdef USE_ONLY_8DOT3 - /* Here is another Windoze bug?: - * you cant rename("pubring.kbx.tmp", "pubring.kbx"); - * but rename("pubring.kbx.tmp", "pubring.aaa"); - * works. So we replace .kbx by .bak or .tmp - */ - if (strlen (template) > 4 - && !strcmp (template+strlen(template)-4, EXTSEP_S "kbx") ) - { - bakfname = xtrymalloc (strlen (template) + 1); - if (!bakfname) - return KEYBOX_Out_Of_Core; - strcpy (bakfname, template); - strcpy (bakfname+strlen(template)-4, EXTSEP_S "bak"); - - tmpfname = xtrymalloc (strlen (template) + 1); - if (!tmpfname) - { - xfree (bakfname); - return KEYBOX_Out_Of_Core; - } - strcpy (tmpfname,template); - strcpy (tmpfname + strlen (template)-4, EXTSEP_S "tmp"); - } - else - { /* file does not end with kbx; hmmm */ - bakfname = xtrymalloc ( strlen (template) + 5); - if (!bakfname) - return KEYBOX_Out_Of_Core; - strcpy (stpcpy (bakfname, template), EXTSEP_S "bak"); - - tmpfname = xtrymalloc ( strlen (template) + 5); - if (!tmpfname) - { - xfree (bakfname); - return KEYBOX_Out_Of_Core; - } - strcpy (stpcpy (tmpfname, template), EXTSEP_S "tmp"); - } -# else /* Posix file names */ - bakfname = xtrymalloc (strlen (template) + 2); - if (!bakfname) - return KEYBOX_Out_Of_Core; - strcpy (stpcpy (bakfname,template),"~"); - - tmpfname = xtrymalloc ( strlen (template) + 5); - if (!tmpfname) - { - xfree (bakfname); - return KEYBOX_Out_Of_Core; - } - strcpy (stpcpy (tmpfname,template), EXTSEP_S "tmp"); -# endif /* Posix filename */ - - *r_fp = fopen (tmpfname, "wb"); - if (!*r_fp) - { - xfree (tmpfname); - xfree (bakfname); - return KEYBOX_File_Create_Error; - } - - *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; - - /* restrict the permissions for secret keyboxs */ -#ifndef HAVE_DOSISH_SYSTEM -/* if (secret && !opt.preserve_permissions) */ -/* { */ -/* if (chmod (tmpfname, S_IRUSR | S_IWUSR) ) */ -/* { */ -/* log_debug ("chmod of `%s' failed: %s\n", */ -/* tmpfname, strerror(errno) ); */ -/* return KEYBOX_Write_File; */ -/* } */ -/* } */ -#endif - - /* fixme: invalidate close caches (not used with stdio)*/ -/* 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 keyboxs */ - if (!secret) - { -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - remove (bakfname); -#endif - if (rename (fname, bakfname) ) - { - return KEYBOX_File_Error; - } - } - - /* then rename the file */ -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - remove (fname); -#endif - if (rename (tmpfname, fname) ) - { - rc = KEYBOX_File_Error; - 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; - } - - return 0; -} - - - -/* Perform insert/delete/update operation. - mode 1 = insert - 2 = delete - 3 = update -*/ -static int -blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob, - int secret, off_t start_offset, unsigned int n_packets ) -{ - FILE *fp, *newfp; - int rc=0; - char *bakfname = NULL; - char *tmpfname = NULL; - char buffer[4096]; - int nread, nbytes; - - /* Open the source file. Because we do a rename, we have to check the - permissions of the file */ - if (access (fname, W_OK)) - return KEYBOX_Write_Error; - - fp = fopen (fname, "rb"); - if (mode == 1 && !fp && errno == ENOENT) - { /* insert mode but file does not exist: create a new keybox file */ - newfp = fopen (fname, "wb"); - if (!newfp ) - { - return KEYBOX_File_Create_Error; - } - - rc = _keybox_write_blob (blob, newfp); - if (rc) - { - return rc; - } - if ( fclose (newfp) ) - { - return KEYBOX_File_Create_Error; - } - -/* if (chmod( fname, S_IRUSR | S_IWUSR )) */ -/* { */ -/* log_debug ("%s: chmod failed: %s\n", fname, strerror(errno) ); */ -/* return KEYBOX_File_Error; */ -/* } */ - return 0; /* ready */ - } - - if (!fp) - { - rc = KEYBOX_File_Open_Error; - goto leave; - } - - /* create the new file */ - rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp); - if (rc) - { - fclose(fp); - goto leave; - } - - /* prepare for insert */ - if (mode == 1) - { - /* copy everything to the new file */ - while ( (nread = fread (buffer, 1, DIM(buffer), fp)) > 0 ) - { - if (fwrite (buffer, nread, 1, newfp) != 1) - { - rc = KEYBOX_Write_Error; - goto leave; - } - } - if (ferror (fp)) - { - rc = KEYBOX_Read_Error; - goto leave; - } - } - - /* prepare for delete or update */ - if ( mode == 2 || mode == 3 ) - { - off_t current = 0; - - /* copy first part to the new file */ - while ( current < start_offset ) - { - nbytes = DIM(buffer); - if (current + nbytes > start_offset) - nbytes = start_offset - current; - nread = fread (buffer, 1, nbytes, fp); - if (!fread) - break; - current += nread; - - if (fwrite (buffer, nread, 1, newfp) != 1) - { - rc = KEYBOX_Write_Error; - goto leave; - } - } - if (ferror (fp)) - { - rc = KEYBOX_Read_Error; - goto leave; - } - - /* skip this blob */ - rc = _keybox_read_blob (NULL, fp); - if (rc) - return rc; - } - - /* Do an insert or update */ - if ( mode == 1 || mode == 3 ) - { - rc = _keybox_write_blob (blob, newfp); - if (rc) - return rc; - } - - /* copy the rest of the packet for an delete or update */ - if (mode == 2 || mode == 3) - { - while ( (nread = fread (buffer, 1, DIM(buffer), fp)) > 0 ) - { - if (fwrite (buffer, nread, 1, newfp) != 1) - { - rc = KEYBOX_Write_Error; - goto leave; - } - } - if (ferror (fp)) - { - rc = KEYBOX_Read_Error; - goto leave; - } - } - - /* close both files */ - if (fclose(fp)) - { - rc = KEYBOX_File_Close_Error; - fclose (newfp); - goto leave; - } - if (fclose(newfp)) - { - rc = KEYBOX_File_Close_Error; - goto leave; - } - - rc = rename_tmp_file (bakfname, tmpfname, fname, secret); - - leave: - xfree(bakfname); - xfree(tmpfname); - return rc; -} - - - - -#ifdef KEYBOX_WITH_X509 -int -keybox_insert_cert (KEYBOX_HANDLE hd, KsbaCert cert, - unsigned char *sha1_digest) -{ - int rc; - const char *fname; - KEYBOXBLOB blob; - - if (!hd) - return KEYBOX_Invalid_Handle; - if (!hd->kb) - return KEYBOX_Invalid_Handle; - fname = hd->kb->fname; - if (!fname) - return KEYBOX_Invalid_Handle; - - /* close this one otherwise we will mess up the position for a next - search. Fixme: it would be better to adjust the position after - the write opertions. */ - if (hd->fp) - { - fclose (hd->fp); - hd->fp = NULL; - } - - rc = _keybox_create_x509_blob (&blob, cert, sha1_digest, hd->ephemeral); - if (!rc) - { - rc = blob_filecopy (1, fname, blob, hd->secret, 0, 0 ); - _keybox_release_blob (blob); - /* if (!rc && !hd->secret && kb_offtbl) */ - /* { */ - /* update_offset_hash_table_from_kb (kb_offtbl, kb, 0); */ - /* } */ - } - return rc; -} - -int -keybox_update_cert (KEYBOX_HANDLE hd, KsbaCert cert, - unsigned char *sha1_digest) -{ - return -1; -} - - -#endif /*KEYBOX_WITH_X509*/ - - -int -keybox_delete (KEYBOX_HANDLE hd) -{ - off_t off; - const char *fname; - FILE *fp; - int rc; - - if (!hd) - return KEYBOX_Invalid_Value; - if (!hd->found.blob) - return KEYBOX_Nothing_Found; - if (!hd->kb) - return KEYBOX_Invalid_Handle; - fname = hd->kb->fname; - if (!fname) - return KEYBOX_Invalid_Handle; - - off = _keybox_get_blob_fileoffset (hd->found.blob); - if (off == (off_t)-1) - return KEYBOX_General_Error; - off += 4; - - if (hd->fp) - { - fclose (hd->fp); - hd->fp = NULL; - } - - fp = fopen (hd->kb->fname, "r+b"); - if (!fp) - return KEYBOX_File_Open_Error; - - if (fseeko (fp, off, SEEK_SET)) - rc = KEYBOX_Write_Error; - else if (putc (0, fp) == EOF) - rc = KEYBOX_Write_Error; - else - rc = 0; - - if (fclose (fp)) - { - if (!rc) - rc = KEYBOX_File_Close_Error; - } - - return rc; -} - - diff --git a/kbx/keybox-util.c b/kbx/keybox-util.c deleted file mode 100644 index ed5d93de0..000000000 --- a/kbx/keybox-util.c +++ /dev/null @@ -1,72 +0,0 @@ -/* keybox-util.c - Utility functions for Keybox - * 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 - */ - -#include -#include -#include -#include - -#include "keybox-defs.h" - - -static void *(*alloc_func)(size_t n) = malloc; -static void *(*realloc_func)(void *p, size_t n) = realloc; -static void (*free_func)(void*) = free; - - - -void -keybox_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), - void *(*new_realloc_func)(void *p, size_t n), - void (*new_free_func)(void*) ) -{ - alloc_func = new_alloc_func; - realloc_func = new_realloc_func; - free_func = new_free_func; -} - -void * -_keybox_malloc (size_t n) -{ - return alloc_func (n); -} - -void * -_keybox_realloc (void *a, size_t n) -{ - return realloc_func (a, n); -} - -void * -_keybox_calloc (size_t n, size_t m) -{ - void *p = _keybox_malloc (n*m); - if (p) - memset (p, 0, n* m); - return p; -} - -void -_keybox_free (void *p) -{ - if (p) - free_func (p); -} - diff --git a/kbx/keybox.h b/kbx/keybox.h deleted file mode 100644 index a763ec837..000000000 --- a/kbx/keybox.h +++ /dev/null @@ -1,125 +0,0 @@ -/* keybox.h - Keybox 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 KEYBOX_H -#define KEYBOX_H 1 -#ifdef __cplusplus -extern "C" { -#if 0 - } -#endif -#endif - -#include "keybox-search-desc.h" - -#define KEYBOX_WITH_OPENPGP 1 -#define KEYBOX_WITH_X509 1 - - -#ifdef KEYBOX_WITH_OPENPGP -# undef KEYBOX_WITH_OPENPGP -/*#include */ -#endif - -#ifdef KEYBOX_WITH_X509 -# include -#endif - - -typedef enum { - KEYBOX_No_Error = 0, - KEYBOX_General_Error = 1, - KEYBOX_Out_Of_Core = 2, - KEYBOX_Invalid_Value = 3, - KEYBOX_Timeout = 4, - KEYBOX_Read_Error = 5, - KEYBOX_Write_Error = 6, - KEYBOX_File_Error = 7, - KEYBOX_Blob_Too_Short = 8, - KEYBOX_Blob_Too_Large = 9, - KEYBOX_Invalid_Handle = 10, - KEYBOX_File_Create_Error = 11, - KEYBOX_File_Open_Error = 12, - KEYBOX_File_Close_Error = 13, - KEYBOX_Nothing_Found = 14, - KEYBOX_Wrong_Blob_Type = 15, - KEYBOX_Missing_Value = 16, -} KeyboxError; - - - -typedef struct keybox_handle *KEYBOX_HANDLE; - - -/*-- keybox-init.c --*/ -void *keybox_register_file (const char *fname, int secret); -int keybox_is_writable (void *token); - -KEYBOX_HANDLE keybox_new (void *token, int secret); -void keybox_release (KEYBOX_HANDLE hd); -const char *keybox_get_resource_name (KEYBOX_HANDLE hd); -int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes); - - -/*-- keybox-search.c --*/ -#ifdef KEYBOX_WITH_X509 -int keybox_get_cert (KEYBOX_HANDLE hd, KsbaCert *ret_cert); -#endif /*KEYBOX_WITH_X509*/ - -int keybox_search_reset (KEYBOX_HANDLE hd); -int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc); - - -/*-- keybox-update.c --*/ -#ifdef KEYBOX_WITH_X509 -int keybox_insert_cert (KEYBOX_HANDLE hd, KsbaCert cert, - unsigned char *sha1_digest); -int keybox_update_cert (KEYBOX_HANDLE hd, KsbaCert cert, - unsigned char *sha1_digest); -#endif /*KEYBOX_WITH_X509*/ - -int keybox_delete (KEYBOX_HANDLE hd); - - -/*-- --*/ - -#if 0 -int keybox_lock (KEYBOX_HANDLE hd, int yes); -int keybox_get_keyblock (KEYBOX_HANDLE hd, KBNODE *ret_kb); -int keybox_locate_writable (KEYBOX_HANDLE hd); -int keybox_search_reset (KEYBOX_HANDLE hd); -int keybox_search (KEYBOX_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc); -int keybox_rebuild_cache (void *); -#endif - - -/*-- keybox-util.c --*/ -void keybox_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), - void *(*new_realloc_func)(void *p, size_t n), - void (*new_free_func)(void*) ); - -/*-- keybox-errors.c (built) --*/ -const char *keybox_strerror (KeyboxError err); - - -#ifdef __cplusplus -} -#endif -#endif /*KEYBOX_H*/ diff --git a/kbx/mkerrors b/kbx/mkerrors deleted file mode 100755 index 5adb7bfdf..000000000 --- a/kbx/mkerrors +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/sh -# mkerrors - Extract error strings from assuan.h -# and create C source for assuan_strerror -# 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 - -cat < -#include "keybox-defs.h" - -/** - * keybox_strerror: - * @err: Error code - * - * This function returns a textual representaion of the given - * errorcode. If this is an unknown value, a string with the value - * is returned (Beware: it is hold in a static buffer). - * - * Return value: String with the error description. - **/ -const char * -keybox_strerror (KeyboxError err) -{ - const char *s; - static char buf[25]; - - switch (err) - { -EOF - -awk ' -/KEYBOX_No_Error/ { okay=1 } -!okay {next} -/}/ { exit 0 } -/KEYBOX_[A-Za-z_]*/ { print_code($1) } - - -function print_code( s ) -{ -printf " case %s: s=\"", s ; -gsub(/_/, " ", s ); -printf "%s\"; break;\n", tolower(substr(s,8)); -} -' - -cat < - - * scdaemon.c (main): New option --daemon so that the program is - not accidently started in the background. - -2002-08-16 Werner Koch - - * scdaemon.c: Include i18n.h. - - * card-common.h (struct p15_private_s): Forward declaration. Add - it to card_ctx_s. - * card.c (card_close): Make sure private data is released. - (card_enum_certs): New. - * card-p15.c (p15_release_private_data): New. - (init_private_data): New to work around an OpenSC weirdness. - (p15_enum_keypairs): Do an OpenSC get_objects only once. - (p15_enum_certs): New. - (card_p15_bind): Bind new function. - * command.c (cmd_learn): Return information about the certificates. - -2002-08-09 Werner Koch - - * card.c (card_get_serial_and_stamp): Use the tokeinfo serial - number as a fallback. Add a special prefix for serial numbers. - -2002-07-30 Werner Koch - - Changes to cope with OpenSC 0.7.0: - - * card.c: Removed the check for the packed opensc version. - Changed include file names of opensc. - (map_sc_err): Adjusted error codes for new opensc version. - * card-p15.c: Changed include filename of opensc. - * card-dinsig.c: Ditto. - - * card-p15.c (p15_decipher): Add flags argument to OpenSC call. - -2002-07-24 Werner Koch - - * card.c (find_simple_tlv, find_iccsn): New. - (card_get_serial_and_stamp): Improved serial number parser. - -2002-06-27 Werner Koch - - * scdaemon.c (main): Use GNUPG_DEFAULT_HOMEDIR constant. - -2002-06-15 Werner Koch - - * card-dinsig.c: Documented some stuff from the DIN norm. - -2002-04-15 Werner Koch - - * command.c (cmd_pksign, cmd_pkdecrypt): Use a copy of the key ID. - -2002-04-12 Werner Koch - - * scdaemon.c: New option --debug-sc N. - * card.c (card_open): set it here. - - * card-p15.c (p15_prepare_key): Factored out common code from ... - (p15_sign, p15_decipher): here and made the decryption work the - regular way. - -2002-04-10 Werner Koch - - * card.c (card_open): Return immediately when no reader is available. - -2002-03-27 Werner Koch - - * card.c (card_open, card_close): Adjusted for changes in OpenSC. - -2002-03-10 Werner Koch - - * card-p15.c, card-dinsig.c, card-common.h: New. - * card.c: Factored most code out to the new modules, so that we - can better support different types of card applications. - -2002-01-26 Werner Koch - - * scdaemon.c scdaemon.h, command.c: New. Based on the code from - the gpg-agent. - - Copyright 2002 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/scd/Makefile.am b/scd/Makefile.am deleted file mode 100644 index 8812d1b9a..000000000 --- a/scd/Makefile.am +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (C) 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 - -## Process this file with automake to produce Makefile.in - -localedir = $(datadir)/locale -INCLUDES = -I../intl -DLOCALEDIR=\"$(localedir)\" - -bin_PROGRAMS = scdaemon - -AM_CPPFLAGS = -I$(top_srcdir)/common $(OPENSC_CFLAGS) $(LIBGCRYPT_CFLAGS) \ - $(KSBA_CFLAGS) -LDFLAGS = @LDFLAGS@ - -scdaemon_SOURCES = \ - scdaemon.c scdaemon.h \ - command.c card.c \ - card-common.h \ - card-p15.c card-dinsig.c - -scdaemon_LDADD = ../jnlib/libjnlib.a ../assuan/libassuan.a \ - ../common/libcommon.a \ - $(OPENSC_LIBS) $(LIBGCRYPT_LIBS) $(KSBA_LIBS) - - - - diff --git a/scd/card-common.h b/scd/card-common.h deleted file mode 100644 index 50014cead..000000000 --- a/scd/card-common.h +++ /dev/null @@ -1,73 +0,0 @@ -/* card-common.h - Common declarations for all card types - * 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 - */ - -#ifndef CARD_COMMON_H -#define CARD_COMMON_H - -/* Declaration of private data structure used by card-p15.c */ -struct p15private_s; - - -struct card_ctx_s { - int reader; /* used reader */ - struct sc_context *ctx; - struct sc_card *scard; - struct sc_pkcs15_card *p15card; /* only if there is a pkcs15 application */ - struct p15private_s *p15priv; /* private data used by card-p15.c */ - - struct { - int initialized; /* the card has been initialied and the function - pointers may be used. However for - unsupported operations the particular - function pointer is set to NULL */ - - int (*enum_keypairs) (CARD card, int idx, - unsigned char *keygrip, char **keyid); - int (*enum_certs) (CARD card, int idx, char **certid, int *certtype); - int (*read_cert) (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert); - int (*sign) (CARD card, - const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - void **outdata, size_t *outdatalen ); - int (*decipher) (CARD card, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - void **outdata, size_t *outdatalen); - } fnc; - -}; - -/*-- card.c --*/ -int map_sc_err (int rc); -int card_help_get_keygrip (KsbaCert cert, unsigned char *array); - -/*-- card-15.c --*/ -void p15_release_private_data (CARD card); - -/* constructors */ -void card_p15_bind (CARD card); -void card_dinsig_bind (CARD card); - - -#endif /*CARD_COMMON_H*/ diff --git a/scd/card-dinsig.c b/scd/card-dinsig.c deleted file mode 100644 index 161d5dbfc..000000000 --- a/scd/card-dinsig.c +++ /dev/null @@ -1,256 +0,0 @@ -/* card-dinsig.c - German signature law (DINSIG) functions - * Copyright (C) 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 - */ - -/* The German signature law and its bylaw (SigG and SigV) is currently - used with an interface specification described in DIN V 66291-1. - The AID to be used is: 'D27600006601'. - - The file IDs for certificates utilize the generic format: - Cxyz - C being the hex digit 'C' (12). - x being the service indicator: - '0' := SigG conform digital signature. - '1' := entity authentication. - '2' := key encipherment. - '3' := data encipherment. - '4' := key agreement. - other values are reserved for future use. - y being the security environment number using '0' for cards - not supporting a SE number. - z being the certificate type: - '0' := C.CH (base certificate of ard holder) or C.ICC. - '1' .. '7' := C.CH (business or professional certificate - of card holder. - '8' .. 'D' := C.CA (certificate of a CA issue by the Root-CA). - 'E' := C.RCA (self certified certificate of the Root-CA). - 'F' := reserved. - - The file IDs used by default are: - '1F00' EF.SSD (security service descriptor). [o,o] - '2F02' EF.GDO (global data objects) [m,m] - 'A000' EF.PROT (signature log). Cyclic file with 20 records of 53 byte. - Read and update after user authentication. [o,o] - 'B000' EF.PK.RCA.DS (public keys of Root-CA). Size is 512b or size - of keys. [m (unless a 'C00E' is present),m] - 'B001' EF.PK.CA.DS (public keys of CAs). Size is 512b or size - of keys. [o,o] - 'C00n' EF.C.CH.DS (digital signature certificate of card holder) - with n := 0 .. 7. Size is 2k or size of cert. Read and - update allowed after user authentication. [m,m] - 'C00m' EF.C.CA.DS (digital signature certificate of CA) - with m := 8 .. E. Size is 1k or size of cert. Read always - allowed, update after uder authentication. [o,o] - 'C100' EF.C.ICC.AUT (AUT certificate of ICC) [o,m] - 'C108' EF.C.CA.AUT (AUT certificate of CA) [o,m] - 'D000' EF.DM (display message) [-,m] - - The letters in brackets indicate optional or mandatory files: The - first for card terminals under full control and the second for - "business" card terminals. - - FIXME: Needs a lot more explanation. - -*/ - - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "scdaemon.h" -#include "card-common.h" - -static int dinsig_read_cert (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert); - - - -/* See card.c for interface description. Frankly we don't do any real - enumeration but just check whether the well know files are - available. */ -static int -dinsig_enum_keypairs (CARD card, int idx, - unsigned char *keygrip, char **keyid) -{ - int rc; - unsigned char *buf; - size_t buflen; - KsbaError krc; - KsbaCert cert; - - /* fixme: We should locate the application via the EF(DIR) and not - assume a Netkey card */ - if (!idx) - rc = dinsig_read_cert (card, "DINSIG-DF01.C000", &buf, &buflen); - else if (idx == 1) - rc = dinsig_read_cert (card, "DINSIG-DF01.C200", &buf, &buflen); - else - rc = -1; - if (rc) - return rc; - - cert = ksba_cert_new (); - if (!cert) - { - xfree (buf); - return GNUPG_Out_Of_Core; - } - - krc = ksba_cert_init_from_mem (cert, buf, buflen); - xfree (buf); - if (krc) - { - log_error ("failed to parse the certificate at idx %d: %s\n", - idx, ksba_strerror (krc)); - ksba_cert_release (cert); - return GNUPG_Card_Error; - } - if (card_help_get_keygrip (cert, keygrip)) - { - log_error ("failed to calculate the keygrip at index %d\n", idx); - ksba_cert_release (cert); - return GNUPG_Card_Error; - } - ksba_cert_release (cert); - - /* return the iD */ - if (keyid) - { - *keyid = xtrymalloc (17); - if (!*keyid) - return GNUPG_Out_Of_Core; - if (!idx) - strcpy (*keyid, "DINSIG-DF01.C000"); - else - strcpy (*keyid, "DINSIG-DF01.C200"); - } - - return 0; -} - - - -/* See card.c for interface description */ -static int -dinsig_read_cert (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert) -{ - int rc; - struct sc_path path; - struct sc_file *file; - unsigned char *buf; - int buflen; - - if (!strcmp (certidstr, "DINSIG-DF01.C000")) - sc_format_path ("3F00DF01C000", &path); - else if (!strcmp (certidstr, "DINSIG-DF01.C200")) - sc_format_path ("3F00DF01C200", &path); - else - return GNUPG_Invalid_Id; - - rc = sc_select_file (card->scard, &path, &file); - if (rc) - { - log_error ("sc_select_file failed: %s\n", sc_strerror (rc)); - return map_sc_err (rc); - } - if (file->type != SC_FILE_TYPE_WORKING_EF - || file->ef_structure != SC_FILE_EF_TRANSPARENT) - { - log_error ("wrong type or structure of certificate EF\n"); - sc_file_free (file); - return GNUPG_Card_Error; - } - if (file->size < 20) /* check against a somewhat arbitrary length */ - { - log_error ("certificate EF too short\n"); - sc_file_free (file); - return GNUPG_Card_Error; - } - buf = xtrymalloc (file->size); - if (!buf) - { - sc_file_free (file); - return GNUPG_Out_Of_Core; - } - - rc = sc_read_binary (card->scard, 0, buf, file->size, 0); - if (rc >= 0 && rc != file->size) - { - log_error ("short read on certificate EF\n"); - sc_file_free (file); - xfree (buf); - return GNUPG_Card_Error; - } - sc_file_free (file); - if (rc < 0) - { - log_error ("error reading certificate EF: %s\n", sc_strerror (rc)); - xfree (buf); - return map_sc_err (rc); - } - buflen = rc; - - /* The object is not a plain certificate but wrapped into id-at - userCertificate - fixme: we should check the specs and decided - whether libksba should support it */ - if (buflen > 9 && buf[0] == 0x30 && buf[4] == 6 && buf[5] == 3 - && buf[6] == 0x55 && buf[7] == 4 && buf[8] == 0x24) - { - /* We have to strip the padding. Although this is a good idea - anyway, we have to do it due to a KSBA problem; KSBA does not - work correct when the buffer is larger than the ASN.1 - structure and the certificates here are padded with FF. So - as a workaround we look at the outer structure to get the - size of the entire thing and adjust the buflen. We can only - do this when there is a 2 byte length field */ - size_t seqlen; - if (buf[1] == 0x82) - { - seqlen = ((buf[2] << 8) | buf[3]) + 4; - if (seqlen < buflen) - buflen = seqlen; - } - memmove (buf, buf+9, buflen-9); - buflen -= 9; - } - - *cert = buf; - *ncert = buflen; - return 0; -} - - - - -/* Bind our operations to the card */ -void -card_dinsig_bind (CARD card) -{ - card->fnc.enum_keypairs = dinsig_enum_keypairs; - card->fnc.read_cert = dinsig_read_cert; - -} diff --git a/scd/card-p15.c b/scd/card-p15.c deleted file mode 100644 index 25502a610..000000000 --- a/scd/card-p15.c +++ /dev/null @@ -1,498 +0,0 @@ -/* card-p15.c - PKCS-15 based card access - * Copyright (C) 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 -#include -#include -#include -#include -#include - -#include -#include - -#include "scdaemon.h" -#include "card-common.h" - - -struct p15private_s { - int n_prkey_rsa_objs; - struct sc_pkcs15_object *prkey_rsa_objs[32]; - int n_cert_objs; - struct sc_pkcs15_object *cert_objs[32]; -}; - - -/* Allocate private data. */ -static int -init_private_data (CARD card) -{ - struct p15private_s *priv; - int rc; - - if (card->p15priv) - return 0; /* already done. */ - - priv = xtrycalloc (1, sizeof *priv); - if (!priv) - return GNUPG_Out_Of_Core; - - /* OpenSC (0.7.0) is a bit strange in that the get_objects functions - tries to be a bit too clever and implicitly does an enumeration - which eventually leads to the fact that every call to this - fucntion returns one more macthing object. The old code in - p15_enum_keypairs assume that it would alwyas return the same - numer of objects and used this to figure out what the last object - enumerated is. We now do an enum_objects just once and keep it - in the private data. */ - rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_PRKEY_RSA, - priv->prkey_rsa_objs, - DIM (priv->prkey_rsa_objs)); - if (rc < 0) - { - log_error ("private keys enumeration failed: %s\n", sc_strerror (rc)); - xfree (priv); - return GNUPG_Card_Error; - } - priv->n_prkey_rsa_objs = rc; - - /* Read all certificate objects. */ - rc = sc_pkcs15_get_objects (card->p15card, SC_PKCS15_TYPE_CERT_X509, - priv->cert_objs, - DIM (priv->cert_objs)); - if (rc < 0) - { - log_error ("private keys enumeration failed: %s\n", sc_strerror (rc)); - xfree (priv); - return GNUPG_Card_Error; - } - priv->n_cert_objs = rc; - - card->p15priv = priv; - return 0; -} - - -/* Release private data used in this module. */ -void -p15_release_private_data (CARD card) -{ - if (!card->p15priv) - return; - xfree (card->p15priv); - card->p15priv = NULL; -} - - - -/* See card.c for interface description */ -static int -p15_enum_keypairs (CARD card, int idx, - unsigned char *keygrip, char **keyid) -{ - int rc; - KsbaError krc; - struct p15private_s *priv; - struct sc_pkcs15_object *tmpobj; - int nobjs; - struct sc_pkcs15_prkey_info *pinfo; - struct sc_pkcs15_cert_info *certinfo; - struct sc_pkcs15_cert *certder; - KsbaCert cert; - - rc = init_private_data (card); - if (rc) - return rc; - priv = card->p15priv; - nobjs = priv->n_prkey_rsa_objs; - rc = 0; - if (idx >= nobjs) - return -1; - pinfo = priv->prkey_rsa_objs[idx]->data; - - /* now we need to read the certificate so that we can calculate the - keygrip */ - rc = sc_pkcs15_find_cert_by_id (card->p15card, &pinfo->id, &tmpobj); - if (rc) - { - log_info ("certificate for private key %d not found: %s\n", - idx, sc_strerror (rc)); - /* note, that we return the ID anyway */ - rc = GNUPG_Missing_Certificate; - goto return_keyid; - } - certinfo = tmpobj->data; - rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder); - if (rc) - { - log_info ("failed to read certificate for private key %d: %s\n", - idx, sc_strerror (rc)); - return GNUPG_Card_Error; - } - - cert = ksba_cert_new (); - if (!cert) - { - sc_pkcs15_free_certificate (certder); - return GNUPG_Out_Of_Core; - } - krc = ksba_cert_init_from_mem (cert, certder->data, certder->data_len); - sc_pkcs15_free_certificate (certder); - if (krc) - { - log_error ("failed to parse the certificate for private key %d: %s\n", - idx, ksba_strerror (krc)); - ksba_cert_release (cert); - return GNUPG_Card_Error; - } - if (card_help_get_keygrip (cert, keygrip)) - { - log_error ("failed to calculate the keygrip of private key %d\n", idx); - ksba_cert_release (cert); - return GNUPG_Card_Error; - } - ksba_cert_release (cert); - - rc = 0; - return_keyid: - if (keyid) - { - char *p; - int i; - - *keyid = p = xtrymalloc (9+pinfo->id.len*2+1); - if (!*keyid) - return GNUPG_Out_Of_Core; - p = stpcpy (p, "P15-5015."); - for (i=0; i < pinfo->id.len; i++, p += 2) - sprintf (p, "%02X", pinfo->id.value[i]); - *p = 0; - } - - return rc; -} - -/* See card.c for interface description */ -static int -p15_enum_certs (CARD card, int idx, char **certid, int *type) -{ - int rc; - struct p15private_s *priv; - struct sc_pkcs15_object *obj; - struct sc_pkcs15_cert_info *cinfo; - int nobjs; - - rc = init_private_data (card); - if (rc) - return rc; - priv = card->p15priv; - nobjs = priv->n_cert_objs; - rc = 0; - if (idx >= nobjs) - return -1; - obj = priv->cert_objs[idx]; - cinfo = obj->data; - - if (certid) - { - char *p; - int i; - - *certid = p = xtrymalloc (9+cinfo->id.len*2+1); - if (!*certid) - return GNUPG_Out_Of_Core; - p = stpcpy (p, "P15-5015."); - for (i=0; i < cinfo->id.len; i++, p += 2) - sprintf (p, "%02X", cinfo->id.value[i]); - *p = 0; - } - if (type) - { - if (!obj->df) - *type = 0; /* unknown */ - else if (obj->df->type == SC_PKCS15_CDF) - *type = 100; - else if (obj->df->type == SC_PKCS15_CDF_TRUSTED) - *type = 101; - else if (obj->df->type == SC_PKCS15_CDF_USEFUL) - *type = 102; - else - *type = 0; /* error -> unknown */ - } - - return rc; -} - - - -static int -idstr_to_id (const char *idstr, struct sc_pkcs15_id *id) -{ - const char *s; - int n; - - /* For now we only support the standard DF */ - if (strncmp (idstr, "P15-5015.", 9) ) - return GNUPG_Invalid_Id; - for (s=idstr+9, n=0; hexdigitp (s); s++, n++) - ; - if (*s || (n&1)) - return GNUPG_Invalid_Id; /* invalid or odd number of digits */ - n /= 2; - if (!n || n > SC_PKCS15_MAX_ID_SIZE) - return GNUPG_Invalid_Id; /* empty or too large */ - for (s=idstr+9, n=0; *s; s += 2, n++) - id->value[n] = xtoi_2 (s); - id->len = n; - return 0; -} - - -/* See card.c for interface description */ -static int -p15_read_cert (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert) -{ - struct sc_pkcs15_object *tmpobj; - struct sc_pkcs15_id certid; - struct sc_pkcs15_cert_info *certinfo; - struct sc_pkcs15_cert *certder; - int rc; - - if (!card || !certidstr || !cert || !ncert) - return GNUPG_Invalid_Value; - if (!card->p15card) - return GNUPG_No_PKCS15_App; - - rc = idstr_to_id (certidstr, &certid); - if (rc) - return rc; - - rc = sc_pkcs15_find_cert_by_id (card->p15card, &certid, &tmpobj); - if (rc) - { - log_info ("certificate '%s' not found: %s\n", - certidstr, sc_strerror (rc)); - return -1; - } - certinfo = tmpobj->data; - rc = sc_pkcs15_read_certificate (card->p15card, certinfo, &certder); - if (rc) - { - log_info ("failed to read certificate '%s': %s\n", - certidstr, sc_strerror (rc)); - return GNUPG_Card_Error; - } - - *cert = xtrymalloc (certder->data_len); - if (!*cert) - { - sc_pkcs15_free_certificate (certder); - return GNUPG_Out_Of_Core; - } - memcpy (*cert, certder->data, certder->data_len); - *ncert = certder->data_len; - sc_pkcs15_free_certificate (certder); - return 0; -} - - - - - -static int -p15_prepare_key (CARD card, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, struct sc_pkcs15_object **r_keyobj) -{ - struct sc_pkcs15_id keyid; - struct sc_pkcs15_pin_info *pin; - struct sc_pkcs15_object *keyobj, *pinobj; - char *pinvalue; - int rc; - - rc = idstr_to_id (keyidstr, &keyid); - if (rc) - return rc; - - rc = sc_pkcs15_find_prkey_by_id (card->p15card, &keyid, &keyobj); - if (rc < 0) - { - log_error ("private key not found: %s\n", sc_strerror(rc)); - return GNUPG_No_Secret_Key; - } - - rc = sc_pkcs15_find_pin_by_auth_id (card->p15card, - &keyobj->auth_id, &pinobj); - if (rc) - { - log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc)); - return GNUPG_Bad_PIN_Method; - } - pin = pinobj->data; - - /* Fixme: pack this into a verification loop */ - /* Fixme: we might want to pass pin->min_length and - pin->stored_length */ - rc = pincb (pincb_arg, pinobj->label, &pinvalue); - if (rc) - { - log_info ("PIN callback returned error: %s\n", gnupg_strerror (rc)); - return rc; - } - - rc = sc_pkcs15_verify_pin (card->p15card, pin, - pinvalue, strlen (pinvalue)); - xfree (pinvalue); - if (rc) - { - log_info ("PIN verification failed: %s\n", sc_strerror (rc)); - return GNUPG_Bad_PIN; - } - - /* fixme: check wheter we need to release KEYOBJ in case of an error */ - *r_keyobj = keyobj; - return 0; -} - - -/* See card.c for interface description */ -static int -p15_sign (CARD card, const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - void **outdata, size_t *outdatalen ) -{ - unsigned int cryptflags; - struct sc_pkcs15_object *keyobj; - int rc; - unsigned char *outbuf = NULL; - size_t outbuflen; - - if (hashalgo != GCRY_MD_SHA1) - return GNUPG_Unsupported_Algorithm; - - rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj); - if (rc) - return rc; - - cryptflags = SC_ALGORITHM_RSA_PAD_PKCS1; - - outbuflen = 1024; - outbuf = xtrymalloc (outbuflen); - if (!outbuf) - return GNUPG_Out_Of_Core; - - rc = sc_pkcs15_compute_signature (card->p15card, keyobj, - cryptflags, - indata, indatalen, - outbuf, outbuflen ); - if (rc < 0) - { - log_error ("failed to create signature: %s\n", sc_strerror (rc)); - rc = GNUPG_Card_Error; - } - else - { - *outdatalen = rc; - *outdata = outbuf; - outbuf = NULL; - rc = 0; - } - - xfree (outbuf); - return rc; -} - - -/* See card.c for description */ -static int -p15_decipher (CARD card, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - void **outdata, size_t *outdatalen ) -{ - struct sc_pkcs15_object *keyobj; - int rc; - unsigned char *outbuf = NULL; - size_t outbuflen; - - rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj); - if (rc) - return rc; - - if (card && card->scard && card->scard->driver - && !strcasecmp (card->scard->driver->short_name, "tcos")) - { - /* very ugly hack to force the use of a local key. We need this - until we have fixed the initialization code for TCOS cards */ - struct sc_pkcs15_prkey_info *prkey = keyobj->data; - if ( !(prkey->key_reference & 0x80)) - { - prkey->key_reference |= 0x80; - log_debug ("using TCOS hack to force the use of local keys\n"); - } - if (*keyidstr && keyidstr[strlen(keyidstr)-1] == '6') - { - prkey->key_reference |= 1; - log_debug ("warning: using even more TCOS hacks\n"); - } - } - - outbuflen = indatalen < 256? 256 : indatalen; - outbuf = xtrymalloc (outbuflen); - if (!outbuf) - return GNUPG_Out_Of_Core; - - rc = sc_pkcs15_decipher (card->p15card, keyobj, - 0, - indata, indatalen, - outbuf, outbuflen); - if (rc < 0) - { - log_error ("failed to decipher the data: %s\n", sc_strerror (rc)); - rc = GNUPG_Card_Error; - } - else - { - *outdatalen = rc; - *outdata = outbuf; - outbuf = NULL; - rc = 0; - } - - xfree (outbuf); - return rc; -} - - - -/* Bind our operations to the card */ -void -card_p15_bind (CARD card) -{ - card->fnc.enum_keypairs = p15_enum_keypairs; - card->fnc.enum_certs = p15_enum_certs; - card->fnc.read_cert = p15_read_cert; - card->fnc.sign = p15_sign; - card->fnc.decipher = p15_decipher; -} diff --git a/scd/card.c b/scd/card.c deleted file mode 100644 index 9e0f060e5..000000000 --- a/scd/card.c +++ /dev/null @@ -1,540 +0,0 @@ -/* card.c - SCdaemon card functions - * Copyright (C) 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 -#include -#include -#include -#include -#include - -#include -#include - -#include "scdaemon.h" -#include "card-common.h" - -/* Map the SC error codes to the GNUPG ones */ -int -map_sc_err (int rc) -{ - switch (rc) - { - case 0: rc = 0; break; - case SC_ERROR_NOT_SUPPORTED: rc = GNUPG_Not_Supported; break; - case SC_ERROR_PKCS15_APP_NOT_FOUND: rc = GNUPG_No_PKCS15_App; break; - case SC_ERROR_OUT_OF_MEMORY: rc = GNUPG_Out_Of_Core; break; - case SC_ERROR_CARD_NOT_PRESENT: rc = GNUPG_Card_Not_Present; break; - case SC_ERROR_CARD_REMOVED: rc = GNUPG_Card_Removed; break; - case SC_ERROR_INVALID_CARD: rc = GNUPG_Invalid_Card; break; - default: rc = GNUPG_Card_Error; break; - } - return rc; -} - -/* Get the keygrip from CERT, return 0 on success */ -int -card_help_get_keygrip (KsbaCert cert, unsigned char *array) -{ - GCRY_SEXP s_pkey; - int rc; - KsbaSexp p; - size_t n; - - p = ksba_cert_get_public_key (cert); - if (!p) - return -1; /* oops */ - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - return -1; /* libksba did not return a proper S-expression */ - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); - xfree (p); - if (rc) - return -1; /* can't parse that S-expression */ - array = gcry_pk_get_keygrip (s_pkey, array); - gcry_sexp_release (s_pkey); - if (!array) - return -1; /* failed to calculate the keygrip */ - return 0; -} - - - - - - - -/* Create a new context for the card and figures out some basic - information of the card. Detects whgether a PKCS_15 application is - stored. - - Common errors: GNUPG_Card_Not_Present */ -int -card_open (CARD *rcard) -{ - CARD card; - int rc; - - card = xtrycalloc (1, sizeof *card); - if (!card) - return GNUPG_Out_Of_Core; - card->reader = 0; - - rc = sc_establish_context (&card->ctx, "scdaemon"); - if (rc) - { - log_error ("failed to establish SC context: %s\n", sc_strerror (rc)); - rc = map_sc_err (rc); - goto leave; - } - if (card->reader >= card->ctx->reader_count) - { - log_error ("no card reader available\n"); - rc = GNUPG_Card_Error; - goto leave; - } - card->ctx->error_file = log_get_stream (); - card->ctx->debug = opt.debug_sc; - card->ctx->debug_file = log_get_stream (); - - if (sc_detect_card_presence (card->ctx->reader[card->reader], 0) != 1) - { - rc = GNUPG_Card_Not_Present; - goto leave; - } - - rc = sc_connect_card (card->ctx->reader[card->reader], 0, &card->scard); - if (rc) - { - log_error ("failed to connect card in reader %d: %s\n", - card->reader, sc_strerror (rc)); - rc = map_sc_err (rc); - goto leave; - } - if (opt.verbose) - log_info ("connected to card in reader %d using driver `%s'\n", - card->reader, card->scard->driver->name); - - rc = sc_lock (card->scard); - if (rc) - { - log_error ("can't lock card in reader %d: %s\n", - card->reader, sc_strerror (rc)); - rc = map_sc_err (rc); - goto leave; - } - - - leave: - if (rc) - card_close (card); - else - *rcard = card; - return rc; -} - - -/* Close a card and release all resources */ -void -card_close (CARD card) -{ - if (card) - { - if (card->p15card) - { - sc_pkcs15_unbind (card->p15card); - card->p15card = NULL; - } - if (card->p15priv) - p15_release_private_data (card); - if (card->scard) - { - sc_unlock (card->scard); - sc_disconnect_card (card->scard, 0); - card->scard = NULL; - } - if (card->ctx) - { - sc_release_context (card->ctx); - card->ctx = NULL; - } - xfree (card); - } -} - -/* Locate a simple TLV encoded data object in BUFFER of LENGTH and - return a pointer to value as well as its length in NBYTES. Return - NULL if it was not found. Note, that the function does not check - whether the value fits into the provided buffer. */ -static const char * -find_simple_tlv (const unsigned char *buffer, size_t length, - int tag, size_t *nbytes) -{ - const char *s = buffer; - size_t n = length; - size_t len; - - for (;;) - { - buffer = s; - if (n < 2) - return NULL; /* buffer too short for tag and length. */ - len = s[1]; - s += 2; n -= 2; - if (len == 255) - { - if (n < 2) - return NULL; /* we expected 2 more bytes with the length. */ - len = (s[0] << 8) | s[1]; - s += 2; n -= 2; - } - if (*buffer == tag) - { - *nbytes = len; - return s; - } - if (len > n) - return NULL; /* buffer too short to skip to the next tag. */ - s += len; n -= len; - } -} - -/* Find the ICC Serial Number within the provided BUFFER of LENGTH - (which should contain the GDO file) and return it as a hex encoded - string and allocated string in SERIAL. Return an error code when - the ICCSN was not found. */ -static int -find_iccsn (const unsigned char *buffer, size_t length, char **serial) -{ - size_t n; - const unsigned char *s; - char *p; - - s = find_simple_tlv (buffer, length, 0x5A, &n); - if (!s) - return GNUPG_Card_Error; - length -= s - buffer; - if (n > length) - { - /* Oops, it does not fit into the buffer. This is an invalid - encoding (or the buffer is too short. However, I have some - test cards with such an invalid encoding and therefore I use - this ugly workaround to return something I can further - experiment with. */ - if (n == 0x0D && length+1 == n) - { - log_debug ("enabling BMI testcard workaround\n"); - n--; - } - else - return GNUPG_Card_Error; /* Bad encoding; does not fit into buffer. */ - } - if (!n) - return GNUPG_Card_Error; /* Well, that is too short. */ - - *serial = p = xtrymalloc (2*n+1); - if (!*serial) - return GNUPG_Out_Of_Core; - for (; n; n--, p += 2, s++) - sprintf (p, "%02X", *s); - *p = 0; - return 0; -} - - -/* Retrieve the serial number and the time of the last update of the - card. The serial number is returned as a malloced string (hex - encoded) in SERIAL and the time of update is returned in STAMP. - If no update time is available the returned value is 0. The serial - is mandatory for a PKCS_15 application and an error will be - returned if this value is not availbale. For non-PKCS-15 cards a - serial number is constructed by other means. Caller must free - SERIAL unless the function returns an error. */ -int -card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp) -{ - int rc; - struct sc_path path; - struct sc_file *file; - unsigned char buf[256]; - int buflen; - - if (!card || !serial || !stamp) - return GNUPG_Invalid_Value; - - *serial = NULL; - *stamp = 0; /* not available */ - - if (!card->fnc.initialized) - { - card->fnc.initialized = 1; - /* The first use of this card tries to figure out the type of the card - and sets up the function pointers. */ - rc = sc_pkcs15_bind (card->scard, &card->p15card); - if (rc) - { - if (rc != SC_ERROR_PKCS15_APP_NOT_FOUND) - log_error ("binding of existing PKCS-15 failed in reader %d: %s\n", - card->reader, sc_strerror (rc)); - card->p15card = NULL; - rc = 0; - } - if (card->p15card) - card_p15_bind (card); - else - card_dinsig_bind (card); - card->fnc.initialized = 1; - } - - - /* We should lookup the iso 7812-1 and 8583-3 - argh ISO - practice is suppressing innovation - IETF rules! So we - always get the serialnumber from the 2F02 GDO file. */ - /* FIXME: in case we can't parse the 2F02 EF and we have a P15 card, - we should get the serial number from the respective P15 file */ - sc_format_path ("3F002F02", &path); - rc = sc_select_file (card->scard, &path, &file); - if (rc) - { - log_error ("sc_select_file failed: %s\n", sc_strerror (rc)); - return GNUPG_Card_Error; - } - if (file->type != SC_FILE_TYPE_WORKING_EF - || file->ef_structure != SC_FILE_EF_TRANSPARENT) - { - log_error ("wrong type or structure of GDO file\n"); - sc_file_free (file); - return GNUPG_Card_Error; - } - - if (!file->size || file->size >= DIM(buf) ) - { /* FIXME: Use a real parser */ - log_error ("unsupported size of GDO file (%d)\n", file->size); - sc_file_free (file); - return GNUPG_Card_Error; - } - buflen = file->size; - - rc = sc_read_binary (card->scard, 0, buf, buflen, 0); - sc_file_free (file); - if (rc < 0) - { - log_error ("error reading GDO file: %s\n", sc_strerror (rc)); - return GNUPG_Card_Error; - } - if (rc != buflen) - { - log_error ("short read on GDO file\n"); - return GNUPG_Card_Error; - } - - rc = find_iccsn (buf, buflen, serial); - if (rc == GNUPG_Card_Error) - log_error ("invalid structure of GDO file\n"); - if (!rc && card->p15card && !strcmp (*serial, "D27600000000000000000000")) - { /* This is a German card with a silly serial number. Try to get - the serial number from the EF(TokenInfo). We indicate such a - serial number by the using the prefix: "FF0100". */ - const char *efser = card->p15card->serial_number; - char *p; - - if (!efser) - efser = ""; - - xfree (*serial); - *serial = NULL; - p = xtrymalloc (strlen (efser) + 7); - if (!p) - rc = GNUPG_Out_Of_Core; - else - { - strcpy (p, "FF0100"); - strcpy (p+6, efser); - *serial = p; - } - } - else if (!rc && **serial == 'F' && (*serial)[1] == 'F') - { /* The serial number starts with our special prefix. This - requires that we put our default prefix "FF0000" in front. */ - char *p = xtrymalloc (strlen (*serial) + 7); - if (!p) - { - xfree (*serial); - *serial = NULL; - rc = GNUPG_Out_Of_Core; - } - else - { - strcpy (p, "FF0000"); - strcpy (p+6, *serial); - xfree (*serial); - *serial = p; - } - } - return rc; -} - - -/* Enumerate all keypairs on the card and return the Keygrip as well - as the internal identification of the key. KEYGRIP must be a - caller provided buffer with a size of 20 bytes which will receive - the KEYGRIP of the keypair. If KEYID is not NULL, it returns the - ID field of the key in allocated memory; this is a string without - spaces. The function returns -1 when all keys have been - enumerated. Note that the error GNUPG_Missing_Certificate may be - returned if there is just the private key but no public key (ie.e a - certificate) available. Applications might want to continue - enumerating after this error.*/ -int -card_enum_keypairs (CARD card, int idx, - unsigned char *keygrip, - char **keyid) -{ - int rc; - - if (keyid) - *keyid = NULL; - - if (!card || !keygrip) - return GNUPG_Invalid_Value; - if (idx < 0) - return GNUPG_Invalid_Index; - if (!card->fnc.initialized) - return GNUPG_Card_Not_Initialized; - if (!card->fnc.enum_keypairs) - return GNUPG_Unsupported_Operation; - rc = card->fnc.enum_keypairs (card, idx, keygrip, keyid); - if (opt.verbose) - log_info ("card operation enum_keypairs result: %s\n", - gnupg_strerror (rc)); - return rc; -} - - -/* Enumerate all trusted certificates available on the card, return - their ID in CERT and the type in CERTTYPE. Types of certificates - are: - 0 := Unknown - 100 := Regular X.509 cert - 101 := Trusted X.509 cert - 102 := Useful X.509 cert - */ -int -card_enum_certs (CARD card, int idx, char **certid, int *certtype) -{ - int rc; - - if (certid) - *certid = NULL; - - if (!card) - return GNUPG_Invalid_Value; - if (idx < 0) - return GNUPG_Invalid_Index; - if (!card->fnc.initialized) - return GNUPG_Card_Not_Initialized; - if (!card->fnc.enum_certs) - return GNUPG_Unsupported_Operation; - rc = card->fnc.enum_certs (card, idx, certid, certtype); - if (opt.verbose) - log_info ("card operation enum_certs result: %s\n", - gnupg_strerror (rc)); - return rc; -} - - - -/* Read the certificate identified by CERTIDSTR which is the - hexadecimal encoded ID of the certificate, prefixed with the string - "3F005015.". The certificate is return in DER encoded form in CERT - and NCERT. */ -int -card_read_cert (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert) -{ - int rc; - - if (!card || !certidstr || !cert || !ncert) - return GNUPG_Invalid_Value; - if (!card->fnc.initialized) - return GNUPG_Card_Not_Initialized; - if (!card->fnc.read_cert) - return GNUPG_Unsupported_Operation; - rc = card->fnc.read_cert (card, certidstr, cert, ncert); - if (opt.verbose) - log_info ("card operation read_cert result: %s\n", gnupg_strerror (rc)); - return rc; -} - - -/* Create the signature and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; it - should return the PIN in an allocated buffer and put it into PIN. */ -int -card_sign (CARD card, const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - void **outdata, size_t *outdatalen ) -{ - int rc; - - if (!card || !indata || !indatalen || !outdata || !outdatalen || !pincb) - return GNUPG_Invalid_Value; - if (!card->fnc.initialized) - return GNUPG_Card_Not_Initialized; - if (!card->fnc.sign) - return GNUPG_Unsupported_Operation; - rc = card->fnc.sign (card, keyidstr, hashalgo, - pincb, pincb_arg, - indata, indatalen, - outdata, outdatalen); - if (opt.verbose) - log_info ("card operation sign result: %s\n", gnupg_strerror (rc)); - return rc; -} - - -/* Create the signature and return the allocated result in OUTDATA. - If a PIN is required the PINCB will be used to ask for the PIN; it - should return the PIN in an allocated buffer and put it into PIN. */ -int -card_decipher (CARD card, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - void **outdata, size_t *outdatalen ) -{ - int rc; - - if (!card || !indata || !indatalen || !outdata || !outdatalen || !pincb) - return GNUPG_Invalid_Value; - if (!card->fnc.initialized) - return GNUPG_Card_Not_Initialized; - if (!card->fnc.decipher) - return GNUPG_Unsupported_Operation; - rc = card->fnc.decipher (card, keyidstr, - pincb, pincb_arg, - indata, indatalen, - outdata, outdatalen); - if (opt.verbose) - log_info ("card operation decipher result: %s\n", gnupg_strerror (rc)); - return rc; -} diff --git a/scd/command.c b/scd/command.c deleted file mode 100644 index aa410a6ee..000000000 --- a/scd/command.c +++ /dev/null @@ -1,651 +0,0 @@ -/* command.c - SCdaemon command handler - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include "scdaemon.h" -#include "../assuan/assuan.h" - -/* maximum length aloowed as a PIN; used for INQUIRE NEEDPIN */ -#define MAXLEN_PIN 100 - -#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t)) - -/* Data used to associate an Assuan context with local server data */ -struct server_local_s { - ASSUAN_CONTEXT assuan_ctx; -}; - - -/* Check whether the option NAME appears in LINE */ -static int -has_option (const char *line, const char *name) -{ - const char *s; - int n = strlen (name); - - s = strstr (line, name); - return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); -} - - - - -/* Note, that this reset_notify is also used for cleanup purposes. */ -static void -reset_notify (ASSUAN_CONTEXT ctx) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - if (ctrl->card_ctx) - { - card_close (ctrl->card_ctx); - ctrl->card_ctx = NULL; - xfree (ctrl->in_data.value); - ctrl->in_data.value = NULL; - } -} - - -static int -option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value) -{ - return 0; -} - - -/* If the card has not yet been opened, do it. Note that this - function returns an Assuan error, so don't map the error a second - time */ -static AssuanError -open_card (CTRL ctrl) -{ - if (!ctrl->card_ctx) - { - int rc = card_open (&ctrl->card_ctx); - if (rc) - return map_to_assuan_status (rc); - } - return 0; -} - - -/* SERIALNO - - Return the serial number of the card using a status reponse. This - functon should be used to check for the presence of a card. - - This function is special in that it can be used to reset the card. - Most other functions will return an error when a card change has - been detected and the use of this function is therefore required. - - Background: We want to keep the client clear of handling card - changes between operations; i.e. the client can assume that all - operations are doneon the same card unless he call this function. - */ -static int -cmd_serialno (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc = 0; - char *serial_and_stamp; - char *serial; - time_t stamp; - - if ((rc = open_card (ctrl))) - return rc; - - rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp); - if (rc) - return map_to_assuan_status (rc); - rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp); - xfree (serial); - if (rc < 0) - return ASSUAN_Out_Of_Core; - rc = 0; - assuan_write_status (ctx, "SERIALNO", serial_and_stamp); - free (serial_and_stamp); - return 0; -} - - - - -/* LEARN [--force] - - Learn all useful information of the currently inserted card. When - used without the force options, the command might do an INQUIRE - like this: - - INQUIRE KNOWNCARDP - - The client should just send an "END" if the processing should go on - or a "CANCEL" to force the function to terminate with a Cancel - error message. The response of this command is a list of status - lines formatted as this: - - S KEYPAIRINFO - - If there is no certificate yet stored on the card a single "X" is - returned as the keygrip. In addition to the keypair info, information - about all certificates stored on the card is also returned: - - S CERTINFO - - Where CERTINFO is a number indicating the type of certificate: - 0 := Unknown - 100 := Regular X.509 cert - 101 := Trusted X.509 cert - 102 := Useful X.509 cert - - -*/ -static int -cmd_learn (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc = 0; - int idx; - - if ((rc = open_card (ctrl))) - return rc; - - /* Unless the force option is used we try a shortcut by identifying - the card using a serial number and inquiring the client with - that. The client may choose to cancel the operation if he already - knows about this card */ - { - char *serial_and_stamp; - char *serial; - time_t stamp; - - rc = card_get_serial_and_stamp (ctrl->card_ctx, &serial, &stamp); - if (rc) - return map_to_assuan_status (rc); - rc = asprintf (&serial_and_stamp, "%s %lu", serial, (unsigned long)stamp); - xfree (serial); - if (rc < 0) - return ASSUAN_Out_Of_Core; - rc = 0; - assuan_write_status (ctx, "SERIALNO", serial_and_stamp); - - if (!has_option (line, "--force")) - { - char *command; - - rc = asprintf (&command, "KNOWNCARDP %s", serial_and_stamp); - if (rc < 0) - { - free (serial_and_stamp); - return ASSUAN_Out_Of_Core; - } - rc = 0; - rc = assuan_inquire (ctx, command, NULL, NULL, 0); - free (command); /* (must use standard free here) */ - if (rc) - { - if (rc != ASSUAN_Canceled) - log_error ("inquire KNOWNCARDP failed: %s\n", - assuan_strerror (rc)); - free (serial_and_stamp); - return rc; - } - /* not canceled, so we have to proceeed */ - } - free (serial_and_stamp); - } - - /* Return information about the certificates. */ - for (idx=0; !rc; idx++) - { - char *certid; - int certtype; - - rc = card_enum_certs (ctrl->card_ctx, idx, &certid, &certtype); - if (!rc) - { - char *buf; - - buf = xtrymalloc (40 + 1 + strlen (certid) + 1); - if (!buf) - rc = GNUPG_Out_Of_Core; - else - { - sprintf (buf, "%d %s", certtype, certid); - assuan_write_status (ctx, "CERTINFO", buf); - xfree (buf); - } - } - xfree (certid); - } - if (rc == -1) - rc = 0; - - - /* Return information about the keys. */ - for (idx=0; !rc; idx++) - { - unsigned char keygrip[20]; - char *keyid; - int no_cert = 0; - - rc = card_enum_keypairs (ctrl->card_ctx, idx, keygrip, &keyid); - if (rc == GNUPG_Missing_Certificate && keyid) - { - /* this does happen with an incomplete personalized - card; i.e. during the time we have stored the key on the - card but not stored the certificate; probably becuase it - has not yet been received back from the CA. Note that we - must release KEYID in this case. */ - rc = 0; - no_cert = 1; - } - if (!rc) - { - char *buf, *p; - - buf = p = xtrymalloc (40 + 1 + strlen (keyid) + 1); - if (!buf) - rc = GNUPG_Out_Of_Core; - else - { - int i; - - if (no_cert) - *p++ = 'X'; - else - { - for (i=0; i < 20; i++, p += 2) - sprintf (p, "%02X", keygrip[i]); - } - *p++ = ' '; - strcpy (p, keyid); - assuan_write_status (ctx, "KEYPAIRINFO", buf); - xfree (buf); - } - } - xfree (keyid); - } - if (rc == -1) - rc = 0; - - - return map_to_assuan_status (rc); -} - - - -/* READCERT - - */ -static int -cmd_readcert (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - unsigned char *cert; - size_t ncert; - - if ((rc = open_card (ctrl))) - return rc; - - rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert); - if (rc) - { - log_error ("card_read_cert failed: %s\n", gnupg_strerror (rc)); - } - if (!rc) - { - rc = assuan_send_data (ctx, cert, ncert); - xfree (cert); - if (rc) - return rc; - } - - return map_to_assuan_status (rc); -} - - -/* READKEY - - Return the public key for the given cert or key ID as an standard - S-Expression. */ -static int -cmd_readkey (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - unsigned char *cert = NULL; - size_t ncert, n; - KsbaCert kc = NULL; - KsbaSexp p; - - if ((rc = open_card (ctrl))) - return rc; - - rc = card_read_cert (ctrl->card_ctx, line, &cert, &ncert); - if (rc) - { - log_error ("card_read_cert failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - - kc = ksba_cert_new (); - if (!kc) - { - xfree (cert); - rc = GNUPG_Out_Of_Core; - goto leave; - } - rc = ksba_cert_init_from_mem (kc, cert, ncert); - if (rc) - { - log_error ("failed to parse the certificate: %s\n", ksba_strerror (rc)); - rc = map_ksba_err (rc); - goto leave; - } - - p = ksba_cert_get_public_key (kc); - if (!p) - { - rc = GNUPG_No_Public_Key; - goto leave; - } - - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - rc = assuan_send_data (ctx, p, n); - rc = map_assuan_err (rc); - xfree (p); - - - leave: - ksba_cert_release (kc); - xfree (cert); - return map_to_assuan_status (rc); -} - - - - -/* SETDATA - - The client should use this command to tell us the data he want to - sign. */ -static int -cmd_setdata (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int n; - char *p; - unsigned char *buf; - - /* parse the hexstring */ - for (p=line,n=0; hexdigitp (p); p++, n++) - ; - if (*p) - return set_error (Parameter_Error, "invalid hexstring"); - if ((n&1)) - return set_error (Parameter_Error, "odd number of digits"); - n /= 2; - buf = xtrymalloc (n); - if (!buf) - return ASSUAN_Out_Of_Core; - - ctrl->in_data.value = buf; - ctrl->in_data.valuelen = n; - for (p=line, n=0; n < ctrl->in_data.valuelen; p += 2, n++) - buf[n] = xtoi_2 (p); - return 0; -} - - - -static int -pin_cb (void *opaque, const char *info, char **retstr) -{ - ASSUAN_CONTEXT ctx = opaque; - char *command; - int rc; - char *value; - size_t valuelen; - - *retstr = NULL; - log_debug ("asking for PIN '%s'\n", info); - - rc = asprintf (&command, "NEEDPIN %s", info); - if (rc < 0) - return GNUPG_Out_Of_Core; - - /* FIXME: Write an inquire function which returns the result in - secure memory */ - rc = assuan_inquire (ctx, command, &value, &valuelen, MAXLEN_PIN); - free (command); - if (rc) - return map_assuan_err (rc); - - if (!valuelen || value[valuelen-1]) - { - /* We require that the returned value is an UTF-8 string */ - xfree (value); - return GNUPG_Invalid_Response; - } - *retstr = value; - return 0; -} - - -/* PKSIGN - - */ -static int -cmd_pksign (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - void *outdata; - size_t outdatalen; - char *keyidstr; - - if ((rc = open_card (ctrl))) - return rc; - - /* We have to use a copy of the key ID because the function may use - the pin_cb which in turn uses the assuan line buffer and thus - overwriting the original line with the keyid */ - keyidstr = strdup (line); - if (!keyidstr) - return ASSUAN_Out_Of_Core; - rc = card_sign (ctrl->card_ctx, - keyidstr, GCRY_MD_SHA1, - pin_cb, ctx, - ctrl->in_data.value, ctrl->in_data.valuelen, - &outdata, &outdatalen); - free (keyidstr); - if (rc) - { - log_error ("card_sign failed: %s\n", gnupg_strerror (rc)); - } - else - { - rc = assuan_send_data (ctx, outdata, outdatalen); - xfree (outdata); - if (rc) - return rc; /* that is already an assuan error code */ - } - - return map_to_assuan_status (rc); -} - -/* PKDECRYPT - - */ -static int -cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - void *outdata; - size_t outdatalen; - char *keyidstr; - - if ((rc = open_card (ctrl))) - return rc; - - keyidstr = strdup (line); - if (!keyidstr) - return ASSUAN_Out_Of_Core; - rc = card_decipher (ctrl->card_ctx, - keyidstr, - pin_cb, ctx, - ctrl->in_data.value, ctrl->in_data.valuelen, - &outdata, &outdatalen); - free (keyidstr); - if (rc) - { - log_error ("card_create_signature failed: %s\n", gnupg_strerror (rc)); - } - else - { - rc = assuan_send_data (ctx, outdata, outdatalen); - xfree (outdata); - if (rc) - return rc; /* that is already an assuan error code */ - } - - return map_to_assuan_status (rc); -} - - - - -/* Tell the assuan library about our commands */ -static int -register_commands (ASSUAN_CONTEXT ctx) -{ - static struct { - const char *name; - int cmd_id; - int (*handler)(ASSUAN_CONTEXT, char *line); - } table[] = { - { "SERIALNO", 0, cmd_serialno }, - { "LEARN", 0, cmd_learn }, - { "READCERT", 0, cmd_readcert }, - { "READKEY", 0, cmd_readkey }, - { "SETDATA", 0, cmd_setdata }, - { "PKSIGN", 0, cmd_pksign }, - { "PKDECRYPT", 0,cmd_pkdecrypt }, - { "", ASSUAN_CMD_INPUT, NULL }, - { "", ASSUAN_CMD_OUTPUT, NULL }, - { NULL } - }; - int i, j, rc; - - for (i=j=0; table[i].name; i++) - { - rc = assuan_register_command (ctx, - table[i].cmd_id? table[i].cmd_id - : (ASSUAN_CMD_USER + j++), - table[i].name, table[i].handler); - if (rc) - return rc; - } - assuan_set_hello_line (ctx, "GNU Privacy Guard's Smartcard server ready"); - - assuan_register_reset_notify (ctx, reset_notify); - assuan_register_option_handler (ctx, option_handler); - return 0; -} - - -/* Startup the server. If LISTEN_FD is given as -1, this is simple - piper server, otherwise it is a regular server */ -void -scd_command_handler (int listen_fd) -{ - int rc; - ASSUAN_CONTEXT ctx; - struct server_control_s ctrl; - - memset (&ctrl, 0, sizeof ctrl); - scd_init_default_ctrl (&ctrl); - - if (listen_fd == -1) - { - int filedes[2]; - - filedes[0] = 0; - filedes[1] = 1; - rc = assuan_init_pipe_server (&ctx, filedes); - } - else - { - rc = assuan_init_socket_server (&ctx, listen_fd); - } - if (rc) - { - log_error ("failed to initialize the server: %s\n", - assuan_strerror(rc)); - scd_exit (2); - } - rc = register_commands (ctx); - if (rc) - { - log_error ("failed to register commands with Assuan: %s\n", - assuan_strerror(rc)); - scd_exit (2); - } - assuan_set_pointer (ctx, &ctrl); - ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local); - ctrl.server_local->assuan_ctx = ctx; - - if (DBG_ASSUAN) - assuan_set_log_stream (ctx, log_get_stream ()); - - for (;;) - { - rc = assuan_accept (ctx); - if (rc == -1) - { - break; - } - else if (rc) - { - log_info ("Assuan accept problem: %s\n", assuan_strerror (rc)); - break; - } - - rc = assuan_process (ctx); - if (rc) - { - log_info ("Assuan processing failed: %s\n", assuan_strerror (rc)); - continue; - } - } - reset_notify (ctx); /* used for cleanup */ - - assuan_deinit_server (ctx); -} diff --git a/scd/scdaemon.c b/scd/scdaemon.c deleted file mode 100644 index b63b59c5b..000000000 --- a/scd/scdaemon.c +++ /dev/null @@ -1,633 +0,0 @@ -/* scdaemon.c - The GnuPG Smartcard Daemon - * 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define JNLIB_NEED_LOG_LOGV -#include "scdaemon.h" -#include "../assuan/assuan.h" /* malloc hooks */ - -#include "i18n.h" -#include "sysutils.h" - - - -enum cmd_and_opt_values -{ aNull = 0, - oCsh = 'c', - oQuiet = 'q', - oSh = 's', - oVerbose = 'v', - - oNoVerbose = 500, - oOptions, - oDebug, - oDebugAll, - oDebugWait, - oDebugSC, - oNoGreeting, - oNoOptions, - oHomedir, - oNoDetach, - oNoGrab, - oLogFile, - oServer, - oDaemon, - oBatch, - -aTest }; - - - -static ARGPARSE_OPTS opts[] = { - - { 301, NULL, 0, N_("@Options:\n ") }, - - { oServer, "server", 0, N_("run in server mode (foreground)") }, - { oDaemon, "daemon", 0, N_("run in daemon mode (background)") }, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, - { oSh, "sh", 0, N_("sh-style command output") }, - { oCsh, "csh", 0, N_("csh-style command output") }, - { oOptions, "options" , 2, N_("read options from file")}, - { oDebug, "debug" ,4|16, N_("set debugging flags")}, - { oDebugAll, "debug-all" ,0, N_("enable full debugging")}, - { oDebugWait,"debug-wait",1, "@"}, - { oDebugSC, "debug-sc", 1, N_("|N|set OpenSC debug level to N")}, - { oNoDetach, "no-detach" ,0, N_("do not detach from the console")}, - { oLogFile, "log-file" ,2, N_("use a log file for the server")}, - - - {0} -}; - - -static volatile int caught_fatal_sig = 0; - -/* It is possible that we are currently running under setuid permissions */ -static int maybe_setuid = 1; - -/* Name of the communication socket */ -static char socket_name[128]; - -static const char * -my_strusage (int level) -{ - const char *p; - switch (level) - { - case 11: p = "scdaemon (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; - case 1: - case 40: p = _("Usage: scdaemon [options] (-h for help)"); - break; - case 41: p = _("Syntax: scdaemon [options] [command [args]]\n" - "Smartcard daemon for GnuPG\n"); - break; - - default: p = NULL; - } - return p; -} - - - -static void -i18n_init (void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file( PACKAGE ); -#else -#ifdef ENABLE_NLS - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); -#endif -#endif -} - - - -/* Used by gcry for logging */ -static void -my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) -{ - /* translate the log levels */ - switch (level) - { - case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break; - case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break; - case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break; - case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break; - case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break; - case GCRY_LOG_BUG: level = JNLIB_LOG_BUG; break; - case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break; - default: level = JNLIB_LOG_ERROR; break; - } - log_logv (level, fmt, arg_ptr); -} - - -static void -cleanup (void) -{ - if (*socket_name) - { - char *p; - - remove (socket_name); - p = strrchr (socket_name, '/'); - if (p) - { - *p = 0; - rmdir (socket_name); - *p = '/'; - } - *socket_name = 0; - } -} - - -static RETSIGTYPE -cleanup_sh (int sig) -{ - if (caught_fatal_sig) - raise (sig); - caught_fatal_sig = 1; - - /* gcry_control( GCRYCTL_TERM_SECMEM );*/ - cleanup (); - -#ifndef HAVE_DOSISH_SYSTEM - { /* reset action to default action and raise signal again */ - struct sigaction nact; - nact.sa_handler = SIG_DFL; - sigemptyset( &nact.sa_mask ); - nact.sa_flags = 0; - sigaction( sig, &nact, NULL); - } -#endif - raise( sig ); -} - -int -main (int argc, char **argv ) -{ - ARGPARSE_ARGS pargs; - int orig_argc; - int may_coredump; - char **orig_argv; - FILE *configfp = NULL; - char *configname = NULL; - const char *shell; - unsigned configlineno; - int parse_debug = 0; - int default_config =1; - int greeting = 0; - int nogreeting = 0; - int pipe_server = 0; - int is_daemon = 0; - int nodetach = 0; - int csh_style = 0; - char *logfile = NULL; - int debug_wait = 0; - - set_strusage (my_strusage); - gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); - /* Please note that we may running SUID(ROOT), so be very CAREFUL - when adding any stuff between here and the call to INIT_SECMEM() - somewhere after the option parsing */ - log_set_prefix ("scdaemon", 1|4); - i18n_init (); - - /* check that the libraries are suitable. Do it here because - the option parsing 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) ); - } - - ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - gcry_set_log_handler (my_gcry_logger, NULL); - gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); - - may_coredump = disable_core_dumps (); - - shell = getenv ("SHELL"); - if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") ) - csh_style = 1; - - /* FIXME: Using this homedir option does only make sense when not - running as a system service. We might want to check for this by - looking at the uid or ebtter use an explict option for this */ - opt.homedir = getenv("GNUPGHOME"); - if (!opt.homedir || !*opt.homedir) - opt.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) - opt.homedir = pargs.r.ret_str; - } - - /* initialize the secure memory. */ - gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); - maybe_setuid = 0; - - /* - Now we are working under our real uid - */ - - - if (default_config) - configname = make_filename (opt.homedir, "scdaemon.conf", NULL ); - - argc = orig_argc; - argv = orig_argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - next_pass: - if (configname) - { - 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) ); - 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 oQuiet: opt.quiet = 1; break; - case oVerbose: opt.verbose++; break; - case oBatch: opt.batch=1; break; - - case oDebug: opt.debug |= pargs.r.ret_ulong; break; - case oDebugAll: opt.debug = ~0; break; - case oDebugWait: debug_wait = pargs.r.ret_int; break; - case oDebugSC: opt.debug_sc = pargs.r.ret_int; 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 oNoGreeting: nogreeting = 1; break; - case oNoVerbose: opt.verbose = 0; break; - case oNoOptions: break; /* no-options */ - case oHomedir: opt.homedir = pargs.r.ret_str; break; - case oNoDetach: nodetach = 1; break; - case oLogFile: logfile = pargs.r.ret_str; break; - case oCsh: csh_style = 1; break; - case oSh: csh_style = 0; break; - case oServer: pipe_server = 1; break; - case oDaemon: is_daemon = 1; break; - - default : pargs.err = configfp? 1:2; break; - } - } - if (configfp) - { - fclose( configfp ); - configfp = NULL; - xfree(configname); - configname = NULL; - goto next_pass; - } - xfree (configname); - configname = NULL; - if (log_get_errorcount(0)) - 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 - log_info ("NOTE: this is a development version!\n"); -#endif - - - if (atexit (cleanup)) - { - log_error ("atexit failed\n"); - cleanup (); - exit (1); - } - - if (debug_wait && pipe_server) - { - log_debug ("waiting for debugger - my pid is %u .....\n", - (unsigned int)getpid()); - sleep (debug_wait); - log_debug ("... okay\n"); - } - - /* now start with logging to a file if this is desired */ - if (logfile) - { - log_set_file (logfile); - log_set_prefix (NULL, 1|2|4); - } - - - if (pipe_server) - { /* this is the simple pipe based server */ - scd_command_handler (-1); - } - else if (!is_daemon) - { - log_info (_("please use the option `--daemon'" - " to run the program in the background\n")); - } - else - { /* regular server mode */ - int fd; - pid_t pid; - int i; - int len; - struct sockaddr_un serv_addr; - char *p; - - /* fixme: if there is already a running gpg-agent we should - share the same directory - and vice versa */ - *socket_name = 0; - snprintf (socket_name, DIM(socket_name)-1, - "/tmp/gpg-XXXXXX/S.scdaemon"); - socket_name[DIM(socket_name)-1] = 0; - p = strrchr (socket_name, '/'); - if (!p) - BUG (); - *p = 0;; - if (!mkdtemp(socket_name)) - { - log_error ("can't create directory `%s': %s\n", - socket_name, strerror(errno) ); - exit (1); - } - *p = '/'; - - if (strchr (socket_name, ':') ) - { - log_error ("colons are not allowed in the socket name\n"); - exit (1); - } - if (strlen (socket_name)+1 >= sizeof serv_addr.sun_path ) - { - log_error ("name of socket to long\n"); - exit (1); - } - - - fd = socket (AF_UNIX, SOCK_STREAM, 0); - if (fd == -1) - { - log_error ("can't create socket: %s\n", strerror(errno) ); - exit (1); - } - - memset (&serv_addr, 0, sizeof serv_addr); - serv_addr.sun_family = AF_UNIX; - strcpy (serv_addr.sun_path, socket_name); - len = (offsetof (struct sockaddr_un, sun_path) - + strlen(serv_addr.sun_path) + 1); - - if (bind (fd, (struct sockaddr*)&serv_addr, len) == -1) - { - log_error ("error binding socket to `%s': %s\n", - serv_addr.sun_path, strerror (errno) ); - close (fd); - exit (1); - } - - if (listen (fd, 5 ) == -1) - { - log_error ("listen() failed: %s\n", strerror (errno)); - close (fd); - exit (1); - } - - if (opt.verbose) - log_info ("listening on socket `%s'\n", socket_name ); - - - fflush (NULL); - pid = fork (); - if (pid == (pid_t)-1) - { - log_fatal ("fork failed: %s\n", strerror (errno) ); - exit (1); - } - else if (pid) - { /* we are the parent */ - char *infostr; - - close (fd); - - /* create the info string: :: */ - if (asprintf (&infostr, "SCDAEMON_INFO=%s:%lu:1", - socket_name, (ulong)pid ) < 0) - { - log_error ("out of core\n"); - kill (pid, SIGTERM); - exit (1); - } - *socket_name = 0; /* don't let cleanup() remove the socket - - the child should do this from now on */ - if (argc) - { /* run the program given on the commandline */ - if (putenv (infostr)) - { - log_error ("failed to set environment: %s\n", - strerror (errno) ); - kill (pid, SIGTERM ); - exit (1); - } - execvp (argv[0], argv); - log_error ("failed to run the command: %s\n", strerror (errno)); - kill (pid, SIGTERM); - exit (1); - } - else - { - /* print the environment string, so that the caller can use - shell's eval to set it */ - if (csh_style) - { - *strchr (infostr, '=') = ' '; - printf ( "setenv %s\n", infostr); - } - else - { - printf ( "%s; export SCDAEMON_INFO;\n", infostr); - } - free (infostr); - exit (0); - } - /* NOTREACHED */ - } /* end parent */ - - /* this is the child */ - - /* detach from tty and put process into a new session */ - if (!nodetach ) - { /* close stdin, stdout and stderr unless it is the log stream */ - for (i=0; i <= 2; i++) - { - if ( log_get_fd () != i) - close (i); - } - if (setsid() == -1) - { - log_error ("setsid() failed: %s\n", strerror(errno) ); - cleanup (); - exit (1); - } - } - - /* setup signals */ - { - struct sigaction oact, nact; - - nact.sa_handler = cleanup_sh; - sigemptyset (&nact.sa_mask); - nact.sa_flags = 0; - - sigaction (SIGHUP, NULL, &oact); - if (oact.sa_handler != SIG_IGN) - sigaction (SIGHUP, &nact, NULL); - sigaction( SIGTERM, NULL, &oact ); - if (oact.sa_handler != SIG_IGN) - sigaction (SIGTERM, &nact, NULL); - nact.sa_handler = SIG_IGN; - sigaction (SIGPIPE, &nact, NULL); - sigaction (SIGINT, &nact, NULL); - } - - if (chdir("/")) - { - log_error ("chdir to / failed: %s\n", strerror (errno)); - exit (1); - } - - scd_command_handler (fd); - - close (fd); - } - - return 0; -} - -void -scd_exit (int rc) -{ - #if 0 -#warning no update_random_seed_file - update_random_seed_file(); - #endif -#if 0 - /* at this time a bit annoying */ - 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 ); -#endif - gcry_control (GCRYCTL_TERM_SECMEM ); - rc = rc? rc : log_get_errorcount(0)? 2 : 0; - exit (rc); -} - - -void -scd_init_default_ctrl (CTRL ctrl) -{ - -} - diff --git a/scd/scdaemon.h b/scd/scdaemon.h deleted file mode 100644 index 9fbf891bb..000000000 --- a/scd/scdaemon.h +++ /dev/null @@ -1,104 +0,0 @@ -/* scdaemon.h - Global definitions for the SCdaemon - * 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 - */ - -#ifndef SCDAEMON_H -#define SCDAEMON_H - -#include -#include -#include "../common/util.h" -#include "../common/errors.h" - -#define MAX_DIGEST_LEN 24 - -/* A large struct name "opt" to keep global flags */ -struct { - unsigned int debug; /* debug flags (DBG_foo_VALUE) */ - int debug_sc; /* OpenSC debug level */ - int verbose; /* verbosity level */ - int quiet; /* be as quiet as possible */ - int dry_run; /* don't change any persistent data */ - int batch; /* batch mode */ - const char *homedir; /* configuration directory name */ -} opt; - - -#define DBG_COMMAND_VALUE 1 /* debug commands i/o */ -#define DBG_MPI_VALUE 2 /* debug mpi details */ -#define DBG_CRYPTO_VALUE 4 /* debug low level crypto */ -#define DBG_MEMORY_VALUE 32 /* debug memory allocation stuff */ -#define DBG_CACHE_VALUE 64 /* debug the caching */ -#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */ -#define DBG_HASHING_VALUE 512 /* debug hashing operations */ -#define DBG_ASSUAN_VALUE 1024 - -#define DBG_COMMAND (opt.debug & DBG_COMMAND_VALUE) -#define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE) -#define DBG_MEMORY (opt.debug & DBG_MEMORY_VALUE) -#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE) -#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE) -#define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE) - -struct server_local_s; -struct card_ctx_s; - -struct server_control_s { - struct server_local_s *server_local; - struct card_ctx_s *card_ctx; - struct { - unsigned char *value; - int valuelen; - } in_data; /* helper to store the value we are going to sign */ - -}; -typedef struct server_control_s *CTRL; -typedef struct card_ctx_s *CARD; - -/*-- scdaemon.c --*/ -void scd_exit (int rc); -void scd_init_default_ctrl (CTRL ctrl); - -/*-- command.c --*/ -void scd_command_handler (int); - -/*-- card.c --*/ -int card_open (CARD *rcard); -void card_close (CARD card); -int card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp); -int card_enum_keypairs (CARD card, int idx, - unsigned char *keygrip, - char **keyid); -int card_enum_certs (CARD card, int idx, char **certid, int *certtype); -int card_read_cert (CARD card, const char *certidstr, - unsigned char **cert, size_t *ncert); -int card_sign (CARD card, - const char *keyidstr, int hashalgo, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - void **outdata, size_t *outdatalen ); -int card_decipher (CARD card, const char *keyidstr, - int (pincb)(void*, const char *, char **), - void *pincb_arg, - const void *indata, size_t indatalen, - void **outdata, size_t *outdatalen); - - -#endif /*SCDAEMON_H*/ diff --git a/sm/ChangeLog b/sm/ChangeLog deleted file mode 100644 index a33416118..000000000 --- a/sm/ChangeLog +++ /dev/null @@ -1,734 +0,0 @@ -2002-09-03 Werner Koch - - * gpgsm.c (main): Disable the internal libgcrypt locking. - -2002-08-21 Werner Koch - - * import.c (print_imported_summary): Cleaned up. Print new - not_imported value. - (check_and_store): Update non_imported counter. - (print_import_problem): New. - (check_and_store): Print error status message. - * server.c (get_status_string): Added STATUS_IMPORT_PROBLEM. - -2002-08-20 Werner Koch - - * gpgsm.c (main): Use the log file only in server mode. - - * import.c (print_imported_summary): New. - (check_and_store): Update the counters, take new argument. - (import_one): Factored out core of gpgsm_import. - (gpgsm_import): Print counters. - (gpgsm_import_files): New. - * gpgsm.c (main): Use the new function for import. - -2002-08-19 Werner Koch - - * decrypt.c (gpgsm_decrypt): Return a better error status token. - * verify.c (gpgsm_verify): Don't error on messages with no signing - time or no message digest. This is only the case for messages - without any signed attributes. - -2002-08-16 Werner Koch - - * certpath.c: Renamed to .. - * certchain.c: this. Renamed all all other usages of "path" in the - context of certificates to "chain". - - * call-agent.c (learn_cb): Special treatment when the issuer - certificate is missing. - -2002-08-10 Werner Koch - - * Makefile.am (INCLUDES): Add definition for localedir. - - * keylist.c (list_cert_colon): Print the short fingerprint in the - key ID field. - * fingerprint.c (gpgsm_get_short_fingerprint): New. - * verify.c (gpgsm_verify): Print more verbose info for a good - signature. - -2002-08-09 Werner Koch - - * decrypt.c (prepare_decryption): Hack to detected already - unpkcsedone keys. - - * gpgsm.c (emergency_cleanup): New. - (main): Initialize the signal handler. - - * sign.c (gpgsm_sign): Reset the hash context for subsequent - signers and release it at the end. - -2002-08-05 Werner Koch - - * server.c (cmd_signer): New command "SIGNER" - (register_commands): Register it. - (cmd_sign): Pass the signer list to gpgsm_sign. - * certlist.c (gpgsm_add_to_certlist): Add SECRET argument, check - for secret key if set and changed all callers. - * sign.c (gpgsm_sign): New argument SIGNERLIST and implemt - multiple signers. - * gpgsm.c (main): Support more than one -u. - - * server.c (cmd_recipient): Return reason code 1 for No_Public_Key - which is actually what gets returned from add_to_certlist. - -2002-07-26 Werner Koch - - * certcheck.c (gpgsm_check_cert_sig): Implement proper cleanup. - (gpgsm_check_cms_signature): Ditto. - -2002-07-22 Werner Koch - - * keydb.c (keydb_add_resource): Register a lock file. - (lock_all, unlock_all): Implemented. - - * delete.c: New. - * gpgsm.c: Made --delete-key work. - * server.c (cmd_delkeys): New. - (register_commands): New command DELKEYS. - - * decrypt.c (gpgsm_decrypt): Print a convenience note when RC2 is - used and a STATUS_ERROR with the algorithm oid. - -2002-07-03 Werner Koch - - * server.c (gpgsm_status2): Insert a blank between all optional - arguments when using assuan. - * server.c (cmd_recipient): No more need for extra blank in constants. - * import.c (print_imported_status): Ditto. - * gpgsm.c (main): Ditto. - -2002-07-02 Werner Koch - - * verify.c (gpgsm_verify): Extend the STATUS_BADSIG line with - the fingerprint. - - * certpath.c (check_cert_policy): Don't use log_error to print a - warning. - - * keydb.c (keydb_store_cert): Add optional ar EXISTED and changed - all callers. - * call-agent.c (learn_cb): Print info message only for real imports. - - * import.c (gpgsm_import): Moved duplicated code to ... - (check_and_store): new function. Added magic to import the entire - chain. Print status only for real imports and moved printing code - to .. - (print_imported_status): New. - - * call-dirmngr.c (gpgsm_dirmngr_isvalid): print status of dirmngr - call in very verbose mode. - - * gpgsm.c (main): Use the same error codes for STATUS_INV_RECP as - with the server mode. - -2002-06-29 Werner Koch - - * gpgsm.c: New option --auto-issuer-key-retrieve. - * certpath.c (find_up): Try to retrieve an issuer key from an - external source and from the ephemeral key DB. - (find_up_store_certs_cb): New. - - * keydb.c (keydb_set_ephemeral): Does now return the old - state. Call the backend only when required. - - * call-dirmngr.c (start_dirmngr): Use GNUPG_DEFAULT_DIRMNGR. - (lookup_status_cb): Issue status only when CTRL is not NULL. - (gpgsm_dirmngr_lookup): Document that CTRL is optional. - - * call-agent.c (start_agent): Use GNUPG_DEFAULT_AGENT. - -2002-06-28 Werner Koch - - * server.c (cmd_recipient): Add more reason codes. - -2002-06-27 Werner Koch - - * certpath.c (gpgsm_basic_cert_check): Use - --debug-no-path-validation to also bypass this basic check. - - * gpgsm.c (main): Use GNUPG_DEFAULT_HOMEDIR constant. - - * call-agent.c (start_agent): Create and pass the list of FD to - keep in the child to assuan. - * call-dirmngr.c (start_dirmngr): Ditto. - -2002-06-26 Werner Koch - - * import.c (gpgsm_import): Print an STATUS_IMPORTED. - - * gpgsm.c: --debug-no-path-validation does not take an argument. - -2002-06-25 Werner Koch - - * certdump.c (print_dn_part): Always print a leading slash, - removed NEED_DELIM arg and changed caller. - - * export.c (gpgsm_export): Print LFs to FP and not stdout. - (print_short_info): Ditto. Make use of gpgsm_print_name. - - * server.c (cmd_export): Use output-fd instead of data lines; this - was actually the specified way. - -2002-06-24 Werner Koch - - * gpgsm.c: Removed duped help entry for --list-keys. - - * gpgsm.c, gpgsm.h: New option --debug-no-path-validation. - - * certpath.c (gpgsm_validate_path): Use it here instead of the - debug flag hack. - - * certpath.c (check_cert_policy): Return No_Policy_Match if the - policy file could not be opened. - -2002-06-20 Werner Koch - - * certlist.c (gpgsm_add_to_certlist): Fixed locating of a - certificate with the required key usage. - - * gpgsm.c (main): Fixed a segv when using --outfile without an - argument. - - * keylist.c (print_capabilities): Also check for non-repudiation - and data encipherment. - * certlist.c (cert_usage_p): Test for signing and encryption was - swapped. Add a case for certification usage, handle - non-repudiation and data encipherment. - (gpgsm_cert_use_cert_p): New. - (gpgsm_add_to_certlist): Added a CTRL argument and changed all - callers to pass it. - * certpath.c (gpgsm_validate_path): Use it here to print a status - message. Added a CTRL argument and changed all callers to pass it. - * decrypt.c (gpgsm_decrypt): Print a status message for wrong key - usage. - * verify.c (gpgsm_verify): Ditto. - * keydb.c (classify_user_id): Allow a colon delimited fingerprint. - -2002-06-19 Werner Koch - - * call-agent.c (learn_cb): Use log_info instead of log_error on - successful import. - - * keydb.c (keydb_set_ephemeral): New. - (keydb_store_cert): New are ephemeral, changed all callers. - * keylist.c (list_external_cb): Store cert as ephemeral. - * export.c (gpgsm_export): Kludge to export epehmeral certificates. - - * gpgsm.c (main): New command --list-external-keys. - -2002-06-17 Werner Koch - - * certreqgen.c (read_parameters): Improved error handling. - (gpgsm_genkey): Print error message. - -2002-06-13 Werner Koch - - * gpgsm.c (main): New option --log-file. - -2002-06-12 Werner Koch - - * call-dirmngr.c (lookup_status_cb): New. - (gpgsm_dirmngr_lookup): Use the status CB. Add new arg CTRL and - changed caller to pass it. - - * gpgsm.c (open_fwrite): New. - (main): Allow --output for --verify. - - * sign.c (hash_and_copy_data): New. - (gpgsm_sign): Implemented normal (non-detached) signatures. - * gpgsm.c (main): Ditto. - - * certpath.c (gpgsm_validate_path): Special error handling for - no policy match. - -2002-06-10 Werner Koch - - * server.c (get_status_string): Add STATUS_ERROR. - - * certpath.c (gpgsm_validate_path): Tweaked the error checking to - return error codes in a more sensitive way. - * verify.c (gpgsm_verify): Send status TRUST_NEVER also for a bad - CA certificate and when the certificate has been revoked. Issue - TRUST_FULLY even when the cert has expired. Append an error token - to these status lines. Issue the new generic error status when a - cert was not found and when leaving the function. - -2002-06-04 Werner Koch - - * gpgsm.c (main): New command --list-sigs - * keylist.c (list_cert_std): New. Use it whenever colon mode is - not used. - (list_cert_chain): New. - -2002-05-31 Werner Koch - - * gpgsm.c (main): Don't print the "go ahead" message for an - invalid command. - -2002-05-23 Werner Koch - - * import.c (gpgsm_import): Add error messages. - -2002-05-21 Werner Koch - - * keylist.c (list_internal_keys): Renamed from gpgsm_list_keys. - (list_external_keys): New. - (gpgsm_list_keys): Dispatcher for above. - * call-dirmngr.c (lookup_cb,pattern_from_strlist) - (gpgsm_dirmngr_lookup): New. - * server.c (option_handler): Handle new option --list-mode. - (do_listkeys): Handle options and actually use the mode argument. - (get_status_string): New code TRUNCATED. - - * import.c (gpgsm_import): Try to identify the type of input and - handle certs-only messages. - -2002-05-14 Werner Koch - - * gpgsm.c: New option --faked-system-time - * sign.c (gpgsm_sign): And use it here. - * certpath.c (gpgsm_validate_path): Ditto. - -2002-05-03 Werner Koch - - * certpath.c (gpgsm_validate_path): Added EXPTIME arg and changed - all callers. - * verify.c (gpgsm_verify): Tweaked usage of log_debug and - log_error. Return EXPSIG status and add expiretime to VALIDSIG. - -2002-04-26 Werner Koch - - * gpgsm.h (DBG_AGENT,DBG_AGENT_VALUE): Replaced by DBG_ASSUAN_*. - Changed all users. - - * call-agent.c (start_agent): Be more silent without -v. - * call-dirmngr.c (start_dirmngr): Ditto. - -2002-04-25 Werner Koch - - * call-agent.c (start_agent): Make copies of old locales and check - for setlocale. - -2002-04-25 Marcus Brinkmann - - * call-agent.c (start_agent): Fix error handling logic so the - locale is always correctly reset. - -2002-04-25 Marcus Brinkmann - - * server.c (option_handler): Accept display, ttyname, ttytype, - lc_ctype and lc_messages options. - * gpgsm.c (main): Allocate memory for these options. - * gpgsm.h (struct opt): Make corresponding members non-const. - -2002-04-24 Marcus Brinkmann - - * gpgsm.h (struct opt): New members display, ttyname, ttytype, - lc_ctype, lc_messages. - * gpgsm.c (enum cmd_and_opt_values): New members oDisplay, - oTTYname, oTTYtype, oLCctype, oLCmessages. - (opts): New entries for these options. - (main): Handle these new options. - * call-agent.c (start_agent): Set the various display and tty - parameter after resetting. - -2002-04-18 Werner Koch - - * certreqgen.c (gpgsm_genkey): Write status output on success. - -2002-04-15 Werner Koch - - * gpgsm.c (main): Check ksba version. - - * certpath.c (find_up): New to use the authorithKeyIdentifier. - Use it in all other functions to locate the signing cert.. - -2002-04-11 Werner Koch - - * certlist.c (cert_usable_p): New. - (gpgsm_cert_use_sign_p,gpgsm_cert_use_encrypt_p): New. - (gpgsm_cert_use_verify_p,gpgsm_cert_use_decrypt_p): New. - (gpgsm_add_to_certlist): Check the key usage. - * sign.c (gpgsm_sign): Ditto. - * verify.c (gpgsm_verify): Print a message wehn an unsuitable - certificate was used. - * decrypt.c (gpgsm_decrypt): Ditto - * keylist.c (print_capabilities): Determine values from the cert. - -2002-03-28 Werner Koch - - * keylist.c (list_cert_colon): Fixed listing of crt record; the - issuer is not at the right place. Print a chainingID. - * certpath.c (gpgsm_walk_cert_chain): Be a bit more silent on - common errors. - -2002-03-21 Werner Koch - - * export.c: New. - * gpgsm.c: Add command --export. - * server.c (cmd_export): New. - -2002-03-13 Werner Koch - - * decrypt.c (gpgsm_decrypt): Allow multiple recipients. - -2002-03-12 Werner Koch - - * certpath.c (check_cert_policy): Print the policy list. - - * verify.c (gpgsm_verify): Detect certs-only message. - -2002-03-11 Werner Koch - - * import.c (gpgsm_import): Print a notice about imported certificates - when in verbose mode. - - * gpgsm.c (main): Print INV_RECP status. - * server.c (cmd_recipient): Ditto. - - * server.c (gpgsm_status2): New. Allows for a list of strings. - (gpgsm_status): Divert to gpgsm_status2. - - * encrypt.c (gpgsm_encrypt): Don't use a default key when no - recipients are given. Print a NO_RECP status. - -2002-03-06 Werner Koch - - * server.c (cmd_listkeys, cmd_listsecretkeys): Divert to - (do_listkeys): new. Add pattern parsing. - - * keylist.c (gpgsm_list_keys): Handle selection pattern. - - * gpgsm.c: New command --learn-card - * call-agent.c (learn_cb,gpgsm_agent_learn): New. - - * gpgsm.c (main): Print error messages for non-implemented commands. - - * base64.c (base64_reader_cb): Use case insensitive compare of the - Content-Type string to detect plain base-64. - -2002-03-05 Werner Koch - - * gpgsm.c, gpgsm.h: Add local_user. - * sign.c (gpgsm_get_default_cert): New. - (get_default_signer): Use the new function if local_user is not - set otherwise used that value. - * encrypt.c (get_default_recipient): Removed. - (gpgsm_encrypt): Use gpgsm_get_default_cert. - - * verify.c (gpgsm_verify): Better error text for a bad signature - found by comparing the hashs. - -2002-02-27 Werner Koch - - * call-dirmngr.c, call-agent.c: Add 2 more arguments to all uses - of assuan_transact. - -2002-02-25 Werner Koch - - * server.c (option_handler): Allow to use -2 for "send all certs - except the root cert". - * sign.c (add_certificate_list): Implement it here. - * certpath.c (gpgsm_is_root_cert): New. - -2002-02-19 Werner Koch - - * certpath.c (check_cert_policy): New. - (gpgsm_validate_path): And call it from here. - * gpgsm.c (main): New options --policy-file, - --disable-policy-checks and --enable-policy-checks. - * gpgsm.h (opt): Added policy_file, no_policy_checks. - -2002-02-18 Werner Koch - - * certpath.c (gpgsm_validate_path): Ask the agent to add the - certificate into the trusted list. - * call-agent.c (gpgsm_agent_marktrusted): New. - -2002-02-07 Werner Koch - - * certlist.c (gpgsm_add_to_certlist): Check that the specified - name identifies a certificate unambiguously. - (gpgsm_find_cert): Ditto. - - * server.c (cmd_listkeys): Check that the data stream is available. - (cmd_listsecretkeys): Ditto. - (has_option): New. - (cmd_sign): Fix ambiguousity in option recognition. - - * gpgsm.c (main): Enable --logger-fd. - - * encrypt.c (gpgsm_encrypt): Increased buffer size for better - performance. - - * call-agent.c (gpgsm_agent_pksign): Check the S-Exp received from - the agent. - - * keylist.c (list_cert_colon): Filter out control characters. - -2002-02-06 Werner Koch - - * decrypt.c (gpgsm_decrypt): Bail out after an decryption error. - - * server.c (reset_notify): Close input and output FDs. - (cmd_encrypt,cmd_decrypt,cmd_verify,cmd_sign.cmd_import) - (cmd_genkey): Close the FDs and release the recipient list even in - the error case. - -2002-02-01 Marcus Brinkmann - - * sign.c (gpgsm_sign): Do not release certificate twice. - -2002-01-29 Werner Koch - - * call-agent.c (gpgsm_agent_havekey): New. - * keylist.c (list_cert_colon): New arg HAVE_SECRET, print "crs" - when we know that the secret key is available. - (gpgsm_list_keys): New arg MODE, check whether a secret key is - available. Changed all callers. - * gpgsm.c (main): New command --list-secret-keys. - * server.c (cmd_listsecretkeys): New. - (cmd_listkeys): Return secret keys with "crs" record. - -2002-01-28 Werner Koch - - * certreqgen.c (create_request): Store the email address in the req. - -2002-01-25 Werner Koch - - * gpgsm.c (main): Disable core dumps. - - * sign.c (add_certificate_list): New. - (gpgsm_sign): Add the certificates to the CMS object. - * certpath.c (gpgsm_walk_cert_chain): New. - * gpgsm.h (server_control_s): Add included_certs. - * gpgsm.c: Add option --include-certs. - (gpgsm_init_default_ctrl): New. - (main): Call it. - * server.c (gpgsm_server): Ditto. - (option_handler): Support --include-certs. - -2002-01-23 Werner Koch - - * certpath.c (gpgsm_validate_path): Print the DN of a missing issuer. - * certdump.c (gpgsm_dump_string): New. - (print_dn): Replaced by above. - -2002-01-22 Werner Koch - - * certpath.c (unknown_criticals): New. - (allowed_ca): New. - (gpgsm_validate_path): Check validity, CA attribute, path length - and unknown critical extensions. - -2002-01-21 Werner Koch - - * gpgsm.c: Add option --enable-crl-checks. - - * call-agent.c (start_agent): Implemented socket based access. - * call-dirmngr.c (start_dirmngr): Ditto. - -2002-01-20 Werner Koch - - * server.c (option_handler): New. - (gpgsm_server): Register it with assuan. - -2002-01-19 Werner Koch - - * server.c (gpgsm_server): Use assuan_deinit_server and setup - assuan logging if enabled. - * call-agent.c (inq_ciphertext_cb): Don't show the session key in - an Assuan log file. - - * gpgsm.c (my_strusage): Take bugreport address from configure.ac - -2002-01-15 Werner Koch - - * import.c (gpgsm_import): Just do a basic cert check before - storing it. - * certpath.c (gpgsm_basic_cert_check): New. - - * keydb.c (keydb_store_cert): New. - * import.c (store_cert): Removed and change all caller to use - the new function. - * verify.c (store_cert): Ditto. - - * certlist.c (gpgsm_add_to_certlist): Validate the path - - * certpath.c (gpgsm_validate_path): Check the trust list. - * call-agent.c (gpgsm_agent_istrusted): New. - -2002-01-14 Werner Koch - - * call-dirmngr.c (inq_certificate): Changed for new interface semantic. - * certlist.c (gpgsm_find_cert): New. - -2002-01-13 Werner Koch - - * fingerprint.c (gpgsm_get_certid): Print the serial and not the - hash after the dot. - -2002-01-11 Werner Koch - - * call-dirmngr.c: New. - * certpath.c (gpgsm_validate_path): Check the CRL here. - * fingerprint.c (gpgsm_get_certid): New. - * gpgsm.c: New options --dirmngr-program and --disable-crl-checks. - -2002-01-10 Werner Koch - - * base64.c (gpgsm_create_writer): Allow to set the object name - -2002-01-08 Werner Koch - - * keydb.c (spacep): Removed because it is now in util.c - - * server.c (cmd_genkey): New. - * certreqgen.c: New. The parameter handling code has been taken - from gnupg/g10/keygen.c version 1.0.6. - * call-agent.c (gpgsm_agent_genkey): New. - -2002-01-02 Werner Koch - - * server.c (rc_to_assuan_status): Removed and changed all callers - to use map_to_assuan_status. - -2001-12-20 Werner Koch - - * verify.c (gpgsm_verify): Implemented non-detached signature - verification. Add OUT_FP arg, initialize a writer and changed all - callers. - * server.c (cmd_verify): Pass an out_fp if one has been set. - - * base64.c (base64_reader_cb): Try to detect an S/MIME body part. - - * certdump.c (print_sexp): Renamed to gpgsm_dump_serial, made - global. - (print_time): Renamed to gpgsm_dump_time, made global. - (gpgsm_dump_serial): Take a real S-Expression as argument and - print the first item. - * keylist.c (list_cert_colon): Ditto. - * keydb.c (keydb_search_issuer_sn): Ditto. - * decrypt.c (print_integer_sexp): Removed and made callers - use gpgsm_dump_serial. - * verify.c (print_time): Removed, made callers use gpgsm_dump_time. - -2001-12-19 Marcus Brinkmann - - * call-agent.c (start_agent): Add new argument to assuan_pipe_connect. - -2001-12-18 Werner Koch - - * verify.c (print_integer_sexp): Renamed from print_integer and - print the serial number according to the S-Exp rules. - * decrypt.c (print_integer_sexp): Ditto. - -2001-12-17 Werner Koch - - * keylist.c (list_cert_colon): Changed for new return value of - get_serial. - * keydb.c (keydb_search_issuer_sn): Ditto. - * certcheck.c (gpgsm_check_cert_sig): Likewise for other S-Exp - returingin functions. - * fingerprint.c (gpgsm_get_keygrip): Ditto. - * encrypt.c (encrypt_dek): Ditto - * certcheck.c (gpgsm_check_cms_signature): Ditto - * decrypt.c (prepare_decryption): Ditto. - * call-agent.c (gpgsm_agent_pkdecrypt): Removed arg ciphertextlen, - use KsbaSexp type and calculate the length. - - * certdump.c (print_sexp): Remaned from print_integer, changed caller. - - * Makefile.am: Use the LIBGCRYPT and LIBKSBA variables. - - * fingerprint.c (gpgsm_get_keygrip): Use the new - gcry_pk_get_keygrip to calculate the grip - note the algorithm and - therefore the grip values changed. - -2001-12-15 Werner Koch - - * certcheck.c (gpgsm_check_cms_signature): Removed the faked-key - kludge. - (gpgsm_create_cms_signature): Removed the commented fake key - code. This makes the function pretty simple. - - * gpgsm.c (main): Renamed the default key database to "keyring.kbx". - - * decrypt.c (gpgsm_decrypt): Write STATUS_DECRYPTION_*. - * sign.c (gpgsm_sign): Write a STATUS_SIG_CREATED. - -2001-12-14 Werner Koch - - * keylist.c (list_cert_colon): Kludge to show an email address - encoded in the subject's DN. - - * verify.c (gpgsm_verify): Add hash debug helpers - * sign.c (gpgsm_sign): Ditto. - - * base64.c (base64_reader_cb): Reset the linelen when we need to - skip the line and adjusted test; I somehow forgot about DeMorgan. - - * server.c (cmd_encrypt,cmd_decrypt,cmd_sign,cmd_verify) - (cmd_import): Close the FDs on success. - (close_message_fd): New. - (input_notify): Setting autodetect_encoding to 0 after initializing - it to 0 is pretty pointless. Easy to fix. - - * gpgsm.c (main): New option --debug-wait n, so that it is - possible to attach gdb when used in server mode. - - * sign.c (get_default_signer): Use keydb_classify_name here. - -2001-12-14 Marcus Brinkmann - - * call-agent.c (LINELENGTH): Removed. - (gpgsm_agent_pksign): Use ASSUAN_LINELENGTH, not LINELENGTH. - (gpgsm_agent_pkdecrypt): Likewise. - -2001-12-13 Werner Koch - - * keylist.c (list_cert_colon): Print alternative names of subject - and a few other values. - -2001-12-12 Werner Koch - - * gpgsm.c (main): New options --assume-{armor,base64,binary}. - * base64.c (base64_reader_cb): Fixed non-autodetection mode. - -2001-12-04 Werner Koch - - * call-agent.c (read_from_agent): Check for inquire responses. - (request_reply): Handle them using a new callback arg, changed all - callers. - (gpgsm_agent_pkdecrypt): New. - -2001-11-27 Werner Koch - - * base64.c: New. Changed all other functions to use this instead - of direct creation of ksba_reader/writer. - * gpgsm.c (main): Set ctrl.auto_encoding unless --no-armor is used. - -2001-11-26 Werner Koch - - * gpgsm.c: New option --agent-program - * call-agent.c (start_agent): Allow to override the default path - to the agent. - - * keydb.c (keydb_add_resource): Create keybox - - * keylist.c (gpgsm_list_keys): Fixed non-server keylisting. - - * server.c (rc_to_assuan_status): New. Use it for all commands. - - - Copyright 2001, 2002 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/sm/Makefile.am b/sm/Makefile.am deleted file mode 100644 index 5c137fbb8..000000000 --- a/sm/Makefile.am +++ /dev/null @@ -1,57 +0,0 @@ -# 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 - -## Process this file with automake to produce Makefile.in - -localedir = $(datadir)/locale -INCLUDES = -I../intl -DLOCALEDIR=\"$(localedir)\" - -bin_PROGRAMS = gpgsm - -AM_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/intl \ - $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) -LDFLAGS = @LDFLAGS@ - -gpgsm_SOURCES = \ - gpgsm.c gpgsm.h \ - misc.c \ - keydb.c keydb.h \ - server.c \ - call-agent.c \ - call-dirmngr.c \ - fingerprint.c \ - base64.c \ - certlist.c \ - certdump.c \ - certcheck.c \ - certchain.c \ - keylist.c \ - verify.c \ - sign.c \ - encrypt.c \ - decrypt.c \ - import.c \ - export.c \ - delete.c \ - certreqgen.c - - -gpgsm_LDADD = ../jnlib/libjnlib.a ../assuan/libassuan.a ../kbx/libkeybox.a \ - ../common/libcommon.a $(LIBGCRYPT_LIBS) $(KSBA_LIBS) - - diff --git a/sm/base64.c b/sm/base64.c deleted file mode 100644 index f70615e97..000000000 --- a/sm/base64.c +++ /dev/null @@ -1,624 +0,0 @@ -/* base64.c - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "gpgsm.h" -#include "i18n.h" - -#ifdef HAVE_DOSISH_SYSTEM - #define LF "\r\n" -#else - #define LF "\n" -#endif - -/* data used by the reader callbacks */ -struct reader_cb_parm_s { - FILE *fp; - unsigned char line[1024]; - int linelen; - int readpos; - int have_lf; - unsigned long line_counter; - - int autodetect; /* try to detect the input encoding */ - int assume_pem; /* assume input encoding is PEM */ - int assume_base64; /* assume input is base64 encoded */ - - int identified; - int is_pem; - int is_base64; - int stop_seen; - int might_be_smime; - - struct { - int idx; - unsigned char val; - int stop_seen; - } base64; -}; - -/* data used by the writer callbacks */ -struct writer_cb_parm_s { - FILE *fp; - const char *pem_name; - - int wrote_begin; - int did_finish; - - struct { - int idx; - int quad_count; - unsigned char radbuf[4]; - } base64; - -}; - - -/* context for this module's functions */ -struct base64_context_s { - union { - struct reader_cb_parm_s rparm; - struct writer_cb_parm_s wparm; - } u; -}; - - -/* The base-64 character list */ -static unsigned char bintoasc[64] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; -/* The reverse base-64 list */ -static unsigned char asctobin[256] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, - 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, - 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff -}; - - -static int -has_only_base64 (const unsigned char *line, int linelen) -{ - if (linelen < 20) - return 0; - for (; linelen; line++, linelen--) - { - if (*line == '\n' || (linelen > 1 && *line == '\r' && line[1] == '\n')) - break; - if ( !strchr (bintoasc, *line) ) - return 0; - } - return 1; /* yes */ -} - -static int -is_empty_line (const unsigned char *line, int linelen) -{ - if (linelen >= 2 && *line == '\r' && line[1] == '\n') - return 1; - if (linelen >= 1 && *line == '\n') - return 1; - return 0; -} - - -static int -base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread) -{ - struct reader_cb_parm_s *parm = cb_value; - size_t n; - int c, c2; - - *nread = 0; - if (!buffer) - return -1; /* not supported */ - - next: - if (!parm->linelen) - { - /* read an entire line or up to the size of the buffer */ - parm->line_counter++; - parm->have_lf = 0; - for (n=0; n < DIM(parm->line);) - { - c = getc (parm->fp); - if (c == EOF) - { - if (ferror (parm->fp)) - return -1; - break; - } - parm->line[n++] = c; - if (c == '\n') - { - parm->have_lf = 1; - /* Fixme: we need to skip overlong lines while detecting - the dashed lines */ - break; - } - } - parm->linelen = n; - if (!n) - return -1; /* eof */ - parm->readpos = 0; - } - - if (!parm->identified) - { - if (!parm->autodetect) - { - if (parm->assume_pem) - { - /* wait for the header line */ - parm->linelen = parm->readpos = 0; - if (!parm->have_lf || strncmp (parm->line, "-----BEGIN ", 11) - || !strncmp (parm->line+11, "PGP ", 4)) - goto next; - parm->is_pem = 1; - } - else if (parm->assume_base64) - parm->is_base64 = 1; - } - else if (parm->line_counter == 1 && !parm->have_lf) - { - /* first line too long - assume DER encoding */ - parm->is_pem = 0; - } - else if (parm->line_counter == 1 && parm->linelen && *parm->line == 0x30) - { - /* the very first byte does pretty much look like a SEQUENCE tag*/ - parm->is_pem = 0; - } - else if ( parm->have_lf && !strncmp (parm->line, "-----BEGIN ", 11) - && strncmp (parm->line+11, "PGP ", 4) ) - { - /* Fixme: we must only compare if the line really starts at - the beginning */ - parm->is_pem = 1; - parm->linelen = parm->readpos = 0; - } - else if ( parm->have_lf && parm->line_counter == 1 - && parm->linelen >= 13 - && !ascii_memcasecmp (parm->line, "Content-Type:", 13)) - { /* might be a S/MIME body */ - parm->might_be_smime = 1; - parm->linelen = parm->readpos = 0; - goto next; - } - else if (parm->might_be_smime == 1 - && is_empty_line (parm->line, parm->linelen)) - { - parm->might_be_smime = 2; - parm->linelen = parm->readpos = 0; - goto next; - } - else if (parm->might_be_smime == 2) - { - parm->might_be_smime = 0; - if ( !has_only_base64 (parm->line, parm->linelen)) - { - parm->linelen = parm->readpos = 0; - goto next; - } - parm->is_pem = 1; - } - else - { - parm->linelen = parm->readpos = 0; - goto next; - } - parm->identified = 1; - parm->base64.stop_seen = 0; - parm->base64.idx = 0; - } - - - n = 0; - if (parm->is_pem || parm->is_base64) - { - if (parm->is_pem && parm->have_lf - && !strncmp (parm->line, "-----END ", 9)) - { - parm->identified = 0; - parm->linelen = parm->readpos = 0; - /* let us return 0 */ - } - else if (parm->stop_seen) - { /* skip the rest of the line */ - parm->linelen = parm->readpos = 0; - } - else - { - int idx = parm->base64.idx; - unsigned char val = parm->base64.val; - - while (n < count && parm->readpos < parm->linelen ) - { - c = parm->line[parm->readpos++]; - if (c == '\n' || c == ' ' || c == '\r' || c == '\t') - continue; - if (c == '=') - { /* pad character: stop */ - if (idx == 1) - buffer[n++] = val; - parm->stop_seen = 1; - break; - } - 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; - buffer[n++] = val; - val = (c<<4)&0xf0; - break; - case 2: - val |= (c>>2)&15; - buffer[n++] = val; - val = (c<<6)&0xc0; - break; - case 3: - val |= c&0x3f; - buffer[n++] = val; - break; - } - idx = (idx+1) % 4; - } - if (parm->readpos == parm->linelen) - parm->linelen = parm->readpos = 0; - - parm->base64.idx = idx; - parm->base64.val = val; - } - } - else - { /* DER encoded */ - while (n < count && parm->readpos < parm->linelen) - buffer[n++] = parm->line[parm->readpos++]; - if (parm->readpos == parm->linelen) - parm->linelen = parm->readpos = 0; - } - - *nread = n; - return 0; -} - - - -static int -simple_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread) -{ - struct reader_cb_parm_s *parm = cb_value; - size_t n; - int c = 0; - - *nread = 0; - if (!buffer) - return -1; /* not supported */ - - for (n=0; n < count; n++) - { - c = getc (parm->fp); - if (c == EOF) - { - if ( ferror (parm->fp) ) - return -1; - if (n) - break; /* return what we have before an EOF */ - return -1; - } - *(byte *)buffer++ = c; - } - - *nread = n; - return 0; -} - - - - -static int -base64_writer_cb (void *cb_value, const void *buffer, size_t count) -{ - struct writer_cb_parm_s *parm = cb_value; - unsigned char radbuf[4]; - int i, c, idx, quad_count; - const unsigned char *p; - FILE *fp = parm->fp; - - if (!count) - return 0; - - if (!parm->wrote_begin) - { - if (parm->pem_name) - { - fputs ("-----BEGIN ", fp); - fputs (parm->pem_name, fp); - fputs ("-----\n", fp); - } - parm->wrote_begin = 1; - parm->base64.idx = 0; - parm->base64.quad_count = 0; - } - - idx = parm->base64.idx; - quad_count = parm->base64.quad_count; - for (i=0; i < idx; i++) - radbuf[i] = parm->base64.radbuf[i]; - - for (p=buffer; count; p++, count--) - { - radbuf[idx++] = *p; - if (idx > 2) - { - idx = 0; - c = bintoasc[(*radbuf >> 2) & 077]; - putc (c, fp); - c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077]; - putc (c, fp); - c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077]; - putc (c, fp); - c = bintoasc[radbuf[2]&077]; - putc (c, fp); - if (++quad_count >= (64/4)) - { - fputs (LF, fp); - quad_count = 0; - } - } - } - for (i=0; i < idx; i++) - parm->base64.radbuf[i] = radbuf[i]; - parm->base64.idx = idx; - parm->base64.quad_count = quad_count; - - return ferror (fp) ? KSBA_Write_Error:0; -} - -static int -base64_finish_write (struct writer_cb_parm_s *parm) -{ - unsigned char radbuf[4]; - int i, c, idx, quad_count; - FILE *fp = parm->fp; - - if (!parm->wrote_begin) - return 0; /* nothing written */ - - /* flush the base64 encoding */ - idx = parm->base64.idx; - quad_count = parm->base64.quad_count; - for (i=0; i < idx; i++) - radbuf[i] = parm->base64.radbuf[i]; - - if (idx) - { - c = bintoasc[(*radbuf>>2)&077]; - putc (c, fp); - if (idx == 1) - { - c = bintoasc[((*radbuf << 4) & 060) & 077]; - putc (c, fp); - putc ('=', fp); - putc ('=', fp); - } - else - { - c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077]; - putc (c, fp); - c = bintoasc[((radbuf[1] << 2) & 074) & 077]; - putc (c, fp); - putc ('=', fp); - - } - if (++quad_count >= (64/4)) - { - fputs (LF, fp); - quad_count = 0; - } - } - - if (quad_count) - fputs (LF, fp); - - if (parm->pem_name) - { - fputs ("-----END ", fp); - fputs (parm->pem_name, fp); - fputs ("-----\n", fp); - } - return ferror (fp)? GNUPG_Write_Error : 0; -} - - - - -/* Create a reader for the given file descriptor. Depending on the - control information an input decoding is automagically choosen. - The function returns a Base64Context object which must be passed to - the gpgme_destroy_reader function. The created KsbaReader object - is also returned, but the caller must not call the - ksba_reader_release function on. */ -int -gpgsm_create_reader (Base64Context *ctx, - CTRL ctrl, FILE *fp, KsbaReader *r_reader) -{ - int rc; - KsbaReader r; - - *r_reader = NULL; - *ctx = xtrycalloc (1, sizeof **ctx); - if (!*ctx) - return seterr (Out_Of_Core); - - r = ksba_reader_new (); - if (!r) - { - xfree (*ctx); *ctx = NULL; - return seterr (Out_Of_Core); - } - - (*ctx)->u.rparm.fp = fp; - if (ctrl->is_pem) - { - (*ctx)->u.rparm.assume_pem = 1; - (*ctx)->u.rparm.assume_base64 = 1; - rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm); - } - else if (ctrl->is_base64) - { - (*ctx)->u.rparm.assume_base64 = 1; - rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm); - } - else if (ctrl->autodetect_encoding) - { - (*ctx)->u.rparm.autodetect = 1; - rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->u.rparm); - } - else - rc = ksba_reader_set_cb (r, simple_reader_cb, &(*ctx)->u.rparm); - - if (rc) - { - ksba_reader_release (r); - xfree (*ctx); *ctx = NULL; - return map_ksba_err (rc); - } - - *r_reader = r; - return 0; -} - - -void -gpgsm_destroy_reader (Base64Context ctx) -{ - xfree (ctx); -} - - - -/* Create a writer for the given stream. Depending on the control - information an output encoding is automagically choosen. The - function returns a Base64Context object which must be passed to the - gpgme_destroy_writer function. The created KsbaWriter object is - also returned, but the caller must not call the ksba_reader_release - function on. */ -int -gpgsm_create_writer (Base64Context *ctx, - CTRL ctrl, FILE *fp, KsbaWriter *r_writer) -{ - int rc; - KsbaWriter w; - - *r_writer = NULL; - *ctx = xtrycalloc (1, sizeof **ctx); - if (!*ctx) - return seterr (Out_Of_Core); - - w = ksba_writer_new (); - if (!w) - { - xfree (*ctx); *ctx = NULL; - return seterr (Out_Of_Core); - } - - if (ctrl->create_pem || ctrl->create_base64) - { - (*ctx)->u.wparm.fp = fp; - if (ctrl->create_pem) - (*ctx)->u.wparm.pem_name = ctrl->pem_name? ctrl->pem_name - : "CMS OBJECT"; - rc = ksba_writer_set_cb (w, base64_writer_cb, &(*ctx)->u.wparm); - } - else - rc = ksba_writer_set_file (w, fp); - - if (rc) - { - ksba_writer_release (w); - xfree (*ctx); *ctx = NULL; - return map_ksba_err (rc); - } - - *r_writer = w; - return 0; -} - - -int -gpgsm_finish_writer (Base64Context ctx) -{ - struct writer_cb_parm_s *parm; - - if (!ctx) - return GNUPG_Invalid_Value; - parm = &ctx->u.wparm; - if (parm->did_finish) - return 0; /* already done */ - parm->did_finish = 1; - if (!parm->fp) - return 0; /* callback was not used */ - return base64_finish_write (parm); -} - -void -gpgsm_destroy_writer (Base64Context ctx) -{ - xfree (ctx); -} diff --git a/sm/call-agent.c b/sm/call-agent.c deleted file mode 100644 index 6cb2fb505..000000000 --- a/sm/call-agent.c +++ /dev/null @@ -1,751 +0,0 @@ -/* call-agent.c - divert operations to the agent - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_LOCALE_H -#include -#endif - -#include "gpgsm.h" -#include "../assuan/assuan.h" -#include "i18n.h" -#include "keydb.h" /* fixme: Move this to import.c */ - -static ASSUAN_CONTEXT agent_ctx = NULL; -static int force_pipe_server = 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; -}; - -struct learn_parm_s { - int error; - ASSUAN_CONTEXT ctx; - struct membuf *data; -}; - -struct membuf { - size_t len; - size_t size; - char *buf; - int out_of_core; -}; - - - -/* A simple implemnation of a dynamic buffer. Use init_membuf() to - create a buffer, put_membuf to append bytes and get_membuf to - release and return the buffer. Allocation errors are detected but - only returned at the final get_membuf(), this helps not to clutter - the code with out of core checks. */ - -static void -init_membuf (struct membuf *mb, int initiallen) -{ - mb->len = 0; - mb->size = initiallen; - mb->out_of_core = 0; - mb->buf = xtrymalloc (initiallen); - if (!mb->buf) - mb->out_of_core = 1; -} - -static void -put_membuf (struct membuf *mb, const void *buf, size_t len) -{ - if (mb->out_of_core) - return; - - if (mb->len + len >= mb->size) - { - char *p; - - mb->size += len + 1024; - p = xtryrealloc (mb->buf, mb->size); - if (!p) - { - mb->out_of_core = 1; - return; - } - mb->buf = p; - } - memcpy (mb->buf + mb->len, buf, len); - mb->len += len; -} - -static void * -get_membuf (struct membuf *mb, size_t *len) -{ - char *p; - - if (mb->out_of_core) - { - xfree (mb->buf); - mb->buf = NULL; - return NULL; - } - - p = mb->buf; - *len = mb->len; - mb->buf = NULL; - mb->out_of_core = 1; /* don't allow a reuse */ - return p; -} - - - -/* 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 (which is suitable given that - the agent is not MT */ - - infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO"); - if (!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)) - { - log_error ("error flushing pending output: %s\n", strerror (errno)); - return seterr (Write_Error); - } - - 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 seterr (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 GNUPG_Out_Of_Core; - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } - if (!opt.ttyname && ttyname (1)) - dft_ttyname = ttyname (1); - if (opt.ttyname || dft_ttyname) - { - char *optstr; - if (asprintf (&optstr, "OPTION ttyname=%s", - opt.ttyname ? opt.ttyname : dft_ttyname) < 0) - return GNUPG_Out_Of_Core; - 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 GNUPG_Out_Of_Core; - 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 GNUPG_Out_Of_Core; - } - 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 = GNUPG_Out_Of_Core; - 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 GNUPG_Out_Of_Core; - } - 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 = GNUPG_Out_Of_Core; - 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; -} - - -static AssuanError -membuf_data_cb (void *opaque, const void *buffer, size_t length) -{ - struct membuf *data = opaque; - - if (buffer) - put_membuf (data, buffer, length); - return 0; -} - - - - -/* Call the agent to do a sign operation using the key identified by - the hex string KEYGRIP. */ -int -gpgsm_agent_pksign (const char *keygrip, - unsigned char *digest, size_t digestlen, int digestalgo, - char **r_buf, size_t *r_buflen ) -{ - int rc, i; - char *p, line[ASSUAN_LINELENGTH]; - struct membuf data; - size_t len; - - *r_buf = NULL; - rc = start_agent (); - if (rc) - return rc; - - if (digestlen*2 + 50 > DIM(line)) - return seterr (General_Error); - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - snprintf (line, DIM(line)-1, "SIGKEY %s", keygrip); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - sprintf (line, "SETHASH %d ", digestalgo); - p = line + strlen (line); - for (i=0; i < digestlen ; i++, p += 2 ) - sprintf (p, "%02X", digest[i]); - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - init_membuf (&data, 1024); - rc = assuan_transact (agent_ctx, "PKSIGN", - 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 (!gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL)) - { - xfree (*r_buf); *r_buf = NULL; - return GNUPG_Invalid_Value; - } - - return *r_buf? 0 : GNUPG_Out_Of_Core; -} - - - - -/* Handle a CIPHERTEXT inquiry. Note, we only send the data, - assuan_transact talkes care of flushing and writing the end */ -static AssuanError -inq_ciphertext_cb (void *opaque, const char *keyword) -{ - struct cipher_parm_s *parm = opaque; - AssuanError rc; - - assuan_begin_confidential (parm->ctx); - rc = assuan_send_data (parm->ctx, parm->ciphertext, parm->ciphertextlen); - assuan_end_confidential (parm->ctx); - return rc; -} - - -/* Call the agent to do a decrypt operation using the key identified by - the hex string KEYGRIP. */ -int -gpgsm_agent_pkdecrypt (const char *keygrip, - KsbaConstSexp ciphertext, - char **r_buf, size_t *r_buflen ) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - struct membuf data; - struct cipher_parm_s cipher_parm; - size_t n, len; - char *buf, *endp; - size_t ciphertextlen; - - if (!keygrip || strlen(keygrip) != 40 || !ciphertext || !r_buf || !r_buflen) - return GNUPG_Invalid_Value; - *r_buf = NULL; - - ciphertextlen = gcry_sexp_canon_len (ciphertext, 0, NULL, NULL); - if (!ciphertextlen) - return GNUPG_Invalid_Value; - - 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); - - assert ( DIM(line) >= 50 ); - snprintf (line, DIM(line)-1, "SETKEY %s", keygrip); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return map_assuan_err (rc); - - init_membuf (&data, 1024); - cipher_parm.ctx = agent_ctx; - cipher_parm.ciphertext = ciphertext; - cipher_parm.ciphertextlen = ciphertextlen; - rc = assuan_transact (agent_ctx, "PKDECRYPT", - membuf_data_cb, &data, - inq_ciphertext_cb, &cipher_parm, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - return map_assuan_err (rc); - } - - put_membuf (&data, "", 1); /* make sure it is 0 terminated */ - buf = get_membuf (&data, &len); - if (!buf) - return seterr (Out_Of_Core); - /* FIXME: We would better a return a full S-exp and not just a part */ - assert (len); - len--; /* remove the terminating 0 */ - n = strtoul (buf, &endp, 10); - if (!n || *endp != ':') - return seterr (Invalid_Sexp); - endp++; - if (endp-buf+n > len) - return seterr (Invalid_Sexp); /* oops len does not match internal len*/ - memmove (buf, endp, n); - *r_buflen = n; - *r_buf = buf; - return 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 newkey */ -int -gpgsm_agent_genkey (KsbaConstSexp keyparms, KsbaSexp *r_pubkey) -{ - int rc; - struct genkey_parm_s gk_parm; - struct membuf 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 GNUPG_Invalid_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 GNUPG_Out_Of_Core; - if (!gcry_sexp_canon_len (buf, len, NULL, NULL)) - { - xfree (buf); - return GNUPG_Invalid_Sexp; - } - *r_pubkey = buf; - return 0; -} - - -/* Ask the agent whether the certificate is in the list of trusted - keys */ -int -gpgsm_agent_istrusted (KsbaCert cert) -{ - int rc; - char *fpr; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (); - if (rc) - return rc; - - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - if (!fpr) - { - log_error ("error getting the fingerprint\n"); - return seterr (General_Error); - } - - snprintf (line, DIM(line)-1, "ISTRUSTED %s", fpr); - line[DIM(line)-1] = 0; - xfree (fpr); - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - -/* Ask the agent to mark CERT as a trusted Root-CA one */ -int -gpgsm_agent_marktrusted (KsbaCert cert) -{ - int rc; - char *fpr, *dn; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (); - if (rc) - return rc; - - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - if (!fpr) - { - log_error ("error getting the fingerprint\n"); - return seterr (General_Error); - } - - dn = ksba_cert_get_issuer (cert, 0); - if (!dn) - { - xfree (fpr); - return seterr (General_Error); - } - snprintf (line, DIM(line)-1, "MARKTRUSTED %s S %s", fpr, dn); - line[DIM(line)-1] = 0; - ksba_free (dn); - xfree (fpr); - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - return map_assuan_err (rc); -} - - - -/* Ask the agent whether the a corresponding secret key is available - for the given keygrip */ -int -gpgsm_agent_havekey (const char *hexkeygrip) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - - rc = start_agent (); - if (rc) - return rc; - - if (!hexkeygrip || strlen (hexkeygrip) != 40) - return GNUPG_Invalid_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); -} - - -static AssuanError -learn_cb (void *opaque, const void *buffer, size_t length) -{ - struct learn_parm_s *parm = opaque; - size_t len; - char *buf; - KsbaCert cert; - int rc; - - if (parm->error) - return 0; - - if (buffer) - { - put_membuf (parm->data, buffer, length); - return 0; - } - /* END encountered - process what we have */ - buf = get_membuf (parm->data, &len); - if (!buf) - { - parm->error = GNUPG_Out_Of_Core; - return 0; - } - - - /* FIXME: this should go into import.c */ - cert = ksba_cert_new (); - if (!cert) - { - parm->error = GNUPG_Out_Of_Core; - return 0; - } - rc = ksba_cert_init_from_mem (cert, buf, len); - if (rc) - { - log_error ("failed to parse a certificate: %s\n", ksba_strerror (rc)); - ksba_cert_release (cert); - parm->error = map_ksba_err (rc); - return 0; - } - - rc = gpgsm_basic_cert_check (cert); - if (rc == GNUPG_Missing_Certificate) - { /* For later use we store it in the ephemeral database. */ - log_info ("issuer certificate missing - storing as ephemeral\n"); - keydb_store_cert (cert, 1, NULL); - } - else if (rc) - log_error ("invalid certificate: %s\n", gnupg_strerror (rc)); - else - { - int existed; - - if (!keydb_store_cert (cert, 0, &existed)) - { - if (opt.verbose > 1 && existed) - log_info ("certificate already in DB\n"); - else if (opt.verbose && !existed) - log_info ("certificate imported\n"); - } - } - - ksba_cert_release (cert); - init_membuf (parm->data, 4096); - return 0; -} - -/* Call the agent to learn about a smartcard */ -int -gpgsm_agent_learn () -{ - int rc; - struct learn_parm_s learn_parm; - struct membuf data; - size_t len; - - rc = start_agent (); - if (rc) - return rc; - - init_membuf (&data, 4096); - learn_parm.error = 0; - learn_parm.ctx = agent_ctx; - learn_parm.data = &data; - rc = assuan_transact (agent_ctx, "LEARN --send", - learn_cb, &learn_parm, - NULL, NULL, NULL, NULL); - xfree (get_membuf (&data, &len)); - if (rc) - return map_assuan_err (rc); - return learn_parm.error; -} - diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c deleted file mode 100644 index a1d94e25b..000000000 --- a/sm/call-dirmngr.c +++ /dev/null @@ -1,495 +0,0 @@ -/* call-dirmngr.c - communication with the dromngr - * Copyright (C) 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 -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "gpgsm.h" -#include "../assuan/assuan.h" -#include "i18n.h" - -struct membuf { - size_t len; - size_t size; - char *buf; - int out_of_core; -}; - - - -static ASSUAN_CONTEXT dirmngr_ctx = NULL; -static int force_pipe_server = 0; - -struct inq_certificate_parm_s { - ASSUAN_CONTEXT ctx; - KsbaCert cert; -}; - -struct lookup_parm_s { - CTRL ctrl; - ASSUAN_CONTEXT ctx; - void (*cb)(void *, KsbaCert); - void *cb_value; - struct membuf data; - int error; -}; - - - - -/* A simple implementation of a dynamic buffer. Use init_membuf() to - create a buffer, put_membuf to append bytes and get_membuf to - release and return the buffer. Allocation errors are detected but - only returned at the final get_membuf(), this helps not to clutter - the code with out of core checks. */ - -static void -init_membuf (struct membuf *mb, int initiallen) -{ - mb->len = 0; - mb->size = initiallen; - mb->out_of_core = 0; - mb->buf = xtrymalloc (initiallen); - if (!mb->buf) - mb->out_of_core = 1; -} - -static void -put_membuf (struct membuf *mb, const void *buf, size_t len) -{ - if (mb->out_of_core) - return; - - if (mb->len + len >= mb->size) - { - char *p; - - mb->size += len + 1024; - p = xtryrealloc (mb->buf, mb->size); - if (!p) - { - mb->out_of_core = 1; - return; - } - mb->buf = p; - } - memcpy (mb->buf + mb->len, buf, len); - mb->len += len; -} - -static void * -get_membuf (struct membuf *mb, size_t *len) -{ - char *p; - - if (mb->out_of_core) - { - xfree (mb->buf); - mb->buf = NULL; - return NULL; - } - - p = mb->buf; - *len = mb->len; - mb->buf = NULL; - mb->out_of_core = 1; /* don't allow a reuse */ - return p; -} - - - - - -/* 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_dirmngr (void) -{ - int rc; - char *infostr, *p; - ASSUAN_CONTEXT ctx; - - if (dirmngr_ctx) - return 0; /* fixme: We need a context for each thread or serialize - the access to the dirmngr */ - - infostr = force_pipe_server? NULL : getenv ("DIRMNGR_INFO"); - if (!infostr) - { - const char *pgmname; - const char *argv[3]; - int no_close_list[3]; - int i; - - if (opt.verbose) - log_info (_("no running dirmngr - starting one\n")); - - if (fflush (NULL)) - { - log_error ("error flushing pending output: %s\n", strerror (errno)); - return seterr (Write_Error); - } - - if (!opt.dirmngr_program || !*opt.dirmngr_program) - opt.dirmngr_program = GNUPG_DEFAULT_DIRMNGR; - if ( !(pgmname = strrchr (opt.dirmngr_program, '/'))) - pgmname = opt.dirmngr_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.dirmngr_program, (char**)argv, - no_close_list); - } - else - { - int prot; - int pid; - - infostr = xstrdup (infostr); - if ( !(p = strchr (infostr, ':')) || p == infostr) - { - log_error (_("malformed DIRMNGR_INFO environment variable\n")); - xfree (infostr); - force_pipe_server = 1; - return start_dirmngr (); - } - *p++ = 0; - pid = atoi (p); - while (*p && *p != ':') - p++; - prot = *p? atoi (p+1) : 0; - if (prot != 1) - { - log_error (_("dirmngr protocol version %d is not supported\n"), - prot); - xfree (infostr); - force_pipe_server = 1; - return start_dirmngr (); - } - - rc = assuan_socket_connect (&ctx, infostr, pid); - xfree (infostr); - if (rc == ASSUAN_Connect_Failed) - { - log_error (_("can't connect to the dirmngr - trying fall back\n")); - force_pipe_server = 1; - return start_dirmngr (); - } - } - - if (rc) - { - log_error ("can't connect to the dirmngr: %s\n", assuan_strerror (rc)); - return seterr (No_Dirmngr); - } - dirmngr_ctx = ctx; - - if (DBG_ASSUAN) - log_debug ("connection to dirmngr established\n"); - return 0; -} - - - -/* Handle a SENDCERT inquiry. */ -static AssuanError -inq_certificate (void *opaque, const char *line) -{ - struct inq_certificate_parm_s *parm = opaque; - AssuanError rc; - const unsigned char *der; - size_t derlen; - - if (!(!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]))) - { - log_error ("unsupported inquiry `%s'\n", line); - return ASSUAN_Inquire_Unknown; - } - line += 8; - - if (!*line) - { /* send the current certificate */ - der = ksba_cert_get_image (parm->cert, &derlen); - if (!der) - rc = ASSUAN_Inquire_Error; - else - rc = assuan_send_data (parm->ctx, der, derlen); - } - else - { /* send the given certificate */ - int err; - KsbaCert cert; - - err = gpgsm_find_cert (line, &cert); - if (err) - { - log_error ("certificate not found: %s\n", gnupg_strerror (err)); - rc = ASSUAN_Inquire_Error; - } - else - { - der = ksba_cert_get_image (cert, &derlen); - if (!der) - rc = ASSUAN_Inquire_Error; - else - rc = assuan_send_data (parm->ctx, der, derlen); - ksba_cert_release (cert); - } - } - - return rc; -} - - - -/* Call the directory manager to check whether the certificate is valid - Returns 0 for valid or usually one of the errors: - - GNUPG_Certificate_Revoked - GNUPG_No_CRL_Known - GNUPG_CRL_Too_Old - */ -int -gpgsm_dirmngr_isvalid (KsbaCert cert) -{ - int rc; - char *certid; - char line[ASSUAN_LINELENGTH]; - struct inq_certificate_parm_s parm; - - rc = start_dirmngr (); - if (rc) - return rc; - - certid = gpgsm_get_certid (cert); - if (!certid) - { - log_error ("error getting the certificate ID\n"); - return seterr (General_Error); - } - - if (opt.verbose > 1) - { - char *fpr = gpgsm_get_fingerprint_string (cert, GCRY_MD_SHA1); - log_info ("asking dirmngr about %s\n", fpr); - xfree (fpr); - } - - parm.ctx = dirmngr_ctx; - parm.cert = cert; - - snprintf (line, DIM(line)-1, "ISVALID %s", certid); - line[DIM(line)-1] = 0; - xfree (certid); - - rc = assuan_transact (dirmngr_ctx, line, NULL, NULL, - inq_certificate, &parm, NULL, NULL); - if (opt.verbose > 1) - log_info ("response of dirmngr: %s\n", rc? assuan_strerror (rc): "okay"); - return map_assuan_err (rc); -} - - - -/* Lookup helpers*/ -static AssuanError -lookup_cb (void *opaque, const void *buffer, size_t length) -{ - struct lookup_parm_s *parm = opaque; - size_t len; - char *buf; - KsbaCert cert; - int rc; - - if (parm->error) - return 0; - - if (buffer) - { - put_membuf (&parm->data, buffer, length); - return 0; - } - /* END encountered - process what we have */ - buf = get_membuf (&parm->data, &len); - if (!buf) - { - parm->error = GNUPG_Out_Of_Core; - return 0; - } - - cert = ksba_cert_new (); - if (!cert) - { - parm->error = GNUPG_Out_Of_Core; - return 0; - } - rc = ksba_cert_init_from_mem (cert, buf, len); - if (rc) - { - log_error ("failed to parse a certificate: %s\n", ksba_strerror (rc)); - } - else - { - parm->cb (parm->cb_value, cert); - } - - ksba_cert_release (cert); - init_membuf (&parm->data, 4096); - return 0; -} - -/* Return a properly escaped pattern from NAMES. The only error - return is NULL to indicate a malloc failure. */ -static char * -pattern_from_strlist (STRLIST names) -{ - STRLIST sl; - int n; - const char *s; - char *pattern, *p; - - for (n=0, sl=names; sl; sl = sl->next) - { - for (s=sl->d; *s; s++, n++) - { - if (*s == '%' || *s == ' ' || *s == '+') - n += 2; - } - n++; - } - - p = pattern = xtrymalloc (n+1); - if (!pattern) - return NULL; - - for (n=0, sl=names; sl; sl = sl->next) - { - for (s=sl->d; *s; s++) - { - switch (*s) - { - case '%': - *p++ = '%'; - *p++ = '2'; - *p++ = '5'; - break; - case ' ': - *p++ = '%'; - *p++ = '2'; - *p++ = '0'; - break; - case '+': - *p++ = '%'; - *p++ = '2'; - *p++ = 'B'; - break; - default: - *p++ = *s; - break; - } - } - *p++ = ' '; - } - if (p == pattern) - *pattern = 0; /* is empty */ - else - p[-1] = '\0'; /* remove trailing blank */ - - return pattern; -} - -static AssuanError -lookup_status_cb (void *opaque, const char *line) -{ - struct lookup_parm_s *parm = opaque; - - if (!strncmp (line, "TRUNCATED", 9) && (line[9]==' ' || !line[9])) - { - if (parm->ctrl) - { - for (line +=9; *line == ' '; line++) - ; - gpgsm_status (parm->ctrl, STATUS_TRUNCATED, line); - } - } - return 0; -} - - -/* Run the Directroy Managers lookup command using the apptern - compiled from the strings given in NAMES. The caller must provide - the callback CB which will be passed cert by cert. Note that CTRL - is optional. */ -int -gpgsm_dirmngr_lookup (CTRL ctrl, STRLIST names, - void (*cb)(void*, KsbaCert), void *cb_value) -{ - int rc; - char *pattern; - char line[ASSUAN_LINELENGTH]; - struct lookup_parm_s parm; - size_t len; - - rc = start_dirmngr (); - if (rc) - return rc; - - pattern = pattern_from_strlist (names); - if (!pattern) - return GNUPG_Out_Of_Core; - snprintf (line, DIM(line)-1, "LOOKUP %s", pattern); - line[DIM(line)-1] = 0; - xfree (pattern); - - parm.ctrl = ctrl; - parm.ctx = dirmngr_ctx; - parm.cb = cb; - parm.cb_value = cb_value; - parm.error = 0; - init_membuf (&parm.data, 4096); - - rc = assuan_transact (dirmngr_ctx, line, lookup_cb, &parm, - NULL, NULL, lookup_status_cb, &parm); - xfree (get_membuf (&parm.data, &len)); - if (rc) - return map_assuan_err (rc); - return parm.error; -} - - diff --git a/sm/certchain.c b/sm/certchain.c deleted file mode 100644 index 8ebd8c023..000000000 --- a/sm/certchain.c +++ /dev/null @@ -1,773 +0,0 @@ -/* certchain.c - certificate chain validation - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gpgsm.h" -#include "keydb.h" -#include "i18n.h" - -static int -unknown_criticals (KsbaCert cert) -{ - static const char *known[] = { - "2.5.29.15", /* keyUsage */ - "2.5.29.19", /* basic Constraints */ - "2.5.29.32", /* certificatePolicies */ - NULL - }; - int rc = 0, i, idx, crit; - const char *oid; - KsbaError err; - - for (idx=0; !(err=ksba_cert_get_extension (cert, idx, - &oid, &crit, NULL, NULL));idx++) - { - if (!crit) - continue; - for (i=0; known[i] && strcmp (known[i],oid); i++) - ; - if (!known[i]) - { - log_error (_("critical certificate extension %s is not supported\n"), - oid); - rc = GNUPG_Unsupported_Certificate; - } - } - if (err && err != -1) - rc = map_ksba_err (err); - - return rc; -} - -static int -allowed_ca (KsbaCert cert, int *chainlen) -{ - KsbaError err; - int flag; - - err = ksba_cert_is_ca (cert, &flag, chainlen); - if (err) - return map_ksba_err (err); - if (!flag) - { - log_error (_("issuer certificate is not marked as a CA\n")); - return GNUPG_Bad_CA_Certificate; - } - return 0; -} - - -static int -check_cert_policy (KsbaCert cert) -{ - KsbaError err; - char *policies; - FILE *fp; - int any_critical; - - err = ksba_cert_get_cert_policies (cert, &policies); - if (err == KSBA_No_Data) - return 0; /* no policy given */ - if (err) - return map_ksba_err (err); - - /* STRING is a line delimited list of certifiate policies as stored - in the certificate. The line itself is colon delimited where the - first field is the OID of the policy and the second field either - N or C for normal or critical extension */ - - if (opt.verbose > 1) - log_info ("certificate's policy list: %s\n", policies); - - /* The check is very minimal but won't give false positives */ - any_critical = !!strstr (policies, ":C"); - - if (!opt.policy_file) - { - xfree (policies); - if (any_critical) - { - log_error ("critical marked policy without configured policies\n"); - return GNUPG_No_Policy_Match; - } - return 0; - } - - fp = fopen (opt.policy_file, "r"); - if (!fp) - { - log_error ("failed to open `%s': %s\n", - opt.policy_file, strerror (errno)); - xfree (policies); - return GNUPG_No_Policy_Match; - } - - for (;;) - { - int c; - char *p, line[256]; - char *haystack, *allowed; - - /* read line */ - do - { - if (!fgets (line, DIM(line)-1, fp) ) - { - xfree (policies); - if (feof (fp)) - { - fclose (fp); - /* with no critical policies this is only a warning */ - if (!any_critical) - { - log_info (_("note: certificate policy not allowed\n")); - return 0; - } - log_error (_("certificate policy not allowed\n")); - return GNUPG_No_Policy_Match; - } - fclose (fp); - return GNUPG_Read_Error; - } - - if (!*line || line[strlen(line)-1] != '\n') - { - /* eat until end of line */ - while ( (c=getc (fp)) != EOF && c != '\n') - ; - fclose (fp); - xfree (policies); - return *line? GNUPG_Line_Too_Long: GNUPG_Incomplete_Line; - } - - /* Allow for empty lines and spaces */ - for (p=line; spacep (p); p++) - ; - } - while (!*p || *p == '\n' || *p == '#'); - - /* parse line */ - for (allowed=line; spacep (allowed); allowed++) - ; - p = strpbrk (allowed, " :\n"); - if (!*p || p == allowed) - { - fclose (fp); - xfree (policies); - return GNUPG_Configuration_Error; - } - *p = 0; /* strip the rest of the line */ - /* See whether we find ALLOWED (which is an OID) in POLICIES */ - for (haystack=policies; (p=strstr (haystack, allowed)); haystack = p+1) - { - if ( !(p == policies || p[-1] == '\n') ) - continue; /* does not match the begin of a line */ - if (p[strlen (allowed)] != ':') - continue; /* the length does not match */ - /* Yep - it does match so return okay */ - fclose (fp); - xfree (policies); - return 0; - } - } -} - - -static void -find_up_store_certs_cb (void *cb_value, KsbaCert cert) -{ - if (keydb_store_cert (cert, 1, NULL)) - log_error ("error storing issuer certificate as ephemeral\n"); - ++*(int*)cb_value; -} - - -static int -find_up (KEYDB_HANDLE kh, KsbaCert cert, const char *issuer) -{ - KsbaName authid; - KsbaSexp authidno; - int rc = -1; - - if (!ksba_cert_get_auth_key_id (cert, NULL, &authid, &authidno)) - { - const char *s = ksba_name_enum (authid, 0); - if (s && *authidno) - { - rc = keydb_search_issuer_sn (kh, s, authidno); - if (rc) - keydb_search_reset (kh); - if (rc == -1) - { /* And try the ephemeral DB. */ - int old = keydb_set_ephemeral (kh, 1); - if (!old) - { - rc = keydb_search_issuer_sn (kh, s, authidno); - if (rc) - keydb_search_reset (kh); - } - keydb_set_ephemeral (kh, old); - } - } - ksba_name_release (authid); - xfree (authidno); - /* Fixme: don't know how to do dirmngr lookup with serial+issuer. */ - } - - if (rc) /* not found via authorithyKeyIdentifier, try regular issuer name */ - rc = keydb_search_subject (kh, issuer); - if (rc == -1) - { - /* Not found, lets see whether we have one in the ephemeral key DB. */ - int old = keydb_set_ephemeral (kh, 1); - if (!old) - { - keydb_search_reset (kh); - rc = keydb_search_subject (kh, issuer); - } - keydb_set_ephemeral (kh, old); - } - - if (rc == -1 && opt.auto_issuer_key_retrieve) - { - STRLIST names = NULL; - int count = 0; - char *pattern; - const char *s; - - if (opt.verbose) - log_info (_("looking up issuer at external location\n")); - /* dirmngr is confused about unknown attributes so has a quick - and ugly hack we locate the CN and use this and the - following. Fixme: we should have far ebtter parsing in the - dirmngr. */ - s = strstr (issuer, "CN="); - if (!s || s == issuer || s[-1] != ',') - s = issuer; - - pattern = xtrymalloc (strlen (s)+2); - if (!pattern) - return GNUPG_Out_Of_Core; - strcpy (stpcpy (pattern, "/"), s); - add_to_strlist (&names, pattern); - xfree (pattern); - rc = gpgsm_dirmngr_lookup (NULL, names, find_up_store_certs_cb, &count); - free_strlist (names); - if (opt.verbose) - log_info (_("number of issuers matching: %d\n"), count); - if (rc) - { - log_error ("external key lookup failed: %s\n", gnupg_strerror (rc)); - rc = -1; - } - else if (!count) - rc = -1; - else - { - int old; - /* The issuers are currently stored in the ephemeral key - DB, so we temporary switch to ephemeral mode. */ - old = keydb_set_ephemeral (kh, 1); - keydb_search_reset (kh); - rc = keydb_search_subject (kh, issuer); - keydb_set_ephemeral (kh, old); - } - } - return rc; -} - - -/* Return the next certificate up in the chain starting at START. - Returns -1 when there are no more certificates. */ -int -gpgsm_walk_cert_chain (KsbaCert start, KsbaCert *r_next) -{ - int rc = 0; - char *issuer = NULL; - char *subject = NULL; - KEYDB_HANDLE kh = keydb_new (0); - - *r_next = NULL; - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = GNUPG_General_Error; - goto leave; - } - - issuer = ksba_cert_get_issuer (start, 0); - subject = ksba_cert_get_subject (start, 0); - if (!issuer) - { - log_error ("no issuer found in certificate\n"); - rc = GNUPG_Bad_Certificate; - goto leave; - } - if (!subject) - { - log_error ("no subject found in certificate\n"); - rc = GNUPG_Bad_Certificate; - goto leave; - } - - if (!strcmp (issuer, subject)) - { - rc = -1; /* we are at the root */ - goto leave; - } - - rc = find_up (kh, start, issuer); - if (rc) - { - /* it is quite common not to have a certificate, so better don't - print an error here */ - if (rc != -1 && opt.verbose > 1) - log_error ("failed to find issuer's certificate: rc=%d\n", rc); - rc = GNUPG_Missing_Certificate; - goto leave; - } - - rc = keydb_get_cert (kh, r_next); - if (rc) - { - log_error ("failed to get cert: rc=%d\n", rc); - rc = GNUPG_General_Error; - } - - leave: - xfree (issuer); - xfree (subject); - keydb_release (kh); - return rc; -} - - -/* Check whether the CERT is a root certificate. Returns True if this - is the case. */ -int -gpgsm_is_root_cert (KsbaCert cert) -{ - char *issuer; - char *subject; - int yes; - - issuer = ksba_cert_get_issuer (cert, 0); - subject = ksba_cert_get_subject (cert, 0); - yes = (issuer && subject && !strcmp (issuer, subject)); - xfree (issuer); - xfree (subject); - return yes; -} - - -/* Validate a chain and optionally return the nearest expiration time - in R_EXPTIME */ -int -gpgsm_validate_chain (CTRL ctrl, KsbaCert cert, time_t *r_exptime) -{ - int rc = 0, depth = 0, maxdepth; - char *issuer = NULL; - char *subject = NULL; - KEYDB_HANDLE kh = keydb_new (0); - KsbaCert subject_cert = NULL, issuer_cert = NULL; - time_t current_time = gnupg_get_time (); - time_t exptime = 0; - int any_expired = 0; - int any_revoked = 0; - int any_no_crl = 0; - int any_crl_too_old = 0; - int any_no_policy_match = 0; - - if (r_exptime) - *r_exptime = 0; - - if (opt.no_chain_validation) - { - log_info ("WARNING: bypassing certificate chain validation\n"); - return 0; - } - - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = GNUPG_General_Error; - goto leave; - } - - if (DBG_X509) - gpgsm_dump_cert ("subject", cert); - - subject_cert = cert; - maxdepth = 50; - - for (;;) - { - xfree (issuer); - xfree (subject); - issuer = ksba_cert_get_issuer (subject_cert, 0); - subject = ksba_cert_get_subject (subject_cert, 0); - - if (!issuer) - { - log_error ("no issuer found in certificate\n"); - rc = GNUPG_Bad_Certificate; - goto leave; - } - - { - time_t not_before, not_after; - - not_before = ksba_cert_get_validity (subject_cert, 0); - not_after = ksba_cert_get_validity (subject_cert, 1); - if (not_before == (time_t)(-1) || not_after == (time_t)(-1)) - { - log_error ("certificate with invalid validity\n"); - rc = GNUPG_Bad_Certificate; - goto leave; - } - - if (not_after) - { - if (!exptime) - exptime = not_after; - else if (not_after < exptime) - exptime = not_after; - } - - if (not_before && current_time < not_before) - { - log_error ("certificate too young; valid from "); - gpgsm_dump_time (not_before); - log_printf ("\n"); - rc = GNUPG_Certificate_Too_Young; - goto leave; - } - if (not_after && current_time > not_after) - { - log_error ("certificate has expired at "); - gpgsm_dump_time (not_after); - log_printf ("\n"); - any_expired = 1; - } - } - - rc = unknown_criticals (subject_cert); - if (rc) - goto leave; - - if (!opt.no_policy_check) - { - rc = check_cert_policy (subject_cert); - if (rc == GNUPG_No_Policy_Match) - { - any_no_policy_match = 1; - rc = 1; - } - else if (rc) - goto leave; - } - - if (!opt.no_crl_check) - { - rc = gpgsm_dirmngr_isvalid (subject_cert); - if (rc) - { - switch (rc) - { - case GNUPG_Certificate_Revoked: - log_error (_("the certificate has been revoked\n")); - any_revoked = 1; - break; - case GNUPG_No_CRL_Known: - log_error (_("no CRL found for certificate\n")); - any_no_crl = 1; - break; - case GNUPG_CRL_Too_Old: - log_error (_("the available CRL is too old\n")); - log_info (_("please make sure that the " - "\"dirmngr\" is properly installed\n")); - any_crl_too_old = 1; - break; - default: - log_error (_("checking the CRL failed: %s\n"), - gnupg_strerror (rc)); - goto leave; - } - rc = 0; - } - } - - if (subject && !strcmp (issuer, subject)) - { - if (gpgsm_check_cert_sig (subject_cert, subject_cert) ) - { - log_error ("selfsigned certificate has a BAD signatures\n"); - rc = depth? GNUPG_Bad_Certificate_Chain : GNUPG_Bad_Certificate; - goto leave; - } - rc = allowed_ca (subject_cert, NULL); - if (rc) - goto leave; - - rc = gpgsm_agent_istrusted (subject_cert); - if (!rc) - ; - else if (rc == GNUPG_Not_Trusted) - { - int rc2; - - char *fpr = gpgsm_get_fingerprint_string (subject_cert, - GCRY_MD_SHA1); - log_info (_("root certificate is not marked trusted\n")); - log_info (_("fingerprint=%s\n"), fpr? fpr : "?"); - xfree (fpr); - rc2 = gpgsm_agent_marktrusted (subject_cert); - if (!rc2) - { - log_info (_("root certificate has now" - " been marked as trusted\n")); - rc = 0; - } - else - { - gpgsm_dump_cert ("issuer", subject_cert); - log_info ("after checking the fingerprint, you may want " - "to enter it manually into " - "\"~/.gnupg-test/trustlist.txt\"\n"); - } - } - else - { - log_error (_("checking the trust list failed: %s\n"), - gnupg_strerror (rc)); - } - - break; /* okay, a self-signed certicate is an end-point */ - } - - depth++; - if (depth > maxdepth) - { - log_error (_("certificate chain too long\n")); - rc = GNUPG_Bad_Certificate_Chain; - goto leave; - } - - /* find the next cert up the tree */ - keydb_search_reset (kh); - rc = find_up (kh, subject_cert, issuer); - if (rc) - { - if (rc == -1) - { - log_info ("issuer certificate ("); - gpgsm_dump_string (issuer); - log_printf (") not found\n"); - } - else - log_error ("failed to find issuer's certificate: rc=%d\n", rc); - rc = GNUPG_Missing_Certificate; - goto leave; - } - - ksba_cert_release (issuer_cert); issuer_cert = NULL; - rc = keydb_get_cert (kh, &issuer_cert); - if (rc) - { - log_error ("failed to get cert: rc=%d\n", rc); - rc = GNUPG_General_Error; - goto leave; - } - - if (DBG_X509) - { - log_debug ("got issuer's certificate:\n"); - gpgsm_dump_cert ("issuer", issuer_cert); - } - - if (gpgsm_check_cert_sig (issuer_cert, subject_cert) ) - { - log_error ("certificate has a BAD signatures\n"); - rc = GNUPG_Bad_Certificate_Chain; - goto leave; - } - - { - int chainlen; - rc = allowed_ca (issuer_cert, &chainlen); - if (rc) - goto leave; - if (chainlen >= 0 && (depth - 1) > chainlen) - { - log_error (_("certificate chain longer than allowed by CA (%d)\n"), - chainlen); - rc = GNUPG_Bad_Certificate_Chain; - goto leave; - } - } - - rc = gpgsm_cert_use_cert_p (issuer_cert); - if (rc) - { - gpgsm_status2 (ctrl, STATUS_ERROR, "certcert.issuer.keyusage", - gnupg_error_token (rc), NULL); - rc = 0; - } - - if (opt.verbose) - log_info ("certificate is good\n"); - - keydb_search_reset (kh); - subject_cert = issuer_cert; - issuer_cert = NULL; - } - - if (opt.no_policy_check) - log_info ("policies not checked due to --disable-policy-checks option\n"); - if (opt.no_crl_check) - log_info ("CRLs not checked due to --disable-crl-checks option\n"); - - if (!rc) - { /* If we encountered an error somewhere during the checks, set - the error code to the most critical one */ - if (any_revoked) - rc = GNUPG_Certificate_Revoked; - else if (any_no_crl) - rc = GNUPG_No_CRL_Known; - else if (any_crl_too_old) - rc = GNUPG_CRL_Too_Old; - else if (any_no_policy_match) - rc = GNUPG_No_Policy_Match; - else if (any_expired) - rc = GNUPG_Certificate_Expired; - } - - leave: - if (r_exptime) - *r_exptime = exptime; - xfree (issuer); - keydb_release (kh); - ksba_cert_release (issuer_cert); - if (subject_cert != cert) - ksba_cert_release (subject_cert); - return rc; -} - - -/* Check that the given certificate is valid but DO NOT check any - constraints. We assume that the issuers certificate is already in - the DB and that this one is valid; which it should be because it - has been checked using this function. */ -int -gpgsm_basic_cert_check (KsbaCert cert) -{ - int rc = 0; - char *issuer = NULL; - char *subject = NULL; - KEYDB_HANDLE kh = keydb_new (0); - KsbaCert issuer_cert = NULL; - - if (opt.no_chain_validation) - { - log_info ("WARNING: bypassing basic certificate checks\n"); - return 0; - } - - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = GNUPG_General_Error; - goto leave; - } - - issuer = ksba_cert_get_issuer (cert, 0); - subject = ksba_cert_get_subject (cert, 0); - if (!issuer) - { - log_error ("no issuer found in certificate\n"); - rc = GNUPG_Bad_Certificate; - goto leave; - } - - if (subject && !strcmp (issuer, subject)) - { - if (gpgsm_check_cert_sig (cert, cert) ) - { - log_error ("selfsigned certificate has a BAD signatures\n"); - rc = GNUPG_Bad_Certificate; - goto leave; - } - } - else - { - /* find the next cert up the tree */ - keydb_search_reset (kh); - rc = find_up (kh, cert, issuer); - if (rc) - { - if (rc == -1) - { - log_info ("issuer certificate ("); - gpgsm_dump_string (issuer); - log_printf (") not found\n"); - } - else - log_error ("failed to find issuer's certificate: rc=%d\n", rc); - rc = GNUPG_Missing_Certificate; - goto leave; - } - - ksba_cert_release (issuer_cert); issuer_cert = NULL; - rc = keydb_get_cert (kh, &issuer_cert); - if (rc) - { - log_error ("failed to get cert: rc=%d\n", rc); - rc = GNUPG_General_Error; - goto leave; - } - - if (gpgsm_check_cert_sig (issuer_cert, cert) ) - { - log_error ("certificate has a BAD signatures\n"); - rc = GNUPG_Bad_Certificate; - goto leave; - } - if (opt.verbose) - log_info ("certificate is good\n"); - } - - leave: - xfree (issuer); - keydb_release (kh); - ksba_cert_release (issuer_cert); - return rc; -} - diff --git a/sm/certcheck.c b/sm/certcheck.c deleted file mode 100644 index 4700fe723..000000000 --- a/sm/certcheck.c +++ /dev/null @@ -1,289 +0,0 @@ -/* certcheck.c - check one certificate - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gpgsm.h" -#include "keydb.h" -#include "i18n.h" - - -static int -do_encode_md (GCRY_MD_HD md, int algo, unsigned int nbits, - GCRY_MPI *r_val) -{ - int nframe = (nbits+7) / 8; - byte *frame; - int i, n; - byte asn[100]; - size_t asnlen; - size_t len; - - asnlen = DIM(asn); - if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen)) - { - log_error ("No object identifier for algo %d\n", algo); - return GNUPG_Internal_Error; - } - - len = gcry_md_get_algo_dlen (algo); - - if ( len + asnlen + 4 > nframe ) - { - log_error ("can't encode a %d bit MD into a %d bits frame\n", - (int)(len*8), (int)nbits); - return GNUPG_Internal_Error; - } - - /* 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 = xtrymalloc (nframe); - if (!frame) - return GNUPG_Out_Of_Core; - n = 0; - frame[n++] = 0; - frame[n++] = 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 (DBG_X509) - { - int j; - log_debug ("encoded hash:"); - for (j=0; j < nframe; j++) - log_printf (" %02X", frame[j]); - log_printf ("\n"); - } - - gcry_mpi_scan (r_val, GCRYMPI_FMT_USG, frame, &nframe); - xfree (frame); - return 0; -} - - -/* - Check the signature on CERT using the ISSUER-CERT. This function - does only test the cryptographic signature and nothing else. It is - assumed that the ISSUER_CERT is valid. */ -int -gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert) -{ - const char *algoid; - GCRY_MD_HD md; - int rc, algo; - GCRY_MPI frame; - KsbaSexp p; - size_t n; - GCRY_SEXP s_sig, s_hash, s_pkey; - - algo = gcry_md_map_name ( (algoid=ksba_cert_get_digest_algo (cert))); - if (!algo) - { - log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?"); - return GNUPG_General_Error; - } - md = gcry_md_open (algo, 0); - if (!md) - { - log_error ("md_open failed: %s\n", gcry_strerror (-1)); - return GNUPG_General_Error; - } - - rc = ksba_cert_hash (cert, 1, HASH_FNC, md); - if (rc) - { - log_error ("ksba_cert_hash failed: %s\n", ksba_strerror (rc)); - gcry_md_close (md); - return map_ksba_err (rc); - } - gcry_md_final (md); - - p = ksba_cert_get_sig_val (cert); - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - gcry_md_close (md); - ksba_free (p); - return GNUPG_Bug; - } - rc = gcry_sexp_sscan ( &s_sig, NULL, p, n); - ksba_free (p); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); - gcry_md_close (md); - return map_gcry_err (rc); - } - - p = ksba_cert_get_public_key (issuer_cert); - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - gcry_md_close (md); - ksba_free (p); - gcry_sexp_release (s_sig); - return GNUPG_Bug; - } - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); - ksba_free (p); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); - gcry_md_close (md); - gcry_sexp_release (s_sig); - return map_gcry_err (rc); - } - - rc = do_encode_md (md, algo, gcry_pk_get_nbits (s_pkey), &frame); - if (rc) - { - gcry_md_close (md); - gcry_sexp_release (s_sig); - gcry_sexp_release (s_pkey); - return rc; - } - - /* put hash into the S-Exp s_hash */ - if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) ) - BUG (); - gcry_mpi_release (frame); - - rc = gcry_pk_verify (s_sig, s_hash, s_pkey); - if (DBG_CRYPTO) - log_debug ("gcry_pk_verify: %s\n", gcry_strerror (rc)); - gcry_md_close (md); - gcry_sexp_release (s_sig); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_pkey); - return map_gcry_err (rc); -} - - - -int -gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval, - GCRY_MD_HD md, int algo) -{ - int rc; - KsbaSexp p; - GCRY_MPI frame; - GCRY_SEXP s_sig, s_hash, s_pkey; - size_t n; - - n = gcry_sexp_canon_len (sigval, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - return GNUPG_Bug; - } - rc = gcry_sexp_sscan (&s_sig, NULL, sigval, n); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); - return map_gcry_err (rc); - } - - p = ksba_cert_get_public_key (cert); - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - ksba_free (p); - gcry_sexp_release (s_sig); - return GNUPG_Bug; - } - if (DBG_X509) - log_printhex ("public key: ", p, n); - - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); - ksba_free (p); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); - gcry_sexp_release (s_sig); - return map_gcry_err (rc); - } - - - rc = do_encode_md (md, algo, gcry_pk_get_nbits (s_pkey), &frame); - if (rc) - { - gcry_sexp_release (s_sig); - gcry_sexp_release (s_pkey); - return rc; - } - /* put hash into the S-Exp s_hash */ - if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) ) - BUG (); - gcry_mpi_release (frame); - - - rc = gcry_pk_verify (s_sig, s_hash, s_pkey); - if (DBG_CRYPTO) - log_debug ("gcry_pk_verify: %s\n", gcry_strerror (rc)); - gcry_sexp_release (s_sig); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_sig); - return map_gcry_err (rc); -} - - - -int -gpgsm_create_cms_signature (KsbaCert cert, GCRY_MD_HD md, int mdalgo, - char **r_sigval) -{ - int rc; - char *grip; - size_t siglen; - - grip = gpgsm_get_keygrip_hexstring (cert); - if (!grip) - return seterr (Bad_Certificate); - - rc = gpgsm_agent_pksign (grip, gcry_md_read(md, mdalgo), - gcry_md_get_algo_dlen (mdalgo), mdalgo, - r_sigval, &siglen); - xfree (grip); - return rc; -} - - - diff --git a/sm/certdump.c b/sm/certdump.c deleted file mode 100644 index 9afb1154d..000000000 --- a/sm/certdump.c +++ /dev/null @@ -1,457 +0,0 @@ -/* certdump.c - Dump a certificate for debugging - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gpgsm.h" -#include "keydb.h" -#include "i18n.h" - -struct dn_array_s { - char *key; - char *value; -}; - - -/* print the first element of an S-Expression */ -void -gpgsm_print_serial (FILE *fp, KsbaConstSexp p) -{ - unsigned long n; - KsbaConstSexp endp; - - if (!p) - fputs (_("none"), fp); - else if (*p != '(') - fputs ("[Internal error - not an S-expression]", fp); - else - { - p++; - n = strtoul (p, (char**)&endp, 10); - p = endp; - if (*p!=':') - fputs ("[Internal Error - invalid S-expression]", fp); - else - { - for (p++; n; n--, p++) - fprintf (fp, "%02X", *p); - } - } -} - - -void -gpgsm_dump_serial (KsbaConstSexp p) -{ - unsigned long n; - KsbaConstSexp endp; - - if (!p) - log_printf ("none"); - else if (*p != '(') - log_printf ("ERROR - not an S-expression"); - else - { - p++; - n = strtoul (p, (char**)&endp, 10); - p = endp; - if (*p!=':') - log_printf ("ERROR - invalid S-expression"); - else - { - for (p++; n; n--, p++) - log_printf ("%02X", *p); - } - } -} - -void -gpgsm_print_time (FILE *fp, time_t t) -{ - if (!t) - fputs (_("none"), fp); - else if ( t == (time_t)(-1) ) - fputs ("[Error - Invalid time]", fp); - else - { - struct tm *tp; - - tp = gmtime (&t); - fprintf (fp, "%04d-%02d-%02d %02d:%02d:%02d Z", - 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday, - tp->tm_hour, tp->tm_min, tp->tm_sec); - assert (!tp->tm_isdst); - } -} - -void -gpgsm_dump_time (time_t t) -{ - - if (!t) - log_printf (_("[none]")); - else if ( t == (time_t)(-1) ) - log_printf (_("[error]")); - else - { - struct tm *tp; - - tp = gmtime (&t); - log_printf ("%04d-%02d-%02d %02d:%02d:%02d", - 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday, - tp->tm_hour, tp->tm_min, tp->tm_sec); - assert (!tp->tm_isdst); - } -} - - - - -void -gpgsm_dump_string (const char *string) -{ - - if (!string) - log_printf ("[error]"); - else - { - const unsigned char *s; - - for (s=string; *s; s++) - { - if (*s < ' ' || (*s >= 0x7f && *s <= 0xa0)) - break; - } - if (!*s && *string != '[') - log_printf ("%s", string); - else - { - log_printf ( "[ "); - log_printhex (NULL, string, strlen (string)); - log_printf ( " ]"); - } - } -} - - -void -gpgsm_dump_cert (const char *text, KsbaCert cert) -{ - KsbaSexp sexp; - unsigned char *p; - char *dn; - time_t t; - - log_debug ("BEGIN Certificate `%s':\n", text? text:""); - if (cert) - { - sexp = ksba_cert_get_serial (cert); - log_debug (" serial: "); - gpgsm_dump_serial (sexp); - ksba_free (sexp); - log_printf ("\n"); - - t = ksba_cert_get_validity (cert, 0); - log_debug (" notBefore: "); - gpgsm_dump_time (t); - log_printf ("\n"); - t = ksba_cert_get_validity (cert, 1); - log_debug (" notAfter: "); - gpgsm_dump_time (t); - log_printf ("\n"); - - dn = ksba_cert_get_issuer (cert, 0); - log_debug (" issuer: "); - gpgsm_dump_string (dn); - ksba_free (dn); - log_printf ("\n"); - - dn = ksba_cert_get_subject (cert, 0); - log_debug (" subject: "); - gpgsm_dump_string (dn); - ksba_free (dn); - log_printf ("\n"); - - log_debug (" hash algo: %s\n", ksba_cert_get_digest_algo (cert)); - - p = gpgsm_get_fingerprint_string (cert, 0); - log_debug (" SHA1 Fingerprint: %s\n", p); - xfree (p); - } - log_debug ("END Certificate\n"); -} - - - -/* helper for the rfc2253 string parser */ -static const unsigned char * -parse_dn_part (struct dn_array_s *array, const unsigned char *string) -{ - const unsigned char *s, *s1; - size_t n; - unsigned char *p; - - /* parse attributeType */ - for (s = string+1; *s && *s != '='; s++) - ; - if (!*s) - return NULL; /* error */ - n = s - string; - if (!n) - return NULL; /* empty key */ - array->key = p = xtrymalloc (n+1); - if (!array->key) - return NULL; - memcpy (p, string, n); - p[n] = 0; - trim_trailing_spaces (p); - if ( !strcmp (p, "1.2.840.113549.1.9.1") ) - strcpy (p, "EMail"); - string = s + 1; - - if (*string == '#') - { /* hexstring */ - string++; - for (s=string; hexdigitp (s); s++) - s++; - n = s - string; - if (!n || (n & 1)) - return NULL; /* empty or odd number of digits */ - n /= 2; - array->value = p = xtrymalloc (n+1); - if (!p) - return NULL; - for (s1=string; n; s1 += 2, n--) - *p++ = xtoi_2 (s1); - *p = 0; - } - else - { /* regular v3 quoted string */ - for (n=0, s=string; *s; s++) - { - if (*s == '\\') - { /* pair */ - s++; - if (*s == ',' || *s == '=' || *s == '+' - || *s == '<' || *s == '>' || *s == '#' || *s == ';' - || *s == '\\' || *s == '\"' || *s == ' ') - n++; - else if (hexdigitp (s) && hexdigitp (s+1)) - { - s++; - n++; - } - else - return NULL; /* invalid escape sequence */ - } - else if (*s == '\"') - return NULL; /* invalid encoding */ - else if (*s == ',' || *s == '=' || *s == '+' - || *s == '<' || *s == '>' || *s == '#' || *s == ';' ) - break; - else - n++; - } - - array->value = p = xtrymalloc (n+1); - if (!p) - return NULL; - for (s=string; n; s++, n--) - { - if (*s == '\\') - { - s++; - if (hexdigitp (s)) - { - *p++ = xtoi_2 (s); - s++; - } - else - *p++ = *s; - } - else - *p++ = *s; - } - *p = 0; - } - return s; -} - - -/* Parse a DN and return an array-ized one. This is not a validating - parser and it does not support any old-stylish syntax; KSBA is - expected to return only rfc2253 compatible strings. */ -static struct dn_array_s * -parse_dn (const unsigned char *string) -{ - struct dn_array_s *array; - size_t arrayidx, arraysize; - int i; - - arraysize = 7; /* C,ST,L,O,OU,CN,email */ - arrayidx = 0; - array = xtrymalloc ((arraysize+1) * sizeof *array); - if (!array) - return NULL; - while (*string) - { - while (*string == ' ') - string++; - if (!*string) - break; /* ready */ - if (arrayidx >= arraysize) - { - struct dn_array_s *a2; - - arraysize += 5; - a2 = xtryrealloc (array, (arraysize+1) * sizeof *array); - if (!a2) - goto failure; - array = a2; - } - array[arrayidx].key = NULL; - array[arrayidx].value = NULL; - string = parse_dn_part (array+arrayidx, string); - arrayidx++; - if (!string) - goto failure; - while (*string == ' ') - string++; - if (*string && *string != ',' && *string != ';' && *string != '+') - goto failure; /* invalid delimiter */ - if (*string) - string++; - } - array[arrayidx].key = NULL; - array[arrayidx].value = NULL; - return array; - - failure: - for (i=0; i < arrayidx; i++) - { - xfree (array[i].key); - xfree (array[i].value); - } - xfree (array); - return NULL; -} - - -static void -print_dn_part (FILE *fp, struct dn_array_s *dn, const char *key) -{ - int any = 0; - - for (; dn->key; dn++) - { - if (!strcmp (dn->key, key) && dn->value && *dn->value) - { - putc ('/', fp); - if (any) - fputs (" + ", fp); - else - fprintf (fp, "%s=", key); - print_sanitized_utf8_string (fp, dn->value, '/'); - any = 1; - } - } -} - -/* Print all parts of a DN in a "standard" sequence. We first print - all the known parts, followed by the uncommon ones */ -static void -print_dn_parts (FILE *fp, struct dn_array_s *dn) -{ - const char *stdpart[] = { - "CN", "OU", "O", "STREET", "L", "ST", "C", "EMail", NULL - }; - int i; - - for (i=0; stdpart[i]; i++) - print_dn_part (fp, dn, stdpart[i]); - - /* now print the rest without any specific ordering */ - for (; dn->key; dn++) - { - for (i=0; stdpart[i]; i++) - { - if (!strcmp (dn->key, stdpart[i])) - break; - } - if (!stdpart[i]) - print_dn_part (fp, dn, dn->key); - } -} - - - -void -gpgsm_print_name (FILE *fp, const char *name) -{ - const unsigned char *s; - int i; - - s = name; - if (!s) - { - fputs (_("[Error - No name]"), fp); - } - else if (*s == '<') - { - const unsigned char *s2 = strchr (s+1, '>'); - if (s2) - print_sanitized_utf8_buffer (fp, s + 1, s2 - s - 1, 0); - } - else if (*s == '(') - fputs (_("[Error - unknown encoding]"), fp); - else if (!((*s >= '0' && *s < '9') - || (*s >= 'A' && *s <= 'Z') - || (*s >= 'a' && *s <= 'z'))) - fputs (_("[Error - invalid encoding]"), fp); - else - { - struct dn_array_s *dn = parse_dn (s); - if (!dn) - fputs (_("[Error - invalid DN]"), fp); - else - { - print_dn_parts (fp, dn); - for (i=0; dn[i].key; i++) - { - xfree (dn[i].key); - xfree (dn[i].value); - } - xfree (dn); - } - } -} - - - diff --git a/sm/certlist.c b/sm/certlist.c deleted file mode 100644 index f31e6ee2b..000000000 --- a/sm/certlist.c +++ /dev/null @@ -1,313 +0,0 @@ -/* certlist.c - build list of certificates - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gpgsm.h" -#include "keydb.h" -#include "i18n.h" - -/* Return 0 if the cert is usable for encryption. A MODE of 0 checks - for signing a MODE of 1 checks for encryption, a MODE of 2 checks - for verification and a MODE of 3 for decryption (just for - debugging) */ -static int -cert_usage_p (KsbaCert cert, int mode) -{ - KsbaError err; - unsigned int use; - - err = ksba_cert_get_key_usage (cert, &use); - if (err == KSBA_No_Data) - { - if (opt.verbose && mode < 2) - log_info (mode? - _("no key usage specified - accepted for encryption\n"): - _("no key usage specified - accepted for signing\n")); - return 0; - } - if (err) - { - log_error (_("error getting key usage information: %s\n"), - ksba_strerror (err)); - return map_ksba_err (err); - } - - if (mode == 4) - { - if ((use & (KSBA_KEYUSAGE_KEY_CERT_SIGN))) - return 0; - log_info ( _("certificate should have not been used certification\n")); - return GNUPG_Wrong_Key_Usage; - } - - if ((use & ((mode&1)? - (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT): - (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION))) - ) - return 0; - log_info (mode==3? _("certificate should have not been used for encryption\n"): - mode==2? _("certificate should have not been used for signing\n"): - mode==1? _("certificate is not usable for encryption\n"): - _("certificate is not usable for signing\n")); - return GNUPG_Wrong_Key_Usage; -} - - -/* Return 0 if the cert is usable for signing */ -int -gpgsm_cert_use_sign_p (KsbaCert cert) -{ - return cert_usage_p (cert, 0); -} - - -/* Return 0 if the cert is usable for encryption */ -int -gpgsm_cert_use_encrypt_p (KsbaCert cert) -{ - return cert_usage_p (cert, 1); -} - -int -gpgsm_cert_use_verify_p (KsbaCert cert) -{ - return cert_usage_p (cert, 2); -} - -int -gpgsm_cert_use_decrypt_p (KsbaCert cert) -{ - return cert_usage_p (cert, 3); -} - -int -gpgsm_cert_use_cert_p (KsbaCert cert) -{ - return cert_usage_p (cert, 4); -} - - -static int -same_subject_issuer (const char *subject, const char *issuer, KsbaCert cert) -{ - char *subject2 = ksba_cert_get_subject (cert, 0); - char *issuer2 = ksba_cert_get_subject (cert, 0); - int tmp; - - tmp = (subject && subject2 - && !strcmp (subject, subject2) - && issuer && issuer2 - && !strcmp (issuer, issuer2)); - xfree (subject2); - xfree (issuer2); - return tmp; -} - - - -/* Add a certificate to a list of certificate and make sure that it is - a valid certificate. With SECRET set to true a secret key must be - avaibale for the certificate. */ -int -gpgsm_add_to_certlist (CTRL ctrl, const char *name, int secret, - CERTLIST *listaddr) -{ - int rc; - KEYDB_SEARCH_DESC desc; - KEYDB_HANDLE kh = NULL; - KsbaCert cert = NULL; - - rc = keydb_classify_name (name, &desc); - if (!rc) - { - kh = keydb_new (0); - if (!kh) - rc = GNUPG_Out_Of_Core; - else - { - int wrong_usage = 0; - char *subject = NULL; - char *issuer = NULL; - - get_next: - rc = keydb_search (kh, &desc, 1); - if (!rc) - rc = keydb_get_cert (kh, &cert); - if (!rc) - { - rc = secret? gpgsm_cert_use_sign_p (cert) - : gpgsm_cert_use_encrypt_p (cert); - if (rc == GNUPG_Wrong_Key_Usage) - { - /* There might be another certificate with the - correct usage, so we try again */ - if (!wrong_usage) - { /* save the first match */ - wrong_usage = rc; - subject = ksba_cert_get_subject (cert, 0); - issuer = ksba_cert_get_subject (cert, 0); - ksba_cert_release (cert); - cert = NULL; - goto get_next; - } - else if (same_subject_issuer (subject, issuer, cert)) - { - wrong_usage = rc; - ksba_cert_release (cert); - cert = NULL; - goto get_next; - } - else - wrong_usage = rc; - - } - } - /* we want the error code from the first match in this case */ - if (rc && wrong_usage) - rc = wrong_usage; - - if (!rc) - { - next_ambigious: - rc = keydb_search (kh, &desc, 1); - if (rc == -1) - rc = 0; - else if (!rc) - { - KsbaCert cert2 = NULL; - - /* We have to ignore ambigious names as long as - there only fault is a bad key usage */ - if (!keydb_get_cert (kh, &cert2)) - { - int tmp = (same_subject_issuer (subject, issuer, cert2) - && ((secret? gpgsm_cert_use_sign_p (cert2): - gpgsm_cert_use_encrypt_p (cert2)) - == GNUPG_Wrong_Key_Usage)); - ksba_cert_release (cert2); - if (tmp) - goto next_ambigious; - } - rc = GNUPG_Ambiguous_Name; - } - } - xfree (subject); - xfree (issuer); - - if (!rc && secret) - { - char *p; - - rc = GNUPG_No_Secret_Key; - p = gpgsm_get_keygrip_hexstring (cert); - if (p) - { - if (!gpgsm_agent_havekey (p)) - rc = 0; - xfree (p); - } - } - if (!rc) - rc = gpgsm_validate_chain (ctrl, cert, NULL); - if (!rc) - { - CERTLIST cl = xtrycalloc (1, sizeof *cl); - if (!cl) - rc = GNUPG_Out_Of_Core; - else - { - cl->cert = cert; cert = NULL; - cl->next = *listaddr; - *listaddr = cl; - } - } - } - } - - keydb_release (kh); - ksba_cert_release (cert); - return rc == -1? GNUPG_No_Public_Key: rc; -} - -void -gpgsm_release_certlist (CERTLIST list) -{ - while (list) - { - CERTLIST cl = list->next; - ksba_cert_release (list->cert); - xfree (list); - list = cl; - } -} - - -/* Like gpgsm_add_to_certlist, but look only for one certificate. No - chain validation is done */ -int -gpgsm_find_cert (const char *name, KsbaCert *r_cert) -{ - int rc; - KEYDB_SEARCH_DESC desc; - KEYDB_HANDLE kh = NULL; - - *r_cert = NULL; - rc = keydb_classify_name (name, &desc); - if (!rc) - { - kh = keydb_new (0); - if (!kh) - rc = GNUPG_Out_Of_Core; - else - { - rc = keydb_search (kh, &desc, 1); - if (!rc) - rc = keydb_get_cert (kh, r_cert); - if (!rc) - { - rc = keydb_search (kh, &desc, 1); - if (rc == -1) - rc = 0; - else - { - if (!rc) - rc = GNUPG_Ambiguous_Name; - ksba_cert_release (*r_cert); - *r_cert = NULL; - } - } - } - } - - keydb_release (kh); - return rc == -1? GNUPG_No_Public_Key: rc; -} - diff --git a/sm/certreqgen.c b/sm/certreqgen.c deleted file mode 100644 index 600a278bc..000000000 --- a/sm/certreqgen.c +++ /dev/null @@ -1,699 +0,0 @@ -/* certreqgen.c - Generate a key and a certification request - * Copyright (C) 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 - */ - -/* -The format of the native parameter file is follows: - o Text only, line length is limited to about 1000 chars. - o You must use UTF-8 encoding to specify non-ascii characters. - o Empty lines are ignored. - o Leading and trailing spaces are ignored. - o A hash sign as the first non white space character is a comment line. - o Control statements are indicated by a leading percent sign, the - arguments are separated by white space from the keyword. - o Parameters are specified by a keyword, followed by a colon. Arguments - are separated by white space. - o The first parameter must be "Key-Type", control statements - may be placed anywhere. - o Key generation takes place when either the end of the parameter file - is reached, the next "Key-Type" parameter is encountered or at the - controlstatement "%commit" - o Control statements: - %echo - Print . - %dry-run - Suppress actual key generation (useful for syntax checking). - %commit - Perform the key generation. Note that an implicit commit is done - at the next "Key-Type" parameter. - %certfile - Do not write the certificate to the keyDB but to . - This must be given before the first - commit to take place, duplicate specification of the same filename - is ignored, the last filename before a commit is used. - The filename is used until a new filename is used (at commit points) - and all keys are written to that file. If a new filename is given, - this file is created (and overwrites an existing one). - Both control statements must be given. - o The order of the parameters does not matter except for "Key-Type" - which must be the first parameter. The parameters are only for the - generated keyblock and parameters from previous key generations are not - used. Some syntactically checks may be performed. - The currently defined parameters are: - Key-Type: - Starts a new parameter block by giving the type of the - primary key. The algorithm must be capable of signing. - This is a required parameter. For now the only supported - algorithm is "rsa". - Key-Length: - Length of the key in bits. Default is 1024. - Key-Usage: - Space or comma delimited list of key usage, allowed values are - "encrypt" and "sign". This is used to generate the KeyUsage extension. - Please make sure that the algorithm is capable of this usage. Default - is to allow encrypt and sign. - Name-DN: subject name - This is the DN name of the subject in rfc2253 format. - Name-Email: - The ist the email address - -Here is an example: -$ cat >foo < -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gpgsm.h" -#include "keydb.h" -#include "i18n.h" - - -enum para_name { - pKEYTYPE, - pKEYLENGTH, - pKEYUSAGE, - pNAMEDN, - pNAMEEMAIL -}; - -struct para_data_s { - struct para_data_s *next; - int lnr; - enum para_name key; - union { - unsigned int usage; - char value[1]; - } u; -}; - -struct reqgen_ctrl_s { - int lnr; - int dryrun; - KsbaWriter writer; -}; - - -static int proc_parameters (struct para_data_s *para, - struct reqgen_ctrl_s *outctrl); -static int create_request (struct para_data_s *para, - KsbaConstSexp public, - struct reqgen_ctrl_s *outctrl); - - - -static void -release_parameter_list (struct para_data_s *r) -{ - struct para_data_s *r2; - - for (; r ; r = r2) - { - r2 = r->next; - 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) -{ - struct para_data_s *r = get_parameter (para, key); - if (!r) - return -1; - if (digitp (r->u.value)) - return atoi( r->u.value ); - return gcry_pk_map_name (r->u.value); -} - -/* parse the usage parameter. Returns 0 on success. Note that we - only care about sign and encrypt and don't (yet) allow all the - other X.509 usage to be specified; instead we will use a fixed - mapping to the X.509 usage flags */ -static int -parse_parameter_usage (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 |= GCRY_PK_USAGE_SIGN; - else if ( !ascii_strcasecmp (p, "encrypt") ) - use |= GCRY_PK_USAGE_ENCR; - else - { - log_error ("line %d: invalid usage list\n", r->lnr); - return -1; /* error */ - } - } - r->u.usage = use; - return 0; -} - - -static unsigned int -get_parameter_uint (struct para_data_s *para, enum para_name key) -{ - struct para_data_s *r = get_parameter (para, key); - - if (!r) - return 0; - - return (unsigned int)strtoul (r->u.value, NULL, 10); -} - - - -/* Read the certificate generation parameters from FP and generate - (all) certificate requests. */ -static int -read_parameters (FILE *fp, KsbaWriter writer) -{ - static struct { - const char *name; - enum para_name key; - } keywords[] = { - { "Key-Type", pKEYTYPE}, - { "Key-Length", pKEYLENGTH }, - { "Key-Usage", pKEYUSAGE }, - { "Name-DN", pNAMEDN }, - { "Name-Email", pNAMEEMAIL }, - { NULL, 0 } - }; - char line[1024], *p; - const char *err = NULL; - struct para_data_s *para, *r; - int i, rc = 0, any = 0; - struct reqgen_ctrl_s outctrl; - - memset (&outctrl, 0, sizeof (outctrl)); - outctrl.writer = writer; - - err = NULL; - para = NULL; - while (fgets (line, DIM(line)-1, fp) ) - { - char *keyword, *value; - - outctrl.lnr++; - if (*line && line[strlen(line)-1] != '\n') - { - err = "line too long"; - break; - } - for (p=line; spacep (p); p++) - ; - if (!*p || *p == '#') - continue; - - keyword = p; - if (*keyword == '%') - { - for (; !spacep (p); p++) - ; - if (*p) - *p++ = 0; - for (; spacep (p); p++) - ; - value = p; - trim_trailing_spaces (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")) - { - rc = proc_parameters (para, &outctrl); - if (rc) - goto leave; - any = 1; - release_parameter_list (para); - para = NULL; - } - 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 (; spacep (p); p++) - ; - if (!*p) - { - err = "missing argument"; - break; - } - value = p; - trim_trailing_spaces (value); - - for (i=0; (keywords[i].name - && ascii_strcasecmp (keywords[i].name, keyword)); i++) - ; - 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) - { - rc = proc_parameters (para, &outctrl); - if (rc) - goto leave; - any = 1; - release_parameter_list (para); - para = NULL; - } - else - { - for (r = para; r && r->key != keywords[i].key; r = r->next) - ; - if (r) - { - err = "duplicate keyword"; - break; - } - } - - r = xtrycalloc (1, sizeof *r + strlen( value )); - if (!r) - { - err = "out of core"; - break; - } - r->lnr = outctrl.lnr; - r->key = keywords[i].key; - strcpy (r->u.value, value); - r->next = para; - para = r; - } - - if (err) - { - log_error ("line %d: %s\n", outctrl.lnr, err); - rc = GNUPG_General_Error; - } - else if (ferror(fp)) - { - log_error ("line %d: read error: %s\n", outctrl.lnr, strerror(errno) ); - rc = GNUPG_General_Error; - } - else if (para) - { - rc = proc_parameters (para, &outctrl); - if (rc) - goto leave; - any = 1; - } - - if (!rc && !any) - rc = GNUPG_No_Data; - - leave: - release_parameter_list (para); - return rc; -} - -/* check whether there are invalid characters in the email address S */ -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++; - else if (!at_seen && !( !!strchr (valid_chars, *s) || *s == '+')) - return 1; - else if (at_seen && !strchr (valid_chars, *s)) - return 1; - } - return at_seen != 1; -} - - -/* Check that all required parameters are given and perform the action */ -static int -proc_parameters (struct para_data_s *para, struct reqgen_ctrl_s *outctrl) -{ - struct para_data_s *r; - const char *s; - int i; - unsigned int nbits; - char numbuf[20]; - unsigned char keyparms[100]; - int rc; - KsbaSexp public; - - /* check that we have all required parameters */ - assert (get_parameter (para, pKEYTYPE)); - - /* We can only use RSA for now. There is a with pkcs-10 on how to - use ElGamal becuase it is expected that a PK algorithm can always - be used for signing. */ - i = get_parameter_algo (para, pKEYTYPE); - if (i < 1 || i != GCRY_PK_RSA ) - { - r = get_parameter (para, pKEYTYPE); - log_error ("line %d: invalid algorithm\n", r->lnr); - return GNUPG_Invalid_Parameter; - } - - /* check the keylength */ - if (!get_parameter (para, pKEYLENGTH)) - nbits = 1024; - else - nbits = get_parameter_uint (para, pKEYLENGTH); - if (nbits < 512 || nbits > 4096) - { - r = get_parameter (para, pKEYTYPE); - log_error ("line %d: invalid key length %u (valid are 512 to 4096)\n", - r->lnr, nbits); - return GNUPG_Invalid_Parameter; - } - - /* check the usage */ - if (parse_parameter_usage (para, pKEYUSAGE)) - return GNUPG_Invalid_Parameter; - - /* check that there is a subject name and that this DN fits our - requirements */ - if (!(s=get_parameter_value (para, pNAMEDN))) - { - r = get_parameter (para, pKEYTYPE); - log_error ("line %d: no subject name given\n", r->lnr); - return GNUPG_Invalid_Parameter; - } - /* fixme check s */ - - /* check that the optional email address is okay */ - if ((s=get_parameter_value (para, pNAMEEMAIL))) - { - if (has_invalid_email_chars (s) - || *s == '@' - || s[strlen(s)-1] == '@' - || s[strlen(s)-1] == '.' - || strstr(s, "..")) - { - r = get_parameter (para, pKEYTYPE); - log_error ("line %d: not a valid email address\n", r->lnr); - return GNUPG_Invalid_Parameter; - } - } - - sprintf (numbuf, "%u", nbits); - snprintf (keyparms, DIM (keyparms)-1, - "(6:genkey(3:rsa(5:nbits%d:%s)))", strlen (numbuf), numbuf); - rc = gpgsm_agent_genkey (keyparms, &public); - if (rc) - { - r = get_parameter (para, pKEYTYPE); - log_error ("line %d: key generation failed: %s\n", - r->lnr, gnupg_strerror (rc)); - return rc; - } - - rc = create_request (para, public, outctrl); - xfree (public); - - return rc; -} - - -/* Parameters are checked, the key pair has been created. Now - generate the request and write it out */ -static int -create_request (struct para_data_s *para, KsbaConstSexp public, - struct reqgen_ctrl_s *outctrl) -{ - KsbaCertreq cr; - KsbaError err; - GCRY_MD_HD md; - KsbaStopReason stopreason; - int rc = 0; - const char *s; - - cr = ksba_certreq_new (); - if (!cr) - return seterr (Out_Of_Core); - - md = gcry_md_open (GCRY_MD_SHA1, 0); - if (!md) - { - log_error ("md_open failed: %s\n", gcry_strerror (-1)); - rc = map_gcry_err (gcry_errno ()); - goto leave; - } - if (DBG_HASHING) - gcry_md_start_debug (md, "cr.cri"); - - ksba_certreq_set_hash_function (cr, HASH_FNC, md); - ksba_certreq_set_writer (cr, outctrl->writer); - - err = ksba_certreq_add_subject (cr, get_parameter_value (para, pNAMEDN)); - if (err) - { - log_error ("error setting the subject's name: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - - s = get_parameter_value (para, pNAMEEMAIL); - if (s) - { - char *buf = xtrymalloc (strlen (s) + 3); - - if (!buf) - { - rc = GNUPG_Out_Of_Core; - goto leave; - } - *buf = '<'; - strcpy (buf+1, s); - strcat (buf+1, ">"); - err = ksba_certreq_add_subject (cr, buf); - xfree (buf); - if (err) - { - log_error ("error setting the subject's alternate name: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - } - - - err = ksba_certreq_set_public_key (cr, public); - if (err) - { - log_error ("error setting the public key: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - - do - { - err = ksba_certreq_build (cr, &stopreason); - if (err) - { - log_error ("ksba_certreq_build failed: %s\n", ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - if (stopreason == KSBA_SR_NEED_SIG) - { - GCRY_SEXP s_pkey; - size_t n; - unsigned char grip[20], hexgrip[41]; - char *sigval; - size_t siglen; - - n = gcry_sexp_canon_len (public, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - err = GNUPG_Bug; - goto leave; - } - rc = gcry_sexp_sscan (&s_pkey, NULL, public, n); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); - rc = map_gcry_err (rc); - goto leave; - } - if ( !gcry_pk_get_keygrip (s_pkey, grip) ) - { - rc = seterr (General_Error); - log_error ("can't figure out the keygrip\n"); - gcry_sexp_release (s_pkey); - goto leave; - } - gcry_sexp_release (s_pkey); - for (n=0; n < 20; n++) - sprintf (hexgrip+n*2, "%02X", grip[n]); - - rc = gpgsm_agent_pksign (hexgrip, - gcry_md_read(md, GCRY_MD_SHA1), - gcry_md_get_algo_dlen (GCRY_MD_SHA1), - GCRY_MD_SHA1, - &sigval, &siglen); - if (rc) - { - log_error ("signing failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - - err = ksba_certreq_set_sig_val (cr, sigval); - xfree (sigval); - if (err) - { - log_error ("failed to store the sig_val: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - } - } - while (stopreason != KSBA_SR_READY); - - - leave: - gcry_md_close (md); - ksba_certreq_release (cr); - return rc; -} - - - -/* Create a new key by reading the parameters from in_fd. Multiple - keys may be created */ -int -gpgsm_genkey (CTRL ctrl, int in_fd, FILE *out_fp) -{ - int rc; - FILE *in_fp; - Base64Context b64writer = NULL; - KsbaWriter writer; - - in_fp = fdopen (dup (in_fd), "rb"); - if (!in_fp) - { - log_error ("fdopen() failed: %s\n", strerror (errno)); - return seterr (IO_Error); - } - - ctrl->pem_name = "NEW CERTIFICATE REQUEST"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gnupg_strerror (rc)); - goto leave; - } - - rc = read_parameters (in_fp, writer); - if (rc) - { - log_error ("error creating certificate request: %s\n", - gnupg_strerror (rc)); - goto leave; - } - - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - - gpgsm_status (ctrl, STATUS_KEY_CREATED, "P"); - log_info ("certificate request created\n"); - - leave: - gpgsm_destroy_writer (b64writer); - fclose (in_fp); - return rc; -} - diff --git a/sm/decrypt.c b/sm/decrypt.c deleted file mode 100644 index 012254e22..000000000 --- a/sm/decrypt.c +++ /dev/null @@ -1,502 +0,0 @@ -/* decrypt.c - Decrypt a message - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gpgsm.h" -#include "keydb.h" -#include "i18n.h" - -struct decrypt_filter_parm_s { - int algo; - int mode; - int blklen; - GCRY_CIPHER_HD hd; - char iv[16]; - size_t ivlen; - int any_data; /* dod we push anything through the filter at all? */ - unsigned char lastblock[16]; /* to strip the padding we have to - keep this one */ - char helpblock[16]; /* needed because there is no block buffering in - libgcrypt (yet) */ - int helpblocklen; -}; - - - -/* decrypt the session key and fill in the parm structure. The - algo and the IV is expected to be already in PARM. */ -static int -prepare_decryption (const char *hexkeygrip, KsbaConstSexp enc_val, - struct decrypt_filter_parm_s *parm) -{ - char *seskey = NULL; - size_t n, seskeylen; - int rc; - - rc = gpgsm_agent_pkdecrypt (hexkeygrip, enc_val, - &seskey, &seskeylen); - if (rc) - { - log_error ("error decrypting session key: %s\n", gnupg_strerror (rc)); - goto leave; - } - - if (DBG_CRYPTO) - log_printhex ("pkcs1 encoded session key:", seskey, seskeylen); - - n=0; - if (seskeylen == 24) - { - /* Smells like a 3-des key. This might happen because a SC has - already done the unpacking. fixme! */ - } - else - { - if (n + 7 > seskeylen ) - { - rc = seterr (Invalid_Session_Key); - goto leave; - } - - /* FIXME: Actually the leading zero is required but due to the way - we encode the output in libgcrypt as an MPI we are not able to - encode that leading zero. However, when using a Smartcard we are - doing it the rightway and therefore we have to skip the zero. This - should be fixed in gpg-agent of course. */ - if (!seskey[n]) - n++; - - if (seskey[n] != 2 ) /* wrong block type version */ - { - rc = seterr (Invalid_Session_Key); - goto leave; - } - - for (n++; n < seskeylen && seskey[n]; n++) /* skip the random bytes */ - ; - n++; /* and the zero byte */ - if (n >= seskeylen ) - { - rc = seterr (Invalid_Session_Key); - goto leave; - } - } - - if (DBG_CRYPTO) - log_printhex ("session key:", seskey+n, seskeylen-n); - - parm->hd = gcry_cipher_open (parm->algo, parm->mode, 0); - if (!parm->hd) - { - rc = gcry_errno (); - log_error ("error creating decryptor: %s\n", gcry_strerror (rc)); - rc = map_gcry_err (rc); - goto leave; - } - - rc = gcry_cipher_setkey (parm->hd, seskey+n, seskeylen-n); - if (rc == GCRYERR_WEAK_KEY) - { - log_info (_("WARNING: message was encrypted with " - "a weak key in the symmetric cipher.\n")); - rc = 0; - } - if (rc) - { - log_error("key setup failed: %s\n", gcry_strerror(rc) ); - rc = map_gcry_err (rc); - goto leave; - } - - gcry_cipher_setiv (parm->hd, parm->iv, parm->ivlen); - - leave: - xfree (seskey); - return rc; -} - - -/* This function is called by the KSBA writer just before the actual - write is done. The function must take INLEN bytes from INBUF, - decrypt it and store it inoutbuf which has a maximum size of - maxoutlen. The valid bytes in outbuf should be return in outlen. - Due to different buffer sizes or different length of input and - output, it may happen that fewer bytes are process or fewer bytes - are written. */ -static KsbaError -decrypt_filter (void *arg, - const void *inbuf, size_t inlen, size_t *inused, - void *outbuf, size_t maxoutlen, size_t *outlen) -{ - struct decrypt_filter_parm_s *parm = arg; - int blklen = parm->blklen; - size_t orig_inlen = inlen; - - /* fixme: Should we issue an error when we have not seen one full block? */ - if (!inlen) - return KSBA_Bug; - - if (maxoutlen < 2*parm->blklen) - return KSBA_Bug; - /* make some space becuase we will later need an extra block at the end */ - maxoutlen -= blklen; - - if (parm->helpblocklen) - { - int i, j; - - for (i=parm->helpblocklen,j=0; i < blklen && j < inlen; i++, j++) - parm->helpblock[i] = ((const char*)inbuf)[j]; - inlen -= j; - if (blklen > maxoutlen) - return KSBA_Bug; - if (i < blklen) - { - parm->helpblocklen = i; - *outlen = 0; - } - else - { - parm->helpblocklen = 0; - if (parm->any_data) - { - memcpy (outbuf, parm->lastblock, blklen); - *outlen =blklen; - } - else - *outlen = 0; - gcry_cipher_decrypt (parm->hd, parm->lastblock, blklen, - parm->helpblock, blklen); - parm->any_data = 1; - } - *inused = orig_inlen - inlen; - return 0; - } - - - if (inlen > maxoutlen) - inlen = maxoutlen; - if (inlen % blklen) - { /* store the remainder away */ - parm->helpblocklen = inlen%blklen; - inlen = inlen/blklen*blklen; - memcpy (parm->helpblock, (const char*)inbuf+inlen, parm->helpblocklen); - } - - *inused = inlen + parm->helpblocklen; - if (inlen) - { - assert (inlen >= blklen); - if (parm->any_data) - { - gcry_cipher_decrypt (parm->hd, (char*)outbuf+blklen, inlen, - inbuf, inlen); - memcpy (outbuf, parm->lastblock, blklen); - memcpy (parm->lastblock,(char*)outbuf+inlen, blklen); - *outlen = inlen; - } - else - { - gcry_cipher_decrypt (parm->hd, outbuf, inlen, inbuf, inlen); - memcpy (parm->lastblock, (char*)outbuf+inlen-blklen, blklen); - *outlen = inlen - blklen; - parm->any_data = 1; - } - } - else - *outlen = 0; - return 0; -} - - - -/* Perform a decrypt operation. */ -int -gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp) -{ - int rc; - KsbaError err; - Base64Context b64reader = NULL; - Base64Context b64writer = NULL; - KsbaReader reader; - KsbaWriter writer; - KsbaCMS cms = NULL; - KsbaStopReason stopreason; - KEYDB_HANDLE kh; - int recp; - FILE *in_fp = NULL; - struct decrypt_filter_parm_s dfparm; - - memset (&dfparm, 0, sizeof dfparm); - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = GNUPG_General_Error; - goto leave; - } - - - in_fp = fdopen ( dup (in_fd), "rb"); - if (!in_fp) - { - log_error ("fdopen() failed: %s\n", strerror (errno)); - rc = seterr (IO_Error); - goto leave; - } - - rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, &reader); - if (rc) - { - log_error ("can't create reader: %s\n", gnupg_strerror (rc)); - goto leave; - } - - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gnupg_strerror (rc)); - goto leave; - } - - cms = ksba_cms_new (); - if (!cms) - { - rc = seterr (Out_Of_Core); - goto leave; - } - - err = ksba_cms_set_reader_writer (cms, reader, writer); - if (err) - { - log_debug ("ksba_cms_set_reader_writer failed: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - - /* parser loop */ - do - { - err = ksba_cms_parse (cms, &stopreason); - if (err) - { - log_debug ("ksba_cms_parse failed: %s\n", ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - - if (stopreason == KSBA_SR_BEGIN_DATA - || stopreason == KSBA_SR_DETACHED_DATA) - { - int algo, mode; - const char *algoid; - int any_key = 0; - - algoid = ksba_cms_get_content_oid (cms, 2/* encryption algo*/); - algo = gcry_cipher_map_name (algoid); - mode = gcry_cipher_mode_from_oid (algoid); - if (!algo || !mode) - { - rc = GNUPG_Unsupported_Algorithm; - log_error ("unsupported algorithm `%s'\n", algoid? algoid:"?"); - if (algoid && !strcmp (algoid, "1.2.840.113549.3.2")) - log_info (_("(this is the RC2 algorithm)\n")); - else if (!algoid) - log_info (_("(this does not seem to be an encrypted" - " message)\n")); - gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.algorithm", - gnupg_error_token (rc), algoid?algoid:"?", NULL); - goto leave; - } - dfparm.algo = algo; - dfparm.mode = mode; - dfparm.blklen = gcry_cipher_get_algo_blklen (algo); - if (dfparm.blklen > sizeof (dfparm.helpblock)) - return GNUPG_Bug; - - rc = ksba_cms_get_content_enc_iv (cms, - dfparm.iv, - sizeof (dfparm.iv), - &dfparm.ivlen); - if (rc) - { - log_error ("error getting IV: %s\n", ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - - for (recp=0; !any_key; recp++) - { - char *issuer; - KsbaSexp serial; - KsbaSexp enc_val; - char *hexkeygrip = NULL; - - err = ksba_cms_get_issuer_serial (cms, recp, &issuer, &serial); - if (err == -1 && recp) - break; /* no more recipients */ - if (err) - log_error ("recp %d - error getting info: %s\n", - recp, ksba_strerror (err)); - else - { - KsbaCert cert = NULL; - - log_debug ("recp %d - issuer: `%s'\n", - recp, issuer? issuer:"[NONE]"); - log_debug ("recp %d - serial: ", recp); - gpgsm_dump_serial (serial); - log_printf ("\n"); - - keydb_search_reset (kh); - rc = keydb_search_issuer_sn (kh, issuer, serial); - if (rc) - { - log_error ("failed to find the certificate: %s\n", - gnupg_strerror(rc)); - goto oops; - } - - rc = keydb_get_cert (kh, &cert); - if (rc) - { - log_error ("failed to get cert: %s\n", gnupg_strerror (rc)); - goto oops; - } - /* Just in case there is a problem with the own - certificate we print this message - should never - happen of course */ - rc = gpgsm_cert_use_decrypt_p (cert); - if (rc) - { - gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.keyusage", - gnupg_error_token (rc), NULL); - rc = 0; - } - - hexkeygrip = gpgsm_get_keygrip_hexstring (cert); - - oops: - xfree (issuer); - xfree (serial); - ksba_cert_release (cert); - } - - if (!hexkeygrip) - ; - else if (!(enc_val = ksba_cms_get_enc_val (cms, recp))) - log_error ("recp %d - error getting encrypted session key\n", - recp); - else - { - rc = prepare_decryption (hexkeygrip, enc_val, &dfparm); - xfree (enc_val); - if (rc) - { - log_debug ("decrypting session key failed: %s\n", - gnupg_strerror (rc)); - } - else - { /* setup the bulk decrypter */ - any_key = 1; - ksba_writer_set_filter (writer, - decrypt_filter, - &dfparm); - } - } - } - if (!any_key) - { - rc = GNUPG_No_Secret_Key; - goto leave; - } - } - else if (stopreason == KSBA_SR_END_DATA) - { - ksba_writer_set_filter (writer, NULL, NULL); - if (dfparm.any_data) - { /* write the last block with padding removed */ - int i, npadding = dfparm.lastblock[dfparm.blklen-1]; - if (!npadding || npadding > dfparm.blklen) - { - log_error ("invalid padding with value %d\n", npadding); - rc = seterr (Invalid_Data); - goto leave; - } - rc = ksba_writer_write (writer, - dfparm.lastblock, - dfparm.blklen - npadding); - if (rc) - { - rc = map_ksba_err (rc); - goto leave; - } - for (i=dfparm.blklen - npadding; i < dfparm.blklen; i++) - { - if (dfparm.lastblock[i] != npadding) - { - log_error ("inconsistent padding\n"); - rc = seterr (Invalid_Data); - goto leave; - } - } - } - } - - } - while (stopreason != KSBA_SR_READY); - - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - gpgsm_status (ctrl, STATUS_DECRYPTION_OKAY, NULL); - - - leave: - if (rc) - gpgsm_status (ctrl, STATUS_DECRYPTION_FAILED, NULL); - ksba_cms_release (cms); - gpgsm_destroy_reader (b64reader); - gpgsm_destroy_writer (b64writer); - keydb_release (kh); - if (in_fp) - fclose (in_fp); - if (dfparm.hd) - gcry_cipher_close (dfparm.hd); - return rc; -} - - diff --git a/sm/delete.c b/sm/delete.c deleted file mode 100644 index cd1491a86..000000000 --- a/sm/delete.c +++ /dev/null @@ -1,165 +0,0 @@ -/* delete.c - * Copyright (C) 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gpgsm.h" -#include "keydb.h" -#include "i18n.h" - - -/* Delete a certificate or an secret key from a key database. */ -static int -delete_one (CTRL ctrl, const char *username) -{ - int rc = 0; - KEYDB_SEARCH_DESC desc; - KEYDB_HANDLE kh = NULL; - KsbaCert cert = NULL; - int duplicates = 0; - - rc = keydb_classify_name (username, &desc); - if (rc) - { - log_error (_("certificate `%s' not found: %s\n"), - username, gnupg_strerror (rc)); - gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "1", NULL); - goto leave; - } - - kh = keydb_new (0); - if (!kh) - { - log_error ("keydb_new failed\n"); - goto leave; - } - - - rc = keydb_search (kh, &desc, 1); - if (!rc) - rc = keydb_get_cert (kh, &cert); - if (!rc) - { - char fpr[20]; - - gpgsm_get_fingerprint (cert, 0, fpr, NULL); - - next_ambigious: - rc = keydb_search (kh, &desc, 1); - if (rc == -1) - rc = 0; - else if (!rc) - { - KsbaCert cert2 = NULL; - char fpr2[20]; - - /* We ignore all duplicated certificates which might have - been inserted due to program bugs. */ - if (!keydb_get_cert (kh, &cert2)) - { - gpgsm_get_fingerprint (cert2, 0, fpr2, NULL); - ksba_cert_release (cert2); - if (!memcmp (fpr, fpr2, 20)) - { - duplicates++; - goto next_ambigious; - } - } - rc = GNUPG_Ambiguous_Name; - } - } - if (rc) - { - if (rc == -1) - rc = GNUPG_No_Public_Key; - log_error (_("certificate `%s' not found: %s\n"), - username, gnupg_strerror (rc)); - gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "3", NULL); - goto leave; - } - - /* we need to search again to get back to the right position. */ - do - { - keydb_search_reset (kh); - rc = keydb_search (kh, &desc, 1); - if (rc) - { - log_error ("problem re-searching certificate: %s\n", - gnupg_strerror (rc)); - goto leave; - } - - rc = keydb_delete (kh); - if (rc) - goto leave; - if (opt.verbose) - { - if (duplicates) - log_info (_("duplicated certificate `%s' deleted\n"), username); - else - log_info (_("certificate `%s' deleted\n"), username); - } - } - while (duplicates--); - - leave: - keydb_release (kh); - ksba_cert_release (cert); - return rc; -} - - - -/* Delete the certificates specified by NAMES. */ -int -gpgsm_delete (CTRL ctrl, STRLIST names) -{ - int rc; - - if (!names) - { - log_error ("nothing to delete\n"); - return GNUPG_No_Data; - } - - for (; names; names=names->next ) - { - rc = delete_one (ctrl, names->d); - if (rc) - { - log_error (_("deleting certificate \"%s\" failed: %s\n"), - names->d, gnupg_strerror (rc) ); - return rc; - } - } - - return 0; -} diff --git a/sm/encrypt.c b/sm/encrypt.c deleted file mode 100644 index 40e12582f..000000000 --- a/sm/encrypt.c +++ /dev/null @@ -1,549 +0,0 @@ -/* encrypt.c - Encrypt a message - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gpgsm.h" -#include "keydb.h" -#include "i18n.h" - - -struct dek_s { - const char *algoid; - int algo; - GCRY_CIPHER_HD chd; - char key[32]; - int keylen; - char iv[32]; - int ivlen; -}; -typedef struct dek_s *DEK; - -struct encrypt_cb_parm_s { - FILE *fp; - DEK dek; - int eof_seen; - int ready; - int readerror; - int bufsize; - unsigned char *buffer; - int buflen; -}; - - - - - -/* initialize the data encryptionkey (session key) */ -static int -init_dek (DEK dek) -{ - int rc=0, mode, i; - - dek->algo = gcry_cipher_map_name (dek->algoid); - mode = gcry_cipher_mode_from_oid (dek->algoid); - if (!dek->algo || !mode) - { - log_error ("unsupported algorithm `%s'\n", dek->algoid); - return GNUPG_Unsupported_Algorithm; - } - - dek->keylen = gcry_cipher_get_algo_keylen (dek->algo); - if (!dek->keylen || dek->keylen > sizeof (dek->key)) - return GNUPG_Bug; - - dek->ivlen = gcry_cipher_get_algo_blklen (dek->algo); - if (!dek->ivlen || dek->ivlen > sizeof (dek->iv)) - return GNUPG_Bug; - - if (dek->keylen < 100/8) - { /* make sure we don't use weak keys */ - log_error ("key length of `%s' too small\n", dek->algoid); - return GNUPG_Unsupported_Algorithm; - } - - dek->chd = gcry_cipher_open (dek->algo, mode, GCRY_CIPHER_SECURE); - if (!dek->chd) - { - log_error ("failed to create cipher context: %s\n", gcry_strerror (-1)); - return GNUPG_General_Error; - } - - for (i=0; i < 8; i++) - { - gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM ); - rc = gcry_cipher_setkey (dek->chd, dek->key, dek->keylen); - if (rc != GCRYERR_WEAK_KEY) - break; - log_info(_("weak key created - retrying\n") ); - } - if (rc) - { - log_error ("failed to set the key: %s\n", gcry_strerror (rc)); - gcry_cipher_close (dek->chd); - dek->chd = NULL; - return map_gcry_err (rc); - } - - gcry_randomize (dek->iv, dek->ivlen, GCRY_STRONG_RANDOM); - rc = gcry_cipher_setiv (dek->chd, dek->iv, dek->ivlen); - if (rc) - { - log_error ("failed to set the IV: %s\n", gcry_strerror (rc)); - gcry_cipher_close (dek->chd); - dek->chd = NULL; - return map_gcry_err (rc); - } - - return 0; -} - - -/* Encode the session key. NBITS is the number of bits which should be - used for packing the session key. returns: An mpi with the session - key (caller must free) */ -static GCRY_MPI -encode_session_key (DEK dek, unsigned int nbits) -{ - int nframe = (nbits+7) / 8; - byte *p; - byte *frame; - int i,n; - MPI a; - - 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 KEY(k 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. - * KEY is the encryption key (session key) - */ - - frame = gcry_xmalloc_secure (nframe); - n = 0; - frame[n++] = 0; - frame[n++] = 2; - i = nframe - 3 - 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; - memcpy (frame+n, dek->key, dek->keylen); - n += dek->keylen; - assert (n == nframe); - if (gcry_mpi_scan (&a, GCRYMPI_FMT_USG, frame, &nframe) ) - BUG (); - gcry_free(frame); - - return a; -} - - - -/* encrypt the DEK under the key contained in CERT and return it as a - canonical S-Exp in encval */ -static int -encrypt_dek (const DEK dek, KsbaCert cert, char **encval) -{ - GCRY_SEXP s_ciph, s_data, s_pkey; - int rc; - KsbaSexp buf; - size_t len; - - *encval = NULL; - - /* get the key from the cert */ - buf = ksba_cert_get_public_key (cert); - if (!buf) - { - log_error ("no public key for recipient\n"); - return GNUPG_No_Public_Key; - } - len = gcry_sexp_canon_len (buf, 0, NULL, NULL); - if (!len) - { - log_error ("libksba did not return a proper S-Exp\n"); - return GNUPG_Bug; - } - rc = gcry_sexp_sscan (&s_pkey, NULL, buf, len); - xfree (buf); buf = NULL; - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); - return map_gcry_err (rc); - } - - /* put the encoded cleartext into a simple list */ - { - /* fixme: actually the pkcs-1 encoding should go into libgcrypt */ - GCRY_MPI data = encode_session_key (dek, gcry_pk_get_nbits (s_pkey)); - if (!data) - { - gcry_mpi_release (data); - return GNUPG_General_Error; - } - if (gcry_sexp_build (&s_data, NULL, "%m", data)) - BUG (); - gcry_mpi_release (data); - } - - /* pass it to libgcrypt */ - rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); - gcry_sexp_release (s_data); - gcry_sexp_release (s_pkey); - - /* reformat it */ - len = gcry_sexp_sprint (s_ciph, GCRYSEXP_FMT_CANON, NULL, 0); - assert (len); - buf = xtrymalloc (len); - if (!buf) - { - gcry_sexp_release (s_ciph); - return GNUPG_Out_Of_Core; - } - len = gcry_sexp_sprint (s_ciph, GCRYSEXP_FMT_CANON, buf, len); - assert (len); - - *encval = buf; - return 0; -} - - - -/* do the actual encryption */ -static int -encrypt_cb (void *cb_value, char *buffer, size_t count, size_t *nread) -{ - struct encrypt_cb_parm_s *parm = cb_value; - int blklen = parm->dek->ivlen; - unsigned char *p; - size_t n; - - *nread = 0; - if (!buffer) - return -1; /* not supported */ - - if (parm->ready) - return -1; - - if (count < blklen) - BUG (); - - if (!parm->eof_seen) - { /* fillup the buffer */ - p = parm->buffer; - for (n=parm->buflen; n < parm->bufsize; n++) - { - int c = getc (parm->fp); - if (c == EOF) - { - if (ferror (parm->fp)) - { - parm->readerror = errno; - return -1; - } - parm->eof_seen = 1; - break; - } - p[n] = c; - } - parm->buflen = n; - } - - n = parm->buflen < count? parm->buflen : count; - n = n/blklen * blklen; - if (n) - { /* encrypt the stuff */ - gcry_cipher_encrypt (parm->dek->chd, buffer, n, parm->buffer, n); - *nread = n; - /* Who cares about cycles, take the easy way and shift the buffer */ - parm->buflen -= n; - memmove (parm->buffer, parm->buffer+n, parm->buflen); - } - else if (parm->eof_seen) - { /* no complete block but eof: add padding */ - /* fixme: we should try to do this also in the above code path */ - int i, npad = blklen - (parm->buflen % blklen); - p = parm->buffer; - for (n=parm->buflen, i=0; n < parm->bufsize && i < npad; n++, i++) - p[n] = npad; - gcry_cipher_encrypt (parm->dek->chd, buffer, n, parm->buffer, n); - *nread = n; - parm->ready = 1; - } - - return 0; -} - - - - -/* Perform an encrypt operation. - - Encrypt the data received on DATA-FD and write it to OUT_FP. The - recipients are take from the certificate given in recplist; if this - is NULL it will be encrypted for a default recipient */ -int -gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp) -{ - int rc = 0; - Base64Context b64writer = NULL; - KsbaError err; - KsbaWriter writer; - KsbaReader reader = NULL; - KsbaCMS cms = NULL; - KsbaStopReason stopreason; - KEYDB_HANDLE kh = NULL; - struct encrypt_cb_parm_s encparm; - DEK dek = NULL; - int recpno; - FILE *data_fp = NULL; - CERTLIST cl; - - memset (&encparm, 0, sizeof encparm); - - if (!recplist) - { - log_error(_("no valid recipients given\n")); - gpgsm_status (ctrl, STATUS_NO_RECP, "0"); - rc = GNUPG_No_Public_Key; - goto leave; - } - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = GNUPG_General_Error; - goto leave; - } - - data_fp = fdopen ( dup (data_fd), "rb"); - if (!data_fp) - { - log_error ("fdopen() failed: %s\n", strerror (errno)); - rc = seterr (IO_Error); - goto leave; - } - - reader = ksba_reader_new (); - if (!reader) - rc = KSBA_Out_Of_Core; - if (!rc) - rc = ksba_reader_set_cb (reader, encrypt_cb, &encparm); - if (rc) - { - rc = map_ksba_err (rc); - goto leave; - } - encparm.fp = data_fp; - - ctrl->pem_name = "ENCRYPTED MESSAGE"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gnupg_strerror (rc)); - goto leave; - } - - cms = ksba_cms_new (); - if (!cms) - { - rc = seterr (Out_Of_Core); - goto leave; - } - - err = ksba_cms_set_reader_writer (cms, reader, writer); - if (err) - { - log_debug ("ksba_cms_set_reader_writer failed: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - - /* We are going to create enveloped data with uninterpreted data as - inner content */ - err = ksba_cms_set_content_type (cms, 0, KSBA_CT_ENVELOPED_DATA); - if (!err) - err = ksba_cms_set_content_type (cms, 1, KSBA_CT_DATA); - if (err) - { - log_debug ("ksba_cms_set_content_type failed: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - - /* create a session key */ - dek = xtrycalloc (1, sizeof *dek); /* hmmm: should we put it into secmem?*/ - if (!dek) - rc = GNUPG_Out_Of_Core; - else - { - dek->algoid = opt.def_cipher_algoid; - rc = init_dek (dek); - } - if (rc) - { - log_error ("failed to create the session key: %s\n", - gnupg_strerror (rc)); - goto leave; - } - - err = ksba_cms_set_content_enc_algo (cms, dek->algoid, dek->iv, dek->ivlen); - if (err) - { - log_error ("ksba_cms_set_content_enc_algo failed: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - - encparm.dek = dek; - /* Use a ~8k (AES) or ~4k (3DES) buffer */ - encparm.bufsize = 500 * dek->ivlen; - encparm.buffer = xtrymalloc (encparm.bufsize); - if (!encparm.buffer) - { - rc = seterr (Out_Of_Core); - goto leave; - } - - /* gather certificates of recipients, encrypt the session key for - each and store them in the CMS object */ - for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next) - { - char *encval; - - rc = encrypt_dek (dek, cl->cert, &encval); - if (rc) - { - log_error ("encryption failed for recipient no. %d: %s\n", - recpno, gnupg_strerror (rc)); - goto leave; - } - - err = ksba_cms_add_recipient (cms, cl->cert); - if (err) - { - log_error ("ksba_cms_add_recipient failed: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - xfree (encval); - goto leave; - } - - err = ksba_cms_set_enc_val (cms, recpno, encval); - xfree (encval); - if (err) - { - log_error ("ksba_cms_set_enc_val failed: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - } - - /* main control loop for encryption */ - recpno = 0; - do - { - err = ksba_cms_build (cms, &stopreason); - if (err) - { - log_debug ("ksba_cms_build failed: %s\n", ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - } - while (stopreason != KSBA_SR_READY); - - if (encparm.readerror) - { - log_error ("error reading input: %s\n", strerror (encparm.readerror)); - rc = seterr (Read_Error); - goto leave; - } - - - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - log_info ("encrypted data created\n"); - - leave: - ksba_cms_release (cms); - gpgsm_destroy_writer (b64writer); - ksba_reader_release (reader); - keydb_release (kh); - xfree (dek); - if (data_fp) - fclose (data_fp); - xfree (encparm.buffer); - return rc; -} diff --git a/sm/export.c b/sm/export.c deleted file mode 100644 index 042850752..000000000 --- a/sm/export.c +++ /dev/null @@ -1,248 +0,0 @@ -/* export.c - * Copyright (C) 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gpgsm.h" -#include "keydb.h" - -static void print_short_info (KsbaCert cert, FILE *fp); - - - -/* Export all certificates or just those given in NAMES. */ -void -gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp) -{ - KEYDB_HANDLE hd; - KEYDB_SEARCH_DESC *desc = NULL; - int ndesc; - Base64Context b64writer = NULL; - KsbaWriter writer; - STRLIST sl; - KsbaCert cert = NULL; - int rc=0; - int count = 0; - int i; - - hd = keydb_new (0); - if (!hd) - { - log_error ("keydb_new failed\n"); - goto leave; - } - - if (!names) - ndesc = 1; - else - { - for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) - ; - } - - desc = xtrycalloc (ndesc, sizeof *desc); - if (!ndesc) - { - log_error ("%s\n", gnupg_strerror (GNUPG_Out_Of_Core)); - goto leave; - } - - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_FIRST; - else - { - for (ndesc=0, sl=names; sl; sl = sl->next) - { - rc = keydb_classify_name (sl->d, desc+ndesc); - if (rc) - { - log_error ("key `%s' not found: %s\n", - sl->d, gnupg_strerror (rc)); - rc = 0; - } - else - ndesc++; - } - } - - /* If all specifications are done by fingerprint, we switch to - ephemeral mode so that _all_ currently available and matching - certificates are exported. - - fixme: we should in this case keep a list of certificates to - avoid accidential export of duplicate certificates. */ - if (names && ndesc) - { - for (i=0; (i < ndesc - && (desc[i].mode == KEYDB_SEARCH_MODE_FPR - || desc[i].mode == KEYDB_SEARCH_MODE_FPR20 - || desc[i].mode == KEYDB_SEARCH_MODE_FPR16)); i++) - ; - if (i == ndesc) - keydb_set_ephemeral (hd, 1); - } - - while (!(rc = keydb_search (hd, desc, ndesc))) - { - const unsigned char *image; - size_t imagelen; - - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_NEXT; - - rc = keydb_get_cert (hd, &cert); - if (rc) - { - log_error ("keydb_get_cert failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - - image = ksba_cert_get_image (cert, &imagelen); - if (!image) - { - log_error ("ksba_cert_get_image failed\n"); - goto leave; - } - - if (ctrl->create_pem) - { - if (count) - putc ('\n', fp); - print_short_info (cert, fp); - putc ('\n', fp); - } - count++; - - if (!b64writer) - { - ctrl->pem_name = "CERTIFICATE"; - rc = gpgsm_create_writer (&b64writer, ctrl, fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gnupg_strerror (rc)); - goto leave; - } - } - - rc = ksba_writer_write (writer, image, imagelen); - if (rc) - { - log_error ("write error: %s\n", ksba_strerror (rc)); - goto leave; - } - - if (ctrl->create_pem) - { - /* We want one certificate per PEM block */ - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - gpgsm_destroy_writer (b64writer); - b64writer = NULL; - } - - ksba_cert_release (cert); - cert = NULL; - } - if (rc && rc != -1) - log_error ("keydb_search failed: %s\n", gnupg_strerror (rc)); - else if (b64writer) - { - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - } - - leave: - gpgsm_destroy_writer (b64writer); - ksba_cert_release (cert); - xfree (desc); - keydb_release (hd); -} - - -/* Print some info about the certifciate CERT to FP */ -static void -print_short_info (KsbaCert cert, FILE *fp) -{ - char *p; - KsbaSexp sexp; - int idx; - - for (idx=0; (p = ksba_cert_get_issuer (cert, idx)); idx++) - { - fputs (!idx? "Issuer ...: " - : "\n aka ...: ", fp); - gpgsm_print_name (fp, p); - xfree (p); - } - putc ('\n', fp); - - fputs ("Serial ...: ", fp); - sexp = ksba_cert_get_serial (cert); - if (sexp) - { - int len; - const unsigned char *s = sexp; - - if (*s == '(') - { - s++; - for (len=0; *s && *s != ':' && digitp (s); s++) - len = len*10 + atoi_1 (s); - if (*s == ':') - for (s++; len; len--, s++) - fprintf (fp, "%02X", *s); - } - xfree (sexp); - } - putc ('\n', fp); - - for (idx=0; (p = ksba_cert_get_subject (cert, idx)); idx++) - { - fputs (!idx? "Subject ..: " - : "\n aka ..: ", fp); - gpgsm_print_name (fp, p); - xfree (p); - } - putc ('\n', fp); -} - - - - - - diff --git a/sm/fingerprint.c b/sm/fingerprint.c deleted file mode 100644 index 6a84966db..000000000 --- a/sm/fingerprint.c +++ /dev/null @@ -1,271 +0,0 @@ -/* fingerprint.c - Get the fingerprint - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gpgsm.h" - -/* Return the fingerprint of the certificate (we can't put this into - libksba because we need libgcrypt support). The caller must - provide an array of sufficient length or NULL so that the function - allocates the array. If r_len is not NULL, the length of the - digest is returned; well, this can also be done by using - gcry_md_get_algo_dlen(). If algo is 0, a SHA-1 will be used. - - If there is a problem , the function does never return NULL but a - digest of all 0xff. - */ -char * -gpgsm_get_fingerprint (KsbaCert cert, int algo, char *array, int *r_len) -{ - GCRY_MD_HD md; - int rc, len; - - if (!algo) - algo = GCRY_MD_SHA1; - - len = gcry_md_get_algo_dlen (algo); - assert (len); - if (!array) - array = xmalloc (len); - - if (r_len) - *r_len = len; - - md = gcry_md_open (algo, 0); - if (!md) - { - log_error ("md_open failed: %s\n", gcry_strerror (-1)); - memset (array, 0xff, len); /* better return an invalid fpr than NULL */ - return array; - } - - rc = ksba_cert_hash (cert, 0, HASH_FNC, md); - if (rc) - { - log_error ("ksba_cert_hash failed: %s\n", ksba_strerror (rc)); - gcry_md_close (md); - memset (array, 0xff, len); /* better return an invalid fpr than NULL */ - return array; - } - gcry_md_final (md); - memcpy (array, gcry_md_read(md, algo), len ); - return array; -} - - -/* Return an allocated buffer with the formatted fingerprint */ -char * -gpgsm_get_fingerprint_string (KsbaCert cert, int algo) -{ - unsigned char digest[MAX_DIGEST_LEN]; - char *buf; - int len, i; - - if (!algo) - algo = GCRY_MD_SHA1; - - len = gcry_md_get_algo_dlen (algo); - assert (len <= MAX_DIGEST_LEN ); - gpgsm_get_fingerprint (cert, algo, digest, NULL); - buf = xmalloc (len*3+1); - *buf = 0; - for (i=0; i < len; i++ ) - sprintf (buf+strlen(buf), i? ":%02X":"%02X", digest[i]); - return buf; -} - -/* Return an allocated buffer with the formatted fingerprint as one - large hexnumber */ -char * -gpgsm_get_fingerprint_hexstring (KsbaCert cert, int algo) -{ - unsigned char digest[MAX_DIGEST_LEN]; - char *buf; - int len, i; - - if (!algo) - algo = GCRY_MD_SHA1; - - len = gcry_md_get_algo_dlen (algo); - assert (len <= MAX_DIGEST_LEN ); - gpgsm_get_fingerprint (cert, algo, digest, NULL); - buf = xmalloc (len*3+1); - *buf = 0; - for (i=0; i < len; i++ ) - sprintf (buf+strlen(buf), "%02X", digest[i]); - return buf; -} - -/* Return a certificate ID. These are the last 4 bytes of the SHA-1 - fingerprint. */ -unsigned long -gpgsm_get_short_fingerprint (KsbaCert cert) -{ - unsigned char digest[20]; - - gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); - return ((digest[16]<<24)|(digest[17]<<16)|(digest[18]<< 8)|digest[19]); -} - - -/* Return the so called KEYGRIP which is the SHA-1 hash of the public - key parameters expressed as an canoncial encoded S-Exp. array must - be 20 bytes long. returns the array or a newly allocated one if the - passed one was NULL */ -char * -gpgsm_get_keygrip (KsbaCert cert, char *array) -{ - GCRY_SEXP s_pkey; - int rc; - KsbaSexp p; - size_t n; - - p = ksba_cert_get_public_key (cert); - if (!p) - return NULL; /* oops */ - - if (DBG_X509) - log_debug ("get_keygrip for public key: %s\n", p); - n = gcry_sexp_canon_len (p, 0, NULL, NULL); - if (!n) - { - log_error ("libksba did not return a proper S-Exp\n"); - return NULL; - } - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); - xfree (p); - if (rc) - { - log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); - return NULL; - } - array = gcry_pk_get_keygrip (s_pkey, array); - gcry_sexp_release (s_pkey); - if (!array) - { - rc = seterr (General_Error); - log_error ("can't calculate keygrip\n"); - return NULL; - } - if (DBG_X509) - log_printhex ("keygrip=", array, 20); - - return array; -} - -/* Return an allocated buffer with the keygrip of CERT in from of an - hexstring. NULL is returned in case of error */ -char * -gpgsm_get_keygrip_hexstring (KsbaCert cert) -{ - unsigned char grip[20]; - char *buf, *p; - int i; - - gpgsm_get_keygrip (cert, grip); - buf = p = xmalloc (20*2+1); - for (i=0; i < 20; i++, p += 2 ) - sprintf (p, "%02X", grip[i]); - return buf; -} - - - -/* For certain purposes we need a certificate id which has an upper - limit of the size. We use the hash of the issuer name and the - serial number for this. In most cases the serial number is not - that large and the resulting string can be passed on an assuan - command line. Everything is hexencoded with the serialnumber - delimted from the has by a dot. - - The caller must free the string. -*/ -char * -gpgsm_get_certid (KsbaCert cert) -{ - KsbaSexp serial; - unsigned char *p; - char *endp; - unsigned char hash[20]; - unsigned long n; - char *certid; - int i; - - p = ksba_cert_get_issuer (cert, 0); - if (!p) - return NULL; /* Ooops: No issuer */ - gcry_md_hash_buffer (GCRY_MD_SHA1, hash, p, strlen (p)); - xfree (p); - - serial = ksba_cert_get_serial (cert); - if (!serial) - return NULL; /* oops: no serial number */ - p = serial; - if (*p != '(') - { - log_error ("Ooops: invalid serial number\n"); - xfree (serial); - return NULL; - } - p++; - n = strtoul (p, &endp, 10); - p = endp; - if (*p != ':') - { - log_error ("Ooops: invalid serial number (no colon)\n"); - xfree (serial); - return NULL; - } - p++; - - certid = xtrymalloc ( 40 + 1 + n*2 + 1); - if (!certid) - { - xfree (serial); - return NULL; /* out of core */ - } - - for (i=0, endp = certid; i < 20; i++, endp += 2 ) - sprintf (endp, "%02X", hash[i]); - *endp++ = '.'; - for (i=0; i < n; i++, endp += 2) - sprintf (endp, "%02X", p[i]); - *endp = 0; - - xfree (serial); - return certid; -} - - - - - - diff --git a/sm/gpgsm.c b/sm/gpgsm.c deleted file mode 100644 index bfcdeb741..000000000 --- a/sm/gpgsm.c +++ /dev/null @@ -1,1388 +0,0 @@ -/* gpgsm.c - GnuPG for S/MIME - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include "gpgsm.h" -#include "../assuan/assuan.h" /* malloc hooks */ -#include "../kbx/keybox.h" /* malloc hooks */ -#include "i18n.h" -#include "keydb.h" -#include "sysutils.h" - -enum cmd_and_opt_values { - aNull = 0, - oArmor = 'a', - aDetachedSign = 'b', - aSym = 'c', - aDecrypt = 'd', - aEncr = 'e', - oInteractive = 'i', - oKOption = 'k', - oDryRun = 'n', - oOutput = 'o', - oQuiet = 'q', - oRecipient = 'r', - aSign = 's', - oTextmodeShort= 't', - oUser = 'u', - oVerbose = 'v', - oCompress = 'z', - oNotation = 'N', - oBatch = 500, - aClearsign, - aStore, - aKeygen, - aSignEncr, - aSignKey, - aLSignKey, - aListPackets, - aEditKey, - aDeleteKey, - aImport, - aVerify, - aVerifyFiles, - aListKeys, - aListExternalKeys, - aListSigs, - aListSecretKeys, - aSendKeys, - aRecvKeys, - aExport, - aCheckKeys, /* nyi */ - aServer, - aLearnCard, - - oOptions, - oDebug, - oDebugAll, - oDebugWait, - oDebugNoChainValidation, - oLogFile, - - oEnableSpecialFilenames, - - oAgentProgram, - oDisplay, - oTTYname, - oTTYtype, - oLCctype, - oLCmessages, - - oDirmngrProgram, - oFakedSystemTime, - - - oAssumeArmor, - oAssumeBase64, - oAssumeBinary, - - oBase64, - oNoArmor, - - oDisableCRLChecks, - oEnableCRLChecks, - - oIncludeCerts, - oPolicyFile, - oDisablePolicyChecks, - oEnablePolicyChecks, - oAutoIssuerKeyRetrieve, - - - oTextmode, - oFingerprint, - oWithFingerprint, - oAnswerYes, - oAnswerNo, - oKeyring, - oSecretKeyring, - oDefaultKey, - oDefRecipient, - oDefRecipientSelf, - oNoDefRecipient, - oStatusFD, - oNoComment, - oNoVersion, - oEmitVersion, - oCompletesNeeded, - oMarginalsNeeded, - oMaxCertDepth, - oLoadExtension, - oRFC1991, - oOpenPGP, - oCipherAlgo, - oDigestAlgo, - oCompressAlgo, - oPasswdFD, - oCommandFD, - oNoVerbose, - oTrustDBName, - oNoSecmemWarn, - oNoDefKeyring, - oNoGreeting, - oNoTTY, - oNoOptions, - oNoBatch, - oHomedir, - oWithColons, - oWithKeyData, - oSkipVerify, - oCompressKeys, - oCompressSigs, - oAlwaysTrust, - oRunAsShmCP, - oSetFilename, - oSetPolicyURL, - oUseEmbeddedFilename, - oComment, - oDefaultComment, - oThrowKeyid, - oForceV3Sigs, - oForceMDC, - oS2KMode, - oS2KDigest, - oS2KCipher, - oCharset, - oNotDashEscaped, - oEscapeFrom, - oLockOnce, - oLockMultiple, - oLockNever, - oKeyServer, - oEncryptTo, - oNoEncryptTo, - oLoggerFD, - oUtf8Strings, - oNoUtf8Strings, - oDisableCipherAlgo, - oDisablePubkeyAlgo, - oAllowNonSelfsignedUID, - oAllowFreeformUID, - oNoLiteral, - oSetFilesize, - oHonorHttpProxy, - oFastListMode, - oListOnly, - oIgnoreTimeConflict, - oNoRandomSeedFile, - oNoAutoKeyRetrieve, - oUseAgent, - oMergeOnly, - oTryAllSecrets, - oTrustedKey, - oEmuMDEncodeBug, - aDummy - }; - - -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")}, - { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")}, - { aDecrypt, "decrypt", 256, N_("decrypt data (default)")}, - { aVerify, "verify" , 256, N_("verify a signature")}, - { aVerifyFiles, "verify-files" , 256, "@" }, - { aListKeys, "list-keys", 256, N_("list keys")}, - { aListExternalKeys, "list-external-keys", 256, N_("list external keys")}, - { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")}, - { aListSigs, "list-sigs", 256, N_("list certificate chain")}, - { aListSigs, "check-sigs",256, "@"}, - { 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")}, - { aDeleteKey, "delete-key",256, N_("remove key from the public keyring")}, - { aSendKeys, "send-keys" , 256, N_("export keys to a key server") }, - { aRecvKeys, "recv-keys" , 256, N_("import keys from a key server") }, - { aImport, "import", 256 , N_("import certificates")}, - { aExport, "export", 256 , N_("export certificates")}, - { aLearnCard, "learn-card", 256 ,N_("register a smartcard")}, - { aServer, "server", 256, N_("run in server mode")}, - { oLogFile, "log-file" ,2, N_("use a log file for the server")}, - - { 301, NULL, 0, N_("@\nOptions:\n ") }, - - { oArmor, "armor", 0, N_("create ascii armored output")}, - { oArmor, "armour", 0, "@" }, - { oBase64, "base64", 0, N_("create base-64 encoded output")}, - - { oAssumeArmor, "assume-armor", 0, N_("assume input is in PEM format")}, - { oAssumeBase64, "assume-base64", 0, - N_("assume input is in base-64 format")}, - { oAssumeBinary, "assume-binary", 0, - N_("assume input is in binary format")}, - - { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")}, - - - { oDisableCRLChecks, "disable-crl-checks", 0, N_("never consult a CRL")}, - { oEnableCRLChecks, "enable-crl-checks", 0, "@"}, - - { oIncludeCerts, "include-certs", 1, - N_("|N|number of certificates to include") }, - - { oPolicyFile, "policy-file", 2, - N_("|FILE|take policy information from FILE") }, - - { oDisablePolicyChecks, "disable-policy-checks", 0, - N_("do not check certificate policies")}, - { oEnablePolicyChecks, "enable-policy-checks", 0, "@"}, - - { oAutoIssuerKeyRetrieve, "auto-issuer-key-retrieve", 0, - N_("fetch missing issuer certificates")}, - -#if 0 - { oDefRecipient, "default-recipient" ,2, - N_("|NAME|use NAME as default recipient")}, - { oDefRecipientSelf, "default-recipient-self" ,0, - N_("use the default key as default recipient")}, - { oNoDefRecipient, "no-default-recipient", 0, "@" }, - { oEncryptTo, "encrypt-to", 2, "@" }, - { oNoEncryptTo, "no-encrypt-to", 0, "@" }, - -#endif - { oUser, "local-user",2, N_("use this user-id to sign or decrypt")}, - -#if 0 - { oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") }, - { oTextmodeShort, NULL, 0, "@"}, - { oTextmode, "textmode", 0, N_("use canonical text mode")}, -#endif - - { oOutput, "output", 2, N_("use as output file")}, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, - { oNoTTY, "no-tty", 0, N_("don't use the terminal at all") }, -#if 0 - { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") }, - { oForceMDC, "force-mdc", 0, N_("always use a MDC for encryption") }, -#endif - { oDryRun, "dry-run", 0, N_("do not make any changes") }, - /*{ oInteractive, "interactive", 0, N_("prompt before overwriting") }, */ - /*{ oUseAgent, "use-agent",0, N_("use the gpg-agent")},*/ - { oBatch, "batch", 0, N_("batch mode: never ask")}, - { oAnswerYes, "yes", 0, N_("assume yes on most questions")}, - { oAnswerNo, "no", 0, N_("assume no on most questions")}, - - { oKeyring, "keyring" ,2, N_("add this keyring to the list of keyrings")}, - { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")}, - { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")}, - { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")}, - { oCharset, "charset" , 2, N_("|NAME|set terminal charset to NAME") }, - { oOptions, "options" , 2, N_("read options from file")}, - - { oDebug, "debug" ,4|16, "@"}, - { oDebugAll, "debug-all" ,0, "@"}, - { oDebugWait, "debug-wait" ,1, "@"}, - { oDebugNoChainValidation, "debug-no-chain-validation" ,0, "@"}, - { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") }, - { aDummy, "no-comment", 0, "@"}, - { aDummy, "completes-needed", 1, "@"}, - { aDummy, "marginals-needed", 1, "@"}, - { oMaxCertDepth, "max-cert-depth", 1, "@" }, - { aDummy, "trusted-key", 2, "@"}, - { oLoadExtension, "load-extension" ,2, - N_("|FILE|load extension module FILE")}, - { aDummy, "rfc1991", 0, "@"}, - { aDummy, "openpgp", 0, "@"}, - { aDummy, "s2k-mode", 1, "@"}, - { aDummy, "s2k-digest-algo",2, "@"}, - { aDummy, "s2k-cipher-algo",2, "@"}, - { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")}, - { oDigestAlgo, "digest-algo", 2 , - N_("|NAME|use message digest algorithm NAME")}, -#if 0 - { oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")}, -#endif - { aDummy, "throw-keyid", 0, "@"}, - { aDummy, "notation-data", 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 */ - { oNoVerbose, "no-verbose", 0, "@"}, - - { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" }, - - - { oTrustDBName, "trustdb-name", 2, "@" }, - { oNoSecmemWarn, "no-secmem-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" */ - { oAgentProgram, "agent-program", 2 , "@" }, - { oDisplay, "display", 2, "@" }, - { oTTYname, "ttyname", 2, "@" }, - { oTTYtype, "ttytype", 2, "@" }, - { oLCctype, "lc-ctype", 2, "@" }, - { oLCmessages, "lc-messages", 2, "@" }, - { oDirmngrProgram, "dirmngr-program", 2 , "@" }, - { oFakedSystemTime, "faked-system-time", 4, "@" }, /* (epoch time) */ - - - { oNoBatch, "no-batch", 0, "@" }, - { oWithColons, "with-colons", 0, "@"}, - { oWithKeyData,"with-key-data", 0, "@"}, - { aListKeys, "list-key", 0, "@" }, /* alias */ - { aListSigs, "list-sig", 0, "@" }, /* alias */ - { aListSigs, "check-sig",0, "@" }, /* alias */ - { oSkipVerify, "skip-verify",0, "@" }, - { oCompressKeys, "compress-keys",0, "@"}, - { oCompressSigs, "compress-sigs",0, "@"}, - { oAlwaysTrust, "always-trust", 0, "@"}, - { oNoVersion, "no-version", 0, "@"}, - { oLockOnce, "lock-once", 0, "@" }, - { oLockMultiple, "lock-multiple", 0, "@" }, - { oLockNever, "lock-never", 0, "@" }, - { oLoggerFD, "logger-fd",1, "@" }, - { oWithFingerprint, "with-fingerprint", 0, "@" }, - { oDisableCipherAlgo, "disable-cipher-algo", 2, "@" }, - { oDisablePubkeyAlgo, "disable-pubkey-algo", 2, "@" }, - { oHonorHttpProxy,"honor-http-proxy", 0, "@" }, - { oListOnly, "list-only", 0, "@"}, - { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" }, - { oNoRandomSeedFile, "no-random-seed-file", 0, "@" }, -{0} }; - - - -int gpgsm_errors_seen = 0; - -/* It is possible that we are currentlu running under setuid permissions */ -static int maybe_setuid = 1; - -/* Option --enable-special-filenames */ -static int allow_special_filenames; - - -static char *build_list (const char *text, - 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 emergency_cleanup (void); -static int check_special_filename (const char *fname); -static int open_read (const char *filename); -static FILE *open_fwrite (const char *filename); - - -static int -our_pk_test_algo (int algo) -{ - return 1; -} - -static int -our_cipher_test_algo (int algo) -{ - return 1; -} - -static int -our_md_test_algo (int algo) -{ - return 1; -} - -static const char * -my_strusage( int level ) -{ - static char *digests, *pubkeys, *ciphers; - const char *p; - - switch (level) - { - case 11: p = "gpgsm (GnuPG)"; - break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; - case 1: - case 40: p = _("Usage: gpgsm [options] [files] (-h for help)"); - break; - case 41: - p = _("Syntax: gpgsm [options] [files]\n" - "sign, check, encrypt or decrypt using the S/MIME protocol\n" - "default operation depends on the input data\n"); - break; - - case 31: p = "\nHome: "; break; - case 32: p = opt.homedir; break; - case 33: p = _("\nSupported algorithms:\n"); break; - case 34: - if (!ciphers) - ciphers = build_list ("Cipher: ", gcry_cipher_algo_name, - our_cipher_test_algo ); - p = ciphers; - break; - case 35: - if (!pubkeys) - pubkeys = build_list ("Pubkey: ", gcry_pk_algo_name, - our_pk_test_algo ); - p = pubkeys; - break; - case 36: - if (!digests) - digests = build_list("Hash: ", gcry_md_algo_name, our_md_test_algo ); - p = digests; - break; - - default: p = NULL; break; - } - return p; -} - - -static char * -build_list (const char *text, const char * (*mapf)(int), int (*chkf)(int)) -{ - int i; - size_t n=strlen(text)+2; - char *list, *p; - - if (maybe_setuid) { - gcry_control (GCRYCTL_DROP_PRIVS); /* drop setuid */ - } - - for (i=1; i < 110; i++ ) - if (!chkf(i)) - n += strlen(mapf(i)) + 2; - list = xmalloc (21 + n); - *list = 0; - for (p=NULL, i=1; i < 110; i++) - { - if (!chkf(i)) - { - if( !p ) - p = stpcpy (list, text ); - else - p = stpcpy (p, ", "); - p = stpcpy (p, mapf(i) ); - } - } - if (p) - p = stpcpy(p, "\n" ); - return list; -} - - -static void -i18n_init(void) -{ -#ifdef USE_SIMPLE_GETTEXT - set_gettext_file (PACKAGE); -#else -# ifdef ENABLE_NLS -# ifdef HAVE_LC_MESSAGES - setlocale (LC_TIME, ""); - setlocale (LC_MESSAGES, ""); -# else - setlocale (LC_ALL, "" ); -# endif - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); -# endif -#endif -} - - -static void -wrong_args (const char *text) -{ - fputs (_("usage: gpgsm [options] "), stderr); - fputs (text, stderr); - putc ('\n', stderr); - gpgsm_exit (2); -} - - -static void -set_debug(void) -{ - if (opt.debug & DBG_MPI_VALUE) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2); - if (opt.debug & DBG_CRYPTO_VALUE ) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1); -} - - -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 == aClearsign) - || (cmd == aClearsign && new_cmd == aSign) ) - cmd = aClearsign; - else - { - log_error(_("conflicting commands\n")); - gpgsm_exit(2); - } - - *ret_cmd = cmd; -} - - -int -main ( int argc, char **argv) -{ - ARGPARSE_ARGS pargs; - int orig_argc; - char **orig_argv; - const char *fname; - /* char *username;*/ - int may_coredump; - STRLIST sl, remusr= NULL, locusr=NULL; - STRLIST nrings=NULL; - int detached_sig = 0; - FILE *configfp = NULL; - char *configname = NULL; - unsigned configlineno; - int parse_debug = 0; - int default_config =1; - int default_keyring = 1; - char *logfile = NULL; - int greeting = 0; - int nogreeting = 0; - int debug_wait = 0; - int use_random_seed = 1; - int with_fpr = 0; - char *def_digest_string = NULL; - enum cmd_and_opt_values cmd = 0; - struct server_control_s ctrl; - CERTLIST recplist = NULL; - CERTLIST signerlist = NULL; - - /* 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 ("gpgsm", 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) ); - } - if (!ksba_check_version (NEED_KSBA_VERSION) ) - { - log_fatal( _("libksba is too old (need %s, have %s)\n"), - NEED_KSBA_VERSION, ksba_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.def_cipher_algoid = "1.2.840.113549.3.7"; /*des-EDE3-CBC*/ -#ifdef __MINGW32__ - 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; - - /* first 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 config 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) - opt.homedir = pargs.r.ret_str; - } - - - /* initialize the secure memory. */ - gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); - maybe_setuid = 0; - - /* - Now we are now working under our real uid - */ - - ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free ); - assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); - - /* Setup a default control structure for command line mode */ - memset (&ctrl, 0, sizeof ctrl); - gpgsm_init_default_ctrl (&ctrl); - ctrl.no_server = 1; - ctrl.status_fd = -1; /* not status output */ - ctrl.autodetect_encoding = 1; - - /* set the default option file */ - if (default_config ) - configname = make_filename (opt.homedir, "gpgsm.conf", NULL); - /* cet the default policy file */ - opt.policy_file = make_filename (opt.homedir, "policies.txt", NULL); - - argc = orig_argc; - argv = orig_argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags = 1; /* do not remove the args */ - - next_pass: - if (configname) { - 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)); - gpgsm_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 aServer: - opt.batch = 1; - set_cmd (&cmd, aServer); - break; - - case aCheckKeys: set_cmd (&cmd, aCheckKeys); break; - case aImport: set_cmd (&cmd, aImport); break; - case aSendKeys: set_cmd (&cmd, aSendKeys); break; - case aRecvKeys: set_cmd (&cmd, aRecvKeys); break; - case aExport: set_cmd (&cmd, aExport); break; - case aListKeys: set_cmd (&cmd, aListKeys); break; - case aListExternalKeys: set_cmd (&cmd, aListExternalKeys); break; - case aListSecretKeys: set_cmd (&cmd, aListSecretKeys); break; - case aListSigs: set_cmd (&cmd, aListSigs); break; - - case aLearnCard: set_cmd (&cmd, aLearnCard); break; - - case aDeleteKey: - set_cmd (&cmd, aDeleteKey); - /*greeting=1;*/ - break; - - case aDetachedSign: - detached_sig = 1; - set_cmd (&cmd, aSign ); - break; - - case aSym: set_cmd (&cmd, aSym); break; - case aDecrypt: set_cmd (&cmd, aDecrypt); break; - case aEncr: set_cmd (&cmd, aEncr); break; - case aSign: set_cmd (&cmd, aSign ); break; - case aKeygen: set_cmd (&cmd, aKeygen); greeting=1; break; - case aClearsign: set_cmd (&cmd, aClearsign); break; - case aVerify: set_cmd (&cmd, aVerify); break; - - - /* output encoding selection */ - case oArmor: - ctrl.create_pem = 1; - break; - case oBase64: - ctrl.create_pem = 0; - ctrl.create_base64 = 1; - break; - case oNoArmor: - ctrl.create_pem = 0; - ctrl.create_base64 = 0; - break; - - /* Input encoding selection */ - case oAssumeArmor: - ctrl.autodetect_encoding = 0; - ctrl.is_pem = 1; - ctrl.is_base64 = 0; - break; - case oAssumeBase64: - ctrl.autodetect_encoding = 0; - ctrl.is_pem = 0; - ctrl.is_base64 = 1; - break; - case oAssumeBinary: - ctrl.autodetect_encoding = 0; - ctrl.is_pem = 0; - ctrl.is_base64 = 0; - break; - - case oDisableCRLChecks: - opt.no_crl_check = 1; - break; - case oEnableCRLChecks: - opt.no_crl_check = 0; - break; - - case oIncludeCerts: ctrl.include_certs = pargs.r.ret_int; break; - - case oPolicyFile: - xfree (opt.policy_file); - if (*pargs.r.ret_str) - opt.policy_file = xstrdup (pargs.r.ret_str); - else - opt.policy_file = NULL; - break; - - case oDisablePolicyChecks: - opt.no_policy_check = 1; - break; - case oEnablePolicyChecks: - opt.no_policy_check = 0; - break; - - case oAutoIssuerKeyRetrieve: - opt.auto_issuer_key_retrieve = 1; - break; - - case oOutput: opt.outfile = pargs.r.ret_str; break; - - - case oQuiet: opt.quiet = 1; break; - case oNoTTY: /* fixme:tty_no_terminal(1);*/ break; - case oDryRun: opt.dry_run = 1; break; - - case oVerbose: - opt.verbose++; - gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose); - break; - case oNoVerbose: - opt.verbose = 0; - gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose); - break; - - case oLogFile: logfile = pargs.r.ret_str; break; - - case oBatch: - opt.batch = 1; - greeting = 0; - break; - case oNoBatch: opt.batch = 0; 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 oDebug: opt.debug |= pargs.r.ret_ulong; break; - case oDebugAll: opt.debug = ~0; break; - case oDebugWait: debug_wait = pargs.r.ret_int; break; - case oDebugNoChainValidation: opt.no_chain_validation = 1; break; - - case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break; - case oLoggerFD: log_set_fd (pargs.r.ret_int ); break; - case oWithFingerprint: - with_fpr=1; /*fall thru*/ - case oFingerprint: - opt.fingerprint++; - 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 oNoOptions: break; /* no-options */ - case oHomedir: opt.homedir = pargs.r.ret_str; break; - case oAgentProgram: opt.agent_program = pargs.r.ret_str; break; - case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break; - case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break; - case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break; - case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break; - case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break; - case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break; - - case oFakedSystemTime: - gnupg_set_time ( (time_t)pargs.r.ret_ulong, 0); - break; - - case oNoDefKeyring: default_keyring = 0; break; - case oNoGreeting: nogreeting = 1; break; - - case oDefaultKey: - /* fixme:opt.def_secret_key = pargs.r.ret_str;*/ - break; - case oDefRecipient: - if (*pargs.r.ret_str) - opt.def_recipient = xstrdup (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 oWithKeyData: opt.with_key_data=1; /* fall thru */ - case oWithColons: ctrl.with_colons = 1; break; - - case oSkipVerify: opt.skip_verify=1; break; - - case oNoEncryptTo: /*fixme: opt.no_encrypt_to = 1;*/ break; - case oEncryptTo: /* store the recipient in the second list */ - sl = add_to_strlist (&remusr, pargs.r.ret_str); - sl->flags = 1; - break; - - case oRecipient: /* store the recipient */ - add_to_strlist ( &remusr, pargs.r.ret_str); - break; - - case oTextmodeShort: /*fixme:opt.textmode = 2;*/ break; - case oTextmode: /*fixme:opt.textmode=1;*/ break; - - case oUser: /* store the local users, the first one is the default */ - if (!opt.local_user) - opt.local_user = pargs.r.ret_str; - add_to_strlist (&locusr, pargs.r.ret_str); - break; - - case oNoSecmemWarn: - gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); - break; - - case oCipherAlgo: - opt.def_cipher_algoid = pargs.r.ret_str; - 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 oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break; - case oNoRandomSeedFile: use_random_seed = 0; break; - - case oEnableSpecialFilenames: allow_special_filenames =1; break; - - - case aDummy: - break; - default: - pargs.err = configfp? 1:2; - break; - } - } - - if (configfp) - { - fclose (configfp); - configfp = NULL; - xfree (configname); - configname = NULL; - goto next_pass; - } - - xfree (configname); - configname = NULL; - - if (log_get_errorcount(0)) - gpgsm_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 - - if (may_coredump && !opt.quiet) - log_info (_("WARNING: program may create a core file!\n")); - - if (logfile && cmd == aServer) - { - log_set_file (logfile); - log_set_prefix (NULL, 1|2|4); - } - - if (gnupg_faked_time_p ()) - { - log_info (_("WARNING: running with faked system time: ")); - gpgsm_dump_time (gnupg_get_time ()); - log_printf ("\n"); - } - -/*FIXME if (opt.batch) */ -/* tty_batchmode (1); */ - - gcry_control (GCRYCTL_RESUME_SECMEM_WARN); - - set_debug (); - - /* FIXME: should set filenames of libgcrypt explicitly - * gpg_opt_homedir = opt.homedir; */ - - /* must do this after dropping setuid, because the mapping functions - may try to load an module and we may have disabled an algorithm */ - if ( !gcry_cipher_map_name (opt.def_cipher_algoid) - || !gcry_cipher_mode_from_oid (opt.def_cipher_algoid)) - 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 (our_md_test_algo(opt.def_digest_algo) ) - log_error (_("selected digest algorithm is invalid\n")); - } - - if (log_get_errorcount(0)) - gpgsm_exit(2); - - /* set the random seed file */ - if (use_random_seed) { - char *p = make_filename (opt.homedir, "random_seed", NULL); -#if 0 -#warning set_random_seed_file not yet available in Libgcrypt - set_random_seed_file(p); -#endif - xfree(p); - } - - - if (!cmd && opt.fingerprint && !with_fpr) - set_cmd (&cmd, aListKeys); - - if (!nrings && default_keyring) /* add default keybox */ - keydb_add_resource ("pubring.kbx", 0, 0); - for (sl = nrings; sl; sl = sl->next) - keydb_add_resource (sl->d, 0, 0); - FREE_STRLIST(nrings); - - - for (sl = locusr; sl; sl = sl->next) - { - int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 1, &signerlist); - if (rc) - { - log_error (_("can't sign using `%s': %s\n"), - sl->d, gnupg_strerror (rc)); - gpgsm_status2 (&ctrl, STATUS_INV_RECP, - rc == -1? "1": - rc == GNUPG_No_Public_Key? "1": - rc == GNUPG_Ambiguous_Name? "2": - rc == GNUPG_Wrong_Key_Usage? "3": - rc == GNUPG_Certificate_Revoked? "4": - rc == GNUPG_Certificate_Expired? "5": - rc == GNUPG_No_CRL_Known? "6": - rc == GNUPG_CRL_Too_Old? "7": - rc == GNUPG_No_Policy_Match? "8": - rc == GNUPG_No_Secret_Key? "9": - "0", - sl->d, NULL); - } - } - for (sl = remusr; sl; sl = sl->next) - { - int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 0, &recplist); - if (rc) - { - log_error (_("can't encrypt to `%s': %s\n"), - sl->d, gnupg_strerror (rc)); - gpgsm_status2 (&ctrl, STATUS_INV_RECP, - rc == -1? "1": - rc == GNUPG_No_Public_Key? "1": - rc == GNUPG_Ambiguous_Name? "2": - rc == GNUPG_Wrong_Key_Usage? "3": - rc == GNUPG_Certificate_Revoked? "4": - rc == GNUPG_Certificate_Expired? "5": - rc == GNUPG_No_CRL_Known? "6": - rc == GNUPG_CRL_Too_Old? "7": - rc == GNUPG_No_Policy_Match? "8": - "0", - sl->d, NULL); - } - } - if (log_get_errorcount(0)) - gpgsm_exit(1); /* must stop for invalid recipients */ - - - - fname = argc? *argv : NULL; - - switch (cmd) - { - case aServer: - if (debug_wait) - { - log_debug ("waiting for debugger - my pid is %u .....\n", - (unsigned int)getpid()); - sleep (debug_wait); - log_debug ("... okay\n"); - } - gpgsm_server (); - break; - - case aEncr: /* encrypt the given file */ - if (!argc) - gpgsm_encrypt (&ctrl, recplist, 0, stdout); /* from stdin */ - else if (argc == 1) - gpgsm_encrypt (&ctrl, recplist, open_read (*argv), stdout); /* from file */ - else - wrong_args (_("--encrypt [datafile]")); - break; - - case aSign: /* sign the given file */ - /* FIXME: We don't handle --output yet. We should also allow - to concatenate multiple files for signing because that is - what gpg does.*/ - if (!argc) - gpgsm_sign (&ctrl, signerlist, - 0, detached_sig, stdout); /* create from stdin */ - else if (argc == 1) - gpgsm_sign (&ctrl, signerlist, - open_read (*argv), detached_sig, stdout); /* from file */ - else - wrong_args (_("--sign [datafile]")); - break; - - case aSignEncr: /* sign and encrypt the given file */ - log_error ("this command has not yet been implemented\n"); - break; - - case aClearsign: /* make a clearsig */ - log_error ("this command has not yet been implemented\n"); - break; - - case aVerify: - { - FILE *fp = NULL; - - if (argc == 2 && opt.outfile) - log_info ("option --output ignored for a detached signature\n"); - else if (opt.outfile) - fp = open_fwrite (opt.outfile); - - if (!argc) - gpgsm_verify (&ctrl, 0, -1, fp); /* normal signature from stdin */ - else if (argc == 1) - gpgsm_verify (&ctrl, open_read (*argv), -1, fp); /* std signature */ - else if (argc == 2) /* detached signature (sig, detached) */ - gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1]), NULL); - else - wrong_args (_("--verify [signature [detached_data]]")); - - if (fp && fp != stdout) - fclose (fp); - } - break; - - case aVerifyFiles: - log_error ("this command has not yet been implemented\n"); - break; - - case aDecrypt: - if (!argc) - gpgsm_decrypt (&ctrl, 0, stdout); /* from stdin */ - else if (argc == 1) - gpgsm_decrypt (&ctrl, open_read (*argv), stdout); /* from file */ - else - wrong_args (_("--decrypt [filename]")); - break; - - case aDeleteKey: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_delete (&ctrl, sl); - free_strlist(sl); - break; - - case aListSigs: - ctrl.with_chain = 1; - case aListKeys: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<6))); - free_strlist(sl); - break; - - case aListExternalKeys: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<7))); - free_strlist(sl); - break; - - case aListSecretKeys: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_list_keys (&ctrl, sl, stdout, (2 | (1<<6))); - free_strlist(sl); - break; - - case aKeygen: /* generate a key */ - log_error ("this function is not yet available from the commandline\n"); - break; - - case aImport: - gpgsm_import_files (&ctrl, argc, argv, open_read); - break; - - case aExport: - for (sl=NULL; argc; argc--, argv++) - add_to_strlist (&sl, *argv); - gpgsm_export (&ctrl, sl, stdout); - free_strlist(sl); - break; - - - case aSendKeys: - case aRecvKeys: - log_error ("this command has not yet been implemented\n"); - break; - - - case aLearnCard: - if (argc) - wrong_args ("--learn-card"); - else - { - int rc = gpgsm_agent_learn (); - if (rc) - log_error ("error learning card: %s\n", gnupg_strerror (rc)); - } - break; - - - default: - log_error ("invalid command (there is no implicit command)\n"); - break; - } - - /* cleanup */ - gpgsm_release_certlist (recplist); - gpgsm_release_certlist (signerlist); - FREE_STRLIST(remusr); - FREE_STRLIST(locusr); - gpgsm_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 -gpgsm_exit (int rc) -{ - #if 0 -#warning no update_random_seed_file - update_random_seed_file(); - #endif -#if 0 - /* at this time a bit annoying */ - 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 ); -#endif - emergency_cleanup (); - rc = rc? rc : log_get_errorcount(0)? 2 : gpgsm_errors_seen? 1 : 0; - exit (rc); -} - - -void -gpgsm_init_default_ctrl (struct server_control_s *ctrl) -{ - ctrl->include_certs = 1; /* only include the signer's cert */ -} - - - -/* Check whether the filename has the form "-&nnnn", where n is a - non-zero number. Returns this number or -1 if it is not the case. */ -static int -check_special_filename (const char *fname) -{ - if (allow_special_filenames - && fname && *fname == '-' && fname[1] == '&' ) { - int i; - - fname += 2; - for (i=0; isdigit (fname[i]); i++ ) - ; - if ( !fname[i] ) - return atoi (fname); - } - return -1; -} - - - -/* Open the FILENAME for read and return the filedescriptor. Stop - with an error message in case of problems. "-" denotes stdin and - if special filenames are allowed the given fd is opened instead. */ -static int -open_read (const char *filename) -{ - int fd; - - if (filename[0] == '-' && !filename[1]) - return 0; /* stdin */ - fd = check_special_filename (filename); - if (fd != -1) - return fd; - fd = open (filename, O_RDONLY); - if (fd == -1) - { - log_error (_("can't open `%s': %s\n"), filename, strerror (errno)); - gpgsm_exit (2); - } - return fd; -} - -/* Open FILENAME for fwrite and return the stream. Stop with an error - message in case of problems. "-" denotes stdout and if special - filenames are allowed the given fd is opened instead. Caller must - close the returned stream unless it is stdout. */ -static FILE * -open_fwrite (const char *filename) -{ - int fd; - FILE *fp; - - if (filename[0] == '-' && !filename[1]) - return stdout; - - fd = check_special_filename (filename); - if (fd != -1) - { - fp = fdopen (dup (fd), "wb"); - if (!fp) - { - log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno)); - gpgsm_exit (2); - } - return fp; - } - fp = fopen (filename, "wb"); - if (!fp) - { - log_error (_("can't open `%s': %s\n"), filename, strerror (errno)); - gpgsm_exit (2); - } - return fp; -} diff --git a/sm/gpgsm.h b/sm/gpgsm.h deleted file mode 100644 index 50590206e..000000000 --- a/sm/gpgsm.h +++ /dev/null @@ -1,261 +0,0 @@ -/* gpgsm.h - Global definitions for GpgSM - * 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 GPGSM_H -#define GPGSM_H - -#include -#include "../common/util.h" -#include "../common/errors.h" - -#define MAX_DIGEST_LEN 24 - -/* A large struct name "opt" to keep global flags */ -struct { - unsigned int debug; /* debug flags (DBG_foo_VALUE) */ - int verbose; /* verbosity level */ - int quiet; /* be as quiet as possible */ - int batch; /* run in batch mode, i.e w/o any user interaction */ - int answer_yes; /* assume yes on most questions */ - int answer_no; /* assume no on most questions */ - int dry_run; /* don't change any persistent data */ - - const char *homedir; /* configuration directory name */ - const char *agent_program; - char *display; - char *ttyname; - char *ttytype; - char *lc_ctype; - char *lc_messages; - - const char *dirmngr_program; - char *outfile; /* name of output file */ - - int with_key_data;/* include raw key in the column delimted output */ - - int fingerprint; /* list fingerprints in all key listings */ - - int armor; /* force base64 armoring (see also ctrl.with_base64) */ - int no_armor; /* don't try to figure out whether data is base64 armored*/ - - const char *def_cipher_algoid; /* cipher algorithm to use if - nothing else is specified */ - - int def_digest_algo; /* Ditto for hash algorithm */ - int def_compress_algo; /* Ditto for compress algorithm */ - - char *def_recipient; /* userID of the default recipient */ - int def_recipient_self; /* The default recipient is the default key */ - - char *local_user; /* NULL or argument to -u */ - - int always_trust; /* Trust the given keys even if there is no - valid certification chain */ - int skip_verify; /* do not check signatures on data */ - - int lock_once; /* Keep lock once they are set */ - - int ignore_time_conflict; /* Ignore certain time conflicts */ - - int no_crl_check; /* Don't do a CRL check */ - - char *policy_file; /* full pathname of policy file */ - int no_policy_check; /* ignore certificate policies */ - int no_chain_validation; /* Bypass all cert chain validity tests */ - - int auto_issuer_key_retrieve; /* try to retrieve a missing issuer key. */ -} opt; - - -#define DBG_X509_VALUE 1 /* debug x.509 data reading/writing */ -#define DBG_MPI_VALUE 2 /* debug mpi details */ -#define DBG_CRYPTO_VALUE 4 /* debug low level crypto */ -#define DBG_MEMORY_VALUE 32 /* debug memory allocation stuff */ -#define DBG_CACHE_VALUE 64 /* debug the caching */ -#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */ -#define DBG_HASHING_VALUE 512 /* debug hashing operations */ -#define DBG_ASSUAN_VALUE 1024 /* debug assuan communication */ - -#define DBG_X509 (opt.debug & DBG_X509_VALUE) -#define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE) -#define DBG_MEMORY (opt.debug & DBG_MEMORY_VALUE) -#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE) -#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE) -#define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE) - -struct server_local_s; - -/* Note that the default values for this are set by - gpgsm_init_default_ctrl() */ -struct server_control_s { - int no_server; /* we are not running under server control */ - int status_fd; /* only for non-server mode */ - struct server_local_s *server_local; - int with_colons; /* use column delimited output format */ - int with_chain; /* include the certifying certs in a listing */ - - int autodetect_encoding; /* try to detect the input encoding */ - int is_pem; /* Is in PEM format */ - int is_base64; /* is in plain base-64 format */ - - int create_base64; /* Create base64 encoded output */ - int create_pem; /* create PEM output */ - const char *pem_name; /* PEM name to use */ - - int include_certs; /* -1 to send all certificates in the chain - along with a signature or the number of - certificates up the chain (0 = none, 1 = only - signer) */ -}; -typedef struct server_control_s *CTRL; - -/* data structure used in base64.c */ -typedef struct base64_context_s *Base64Context; - - -struct certlist_s { - struct certlist_s *next; - KsbaCert cert; -}; -typedef struct certlist_s *CERTLIST; - -/*-- gpgsm.c --*/ -void gpgsm_exit (int rc); -void gpgsm_init_default_ctrl (struct server_control_s *ctrl); - -/*-- server.c --*/ -void gpgsm_server (void); -void gpgsm_status (CTRL ctrl, int no, const char *text); -void gpgsm_status2 (CTRL ctrl, int no, ...); - -/*-- fingerprint --*/ -char *gpgsm_get_fingerprint (KsbaCert cert, int algo, char *array, int *r_len); -char *gpgsm_get_fingerprint_string (KsbaCert cert, int algo); -char *gpgsm_get_fingerprint_hexstring (KsbaCert cert, int algo); -unsigned long gpgsm_get_short_fingerprint (KsbaCert cert); -char *gpgsm_get_keygrip (KsbaCert cert, char *array); -char *gpgsm_get_keygrip_hexstring (KsbaCert cert); -char *gpgsm_get_certid (KsbaCert cert); - - -/*-- base64.c --*/ -int gpgsm_create_reader (Base64Context *ctx, - CTRL ctrl, FILE *fp, KsbaReader *r_reader); -void gpgsm_destroy_reader (Base64Context ctx); -int gpgsm_create_writer (Base64Context *ctx, - CTRL ctrl, FILE *fp, KsbaWriter *r_writer); -int gpgsm_finish_writer (Base64Context ctx); -void gpgsm_destroy_writer (Base64Context ctx); - - -/*-- certdump.c --*/ -void gpgsm_print_serial (FILE *fp, KsbaConstSexp p); -void gpgsm_print_time (FILE *fp, time_t t); -void gpgsm_print_name (FILE *fp, const char *string); - -void gpgsm_dump_cert (const char *text, KsbaCert cert); -void gpgsm_dump_serial (KsbaConstSexp p); -void gpgsm_dump_time (time_t t); -void gpgsm_dump_string (const char *string); - - - -/*-- certcheck.c --*/ -int gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert); -int gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval, - GCRY_MD_HD md, int hash_algo); -/* fixme: move create functions to another file */ -int gpgsm_create_cms_signature (KsbaCert cert, GCRY_MD_HD md, int mdalgo, - char **r_sigval); - - -/*-- certchain.c --*/ -int gpgsm_walk_cert_chain (KsbaCert start, KsbaCert *r_next); -int gpgsm_is_root_cert (KsbaCert cert); -int gpgsm_validate_chain (CTRL ctrl, KsbaCert cert, time_t *r_exptime); -int gpgsm_basic_cert_check (KsbaCert cert); - -/*-- certlist.c --*/ -int gpgsm_cert_use_sign_p (KsbaCert cert); -int gpgsm_cert_use_encrypt_p (KsbaCert cert); -int gpgsm_cert_use_verify_p (KsbaCert cert); -int gpgsm_cert_use_decrypt_p (KsbaCert cert); -int gpgsm_cert_use_cert_p (KsbaCert cert); -int gpgsm_add_to_certlist (CTRL ctrl, const char *name, int secret, - CERTLIST *listaddr); -void gpgsm_release_certlist (CERTLIST list); -int gpgsm_find_cert (const char *name, KsbaCert *r_cert); - -/*-- keylist.c --*/ -void gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode); - -/*-- import.c --*/ -int gpgsm_import (CTRL ctrl, int in_fd); -int gpgsm_import_files (CTRL ctrl, int nfiles, char **files, - int (*of)(const char *fname)); - -/*-- export.c --*/ -void gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp); - -/*-- delete.c --*/ -int gpgsm_delete (CTRL ctrl, STRLIST names); - -/*-- verify.c --*/ -int gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp); - -/*-- sign.c --*/ -int gpgsm_get_default_cert (KsbaCert *r_cert); -int gpgsm_sign (CTRL ctrl, CERTLIST signerlist, - int data_fd, int detached, FILE *out_fp); - -/*-- encrypt.c --*/ -int gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int in_fd, FILE *out_fp); - -/*-- decrypt.c --*/ -int gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp); - -/*-- certreqgen.c --*/ -int gpgsm_genkey (CTRL ctrl, int in_fd, FILE *out_fp); - -/*-- call-agent.c --*/ -int gpgsm_agent_pksign (const char *keygrip, - unsigned char *digest, - size_t digestlen, - int digestalgo, - char **r_buf, size_t *r_buflen); -int gpgsm_agent_pkdecrypt (const char *keygrip, - KsbaConstSexp ciphertext, - char **r_buf, size_t *r_buflen); -int gpgsm_agent_genkey (KsbaConstSexp keyparms, KsbaSexp *r_pubkey); -int gpgsm_agent_istrusted (KsbaCert cert); -int gpgsm_agent_havekey (const char *hexkeygrip); -int gpgsm_agent_marktrusted (KsbaCert cert); -int gpgsm_agent_learn (void); - -/*-- call-dirmngr.c --*/ -int gpgsm_dirmngr_isvalid (KsbaCert cert); -int gpgsm_dirmngr_lookup (CTRL ctrl, STRLIST names, - void (*cb)(void*, KsbaCert), void *cb_value); - - - - - -#endif /*GPGSM_H*/ diff --git a/sm/import.c b/sm/import.c deleted file mode 100644 index 2fc6b1a79..000000000 --- a/sm/import.c +++ /dev/null @@ -1,349 +0,0 @@ -/* import.c - Import certificates - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gpgsm.h" -#include "keydb.h" -#include "i18n.h" - -struct stats_s { - unsigned long count; - unsigned long imported; - unsigned long unchanged; - unsigned long not_imported; -}; - - - -static void -print_imported_status (CTRL ctrl, KsbaCert cert) -{ - char *fpr; - - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - gpgsm_status2 (ctrl, STATUS_IMPORTED, fpr, "[X.509]", NULL); - xfree (fpr); -} - - -/* Print an IMPORT_PROBLEM status. REASON is one of: - 0 := "No specific reason given". - 1 := "Invalid Certificate". - 2 := "Issuer Certificate missing". - 3 := "Certificate Chain too long". - 4 := "Error storing certificate". -*/ -static void -print_import_problem (CTRL ctrl, KsbaCert cert, int reason) -{ - char *fpr = NULL; - char buf[25]; - int i; - - sprintf (buf, "%d", reason); - if (cert) - { - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - /* detetect an error (all high) value */ - for (i=0; fpr[i] == 'F'; i++) - ; - if (!fpr[i]) - { - xfree (fpr); - fpr = NULL; - } - } - gpgsm_status2 (ctrl, STATUS_IMPORT_PROBLEM, buf, fpr, NULL); - xfree (fpr); -} - - -void -print_imported_summary (CTRL ctrl, struct stats_s *stats) -{ - char buf[14*25]; - - if (!opt.quiet) - { - log_info (_("total number processed: %lu\n"), stats->count); - if (stats->imported) - { - log_info (_(" imported: %lu"), stats->imported ); - log_printf ("\n"); - } - if (stats->unchanged) - log_info (_(" unchanged: %lu\n"), stats->unchanged); - if (stats->not_imported) - log_info (_(" not imported: %lu\n"), stats->not_imported); - } - - sprintf (buf, "%lu 0 %lu 0 %lu 0 0 0 0 0 0 0 0 %lu", - stats->count, - stats->imported, - stats->unchanged, - stats->not_imported - ); - gpgsm_status (ctrl, STATUS_IMPORT_RES, buf); -} - - - -static void -check_and_store (CTRL ctrl, struct stats_s *stats, KsbaCert cert, int depth) -{ - int rc; - - stats->count++; - if ( depth >= 50 ) - { - log_error (_("certificate chain too long\n")); - stats->not_imported++; - print_import_problem (ctrl, cert, 3); - return; - } - - rc = gpgsm_basic_cert_check (cert); - if (!rc) - { - int existed; - - if (!keydb_store_cert (cert, 0, &existed)) - { - KsbaCert next = NULL; - - if (!existed) - { - print_imported_status (ctrl, cert); - stats->imported++; - } - else - stats->unchanged++; - - if (opt.verbose > 1 && existed) - { - if (depth) - log_info ("issuer certificate already in DB\n"); - else - log_info ("certificate already in DB\n"); - } - else if (opt.verbose && !existed) - { - if (depth) - log_info ("issuer certificate imported\n"); - else - log_info ("certificate imported\n"); - } - /* Now lets walk up the chain and import all certificates up - the chain.*/ - else if (!gpgsm_walk_cert_chain (cert, &next)) - { - check_and_store (ctrl, stats, next, depth+1); - ksba_cert_release (next); - } - } - else - { - log_error (_("error storing certificate\n")); - stats->not_imported++; - print_import_problem (ctrl, cert, 4); - } - } - else - { - log_error (_("basic certificate checks failed - not imported\n")); - stats->not_imported++; - print_import_problem (ctrl, cert, - rc == GNUPG_Missing_Certificate? 2 : - rc == GNUPG_Bad_Certificate? 1 : 0); - } -} - - - - -static int -import_one (CTRL ctrl, struct stats_s *stats, int in_fd) -{ - int rc; - Base64Context b64reader = NULL; - KsbaReader reader; - KsbaCert cert = NULL; - KsbaCMS cms = NULL; - FILE *fp = NULL; - KsbaContentType ct; - - fp = fdopen ( dup (in_fd), "rb"); - if (!fp) - { - log_error ("fdopen() failed: %s\n", strerror (errno)); - rc = seterr (IO_Error); - goto leave; - } - - rc = gpgsm_create_reader (&b64reader, ctrl, fp, &reader); - if (rc) - { - log_error ("can't create reader: %s\n", gnupg_strerror (rc)); - goto leave; - } - - ct = ksba_cms_identify (reader); - if (ct == KSBA_CT_SIGNED_DATA) - { /* This is probably a signed-only message - import the certs */ - KsbaStopReason stopreason; - int i; - - cms = ksba_cms_new (); - if (!cms) - { - rc = seterr (Out_Of_Core); - goto leave; - } - - rc = ksba_cms_set_reader_writer (cms, reader, NULL); - if (rc) - { - log_error ("ksba_cms_set_reader_writer failed: %s\n", - ksba_strerror (rc)); - rc = map_ksba_err (rc); - goto leave; - } - - - do - { - rc = ksba_cms_parse (cms, &stopreason); - if (rc) - { - log_error ("ksba_cms_parse failed: %s\n", ksba_strerror (rc)); - rc = map_ksba_err (rc); - goto leave; - } - - if (stopreason == KSBA_SR_BEGIN_DATA) - log_info ("not a certs-only message\n"); - } - while (stopreason != KSBA_SR_READY); - - for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++) - { - check_and_store (ctrl, stats, cert, 0); - ksba_cert_release (cert); - cert = NULL; - } - if (!i) - log_error ("no certificate found\n"); - } - else if (ct == KSBA_CT_NONE) - { /* Failed to identify this message - assume a certificate */ - - cert = ksba_cert_new (); - if (!cert) - { - rc = seterr (Out_Of_Core); - goto leave; - } - - rc = ksba_cert_read_der (cert, reader); - if (rc) - { - rc = map_ksba_err (rc); - goto leave; - } - - check_and_store (ctrl, stats, cert, 0); - } - else - { - log_error ("can't extract certificates from input\n"); - rc = GNUPG_No_Data; - } - - leave: - ksba_cms_release (cms); - ksba_cert_release (cert); - gpgsm_destroy_reader (b64reader); - if (fp) - fclose (fp); - return rc; -} - - -int -gpgsm_import (CTRL ctrl, int in_fd) -{ - int rc; - struct stats_s stats; - - memset (&stats, 0, sizeof stats); - rc = import_one (ctrl, &stats, in_fd); - print_imported_summary (ctrl, &stats); - /* If we never printed an error message do it now so that a command - line invocation will return with an error (log_error keeps a - global errorcount) */ - if (rc && !log_get_errorcount (0)) - log_error (_("error importing certificate: %s\n"), gnupg_strerror (rc)); - return rc; -} - - -int -gpgsm_import_files (CTRL ctrl, int nfiles, char **files, - int (*of)(const char *fname)) -{ - int rc = 0; - struct stats_s stats; - - memset (&stats, 0, sizeof stats); - - if (!nfiles) - rc = import_one (ctrl, &stats, 0); - else - { - for (; nfiles && !rc ; nfiles--, files++) - { - int fd = of (*files); - rc = import_one (ctrl, &stats, fd); - close (fd); - if (rc == -1) - rc = 0; - } - } - print_imported_summary (ctrl, &stats); - /* If we never printed an error message do it now so that a command - line invocation will return with an error (log_error keeps a - global errorcount) */ - if (rc && !log_get_errorcount (0)) - log_error (_("error importing certificate: %s\n"), gnupg_strerror (rc)); - return rc; -} - - diff --git a/sm/keydb.c b/sm/keydb.c deleted file mode 100644 index 5b5722d3e..000000000 --- a/sm/keydb.c +++ /dev/null @@ -1,1282 +0,0 @@ -/* keydb.c - key database dispatcher - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gpgsm.h" -#include "../kbx/keybox.h" -#include "keydb.h" -#include "i18n.h" - -#define DIRSEP_C '/' - -static int active_handles; - -typedef enum { - KEYDB_RESOURCE_TYPE_NONE = 0, - KEYDB_RESOURCE_TYPE_KEYBOX -} KeydbResourceType; -#define MAX_KEYDB_RESOURCES 20 - -struct resource_item { - KeydbResourceType type; - union { - KEYBOX_HANDLE kr; - } u; - void *token; - int secret; - DOTLOCK lockhandle; -}; - -static struct resource_item all_resources[MAX_KEYDB_RESOURCES]; -static int used_resources; - -struct keydb_handle { - int locked; - int found; - int current; - int is_ephemeral; - 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 keybox file). - * The first keybox which is added by this function is - * created if it does not exist. - * Note: this function may be called before secure memory is - * available. - */ -int -keydb_add_resource (const char *url, int force, int secret) -{ - static int any_secret, any_public; - const char *resname = url; - char *filename = NULL; - int rc = 0; - FILE *fp; - KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; - const char *created_fname = NULL; - - /* Do we have an URL? - gnupg-kbx:filename := this is a plain keybox - filename := See what is is, but create as plain keybox. - */ - if (strlen (resname) > 10) - { - if (!strncmp (resname, "gnupg-kbx:", 10) ) - { - rt = KEYDB_RESOURCE_TYPE_KEYBOX; - resname += 10; - } -#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__) - else if (strchr (resname, ':')) - { - log_error ("invalid key resource URL `%s'\n", url ); - rc = GNUPG_General_Error; - 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 *fp2 = fopen( filename, "rb" ); - - if (fp2) { - u32 magic; - - /* FIXME: check for the keybox magic */ - if (fread( &magic, 4, 1, fp2) == 1 ) - { - if (magic == 0x13579ace || magic == 0xce9a5713) - ; /* GDBM magic - no more support */ - else - rt = KEYDB_RESOURCE_TYPE_KEYBOX; - } - else /* maybe empty: assume ring */ - rt = KEYDB_RESOURCE_TYPE_KEYBOX; - fclose (fp2); - } - else /* no file yet: create ring */ - rt = KEYDB_RESOURCE_TYPE_KEYBOX; - } - - switch (rt) - { - case KEYDB_RESOURCE_TYPE_NONE: - log_error ("unknown type of key resource `%s'\n", url ); - rc = GNUPG_General_Error; - goto leave; - - case KEYDB_RESOURCE_TYPE_KEYBOX: - fp = fopen (filename, "rb"); - if (!fp && !force) - { - rc = GNUPG_File_Open_Error; - goto leave; - } - - if (!fp) - { /* no file */ -#if 0 /* no autocreate of the homedirectory yet */ - { - char *last_slash_in_filename; - - 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 in this case the process will be - terminated, so that on the next invocation can - read the options file in on startup */ - try_make_homedir (filename); - rc = GNUPG_File_Open_Error; - *last_slash_in_filename = DIRSEP_C; - goto leave; - } - *last_slash_in_filename = DIRSEP_C; - } -#endif - fp = fopen (filename, "w"); - if (!fp) - { - log_error (_("error creating keybox `%s': %s\n"), - filename, strerror(errno)); - rc = GNUPG_File_Create_Error; - goto leave; - } - - if (!opt.quiet) - log_info (_("keybox `%s' created\n"), filename); - created_fname = filename; - } - fclose (fp); - fp = NULL; - /* now register the file */ - { - - void *token = keybox_register_file (filename, secret); - if (!token) - ; /* already registered - ignore it */ - else if (used_resources >= MAX_KEYDB_RESOURCES) - rc = GNUPG_Resource_Limit; - else - { - 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; - - all_resources[used_resources].lockhandle - = create_dotlock (filename); - if (!all_resources[used_resources].lockhandle) - log_fatal ( _("can't create lock for `%s'\n"), filename); - - used_resources++; - } - } - break; - default: - log_error ("resource type of `%s' not supported\n", url); - rc = GNUPG_Not_Supported; - goto leave; - } - - /* fixme: check directory permissions and print a warning */ - - leave: - if (rc) - log_error ("keyblock resource `%s': %s\n", filename, gnupg_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_KEYBOX: - 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].lockhandle = all_resources[i].lockhandle; - hd->active[j].u.kr = keybox_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_KEYBOX: - keybox_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_KEYBOX: - s = keybox_get_resource_name (hd->active[idx].u.kr); - break; - } - - return s? s: ""; -} - -/* Switch the handle into ephemeral mode and return the orginal value. */ -int -keydb_set_ephemeral (KEYDB_HANDLE hd, int yes) -{ - int i; - - if (!hd) - return 0; - - yes = !!yes; - if (hd->is_ephemeral != yes) - { - for (i=0; i < hd->used; i++) - { - switch (hd->active[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - keybox_set_ephemeral (hd->active[i].u.kr, yes); - break; - } - } - } - - i = hd->is_ephemeral; - hd->is_ephemeral = yes; - return i; -} - - - -static int -lock_all (KEYDB_HANDLE hd) -{ - int i, rc = 0; - - /* Fixme: This locking scheme may lead to deadlock if the resources - are not added in the same sequence by all processes. We are - cuurently only allowing one resource so it is not a problem. */ - for (i=0; i < hd->used; i++) - { - switch (hd->active[i].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - if (hd->active[i].lockhandle) - rc = make_dotlock (hd->active[i].lockhandle, -1); - break; - } - if (rc) - 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_KEYBOX: - if (hd->active[i].lockhandle) - release_dotlock (hd->active[i].lockhandle); - 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_KEYBOX: - if (hd->active[i].lockhandle) - release_dotlock (hd->active[i].lockhandle); - break; - } - } - hd->locked = 0; -} - - -#if 0 -/* - * Return the last found keybox. 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 G10ERR_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 = G10ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_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 G10ERR_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 = G10ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_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 G10ERR_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 G10ERR_GENERAL; - - rc = lock_all (hd); - if (rc) - return rc; - - switch (hd->active[idx].type) { - case KEYDB_RESOURCE_TYPE_NONE: - rc = G10ERR_GENERAL; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_insert_keyblock (hd->active[idx].u.kr, kb); - break; - } - - unlock_all (hd); - return rc; -} - -#endif /*disabled code*/ - - - -/* - Return the last found keybox. 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_cert (KEYDB_HANDLE hd, KsbaCert *r_cert) -{ - int rc = 0; - - if (!hd) - return GNUPG_Invalid_Value; - - if ( hd->found < 0 || hd->found >= hd->used) - return -1; /* nothing found */ - - switch (hd->active[hd->found].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - rc = GNUPG_General_Error; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_get_cert (hd->active[hd->found].u.kr, r_cert); - break; - } - - return rc; -} - -/* - * Insert a new Certificate into one of the resources. - */ -int -keydb_insert_cert (KEYDB_HANDLE hd, KsbaCert cert) -{ - int rc = -1; - int idx; - char digest[20]; - - if (!hd) - return GNUPG_Invalid_Value; - - 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 GNUPG_General_Error; - - rc = lock_all (hd); - if (rc) - return rc; - - gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/ - - switch (hd->active[idx].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - rc = GNUPG_General_Error; - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_insert_cert (hd->active[idx].u.kr, cert, digest); - break; - } - - unlock_all (hd); - return rc; -} - - - -/* update the current keyblock with KB */ -int -keydb_update_cert (KEYDB_HANDLE hd, KsbaCert cert) -{ - int rc = 0; - char digest[20]; - - if (!hd) - return GNUPG_Invalid_Value; - - 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; - - gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/ - - switch (hd->active[hd->found].type) - { - case KEYDB_RESOURCE_TYPE_NONE: - rc = GNUPG_General_Error; /* oops */ - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_update_cert (hd->active[hd->found].u.kr, cert, digest); - break; - } - - unlock_all (hd); - return rc; -} - - -/* - * The current keyblock or cert will be deleted. - */ -int -keydb_delete (KEYDB_HANDLE hd) -{ - int rc = -1; - - if (!hd) - return GNUPG_Invalid_Value; - - 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 = GNUPG_General_Error; - break; - case KEYDB_RESOURCE_TYPE_KEYBOX: - rc = keybox_delete (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 GNUPG_Invalid_Value; - - 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_KEYBOX: - if (keybox_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; - - 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_KEYBOX: -/* rc = keybox_rebuild_cache (all_resources[i].token); */ -/* if (rc) */ -/* log_error (_("failed to rebuild keybox cache: %s\n"), */ -/* g10_errstr (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 GNUPG_Invalid_Value; - - 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_KEYBOX: - rc = keybox_search_reset (hd->active[i].u.kr); - break; - } - } - return rc; /* fixme: we need to map error codes or share them with - all modules*/ -} - -/* - * 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_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc) -{ - int rc = -1; - - if (!hd) - return GNUPG_Invalid_Value; - - 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_KEYBOX: - rc = keybox_search (hd->active[hd->current].u.kr, desc, ndesc); - 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, 20); - return keydb_search (hd, &desc, 1); -} - -int -keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer) -{ - KEYDB_SEARCH_DESC desc; - int rc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_ISSUER; - desc.u.name = issuer; - rc = keydb_search (hd, &desc, 1); - return rc; -} - -int -keydb_search_issuer_sn (KEYDB_HANDLE hd, - const char *issuer, KsbaConstSexp serial) -{ - KEYDB_SEARCH_DESC desc; - int rc; - const unsigned char *s; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_ISSUER_SN; - s = serial; - if (*s !='(') - return GNUPG_Invalid_Value; - s++; - for (desc.snlen = 0; digitp (s); s++) - desc.snlen = 10*desc.snlen + atoi_1 (s); - if (*s !=':') - return GNUPG_Invalid_Value; - desc.sn = s+1; - desc.u.name = issuer; - rc = keydb_search (hd, &desc, 1); - return rc; -} - -int -keydb_search_subject (KEYDB_HANDLE hd, const char *name) -{ - KEYDB_SEARCH_DESC desc; - int rc; - - memset (&desc, 0, sizeof desc); - desc.mode = KEYDB_SEARCH_MODE_SUBJECT; - desc.u.name = name; - rc = keydb_search (hd, &desc, 1); - return rc; -} - - -static int -hextobyte (const unsigned 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; -} - - -static int -classify_user_id (const char *name, - KEYDB_SEARCH_DESC *desc, - int *force_exact ) -{ - const char *s; - int hexprefix = 0; - int hexlength; - int mode = 0; - - /* 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); - *force_exact = 0; - /* skip leading spaces. Fixme: what about trailing white space? */ - 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; - s++; - 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 '/': /* subject's DN */ - s++; - if (!*s || spacep (s)) - return 0; /* no DN or prefixed with a space */ - desc->u.name = s; - mode = KEYDB_SEARCH_MODE_SUBJECT; - break; - - case '#': - { - const char *si; - - s++; - if ( *s == '/') - { /* "#/" indicates an issuer's DN */ - s++; - if (!*s || spacep (s)) - return 0; /* no DN or prefixed with a space */ - desc->u.name = s; - mode = KEYDB_SEARCH_MODE_ISSUER; - } - else - { /* serialnumber + optional issuer ID */ - for (si=s; *si && *si != '/'; si++) - { - if (!strchr("01234567890abcdefABCDEF", *si)) - return 0; /* invalid digit in serial number*/ - } - desc->sn = s; - desc->snlen = -1; - if (!*si) - mode = KEYDB_SEARCH_MODE_SN; - else - { - s = si+1; - if (!*s || spacep (s)) - return 0; /* no DN or prefixed with a space */ - desc->u.name = s; - mode = KEYDB_SEARCH_MODE_ISSUER_SN; - } - } - } - break; - - 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] =='!') - { - *force_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 */ - /* The first chars looked like a hex number, but really is - not */ - hexlength = 0; - } - - if (*force_exact) - hexlength--; /* remove the bang */ - - if (hexlength == 8 - || (!hexprefix && hexlength == 9 && *s == '0')) - { /* short keyid */ - unsigned long kid; - if (hexlength == 9) - s++; - kid = strtoul( s, NULL, 16 ); - desc->u.kid[4] = kid >> 24; - desc->u.kid[5] = kid >> 16; - desc->u.kid[6] = kid >> 8; - desc->u.kid[7] = kid; - mode = KEYDB_SEARCH_MODE_SHORT_KID; - } - else if (hexlength == 16 - || (!hexprefix && hexlength == 17 && *s == '0')) - { /* complete keyid */ - unsigned long kid0, kid1; - char buf[9]; - if (hexlength == 17) - s++; - mem2str(buf, s, 9 ); - kid0 = strtoul (buf, NULL, 16); - kid1 = strtoul (s+8, NULL, 16); - desc->u.kid[0] = kid0 >> 24; - desc->u.kid[1] = kid0 >> 16; - desc->u.kid[2] = kid0 >> 8; - desc->u.kid[3] = kid0; - desc->u.kid[4] = kid1 >> 24; - desc->u.kid[5] = kid1 >> 16; - desc->u.kid[6] = kid1 >> 8; - desc->u.kid[7] = kid1; - 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) - { - /* The fingerprint in an X.509 listing is often delimited by - colons, so we try to single this case out. */ - mode = 0; - hexlength = strspn (s, ":0123456789abcdefABCDEF"); - if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength))) - { - int i; - - for (i=0; i < 20; i++, s += 3) - { - int c = hextobyte(s); - if (c == -1 || (i < 19 && s[2] != ':')) - break; - desc->u.fpr[i] = c; - } - if (i == 20) - mode = KEYDB_SEARCH_MODE_FPR20; - } - if (!mode) /* default is substring search */ - { - *force_exact = 0; - desc->u.name = s; - mode = KEYDB_SEARCH_MODE_SUBSTR; - } - } - else - { /* hex number with a prefix but a wrong length */ - return 0; - } - } - - desc->mode = mode; - return mode; -} - - -int -keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc) -{ - int dummy; - KEYDB_SEARCH_DESC dummy_desc; - - if (!desc) - desc = &dummy_desc; - - if (!classify_user_id (name, desc, &dummy)) - return GNUPG_Invalid_Name; - return 0; -} - - -/* Store the certificate in the key DB but make sure that it does not - already exists. We do this simply by comparing the fingerprint. - If EXISTED is not NULL it will be set to true if the certificate - was already in the DB. */ -int -keydb_store_cert (KsbaCert cert, int ephemeral, int *existed) -{ - KEYDB_HANDLE kh; - int rc; - unsigned char fpr[20]; - - if (existed) - *existed = 0; - - if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL)) - { - log_error (_("failed to get the fingerprint\n")); - return GNUPG_General_Error; - } - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocate keyDB handle\n")); - return GNUPG_Out_Of_Core; - } - - if (ephemeral) - keydb_set_ephemeral (kh, 1); - - rc = keydb_search_fpr (kh, fpr); - if (rc != -1) - { - keydb_release (kh); - if (!rc) - { - if (existed) - *existed = 1; - return 0; /* okay */ - } - log_error (_("problem looking for existing certificate: %s\n"), - gnupg_strerror (rc)); - return rc; - } - - rc = keydb_locate_writable (kh, 0); - if (rc) - { - log_error (_("error finding writable keyDB: %s\n"), gnupg_strerror (rc)); - keydb_release (kh); - return rc; - } - - rc = keydb_insert_cert (kh, cert); - if (rc) - { - log_error (_("error storing certificate: %s\n"), gnupg_strerror (rc)); - keydb_release (kh); - return rc; - } - keydb_release (kh); - return 0; -} - - - diff --git a/sm/keydb.h b/sm/keydb.h deleted file mode 100644 index ad7eaf51d..000000000 --- a/sm/keydb.h +++ /dev/null @@ -1,73 +0,0 @@ -/* keydb.h - Key database - * 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 GNUPG_KEYDB_H -#define GNUPG_KEYDB_H - -#include - -#include "../kbx/keybox-search-desc.h" - -typedef struct keydb_handle *KEYDB_HANDLE; - - -/*-- keydb.c --*/ -int keydb_add_resource (const char *url, int force, int secret); -KEYDB_HANDLE keydb_new (int secret); -void keydb_release (KEYDB_HANDLE hd); -int keydb_set_ephemeral (KEYDB_HANDLE hd, int yes); -const char *keydb_get_resource_name (KEYDB_HANDLE hd); - -#if 0 /* pgp stuff */ -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); -#endif - -int keydb_get_cert (KEYDB_HANDLE hd, KsbaCert *r_cert); -int keydb_insert_cert (KEYDB_HANDLE hd, KsbaCert cert); -int keydb_update_cert (KEYDB_HANDLE hd, KsbaCert cert); - -int keydb_delete (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); -int keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc); -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); -int keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer); -int keydb_search_issuer_sn (KEYDB_HANDLE hd, - const char *issuer, const unsigned char *serial); -int keydb_search_subject (KEYDB_HANDLE hd, const char *issuer); - -int keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc); - -int keydb_store_cert (KsbaCert cert, int ephemeral, int *existed); - - -#endif /*GNUPG_KEYDB_H*/ - - - - diff --git a/sm/keylist.c b/sm/keylist.c deleted file mode 100644 index 96a8469ba..000000000 --- a/sm/keylist.c +++ /dev/null @@ -1,616 +0,0 @@ -/* keylist.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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gpgsm.h" -#include "keydb.h" -#include "i18n.h" - -struct list_external_parm_s { - FILE *fp; - int print_header; - int with_colons; - int with_chain; -}; - - - -static void -print_key_data (KsbaCert cert, FILE *fp) -{ -#if 0 - int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0; - int i; - - for(i=0; i < n; i++ ) - { - fprintf (fp, "pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) ); - mpi_print(stdout, pk->pkey[i], 1 ); - putchar(':'); - putchar('\n'); - } -#endif -} - -static void -print_capabilities (KsbaCert cert, FILE *fp) -{ - KsbaError err; - unsigned int use; - - err = ksba_cert_get_key_usage (cert, &use); - if (err == KSBA_No_Data) - { - putc ('e', fp); - putc ('s', fp); - putc ('c', fp); - putc ('E', fp); - putc ('S', fp); - putc ('C', fp); - return; - } - if (err) - { - log_error (_("error getting key usage information: %s\n"), - ksba_strerror (err)); - return; - } - - if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT))) - putc ('e', fp); - if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION))) - putc ('s', fp); - if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN)) - putc ('c', fp); - if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT))) - putc ('E', fp); - if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION))) - putc ('S', fp); - if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN)) - putc ('C', fp); -} - - -static void -print_time (time_t t, FILE *fp) -{ - if (!t) - ; - else if ( t == (time_t)(-1) ) - putc ('?', fp); - else - fprintf (fp, "%lu", (unsigned long)t); -} - - -/* return an allocated string with the email address extracted from a - DN */ -static char * -email_kludge (const char *name) -{ - const unsigned char *p; - unsigned char *buf; - int n; - - if (strncmp (name, "1.2.840.113549.1.9.1=#", 22)) - return NULL; - /* This looks pretty much like an email address in the subject's DN - we use this to add an additional user ID entry. This way, - openSSL generated keys get a nicer and usable listing */ - name += 22; - for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++) - ; - if (*p != '#' || !n) - return NULL; - buf = xtrymalloc (n+3); - if (!buf) - return NULL; /* oops, out of core */ - *buf = '<'; - for (n=1, p=name; *p != '#'; p +=2, n++) - buf[n] = xtoi_2 (p); - buf[n++] = '>'; - buf[n] = 0; - return buf; -} - - - - -/* List one certificate in colon mode */ -static void -list_cert_colon (KsbaCert cert, FILE *fp, int have_secret) -{ - int idx, trustletter = 0; - char *p; - KsbaSexp sexp; - char *fpr; - - fputs (have_secret? "crs:":"crt:", fp); - trustletter = 0; -#if 0 - if (is_not_valid (cert)) - putc ('i', fp); - else if ( is_revoked (cert) ) - putc ('r', fp); - else if ( has_expired (cert)) - putcr ('e', fp); - else -#endif - { - trustletter = '?'; /*get_validity_info ( pk, NULL );*/ - putc (trustletter, fp); - } - - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - fprintf (fp, ":%u:%d:%s:", - /*keylen_of_cert (cert)*/1024, - /* pubkey_algo_of_cert (cert)*/1, - fpr+24); - - /* we assume --fixed-list-mode for gpgsm */ - print_time ( ksba_cert_get_validity (cert, 0), fp); - putc (':', fp); - print_time ( ksba_cert_get_validity (cert, 1), fp); - putc (':', fp); - /* field 8, serial number: */ - if ((sexp = ksba_cert_get_serial (cert))) - { - int len; - const unsigned char *s = sexp; - - if (*s == '(') - { - s++; - for (len=0; *s && *s != ':' && digitp (s); s++) - len = len*10 + atoi_1 (s); - if (*s == ':') - for (s++; len; len--, s++) - fprintf (fp,"%02X", *s); - } - xfree (sexp); - } - putc (':', fp); - /* field 9, ownertrust - not used here */ - putc (':', fp); - /* field 10, old user ID - we use it here for the issuer DN */ - if ((p = ksba_cert_get_issuer (cert,0))) - { - print_sanitized_string (fp, p, ':'); - xfree (p); - } - putc (':', fp); - /* field 11, signature class - not used */ - putc (':', fp); - /* field 12, capabilities: */ - print_capabilities (cert, fp); - putc (':', fp); - putc ('\n', fp); - - /* FPR record */ - fprintf (fp, "fpr:::::::::%s:::", fpr); - xfree (fpr); fpr = NULL; - /* print chaining ID (field 13)*/ - { - KsbaCert next; - - if (!gpgsm_walk_cert_chain (cert, &next)) - { - p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1); - fputs (p, fp); - xfree (p); - ksba_cert_release (next); - } - } - putc (':', fp); - putc ('\n', fp); - - - if (opt.with_key_data) - { - if ( (p = gpgsm_get_keygrip_hexstring (cert))) - { - fprintf (fp, "grp:::::::::%s:\n", p); - xfree (p); - } - print_key_data (cert, fp); - } - - for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++) - { - fprintf (fp, "uid:%c::::::::", trustletter); - print_sanitized_string (fp, p, ':'); - putc (':', fp); - putc (':', fp); - putc ('\n', fp); - if (!idx) - { - /* It would be better to get the faked email address from - the keydb. But as long as we don't have a way to pass - the meta data back, we just check it the same way as the - code used to create the keybox meta data does */ - char *pp = email_kludge (p); - if (pp) - { - fprintf (fp, "uid:%c::::::::", trustletter); - print_sanitized_string (fp, pp, ':'); - putc (':', fp); - putc (':', fp); - putc ('\n', fp); - xfree (pp); - } - } - xfree (p); - } -} - - -/* List one certificate in standard mode */ -static void -list_cert_std (KsbaCert cert, FILE *fp, int have_secret) -{ - KsbaError kerr; - KsbaSexp sexp; - char *dn; - time_t t; - int idx; - int is_ca, chainlen; - unsigned int kusage; - char *string, *p; - - sexp = ksba_cert_get_serial (cert); - fputs ("Serial number: ", fp); - gpgsm_print_serial (fp, sexp); - ksba_free (sexp); - putc ('\n', fp); - - dn = ksba_cert_get_issuer (cert, 0); - fputs (" Issuer: ", fp); - gpgsm_print_name (fp, dn); - ksba_free (dn); - putc ('\n', fp); - for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++) - { - fputs (" aka: ", fp); - gpgsm_print_name (fp, dn); - ksba_free (dn); - putc ('\n', fp); - } - - dn = ksba_cert_get_subject (cert, 0); - fputs (" Subject: ", fp); - gpgsm_print_name (fp, dn); - ksba_free (dn); - putc ('\n', fp); - for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++) - { - fputs (" aka: ", fp); - gpgsm_print_name (fp, dn); - ksba_free (dn); - putc ('\n', fp); - } - - t = ksba_cert_get_validity (cert, 0); - fputs (" validity: ", fp); - gpgsm_print_time (fp, t); - fputs (" through ", fp); - t = ksba_cert_get_validity (cert, 1); - gpgsm_print_time (fp, t); - putc ('\n', fp); - - kerr = ksba_cert_get_key_usage (cert, &kusage); - if (kerr != KSBA_No_Data) - { - fputs (" key usage:", fp); - if (kerr) - fprintf (fp, " [error: %s]", ksba_strerror (kerr)); - else - { - if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE)) - fputs (" digitalSignature", fp); - if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION)) - fputs (" nonRepudiation", fp); - if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) - fputs (" keyEncipherment", fp); - if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT)) - fputs (" dataEncipherment", fp); - if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT)) - fputs (" keyAgreement", fp); - if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN)) - fputs (" certSign", fp); - if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN)) - fputs (" crlSign", fp); - if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY)) - fputs (" encipherOnly", fp); - if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY)) - fputs (" decipherOnly", fp); - } - putc ('\n', fp); - } - - kerr = ksba_cert_get_cert_policies (cert, &string); - if (kerr != KSBA_No_Data) - { - fputs (" policies: ", fp); - if (kerr) - fprintf (fp, "[error: %s]", ksba_strerror (kerr)); - else - { - for (p=string; *p; p++) - { - if (*p == '\n') - *p = ','; - } - print_sanitized_string (fp, string, 0); - xfree (string); - } - putc ('\n', fp); - } - - kerr = ksba_cert_is_ca (cert, &is_ca, &chainlen); - if (kerr || is_ca) - { - fputs (" chain length: ", fp); - if (kerr) - fprintf (fp, "[error: %s]", ksba_strerror (kerr)); - else if (chainlen == -1) - fputs ("unlimited", fp); - else - fprintf (fp, "%d", chainlen); - putc ('\n', fp); - } - - - dn = gpgsm_get_fingerprint_string (cert, 0); - fprintf (fp, " fingerprint: %s\n", dn?dn:"error"); - xfree (dn); -} - -/* Same as standard mode mode list all certifying certts too */ -static void -list_cert_chain (KsbaCert cert, FILE *fp) -{ - KsbaCert next = NULL; - - list_cert_std (cert, fp, 0); - ksba_cert_ref (cert); - while (!gpgsm_walk_cert_chain (cert, &next)) - { - ksba_cert_release (cert); - fputs ("Certified by\n", fp); - list_cert_std (next, fp, 0); - cert = next; - } - ksba_cert_release (cert); - putc ('\n', fp); -} - - - -/* List all internal keys or just the key given as NAMES. - */ -static void -list_internal_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode) -{ - KEYDB_HANDLE hd; - KEYDB_SEARCH_DESC *desc = NULL; - STRLIST sl; - int ndesc; - KsbaCert cert = NULL; - int rc=0; - const char *lastresname, *resname; - int have_secret; - - hd = keydb_new (0); - if (!hd) - { - log_error ("keydb_new failed\n"); - goto leave; - } - - if (!names) - ndesc = 1; - else - { - for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) - ; - } - - desc = xtrycalloc (ndesc, sizeof *desc); - if (!ndesc) - { - log_error ("out of core\n"); - goto leave; - } - - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_FIRST; - else - { - for (ndesc=0, sl=names; sl; sl = sl->next) - { - rc = keydb_classify_name (sl->d, desc+ndesc); - if (rc) - { - log_error ("key `%s' not found: %s\n", - sl->d, gnupg_strerror (rc)); - rc = 0; - } - else - ndesc++; - } - - } - - /* 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 */ - - lastresname = NULL; - while (!(rc = keydb_search (hd, desc, ndesc))) - { - if (!names) - desc[0].mode = KEYDB_SEARCH_MODE_NEXT; - - rc = keydb_get_cert (hd, &cert); - if (rc) - { - log_error ("keydb_get_cert failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - - resname = keydb_get_resource_name (hd); - - if (lastresname != resname ) - { - int i; - - if (ctrl->no_server) - { - fprintf (fp, "%s\n", resname ); - for (i=strlen(resname); i; i-- ) - putchar('-'); - putc ('\n', fp); - lastresname = resname; - } - } - - have_secret = 0; - if (mode) - { - char *p = gpgsm_get_keygrip_hexstring (cert); - if (p) - { - if (!gpgsm_agent_havekey (p)) - have_secret = 1; - xfree (p); - } - } - - if (!mode - || ((mode & 1) && !have_secret) - || ((mode & 2) && have_secret) ) - { - if (ctrl->with_colons) - list_cert_colon (cert, fp, have_secret); - else if (ctrl->with_chain) - list_cert_chain (cert, fp); - else - { - list_cert_std (cert, fp, have_secret); - putc ('\n', fp); - } - } - ksba_cert_release (cert); - cert = NULL; - } - if (rc && rc != -1) - log_error ("keydb_search failed: %s\n", gnupg_strerror (rc)); - - leave: - ksba_cert_release (cert); - xfree (desc); - keydb_release (hd); -} - - - -static void -list_external_cb (void *cb_value, KsbaCert cert) -{ - struct list_external_parm_s *parm = cb_value; - - if (keydb_store_cert (cert, 1, NULL)) - log_error ("error storing certificate as ephemeral\n"); - - if (parm->print_header) - { - const char *resname = "[external keys]"; - int i; - - fprintf (parm->fp, "%s\n", resname ); - for (i=strlen(resname); i; i-- ) - putchar('-'); - putc ('\n', parm->fp); - parm->print_header = 0; - } - - if (parm->with_colons) - list_cert_colon (cert, parm->fp, 0); - else if (parm->with_chain) - list_cert_chain (cert, parm->fp); - else - { - list_cert_std (cert, parm->fp, 0); - putc ('\n', parm->fp); - } -} - - -/* List external keys similar to internal one. Note: mode does not - make sense here because it would be unwise to list external secret - keys */ -static void -list_external_keys (CTRL ctrl, STRLIST names, FILE *fp) -{ - int rc; - struct list_external_parm_s parm; - - parm.fp = fp; - parm.print_header = ctrl->no_server; - parm.with_colons = ctrl->with_colons; - parm.with_chain = ctrl->with_chain; - - rc = gpgsm_dirmngr_lookup (ctrl, names, list_external_cb, &parm); - if (rc) - log_error ("listing external keys failed: %s\n", gnupg_strerror (rc)); -} - -/* List all keys or just the key given as NAMES. - MODE controls the operation mode: - Bit 0-2: - 0 = list all public keys but don't flag secret ones - 1 = list only public keys - 2 = list only secret keys - 3 = list secret and public keys - Bit 6: list internal keys - Bit 7: list external keys - */ -void -gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode) -{ - if ((mode & (1<<6))) - list_internal_keys (ctrl, names, fp, (mode & 3)); - if ((mode & (1<<7))) - list_external_keys (ctrl, names, fp); -} diff --git a/sm/misc.c b/sm/misc.c deleted file mode 100644 index 3260b90b2..000000000 --- a/sm/misc.c +++ /dev/null @@ -1,32 +0,0 @@ -/* misc.c - Miscellaneous fucntions - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "gpgsm.h" - diff --git a/sm/server.c b/sm/server.c deleted file mode 100644 index e8200feda..000000000 --- a/sm/server.c +++ /dev/null @@ -1,1057 +0,0 @@ -/* server.c - Server mode and main entry point - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include "gpgsm.h" -#include "../assuan/assuan.h" - -#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t)) - - -/* The filepointer for status message used in non-server mode */ -static FILE *statusfp; - -/* Data used to assuciate an Assuan context with local server data */ -struct server_local_s { - ASSUAN_CONTEXT assuan_ctx; - int message_fd; - int list_internal; - int list_external; - CERTLIST recplist; - CERTLIST signerlist; -}; - - - -/* note, that it is sufficient to allocate the target string D as - long as the source string S, i.e.: strlen(s)+1; */ -static void -strcpy_escaped_plus (char *d, const unsigned char *s) -{ - while (*s) - { - if (*s == '%' && s[1] && s[2]) - { - s++; - *d++ = xtoi_2 ( s); - s += 2; - } - else if (*s == '+') - *d++ = ' ', s++; - else - *d++ = *s++; - } - *d = 0; -} - - - - -/* Check whether the option NAME appears in LINE */ -static int -has_option (const char *line, const char *name) -{ - const char *s; - int n = strlen (name); - - s = strstr (line, name); - return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); -} - - -static void -close_message_fd (CTRL ctrl) -{ - if (ctrl->server_local->message_fd != -1) - { - close (ctrl->server_local->message_fd); - ctrl->server_local->message_fd = -1; - } -} - - -static int -option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - if (!strcmp (key, "include-certs")) - { - int i = *value? atoi (value) : -1; - if (ctrl->include_certs < -2) - return ASSUAN_Parameter_Error; - ctrl->include_certs = i; - } - else if (!strcmp (key, "display")) - { - if (opt.display) - free (opt.display); - opt.display = strdup (value); - if (!opt.display) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "ttyname")) - { - if (opt.ttyname) - free (opt.ttyname); - opt.ttyname = strdup (value); - if (!opt.ttyname) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "ttytype")) - { - if (opt.ttytype) - free (opt.ttytype); - opt.ttytype = strdup (value); - if (!opt.ttytype) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "lc-ctype")) - { - if (opt.lc_ctype) - free (opt.lc_ctype); - opt.lc_ctype = strdup (value); - if (!opt.lc_ctype) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "lc-messages")) - { - if (opt.lc_messages) - free (opt.lc_messages); - opt.lc_messages = strdup (value); - if (!opt.lc_messages) - return ASSUAN_Out_Of_Core; - } - else if (!strcmp (key, "list-mode")) - { - int i = *value? atoi (value) : 0; - if (!i || i == 1) /* default and mode 1 */ - { - ctrl->server_local->list_internal = 1; - ctrl->server_local->list_external = 0; - } - else if (i == 2) - { - ctrl->server_local->list_internal = 0; - ctrl->server_local->list_external = 1; - } - else if (i == 3) - { - ctrl->server_local->list_internal = 1; - ctrl->server_local->list_external = 1; - } - else - return ASSUAN_Parameter_Error; - } - else - return ASSUAN_Invalid_Option; - - return 0; -} - - - - -static void -reset_notify (ASSUAN_CONTEXT ctx) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - gpgsm_release_certlist (ctrl->server_local->recplist); - gpgsm_release_certlist (ctrl->server_local->signerlist); - ctrl->server_local->recplist = NULL; - ctrl->server_local->signerlist = NULL; - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); -} - - -static void -input_notify (ASSUAN_CONTEXT ctx, const char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - ctrl->autodetect_encoding = 0; - ctrl->is_pem = 0; - ctrl->is_base64 = 0; - if (strstr (line, "--armor")) - ctrl->is_pem = 1; - else if (strstr (line, "--base64")) - ctrl->is_base64 = 1; - else if (strstr (line, "--binary")) - ; - else - ctrl->autodetect_encoding = 1; -} - -static void -output_notify (ASSUAN_CONTEXT ctx, const char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - - ctrl->create_pem = 0; - ctrl->create_base64 = 0; - if (strstr (line, "--armor")) - ctrl->create_pem = 1; - else if (strstr (line, "--base64")) - ctrl->create_base64 = 1; /* just the raw output */ -} - - - -/* RECIPIENT - - Set the recipient for the encryption. should be the - internal representation of the key; the server may accept any other - way of specification [we will support this]. If this is a valid and - trusted recipient the server does respond with OK, otherwise the - return is an ERR with the reason why the recipient can't be used, - the encryption will then not be done for this recipient. IF the - policy is not to encrypt at all if not all recipients are valid, the - client has to take care of this. All RECIPIENT commands are - cumulative until a RESET or an successful ENCRYPT command. */ -static int -cmd_recipient (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - - rc = gpgsm_add_to_certlist (ctrl, line, 0, &ctrl->server_local->recplist); - if (rc) - gpgsm_status2 (ctrl, STATUS_INV_RECP, - rc == -1? "1": - rc == GNUPG_No_Public_Key? "1": - rc == GNUPG_Ambiguous_Name? "2": - rc == GNUPG_Wrong_Key_Usage? "3": - rc == GNUPG_Certificate_Revoked? "4": - rc == GNUPG_Certificate_Expired? "5": - rc == GNUPG_No_CRL_Known? "6": - rc == GNUPG_CRL_Too_Old? "7": - rc == GNUPG_No_Policy_Match? "8": - "0", - line, NULL); - - return map_to_assuan_status (rc); -} - -/* SIGNER - - Set the signer's keys for the signature creation. should - be the internal representation of the key; the server may accept any - other way of specification [we will support this]. If this is a - valid and usable signing key the server does respond with OK, - otherwise it returns an ERR with the reason why the key can't be - used, the signing will then not be done for this key. If the policy - is not to sign at all if not all signer keys are valid, the client - has to take care of this. All SIGNER commands are cumulative until - a RESET but they are *not* reset by an SIGN command becuase it can - be expected that set of signers are used for more than one sign - operation. - - Note that this command returns an INV_RECP status which is a bit - strange, but they are very similar. */ -static int -cmd_signer (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - - rc = gpgsm_add_to_certlist (ctrl, line, 1, &ctrl->server_local->signerlist); - if (rc) - gpgsm_status2 (ctrl, STATUS_INV_RECP, - rc == -1? "1": - rc == GNUPG_No_Public_Key? "1": - rc == GNUPG_Ambiguous_Name? "2": - rc == GNUPG_Wrong_Key_Usage? "3": - rc == GNUPG_Certificate_Revoked? "4": - rc == GNUPG_Certificate_Expired? "5": - rc == GNUPG_No_CRL_Known? "6": - rc == GNUPG_CRL_Too_Old? "7": - rc == GNUPG_No_Policy_Match? "8": - rc == GNUPG_No_Secret_Key? "9": - "0", - line, NULL); - - return map_to_assuan_status (rc); -} - - -/* ENCRYPT - - Do the actual encryption process. Takes the plaintext from the INPUT - command, writes to the ciphertext to the file descriptor set with - the OUTPUT command, take the recipients form all the recipients set - so far. If this command fails the clients should try to delete all - output currently done or otherwise mark it as invalid. GPGSM does - ensure that there won't be any security problem with leftover data - on the output in this case. - - This command should in general not fail, as all necessary checks - have been done while setting the recipients. The input and output - pipes are closed. */ -static int -cmd_encrypt (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int inp_fd, out_fd; - FILE *out_fp; - int rc; - - inp_fd = assuan_get_input_fd (ctx); - if (inp_fd == -1) - return set_error (No_Input, NULL); - out_fd = assuan_get_output_fd (ctx); - if (out_fd == -1) - return set_error (No_Output, NULL); - - out_fp = fdopen ( dup(out_fd), "w"); - if (!out_fp) - return set_error (General_Error, "fdopen() failed"); - rc = gpgsm_encrypt (assuan_get_pointer (ctx), - ctrl->server_local->recplist, - inp_fd, out_fp); - fclose (out_fp); - - gpgsm_release_certlist (ctrl->server_local->recplist); - ctrl->server_local->recplist = NULL; - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - return map_to_assuan_status (rc); -} - -/* DECRYPT - - This performs the decrypt operation after doing some check on the - internal state. (e.g. that only needed data has been set). Because - it utilizes the GPG-Agent for the session key decryption, there is - no need to ask the client for a protecting passphrase - GpgAgent - does take care of this by requesting this from the user. */ -static int -cmd_decrypt (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int inp_fd, out_fd; - FILE *out_fp; - int rc; - - inp_fd = assuan_get_input_fd (ctx); - if (inp_fd == -1) - return set_error (No_Input, NULL); - out_fd = assuan_get_output_fd (ctx); - if (out_fd == -1) - return set_error (No_Output, NULL); - - out_fp = fdopen ( dup(out_fd), "w"); - if (!out_fp) - return set_error (General_Error, "fdopen() failed"); - rc = gpgsm_decrypt (ctrl, inp_fd, out_fp); - fclose (out_fp); - - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - -/* VERIFY - - This does a verify operation on the message send to the input-FD. - The result is written out using status lines. If an output FD was - given, the signed text will be written to that. - - If the signature is a detached one, the server will inquire about - the signed material and the client must provide it. - */ -static int -cmd_verify (ASSUAN_CONTEXT ctx, char *line) -{ - int rc; - CTRL ctrl = assuan_get_pointer (ctx); - int fd = assuan_get_input_fd (ctx); - int out_fd = assuan_get_output_fd (ctx); - FILE *out_fp = NULL; - - if (fd == -1) - return set_error (No_Input, NULL); - - if (out_fd != -1) - { - out_fp = fdopen ( dup(out_fd), "w"); - if (!out_fp) - return set_error (General_Error, "fdopen() failed"); - } - - rc = gpgsm_verify (assuan_get_pointer (ctx), fd, - ctrl->server_local->message_fd, out_fp); - if (out_fp) - fclose (out_fp); - - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - -/* SIGN [--detached] - - Sign the data set with the INPUT command and write it to the sink - set by OUTPUT. With "--detached" specified, a detached signature is - created (surprise). */ -static int -cmd_sign (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int inp_fd, out_fd; - FILE *out_fp; - int detached; - int rc; - - inp_fd = assuan_get_input_fd (ctx); - if (inp_fd == -1) - return set_error (No_Input, NULL); - out_fd = assuan_get_output_fd (ctx); - if (out_fd == -1) - return set_error (No_Output, NULL); - - detached = has_option (line, "--detached"); - - out_fp = fdopen ( dup(out_fd), "w"); - if (!out_fp) - return set_error (General_Error, "fdopen() failed"); - - rc = gpgsm_sign (assuan_get_pointer (ctx), ctrl->server_local->signerlist, - inp_fd, detached, out_fp); - fclose (out_fp); - - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - -/* IMPORT - - Import the certificates read form the input-fd, return status - message for each imported one. The import checks the validity of - the certificate but not of the entire chain. It is possible to - import expired certificates. */ -static int -cmd_import (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int rc; - int fd = assuan_get_input_fd (ctx); - - if (fd == -1) - return set_error (No_Input, NULL); - - rc = gpgsm_import (assuan_get_pointer (ctx), fd); - - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - -static int -cmd_export (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int fd = assuan_get_output_fd (ctx); - FILE *out_fp; - char *p; - STRLIST list, sl; - - if (fd == -1) - return set_error (No_Output, NULL); - - /* break the line down into an STRLIST */ - list = NULL; - for (p=line; *p; line = p) - { - while (*p && *p != ' ') - p++; - if (*p) - *p++ = 0; - if (*line) - { - sl = xtrymalloc (sizeof *sl + strlen (line)); - if (!sl) - { - free_strlist (list); - return ASSUAN_Out_Of_Core; - } - sl->flags = 0; - strcpy_escaped_plus (sl->d, line); - sl->next = list; - list = sl; - } - } - - out_fp = fdopen ( dup(fd), "w"); - if (!out_fp) - { - free_strlist (list); - return set_error (General_Error, "fdopen() failed"); - } - - gpgsm_export (ctrl, list, out_fp); - fclose (out_fp); - free_strlist (list); - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - return 0; -} - - -static int -cmd_delkeys (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - char *p; - STRLIST list, sl; - int rc; - - /* break the line down into an STRLIST */ - list = NULL; - for (p=line; *p; line = p) - { - while (*p && *p != ' ') - p++; - if (*p) - *p++ = 0; - if (*line) - { - sl = xtrymalloc (sizeof *sl + strlen (line)); - if (!sl) - { - free_strlist (list); - return ASSUAN_Out_Of_Core; - } - sl->flags = 0; - strcpy_escaped_plus (sl->d, line); - sl->next = list; - list = sl; - } - } - - rc = gpgsm_delete (ctrl, list); - free_strlist (list); - - /* close and reset the fd */ - close_message_fd (ctrl); - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - - -/* MESSAGE FD= - - Set the file descriptor to read a message which is used with - detached signatures */ -static int -cmd_message (ASSUAN_CONTEXT ctx, char *line) -{ - char *endp; - int fd; - CTRL ctrl = assuan_get_pointer (ctx); - - if (strncmp (line, "FD=", 3)) - return set_error (Syntax_Error, "FD= expected"); - line += 3; - if (!digitp (line)) - return set_error (Syntax_Error, "number required"); - fd = strtoul (line, &endp, 10); - if (*endp) - return set_error (Syntax_Error, "garbage found"); - if (fd == -1) - return set_error (No_Input, NULL); - - ctrl->server_local->message_fd = fd; - return 0; -} - - -static int -do_listkeys (ASSUAN_CONTEXT ctx, char *line, int mode) -{ - CTRL ctrl = assuan_get_pointer (ctx); - FILE *fp = assuan_get_data_fp (ctx); - char *p; - STRLIST list, sl; - unsigned int listmode; - - if (!fp) - return set_error (General_Error, "no data stream"); - - /* break the line down into an STRLIST */ - list = NULL; - for (p=line; *p; line = p) - { - while (*p && *p != ' ') - p++; - if (*p) - *p++ = 0; - if (*line) - { - sl = xtrymalloc (sizeof *sl + strlen (line)); - if (!sl) - { - free_strlist (list); - return ASSUAN_Out_Of_Core; - } - sl->flags = 0; - strcpy_escaped_plus (sl->d, line); - sl->next = list; - list = sl; - } - } - - ctrl->with_colons = 1; - listmode = mode; - if (ctrl->server_local->list_internal) - listmode |= (1<<6); - if (ctrl->server_local->list_external) - listmode |= (1<<7); - gpgsm_list_keys (assuan_get_pointer (ctx), list, fp, listmode); - free_strlist (list); - return 0; -} - -static int -cmd_listkeys (ASSUAN_CONTEXT ctx, char *line) -{ - return do_listkeys (ctx, line, 3); -} - -static int -cmd_listsecretkeys (ASSUAN_CONTEXT ctx, char *line) -{ - return do_listkeys (ctx, line, 2); -} - - -/* GENKEY - - Read the parameters in native format from the input fd and write a - certificate request to the output. - */ -static int -cmd_genkey (ASSUAN_CONTEXT ctx, char *line) -{ - CTRL ctrl = assuan_get_pointer (ctx); - int inp_fd, out_fd; - FILE *out_fp; - int rc; - - inp_fd = assuan_get_input_fd (ctx); - if (inp_fd == -1) - return set_error (No_Input, NULL); - out_fd = assuan_get_output_fd (ctx); - if (out_fd == -1) - return set_error (No_Output, NULL); - - out_fp = fdopen ( dup(out_fd), "w"); - if (!out_fp) - return set_error (General_Error, "fdopen() failed"); - rc = gpgsm_genkey (ctrl, inp_fd, out_fp); - fclose (out_fp); - - /* close and reset the fds */ - assuan_close_input_fd (ctx); - assuan_close_output_fd (ctx); - - return map_to_assuan_status (rc); -} - - - - - -/* Tell the assuan library about our commands */ -static int -register_commands (ASSUAN_CONTEXT ctx) -{ - static struct { - const char *name; - int cmd_id; - int (*handler)(ASSUAN_CONTEXT, char *line); - } table[] = { - { "RECIPIENT", 0, cmd_recipient }, - { "SIGNER", 0, cmd_signer }, - { "ENCRYPT", 0, cmd_encrypt }, - { "DECRYPT", 0, cmd_decrypt }, - { "VERIFY", 0, cmd_verify }, - { "SIGN", 0, cmd_sign }, - { "IMPORT", 0, cmd_import }, - { "EXPORT", 0, cmd_export }, - { "", ASSUAN_CMD_INPUT, NULL }, - { "", ASSUAN_CMD_OUTPUT, NULL }, - { "MESSAGE", 0, cmd_message }, - { "LISTKEYS", 0, cmd_listkeys }, - { "LISTSECRETKEYS", 0, cmd_listsecretkeys }, - { "GENKEY", 0, cmd_genkey }, - { "DELKEYS", 0, cmd_delkeys }, - { NULL } - }; - int i, j, rc; - - for (i=j=0; table[i].name; i++) - { - rc = assuan_register_command (ctx, - table[i].cmd_id? table[i].cmd_id - : (ASSUAN_CMD_USER + j++), - table[i].name, table[i].handler); - if (rc) - return rc; - } - return 0; -} - -/* Startup the server */ -void -gpgsm_server (void) -{ - int rc; - int filedes[2]; - ASSUAN_CONTEXT ctx; - struct server_control_s ctrl; - - memset (&ctrl, 0, sizeof ctrl); - gpgsm_init_default_ctrl (&ctrl); - - /* For now we use a simple pipe based server so that we can work - from scripts. We will later add options to run as a daemon and - wait for requests on a Unix domain socket */ - filedes[0] = 0; - filedes[1] = 1; - rc = assuan_init_pipe_server (&ctx, filedes); - if (rc) - { - log_error ("failed to initialize the server: %s\n", - assuan_strerror(rc)); - gpgsm_exit (2); - } - rc = register_commands (ctx); - if (rc) - { - log_error ("failed to the register commands with Assuan: %s\n", - assuan_strerror(rc)); - gpgsm_exit (2); - } - assuan_set_hello_line (ctx, "GNU Privacy Guard's S/M server ready"); - - assuan_register_reset_notify (ctx, reset_notify); - assuan_register_input_notify (ctx, input_notify); - assuan_register_output_notify (ctx, output_notify); - assuan_register_option_handler (ctx, option_handler); - - assuan_set_pointer (ctx, &ctrl); - ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local); - ctrl.server_local->assuan_ctx = ctx; - ctrl.server_local->message_fd = -1; - ctrl.server_local->list_internal = 1; - ctrl.server_local->list_external = 0; - - if (DBG_ASSUAN) - assuan_set_log_stream (ctx, log_get_stream ()); - - for (;;) - { - rc = assuan_accept (ctx); - if (rc == -1) - { - break; - } - else if (rc) - { - log_info ("Assuan accept problem: %s\n", assuan_strerror (rc)); - break; - } - - rc = assuan_process (ctx); - if (rc) - { - log_info ("Assuan processing failed: %s\n", assuan_strerror (rc)); - continue; - } - } - - gpgsm_release_certlist (ctrl.server_local->recplist); - ctrl.server_local->recplist = NULL; - gpgsm_release_certlist (ctrl.server_local->signerlist); - ctrl.server_local->signerlist = NULL; - - assuan_deinit_server (ctx); -} - - -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_SIGEXPIRED: s = "SIGEXPIRED"; 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_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_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_EXPSIG : s = "EXPSIG"; break; - case STATUS_EXPKEYSIG : s = "EXPKEYSIG"; break; - case STATUS_TRUNCATED : s = "TRUNCATED"; break; - case STATUS_ERROR : s = "ERROR"; break; - case STATUS_IMPORT_PROBLEM : s = "IMPORT_PROBLEM"; break; - default: s = "?"; break; - } - return s; -} - - -void -gpgsm_status2 (CTRL ctrl, int no, ...) -{ - va_list arg_ptr; - const char *text; - - va_start (arg_ptr, no); - - if (ctrl->no_server) - { - if (ctrl->status_fd == -1) - return; /* no status wanted */ - if (!statusfp) - { - if (ctrl->status_fd == 1) - statusfp = stdout; - else if (ctrl->status_fd == 2) - statusfp = stderr; - else - statusfp = fdopen (ctrl->status_fd, "w"); - - if (!statusfp) - { - log_fatal ("can't open fd %d for status output: %s\n", - ctrl->status_fd, strerror(errno)); - } - } - - fputs ("[GNUPG:] ", statusfp); - fputs (get_status_string (no), statusfp); - - while ( (text = va_arg (arg_ptr, const char*) )) - { - 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); - } - else - { - ASSUAN_CONTEXT ctx = ctrl->server_local->assuan_ctx; - char buf[950], *p; - size_t n; - - p = buf; - n = 0; - while ( (text = va_arg (arg_ptr, const char *)) ) - { - if (n) - { - *p++ = ' '; - n++; - } - for ( ; *text && n < DIM (buf)-2; n++) - *p++ = *text++; - } - *p = 0; - assuan_write_status (ctx, get_status_string (no), buf); - } - - va_end (arg_ptr); -} - -void -gpgsm_status (CTRL ctrl, int no, const char *text) -{ - gpgsm_status2 (ctrl, no, text, NULL); -} - - - -#if 0 -/* - * 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); -} -#endif diff --git a/sm/sign.c b/sm/sign.c deleted file mode 100644 index 061dfeebc..000000000 --- a/sm/sign.c +++ /dev/null @@ -1,622 +0,0 @@ -/* sign.c - Sign a message - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gpgsm.h" -#include "keydb.h" -#include "i18n.h" - - -static void -hash_data (int fd, GCRY_MD_HD md) -{ - FILE *fp; - char buffer[4096]; - int nread; - - fp = fdopen ( dup (fd), "rb"); - if (!fp) - { - log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno)); - return; - } - - do - { - nread = fread (buffer, 1, DIM(buffer), fp); - gcry_md_write (md, buffer, nread); - } - while (nread); - if (ferror (fp)) - log_error ("read error on fd %d: %s\n", fd, strerror (errno)); - fclose (fp); -} - -static int -hash_and_copy_data (int fd, GCRY_MD_HD md, KsbaWriter writer) -{ - KsbaError err; - FILE *fp; - char buffer[4096]; - int nread; - int rc = 0; - int any = 0; - - fp = fdopen ( dup (fd), "rb"); - if (!fp) - { - log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno)); - return GNUPG_File_Open_Error; - } - - do - { - nread = fread (buffer, 1, DIM(buffer), fp); - if (nread) - { - any = 1; - gcry_md_write (md, buffer, nread); - err = ksba_writer_write_octet_string (writer, buffer, nread, 0); - if (err) - { - log_error ("write failed: %s\n", ksba_strerror (err)); - rc = map_ksba_err (err); - } - } - } - while (nread && !rc); - if (ferror (fp)) - { - log_error ("read error on fd %d: %s\n", fd, strerror (errno)); - rc = GNUPG_Read_Error; - } - fclose (fp); - if (!any) - { - /* We can't allow to sign an empty message becuase it does not - make mnuch sense and more seriously, ksba-cms_build has - already written the tag for data and now expects an octet - string but an octet string of zeize 0 is illegal. */ - log_error ("cannot sign an empty message\n"); - rc = GNUPG_No_Data; - } - if (!rc) - { - err = ksba_writer_write_octet_string (writer, NULL, 0, 1); - if (err) - { - log_error ("write failed: %s\n", ksba_strerror (err)); - rc = map_ksba_err (err); - } - } - - return rc; -} - - -/* Get the default certificate which is defined as the first one our - keyDB retruns and has a secret key available */ -int -gpgsm_get_default_cert (KsbaCert *r_cert) -{ - KEYDB_HANDLE hd; - KsbaCert cert = NULL; - int rc; - char *p; - - hd = keydb_new (0); - if (!hd) - return GNUPG_General_Error; - rc = keydb_search_first (hd); - if (rc) - { - keydb_release (hd); - return rc; - } - - do - { - rc = keydb_get_cert (hd, &cert); - if (rc) - { - log_error ("keydb_get_cert failed: %s\n", gnupg_strerror (rc)); - keydb_release (hd); - return rc; - } - - p = gpgsm_get_keygrip_hexstring (cert); - if (p) - { - if (!gpgsm_agent_havekey (p)) - { - xfree (p); - keydb_release (hd); - *r_cert = cert; - return 0; /* got it */ - } - xfree (p); - } - - ksba_cert_release (cert); - cert = NULL; - } - while (!(rc = keydb_search_next (hd))); - if (rc && rc != -1) - log_error ("keydb_search_next failed: %s\n", gnupg_strerror (rc)); - - ksba_cert_release (cert); - keydb_release (hd); - return rc; -} - - -static KsbaCert -get_default_signer (void) -{ - KEYDB_SEARCH_DESC desc; - KsbaCert cert = NULL; - KEYDB_HANDLE kh = NULL; - int rc; - - if (!opt.local_user) - { - rc = gpgsm_get_default_cert (&cert); - if (rc) - { - if (rc != -1) - log_debug ("failed to find default certificate: %s\n", - gnupg_strerror (rc)); - return NULL; - } - return cert; - } - - rc = keydb_classify_name (opt.local_user, &desc); - if (rc) - { - log_error ("failed to find default signer: %s\n", gnupg_strerror (rc)); - return NULL; - } - - kh = keydb_new (0); - if (!kh) - return NULL; - - rc = keydb_search (kh, &desc, 1); - if (rc) - { - log_debug ("failed to find default certificate: rc=%d\n", rc); - } - else - { - rc = keydb_get_cert (kh, &cert); - if (rc) - { - log_debug ("failed to get cert: rc=%d\n", rc); - } - } - - keydb_release (kh); - return cert; -} - -/* Depending on the options in CTRL add the certificate CERT as well as - other certificate up in the chain to the Root-CA to the CMS - object. */ -static int -add_certificate_list (CTRL ctrl, KsbaCMS cms, KsbaCert cert) -{ - KsbaError err; - int rc = 0; - KsbaCert next = NULL; - int n; - int not_root = 0; - - ksba_cert_ref (cert); - - n = ctrl->include_certs; - if (n == -2) - { - not_root = 1; - n = -1; - } - if (n < 0 || n > 50) - n = 50; /* We better apply an upper bound */ - - if (n) - { - if (not_root && gpgsm_is_root_cert (cert)) - err = 0; - else - err = ksba_cms_add_cert (cms, cert); - if (err) - goto ksba_failure; - } - while ( n-- && !(rc = gpgsm_walk_cert_chain (cert, &next)) ) - { - if (not_root && gpgsm_is_root_cert (next)) - err = 0; - else - err = ksba_cms_add_cert (cms, next); - ksba_cert_release (cert); - cert = next; next = NULL; - if (err) - goto ksba_failure; - } - ksba_cert_release (cert); - - return rc == -1? 0: rc; - - ksba_failure: - ksba_cert_release (cert); - log_error ("ksba_cms_add_cert failed: %s\n", ksba_strerror (err)); - return map_ksba_err (err); -} - - - - -/* Perform a sign operation. - - Sign the data received on DATA-FD in embedded mode or in detached - mode when DETACHED is true. Write the signature to OUT_FP. The - keys used to sign are taken from SIGNERLIST or the default one will - be used if the value of this argument is NULL. */ -int -gpgsm_sign (CTRL ctrl, CERTLIST signerlist, - int data_fd, int detached, FILE *out_fp) -{ - int i, rc; - KsbaError err; - Base64Context b64writer = NULL; - KsbaWriter writer; - KsbaCMS cms = NULL; - KsbaStopReason stopreason; - KEYDB_HANDLE kh = NULL; - GCRY_MD_HD data_md = NULL; - int signer; - const char *algoid; - int algo; - time_t signed_at; - CERTLIST cl; - int release_signerlist = 0; - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = GNUPG_General_Error; - goto leave; - } - - ctrl->pem_name = "SIGNED MESSAGE"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gnupg_strerror (rc)); - goto leave; - } - - cms = ksba_cms_new (); - if (!cms) - { - rc = seterr (Out_Of_Core); - goto leave; - } - - err = ksba_cms_set_reader_writer (cms, NULL, writer); - if (err) - { - log_debug ("ksba_cms_set_reader_writer failed: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - - /* We are going to create signed data with data as encap. content */ - err = ksba_cms_set_content_type (cms, 0, KSBA_CT_SIGNED_DATA); - if (!err) - err = ksba_cms_set_content_type (cms, 1, KSBA_CT_DATA); - if (err) - { - log_debug ("ksba_cms_set_content_type failed: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - - /* If no list of signers is given, use a default one. */ - if (!signerlist) - { - KsbaCert cert = get_default_signer (); - if (!cert) - { - log_error ("no default signer found\n"); - rc = seterr (General_Error); - goto leave; - } - signerlist = xtrycalloc (1, sizeof *signerlist); - if (!signerlist) - { - rc = GNUPG_Out_Of_Core; - ksba_cert_release (cert); - goto leave; - } - signerlist->cert = cert; - release_signerlist = 1; - } - - - /* Gather certificates of signers and store them in the CMS object. */ - for (cl=signerlist; cl; cl = cl->next) - { - rc = gpgsm_cert_use_sign_p (cl->cert); - if (rc) - goto leave; - - err = ksba_cms_add_signer (cms, cl->cert); - if (err) - { - log_error ("ksba_cms_add_signer failed: %s\n", ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - rc = add_certificate_list (ctrl, cms, cl->cert); - if (rc) - { - log_error ("failed to store list of certificates: %s\n", - gnupg_strerror(rc)); - goto leave; - } - /* Set the hash algorithm we are going to use */ - err = ksba_cms_add_digest_algo (cms, "1.3.14.3.2.26" /*SHA-1*/); - if (err) - { - log_debug ("ksba_cms_add_digest_algo failed: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - } - - /* Prepare hashing (actually we are figuring out what we have set above)*/ - data_md = gcry_md_open (0, 0); - if (!data_md) - { - rc = map_gcry_err (gcry_errno()); - log_error ("md_open failed: %s\n", gcry_strerror (-1)); - goto leave; - } - if (DBG_HASHING) - gcry_md_start_debug (data_md, "sign.data"); - - for (i=0; (algoid=ksba_cms_get_digest_algo_list (cms, i)); i++) - { - algo = gcry_md_map_name (algoid); - if (!algo) - { - log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?"); - rc = GNUPG_Bug; - goto leave; - } - gcry_md_enable (data_md, algo); - } - - if (detached) - { /* we hash the data right now so that we can store the message - digest. ksba_cms_build() takes this as an flag that detached - data is expected. */ - unsigned char *digest; - size_t digest_len; - /* Fixme do this for all signers and get the algo to use from - the signer's certificate - does not make mich sense, bu we - should do this consistent as we have already done it above */ - algo = GCRY_MD_SHA1; - hash_data (data_fd, data_md); - digest = gcry_md_read (data_md, algo); - digest_len = gcry_md_get_algo_dlen (algo); - if ( !digest || !digest_len) - { - log_error ("problem getting the hash of the data\n"); - rc = GNUPG_Bug; - goto leave; - } - for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) - { - err = ksba_cms_set_message_digest (cms, signer, digest, digest_len); - if (err) - { - log_error ("ksba_cms_set_message_digest failed: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - } - } - - signed_at = gnupg_get_time (); - for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) - { - err = ksba_cms_set_signing_time (cms, signer, signed_at); - if (err) - { - log_error ("ksba_cms_set_signing_time failed: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - } - - do - { - err = ksba_cms_build (cms, &stopreason); - if (err) - { - log_debug ("ksba_cms_build failed: %s\n", ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - - if (stopreason == KSBA_SR_BEGIN_DATA) - { /* hash the data and store the message digest */ - unsigned char *digest; - size_t digest_len; - - assert (!detached); - /* Fixme: get the algo to use from the signer's certificate - - does not make much sense, but we should do this - consistent as we have already done it above. Code is - mostly duplicated above. */ - - algo = GCRY_MD_SHA1; - rc = hash_and_copy_data (data_fd, data_md, writer); - if (rc) - goto leave; - digest = gcry_md_read (data_md, algo); - digest_len = gcry_md_get_algo_dlen (algo); - if ( !digest || !digest_len) - { - log_error ("problem getting the hash of the data\n"); - rc = GNUPG_Bug; - goto leave; - } - for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) - { - err = ksba_cms_set_message_digest (cms, signer, - digest, digest_len); - if (err) - { - log_error ("ksba_cms_set_message_digest failed: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - } - } - else if (stopreason == KSBA_SR_NEED_SIG) - { /* calculate the signature for all signers */ - GCRY_MD_HD md; - - algo = GCRY_MD_SHA1; - md = gcry_md_open (algo, 0); - if (DBG_HASHING) - gcry_md_start_debug (md, "sign.attr"); - - if (!md) - { - log_error ("md_open failed: %s\n", gcry_strerror (-1)); - goto leave; - } - ksba_cms_set_hash_function (cms, HASH_FNC, md); - for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) - { - char *sigval = NULL; - char *buf, *fpr; - - if (signer) - gcry_md_reset (md); - rc = ksba_cms_hash_signed_attrs (cms, signer); - if (rc) - { - log_debug ("hashing signed attrs failed: %s\n", - ksba_strerror (rc)); - gcry_md_close (md); - goto leave; - } - - rc = gpgsm_create_cms_signature (cl->cert, md, algo, &sigval); - if (rc) - { - gcry_md_close (md); - goto leave; - } - - err = ksba_cms_set_sig_val (cms, signer, sigval); - xfree (sigval); - if (err) - { - log_error ("failed to store the signature: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - gcry_md_close (md); - goto leave; - } - - /* write a status message */ - fpr = gpgsm_get_fingerprint_hexstring (cl->cert, GCRY_MD_SHA1); - if (!fpr) - { - rc = seterr (Out_Of_Core); - gcry_md_close (md); - goto leave; - } - rc = asprintf (&buf, "%c %d %d 00 %lu %s", - detached? 'D':'S', - GCRY_PK_RSA, /* FIXME: get pk algo from cert */ - algo, - (ulong)signed_at, - fpr); - xfree (fpr); - if (rc < 0) - { - rc = seterr (Out_Of_Core); - gcry_md_close (md); - goto leave; - } - rc = 0; - gpgsm_status (ctrl, STATUS_SIG_CREATED, buf); - free (buf); /* yes, we must use the regular free() here */ - } - gcry_md_close (md); - - } - } - while (stopreason != KSBA_SR_READY); - - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - - log_info ("signature created\n"); - - - leave: - if (release_signerlist) - gpgsm_release_certlist (signerlist); - ksba_cms_release (cms); - gpgsm_destroy_writer (b64writer); - keydb_release (kh); - gcry_md_close (data_md); - return rc; -} diff --git a/sm/verify.c b/sm/verify.c deleted file mode 100644 index df7c8bfe8..000000000 --- a/sm/verify.c +++ /dev/null @@ -1,510 +0,0 @@ -/* verify.c - Verify a messages signature - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gpgsm.h" -#include "keydb.h" -#include "i18n.h" - -/* fixme: Move this to jnlib */ -static char * -strtimestamp (time_t atime) -{ - char *buffer = xmalloc (15); - - if (atime < 0) - strcpy (buffer, "????" "-??" "-??"); - else if (!atime) - strcpy (buffer, "none"); - else - { - struct tm *tp; - - tp = gmtime( &atime ); - sprintf (buffer, "%04d-%02d-%02d", - 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday); - } - return buffer; -} - - - -/* Hash the data for a detached signature */ -static void -hash_data (int fd, GCRY_MD_HD md) -{ - FILE *fp; - char buffer[4096]; - int nread; - - fp = fdopen ( dup (fd), "rb"); - if (!fp) - { - log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno)); - return; - } - - do - { - nread = fread (buffer, 1, DIM(buffer), fp); - gcry_md_write (md, buffer, nread); - } - while (nread); - if (ferror (fp)) - log_error ("read error on fd %d: %s\n", fd, strerror (errno)); - fclose (fp); -} - - - - -/* Perform a verify operation. To verify detached signatures, data_fd - must be different than -1. With OUT_FP given and a non-detached - signature, the signed material is written to that stream. */ -int -gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp) -{ - int i, rc; - Base64Context b64reader = NULL; - Base64Context b64writer = NULL; - KsbaError err; - KsbaReader reader; - KsbaWriter writer = NULL; - KsbaCMS cms = NULL; - KsbaStopReason stopreason; - KsbaCert cert; - KEYDB_HANDLE kh; - GCRY_MD_HD data_md = NULL; - int signer; - const char *algoid; - int algo; - int is_detached; - FILE *fp = NULL; - char *p; - - kh = keydb_new (0); - if (!kh) - { - log_error (_("failed to allocated keyDB handle\n")); - rc = GNUPG_General_Error; - goto leave; - } - - - fp = fdopen ( dup (in_fd), "rb"); - if (!fp) - { - log_error ("fdopen() failed: %s\n", strerror (errno)); - rc = seterr (IO_Error); - goto leave; - } - - rc = gpgsm_create_reader (&b64reader, ctrl, fp, &reader); - if (rc) - { - log_error ("can't create reader: %s\n", gnupg_strerror (rc)); - goto leave; - } - - if (out_fp) - { - rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gnupg_strerror (rc)); - goto leave; - } - } - - cms = ksba_cms_new (); - if (!cms) - { - rc = seterr (Out_Of_Core); - goto leave; - } - - err = ksba_cms_set_reader_writer (cms, reader, writer); - if (err) - { - log_error ("ksba_cms_set_reader_writer failed: %s\n", - ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - - data_md = gcry_md_open (0, 0); - if (!data_md) - { - rc = map_gcry_err (gcry_errno()); - log_error ("md_open failed: %s\n", gcry_strerror (-1)); - goto leave; - } - if (DBG_HASHING) - gcry_md_start_debug (data_md, "vrfy.data"); - - is_detached = 0; - do - { - err = ksba_cms_parse (cms, &stopreason); - if (err) - { - log_error ("ksba_cms_parse failed: %s\n", ksba_strerror (err)); - rc = map_ksba_err (err); - goto leave; - } - - if (stopreason == KSBA_SR_NEED_HASH) - { - is_detached = 1; - if (opt.verbose) - log_info ("detached signature\n"); - } - - if (stopreason == KSBA_SR_NEED_HASH - || stopreason == KSBA_SR_BEGIN_DATA) - { /* We are now able to enable the hash algorithms */ - for (i=0; (algoid=ksba_cms_get_digest_algo_list (cms, i)); i++) - { - algo = gcry_md_map_name (algoid); - if (!algo) - log_error ("unknown hash algorithm `%s'\n", - algoid? algoid:"?"); - else - gcry_md_enable (data_md, algo); - } - if (is_detached) - { - if (data_fd == -1) - log_info ("detached signature w/o data " - "- assuming certs-only\n"); - else - hash_data (data_fd, data_md); - } - else - { - ksba_cms_set_hash_function (cms, HASH_FNC, data_md); - } - } - else if (stopreason == KSBA_SR_END_DATA) - { /* The data bas been hashed */ - - } - } - while (stopreason != KSBA_SR_READY); - - if (b64writer) - { - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gnupg_strerror (rc)); - goto leave; - } - } - - if (data_fd != -1 && !is_detached) - { - log_error ("data given for a non-detached signature\n"); - rc = GNUPG_Conflict; - goto leave; - } - - for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++) - { - /* Fixme: it might be better to check the validity of the - certificate first before entering it into the DB. This way - we would avoid cluttering the DB with invalid - certificates. */ - keydb_store_cert (cert, 0, NULL); - ksba_cert_release (cert); - } - - cert = NULL; - err = 0; - for (signer=0; ; signer++) - { - char *issuer = NULL; - KsbaSexp sigval = NULL; - time_t sigtime, keyexptime; - KsbaSexp serial; - char *msgdigest = NULL; - size_t msgdigestlen; - - err = ksba_cms_get_issuer_serial (cms, signer, &issuer, &serial); - if (!signer && err == KSBA_No_Data && data_fd == -1 && is_detached) - { - log_info ("certs-only message accepted\n"); - err = 0; - break; - } - if (err) - { - if (signer && err == -1) - err = 0; - break; - } - if (DBG_X509) - { - log_debug ("signer %d - issuer: `%s'\n", - signer, issuer? issuer:"[NONE]"); - log_debug ("signer %d - serial: ", signer); - gpgsm_dump_serial (serial); - log_printf ("\n"); - } - - err = ksba_cms_get_signing_time (cms, signer, &sigtime); - if (err == KSBA_No_Data) - sigtime = 0; - else if (err) - { - log_error ("error getting signing time: %s\n", ksba_strerror (err)); - sigtime = (time_t)-1; - } - - err = ksba_cms_get_message_digest (cms, signer, - &msgdigest, &msgdigestlen); - if (!err) - { - algoid = ksba_cms_get_digest_algo (cms, signer); - algo = gcry_md_map_name (algoid); - if (DBG_X509) - log_debug ("signer %d - digest algo: %d\n", signer, algo); - if ( !gcry_md_info (data_md, GCRYCTL_IS_ALGO_ENABLED, &algo, NULL) ) - { - log_error ("digest algo %d has not been enabled\n", algo); - goto next_signer; - } - } - else if (err == KSBA_No_Data) - { - assert (!msgdigest); - err = 0; - algoid = NULL; - algo = 0; - } - else /* real error */ - break; - - sigval = ksba_cms_get_sig_val (cms, signer); - if (!sigval) - { - log_error ("no signature value available\n"); - goto next_signer; - } - if (DBG_X509) - log_debug ("signer %d - signature available", signer); - - /* Find the certificate of the signer */ - keydb_search_reset (kh); - rc = keydb_search_issuer_sn (kh, issuer, serial); - if (rc) - { - if (rc == -1) - { - log_error ("certificate not found\n"); - rc = GNUPG_No_Public_Key; - } - else - log_error ("failed to find the certificate: %s\n", - gnupg_strerror(rc)); - gpgsm_status2 (ctrl, STATUS_ERROR, "verify.findkey", - gnupg_error_token (rc), NULL); - /* fixme: we might want to append the issuer and serial - using our standard notation */ - goto next_signer; - } - - rc = keydb_get_cert (kh, &cert); - if (rc) - { - log_error ("failed to get cert: %s\n", gnupg_strerror (rc)); - goto next_signer; - } - - log_info (_("Signature made ")); - if (sigtime) - gpgsm_dump_time (sigtime); - else - log_printf (_("[date not given]")); - log_printf (_(" using certificate ID %08lX\n"), - gpgsm_get_short_fingerprint (cert)); - - - if (msgdigest) - { /* Signed attributes are available. */ - GCRY_MD_HD md; - unsigned char *s; - - /* check that the message digest in the signed attributes - matches the one we calculated on the data */ - s = gcry_md_read (data_md, algo); - if ( !s || !msgdigestlen - || gcry_md_get_algo_dlen (algo) != msgdigestlen - || !s || memcmp (s, msgdigest, msgdigestlen) ) - { - char *fpr; - - log_error ("invalid signature: message digest attribute " - "does not match calculated one\n"); - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - gpgsm_status (ctrl, STATUS_BADSIG, fpr); - xfree (fpr); - goto next_signer; - } - - md = gcry_md_open (algo, 0); - if (!md) - { - log_error ("md_open failed: %s\n", gcry_strerror (-1)); - goto next_signer; - } - if (DBG_HASHING) - gcry_md_start_debug (md, "vrfy.attr"); - - ksba_cms_set_hash_function (cms, HASH_FNC, md); - rc = ksba_cms_hash_signed_attrs (cms, signer); - if (rc) - { - log_error ("hashing signed attrs failed: %s\n", - ksba_strerror (rc)); - gcry_md_close (md); - goto next_signer; - } - rc = gpgsm_check_cms_signature (cert, sigval, md, algo); - gcry_md_close (md); - } - else - { - rc = gpgsm_check_cms_signature (cert, sigval, data_md, algo); - } - - if (rc) - { - char *fpr; - - log_error ("invalid signature: %s\n", gnupg_strerror (rc)); - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - gpgsm_status (ctrl, STATUS_BADSIG, fpr); - xfree (fpr); - goto next_signer; - } - rc = gpgsm_cert_use_verify_p (cert); /*(this displays an info message)*/ - if (rc) - { - gpgsm_status2 (ctrl, STATUS_ERROR, "verify.keyusage", - gnupg_error_token (rc), NULL); - rc = 0; - } - - if (DBG_X509) - log_debug ("signature okay - checking certs\n"); - rc = gpgsm_validate_chain (ctrl, cert, &keyexptime); - if (rc == GNUPG_Certificate_Expired) - { - gpgsm_status (ctrl, STATUS_EXPKEYSIG, NULL); - rc = 0; - } - else - gpgsm_status (ctrl, STATUS_GOODSIG, NULL); - - { - char *buf, *fpr, *tstr; - - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - tstr = strtimestamp (sigtime); - buf = xmalloc ( strlen(fpr) + strlen (tstr) + 120); - sprintf (buf, "%s %s %lu %lu", fpr, tstr, - (unsigned long)sigtime, (unsigned long)keyexptime ); - xfree (tstr); - xfree (fpr); - gpgsm_status (ctrl, STATUS_VALIDSIG, buf); - xfree (buf); - } - - if (rc) /* of validate_chain */ - { - log_error ("invalid certification chain: %s\n", gnupg_strerror (rc)); - if (rc == GNUPG_Bad_Certificate_Chain - || rc == GNUPG_Bad_Certificate - || rc == GNUPG_Bad_CA_Certificate - || rc == GNUPG_Certificate_Revoked) - gpgsm_status (ctrl, STATUS_TRUST_NEVER, gnupg_error_token (rc)); - else - gpgsm_status (ctrl, STATUS_TRUST_UNDEFINED, gnupg_error_token (rc)); - goto next_signer; - } - - for (i=0; (p = ksba_cert_get_subject (cert, i)); i++) - { - log_info (!i? _("Good signature from") - : _(" aka")); - log_printf (" \""); - gpgsm_print_name (log_get_stream (), p); - log_printf ("\"\n"); - ksba_free (p); - } - - gpgsm_status (ctrl, STATUS_TRUST_FULLY, NULL); - - - next_signer: - rc = 0; - xfree (issuer); - xfree (serial); - xfree (sigval); - xfree (msgdigest); - ksba_cert_release (cert); - cert = NULL; - } - rc = 0; - if (err) - { - log_error ("ksba error: %s\n", ksba_strerror (err)); - rc = map_ksba_err (rc); - } - - - - leave: - ksba_cms_release (cms); - gpgsm_destroy_reader (b64reader); - gpgsm_destroy_writer (b64writer); - keydb_release (kh); - gcry_md_close (data_md); - if (fp) - fclose (fp); - - if (rc) - gpgsm_status2 (ctrl, STATUS_ERROR, "verify.leave", - gnupg_error_token (rc), NULL); - return rc; -} - diff --git a/tests/567064FE6D14A17B2D811ABB407728BC558AA455 b/tests/567064FE6D14A17B2D811ABB407728BC558AA455 deleted file mode 100644 index cf0535ff7..000000000 --- a/tests/567064FE6D14A17B2D811ABB407728BC558AA455 +++ /dev/null @@ -1,18 +0,0 @@ -(private-key - (oid.1.2.840.113549.1.1.1 - (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#) - (e #010001#) - (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B117D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BDC543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#) - (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#) - (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f935a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#) - (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891eebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#) - ) -) - - - - - - - - diff --git a/tests/ChangeLog b/tests/ChangeLog deleted file mode 100644 index d9ff7eb8f..000000000 --- a/tests/ChangeLog +++ /dev/null @@ -1,52 +0,0 @@ -2002-09-04 Neal H. Walfield - - * Makefile.am (inittests.stamp): Do not set LD_LIBRARY_PATH, but - rather prepend it. Be more robust and prefer printf over echo -n. - -2002-09-04 Marcus Brinkmann - - * asschk.c (start_server): Close the parent's file descriptors in - the child. - (read_assuan): Variable NREAD removed. Cut off the received line - currectly if more than one line was read. - -2002-09-03 Neal H. Walfield - - * Makefile.am (inittests.stamp): Construct an LD_LIBRARY_PATH from - LDFLAGS. - -2002-08-09 Werner Koch - - * asschk.c (cmd_getenv): New. - (expand_line): Allow / as variable name delimiter. - * sm-sign+verify, sm-verify: Use $srcdir so that a VPATH build works. - - * Makefile.am: Fixes for make dist. - * samplekets/Makefile.am: New. - -2002-08-08 Werner Koch - - * asschk.c: Added some new features. - * runtest, inittests: New. - * text-1.txt, text-2.txt, text-3.txt: New. - * text-1.osig.pem, text-1.dsig.pem, text-1.osig-bad.pem: New. - * text-2.osig.pem, text-2.osig-bad.pem: New. - * samplekeys : New directory - * sm-verify, sm-sign+verify: The first test scripts. - -2002-08-06 Werner Koch - - * Makefile.am, asschk.c: New. - - - Copyright 2002 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/tests/Makefile.am b/tests/Makefile.am deleted file mode 100644 index b2fa56704..000000000 --- a/tests/Makefile.am +++ /dev/null @@ -1,78 +0,0 @@ -# Makefile.am -tests makefile for libxtime -# Copyright (C) 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 - -## Process this file with automake to produce Makefile.in - -GPGSM = ../sm/gpgsm - -# We can't unset a variable here so we unset GPG_AGENT_INFO in runtest -TESTS_ENVIRONMENT = GNUPGHOME=`pwd` LC_ALL=C GPGSM=$(GPGSM) $(srcdir)/runtest - -testscripts = sm-sign+verify sm-verify - -EXTRA_DIST = runtest inittests $(testscripts) \ - text-1.txt text-2.txt text-3.txt \ - text-1.osig.pem text-1.dsig.pem text-1.osig-bad.pem \ - text-2.osig.pem text-2.osig-bad.pem \ - samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key \ - samplekeys/cert_g10code_pete1.pem \ - samplekeys/cert_g10code_test1.pem \ - samplekeys/cert_g10code_theo1.pem - -TESTS = $(testscripts) - -CLEANFILES = inittests.stamp x y y z out err - *.lock .\#lk* - -DISTCLEANFILES = pubring.kbx~ random_seed - -noinst_PROGRAMS = asschk - -asschk_SOURCES = asschk.c - - -all-local: inittests.stamp - -clean-local: - srcdir=$(srcdir) $(TESTS_ENVIRONMENT) $(srcdir)/inittests --clean - -inittests.stamp: inittests - LD_LIBRARY_PATH=$$(seen=0; \ - for i in $(LDFLAGS); \ - do \ - if echo "$$i" | egrep '^-L' >/dev/null 2>&1; \ - then \ - if test $$seen = 0; \ - then \ - seen=1; \ - else \ - printf ":"; \ - fi; \ - printf "%s" "$${i}" | sed 's/^-L//'; \ - fi; \ - done; \ - if test $$seen != 0 \ - && test x$${LD_LIBRARY_PATH} != x; \ - then \ - printf ":"; \ - fi; \ - printf "%s" "$${LD_LIBRARY_PATH}") \ - srcdir=$(srcdir) $(TESTS_ENVIRONMENT) $(srcdir)/inittests - echo timestamp >./inittests.stamp - diff --git a/tests/asschk.c b/tests/asschk.c deleted file mode 100644 index 1a11ead33..000000000 --- a/tests/asschk.c +++ /dev/null @@ -1,1046 +0,0 @@ -/* asschk.c - Assuan Server Checker - * Copyright (C) 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 - */ - -/* This is a simple stand-alone Assuan server test program. We don't - want to use the assuan library because we don't want to hide errors - in that library. - - The script language is line based. Empty lines or lines containing - only white spaces are ignored, line with a hash sign as first non - white space character are treated as comments. - - A simple macro mechanism is implemnted. Macros are expanded before - a line is processed but after comment processing. Macros are only - expanded once and non existing macros expand to the empty string. - A macro is dereferenced by prefixing its name with a dollar sign; - the end of the name is currently indicated by a white space, a - dollar sign or a slash. To use a dollor sign verbatim, double it. - - A macro is assigned by prefixing a statement with the macro name - and an equal sign. The value is assigned verbatim if it does not - resemble a command, otherwise the return value of the command will - get assigned. The command "let" may be used to assign values - unambigiously and it should be used if the value starts with a - letter. - - Conditions are not yes implemented except for a simple evaluation - which yields false for an empty string or the string "0". The - result may be negated by prefixing with a '!'. - - The general syntax of a command is: - - [ =] [] - - If NAME is not specifed but the statement returns a value it is - assigned to the name "?" so that it can be referenced using "$?". - The following commands are implemented: - - let - Return VALUE. - - echo - Print VALUE. - - openfile - Open file FILENAME for read access and retrun the file descriptor. - - createfile - Create file FILENAME, open for write access and retrun the file - descriptor. - - pipeserver - Connect to the Assuan server PROGRAM. - - send - Send LINE to the server. - - expect-ok - Expect an OK response from the server. Status and data out put - is ignored. - - expect-err - Expect an ERR response from the server. Status and data out put - is ignored. - - count-status - Initialize the assigned variable to 0 and assign it as an counter for - status code CODE. This command must be called with an assignment. - - quit - Terminate the process. - - quit-if - Terminate the process if CONDITION evaluates to true. - - fail-if - Terminate the process with an exit code of 1 if CONDITION - evaluates to true. - - cmpfiles - Returns true when the content of the files FIRST and SECOND match. - - getenv - Return the value of the environment variable NAME. - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) -# define ATTR_PRINTF(f,a) __attribute__ ((format (printf,f,a))) -#else -# define ATTR_PRINTF(f,a) -#endif - -#define spacep(p) (*(p) == ' ' || *(p) == '\t') - -#define MAX_LINELEN 2048 - -typedef enum { - LINE_OK = 0, - LINE_ERR, - LINE_STAT, - LINE_DATA, - LINE_END, -} LINETYPE; - -typedef enum { - VARTYPE_SIMPLE = 0, - VARTYPE_FD, - VARTYPE_COUNTER -} VARTYPE; - - -struct variable_s { - struct variable_s *next; - VARTYPE type; - unsigned int count; - char *value; - char name[1]; -}; -typedef struct variable_s *VARIABLE; - - -static void die (const char *format, ...) ATTR_PRINTF(1,2); - - -/* Name of this program to be printed in error messages. */ -static const char *invocation_name; - -/* Talk a bit about what is going on. */ -static int opt_verbose; - -/* Option to ignore the echo command. */ -static int opt_no_echo; - -/* File descriptors used to communicate with the current server. */ -static int server_send_fd = -1; -static int server_recv_fd = -1; - -/* The Assuan protocol limits the line length to 1024, so we can - safely use a (larger) buffer. The buffer is filled using the - read_assuan(). */ -static char recv_line[MAX_LINELEN]; -/* Tell the status of the current line. */ -static LINETYPE recv_type; - -/* This is our variable storage. */ -static VARIABLE variable_list; - - -static void -die (const char *format, ...) -{ - va_list arg_ptr; - - fflush (stdout); - fprintf (stderr, "%s: ", invocation_name); - - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - putc ('\n', stderr); - - exit (1); -} - -static void -err (const char *format, ...) -{ - va_list arg_ptr; - - fflush (stdout); - fprintf (stderr, "%s: ", invocation_name); - - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - putc ('\n', stderr); -} - -static void * -xmalloc (size_t n) -{ - void *p = malloc (n); - if (!p) - die ("out of core"); - return p; -} - -static void * -xcalloc (size_t n, size_t m) -{ - void *p = calloc (n, m); - if (!p) - die ("out of core"); - return p; -} - -static char * -xstrdup (const char *s) -{ - char *p = xmalloc (strlen (s)+1); - strcpy (p, s); - return p; -} - - -/* Write LENGTH bytes from BUFFER to FD. */ -static int -writen (int fd, const char *buffer, size_t length) -{ - while (length) - { - int nwritten = write (fd, buffer, length); - - if (nwritten < 0) - { - if (errno == EINTR) - continue; - return -1; /* write error */ - } - length -= nwritten; - buffer += nwritten; - } - return 0; /* okay */ -} - - - - -/* Assuan specific stuff. */ - -/* Read a line from FD, store it in the global recv_line, analyze the - type and store that in recv_type. The function terminates on a - communication error. Returns a pointer into the inputline to the - first byte of the arguments. The parsing is very strict to match - excalty what we want to send. */ -static char * -read_assuan (int fd) -{ - static char pending[MAX_LINELEN]; - static size_t pending_len; - size_t nleft = sizeof recv_line; - char *buf = recv_line; - char *p; - - while (nleft > 0) - { - int n; - - if (pending_len) - { - if (pending_len >= nleft) - die ("received line too large"); - memcpy (buf, pending, pending_len); - n = pending_len; - pending_len = 0; - } - else - n = read (fd, buf, nleft); - if (n < 0) - { - if (errno == EINTR) - continue; - die ("reading fd %d failed: %s", fd, strerror (errno)); - } - else if (!n) - die ("received incomplete line on fd %d", fd); - p = buf; - nleft -= n; - buf += n; - - for (; n && *p != '\n'; n--, p++) - ; - if (n) - { - if (n>1) - { - n--; - memcpy (pending, p + 1, n); - pending_len = n; - } - *p = '\0'; - break; - } - } - if (!nleft) - die ("received line too large"); - - p = recv_line; - if (p[0] == 'O' && p[1] == 'K' && (p[2] == ' ' || !p[2])) - { - recv_type = LINE_OK; - p += 3; - } - else if (p[0] == 'E' && p[1] == 'R' && p[2] == 'R' - && (p[3] == ' ' || !p[3])) - { - recv_type = LINE_ERR; - p += 4; - } - else if (p[0] == 'S' && (p[1] == ' ' || !p[1])) - { - recv_type = LINE_STAT; - p += 2; - } - else if (p[0] == 'D' && p[1] == ' ') - { - recv_type = LINE_DATA; - p += 2; - } - else if (p[0] == 'E' && p[1] == 'N' && p[2] == 'D' && !p[3]) - { - recv_type = LINE_END; - p += 3; - } - else - die ("invalid line type (%.5s)", p); - - return p; -} - -/* Write LINE to the server using FD. It is expected that the line - contains the terminating linefeed as last character. */ -static void -write_assuan (int fd, const char *line) -{ - char buffer[1026]; - size_t n = strlen (line); - - if (n > 1024) - die ("line too long for Assuan protocol"); - strcpy (buffer, line); - if (!n || buffer[n-1] != '\n') - buffer[n++] = '\n'; - - if (writen (fd, buffer, n)) - die ("sending line to %d failed: %s", fd, strerror (errno)); -} - - -/* Start the server with path PGMNAME and connect its stdout and - strerr to a newly created pipes; the file descriptors are then - store in the gloabl variables SERVER_SEND_FD and - SERVER_RECV_FD. The initial handcheck is performed.*/ -static void -start_server (const char *pgmname) -{ - int rp[2]; - int wp[2]; - pid_t pid; - - if (pipe (rp) < 0) - die ("pipe creation failed: %s", strerror (errno)); - if (pipe (wp) < 0) - die ("pipe creation failed: %s", strerror (errno)); - - fflush (stdout); - fflush (stderr); - pid = fork (); - if (pid < 0) - die ("fork failed"); - - if (!pid) - { - const char *arg0; - - arg0 = strrchr (pgmname, '/'); - if (arg0) - arg0++; - else - arg0 = pgmname; - - if (wp[0] != STDIN_FILENO) - { - if (dup2 (wp[0], STDIN_FILENO) == -1) - die ("dup2 failed in child: %s", strerror (errno)); - close (wp[0]); - } - if (rp[1] != STDOUT_FILENO) - { - if (dup2 (rp[1], STDOUT_FILENO) == -1) - die ("dup2 failed in child: %s", strerror (errno)); - close (rp[1]); - } - if (!opt_verbose) - { - int fd = open ("/dev/null", O_WRONLY); - if (fd == -1) - die ("can't open `/dev/null': %s", strerror (errno)); - if (dup2 (fd, STDERR_FILENO) == -1) - die ("dup2 failed in child: %s", strerror (errno)); - close (fd); - } - - close (wp[1]); - close (rp[0]); - execl (pgmname, arg0, "--server", NULL); - die ("exec failed for `%s': %s", pgmname, strerror (errno)); - } - close (wp[0]); - close (rp[1]); - server_send_fd = wp[1]; - server_recv_fd = rp[0]; - - read_assuan (server_recv_fd); - if (recv_type != LINE_OK) - die ("no greating message"); -} - - - - - -/* Script intepreter. */ - -static void -unset_var (const char *name) -{ - VARIABLE var; - - for (var=variable_list; var && strcmp (var->name, name); var = var->next) - ; - if (!var) - return; -/* fprintf (stderr, "unsetting `%s'\n", name); */ - - if (var->type == VARTYPE_FD && var->value) - { - int fd; - - fd = atoi (var->value); - if (fd != -1 && fd != 0 && fd != 1 && fd != 2) - close (fd); - } - - free (var->value); - var->value = NULL; - var->type = 0; - var->count = 0; -} - - -static void -set_type_var (const char *name, const char *value, VARTYPE type) -{ - VARIABLE var; - - if (!name) - name = "?"; - for (var=variable_list; var && strcmp (var->name, name); var = var->next) - ; - if (!var) - { - var = xcalloc (1, sizeof *var + strlen (name)); - strcpy (var->name, name); - var->next = variable_list; - variable_list = var; - } - else - free (var->value); - - if (var->type == VARTYPE_FD && var->value) - { - int fd; - - fd = atoi (var->value); - if (fd != -1 && fd != 0 && fd != 1 && fd != 2) - close (fd); - } - - var->type = type; - var->count = 0; - if (var->type == VARTYPE_COUNTER) - { - /* We need some extra sapce as scratch area for get_var. */ - var->value = xmalloc (strlen (value) + 1 + 20); - strcpy (var->value, value); - } - else - var->value = xstrdup (value); -} - -static void -set_var (const char *name, const char *value) -{ - set_type_var (name, value, 0); -} - - -static const char * -get_var (const char *name) -{ - VARIABLE var; - - for (var=variable_list; var && strcmp (var->name, name); var = var->next) - ; - if (!var) - return NULL; - if (var->type == VARTYPE_COUNTER && var->value) - { /* Use the scratch space allocated by set_var. */ - char *p = var->value + strlen(var->value)+1; - sprintf (p, "%u", var->count); - return p; - } - else - return var->value; -} - - -/* Incremente all counter type variables with NAME in their VALUE. */ -static void -inc_counter (const char *name) -{ - VARIABLE var; - - if (!*name) - return; - for (var=variable_list; var; var = var->next) - { - if (var->type == VARTYPE_COUNTER - && var->value && !strcmp (var->value, name)) - var->count++; - } -} - - -/* Expand variables in LINE and return a new allocated buffer if - required. The function might modify LINE if the expanded version - fits into it. */ -static char * -expand_line (char *buffer) -{ - char *line = buffer; - char *p, *pend; - const char *value; - size_t valuelen, n; - char *result = NULL; - - while (*line) - { - p = strchr (line, '$'); - if (!p) - return result; /* nothing more to expand */ - - if (p[1] == '$') /* quoted */ - { - memmove (p, p+1, strlen (p+1)+1); - line = p + 1; - continue; - } - for (pend=p+1; *pend && !spacep (pend) - && *pend != '$' && *pend != '/'; pend++) - ; - if (*pend) - { - int save = *pend; - *pend = 0; - value = get_var (p+1); - *pend = save; - } - else - value = get_var (p+1); - if (!value) - value = ""; - valuelen = strlen (value); - if (valuelen <= pend - p) - { - memcpy (p, value, valuelen); - p += valuelen; - n = pend - p; - if (n) - memmove (p, p+n, strlen (p+n)+1); - line = p; - } - else - { - char *src = result? result : buffer; - char *dst; - - dst = xmalloc (strlen (src) + valuelen + 1); - n = p - src; - memcpy (dst, src, n); - memcpy (dst + n, value, valuelen); - n += valuelen; - strcpy (dst + n, pend); - line = dst + n; - free (result); - result = dst; - } - } - return result; -} - - -/* Evaluate COND and return the result. */ -static int -eval_boolean (const char *cond) -{ - int true = 1; - - for ( ; *cond == '!'; cond++) - true = !true; - if (!*cond || (*cond == '0' && !cond[1])) - return !true; - return true; -} - - - - - -static void -cmd_let (const char *assign_to, char *arg) -{ - set_var (assign_to, arg); -} - - -static void -cmd_echo (const char *assign_to, char *arg) -{ - if (!opt_no_echo) - printf ("%s\n", arg); -} - -static void -cmd_send (const char *assign_to, char *arg) -{ - if (opt_verbose) - fprintf (stderr, "sending `%s'\n", arg); - write_assuan (server_send_fd, arg); -} - -static void -handle_status_line (char *arg) -{ - char *p; - - for (p=arg; *p && !spacep (p); p++) - ; - if (*p) - { - int save = *p; - *p = 0; - inc_counter (arg); - *p = save; - } - else - inc_counter (arg); -} - -static void -cmd_expect_ok (const char *assign_to, char *arg) -{ - if (opt_verbose) - fprintf (stderr, "expecting OK\n"); - do - { - char *p = read_assuan (server_recv_fd); - if (opt_verbose > 1) - fprintf (stderr, "got line `%s'\n", recv_line); - if (recv_type == LINE_STAT) - handle_status_line (p); - } - while (recv_type != LINE_OK && recv_type != LINE_ERR); - if (recv_type != LINE_OK) - die ("expected OK but got `%s'", recv_line); -} - -static void -cmd_expect_err (const char *assign_to, char *arg) -{ - if (opt_verbose) - fprintf (stderr, "expecting ERR\n"); - do - { - char *p = read_assuan (server_recv_fd); - if (opt_verbose > 1) - fprintf (stderr, "got line `%s'\n", recv_line); - if (recv_type == LINE_STAT) - handle_status_line (p); - } - while (recv_type != LINE_OK && recv_type != LINE_ERR); - if (recv_type != LINE_ERR) - die ("expected ERR but got `%s'", recv_line); -} - -static void -cmd_count_status (const char *assign_to, char *arg) -{ - char *p; - - if (!*assign_to || !*arg) - die ("syntax error: count-status requires an argument and a variable"); - - for (p=arg; *p && !spacep (p); p++) - ; - if (*p) - { - for (*p++ = 0; spacep (p); p++) - ; - if (*p) - die ("cmpfiles: syntax error"); - } - set_type_var (assign_to, arg, VARTYPE_COUNTER); -} - -static void -cmd_openfile (const char *assign_to, char *arg) -{ - int fd; - char numbuf[20]; - - do - fd = open (arg, O_RDONLY); - while (fd == -1 && errno == EINTR); - if (fd == -1) - die ("error opening `%s': %s", arg, strerror (errno)); - - sprintf (numbuf, "%d", fd); - set_type_var (assign_to, numbuf, VARTYPE_FD); -} - -static void -cmd_createfile (const char *assign_to, char *arg) -{ - int fd; - char numbuf[20]; - - do - fd = open (arg, O_WRONLY|O_CREAT|O_TRUNC, 0666); - while (fd == -1 && errno == EINTR); - if (fd == -1) - die ("error creating `%s': %s", arg, strerror (errno)); - - sprintf (numbuf, "%d", fd); - set_type_var (assign_to, numbuf, VARTYPE_FD); -} - - -static void -cmd_pipeserver (const char *assign_to, char *arg) -{ - if (!*arg) - die ("syntax error: servername missing"); - - start_server (arg); -} - - -static void -cmd_quit_if(const char *assign_to, char *arg) -{ - if (eval_boolean (arg)) - exit (0); -} - -static void -cmd_fail_if(const char *assign_to, char *arg) -{ - if (eval_boolean (arg)) - exit (1); -} - - -static void -cmd_cmpfiles (const char *assign_to, char *arg) -{ - char *p = arg; - char *second; - FILE *fp1, *fp2; - char buffer1[2048]; /* note: both must be of equal size. */ - char buffer2[2048]; - size_t nread1, nread2; - int rc = 0; - - set_var (assign_to, "0"); - for (p=arg; *p && !spacep (p); p++) - ; - if (!*p) - die ("cmpfiles: syntax error"); - for (*p++ = 0; spacep (p); p++) - ; - second = p; - for (; *p && !spacep (p); p++) - ; - if (*p) - { - for (*p++ = 0; spacep (p); p++) - ; - if (*p) - die ("cmpfiles: syntax error"); - } - - fp1 = fopen (arg, "rb"); - if (!fp1) - { - err ("can't open `%s': %s", arg, strerror (errno)); - return; - } - fp2 = fopen (second, "rb"); - if (!fp2) - { - err ("can't open `%s': %s", second, strerror (errno)); - fclose (fp1); - return; - } - while ( (nread1 = fread (buffer1, 1, sizeof buffer1, fp1))) - { - if (ferror (fp1)) - break; - nread2 = fread (buffer2, 1, sizeof buffer2, fp2); - if (ferror (fp2)) - break; - if (nread1 != nread2 || memcmp (buffer1, buffer2, nread1)) - { - rc = 1; - break; - } - } - if (feof (fp1) && feof (fp2) && !rc) - { - if (opt_verbose) - err ("files match"); - set_var (assign_to, "1"); - } - else if (!rc) - err ("cmpfiles: read error: %s", strerror (errno)); - else - err ("cmpfiles: mismatch"); - fclose (fp1); - fclose (fp2); -} - -static void -cmd_getenv (const char *assign_to, char *arg) -{ - const char *s; - s = *arg? getenv (arg):""; - set_var (assign_to, s? s:""); -} - - - - -/* Process the current script line LINE. */ -static int -interpreter (char *line) -{ - static struct { - const char *name; - void (*fnc)(const char*, char*); - } cmdtbl[] = { - { "let" , cmd_let }, - { "echo" , cmd_echo }, - { "send" , cmd_send }, - { "expect-ok" , cmd_expect_ok }, - { "expect-err", cmd_expect_err }, - { "count-status", cmd_count_status }, - { "openfile" , cmd_openfile }, - { "createfile", cmd_createfile }, - { "pipeserver", cmd_pipeserver }, - { "quit" , NULL }, - { "quit-if" , cmd_quit_if }, - { "fail-if" , cmd_fail_if }, - { "cmpfiles" , cmd_cmpfiles }, - { "getenv" , cmd_getenv }, - { NULL } - }; - char *p, *save_p; - int i, save_c; - char *stmt = NULL; - char *assign_to = NULL; - char *must_free = NULL; - - for ( ;spacep (line); line++) - ; - if (!*line || *line == '#') - return 0; /* empty or comment */ - p = expand_line (line); - if (p) - { - must_free = p; - line = p; - for ( ;spacep (line); line++) - ; - if (!*line || *line == '#') - { - free (must_free); - return 0; /* empty or comment */ - } - } - for (p=line; *p && !spacep (p) && *p != '='; p++) - ; - if (*p == '=') - { - *p = 0; - assign_to = line; - } - else if (*p) - { - for (*p++ = 0; spacep (p); p++) - ; - if (*p == '=') - assign_to = line; - } - if (!*line) - die ("syntax error"); - stmt = line; - save_c = 0; - save_p = NULL; - if (assign_to) - { /* this is an assignment */ - for (p++; spacep (p); p++) - ; - if (!*p) - { - unset_var (assign_to); - free (must_free); - return 0; - } - stmt = p; - for (; *p && !spacep (p); p++) - ; - if (*p) - { - save_p = p; - save_c = *p; - for (*p++ = 0; spacep (p); p++) - ; - } - } - for (i=0; cmdtbl[i].name && strcmp (stmt, cmdtbl[i].name); i++) - ; - if (!cmdtbl[i].name) - { - if (!assign_to) - die ("invalid statement `%s'\n", stmt); - if (save_p) - *save_p = save_c; - set_var (assign_to, stmt); - free (must_free); - return 0; - } - - if (cmdtbl[i].fnc) - cmdtbl[i].fnc (assign_to, p); - free (must_free); - return cmdtbl[i].fnc? 0:1; -} - - - -int -main (int argc, char **argv) -{ - char buffer[2048]; - char *p, *pend; - - if (!argc) - invocation_name = "asschk"; - else - { - invocation_name = *argv++; - argc--; - p = strrchr (invocation_name, '/'); - if (p) - invocation_name = p+1; - } - - - set_var ("?","1"); /* defaults to true */ - - for (; argc; argc--, argv++) - { - p = *argv; - if (*p != '-') - break; - if (!strcmp (p, "--verbose")) - opt_verbose++; - else if (!strcmp (p, "--no-echo")) - opt_no_echo++; - else if (*p == '-' && p[1] == 'D') - { - p += 2; - pend = strchr (p, '='); - if (pend) - { - int tmp = *pend; - *pend = 0; - set_var (p, pend+1); - *pend = tmp; - } - else - set_var (p, "1"); - } - else if (*p == '-' && p[1] == '-' && !p[2]) - { - argc--; argv++; - break; - } - else - break; - } - if (argc) - die ("usage: asschk [--verbose] {-D[=]}"); - - - while (fgets (buffer, sizeof buffer, stdin)) - { - p = strchr (buffer,'\n'); - if (!p) - die ("incomplete script line"); - *p = 0; - if (interpreter (buffer)) - break; - fflush (stdout); - } - return 0; -} - diff --git a/tests/cert_cci_sphinx_ca.pem b/tests/cert_cci_sphinx_ca.pem deleted file mode 100644 index b426c2f33..000000000 --- a/tests/cert_cci_sphinx_ca.pem +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIEOp0SzjANBgkqhkiG9w0BAQUFADAzMQswCQYDVQQGEwJERTERMA8G -A1UEChQIVEVTVF9QS0kxETAPBgNVBAMUCFRFU1RfUENBMB4XDTAxMDIyODE1MDEzNFoXDTAx -MDQxMTE0MDEzNFowNDELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMRIwEAYDVQQD -EwlTUEhJTlgtQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAP9STo2ReixFod9ItCJJ -QtmAs0Emajr9SvKmE8xzHmEmOP1rZzYZtqkSScIeVaOD1+6GMhNLHGxn+laAbANuxbV489yF -XjpiKlFKOKTzUyuZOO9BJDnRGaSyRyKICK9787RkP377lorO1eziqkCoxP75NIqVlOjajHVH -z0pzZCNNAgMBAAGjgeowgecwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8BAf8EBAMCAQYw -FgYDVR0gBA8wDTALBgkrBgEEAbMBAQEwTAYDVR0fBEUwQzBBoD+gPYY7bGRhcDovLy9jbj1U -RVNUX1BDQSxvPVRFU1RfUEtJLGM9REU/YXV0aG9yaXR5UmV2b2NhdGlvbkxpc3QwSAYDVR0j -BEEwP6E3pDUwMzELMAkGA1UEBhMCREUxETAPBgNVBAoUCFRFU1RfUEtJMREwDwYDVQQDFAhU -RVNUX1BDQYIEOo0HwTARBgNVHQ4ECgQITJJvsx0o58QwDQYJKoZIhvcNAQEFBQADggEBAHjK -fRKOo2uzIyVH5s8ii+hIqJiPL6Z06siqo0XeVxoY3BTtfMo089q1krWJuSIoUPSeg4+OG7Go -Ga3qb33TF7zghUayLwWt4vsXBYkrU5VEEc6jN4NO80rPHsaMHPfGDko5BKmeXVkHPOBaFVLk -I6BuOCNQtRQrVaCbeEjqJkAWJtYG4Yhh63Vyv+bpfMfbm8oBE186pnUxZT1XHynIvrh5gjlX -9sbqqPPd5VqAmql+j4Hy1eC2XpU8JOqX1mif5uIdz0a8FtJP4bBX9lwL3zIhTtNOGiMYKxbT -TOpjDRA9dfpYS7qEq3kYNtqttfAxS67iq1BHafjskOF9jaStk+Y= ------END CERTIFICATE----- diff --git a/tests/cert_cci_test_wzs.pem b/tests/cert_cci_test_wzs.pem deleted file mode 100644 index 7ba60ce0c..000000000 --- a/tests/cert_cci_test_wzs.pem +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN CERTIFICATE----- -LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEw -RlVSUzB0TFMwdENnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= ------END CERTIFICATE----- diff --git a/tests/cert_cci_test_zs.pem b/tests/cert_cci_test_zs.pem deleted file mode 100644 index 025a22c8c..000000000 --- a/tests/cert_cci_test_zs.pem +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICyzCCAjSgAwIBAgIBBTANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxGDAWBgNVBAMTD1NQSElOWC1UZXN0LVdaUzAeFw0wMTA4MjQxMDA5MDNa -Fw0wMzA4MjQxMDA5MDNaMDkxCzAJBgNVBAYTAkRFMREwDwYDVQQKEwhDQ0kgR21iSDEXMBUG -A1UEAxMOU1BISU5YLVRlc3QtWlMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAP+E1LeX -nwq5qAmfHX+zfabAaeMR9Ufow/1ojNg8md+XGVUFJ0a9GZJVQ4ngmxKHmO+6fT77Z0Sj7BQT -bxLbZEqvBxYDSoJgN6K7q2LdbTPIKMOzVF+TxtNyauZx+yxJxTMYYkyVmAlfjAx8Wlznf8Aj -kZywmjVtYWpoN0WedGsbAgMBAAGjgeEwgd4wVwYDVR0fBFAwTjBMoEqgSIZGbGRhcDovLy9j -bj1TUEhJTlgtVGVzdC1XWlMsIG89Q0NJIEdtYkgsIEM9REU/Y2VydGlmaWNhdGVSZXZvY2F0 -aW9uTGlzdDASBgNVHRMBAf8ECDAGAQH/AgEAMBEGA1UdIAQKMAgwBgYEgnEJCTAOBgNVHQ8B -Af8EBAMCAQYwTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBH -bWJIMRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQEwDQYJKoZIhvcNAQEFBQADgYEAGWjq -TsoWQmUiY3c5Tju+jL51AapWWZbZP8xpBTFjXNRQcRPzWrtHCWS3fhae+aMyGFxiqEhGLePc -QvNdgZmZtzNYSfmeS3iji3zSj7CFmUQKwFrAXUDQNvkS+87FwVno8LilnC0zMfhSW699HtWe -DW/o0CuhXX6IJXXWuSudCH8= ------END CERTIFICATE----- diff --git a/tests/cert_cci_user02.pem b/tests/cert_cci_user02.pem deleted file mode 100644 index b1fba0df7..000000000 --- a/tests/cert_cci_user02.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBDCCAm2gAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxFzAVBgNVBAMTDlNQSElOWC1UZXN0LVpTMB4XDTAxMTIxMTA3MTYyMloX -DTAyMTIxMTA3MTYyMlowODELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMRYwFAYD -VQQDEw1TcGhpbnggVXNlcjAyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD+Gt/ahGJL -uEUVFgceVUsShMgJirndaGjJb/kR3cHQ4Yh4XM9WvP2ze6SRb1cn3Xq9bR1RTFwRoupp9h94 -OwhxjhOTKtTtwFv/OcffJPwAF6K+ms5s8oSBzNX6mo+sLwoVWHaXaSP7rzvOhvYPJpCE6zrS -GO4aUcH50f63wusSKQIDAQABo4IBGzCCARcwVgYDVR0fBE8wTTBLoEmgR4ZFbGRhcDovLy9j -bj1TUEhJTlgtVGVzdC1aUywgbz1DQ0kgR21iSCwgYz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRp -b25MaXN0MAwGA1UdEwEB/wQCMAAwHwYDVR0RBBgwFoEUc3BoaW54X3VzZXIwMkBjY2kuZGUw -EQYDVR0gBAowCDAGBgSCcQkJMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQUZpxNoy1I5cIT -OmeF8LSUJjWnlaowTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCEND -SSBHbWJIMRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQUwDQYJKoZIhvcNAQEFBQADgYEA -UU1L9U5LOBaa99Q2ogsLS3PuSOhMKSKWwK+rG5YzNGh9L3+Ecp6/cdZeGY8IV4kQHx2YDhon -tX+SfEnAU5WKN+YfxbLQz5jbDYeyIkFXPFn4Pzt4+1gFLOVvdHFJKT6tb0ZbbLkJkrK+gf29 -sFHz/tVEIiwvWdzCQh669TvmSLc= ------END CERTIFICATE----- diff --git a/tests/cert_cci_user03.pem b/tests/cert_cci_user03.pem deleted file mode 100644 index 44a8510d2..000000000 --- a/tests/cert_cci_user03.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBDCCAm2gAwIBAgIBHzANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxFzAVBgNVBAMTDlNQSElOWC1UZXN0LVpTMB4XDTAxMTIxMTA4NDMwNVoX -DTAyMTIxMTA4NDMwNVowODELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMRYwFAYD -VQQDEw1TcGhpbnggVXNlcjAzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDWLHGzEVlh -NKr5RkWi80jZpuVg20C+1W4H/ez2fuGP8IXZAyy6MYPLQSsFuuwfTtLwFDccJ4PubN/JhSLj -37/AGyygJODQd41CcQxLyB4NqhsYz+dXJv/Rx/E9HDbgsf7fCVwmCpF71phTzeq+zzJYYlDK -uLLvr2auODr4h24jSwIDAQABo4IBGzCCARcwVgYDVR0fBE8wTTBLoEmgR4ZFbGRhcDovLy9j -bj1TUEhJTlgtVGVzdC1aUywgbz1DQ0kgR21iSCwgYz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRp -b25MaXN0MAwGA1UdEwEB/wQCMAAwHwYDVR0RBBgwFoEUc3BoaW54X3VzZXIwM0BjY2kuZGUw -EQYDVR0gBAowCDAGBgSCcQkJMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQU04AGVPNiznW2 -ZoKD0hqNulIe0zIwTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCEND -SSBHbWJIMRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQUwDQYJKoZIhvcNAQEFBQADgYEA -qvifydhixBkVQ0ZesWHXVDwhPOjWtHMuYafMP+9Vn46HCqsbl4gnQqwdwHKl2ox4qd4VOOu8 -PmfKgLysWq11tp/+LCFIEDSLHKCQ1YpBaAxbBg4JxqeTXDF3a3u1RnYOEaVhMZ6L91u16vHT -MJ93W8Fphgf2Fj7EUBPhpyhsnKw= ------END CERTIFICATE----- diff --git a/tests/cert_cci_user04.pem b/tests/cert_cci_user04.pem deleted file mode 100644 index e76880162..000000000 --- a/tests/cert_cci_user04.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBDCCAm2gAwIBAgIBGzANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxFzAVBgNVBAMTDlNQSElOWC1UZXN0LVpTMB4XDTAxMTIxMTA3MTIxM1oX -DTAyMTIxMTA3MTIxM1owODELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMRYwFAYD -VQQDEw1TcGhpbnggVXNlcjA0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDrExMHDJKt -W6ByaO3hVYJCZXJmyMAhHxm31yLXzbd2V5R3Q6ZH4ARk00AMRPDgPLf/NK913OcUFJDrlhLh -aVUfdtz7V095S6Xl38gaClidx2ZJ2EwM4pNxCDeWS1ZFsJMGcis74L5QGrn3/L+76psz7erW -usP+qwy3+3HzL6/hWQIDAQABo4IBGzCCARcwVgYDVR0fBE8wTTBLoEmgR4ZFbGRhcDovLy9j -bj1TUEhJTlgtVGVzdC1aUywgbz1DQ0kgR21iSCwgYz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRp -b25MaXN0MAwGA1UdEwEB/wQCMAAwHwYDVR0RBBgwFoEUc3BoaW54X3VzZXIwNEBjY2kuZGUw -EQYDVR0gBAowCDAGBgSCcQkJMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQU/UkAw08BpS4w -bM1Eo5MTX21niG4wTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCEND -SSBHbWJIMRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQUwDQYJKoZIhvcNAQEFBQADgYEA -3mZM7XFH3CuiGQYe7Wrom+t/QH9BWwORHrskGiVyzBh5Z40HboB8vIN6I6CrQYJHK9DGKnAL -x5AjZ8MUUG3le5M2G6QdhbtGW0jZg5nF1LHx8QYIx8NJSoYa6uPcfr7Q9WgMvTcmA+gXGgzY -Uqv0AMWOx0f3ww0gUpFYIp22ZCc= ------END CERTIFICATE----- diff --git a/tests/cert_cci_user06.pem b/tests/cert_cci_user06.pem deleted file mode 100644 index 7026112b4..000000000 --- a/tests/cert_cci_user06.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDBDCCAm2gAwIBAgIBIzANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxFzAVBgNVBAMTDlNQSElOWC1UZXN0LVpTMB4XDTAxMTIxMTEyNDMwNVoX -DTAyMTIxMTEyNDMwNVowODELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMRYwFAYD -VQQDEw1TcGhpbnggVXNlcjA2MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCQ/o0hz0Uz -OGOUfDkzeburb1AO9VChEkO+x8ROoepsjJjkNDtC/4924biA8irfAymzqWP/QwQryS4+Zy6S -O9Jl4yoYNswoZuVhTc+WBkjFMC6qz/Y8mZZb5Fgysf+KAz0Swm0FlWjCYNMcWUp4FHJluG1m -iBarOZRharIVj+HNBwIDAQABo4IBGzCCARcwVgYDVR0fBE8wTTBLoEmgR4ZFbGRhcDovLy9j -bj1TUEhJTlgtVGVzdC1aUywgbz1DQ0kgR21iSCwgYz1ERT9jZXJ0aWZpY2F0ZVJldm9jYXRp -b25MaXN0MAwGA1UdEwEB/wQCMAAwHwYDVR0RBBgwFoEUc3BoaW54X3VzZXIwNkBjY2kuZGUw -EQYDVR0gBAowCDAGBgSCcQkJMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQUSIIT/NH6GsX/ -f1C44FyKEokGNVswTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCEND -SSBHbWJIMRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQUwDQYJKoZIhvcNAQEFBQADgYEA -aBq+Qi0+Cb8XpnZqUITOmRC9VspxnMcE5IskEtbb2aCU2WkCGCTYMrVzug3BIKo4eNnOHl4k -2oKL8tANapawZSMQb3DtnAvQykYK9DAMYjojOao/2doYKNFoUszg1k+PI+Q1IuV4VjM79R9s -OwpipIj2q08Kx0NrliREuzB75Sg= ------END CERTIFICATE----- diff --git a/tests/cert_cci_user07.pem b/tests/cert_cci_user07.pem deleted file mode 100644 index 2dfadf872..000000000 --- a/tests/cert_cci_user07.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIC/jCCAmegAwIBAgIBIDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJERTERMA8GA1UE -ChMIQ0NJIEdtYkgxFzAVBgNVBAMTDlNQSElOWC1UZXN0LVpTMB4XDTAxMTIxMTA4NTgzOFoX -DTAyMTIxMTA4NTgzOFowMzELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJIMREwDwYD -VQQDEwhTcGhpbngwNzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtV86FCbl5CQqthMK -vjWjCFOfQZW2v66oiIuE/WZjyOIu1n4FC6z0+pI3FmeKrKhiYeXP8A2J/BzwS9ZD+0as5EyU -+QUzMPdm8pkzvkZCUPKRVi2cyRrBwwqnhH8Bwk2L2o2WMe46D3WBx4hSG+vhQvNMP4nrIGbs -oh+3XJjkoXcCAwCnU6OCARowggEWMFYGA1UdHwRPME0wS6BJoEeGRWxkYXA6Ly8vY249U1BI -SU5YLVRlc3QtWlMsIG89Q0NJIEdtYkgsIGM9REU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlz -dDAMBgNVHRMBAf8EAjAAMB4GA1UdEQQXMBWBE3NwaGlueDA3QGl0cy5jY2kuZGUwEQYDVR0g -BAowCDAGBgSCcQkJMA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQUdyGyVPOTruMiE7OLekoP -8oJttzcwTAYDVR0jBEUwQ6E+pDwwOjELMAkGA1UEBhMCREUxETAPBgNVBAoTCENDSSBHbWJI -MRgwFgYDVQQDEw9TUEhJTlgtVGVzdC1XWlOCAQUwDQYJKoZIhvcNAQEFBQADgYEABjjhOFKV -3cVF7EGsPfnCq9CYjanFr7jhPxEYG0BuY+x1zgpsTkJm4/wk+NhGo/sFjrq7YExkhQgQViGt -9UhnXZQPsayna1lmkwl/edzpR3A1ELbiULTVGdLarP3MmWEMzKl/Z6prbb+cD1Qwb8D5DG+Q -u3E39VxgzG8i9wMSFh8= ------END CERTIFICATE----- diff --git a/tests/cert_testpki_testpca.pem b/tests/cert_testpki_testpca.pem deleted file mode 100644 index 255d6f4af..000000000 --- a/tests/cert_testpki_testpca.pem +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDzDCCArSgAwIBAgIEOo0HwTANBgkqhkiG9w0BAQUFADAzMQswCQYDVQQGEwJERTERMA8G -A1UEChQIVEVTVF9QS0kxETAPBgNVBAMUCFRFU1RfUENBMB4XDTAxMDIxNjExMDAwNloXDTA2 -MDIxNjExMDAwNlowMzELMAkGA1UEBhMCREUxETAPBgNVBAoUCFRFU1RfUEtJMREwDwYDVQQD -FAhURVNUX1BDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANTELO2lGugWqO5B -cLGU61TMZzUoR0yDAhPOjNU/CkLy9x+bDLJFAuvYQOm7SRcbTNcviUyot064ROWCcVn51kNf -+fmZhTyMix36ffcEERO7NaN4ZN7eXi39u9udTfPoQjUpy2tBVOwHlzBdHhklG1hBodqlmbfE -5Yt6ku0jm4wfxoiqgbF2dh9PhuCClt4YuBcnELw52duAKYNiHwfIqrwgDvAdi/J+mdgcxy1Z -xl/oIIVEy5FiQlMkleCDxstuEhVde8/ZzzyDbC+22Ok5xr6wexgUK792G6NZ+q+0BK+9Hqtw -m8/7UHyuUGboyHAT8V7ecgrpEg5rvJgRxtxUYA8CAwEAAaOB5zCB5DAPBgNVHRMBAf8EBTAD -AQH/MBYGA1UdIAQPMA0wCwYJKwYBBAGzAQEBMEwGA1UdHwRFMEMwQaA/oD2GO2xkYXA6Ly8v -Y249VEVTVF9QQ0Esbz1URVNUX1BLSSxjPURFP2F1dGhvcml0eVJldm9jYXRpb25MaXN0MBEG -A1UdDgQKBAhOFXmpxh5ysDBIBgNVHSMEQTA/oTekNTAzMQswCQYDVQQGEwJERTERMA8GA1UE -ChQIVEVTVF9QS0kxETAPBgNVBAMUCFRFU1RfUENBggQ6jQfBMA4GA1UdDwEB/wQEAwIBBjAN -BgkqhkiG9w0BAQUFAAOCAQEAs/wp8umfNLnEQ56DyIAOdWUwgJNrLYK2hk84G+lQKhem+jD0 -BoklUd/DifJxXE6QVFMxjr9aoYjMcloCuYV2jLd0kdebDmFvFNl3O9+mR0br8wHRCXhfPMwg -dThmhdtDs9qfyfStNStLch4F0edDYJtO3XaGWlQk52ykJy3yoyxmDUIzPTIKCV3LYO7bOXfw -FVECQaoO2+HrrZef6d3h3XL7leWhGYZ2YV77yzfZuN41y8aXQKF/1J7mYvpjceUJAyMZCUMz -FLDH4Zj4YGc8OH1xpAvGgztDuPQU8JXJBXuXIL0jmUcJRAZmgbeWWOgGIhYtJ4Stoy0pnHTZ -dcn+jw== ------END CERTIFICATE----- diff --git a/tests/crl_testpki_testpca.pem b/tests/crl_testpki_testpca.pem deleted file mode 100644 index 458c48164..000000000 --- a/tests/crl_testpki_testpca.pem +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDWTCCAkECAQEwDQYJKoZIhvcNAQEFBQAwMzELMAkGA1UEBhMCREUxETAPBgNVBAoUCFRF -U1RfUEtJMREwDwYDVQQDFAhURVNUX1BDQRcNMDIwMTE0MDcwMDI4WhcNMDIwMjE0MDcwMDI4 -WjCCAXIwIwIEOpzbCxcNMDEwMjI4MTQ1NTE5WjAMMAoGA1UdFQQDCgEDMCMCBDr7z9QXDTAx -MDUxNDExMTY0M1owDDAKBgNVHRUEAwoBAzAjAgQ7Cmq5Fw0wMTA1MjkxMzE1NTNaMAwwCgYD -VR0VBAMKAQMwIwIEOxOgZBcNMDEwNjI5MDcwNzMwWjAMMAoGA1UdFQQDCgEDMCMCBDs8KH4X -DTAxMDYyOTA3MTA0MVowDDAKBgNVHRUEAwoBAzAjAgQ7xr4IFw0wMTEwMzAwODIwMDdaMAww -CgYDVR0VBAMKAQAwIwIEO95jKhcNMDExMTA3MTIxNzE2WjAMMAoGA1UdFQQDCgEAMCMCBDvp -JwAXDTAxMTEwNzE0MTEwMFowDDAKBgNVHRUEAwoBAzAjAgQ8GHpuFw0wMTEyMTMxMDAzNTFa -MAwwCgYDVR0VBAMKAQMwIwIEPBh8ihcNMDExMjEzMTAxMjE3WjAMMAoGA1UdFQQDCgEDoGQw -YjALBgNVHRQEBAICAVAwSAYDVR0jBEEwP6E3pDUwMzELMAkGA1UEBhMCREUxETAPBgNVBAoU -CFRFU1RfUEtJMREwDwYDVQQDFAhURVNUX1BDQYIEOo0HwTAJBgNVHRwEAjAAMA0GCSqGSIb3 -DQEBBQUAA4IBAQCCTBKii6N4bX7sH6d3fq6yFbn2Xr5xDbDkpjHYSvHhBnfEnFAQOjOsn9ar -qk8NDUCT4j4AWD//i/9l5YbvY+32/ER32vZ5PDtSyhZ/pHIOaYUy0haf2pwDSXf7ESZKUM5a -O8UOVBlXhniClnakZHI6z7r7Md5xIJ5C2W8JaLUswiycvyMg37eM6a+d+J+ZlFXQZNO/9cfN -ItcSCBaRgUWm4LNdTJllNeZ9HMBOJ3pgS7yta4WNQi2mNgRzCcJJuVm5qmXo/9v7hMLmL+pb -YUPnQIfyjYmJK0ea+8KsKsgIKtiU8xteqTxPQ3VJBbH7ChcO4SMUPq5yL3otGZu5zOoQ ------END CERTIFICATE----- diff --git a/tests/inittests b/tests/inittests deleted file mode 100755 index b1860f5fd..000000000 --- a/tests/inittests +++ /dev/null @@ -1,96 +0,0 @@ -#!/bin/sh -# Copyright (C) 2002 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. - -set -e - -sample_certs=' -cert_g10code_test1.pem -cert_g10code_pete1.pem -cert_g10code_theo1.pem -' - -private_keys=' -32100C27173EF6E9C4E9A25D3D69F86D37A4F939 -' - -clean_files=' -gpgsm.conf gpg-agent.conf trustlist.txt pubring.kbx -msg msg.sig msg.unsig -' - - -[ -z "$srcdir" ] && srcdir=. -[ -z "$GPGSM" ] && GPGSM=../sm/gpgsm - -if [ -d $srcdir/samplekeys ] \ - && grep TESTS_ENVIRONMENT Makefile >/dev/null 2>&1; then - : -else - # During make distclean the Makefile has already been removed, - # so we need this extra test. - if ! grep gnupg-test-directory testdir.stamp >/dev/null 2>&1; then - echo "inittests: please cd to the tests directory first" >&2 - exit 1 - fi -fi - -if [ "$1" = "--clean" ]; then - if [ -d private-keys-v1.d ]; then - rm private-keys-v1.d/* 2>/dev/null || true - rmdir private-keys-v1.d - fi - rm ${clean_files} testdir.stamp 2>/dev/null || true - exit 0 -fi - -if [ "$GNUPGHOME" != "`pwd`" ]; then - echo "inittests: please set GNUPGHOME to the test directory" >&2 - exit 1 -fi - -if [ -n "$GPG_AGENT_INFO" ]; then - echo "inittests: please unset GPG_AGENT_INFO" >&2 - exit 1 -fi - -# A stamp file used with --clean -echo gnupg-test-directory > testdir.stamp - - -# Create the private key directy if it does not exists and copy -# the sample keys. -[ -d private-keys-v1.d ] || mkdir private-keys-v1.d -for i in ${private_keys}; do - cat ${srcdir}/samplekeys/$i.key >private-keys-v1.d/$i.key -done - -# Create the configuration scripts -cat > gpgsm.conf < gpg-agent.conf < trustlist.txt < - - - E76B5D4BA2CF0B05BBBE425CDBF4E9DC4904941D - 0 - 1024 - 1017250241 - 1048786241 - - - 1.2.840.113549.1.9.1=#7468656F62616C642E7469676572406B6572636B686F6666732E673130636F64652E6465,CN=Theobald Tiger,OU=Kerckhoffs Testlab,O=g10 Code GmbH,L=Düsseldorf,ST=NRW,C=de - - - - ------BEGIN CERTIFICATE----- -MIID9DCCA12gAwIBAgIBADANBgkqhkiG9w0BAQQFADCBszELMAkGA1UEBhMCZGUx -DDAKBgNVBAgTA05SVzETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEw -IENvZGUgR21iSDEbMBkGA1UECxMSS2VyY2tob2ZmcyBUZXN0bGFiMRcwFQYDVQQD -Ew5UaGVvYmFsZCBUaWdlcjEzMDEGCSqGSIb3DQEJARYkdGhlb2JhbGQudGlnZXJA -a2VyY2tob2Zmcy5nMTBjb2RlLmRlMB4XDTAyMDMyNzE3MzA0MVoXDTAzMDMyNzE3 -MzA0MVowgbMxCzAJBgNVBAYTAmRlMQwwCgYDVQQIEwNOUlcxEzARBgNVBAcUCkT8 -c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGzAZBgNVBAsTEktlcmNr -aG9mZnMgVGVzdGxhYjEXMBUGA1UEAxMOVGhlb2JhbGQgVGlnZXIxMzAxBgkqhkiG -9w0BCQEWJHRoZW9iYWxkLnRpZ2VyQGtlcmNraG9mZnMuZzEwY29kZS5kZTCBnzAN -BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2N+6T7awrnWhg1g+HIE8TGn3e8OOkqmE -v2k7uazL2aGUIk2Omg+2Jjq2dovotiSAjoVQFtJ+Ahk4aiGFA4Zdp34ZzijpXhD+ -+xbFt1Vz/zBWlExpN9A5m2XPAbcW5rTMcl9O6jXKgu4sLDXOGOVCSOIpaQGwB3g3 -ti/p7J4lvFcCAwEAAaOCARQwggEQMB0GA1UdDgQWBBQTVJsLsvwdrA5XJMZyCECy -gFdHGzCB4AYDVR0jBIHYMIHVgBQTVJsLsvwdrA5XJMZyCECygFdHG6GBuaSBtjCB -szELMAkGA1UEBhMCZGUxDDAKBgNVBAgTA05SVzETMBEGA1UEBxQKRPxzc2VsZG9y -ZjEWMBQGA1UEChMNZzEwIENvZGUgR21iSDEbMBkGA1UECxMSS2VyY2tob2ZmcyBU -ZXN0bGFiMRcwFQYDVQQDEw5UaGVvYmFsZCBUaWdlcjEzMDEGCSqGSIb3DQEJARYk -dGhlb2JhbGQudGlnZXJAa2VyY2tob2Zmcy5nMTBjb2RlLmRlggEAMAwGA1UdEwQF -MAMBAf8wDQYJKoZIhvcNAQEEBQADgYEASILHzi6O8Gf4Xd98FFtln3FGLhlHlxKV -xuO4Qn+qcBN7dFfQE3B/WKRR5jC8NTZHgGzAzcVv/ha2AAVs/zbSxE6lU04OOSJv -qm9lo6lsm5P+C/NH/hSdlUfSoKbmt5ZAPYpOhHvmPQpLi4Iv4hjeFqoCN5OVXOXN -OSgvBzegSSA= ------END CERTIFICATE----- diff --git a/tests/skey_g10code_test1.pem b/tests/skey_g10code_test1.pem deleted file mode 100644 index 9f2db8e68..000000000 --- a/tests/skey_g10code_test1.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,CFA7DAB8D1EEDCFF - -KTLOYLEGXYFQ63WnUsqFp/vM5HWsJq758AQ5RaYp7jbtCoZdrSp5GovmLUBTPfR+ -hjfcJgGlyWIPDhPAcOObz2XnnpzcKEfmPKR/W+Ou7DFX/6WUh1xwzHq+ddPnCMHJ -vfhx2iMf0e4Y9ZMATBPcU0YIE/Rp9F4wmMKmEAGtAPOSMNdvH17KHlNLXsX+VlXf -scGi9Hr0KFcC/5ehA3J40vBlAg6oZeXwNuERX1PXOpAIlcGY0RklJhTvTBonCfaV -7+CrfggFed3/b7QuqsNTlRdmW3ctf2rqNoFFIhRB5OVQsLG4CrzIQMdzxMqlZrGd -Eks+0HLOMGO41ioaenz6015ClHORpAf3VXN8NUUrrDAvJL2HVlqFgDBCi9qi9Dp2 -TuVePAkJlpBYodgIdwvLN//dav6ZJ+FOOk3A5AnKOtNyTGO4I2Bz8nAS3JpVudk9 -ca8CEIIj52dEric6YMiBFokoiIEgMOI/6wjatDL1Yldev+kjH/el+FZT4jZm2lvQ -l1xbg4sqmPNSyIKSv8V95gO2W5E5V9kO/MBiad2GdX4qrVT1c/LwFC96t+tZKFxr -rHdN31CzZE3bHnXxvss3ai+k9IO1NZHfeeb9uqSmGd3AxbmBwWA50bxCsee+HP0R -ihU2BE5NKdlw1faBk+DPVT569uScO4PDc6Jd4fh7g7oBzLhhhcCqNnLEZh8lqa3L -rsb880baq8dm72cz8IXj//x5AppfCz8M8od/UkaQ0/pN2GGTpe4qSPPK0YJ/4MfR -f9jdMbZA6O8si3t7I4jOF2z1UHkFGaseax54ILTsTVE= ------END RSA PRIVATE KEY----- - diff --git a/tests/sm-sign+verify b/tests/sm-sign+verify deleted file mode 100644 index 1c3ae7dbd..000000000 --- a/tests/sm-sign+verify +++ /dev/null @@ -1,73 +0,0 @@ -# sm-sign+verify -# -# Creating a signature and verifying it -# Requirements: a plain file "text-1.txt" - -srcdir = getenv srcdir -plaintext = let $srcdir/text-1.txt - -in = openfile $plaintext -out = createfile msg.sig -in2 = openfile msg.sig -out2 = createfile msg.unsig - -pipeserver $GPGSM -send INPUT FD=$in -expect-ok -send OUTPUT FD=$out -expect-ok -send SIGN -expect-ok - -send RESET -expect-ok -send INPUT FD=$in2 -expect-ok -send OUTPUT FD=$out2 -expect-ok -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo goodsig=$goodsig trusted=$trusted -fail-if !$goodsig -fail-if !$trusted -send BYE -expect-ok - -# Unset variables so that the files get closed. -in = -out = -in2 = -out2= - -cmpfiles $plaintext msg.unsig -fail-if !$? - -# Lets check it again with a new server instance, this time we keep -# the server running to check whether the entire message has been -# output after the VERIFY. -in = openfile msg.sig -out = createfile msg.unsig -pipeserver $GPGSM -send INPUT FD=$in -expect-ok -send OUTPUT FD=$out -expect-ok -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo goodsig=$goodsig trusted=$trusted -fail-if !$goodsig -fail-if !$trusted - -cmpfiles $plaintext msg.unsig -fail-if !$? - -send BYE -expect-ok - - -quit - diff --git a/tests/sm-verify b/tests/sm-verify deleted file mode 100644 index b06dc16a4..000000000 --- a/tests/sm-verify +++ /dev/null @@ -1,114 +0,0 @@ -# sm-verify -# -# Verify a few distributed signatures. -# Requirements: -# - -srcdir = getenv srcdir - -# Check an opaque signature -sig = openfile $srcdir/text-1.osig.pem -out = createfile msg.unsig -pipeserver $GPGSM -send INPUT FD=$sig -expect-ok -send OUTPUT FD=$out -expect-ok -badsig = count-status BADSIG -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo badsig=$badsig goodsig=$goodsig trusted=$trusted -fail-if $badsig -fail-if !$goodsig -fail-if !$trusted -send BYE -expect-ok - -sig = -out = -cmpfiles $srcdir/text-1.txt msg.unsig -fail-if !$? - -# Check a detached signature. -sig = openfile $srcdir/text-1.dsig.pem -plain = openfile $srcdir/text-1.txt -pipeserver $GPGSM -send INPUT FD=$sig -expect-ok -send MESSAGE FD=$plain -expect-ok -badsig = count-status BADSIG -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo badsig=$badsig goodsig=$goodsig trusted=$trusted -fail-if $badsig -fail-if !$goodsig -fail-if !$trusted -send BYE -expect-ok - -# Check a tampered opaque message -sig = openfile $srcdir/text-1.osig-bad.pem -out = createfile msg.unsig - -pipeserver $GPGSM -send INPUT FD=$sig -expect-ok -send OUTPUT FD=$out -expect-ok -badsig = count-status BADSIG -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo badsig=$badsig goodsig=$goodsig trusted=$trusted -fail-if $goodsig -fail-if !$badsig -fail-if $trusted -send BYE -expect-ok - -# Check another opaque signature but without asking for the output. -sig = openfile $srcdir/text-2.osig.pem - -pipeserver $GPGSM -send INPUT FD=$sig -expect-ok -badsig = count-status BADSIG -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo badsig=$badsig goodsig=$goodsig trusted=$trusted -fail-if $badsig -fail-if !$goodsig -fail-if !$trusted -send BYE -expect-ok - -# We als have tampered version. -sig = openfile $srcdir/text-2.osig-bad.pem - -pipeserver $GPGSM -send INPUT FD=$sig -expect-ok -badsig = count-status BADSIG -goodsig = count-status GOODSIG -trusted = count-status TRUST_FULLY -send VERIFY -expect-ok -echo badsig=$badsig goodsig=$goodsig trusted=$trusted -fail-if $goodsig -fail-if !$badsig -fail-if $trusted -send BYE -expect-ok - - -quit - - diff --git a/tests/text-1.dsig.pem b/tests/text-1.dsig.pem deleted file mode 100644 index a031ec259..000000000 --- a/tests/text-1.dsig.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAA -oIIDGTCCAxUwggJ+oAMCAQICAQAwDQYJKoZIhvcNAQEEBQAwazELMAkGA1UEBhMC -REUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgx -GTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAx -MB4XDTAxMTIwMzA5MzYzOFoXDTAyMTIwMzA5MzYzOFowazELMAkGA1UEBhMCREUx -EzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAX -BgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMIGf -MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgzpb5C2yeAvOSK+rak/5QqHXqxrzB -i7mpzy6EllyqLR/5Wn9UJGXGwMGdJ25FJs4EiGinqRT9NDzDqH3XQpH/xWVQbVu7 -Jcusag4t0fi8qrDUopwvN8lQ82NIS/Jp94kUQEZLr3mCfgOjbnC4FJOO69xj6WQk -e+ddxYsBS36iUQIDAQABo4HIMIHFMB0GA1UdDgQWBBQzN40SkcBUcYM4Xwhlv6lL -+Y408zCBlQYDVR0jBIGNMIGKgBQzN40SkcBUcYM4Xwhlv6lL+Y4086FvpG0wazEL -MAkGA1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBD -b2RlIEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rl -c3QgY2VydCAxggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAbIcE -Hoo4qNobF2cWRCBaDZXQ6XcXG1lMLObrTSe4asUK++H59nC/ax+wMnDVrWZ8gkwJ -O1KsHGx98+gjaCR+lP5P/yE5O8PD7TOp8OiYZVyw/guuQYn4qeondibUUMJeJCf7 -T6cfv+NjLpIt8lRTfgRBhT6SOoXSZodR8/NZPBkxggFXMIIBUwIBATBwMGsxCzAJ -BgNVBAYTAkRFMRMwEQYDVQQHFApE/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29k -ZSBHbWJIMRkwFwYDVQQLExBBZWd5cHRlbiBQcm9qZWN0MRQwEgYDVQQDEwt0ZXN0 -IGNlcnQgMQIBADAHBgUrDgMCGqBDMBwGCSqGSIb3DQEJBTEPFw0wMjA4MDgxMjIy -NTRaMCMGCSqGSIb3DQEJBDEWBBR5MsAm+0wJAVQl3AAGYmnpxA4XLjALBgkqhkiG -9w0BAQEEgYAZpBbucgorq56kl2rokCV1EAZcKgylfpEkqSz4RU6qNid+0NtjSAxi -5164wjMLG71U9qSBX4XDdDQPHpH+PPF/8021kne2kPfeP68NiXK8CagdIqlnuJEj -K934mVre7AIjrXqoob1ipUtCWeK+2uHXsUjtUn3u1Y3eWVZ6+1hDTAAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-1.osig-bad.pem b/tests/text-1.osig-bad.pem deleted file mode 100644 index 0b5f4a439..000000000 --- a/tests/text-1.osig-bad.pem +++ /dev/null @@ -1,45 +0,0 @@ -The text in this message has been tampered. - ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCAJIAEggPh -SGlnaCBQcmllc3Q6CUFybWFtZW50cyBDaGFwdGVyIE9uZSwgdmVyc2VzIG5pbmUgdGhyb3Vn -aCB0d2VudHktc2V2ZW46CkJyby4gTWF5bmFyZDoJQW5kIFNhaW50IEF0dGlsYSByYWlzZWQg -dGhlIEhvbHkgSGFuZCBHcmVuYWRlIHVwIG9uIGhpZ2gKCXNheWluZywgIk9oIExvcmQsIEJs -ZXNzIHVzIHRoaXMgSG9seSBIYW5kIEdyZW5hZGUsIGFuZCB3aXRoIGl0CglzbWFzaCBvdXIg -ZW5lbWllcyB0byB0aW55IGJpdHMuIiAgQW5kIHRoZSBMb3JkIGRpZCBncmluLCBhbmQgdGhl -CglwZW9wbGUgZGlkIGZlYXN0IHVwb24gdGhlIGxhbWJzLCBhbmQgc3RvYXRzLCBhbmQgb3Jh -bmd1dGFucywgYW5kCglicmVha2Zhc3QgY2VyZWFscywgYW5kIGxpbWEgYmVhbi0KSGlnaCBQ -cmllc3Q6CVNraXAgYSBiaXQsIHNpc3Rlci4gCkJyby4gTWF5bmFyZDoJQW5kIHRoZW4gdGhl -IExvcmQgc3Bha2UsIHNheWluZzogIkZpcnN0LCBzaGFsdCB0aG91IHRha2UKCW91dCB0aGUg -aG9seSBwaW4uICBUaGVuIHNoYWx0IHRob3UgY291bnQgdG8gdGhyZWUuICBObyBtb3JlLCBu -byBsZXNzLgoJKlRocmVlKiBzaGFsbCBiZSB0aGUgbnVtYmVyIG9mIHRoZSBjb3VudGluZywg -YW5kIHRoZSBudW1iZXIgb2YgdGhlCgljb3VudGluZyBzaGFsbCBiZSB0aHJlZS4gICpGb3Vy -KiBzaGFsdCB0aG91IG5vdCBjb3VudCwgYW5kIG5laXRoZXIKCWNvdW50IHRob3UgdHdvLCBl -eGNlcHRpbmcgdGhhdCB0aG91IHRoZW4gZ29lc3Qgb24gdG8gdGhyZWUuICBGaXZlIGlzCglS -SUdIVCBPVVQuICBPbmNlIHRoZSBudW1iZXIgdGhyZWUsIGJlaW5nIHRoZSB0aGlyZCBudW1i -ZXIgYmUgcmVhY2hlZCwKCXRoZW4gbG9iYmVzdCB0aG91IHRoeSBIb2x5IEhhbmQgR3JlbmFk -ZSB0b3dhcmRzIHRoeSBmb2UsIHdobywgYmVpbmcKCW5hdWdodHkgaW4gbXkgc2lnaHQsIHNo -YWxsIHNudWZmIGl0LiAgQW1lbi4KQWxsOglBbWVuLgoJCS0tIE1vbnR5IFB5dGhvbiwgIlRo -ZSBIb2x5IEhhbmQgR3JlbmFkZSIKAAAAAAAAoIIDGTCCAxUwggJ+oAMCAQICAQAwDQYJKoZI -hvcNAQEEBQAwazELMAkGA1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoT -DWcxMCBDb2RlIEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rl -c3QgY2VydCAxMB4XDTAxMTIwMzA5MzYzOFoXDTAyMTIwMzA5MzYzOFowazELMAkGA1UEBhMC -REUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNV -BAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMIGfMA0GCSqGSIb3 -DQEBAQUAA4GNADCBiQKBgQDgzpb5C2yeAvOSK+rak/5QqHXqxrzBi7mpzy6EllyqLR/5Wn9U -JGXGwMGdJ25FJs4EiGinqRT9NDzDqH3XQpH/xWVQbVu7Jcusag4t0fi8qrDUopwvN8lQ82NI -S/Jp94kUQEZLr3mCfgOjbnC4FJOO69xj6WQke+ddxYsBS36iUQIDAQABo4HIMIHFMB0GA1Ud -DgQWBBQzN40SkcBUcYM4Xwhlv6lL+Y408zCBlQYDVR0jBIGNMIGKgBQzN40SkcBUcYM4Xwhl -v6lL+Y4086FvpG0wazELMAkGA1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNV -BAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMT -C3Rlc3QgY2VydCAxggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAbIcEHoo4 -qNobF2cWRCBaDZXQ6XcXG1lMLObrTSe4asUK++H59nC/ax+wMnDVrWZ8gkwJO1KsHGx98+gj -aCR+lP5P/yE5O8PD7TOp8OiYZVyw/guuQYn4qeondibUUMJeJCf7T6cfv+NjLpIt8lRTfgRB -hT6SOoXSZodR8/NZPBkxggFXMIIBUwIBATBwMGsxCzAJBgNVBAYTAkRFMRMwEQYDVQQHFApE -/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBHbWJIMRkwFwYDVQQLExBBZWd5cHRlbiBQ -cm9qZWN0MRQwEgYDVQQDEwt0ZXN0IGNlcnQgMQIBADAHBgUrDgMCGqBDMBwGCSqGSIb3DQEJ -BTEPFw0wMjA4MDgxMjIyNDZaMCMGCSqGSIb3DQEJBDEWBBR5MsAm+0wJAVQl3AAGYmnpxA4X -LjALBgkqhkiG9w0BAQEEgYC+7rFtegP8v+Z5yI4CH/0Y4RK48DM1oFMSz4xySpERFTk9p5RP -BDhOqaaACVKUdmNW6xYJAFo53tQxbBTZ12woctFLbLm9rs/F6Tz2JIA9GxpXInkKYdvkaVHb -pvEQgeoezFc4fd4yB87kgq4zZTViFcCJ3OvjboCu9ltIeIn73AAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-1.osig-badusage.pem b/tests/text-1.osig-badusage.pem deleted file mode 100644 index 027f23ead..000000000 --- a/tests/text-1.osig-badusage.pem +++ /dev/null @@ -1,75 +0,0 @@ -This message was created by violating the keyUsage: keyEncipherment. - ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA -JIAEggPhSGlnaCBQcmllc3Q6CUFybWFtZW50cyBDaGFwdGVyIE9uZSwgdmVyc2Vz -IG5pbmUgdGhyb3VnaCB0d2VudHktc2V2ZW46CkJyby4gTWF5bmFyZDoJQW5kIFNh -aW50IEF0dGlsYSByYWlzZWQgdGhlIEhvbHkgSGFuZCBHcmVuYWRlIHVwIG9uIGhp -Z2gKCXNheWluZywgIk9oIExvcmQsIEJsZXNzIHVzIHRoaXMgSG9seSBIYW5kIEdy -ZW5hZGUsIGFuZCB3aXRoIGl0CglzbWFzaCBvdXIgZW5lbWllcyB0byB0aW55IGJp -dHMuIiAgQW5kIHRoZSBMb3JkIGRpZCBncmluLCBhbmQgdGhlCglwZW9wbGUgZGlk -IGZlYXN0IHVwb24gdGhlIGxhbWJzLCBhbmQgc3RvYXRzLCBhbmQgb3Jhbmd1dGFu -cywgYW5kCglicmVha2Zhc3QgY2VyZWFscywgYW5kIGxpbWEgYmVhbi0KSGlnaCBQ -cmllc3Q6CVNraXAgYSBiaXQsIGJyb3RoZXIuCkJyby4gTWF5bmFyZDoJQW5kIHRo -ZW4gdGhlIExvcmQgc3Bha2UsIHNheWluZzogIkZpcnN0LCBzaGFsdCB0aG91IHRh -a2UKCW91dCB0aGUgaG9seSBwaW4uICBUaGVuIHNoYWx0IHRob3UgY291bnQgdG8g -dGhyZWUuICBObyBtb3JlLCBubyBsZXNzLgoJKlRocmVlKiBzaGFsbCBiZSB0aGUg -bnVtYmVyIG9mIHRoZSBjb3VudGluZywgYW5kIHRoZSBudW1iZXIgb2YgdGhlCglj -b3VudGluZyBzaGFsbCBiZSB0aHJlZS4gICpGb3VyKiBzaGFsdCB0aG91IG5vdCBj -b3VudCwgYW5kIG5laXRoZXIKCWNvdW50IHRob3UgdHdvLCBleGNlcHRpbmcgdGhh -dCB0aG91IHRoZW4gZ29lc3Qgb24gdG8gdGhyZWUuICBGaXZlIGlzCglSSUdIVCBP -VVQuICBPbmNlIHRoZSBudW1iZXIgdGhyZWUsIGJlaW5nIHRoZSB0aGlyZCBudW1i -ZXIgYmUgcmVhY2hlZCwKCXRoZW4gbG9iYmVzdCB0aG91IHRoeSBIb2x5IEhhbmQg -R3JlbmFkZSB0b3dhcmRzIHRoeSBmb2UsIHdobywgYmVpbmcKCW5hdWdodHkgaW4g -bXkgc2lnaHQsIHNoYWxsIHNudWZmIGl0LiAgQW1lbi4KQWxsOglBbWVuLgoJCS0t -IE1vbnR5IFB5dGhvbiwgIlRoZSBIb2x5IEhhbmQgR3JlbmFkZSIKAAAAAAAAoIIH -gjCCA+IwggNLoAMCAQICAQAwDQYJKoZIhvcNAQEEBQAwga0xCzAJBgNVBAYTAmRl -MQwwCgYDVQQIEwNOUlcxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcx -MCBDb2RlIEdtYkgxHjAcBgNVBAsTFVRlc3QgQ0Egb24gS2VyY2tob2ZmczEVMBMG -A1UEAxMMUm9vdC1UZXN0LUNBMSwwKgYJKoZIhvcNAQkBFh10ZXN0LWNhQGtlcmNr -aG9mZnMuZzEwY29kZS5kZTAeFw0wMjAzMTEwOTI1MDFaFw0wMzAzMTEwOTI1MDFa -MIGtMQswCQYDVQQGEwJkZTEMMAoGA1UECBMDTlJXMRMwEQYDVQQHFApE/HNzZWxk -b3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBHbWJIMR4wHAYDVQQLExVUZXN0IENBIG9u -IEtlcmNraG9mZnMxFTATBgNVBAMTDFJvb3QtVGVzdC1DQTEsMCoGCSqGSIb3DQEJ -ARYddGVzdC1jYUBrZXJja2hvZmZzLmcxMGNvZGUuZGUwgZ8wDQYJKoZIhvcNAQEB -BQADgY0AMIGJAoGBAMsjHHkftougdddTWQ6lcwlowfr3MpmiqDcTOfPuJzY69PGn -8dzNnbjF+qDmqW8b6YHWTmYVfZWwzBbGfUnP/K/Jz8Crk1vd3EtqnHkyNdnzj3dW -prXed2ncUff+x3ZxvthFFnBDumzbV0sR3FoRhhY0rKSkHpK7MxWRWm3U8BkdAgMB -AAGjggEOMIIBCjAdBgNVHQ4EFgQUilgNzsWIc4O+ang1CsXuXu1NypMwgdoGA1Ud -IwSB0jCBz4AUilgNzsWIc4O+ang1CsXuXu1NypOhgbOkgbAwga0xCzAJBgNVBAYT -AmRlMQwwCgYDVQQIEwNOUlcxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoT -DWcxMCBDb2RlIEdtYkgxHjAcBgNVBAsTFVRlc3QgQ0Egb24gS2VyY2tob2ZmczEV -MBMGA1UEAxMMUm9vdC1UZXN0LUNBMSwwKgYJKoZIhvcNAQkBFh10ZXN0LWNhQGtl -cmNraG9mZnMuZzEwY29kZS5kZYIBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB -BAUAA4GBAJGB2WETqLts9jGrzlRTnWOZ1D6oKkx5Q+c9gA6LQnpHYkUO2LCRx6g2 -hMEXRsVcTbxT2t9YgPlXmbuGE2jogFtJRWe0mGMI0byo7Pgg0MZD1QVscgeyTXiD -o7VsiuBU683Lt2jYHyCcTLs2FPBFMLsMD6/hsWD+RlBUlYT/lTrMMIIDmDCCAwGg -AwIBAgIBAzANBgkqhkiG9w0BAQUFADCBrTELMAkGA1UEBhMCZGUxDDAKBgNVBAgT -A05SVzETMBEGA1UEBxQKRPxzc2VsZG9yZjEWMBQGA1UEChMNZzEwIENvZGUgR21i -SDEeMBwGA1UECxMVVGVzdCBDQSBvbiBLZXJja2hvZmZzMRUwEwYDVQQDEwxSb290 -LVRlc3QtQ0ExLDAqBgkqhkiG9w0BCQEWHXRlc3QtY2FAa2VyY2tob2Zmcy5nMTBj -b2RlLmRlMB4XDTAyMDkwMzEwMzg1NloXDTEyMDgzMTEwMzg1NlowTzELMAkGA1UE -BhMCZGUxETAPBgNVBAoTCGcxMCBjb2RlMRAwDgYDVQQLEwdUZXN0bGFiMRswGQYD -VQQDExJFbmNyeXB0IE9ubHkgS2V5IDEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ -AoGBANsmhi/X6vesmlK6Ikc+KMjfRjewoEgjB3L21c2W7vkF19ZQqElXy9PMzXIK -nJQetDD+UIjmqN3Q1XcFBqMU3bT1eaJpb7U+mOeodQ9AABapiF0cH10ZrJDRhhht -9LNU873Kl4vL+xgQ3+WraK/ksrCdH4IjJlUUr+zfWWYo+MWPAgMBAAGjggEjMIIB -HzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFIDAdBgNVHQ4EFgQUxWTiIXcx29tl0D0T -Yl9sQ4z4foIwgdoGA1UdIwSB0jCBz4AUilgNzsWIc4O+ang1CsXuXu1NypOhgbOk -gbAwga0xCzAJBgNVBAYTAmRlMQwwCgYDVQQIEwNOUlcxEzARBgNVBAcUCkT8c3Nl -bGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxHjAcBgNVBAsTFVRlc3QgQ0Eg -b24gS2VyY2tob2ZmczEVMBMGA1UEAxMMUm9vdC1UZXN0LUNBMSwwKgYJKoZIhvcN -AQkBFh10ZXN0LWNhQGtlcmNraG9mZnMuZzEwY29kZS5kZYIBADAJBgNVHREEAjAA -MA0GCSqGSIb3DQEBBQUAA4GBAGPwl3GN6TxYlwnN7Za2H4lJthUkBdxrjoh7D7z4 -kxpo0JGgcBbDEpGPDNtwNg73ukwruGOiOJPGk6qZI1TtI+7joScHf1dtGUTcfFW+ -qpGkImJDrY1IV+ud6qhL2LxY4FLAuEv2iPNSbM9N3X8nB0ofWoPefISRwikYCdR8 -3m+tMYIBmzCCAZcCAQEwgbMwga0xCzAJBgNVBAYTAmRlMQwwCgYDVQQIEwNOUlcx -EzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxHjAc -BgNVBAsTFVRlc3QgQ0Egb24gS2VyY2tob2ZmczEVMBMGA1UEAxMMUm9vdC1UZXN0 -LUNBMSwwKgYJKoZIhvcNAQkBFh10ZXN0LWNhQGtlcmNraG9mZnMuZzEwY29kZS5k -ZQIBAzAHBgUrDgMCGqBDMBwGCSqGSIb3DQEJBTEPFw0wMjA5MDMxMTA0MzBaMCMG -CSqGSIb3DQEJBDEWBBR5MsAm+0wJAVQl3AAGYmnpxA4XLjALBgkqhkiG9w0BAQEE -gYB0gCqSUCIvw+26dmMFDUz/s3MG9nusAvYJpig8DLIsAGwmAw6Pg0XsI3Wkufb6 -KMTkmyjZLAsNUYWpQgcWkUvIR68iYtI1hd610+YbZubK+IppGkxUrXtFuaMK0xQs -tC0yMxlbcDBteiJYAZTDxn7cypmz106o6k4Utf0CPmd2LQAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-1.osig.pem b/tests/text-1.osig.pem deleted file mode 100644 index 7317350ec..000000000 --- a/tests/text-1.osig.pem +++ /dev/null @@ -1,48 +0,0 @@ ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA -JIAEggPhSGlnaCBQcmllc3Q6CUFybWFtZW50cyBDaGFwdGVyIE9uZSwgdmVyc2Vz -IG5pbmUgdGhyb3VnaCB0d2VudHktc2V2ZW46CkJyby4gTWF5bmFyZDoJQW5kIFNh -aW50IEF0dGlsYSByYWlzZWQgdGhlIEhvbHkgSGFuZCBHcmVuYWRlIHVwIG9uIGhp -Z2gKCXNheWluZywgIk9oIExvcmQsIEJsZXNzIHVzIHRoaXMgSG9seSBIYW5kIEdy -ZW5hZGUsIGFuZCB3aXRoIGl0CglzbWFzaCBvdXIgZW5lbWllcyB0byB0aW55IGJp -dHMuIiAgQW5kIHRoZSBMb3JkIGRpZCBncmluLCBhbmQgdGhlCglwZW9wbGUgZGlk -IGZlYXN0IHVwb24gdGhlIGxhbWJzLCBhbmQgc3RvYXRzLCBhbmQgb3Jhbmd1dGFu -cywgYW5kCglicmVha2Zhc3QgY2VyZWFscywgYW5kIGxpbWEgYmVhbi0KSGlnaCBQ -cmllc3Q6CVNraXAgYSBiaXQsIGJyb3RoZXIuCkJyby4gTWF5bmFyZDoJQW5kIHRo -ZW4gdGhlIExvcmQgc3Bha2UsIHNheWluZzogIkZpcnN0LCBzaGFsdCB0aG91IHRh -a2UKCW91dCB0aGUgaG9seSBwaW4uICBUaGVuIHNoYWx0IHRob3UgY291bnQgdG8g -dGhyZWUuICBObyBtb3JlLCBubyBsZXNzLgoJKlRocmVlKiBzaGFsbCBiZSB0aGUg -bnVtYmVyIG9mIHRoZSBjb3VudGluZywgYW5kIHRoZSBudW1iZXIgb2YgdGhlCglj -b3VudGluZyBzaGFsbCBiZSB0aHJlZS4gICpGb3VyKiBzaGFsdCB0aG91IG5vdCBj -b3VudCwgYW5kIG5laXRoZXIKCWNvdW50IHRob3UgdHdvLCBleGNlcHRpbmcgdGhh -dCB0aG91IHRoZW4gZ29lc3Qgb24gdG8gdGhyZWUuICBGaXZlIGlzCglSSUdIVCBP -VVQuICBPbmNlIHRoZSBudW1iZXIgdGhyZWUsIGJlaW5nIHRoZSB0aGlyZCBudW1i -ZXIgYmUgcmVhY2hlZCwKCXRoZW4gbG9iYmVzdCB0aG91IHRoeSBIb2x5IEhhbmQg -R3JlbmFkZSB0b3dhcmRzIHRoeSBmb2UsIHdobywgYmVpbmcKCW5hdWdodHkgaW4g -bXkgc2lnaHQsIHNoYWxsIHNudWZmIGl0LiAgQW1lbi4KQWxsOglBbWVuLgoJCS0t -IE1vbnR5IFB5dGhvbiwgIlRoZSBIb2x5IEhhbmQgR3JlbmFkZSIKAAAAAAAAoIID -GTCCAxUwggJ+oAMCAQICAQAwDQYJKoZIhvcNAQEEBQAwazELMAkGA1UEBhMCREUx -EzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAX -BgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMB4X -DTAxMTIwMzA5MzYzOFoXDTAyMTIwMzA5MzYzOFowazELMAkGA1UEBhMCREUxEzAR -BgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNV -BAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMIGfMA0G -CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgzpb5C2yeAvOSK+rak/5QqHXqxrzBi7mp -zy6EllyqLR/5Wn9UJGXGwMGdJ25FJs4EiGinqRT9NDzDqH3XQpH/xWVQbVu7Jcus -ag4t0fi8qrDUopwvN8lQ82NIS/Jp94kUQEZLr3mCfgOjbnC4FJOO69xj6WQke+dd -xYsBS36iUQIDAQABo4HIMIHFMB0GA1UdDgQWBBQzN40SkcBUcYM4Xwhlv6lL+Y40 -8zCBlQYDVR0jBIGNMIGKgBQzN40SkcBUcYM4Xwhlv6lL+Y4086FvpG0wazELMAkG -A1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2Rl -IEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3Qg -Y2VydCAxggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAbIcEHoo4 -qNobF2cWRCBaDZXQ6XcXG1lMLObrTSe4asUK++H59nC/ax+wMnDVrWZ8gkwJO1Ks -HGx98+gjaCR+lP5P/yE5O8PD7TOp8OiYZVyw/guuQYn4qeondibUUMJeJCf7T6cf -v+NjLpIt8lRTfgRBhT6SOoXSZodR8/NZPBkxggFXMIIBUwIBATBwMGsxCzAJBgNV -BAYTAkRFMRMwEQYDVQQHFApE/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBH -bWJIMRkwFwYDVQQLExBBZWd5cHRlbiBQcm9qZWN0MRQwEgYDVQQDEwt0ZXN0IGNl -cnQgMQIBADAHBgUrDgMCGqBDMBwGCSqGSIb3DQEJBTEPFw0wMjA4MDgxMjIyNDZa -MCMGCSqGSIb3DQEJBDEWBBR5MsAm+0wJAVQl3AAGYmnpxA4XLjALBgkqhkiG9w0B -AQEEgYC+7rFtegP8v+Z5yI4CH/0Y4RK48DM1oFMSz4xySpERFTk9p5RPBDhOqaaA -CVKUdmNW6xYJAFo53tQxbBTZ12woctFLbLm9rs/F6Tz2JIA9GxpXInkKYdvkaVHb -pvEQgeoezFc4fd4yB87kgq4zZTViFcCJ3OvjboCu9ltIeIn73AAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-1.txt b/tests/text-1.txt deleted file mode 100644 index b14c1a27c..000000000 --- a/tests/text-1.txt +++ /dev/null @@ -1,17 +0,0 @@ -High Priest: Armaments Chapter One, verses nine through twenty-seven: -Bro. Maynard: And Saint Attila raised the Holy Hand Grenade up on high - saying, "Oh Lord, Bless us this Holy Hand Grenade, and with it - smash our enemies to tiny bits." And the Lord did grin, and the - people did feast upon the lambs, and stoats, and orangutans, and - breakfast cereals, and lima bean- -High Priest: Skip a bit, brother. -Bro. Maynard: And then the Lord spake, saying: "First, shalt thou take - out the holy pin. Then shalt thou count to three. No more, no less. - *Three* shall be the number of the counting, and the number of the - counting shall be three. *Four* shalt thou not count, and neither - count thou two, excepting that thou then goest on to three. Five is - RIGHT OUT. Once the number three, being the third number be reached, - then lobbest thou thy Holy Hand Grenade towards thy foe, who, being - naughty in my sight, shall snuff it. Amen. -All: Amen. - -- Monty Python, "The Holy Hand Grenade" diff --git a/tests/text-2.osig-bad.pem b/tests/text-2.osig-bad.pem deleted file mode 100644 index 555844844..000000000 --- a/tests/text-2.osig-bad.pem +++ /dev/null @@ -1,28 +0,0 @@ -The signature time in this message has been tampered. - ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCAJIAEU01p -bGl0YXJ5IGludGVsbGlnZW5jZSBpcyBhIGNvbnRyYWRpY3Rpb24gaW4gdGVybXMuCiAgICAg -ICAgICAgICAgICAtLSBHcm91Y2hvIE1hcngKAAAAAAAAoIIDGTCCAxUwggJ+oAMCAQICAQAw -DQYJKoZIhvcNAQEEBQAwazELMAkGA1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAU -BgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNV -BAMTC3Rlc3QgY2VydCAxMB4XDTAxMTIwMzA5MzYzOFoXDTAyMTIwMzA5MzYzOFowazELMAkG -A1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgx -GTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMIGfMA0G -CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgzpb5C2yeAvOSK+rak/5QqHXqxrzBi7mpzy6Ellyq -LR/5Wn9UJGXGwMGdJ25FJs4EiGinqRT9NDzDqH3XQpH/xWVQbVu7Jcusag4t0fi8qrDUopwv -N8lQ82NIS/Jp94kUQEZLr3mCfgOjbnC4FJOO69xj6WQke+ddxYsBS36iUQIDAQABo4HIMIHF -MB0GA1UdDgQWBBQzN40SkcBUcYM4Xwhlv6lL+Y408zCBlQYDVR0jBIGNMIGKgBQzN40SkcBU -cYM4Xwhlv6lL+Y4086FvpG0wazELMAkGA1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYx -FjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDAS -BgNVBAMTC3Rlc3QgY2VydCAxggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEA -bIcEHoo4qNobF2cWRCBaDZXQ6XcXG1lMLObrTSe4asUK++H59nC/ax+wMnDVrWZ8gkwJO1Ks -HGx98+gjaCR+lP5P/yE5O8PD7TOp8OiYZVyw/guuQYn4qeondibUUMJeJCf7T6cfv+NjLpIt -8lRTfgRBhT6SOoXSZodR8/NZPBkxggFXMIIBUwIBATBwMGsxCzAJBgNVBAYTAkRFMRMwEQYD -VQQHFApE/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBHbWJIMRkwFwYDVQQLExBBZWd5 -cHRlbiBQcm9qZWN0MRQwEgYDVQQDEwt0ZXN0IGNlcnQgMQIBADAHBgUrDgMCGqBDMBwGCSqG -SIb3DQEJBTEPFw0wMjA4MDcxMjM4MjJaMCMGCSqGSIb3DQEJBDEWBBSzI9M4i+WJMTDoCeLu -lJP7p1PCezALBgkqhkiG9w0BAQEEgYAqoJR3uJkChUhaH0EH3U5JpQApIhVEqedaKPT6BCPP -WALFPzEa6YKzftA5e+Dap41UnB8nQ9rfwYty3hw5EulzV9iLnhGornQIgI6D5o7ymxyacsiY -EarezxGXjuPMnyXcpTOgt+vz2k3qisjzxU32zpsOuK6U82PSHysX8rH9QgAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-2.osig.pem b/tests/text-2.osig.pem deleted file mode 100644 index 57b5da9b2..000000000 --- a/tests/text-2.osig.pem +++ /dev/null @@ -1,29 +0,0 @@ ------BEGIN SIGNED MESSAGE----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA -JIAEU01pbGl0YXJ5IGludGVsbGlnZW5jZSBpcyBhIGNvbnRyYWRpY3Rpb24gaW4g -dGVybXMuCiAgICAgICAgICAgICAgICAtLSBHcm91Y2hvIE1hcngKAAAAAAAAoIID -GTCCAxUwggJ+oAMCAQICAQAwDQYJKoZIhvcNAQEEBQAwazELMAkGA1UEBhMCREUx -EzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAX -BgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMB4X -DTAxMTIwMzA5MzYzOFoXDTAyMTIwMzA5MzYzOFowazELMAkGA1UEBhMCREUxEzAR -BgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2RlIEdtYkgxGTAXBgNV -BAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3QgY2VydCAxMIGfMA0G -CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgzpb5C2yeAvOSK+rak/5QqHXqxrzBi7mp -zy6EllyqLR/5Wn9UJGXGwMGdJ25FJs4EiGinqRT9NDzDqH3XQpH/xWVQbVu7Jcus -ag4t0fi8qrDUopwvN8lQ82NIS/Jp94kUQEZLr3mCfgOjbnC4FJOO69xj6WQke+dd -xYsBS36iUQIDAQABo4HIMIHFMB0GA1UdDgQWBBQzN40SkcBUcYM4Xwhlv6lL+Y40 -8zCBlQYDVR0jBIGNMIGKgBQzN40SkcBUcYM4Xwhlv6lL+Y4086FvpG0wazELMAkG -A1UEBhMCREUxEzARBgNVBAcUCkT8c3NlbGRvcmYxFjAUBgNVBAoTDWcxMCBDb2Rl -IEdtYkgxGTAXBgNVBAsTEEFlZ3lwdGVuIFByb2plY3QxFDASBgNVBAMTC3Rlc3Qg -Y2VydCAxggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAbIcEHoo4 -qNobF2cWRCBaDZXQ6XcXG1lMLObrTSe4asUK++H59nC/ax+wMnDVrWZ8gkwJO1Ks -HGx98+gjaCR+lP5P/yE5O8PD7TOp8OiYZVyw/guuQYn4qeondibUUMJeJCf7T6cf -v+NjLpIt8lRTfgRBhT6SOoXSZodR8/NZPBkxggFXMIIBUwIBATBwMGsxCzAJBgNV -BAYTAkRFMRMwEQYDVQQHFApE/HNzZWxkb3JmMRYwFAYDVQQKEw1nMTAgQ29kZSBH -bWJIMRkwFwYDVQQLExBBZWd5cHRlbiBQcm9qZWN0MRQwEgYDVQQDEwt0ZXN0IGNl -cnQgMQIBADAHBgUrDgMCGqBDMBwGCSqGSIb3DQEJBTEPFw0wMjA4MDgxMjM4MjJa -MCMGCSqGSIb3DQEJBDEWBBSzI9M4i+WJMTDoCeLulJP7p1PCezALBgkqhkiG9w0B -AQEEgYAqoJR3uJkChUhaH0EH3U5JpQApIhVEqedaKPT6BCPPWALFPzEa6YKzftA5 -e+Dap41UnB8nQ9rfwYty3hw5EulzV9iLnhGornQIgI6D5o7ymxyacsiYEarezxGX -juPMnyXcpTOgt+vz2k3qisjzxU32zpsOuK6U82PSHysX8rH9QgAAAAAAAA== ------END SIGNED MESSAGE----- diff --git a/tests/text-2.txt b/tests/text-2.txt deleted file mode 100644 index 314c7a4e8..000000000 --- a/tests/text-2.txt +++ /dev/null @@ -1,2 +0,0 @@ -Military intelligence is a contradiction in terms. - -- Groucho Marx diff --git a/tests/text-3.txt b/tests/text-3.txt deleted file mode 100644 index 9345b550f..000000000 --- a/tests/text-3.txt +++ /dev/null @@ -1,2 +0,0 @@ -Military justice is to justice what military music is to music. - -- Groucho Marx