1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-11-10 21:38:50 +01:00
Commit Graph

75 Commits

Author SHA1 Message Date
Werner Koch
4c14bbf56f
sm: Update pkcs#12 module from master
* sm/minip12.c: Update from master.
* sm/import.c (parse_p12): Pass NULL for curve.
--

Over the last years we had a couple of changes not backported to 2.2.
However, to support DFN p12 files and probably other p12 files we need
to update the minip12.c module.  Instead of picking commits we take
the module verbatim, which is relatively easy because it was
originally designed to be a standalone module.

Summary of commits taken from master:

  sm: Improve pkcs#12 debug output.
  sm: Rework the PKCS#12 parser to support DFN issued keys.
  sm: Fix parsing encrypted data.
  sm: Do not print certain issuer not found diags in quiet mode.
  sm: Silence some output on --quiet
  sm: Replace all assert calls by log_assert.
  doc: Typo fixes in code comments
  sm: Add support to export ECC private keys.

Detailed log messages for those commits:

  commit 52f9e13c0c

    sm: Improve pkcs#12 debug output.

    * sm/minip12.c (parse_shrouded_key_bag): Fix offset diagnostic.
    (parse_cert_bag): Ditto.
    (parse_bag_data): Remove debug output.  Pass startoffset.
    Fix offset diagnostic.

  commit a4e04375e8

    sm: Rework the PKCS#12 parser to support DFN issued keys.

    * sm/minip12.c (struct p12_parse_ctx_s): New.  Use this instead of
    passing several parameters to most functions.
    (parse_pag_data): Factor things out to  ...
    parse_shrouded_key_bag): new.
    (parse_cert_bag): New.
    (parse_bag_data): New.
    (p12_parse): Setup the parse context.

    To support newer pkcs#12 files like those issued by the DFN we
    need to support another ordering of data elements.  This rework
    reflects the P12 data structure a bit better than our old ad-hoc
    hacks.  Tests could only be done with the certificate parts and
    not the encrypted private keys.

GnuPG-bug-id: 6037

  commit 6c50834c09

    sm: Fix parsing encrypted data.

    * sm/minip12.c (cram_octet_string): Finish when N==0.
    (parse_bag_encrypted_data): Support constructed data with multiple
    octet strings.

GnuPG-bug-id: 5793

  commit a170f0e73f

    sm: Do not print certain issuer not found diags in quiet mode.

    * sm/certchain.c (find_up_dirmngr): Print one diagnostic only in
    verbose mode.  Do not print issuer not found diags in quiet mode.
    * sm/minip12.c (parse_bag_data): Add missing verbose condition.

GnuPG-bug-id: 4757

  commit 615d2e4fb1

    sm: Silence some output on --quiet

    * sm/encrypt.c (gpgsm_encrypt): Take care of --quiet.
    * sm/gpgsm.c: Include minip12.h.
    (set_debug): Call p12_set_verbosity.
    * sm/import.c (parse_p12): Dump keygrip only in debug mode.
    * sm/minip12.c (opt_verbose, p12_set_verbosity): New.
    (parse_bag_encrypted_data): Print info messages only in verbose
    mode.

GnuPG-bug-id: 4757

  commit 9ee975d588

    gpgsm: Replace all assert calls by log_assert.

  commit 9bc9d0818b

    doc: Typo fixes in code comments

  commit 5da6925a33

    sm: Add support to export ECC private keys.

    * sm/minip12.c [TEST]: Remove test code.  Include util.h, tlv.h. and
    openpgpdefs.h.  Remove the class and tag constants and replace
    them by those from tlv.h.
    (builder_add_oid, builder_add_mpi): New.
    (build_key_sequence): Rename to ...
    (build_rsa_key_sequence): this.
    (build_ecc_key_sequence): New.
    (p12_build): Call RSA or ECC builder.
    (p12_raw_build): Ditto.
    * sm/export.c (gpgsm_p12_export): Use correct armor header for ECC.
    (sexp_to_kparms): Support ECC.

GnuPG-bug-id: 4921
2022-06-21 18:22:14 +02:00
Werner Koch
50ea1b67e8
sm: Ask for the password for password based decryption (pwri)
* sm/decrypt.c (pwri_decrypt): Add arg ctrl.  Ask for passphrase.

