summaryrefslogtreecommitdiffstats
path: root/sm
diff options
context:
space:
mode:
authorRepo Admin <nobody@gnupg.org>2002-10-19 09:55:27 +0200
committerRepo Admin <nobody@gnupg.org>2002-10-19 09:55:27 +0200
commit82a17c9fb3d64ccdd474c3bedf564368f77e84a4 (patch)
tree0c01ee8cea5f6f77e830955c6b97024752740a2b /sm
parentBumped version number for cvs version (diff)
downloadgnupg2-82a17c9fb3d64ccdd474c3bedf564368f77e84a4.tar.xz
gnupg2-82a17c9fb3d64ccdd474c3bedf564368f77e84a4.zip
This commit was manufactured by cvs2svn to create branch
'GNUPG-1-9-BRANCH'.
Diffstat (limited to 'sm')
-rw-r--r--sm/ChangeLog741
-rw-r--r--sm/Makefile.am57
-rw-r--r--sm/base64.c624
-rw-r--r--sm/call-agent.c751
-rw-r--r--sm/call-dirmngr.c495
-rw-r--r--sm/certchain.c786
-rw-r--r--sm/certcheck.c301
-rw-r--r--sm/certdump.c457
-rw-r--r--sm/certlist.c313
-rw-r--r--sm/certreqgen.c699
-rw-r--r--sm/decrypt.c502
-rw-r--r--sm/delete.c165
-rw-r--r--sm/encrypt.c549
-rw-r--r--sm/export.c248
-rw-r--r--sm/fingerprint.c271
-rw-r--r--sm/gpgsm.c1388
-rw-r--r--sm/gpgsm.h261
-rw-r--r--sm/import.c349
-rw-r--r--sm/keydb.c1282
-rw-r--r--sm/keylist.c616
-rw-r--r--sm/server.c1057
-rw-r--r--sm/sign.c622
-rw-r--r--sm/verify.c510
23 files changed, 0 insertions, 13044 deletions
diff --git a/sm/ChangeLog b/sm/ChangeLog
deleted file mode 100644
index 8e11e0ddf..000000000
--- a/sm/ChangeLog
+++ /dev/null
@@ -1,741 +0,0 @@
-2002-09-19 Werner Koch <wk@gnupg.org>
-
- * certcheck.c (gpgsm_check_cert_sig): Add cert hash debugging.
-
- * certchain.c (find_up): Print info when the cert was not found
- by the autorithyKeyIdentifier.
-
-2002-09-03 Werner Koch <wk@gnupg.org>
-
- * gpgsm.c (main): Disable the internal libgcrypt locking.
-
-2002-08-21 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * certcheck.c (gpgsm_check_cert_sig): Implement proper cleanup.
- (gpgsm_check_cms_signature): Ditto.
-
-2002-07-22 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * server.c (cmd_recipient): Add more reason codes.
-
-2002-06-27 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * import.c (gpgsm_import): Print an STATUS_IMPORTED.
-
- * gpgsm.c: --debug-no-path-validation does not take an argument.
-
-2002-06-25 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * certreqgen.c (read_parameters): Improved error handling.
- (gpgsm_genkey): Print error message.
-
-2002-06-13 Werner Koch <wk@gnupg.org>
-
- * gpgsm.c (main): New option --log-file.
-
-2002-06-12 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * gpgsm.c (main): Don't print the "go ahead" message for an
- invalid command.
-
-2002-05-23 Werner Koch <wk@gnupg.org>
-
- * import.c (gpgsm_import): Add error messages.
-
-2002-05-21 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * call-agent.c (start_agent): Make copies of old locales and check
- for setlocale.
-
-2002-04-25 Marcus Brinkmann <marcus@g10code.de>
-
- * call-agent.c (start_agent): Fix error handling logic so the
- locale is always correctly reset.
-
-2002-04-25 Marcus Brinkmann <marcus@g10code.de>
-
- * 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 <marcus@g10code.de>
-
- * 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 <wk@gnupg.org>
-
- * certreqgen.c (gpgsm_genkey): Write status output on success.
-
-2002-04-15 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * export.c: New.
- * gpgsm.c: Add command --export.
- * server.c (cmd_export): New.
-
-2002-03-13 Werner Koch <wk@gnupg.org>
-
- * decrypt.c (gpgsm_decrypt): Allow multiple recipients.
-
-2002-03-12 Werner Koch <wk@gnupg.org>
-
- * certpath.c (check_cert_policy): Print the policy list.
-
- * verify.c (gpgsm_verify): Detect certs-only message.
-
-2002-03-11 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * call-dirmngr.c, call-agent.c: Add 2 more arguments to all uses
- of assuan_transact.
-
-2002-02-25 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <marcus@g10code.de>
-
- * sign.c (gpgsm_sign): Do not release certificate twice.
-
-2002-01-29 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * certreqgen.c (create_request): Store the email address in the req.
-
-2002-01-25 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * server.c (option_handler): New.
- (gpgsm_server): Register it with assuan.
-
-2002-01-19 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * call-dirmngr.c (inq_certificate): Changed for new interface semantic.
- * certlist.c (gpgsm_find_cert): New.
-
-2002-01-13 Werner Koch <wk@gnupg.org>
-
- * fingerprint.c (gpgsm_get_certid): Print the serial and not the
- hash after the dot.
-
-2002-01-11 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * base64.c (gpgsm_create_writer): Allow to set the object name
-
-2002-01-08 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * server.c (rc_to_assuan_status): Removed and changed all callers
- to use map_to_assuan_status.
-
-2001-12-20 Werner Koch <wk@gnupg.org>
-
- * 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 <marcus@g10code.de>
-
- * call-agent.c (start_agent): Add new argument to assuan_pipe_connect.
-
-2001-12-18 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <marcus@g10code.de>
-
- * call-agent.c (LINELENGTH): Removed.
- (gpgsm_agent_pksign): Use ASSUAN_LINELENGTH, not LINELENGTH.
- (gpgsm_agent_pkdecrypt): Likewise.
-
-2001-12-13 Werner Koch <wk@gnupg.org>
-
- * keylist.c (list_cert_colon): Print alternative names of subject
- and a few other values.
-
-2001-12-12 Werner Koch <wk@gnupg.org>
-
- * gpgsm.c (main): New options --assume-{armor,base64,binary}.
- * base64.c (base64_reader_cb): Fixed non-autodetection mode.
-
-2001-12-04 Werner Koch <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <wk@gnupg.org>
-
- * 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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <ksba.h>
-
-#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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-#include <gcrypt.h>
-#ifdef HAVE_LOCALE_H
-#include <locale.h>
-#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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <gcrypt.h>
-
-#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 b01398f18..000000000
--- a/sm/certchain.c
+++ /dev/null
@@ -1,786 +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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <gcrypt.h>
-#include <ksba.h>
-
-#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);
- }
- }
- /* print a note so that the user does not feel too helpless when
- an issuer certificate was found and gpgsm prints BAD
- signature becuase it is not the correct one. */
- if (rc == -1)
- {
- log_info ("issuer certificate (#");
- gpgsm_dump_serial (authidno);
- log_printf ("/");
- gpgsm_dump_string (s);
- log_printf (") not found\n");
- }
- else if (rc)
- log_error ("failed to find authorityKeyIdentifier: rc=%d\n", rc);
- 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 better 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 37d2b00df..000000000
--- a/sm/certcheck.c
+++ /dev/null
@@ -1,301 +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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <gcrypt.h>
-#include <ksba.h>
-
-#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;
- }
- if (DBG_HASHING)
- gcry_md_start_debug (md, "hash.cert");
-
- 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;
- }
- if (DBG_X509)
- {
- int j;
- log_debug ("signature value:");
- for (j=0; j < n; j++)
- log_printf (" %02X", p[j]);
- log_printf ("\n");
- }
-
- 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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <gcrypt.h>
-#include <ksba.h>
-
-#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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <gcrypt.h>
-#include <ksba.h>
-
-#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 <text>
- Print <text>.
- %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 <filename>
- Do not write the certificate to the keyDB but to <filename>.
- 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: <algo>
- 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-in-bits>
- Length of the key in bits. Default is 1024.
- Key-Usage: <usage-list>
- 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: <string>
- The ist the email address
-
-Here is an example:
-$ cat >foo <<EOF
-%echo Generating a standard key
-Key-Type: RSA
-Key-Length: 1024
-Name-DN: CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Düsseldorf,C=DE
-Name-Email: joe@foo.bar
-# Do a commit here, so that we can later print "done" :-)
-%commit
-%echo done
-EOF
-*/
-
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <gcrypt.h>
-#include <ksba.h>
-
-#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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <gcrypt.h>
-#include <ksba.h>
-
-#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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <gcrypt.h>
-#include <ksba.h>
-
-#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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <gcrypt.h>
-#include <ksba.h>
-
-#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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <gcrypt.h>
-#include <ksba.h>
-
-#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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <gcrypt.h>
-#include <ksba.h>
-
-#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 <config.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include <gcrypt.h>
-#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 <ksba.h>
-#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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <gcrypt.h>
-#include <ksba.h>
-
-#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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "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/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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <gcrypt.h>
-#include <ksba.h>
-
-#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/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 <config.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <unistd.h>
-
-#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 <userID>
-
- Set the recipient for the encryption. <userID> 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 <userID>
-
- Set the signer's keys for the signature creation. <userID> 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=<n>
-
- 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=<n> 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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <gcrypt.h>
-#include <ksba.h>
-
-#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 <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <assert.h>
-
-#include <gcrypt.h>
-#include <ksba.h>
-
-#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;
-}
-