* sm/export.c (export_p12): Mark string as translatable.
* sm/import.c (parse_p12): Ditto.
--

This is finishes the support for PWRI.

The N_() marks are added so that we don't rely of the side-effect of
having the same strings in protect-tool.c

Signed-off-by: Werner Koch <wk@gnupg.org>
(cherry picked from commit eeb65d3bbd)
2021-05-17 19:29:06 +02:00
Werner Koch
bcdbf0fcf3
sm: Silence some output on --quiet
* sm/encrypt.c (gpgsm_encrypt): Take care of --quiet.
* sm/gpgsm.c: Include minip12.h.
(set_debug): Call p12_set_verbosity.
* sm/import.c (parse_p12): Dump keygrip only in debug mode.
* sm/minip12.c (opt_verbose, p12_set_verbosity): New.
(parse_bag_encrypted_data): Print info messages only in verbose mode.
--

GnuPG-bug-id: 4757
2021-02-24 08:38:13 +01:00
Werner Koch
c6324ee07a
common: Change argument order of log_printhex.
* common/logging.c (log_printhex): Chnage order of args.  Make it
printf alike.  Change all callers.
* configure.ac: Add -Wno-format-zero-length
--

This makes it consistent with modern libgpgrt logging and thus eases
back porting from newer GnuPG versions which use libgpgrt logging.

Signed-off-by: Werner Koch <wk@gnupg.org>
2020-05-12 18:51:47 +02:00
NIIBE Yutaka
5c8fe54809 Spelling fixes in docs and comments.
--

In addition, fix trailing spaces in tests/inittests.

GnuPG-bug-id: 3121
Reported-by: ka7 (klemens)
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-04-28 10:06:33 +09:00
NIIBE Yutaka
70aca95d68 Remove -I option to common.
* dirmngr/Makefile.am (AM_CPPFLAGS): Remove -I$(top_srcdir)/common.
* g10/Makefile.am (AM_CPPFLAGS): Ditto.
* g13/Makefile.am (AM_CPPFLAGS): Ditto.
* kbx/Makefile.am (AM_CPPFLAGS): Ditto.
* scd/Makefile.am (AM_CPPFLAGS): Ditto.
* sm/Makefile.am (AM_CPPFLAGS): Ditto.
* tools/Makefile.am (AM_CPPFLAGS): Ditto.
* Throughout: Follow the change.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
2017-03-07 20:25:54 +09:00
Werner Koch
e1dfd86236
common: Rename remaining symbols in ksba-io-support.
* common/ksba-io-support.c (gpgsm_reader_eof_seen): Rename to ...
(gnupg_ksba_reader_eof_seen): this.  Change all callers.
(gpgsm_destroy_reader): Rename to ...
(gnupg_ksba_destroy_reader): this.  Change all callers.
(gpgsm_finish_writer): Rename to ...
(gnupg_ksba_finish_writer): this.  Change all callers.
(gpgsm_destroy_writer): Rename to ...
(gnupg_ksba_destroy_writer): this.  Change all callers.
* common/ksba-io-support.c (struct base64_context_s): Rename to ...
(gnupg_ksba_io_s): this.
* common/ksba-io-support.h (base64_context_s): Ditto.
(Base64Context): Rename this typedef to ...
(gnupg_ksba_io_t): this.  Change all users.

Signed-off-by: Werner Koch <wk@gnupg.org>
2017-02-16 17:21:05 +01:00
Werner Koch
28c31524be
common: Remove gpgsm dependencies from ksba-io-support.
* common/ksba-io-support.c: Include ksba-io-support.h instead of
../sm/gpgsm.h.  Include util.h.
(writer_cb_parm_s): Remove const from 'pem_name'.
(gpgsm_destroy_writer): Free 'pem_name'.
(gpgsm_create_reader): Rename to ...
(gnupg_ksba_create_reader): this.  Replace args CTRL and
ALLOW_MULTI_PEM by a new arg FLAGS.  Change the code to evaluate
FLAGS.  Change all callers to pass the FLAGS.
(gpgsm_create_writer): Rename to ...
(gnupg_ksba_create_writer): this.  Replace arg CTRL by new arg FLAGS.
Add arg PEM_NAME.  Evaluate FLAGS.  Store a copy of PEM_NAME.  Change
all callers to pass the FLAGS and PEM_NAME.

Signed-off-by: Werner Koch <wk@gnupg.org>
2017-02-16 16:22:07 +01:00
Werner Koch
5d13581f47
gpg,sm: Add STATUS_ERROR keydb_search and keydb_add-resource.
* g10/keydb.c (keydb_add_resource): Make ANY_REGISTERED
file-global.  Write a STATUS_ERROR.
(maybe_create_keyring_or_box): Check for non-accessible but existant
file.
(keydb_search): Write a STATUS_ERROR if no keyring has been registered
but continue to return NOT_FOUND.
* sm/keydb.c (keydb_add_resource): Rename ANY_PUBLIC to ANY_REGISTERED
and make file-global.  Write a STATUS_ERROR.
(keydb_search): Write a STATUS_ERROR if no keyring has been registered
but continue to return NOT_FOUND.  Also add new arg CTRL and change
all callers to pass it down.

Signed-off-by: Werner Koch <wk@gnupg.org>
2016-11-10 17:07:28 +01:00
Werner Koch
c8044c6e33
sm: Remove unused arg SECRET from keydb functions.
* sm/keydb.c (struct resource_item): Remove field 'secret'.
(keydb_add_resource): Remove arg 'secret' and change all callers.
(keydb_new): Ditto.

Signed-off-by: Werner Koch <wk@gnupg.org>
2016-11-10 17:04:03 +01:00
Werner Koch
4d7dc432b5
Change all http://www.gnu.org in license notices to https://
--
2016-11-05 12:02:19 +01:00
Justus Winter
a9e0905342 Fix typos found using codespell.
* agent/cache.c: Fix typos.
* agent/call-pinentry.c: Likewise.
* agent/call-scd.c: Likewise.
* agent/command-ssh.c: Likewise.
* agent/command.c: Likewise.
* agent/divert-scd.c: Likewise.
* agent/findkey.c: Likewise.
* agent/gpg-agent.c: Likewise.
* agent/w32main.c: Likewise.
* common/argparse.c: Likewise.
* common/audit.c: Likewise.
* common/audit.h: Likewise.
* common/convert.c: Likewise.
* common/dotlock.c: Likewise.
* common/exechelp-posix.c: Likewise.
* common/exechelp-w32.c: Likewise.
* common/exechelp-w32ce.c: Likewise.
* common/exechelp.h: Likewise.
* common/helpfile.c: Likewise.
* common/i18n.h: Likewise.
* common/iobuf.c: Likewise.
* common/iobuf.h: Likewise.
* common/localename.c: Likewise.
* common/logging.c: Likewise.
* common/openpgp-oid.c: Likewise.
* common/session-env.c: Likewise.
* common/sexputil.c: Likewise.
* common/sysutils.c: Likewise.
* common/t-sexputil.c: Likewise.
* common/ttyio.c: Likewise.
* common/util.h: Likewise.
* dirmngr/cdblib.c: Likewise.
* dirmngr/certcache.c: Likewise.
* dirmngr/crlcache.c: Likewise.
* dirmngr/dirmngr-client.c: Likewise.
* dirmngr/dirmngr.c: Likewise.
* dirmngr/dirmngr_ldap.c: Likewise.
* dirmngr/dns-stuff.c: Likewise.
* dirmngr/http.c: Likewise.
* dirmngr/ks-engine-hkp.c: Likewise.
* dirmngr/ks-engine-ldap.c: Likewise.
* dirmngr/ldap-wrapper.c: Likewise.
* dirmngr/ldap.c: Likewise.
* dirmngr/misc.c: Likewise.
* dirmngr/ocsp.c: Likewise.
* dirmngr/validate.c: Likewise.
* g10/encrypt.c: Likewise.
* g10/getkey.c: Likewise.
* g10/gpg.c: Likewise.
* g10/gpgv.c: Likewise.
* g10/import.c: Likewise.
* g10/keydb.c: Likewise.
* g10/keydb.h: Likewise.
* g10/keygen.c: Likewise.
* g10/keyid.c: Likewise.
* g10/keylist.c: Likewise.
* g10/keyring.c: Likewise.
* g10/mainproc.c: Likewise.
* g10/misc.c: Likewise.
* g10/options.h: Likewise.
* g10/packet.h: Likewise.
* g10/parse-packet.c: Likewise.
* g10/pkclist.c: Likewise.
* g10/pkglue.c: Likewise.
* g10/plaintext.c: Likewise.
* g10/server.c: Likewise.
* g10/sig-check.c: Likewise.
* g10/sqlite.c: Likewise.
* g10/tdbio.c: Likewise.
* g10/test-stubs.c: Likewise.
* g10/tofu.c: Likewise.
* g10/trust.c: Likewise.
* g10/trustdb.c: Likewise.
* g13/create.c: Likewise.
* g13/mountinfo.c: Likewise.
* kbx/keybox-blob.c: Likewise.
* kbx/keybox-file.c: Likewise.
* kbx/keybox-init.c: Likewise.
* kbx/keybox-search-desc.h: Likewise.
* kbx/keybox-search.c: Likewise.
* kbx/keybox-update.c: Likewise.
* scd/apdu.c: Likewise.
* scd/app-openpgp.c: Likewise.
* scd/app-p15.c: Likewise.
* scd/app.c: Likewise.
* scd/ccid-driver.c: Likewise.
* scd/command.c: Likewise.
* scd/iso7816.c: Likewise.
* sm/base64.c: Likewise.
* sm/call-agent.c: Likewise.
* sm/call-dirmngr.c: Likewise.
* sm/certchain.c: Likewise.
* sm/gpgsm.c: Likewise.
* sm/import.c: Likewise.
* sm/keydb.c: Likewise.
* sm/minip12.c: Likewise.
* sm/qualified.c: Likewise.
* sm/server.c: Likewise.
* tools/gpg-check-pattern.c: Likewise.
* tools/gpgconf-comp.c: Likewise.
* tools/gpgkey2ssh.c: Likewise.
* tools/gpgparsemail.c: Likewise.
* tools/gpgtar.c: Likewise.
* tools/rfc822parse.c: Likewise.
* tools/symcryptrun.c: Likewise.

Signed-off-by: Justus Winter <justus@g10code.com>
2015-11-17 12:50:22 +01:00
Werner Koch
5da12674ea Fix regression in gpg's mail address parsing.
Since 2009-12-08 gpg was not able to find email addresses indicated
by a leading '<'.  This happened when I merged the user id
classification code of gpgsm and gpg.
2011-04-25 23:59:25 +02:00
Werner Koch
b008274afd Nuked almost all trailing white space.
We better do this once and for all instead of cluttering all future
commits with diffs of trailing white spaces.  In the majority of cases
blank or single lines are affected and thus this change won't disturb
a git blame too much.  For future commits the pre-commit scripts
checks that this won't happen again.
2011-02-04 12:57:53 +01:00
Werner Koch
bfbd80feb9 Exporting secret keys via gpg-agent is now basically supported.
A couple of forward ported changes.
Doc updates.
2010-10-01 20:33:53 +00:00
Werner Koch
91056b1976 Implement export of pkcs#12 objects using a direct agent connection. 2010-06-21 10:01:24 +00:00
Werner Koch
006fd75aea Avoid using the protect-tool to import pkcs#12. 2010-06-17 15:44:44 +00:00
Werner Koch
c3f08dcb72 Merged Dirmngr with GnuPG.
A few code changes to support dirmngr.
2010-06-09 16:53:51 +00:00
Werner Koch
f080b353ed More changes for CE. gpgsm does now build and run a keylisting. 2010-03-24 12:15:30 +00:00
Werner Koch
943aaf0cba Replace use stdio by estream functions. 2010-03-08 12:22:18 +00:00
Werner Koch
9a96043be4 Unification of the search descriptor usage. 2009-12-08 16:30:33 +00:00
Werner Koch
2193992559 Impleemned gpgsm's IMPORT --re-import feature.
Typo fix.
2009-07-07 16:52:12 +00:00
Werner Koch
f8b4cd7650 Import/export of pkcs#12 now uses the gpg-agent directly.
Removed duplicated code (percent unescaping).
2009-04-01 10:51:53 +00:00
Werner Koch
0ca1cfe3b3 Try to start the agent before invoking the protect-tool. 2008-10-23 09:41:41 +00:00
Werner Koch
0a5f742466 Marked all unused args on non-W32 platforms. 2008-10-20 13:53:23 +00:00
Werner Koch
ee3a1ec0d8 Fix --output option used when with --export-secret-kety-p12. 2008-05-20 08:00:40 +00:00
Werner Koch
0819c1e8ca Always search missing certifcates using a running Dirmngr's cache. 2008-02-13 16:47:14 +00:00
Werner Koch
d84d5ea748 [W32] Avoid extra console window when importing or exporting.
Fixes bug 875.
2008-01-27 14:43:52 +00:00
Werner Koch
8464627bf4 Extended the --check-program output: Error messages are now inlcued in an
easy parsable format.
2007-08-29 16:59:20 +00:00
Werner Koch
b13587ef16 New command --check-programs for gpgconf. 2007-08-29 09:51:37 +00:00
Werner Koch
f81f521a72 Updated estream.
More changes for Windows.
2007-08-22 10:55:07 +00:00
Werner Koch
74d344a521 Implemented the chain model for X.509 validation. 2007-08-10 16:52:05 +00:00
Werner Koch
93d3811abc Changed to GPLv3.
Removed intl/.
2007-07-04 19:49:40 +00:00
Werner Koch
0cfbfd6186 A whole bunch of changes to allow building for Windows.
See the ChangeLogs for details.
2007-06-14 17:05:07 +00:00
Werner Koch
12cc96a176 kbx/
* keybox.h (KEYBOX_FLAG_BLOB_SECRET, KEYBOX_FLAG_BLOB_EPHEMERAL):
	New.
	* keybox-update.c (keybox_compress): Use it here instead of a
	magic constant.
sm/
	* fingerprint.c (gpgsm_get_fingerprint): Add caching.
	(gpgsm_get_fingerprint_string): Use bin2hexcolon().
	(gpgsm_get_fingerprint_hexstring): Use bin2hex and allocate only
	as much memory as required.
	(gpgsm_get_keygrip_hexstring): Use bin2hex.

	* certchain.c (gpgsm_validate_chain): Keep track of the
	certificate chain and reset the ephemeral flags.
	* keydb.c (keydb_set_cert_flags): New args EPHEMERAL and MASK.
	Changed caller to use a mask of ~0.  Return a proper error code if
	the certificate is not available.
2007-03-20 16:57:40 +00:00
Werner Koch
03d3322e5f Take advantage of newer gpg-error features. 2006-09-14 16:50:33 +00:00
Werner Koch
eef036df23 The big Assuan error code removal. 2006-09-06 16:35:52 +00:00
Werner Koch
f98537733a Updated FSF's address. 2006-06-20 17:21:37 +00:00
Werner Koch
581f5ddb17 * configure.ac: Add PATHSEP_C and PATHSEP_S. For W32 let all
directories default to c:/gnupg.  Require libassuan 0.6.9.

* gpg-agent.c (main) [W32]: Now that Mutexes work we can remove
the pth_init kludge.
(main): Add new options --[no-]use-standard-socket.
(check_for_running_agent): Check whether it is running on the
standard socket.

* sysutils.h [W32]: Define sleep.
* util.h: Add prototype for mkdtemp.

* call-agent.c (start_agent): Before starting a pipe server start
to connect to a server on the standard socket.  Use PATHSEP
* call-dirmngr.c (start_dirmngr): Use PATHSEP.

* import.c: Include unistd.h for dup and close.
2004-12-20 16:17:25 +00:00
Werner Koch
0a058ac53c * exechelp.h, exechelp.c: New. Based on code from ../sm/import.c.
* gpgsm.c (run_protect_tool) [_WIN32]: Disabled.

* import.c (popen_protect_tool): Simplified by making use of
gnupg_spawn_process.
(parse_p12): Likewise, using gnupg_wait_process.
* export.c (popen_protect_tool): Ditto.
(export_p12): Ditto.
2004-12-06 18:28:56 +00:00
Werner Koch
530a0a91c4 * minip12.c (parse_bag_encrypted_data): Print error if a bad
passphrase has been given.

* gpg-agent.texi (Invoking GPG-AGENT): Add a few words about the
expected pinentry filename.

* import.c (parse_p12): Write an error status line for bad
passphrases. Add new arg CTRL and changed caller.
* export.c (export_p12): Likewise.
2004-09-29 13:50:31 +00:00
Marcus Brinkmann
e5a6d2b456 2004-08-17 Marcus Brinkmann <marcus@g10code.de>
* import.c: Fix typo in last change.
2004-08-17 20:06:24 +00:00
Werner Koch
066352a6a5 * import.c (check_and_store): Do a full validation if
--with-validation is set.

* certchain.c (gpgsm_basic_cert_check): Print more detailed error
messages.

* certcheck.c (do_encode_md): Partly support DSA.  Add new arg
PKALGO. Changed all callers to pass it.
(pk_algo_from_sexp): New.

tests/pkits: New directory
2004-08-17 15:26:22 +00:00
Werner Koch
28f89ad245 * protect-tool.c: New option --enable-status-msg.
(store_private_key): Print status messages for imported keys.
(read_and_unprotect): Ditto for bad passphrase.

* import.c (check_and_store): Do not update the stats for hidden
imports of issuer certs.
(popen_protect_tool): Request statusmessages from the protect-tool.
(parse_p12): Detect status messages. Add new arg STATS and update them.
(print_imported_summary): Include secret key stats.
2004-04-30 15:24:33 +00:00
Werner Koch
6d96ca16cf (check_and_store): Do not update the stats for hidden
imports of issuer certs.
2004-04-30 03:27:10 +00:00
Werner Koch
aaac5dd2dc * misc.c (setup_pinentry_env): New.
* import.c (popen_protect_tool): Call it.
* export.c (popen_protect_tool): Call it.
2004-04-13 09:45:35 +00:00
Werner Koch
d84d632583 * configure.ac: Require libgcrypt 1.1.94.
Introduce PACKAGE_GT and set it to gnupg2.

* gpg-agent.c (main): Use new libgcrypt thread library register
scheme.

* Makevars (DOMAIN): Init from PACKAGE_GT
2004-04-06 10:01:04 +00:00
Werner Koch
a1b487a17a * protect-tool.c: New options --have-cert and --prompt.
(export_p12_file): Read a certificate from STDIN and pass it to
p12_build.  Detect a keygrip and construct the filename in that
case.  Unprotcet a key if needed.  Print error messages for key
formats we can't handle.
(release_passphrase): New.
(get_passphrase): New arg PROMPTNO. Return the allocated
string. Changed all callers.

* minip12.c: Revamped the build part.
(p12_build): New args CERT and CERTLEN.

* simple-pwquery.c (agent_open): Don't mangle INFOSTR.

* export.c (export_p12, popen_protect_tool)
(gpgsm_p12_export): New.
* gpgsm.c (main): New command --export-secret-key-p12.
2004-02-19 16:26:32 +00:00
Werner Koch
45a817bf4a * gpgsm.c: New option --with-md5-fingerprint.
* keylist.c (list_cert_std): Print MD5 fpr.

* gpgsm.c: New options --with-validation.
* server.c (option_handler): New option "with-validation".
* keylist.c (list_cert_std, list_internal_keys): New args CTRL and
WITH_VALIDATION. Changed callers to set it.
(list_external_cb, list_external_keys): Pass CTRL to the callback.
(list_cert_colon): Add arg CTRL.  Check validation if requested.
* certchain.c (unknown_criticals, allowed_ca, check_cert_policy)
(gpgsm_validate_chain): New args LISTMODE and FP.
(do_list): New helper for info output.
(find_up): New arg FIND_NEXT.
(gpgsm_validate_chain): After a bad signature try again with other
CA certificates.

* import.c (print_imported_status): New arg NEW_CERT. Print
additional STATUS_IMPORT_OK becuase that is what gpgme expects.
(check_and_store): Always call above function after import.
* server.c (get_status_string): Added STATUS_IMPORT_OK.
2004-02-17 15:05:04 +00:00
Werner Koch
1a159fd8e3 * encrypt.c (init_dek): Check for too weak algorithms.
* import.c (parse_p12, popen_protect_tool): New.

* base64.c (gpgsm_create_reader): New arg ALLOW_MULTI_PEM.
Changed all callers.
(base64_reader_cb): Handle it here.
(gpgsm_reader_eof_seen): New.
(base64_reader_cb): Set a flag for EOF.
(simple_reader_cb): Ditto.
2004-02-13 12:40:23 +00:00