summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--TODO2
-rw-r--r--common/ChangeLog8
-rw-r--r--common/iobuf.c20
-rw-r--r--common/ttyio.c16
-rw-r--r--common/util.h4
-rw-r--r--configure.ac36
-rw-r--r--g10/ChangeLog264
-rw-r--r--g10/Makefile.am2
-rw-r--r--g10/armor.c39
-rw-r--r--g10/build-packet.c4
-rw-r--r--g10/encode.c4
-rw-r--r--g10/exec.c10
-rw-r--r--g10/g10.c313
-rw-r--r--g10/getkey.c8
-rw-r--r--g10/gpgv.c16
-rw-r--r--g10/import.c232
-rw-r--r--g10/keyedit.c226
-rw-r--r--g10/keygen.c52
-rw-r--r--g10/keylist.c147
-rw-r--r--g10/keyring.c7
-rw-r--r--g10/keyserver.c9
-rw-r--r--g10/main.h5
-rw-r--r--g10/mainproc.c131
-rw-r--r--g10/misc.c29
-rw-r--r--g10/options.h27
-rw-r--r--g10/options.skel18
-rw-r--r--g10/packet.h9
-rw-r--r--g10/parse-packet.c65
-rw-r--r--g10/passphrase.c22
-rw-r--r--g10/photoid.c4
-rw-r--r--g10/pkclist.c4
-rw-r--r--g10/revoke.c2
-rw-r--r--g10/sig-check.c81
-rw-r--r--g10/sign.c65
-rw-r--r--g10/signal.c27
-rw-r--r--g10/status.c1
-rw-r--r--g10/status.h1
-rw-r--r--g10/tdbdump.c2
-rw-r--r--g10/tdbio.c5
-rw-r--r--g10/trustdb.c42
-rw-r--r--g10/trustdb.h3
-rw-r--r--include/ChangeLog11
-rw-r--r--include/cipher.h1
-rw-r--r--include/types.h10
45 files changed, 1489 insertions, 509 deletions
diff --git a/ChangeLog b/ChangeLog
index 172dd0fe4..ce3d76967 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2003-09-23 Werner Koch <wk@gnupg.org>
+
+ Merged most of David Shaw's changes in 1.3 since 2003-06-03.
+
+ * configure.ac: Drop all TIGER/192 support.
+ (uint64_t): Check for UINT64_C to go along with uint64_t.
+ (getaddrinfo): Check for it.
+ (sigset_t): Check for sigset_t and struct sigaction. This is for
+ Forte c89 on Solaris which seems to define only the function call
+ half of the two pairs by default.
+ (W32LIBS): Include wsock32 in W32LIBS. This is different from
+ NETLIBS so we don't need to force other platforms to pull in the
+ netlibs when they aren't actually needed.
+
2003-09-06 Werner Koch <wk@gnupg.org>
Released 1.9.1.
diff --git a/TODO b/TODO
index fe81d0241..da337f247 100644
--- a/TODO
+++ b/TODO
@@ -63,3 +63,5 @@ might want to have an agent context for each service request
* ALL
** Return IMPORT_OK status.
+
+* Where is http.c, regcomp.c, srv.c, w32reg.c ?
diff --git a/common/ChangeLog b/common/ChangeLog
index 66e935b28..caabdd4cf 100644
--- a/common/ChangeLog
+++ b/common/ChangeLog
@@ -1,3 +1,11 @@
+2003-09-23 Werner Koch <wk@gnupg.org>
+
+ * iobuf.c (check_special_filename): Replaced is isdigit by digitp
+ to avoid passing negative values and potential locale problems.
+ Problem noted by Christian Biere.
+
+ * util.h (ascii_isspace): New.
+
2003-09-18 Werner Koch <wk@gnupg.org>
* ttyio.c (tty_fprintf): New.
diff --git a/common/iobuf.c b/common/iobuf.c
index 773e2993b..4d735397e 100644
--- a/common/iobuf.c
+++ b/common/iobuf.c
@@ -101,7 +101,7 @@ typedef struct close_cache_s *CLOSE_CACHE;
static CLOSE_CACHE close_cache;
#endif
-#ifdef __MINGW32__
+#ifdef _WIN32
typedef struct
{
int sock;
@@ -112,7 +112,7 @@ typedef struct
char fname[1]; /* name of the file */
}
sock_filter_ctx_t;
-#endif /*__MINGW32__*/
+#endif /*_WIN32*/
/* The first partial length header block must be of size 512
* to make it easier (and efficienter) we use a min. block size of 512
@@ -580,7 +580,7 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
return rc;
}
-#ifdef __MINGW32__
+#ifdef _WIN32
/* Becuase sockets are an special object under Lose32 we have to
* use a special filter */
static int
@@ -667,7 +667,7 @@ sock_filter (void *opaque, int control, iobuf_t chain, byte * buf,
}
return rc;
}
-#endif /*__MINGW32__*/
+#endif /*_WIN32*/
/****************
* This is used to implement the block write mode.
@@ -1171,7 +1171,7 @@ check_special_filename (const char *fname)
int i;
fname += 2;
- for (i = 0; isdigit (fname[i]); i++)
+ for (i = 0; digitp (fname+i); i++)
;
if (!fname[i])
return atoi (fname);
@@ -1262,7 +1262,7 @@ iobuf_t
iobuf_sockopen (int fd, const char *mode)
{
iobuf_t a;
-#ifdef __MINGW32__
+#ifdef _WIN32
sock_filter_ctx_t *scx;
size_t len;
@@ -1405,7 +1405,7 @@ iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
b->keep_open = intval;
return 0;
}
-#ifdef __MINGW32__
+#ifdef _WIN32
else if (!a->chain && a->filter == sock_filter)
{
sock_filter_ctx_t *b = a->filter_ov;
@@ -1440,7 +1440,7 @@ iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
b->no_cache = intval;
return 0;
}
-#ifdef __MINGW32__
+#ifdef _WIN32
else if (!a->chain && a->filter == sock_filter)
{
sock_filter_ctx_t *b = a->filter_ov;
@@ -2363,7 +2363,7 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
int
iobuf_translate_file_handle (int fd, int for_write)
{
-#ifdef __MINGW32__
+#ifdef _WIN32
{
int x;
@@ -2387,7 +2387,7 @@ iobuf_translate_file_handle (int fd, int for_write)
static int
translate_file_handle (int fd, int for_write)
{
-#ifdef __MINGW32__
+#ifdef _WIN32
#ifdef FILE_FILTER_USES_STDIO
fd = iobuf_translate_file_handle (fd, for_write);
#else
diff --git a/common/ttyio.c b/common/ttyio.c
index c77b4a85a..eab805e20 100644
--- a/common/ttyio.c
+++ b/common/ttyio.c
@@ -37,7 +37,7 @@
#define HAVE_TCGETATTR
#endif
#endif
-#ifdef __MINGW32__ /* use the odd Win32 functions */
+#ifdef _WIN32 /* use the odd Win32 functions */
#include <windows.h>
#ifdef HAVE_TCGETATTR
#error mingw32 and termios
@@ -51,7 +51,7 @@
#define CONTROL_D ('D' - 'A' + 1)
-#ifdef __MINGW32__ /* use the odd Win32 functions */
+#ifdef _WIN32 /* use the odd Win32 functions */
static struct {
HANDLE in, out;
} con;
@@ -124,7 +124,7 @@ init_ttyfp(void)
if( initialized )
return;
-#if defined(__MINGW32__)
+#if defined(_WIN32)
{
SECURITY_ATTRIBUTES sa;
@@ -194,7 +194,7 @@ tty_printf( const char *fmt, ... )
init_ttyfp();
va_start( arg_ptr, fmt ) ;
-#ifdef __MINGW32__
+#ifdef _WIN32
{
char *buf = NULL;
int n;
@@ -241,7 +241,7 @@ tty_fprintf (FILE *fp, const char *fmt, ... )
init_ttyfp();
va_start( arg_ptr, fmt ) ;
-#ifdef __MINGW32__
+#ifdef _WIN32
{
char *buf = NULL;
int n;
@@ -278,7 +278,7 @@ tty_print_string ( const byte *p, size_t n )
if( !initialized )
init_ttyfp();
-#ifdef __MINGW32__
+#ifdef _WIN32
/* not so effective, change it if you want */
for( ; n; n--, p++ )
if( iscntrl( *p ) ) {
@@ -372,7 +372,7 @@ do_get( const char *prompt, int hidden )
buf = xmalloc((n=50));
i = 0;
-#ifdef __MINGW32__ /* windoze version */
+#ifdef _WIN32 /* windoze version */
if( hidden )
SetConsoleMode(con.in, HID_INPMODE );
@@ -527,7 +527,7 @@ tty_kill_prompt()
last_prompt_len = 0;
if( !last_prompt_len )
return;
-#ifdef __MINGW32__
+#ifdef _WIN32
tty_printf("\r%*s\r", last_prompt_len, "");
#else
{
diff --git a/common/util.h b/common/util.h
index 045851481..78aa2f890 100644
--- a/common/util.h
+++ b/common/util.h
@@ -107,6 +107,10 @@ int asprintf (char **result, const char *format, ...);
#define hexdigitp(a) (digitp (a) \
|| (*(a) >= 'A' && *(a) <= 'F') \
|| (*(a) >= 'a' && *(a) <= 'f'))
+ /* Note this isn't identical to a C locale isspace() without \f and
+ \v, but works for the purposes used here. */
+#define ascii_isspace(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t')
+
/* the atoi macros assume that the buffer has only valid digits */
#define atoi_1(p) (*(p) - '0' )
#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1))
diff --git a/configure.ac b/configure.ac
index 4ee1898b5..23baee44a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -647,7 +647,17 @@ AC_CHECK_SIZEOF(unsigned short)
AC_CHECK_SIZEOF(unsigned int)
AC_CHECK_SIZEOF(unsigned long)
AC_CHECK_SIZEOF(unsigned long long)
-AC_CHECK_SIZEOF(uint64_t)
+# Ensure that we have UINT64_C before we bother to check for uint64_t
+# fixme: really needed in gnupg? I think it is only useful in libcgrypt.
+AC_CACHE_CHECK([for UINT64_C],[gnupg_cv_uint64_c_works],
+ AC_COMPILE_IFELSE(AC_LANG_PROGRAM([#include <inttypes.h>
+uint64_t foo=UINT64_C(42);]),gnupg_cv_uint64_c_works=yes,gnupg_cv_uint64_c_works=no))
+if test "$gnupg_cv_uint64_c_works" = "yes" ; then
+ AC_CHECK_SIZEOF(uint64_t)
+fi
+
+
+
if test "$ac_cv_sizeof_unsigned_short" = "0" \
|| test "$ac_cv_sizeof_unsigned_int" = "0" \
@@ -660,19 +670,8 @@ if test "$ac_cv_sizeof_unsigned_int" != "8" \
&& test "$ac_cv_sizeof_unsigned_long" != "8" \
&& test "$ac_cv_sizeof_unsigned_long_long" != "8" \
&& test "$ac_cv_sizeof_uint64_t" != "8"; then
- AC_MSG_WARN([No 64-bit types. Disabling TIGER/192, SHA-384, and SHA-512])
+ AC_MSG_WARN([No 64-bit types. Disabling SHA-384, and SHA-512])
else
- if test x"$use_tiger192" = xyes ; then
- AC_SUBST(TIGER_O,tiger.o)
- AC_DEFINE(USE_TIGER192,1,[Define to include the TIGER/192 digest])
- fi
-
- if test "$use_old_tiger192" = yes ; then
- AC_SUBST(TIGER_O,tiger.o)
- AC_DEFINE(USE_TIGER192,1,[Define to include the TIGER/192 digest])
- AC_DEFINE(USE_OLD_TIGER,1,[Define to use the old fake OID for TIGER/192 digest support])
- fi
-
if test x"$use_sha512" = xyes ; then
AC_SUBST(SHA512_O,sha512.o)
AC_DEFINE(USE_SHA512,1,[Define to include the SHA-384 and SHA-512 digests])
@@ -689,9 +688,11 @@ AC_CHECK_FUNCS(strerror stpcpy strsep strlwr tcgetattr strtoul mmap)
AC_CHECK_FUNCS(strcasecmp strncasecmp ctermid times)
AC_CHECK_FUNCS(memmove gettimeofday getrusage setrlimit clock_gettime)
AC_CHECK_FUNCS(atexit raise getpagesize strftime nl_langinfo setlocale)
-AC_CHECK_FUNCS(waitpid wait4 sigaction sigprocmask rand pipe stat)
+AC_CHECK_FUNCS(waitpid wait4 sigaction sigprocmask rand pipe stat getaddrinfo)
+
+AC_CHECK_TYPES([struct sigaction, sigset_t],,,[#include <signal.h>])
-# These are needed by libjnlib - fixme: we should have a macros for them
+# These are needed by libjnlib - fixme: we should have macros for them
AC_CHECK_FUNCS(memicmp stpcpy strlwr strtoul memmove stricmp strtol)
AC_CHECK_FUNCS(getrusage setrlimit stat setlocale)
AC_CHECK_FUNCS(flockfile funlockfile)
@@ -703,6 +704,8 @@ AC_REPLACE_FUNCS(fseeko ftello)
AC_REPLACE_FUNCS(isascii)
AC_REPLACE_FUNCS(putc_unlocked)
+
+
#
# check for gethrtime and run a testprogram to see whether
# it is broken. It has been reported that some Solaris and HP UX systems
@@ -877,7 +880,7 @@ GNUPG_CHECK_GNUMAKE
# mysterious reasons - the final link step should bail out.
case "${target}" in
*-*-mingw32*)
- LIBS="$LIBS -lwsock32"
+ W32LIBS="-lwsock32"
;;
*)
;;
@@ -893,6 +896,7 @@ if test "$GCC" = yes; then
fi
AC_SUBST(NETLIBS)
+AC_SUBST(W32LIBS)
# We use jnlib, so tell other modules about it
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 221961c4e..ac7a69468 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,267 @@
+2003-09-23 Werner Koch <wk@gnupg.org>
+
+ Merged most of David Shaw's changes in 1.3 since 2003-06-03.
+
+ * Makefile.am: Include W32LIBS where appropriate.
+
+ * armor.c (parse_hash_header,armor_filter): Drop TIGER/192 support.
+ * g10.c (print_hex,print_mds): Ditto.
+ * pkclist.c (algo_available): Ditto.
+
+ * armor.c (armor_filter): Allow using --comment multiple times to
+ get multiple Comment header lines. --no-comments resets list.
+ * options.h, g10.c (main): Ditto. Deprecate --default-comment in
+ favor of --no-comments.
+
+ * g10.c (main): Trim --help to commonly used options. Remove -f.
+
+ * g10.c (main): Add --multifile as an alias to turn --encrypt into
+ --encrypt-files (plus --verify-files, --decrypt-files). Error out
+ if --multifile is used with the commands that don't support it yet.
+
+ * encode.c (use_mdc), g10.c (main): Use RFC1991 and RFC2440
+ directly to check for MDC usability. Do not set the force_mdc or
+ disable_mdc flags since there is no point any longer.
+
+ * g10.c (main): Use "keyserver-url" instead of
+ "preferred-keyserver" for the sake of short and simple commands.
+ (add_keyserver_url): Clarify a few strings. It's a
+ "preferred keyserver URL".
+ * keyedit.c (keyedit_menu): Ditto.
+ * sign.c (mk_notation_policy_etc): Ditto.
+
+ * main.h, keygen.c (keygen_add_keyserver_url): Signature callback
+ for adding a keyserver URL.
+ * keyedit.c (keyedit_menu, menu_set_keyserver_url): New command to
+ set preferred keyserver to specified (or all) user IDs.
+ * build-packet.c (build_sig_subpkt): Set preferred keyserver flag
+ while building a preferred keyserver subpacket.
+
+ * keylist.c (show_policy_url, show_keyserver_url): URLs might be
+ UTF8.
+
+ * keyedit.c (menu_addrevoker): Fix leaking a few bytes.
+
+ * keyedit.c (show_key_with_all_names): Use list-option
+ show-long-keyid in main --edit-key display.
+
+ * keyedit.c (print_and_check_one_sig): Use list-option
+ show-long-keyid in --edit-key "check" function.
+
+ * passphrase.c (agent_send_all_options): Make use of $GPG_TTY.
+
+ * g10.c (main): Disable use-agent if passphrase-fd is given
+ later. Suggested by Kurt Garloff.
+
+ * exec.c, g10.c, gpgv.c, passphrase.c, photoid.c:
+ s/__MINGW32__/_WIN32/ to help building on native Windows
+ compilers. Requested by Brian Gladman. From Werner on stable
+ branch.
+
+ * options.h, g10.c (main): Add list-option
+ list-preferred-keyserver.
+
+ * keyedit.c (change_passphrase): When responding 'no' to the blank
+ passphrase question, re-prompt for a new passphrase. This is bug
+ #202.
+
+ * mainproc.c (check_sig_and_print): Use two different preferred
+ keyserver displays - one if the key is not present (to tell the
+ user where to get the key), the other if it is present (to tell
+ the user where the key can be refreshed).
+
+ * packet.h, parse-packet.c (parse_signature): Set flag if a
+ preferred keyserver is present.
+
+ * keylist.c (list_keyblock_print): Show keyserver url in listings
+ with list-option show-keyserver-url.
+
+ * mainproc.c (check_sig_and_print): Get the uid validity before
+ printing any sig results to avoid munging the output with trustdb
+ warnings.
+
+ * g10.c (main): Don't include --show-keyring in --help as it is
+ deprecated.
+
+ * options.skel: Note that keyserver.pgp.com isn't synchronized,
+ and explain the roundrobin a bit better.
+
+ * sig-check.c (check_key_signature2), import.c (import_one,
+ import_revoke_cert, chk_self_sigs, delete_inv_parts,
+ collapse_uids, merge_blocks): Make much quieter during import of
+ slightly munged, but recoverable, keys. Use log_error for
+ unrecoverable import failures.
+
+ * keyring.c (keyring_rebuild_cache): Comment.
+
+ * sign.c (mk_notation_and_policy): Making a v3 signature with
+ notations or policy urls is an error, not an info (i.e. increment
+ the errorcount). Don't print the notation or policy url to stdout
+ since it can be mixed into the output stream when piping and munge
+ the stream.
+
+ * packet.h, sig-check.c (signature_check2, do_check,
+ do_check_messages): Provide a signing-key-is-revoked flag. Change
+ all callers.
+
+ * status.h, status.c (get_status_string): New REVKEYSIG status tag
+ for a good signature from a revoked key.
+
+ * mainproc.c (do_check_sig, check_sig_and_print): Use it here.
+
+ * import.c (import_revoke_cert, merge_blocks, merge_sigs): Compare
+ actual signatures on import rather than using keyid or class
+ matching. This does not change actual behavior with a key, but
+ does mean that all sigs are imported whether they will be used or
+ not.
+
+ * parse-packet.c (parse_signature): Don't give "signature packet
+ without xxxx" warnings for experimental pk algorithms. An
+ experimental algorithm may not have a notion of (for example) a
+ keyid (i.e. PGP's x.509 stuff).
+
+ * options.h, g10.c (main), keylist.c (list_keyblock_print),
+ keyedit.c (print_and_check_one_sig): New "show-sig-expire"
+ list-option to show signature expiration dates (if any).
+
+ * options.h, g10.c (main, add_keyserver_url): Add
+ --sig-preferred-keyserver to implant a "where to get my key"
+ subpacket into a signature.
+
+ * sign.c (mk_notation_and_policy): Rename to
+ mk_notation_policy_etc and add preferred keyserver support for
+ signatures.
+
+ * keygen.c (do_add_key_flags): Don't set the certify flag for
+ subkeys.
+ (ask_algo): Provide key flags for DSA, Elgamal_e, and Elgamal
+ subkeys.
+ (generate_keypair): Provide key flags for the default DSA/Elgamal
+ keys.
+
+ * sig-check.c (signature_check, signature_check2,
+ check_key_signature, check_key_signature2): Allow passing NULLs
+ for unused parameters in the x2 form of each function to avoid the
+ need for dummy variables. getkey.c, mainproc.c: Change all
+ callers.
+
+ * trustdb.h, trustdb.c (read_trust_options): New. Returns items
+ from the trustdb version record.
+ * keylist.c (public_key_list): Use it here for the new "tru"
+ record.
+ * gpgv.c (read_trust_options): Stub.
+
+ * keyedit.c (show_key_with_all_names): Use list-option
+ show-validity in --edit-key interface as well.
+
+ * options.h, g10.c (main), mainproc.c (check_sig_and_print): Add
+ verify-options "show-validity" and "show-long-keyid" to show
+ trustdb validity and long keyids during (file) signature
+ verification.
+
+ * packet.h, main.h, sig-check.c (signature_check2)
+ (check_key_signature2, do_check): If ret_pk is set, fill in the pk
+ used to verify the signature. Change all callers in getkey.c,
+ mainproc.c, and sig-check.c.
+
+ * keylist.c (list_keyblock_colon): Use the ret_pk from above to
+ put the fingerprint of the signing key in "sig" records during a
+ --with-colons --check-sigs. This requires --no-sig-cache as well
+ since we don't cache fingerprints.
+
+ * parse-packet.c (parse_signature): No need to reserve 8 bytes for
+ the unhashed signature cache any longer.
+
+ * misc.c (pct_expando): Add two new expandos - signer's
+ fingerprint (%g), and signer's primary fingerprint (%p).
+
+ * g10.c (main): Add --rfc2440 alias for --openpgp since in a few
+ months, they won't be the same thing.
+
+ * keyserver.c (parse_keyserver_uri): Accept "http" as an alias for
+ "hkp", since it is occasionally written that way.
+ (keyserver_spawn): Use ascii_isspace to avoid locale issues.
+
+ * keygen.c (ask_user_id): Make --allow-freeform-uid apply to the
+ email field as well as the name field, and allow mixing fields
+ when it is set.
+
+ * trustdb.c (validate_one_keyblock): Certifications on revoked or
+ expired uids do not count in the web of trust.
+
+ * signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
+ sigprocmask() if we have sigset_t, and only use sigaction() if we
+ have struct sigaction. This is for Forte c89 on Solaris which
+ seems to define only the function call half of the two pairs by
+ default.
+ (pause_on_sigusr): Typo.
+ (do_block): If we can't use sigprocmask() and sigset_t, try to get
+ the number of signals from NSIG as well as MAXSIG, and if we
+ can't, fail with an explanation.
+
+ * signal.c, tdbio.c: Comment out the transaction code. It was not
+ used in this version, and was causing some build problems on
+ quasi-posix platforms (Solaris and Forte c89).
+
+ * keylist.c (list_keyblock_colon): Don't include validity values
+ when listing secret keys since they can be incorrect and/or
+ misleading. This is a temporary kludge, and will be handled
+ properly in 1.9/2.0.
+
+ * mainproc.c (check_sig_and_print): Only show the "key available
+ from" preferred keyserver line if the key is not currently
+ present.
+
+ * keyedit.c (sign_uids): Do not sign expired uids without --expert
+ (same behavior as revoked uids). Do not allow signing a user ID
+ without a self-signature. --expert overrides. Add additional
+ prompt to the signature level question.
+ (menu_expire): When changing expiration dates, don't replace
+ selfsigs on revoked uids since this would effectively unrevoke
+ them. There is also no point in replacing expired selfsigs. This
+ is bug #181
+
+ * g10.c (add_notation_data): Make sure that only ascii is passed
+ to iscntrl. Noted by Christian Biere.
+ * getkey.c (classify_user_id2): Replaced isspace by spacep
+ * keygen.c (ask_user_id): Ditto.
+ (get_parameter_algo): Ditto.
+ * keyedit.c (keyedit_menu): Ditto.
+ * tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
+ * revoke.c (ask_revocation_reason):
+ * keyserver.c (keyserver_spawn): Dito.
+
+ * parse-packet.c (parse): Disallow old style partial length for
+ all key material packets to avoid possible corruption of keyrings.
+
+ * import.c (import_keys_internal): Invalidate the cache so that
+ the file descriptor gets closed. Fixes bug reported by Juan
+ F. Codagnone.
+
+ * options.h, g10.c (main), main.h, keylist.c (show_keyserver_url),
+ mainproc.c (check_sig_and_print), parse-packet.c (dump_sig_subpkt,
+ parse_one_sig_subpkt, can_handle_critical): Add read-only support
+ for preferred keyserver subpackets. They're basically policy URLs
+ with a different name. Add a verify-option
+ "show-preferred-keyserver" to turn them on and off (on by default,
+ as per stable branch).
+
+ * g10.c (main): Add "--set-notation" as alias to "--notation-data"
+ this is to make things consistent with --set-policy-url meaning
+ both sigs and certs.
+
+ * options.h, g10.c (main), keylist.c (list_keyblock_print): Add
+ "show-validity" and "show-long-keyid" list-options.
+
+ * gpgv.c (get_validity, trust_value_to_string): Stubs.
+
+ * g10.c (main): Use SAFE_VERSION instead of VERSION in the
+ version-specific gpg.conf file so it can be overridden on RISCOS.
+
+ * keyedit.c (show_key_with_all_names): Fix assertion failure when
+ using toggle to see a secret key. Reported by Maxim Britov.
+
+
2003-09-22 Timo Schulz <twoaday@freakmail.de>
* card-util.c (card_status): Free pk in case of an error
diff --git a/g10/Makefile.am b/g10/Makefile.am
index 59213d04b..ef2b0c3a8 100644
--- a/g10/Makefile.am
+++ b/g10/Makefile.am
@@ -109,7 +109,7 @@ gpgv2_SOURCES = gpgv.c \
# ks-db.h \
# $(common_source)
-LDADD = $(needed_libs) @INTLLIBS@ @CAPLIBS@ @ZLIBS@
+LDADD = $(needed_libs) @INTLLIBS@ @CAPLIBS@ @ZLIBS@ @W32LIBS@
gpg2_LDADD = $(LIBGCRYPT_LIBS) $(LDADD) -lassuan -lgpg-error
gpgv2_LDADD = $(LIBGCRYPT_LIBS) $(LDADD) -lassuan -lgpg-error
diff --git a/g10/armor.c b/g10/armor.c
index c6930e22a..121ec3a09 100644
--- a/g10/armor.c
+++ b/g10/armor.c
@@ -249,16 +249,12 @@ parse_hash_header( const char *line )
found |= 2;
else if( !strncmp( s, "MD5", s2-s ) )
found |= 4;
- else if( !strncmp( s, "TIGER192", s2-s ) )
- found |= 8;
- else if( !strncmp( s, "TIGER", s2-s ) ) /* used by old versions */
- found |= 8;
else if( !strncmp( s, "SHA256", s2-s ) )
- found |= 16;
+ found |= 8;
else if( !strncmp( s, "SHA384", s2-s ) )
- found |= 32;
+ found |= 16;
else if( !strncmp( s, "SHA512", s2-s ) )
- found |= 64;
+ found |= 32;
else
return 0;
for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
@@ -899,12 +895,10 @@ armor_filter( void *opaque, int control,
if( hashes & 4 )
buf[n++] = DIGEST_ALGO_MD5;
if( hashes & 8 )
- buf[n++] = DIGEST_ALGO_TIGER;
- if( hashes & 16 )
buf[n++] = DIGEST_ALGO_SHA256;
- if( hashes & 32 )
+ if( hashes & 16 )
buf[n++] = DIGEST_ALGO_SHA384;
- if( hashes & 64 )
+ if( hashes & 32 )
buf[n++] = DIGEST_ALGO_SHA512;
buf[1] = n - 2;
@@ -932,6 +926,7 @@ armor_filter( void *opaque, int control,
else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
if( !afx->status ) { /* write the header line */
const char *s;
+ STRLIST comment = opt.comments;
if( afx->what >= DIM(head_strings) )
log_bug("afx->what=%d", afx->what);
@@ -942,22 +937,24 @@ armor_filter( void *opaque, int control,
iobuf_writestr(a, "Version: GnuPG v" VERSION " ("
PRINTABLE_OS_NAME ")" LF );
- /* write the comment string or a default one */
- s = opt.comment_string;
- if( s && *s ) {
+ /* Write the comment string. */
+ for(s=comment? comment->d:NULL; comment;
+ comment=comment->next,s=comment->d)
+ {
iobuf_writestr(a, "Comment: " );
- for( ; *s; s++ ) {
+ for ( ; *s; s++ )
+ {
if( *s == '\n' )
- iobuf_writestr(a, "\\n" );
+ iobuf_writestr(a, "\\n" );
else if( *s == '\r' )
- iobuf_writestr(a, "\\r" );
+ iobuf_writestr(a, "\\r" );
else if( *s == '\v' )
- iobuf_writestr(a, "\\v" );
+ iobuf_writestr(a, "\\v" );
else
- iobuf_put(a, *s );
- }
+ iobuf_put(a, *s );
+ }
iobuf_writestr(a, LF );
- }
+ }
if ( afx->hdrlines ) {
for ( s = afx->hdrlines; *s; s++ ) {
diff --git a/g10/build-packet.c b/g10/build-packet.c
index a24bdfcc6..d2c538477 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.c
@@ -756,6 +756,10 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
sig->flags.policy_url=1;
break;
+ case SIGSUBPKT_PREF_KS:
+ sig->flags.pref_ks=1;
+ break;
+
case SIGSUBPKT_EXPORTABLE:
if(buffer[0])
sig->flags.exportable=1;
diff --git a/g10/encode.c b/g10/encode.c
index 9fc00183f..7794bdb7c 100644
--- a/g10/encode.c
+++ b/g10/encode.c
@@ -122,6 +122,10 @@ use_mdc (PK_LIST pk_list,int algo)
CIPHER_ALGO_TWOFISH
};
int i;
+
+ /* RFC-1991 and 2440 don't have MDC */
+ if(RFC1991 || RFC2440)
+ return 0;
/* --force-mdc overrides --disable-mdc */
if (opt.force_mdc)
diff --git a/g10/exec.c b/g10/exec.c
index f3b58aa3c..a49fe15d2 100644
--- a/g10/exec.c
+++ b/g10/exec.c
@@ -1,5 +1,5 @@
/* exec.c - generic call-a-program code
- * Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -59,7 +59,7 @@ int set_exec_path(const char *path,int method) { return GPG_ERR_GENERAL; }
char *mkdtemp(char *template);
#endif
-#if defined (__MINGW32__)
+#if defined (_WIN32)
/* This is a nicer system() for windows that waits for programs to
return before returning control to the caller. I hate helpful
computers. */
@@ -139,7 +139,7 @@ static int make_tempdir(struct exec_info *info)
if(tmp==NULL)
{
-#if defined (__MINGW32__)
+#if defined (_WIN32)
tmp=xmalloc (256);
if(GetTempPath(256,tmp)==0)
strcpy(tmp,"c:\\windows\\temp");
@@ -176,7 +176,7 @@ static int make_tempdir(struct exec_info *info)
sprintf(info->tempdir,"%s" DIRSEP_S "gpg-XXXXXX",tmp);
-#if defined (__MINGW32__)
+#if defined (_WIN32)
xfree (tmp);
#endif
@@ -502,7 +502,7 @@ int exec_read(struct exec_info *info)
if(DBG_EXTPROG)
log_debug("system() command is %s\n",info->command);
-#if defined (__MINGW32__)
+#if defined (_WIN32)
info->progreturn=win_system(info->command);
#else
info->progreturn=system(info->command);
diff --git a/g10/g10.c b/g10/g10.c
index 619832372..cdd10d845 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -59,7 +59,6 @@ enum cmd_and_opt_values { aNull = 0,
aSym = 'c',
aDecrypt = 'd',
aEncr = 'e',
- aEncrFiles,
oInteractive = 'i',
aListKeys = 'k',
aListSecretKeys = 'K',
@@ -73,12 +72,13 @@ enum cmd_and_opt_values { aNull = 0,
oUser = 'u',
oVerbose = 'v',
oCompress = 'z',
- oNotation = 'N',
+ oSetNotation = 'N',
oBatch = 500,
oSigNotation,
oCertNotation,
oShowNotation,
oNoShowNotation,
+ aEncrFiles,
aDecryptFiles,
aClearsign,
aStore,
@@ -172,6 +172,7 @@ enum cmd_and_opt_values { aNull = 0,
oLoadExtension,
oGnuPG,
oRFC1991,
+ oRFC2440,
oOpenPGP,
oPGP2,
oPGP6,
@@ -219,9 +220,11 @@ enum cmd_and_opt_values { aNull = 0,
oCertPolicyURL,
oShowPolicyURL,
oNoShowPolicyURL,
+ oSigKeyserverURL,
oUseEmbeddedFilename,
oComment,
oDefaultComment,
+ oNoComments,
oThrowKeyid,
oNoThrowKeyid,
oShowPhotos,
@@ -315,6 +318,7 @@ enum cmd_and_opt_values { aNull = 0,
oMangleDosFilenames,
oNoMangleDosFilenames,
oEnableProgressFilter,
+ oMultifile,
aTest };
@@ -326,17 +330,17 @@ static ARGPARSE_OPTS opts[] = {
{ aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature") },
{ aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
{ aEncr, "encrypt", 256, N_("encrypt data")},
- { aEncrFiles, "encrypt-files", 256, N_("|[files]|encrypt files")},
+ { aEncrFiles, "encrypt-files", 256, "@"},
{ aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
- { aStore, "store", 256, N_("store only")},
+ { aStore, "store", 256, "@"},
{ aDecrypt, "decrypt", 256, N_("decrypt data (default)")},
- { aDecryptFiles, "decrypt-files", 256, N_("|[files]|decrypt files")},
+ { aDecryptFiles, "decrypt-files", 256, "@"},
{ aVerify, "verify" , 256, N_("verify a signature")},
{ aVerifyFiles, "verify-files" , 256, "@" },
{ aListKeys, "list-keys", 256, N_("list keys")},
{ aListKeys, "list-public-keys", 256, "@" },
{ aListSigs, "list-sigs", 256, N_("list keys and signatures")},
- { aCheckKeys, "check-sigs",256, N_("check key signatures")},
+ { aCheckKeys, "check-sigs",256, N_("list and check key signatures")},
{ oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
{ aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
{ aKeygen, "gen-key", 256, N_("generate a new key pair")},
@@ -345,8 +349,8 @@ static ARGPARSE_OPTS opts[] = {
N_("remove keys from the secret keyring")},
{ aSignKey, "sign-key" ,256, N_("sign a key")},
{ aLSignKey, "lsign-key" ,256, N_("sign a key locally")},
- { aNRSignKey, "nrsign-key" ,256, N_("sign a key non-revocably")},
- { aNRLSignKey, "nrlsign-key" ,256, N_("sign a key locally and non-revocably")},
+ { aNRSignKey, "nrsign-key" ,256, "@"},
+ { aNRLSignKey, "nrlsign-key" ,256, "@"},
{ aEditKey, "edit-key" ,256, N_("sign or edit a key")},
{ aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")},
{ aDesigRevoke, "desig-revoke",256, "@" },
@@ -366,19 +370,15 @@ static ARGPARSE_OPTS opts[] = {
{ aCardEdit, "card-edit", 256, N_("change data on a card")},
{ aChangePIN, "change-pin", 256, N_("change a card's PIN")},
- { aListPackets, "list-packets",256,N_("list only the sequence of packets")},
- { aExportOwnerTrust,
- "export-ownertrust", 256, N_("export the ownertrust values")},
- { aImportOwnerTrust,
- "import-ownertrust", 256, N_("import ownertrust values")},
- { aUpdateTrustDB,
- "update-trustdb",0 , N_("update the trust database")},
- { aCheckTrustDB,
- "check-trustdb",0 , N_("unattended trust database update")},
+ { aListPackets, "list-packets",256, "@"},
+ { aExportOwnerTrust, "export-ownertrust", 256, "@"},
+ { aImportOwnerTrust, "import-ownertrust", 256, "@"},
+ { aUpdateTrustDB, "update-trustdb",0 , N_("update the trust database")},
+ { aCheckTrustDB, "check-trustdb",0 , "@"},
{ aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")},
- { aDeArmor, "dearmor", 256, N_("De-Armor a file or stdin") },
+ { aDeArmor, "dearmor", 256, "@" },
{ aDeArmor, "dearmour", 256, "@" },
- { aEnArmor, "enarmor", 256, N_("En-Armor a file or stdin") },
+ { aEnArmor, "enarmor", 256, "@" },
{ aEnArmor, "enarmour", 256, "@" },
{ aPrintMD, "print-md" , 256, N_("|algo [files]|print message digests")},
{ aPrimegen, "gen-prime" , 256, "@" },
@@ -391,10 +391,8 @@ static ARGPARSE_OPTS opts[] = {
{ oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
{ oHiddenRecipient, "hidden-recipient", 2, "@" },
{ oRecipient, "remote-user", 2, "@"}, /* old option name */
- { oDefRecipient, "default-recipient" ,2,
- N_("|NAME|use NAME as default recipient")},
- { oDefRecipientSelf, "default-recipient-self" ,0,
- N_("use the default key as default recipient")},
+ { oDefRecipient, "default-recipient" ,2, "@" },
+ { oDefRecipientSelf, "default-recipient-self" ,0, "@" },
{ oNoDefRecipient, "no-default-recipient", 0, "@" },
{ oTempDir, "temp-directory", 2, "@" },
{ oExecPath, "exec-path", 2, "@" },
@@ -414,82 +412,82 @@ static ARGPARSE_OPTS opts[] = {
{ oNoAskCertExpire, "no-ask-cert-expire", 0, "@"},
{ 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") },
- { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") },
- { oNoForceV3Sigs, "no-force-v3-sigs", 0, N_("do not force v3 signatures") },
- { oForceV4Certs, "force-v4-certs", 0, N_("force v4 key signatures") },
- { oNoForceV4Certs, "no-force-v4-certs", 0, N_("do not force v4 key signatures") },
- { oForceMDC, "force-mdc", 0, N_("always use a MDC for encryption") },
+ { oQuiet, "quiet", 0, "@" },
+ { oNoTTY, "no-tty", 0, "@" },
+ { oForceV3Sigs, "force-v3-sigs", 0, "@" },
+ { oNoForceV3Sigs, "no-force-v3-sigs", 0, "@" },
+ { oForceV4Certs, "force-v4-certs", 0, "@" },
+ { oNoForceV4Certs, "no-force-v4-certs", 0, "@" },
+ { oForceMDC, "force-mdc", 0, "@" },
{ oNoForceMDC, "no-force-mdc", 0, "@" },
- { oDisableMDC, "disable-mdc", 0, N_("never use a MDC for encryption") },
+ { oDisableMDC, "disable-mdc", 0, "@" },
{ oNoDisableMDC, "no-disable-mdc", 0, "@" },
{ oDryRun, "dry-run", 0, N_("do not make any changes") },
{ oInteractive, "interactive", 0, N_("prompt before overwriting") },
- { oUseAgent, "use-agent",0, N_("use the gpg-agent")},
+ { oUseAgent, "use-agent",0, "@"},
{ oNoUseAgent, "no-use-agent",0, "@"},
{ oGpgAgentInfo, "gpg-agent-info",2, "@"},
- { 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")},
+ { oBatch, "batch", 0, "@"},
+ { oAnswerYes, "yes", 0, "@"},
+ { oAnswerNo, "no", 0, "@"},
+ { oKeyring, "keyring" , 2, "@"},
{ oPrimaryKeyring, "primary-keyring",2, "@" },
- { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
- { oShowKeyring, "show-keyring", 0, N_("show which keyring a listed key is on")},
- { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
- { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")},
+ { oSecretKeyring, "secret-keyring" ,2, "@"},
+ { oShowKeyring, "show-keyring", 0, "@"},
+ { oDefaultKey, "default-key" , 2, "@"},
+ { oKeyServer, "keyserver", 2, "@"},
{ oKeyServerOptions, "keyserver-options",2,"@"},
{ oImportOptions, "import-options",2,"@"},
{ oExportOptions, "export-options",2,"@"},
{ oListOptions, "list-options",2,"@"},
- { oCharset, "charset" , 2, N_("|NAME|set terminal charset to NAME") },
- { oOptions, "options" , 2, N_("read options from file")},
+ { oVerifyOptions, "verify-options",2,"@"},
+ { oCharset, "charset" , 2, "@" },
+ { oOptions, "options" , 2, "@"},
{ oDebug, "debug" ,4|16, "@"},
{ oDebugAll, "debug-all" ,0, "@"},
- { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
+ { oStatusFD, "status-fd" ,1, "@" },
#ifdef __riscos__
- { oStatusFile, "status-file" ,2, N_("|[file]|write status info to file") },
+ { oStatusFile, "status-file" ,2, "@" },
#endif /* __riscos__ */
{ oAttributeFD, "attribute-fd" ,1, "@" },
#ifdef __riscos__
{ oAttributeFile, "attribute-file" ,2, "@" },
#endif /* __riscos__ */
- { oNoSKComments, "no-comment", 0, "@"},
{ oNoSKComments, "no-sk-comments", 0, "@"},
{ oSKComments, "sk-comments", 0, "@"},
{ oCompletesNeeded, "completes-needed", 1, "@"},
{ oMarginalsNeeded, "marginals-needed", 1, "@"},
{ oMaxCertDepth, "max-cert-depth", 1, "@" },
- { oTrustedKey, "trusted-key", 2, N_("|KEYID|ultimately trust this key")},
- { oLoadExtension, "load-extension" ,2, N_("|FILE|load extension module FILE")},
+ { oTrustedKey, "trusted-key", 2, "@"},
+ { oLoadExtension, "load-extension" ,2, "@"},
{ oGnuPG, "gnupg", 0, "@"},
{ oGnuPG, "no-pgp2", 0, "@"},
{ oGnuPG, "no-pgp6", 0, "@"},
{ oGnuPG, "no-pgp7", 0, "@"},
{ oGnuPG, "no-pgp8", 0, "@"},
- { oRFC1991, "rfc1991", 0, N_("emulate the mode described in RFC1991")},
- { oOpenPGP, "openpgp", 0, N_("set all packet, cipher and digest options to OpenPGP behavior")},
- { oPGP2, "pgp2", 0, N_("set all packet, cipher and digest options to PGP 2.x behavior")},
+ { oRFC1991, "rfc1991", 0, "@"},
+ { oRFC2440, "rfc2440", 0, "@"},
+ { oOpenPGP, "openpgp", 0, N_("use strict OpenPGP behavior")},
+ { oPGP2, "pgp2", 0, N_("generate PGP 2.x compatible messages")},
{ oPGP6, "pgp6", 0, "@"},
{ oPGP7, "pgp7", 0, "@"},
{ oPGP8, "pgp8", 0, "@"},
- { oS2KMode, "s2k-mode", 1, N_("|N|use passphrase mode N")},
- { oS2KDigest, "s2k-digest-algo",2,
- N_("|NAME|use message digest algorithm NAME for passphrases")},
- { oS2KCipher, "s2k-cipher-algo",2,
- N_("|NAME|use cipher algorithm NAME for passphrases")},
+ { oS2KMode, "s2k-mode", 1, "@"},
+ { oS2KDigest, "s2k-digest-algo",2, "@"},
+ { oS2KCipher, "s2k-cipher-algo",2, "@"},
{ oSimpleSKChecksum, "simple-sk-checksum", 0, "@"},
- { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")},
- { oDigestAlgo, "digest-algo", 2 , N_("|NAME|use message digest algorithm NAME")},
+ { oCipherAlgo, "cipher-algo", 2 , "@"},
+ { oDigestAlgo, "digest-algo", 2 , "@"},
{ oCertDigestAlgo, "cert-digest-algo", 2 , "@" },
- { oCompressAlgo,"compress-algo",2,N_("|NAME|use compression algorithm NAME")},
- { oThrowKeyid, "throw-keyid", 0, N_("throw keyid field of encrypted packets")},
+ { oCompressAlgo,"compress-algo",2, "@"},
+ { oThrowKeyid, "throw-keyid", 0, "@"},
{ oNoThrowKeyid, "no-throw-keyid", 0, "@" },
{ oShowPhotos, "show-photos", 0, "@" },
{ oNoShowPhotos, "no-show-photos", 0, "@" },
{ oPhotoViewer, "photo-viewer", 2, "@" },
- { oNotation, "notation-data", 2, "@" },
+ { oSetNotation, "set-notation", 2, "@" },
+ { oSetNotation, "notation-data", 2, "@" }, /* Alias */
{ oSigNotation, "sig-notation", 2, "@" },
{ oCertNotation, "cert-notation", 2, "@" },
@@ -556,8 +554,10 @@ static ARGPARSE_OPTS opts[] = {
{ oNoShowPolicyURL, "no-show-policy-url", 0, "@" },
{ oShowNotation, "show-notation", 0, "@" },
{ oNoShowNotation, "no-show-notation", 0, "@" },
+ { oSigKeyserverURL, "sig-keyserver-url", 2, "@" },
{ oComment, "comment", 2, "@" },
{ oDefaultComment, "default-comment", 0, "@" },
+ { oNoComments, "no-comments", 0, "@" },
{ oEmitVersion, "emit-version", 0, "@"},
{ oNoEmitVersion, "no-emit-version", 0, "@"},
{ oNoEmitVersion, "no-version", 0, "@"}, /* alias */
@@ -625,6 +625,7 @@ static ARGPARSE_OPTS opts[] = {
{ oMangleDosFilenames, "mangle-dos-filenames", 0, "@" },
{ oNoMangleDosFilenames, "no-mangle-dos-filenames", 0, "@" },
{ oEnableProgressFilter, "enable-progress-filter", 0, "@" },
+ { oMultifile, "multifile", 0, "@" },
{0} };
@@ -641,6 +642,7 @@ static void set_cmd( enum cmd_and_opt_values *ret_cmd,
static void print_mds( const char *fname, int algo );
static void add_notation_data( const char *string, int which );
static void add_policy_url( const char *string, int which );
+static void add_keyserver_url( const char *string, int which );
static void emergency_cleanup (void);
#ifdef __riscos__
@@ -1158,6 +1160,7 @@ main( int argc, char **argv )
char *pers_digest_list = NULL;
char *pers_compress_list = NULL;
int eyes_only=0;
+ int multifile=0;
int pwfd = -1;
int with_fpr = 0; /* make an option out of --fingerprint */
int any_explicit_recipient = 0;
@@ -1222,12 +1225,13 @@ main( int argc, char **argv )
opt.keyserver_options.include_subkeys=1;
opt.keyserver_options.include_revoked=1;
opt.keyserver_options.try_dns_srv=1;
- opt.verify_options=VERIFY_SHOW_POLICY|VERIFY_SHOW_NOTATION;
+ opt.verify_options=
+ VERIFY_SHOW_POLICY|VERIFY_SHOW_NOTATION|VERIFY_SHOW_KEYSERVER;
opt.trust_model=TM_AUTO;
opt.mangle_dos_filenames = 1;
opt.use_agent = 1;
-#if defined (__MINGW32__)
+#if defined (_WIN32)
set_homedir ( read_w32_registry_string( NULL,
"Software\\GNU\\GnuPG", "HomeDir" ));
#else
@@ -1389,11 +1393,15 @@ main( int argc, char **argv )
case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
case aSym: set_cmd( &cmd, aSym); break;
+ case aDecryptFiles: multifile=1; /* fall through */
case aDecrypt: set_cmd( &cmd, aDecrypt); break;
- case aDecryptFiles: set_cmd( &cmd, aDecryptFiles); break;
+ case aEncrFiles: multifile=1; /* fall through */
case aEncr: set_cmd( &cmd, aEncr); break;
- case aEncrFiles: set_cmd( &cmd, aEncrFiles ); break;
+
+ case aVerifyFiles: multifile=1; /* fall through */
+ case aVerify: set_cmd( &cmd, aVerify); break;
+
case aSign: set_cmd( &cmd, aSign ); break;
case aKeygen: set_cmd( &cmd, aKeygen); greeting=1; break;
case aSignKey: set_cmd( &cmd, aSignKey); break;
@@ -1405,8 +1413,7 @@ main( int argc, char **argv )
case aClearsign: set_cmd( &cmd, aClearsign); break;
case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
case aDesigRevoke: set_cmd( &cmd, aDesigRevoke); break;
- case aVerify: set_cmd( &cmd, aVerify); break;
- case aVerifyFiles: set_cmd( &cmd, aVerifyFiles); break;
+
case aPrimegen: set_cmd( &cmd, aPrimegen); break;
case aGenRandom: set_cmd( &cmd, aGenRandom); break;
case aPrintMD: set_cmd( &cmd, aPrintMD); break;
@@ -1564,7 +1571,7 @@ main( int argc, char **argv )
break;
case oLoadExtension:
#ifndef __riscos__
-#if defined(USE_DYNAMIC_LINKING) || defined(__MINGW32__)
+#if defined(USE_DYNAMIC_LINKING) || defined(_WIN32)
if(check_permissions(pargs.r.ret_str,2))
log_info(_("cipher extension \"%s\" not loaded due to "
"unsafe permissions\n"),pargs.r.ret_str);
@@ -1579,14 +1586,13 @@ main( int argc, char **argv )
case oRFC1991:
opt.compliance = CO_RFC1991;
opt.force_v4_certs = 0;
- opt.disable_mdc = 1;
opt.escape_from = 1;
break;
+ case oRFC2440:
case oOpenPGP:
/* TODO: When 2440bis becomes a RFC, these may need
changing. */
opt.compliance = CO_RFC2440;
- opt.disable_mdc = 1;
opt.allow_non_selfsigned_uid = 1;
opt.allow_freeform_uid = 1;
opt.pgp2_workarounds = 0;
@@ -1627,9 +1633,19 @@ main( int argc, char **argv )
opt.list_options&=~LIST_SHOW_POLICY;
opt.verify_options&=~VERIFY_SHOW_POLICY;
break;
+ case oSigKeyserverURL: add_keyserver_url(pargs.r.ret_str,0); break;
case oUseEmbeddedFilename: opt.use_embedded_filename = 1; break;
- case oComment: opt.comment_string = pargs.r.ret_str; break;
- case oDefaultComment: opt.comment_string = NULL; break;
+
+ case oComment: add_to_strlist(&opt.comments,pargs.r.ret_str); break;
+ case oDefaultComment:
+ deprecated_warning(configname,configlineno,
+ "--default-comment","--no-comments","");
+ /* fall through */
+ case oNoComments:
+ free_strlist(opt.comments);
+ opt.comments=NULL;
+ break;
+
case oThrowKeyid: opt.throw_keyid = 1; break;
case oNoThrowKeyid: opt.throw_keyid = 0; break;
case oShowPhotos:
@@ -1686,6 +1702,7 @@ main( int argc, char **argv )
case oCompress: opt.compress = pargs.r.ret_int; break;
case oPasswdFD:
pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
+ opt.use_agent = 0;
break;
#ifdef __riscos__
case oPasswdFile:
@@ -1784,9 +1801,11 @@ main( int argc, char **argv )
{"show-photos",LIST_SHOW_PHOTOS},
{"show-policy-url",LIST_SHOW_POLICY},
{"show-notation",LIST_SHOW_NOTATION},
- {"show-keyring",LIST_SHOW_KEYRING},
+ {"show-keyserver-url",LIST_SHOW_KEYSERVER},
{"show-validity",LIST_SHOW_VALIDITY},
{"show-long-keyid",LIST_SHOW_LONG_KEYID},
+ {"show-keyring",LIST_SHOW_KEYRING},
+ {"show-sig-expire",LIST_SHOW_SIG_EXPIRE},
{NULL,0}
};
@@ -1807,6 +1826,9 @@ main( int argc, char **argv )
{"show-photos",VERIFY_SHOW_PHOTOS},
{"show-policy-url",VERIFY_SHOW_POLICY},
{"show-notation",VERIFY_SHOW_NOTATION},
+ {"show-keyserver-url",VERIFY_SHOW_KEYSERVER},
+ {"show-validity",VERIFY_SHOW_VALIDITY},
+ {"show-long-keyid",VERIFY_SHOW_LONG_KEYID},
{NULL,0}
};
@@ -1827,7 +1849,7 @@ main( int argc, char **argv )
else
opt.exec_path_set=1;
break;
- case oNotation:
+ case oSetNotation:
add_notation_data( pargs.r.ret_str, 0 );
add_notation_data( pargs.r.ret_str, 1 );
break;
@@ -1931,6 +1953,7 @@ main( int argc, char **argv )
case oNoMangleDosFilenames: opt.mangle_dos_filenames = 0; break;
case oEnableProgressFilter: opt.enable_progress_filter = 1; break;
+ case oMultifile: multifile=1; break;
default : pargs.err = configfp? 1:2; break;
}
@@ -2053,8 +2076,6 @@ main( int argc, char **argv )
compliance_failure();
else
{
- opt.force_mdc = 0;
- opt.disable_mdc = 1;
opt.force_v4_certs = 0;
opt.sk_comments = 0;
opt.escape_from = 1;
@@ -2073,8 +2094,6 @@ main( int argc, char **argv )
opt.escape_from=1;
opt.force_v3_sigs=1;
opt.ask_sig_expire=0;
- opt.force_mdc=0;
- opt.disable_mdc=1;
}
else if(PGP7)
{
@@ -2170,6 +2189,37 @@ main( int argc, char **argv )
keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP))
log_error(_("invalid personal compress preferences\n"));
+ /* We don't support all possible commands with multifile yet */
+ if(multifile)
+ {
+ char *cmdname;
+
+ switch(cmd)
+ {
+ case aSign:
+ cmdname="--sign";
+ break;
+ case aClearsign:
+ cmdname="--clearsign";
+ break;
+ case aDetachedSign:
+ cmdname="--detach-sign";
+ break;
+ case aSym:
+ cmdname="--symmetric";
+ break;
+ case aStore:
+ cmdname="--store";
+ break;
+ default:
+ cmdname=NULL;
+ break;
+ }
+
+ if(cmdname)
+ log_error(_("%s does not yet work with %s\n"),cmdname,"--multifile");
+ }
+
if( log_get_errorcount(0) )
g10_exit(2);
@@ -2262,8 +2312,7 @@ main( int argc, char **argv )
if( cmd != aDeArmor && cmd != aEnArmor )
{
if (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys
- && cmd != aVerify && cmd != aVerifyFiles
- && cmd != aSym)
+ && cmd != aVerify && cmd != aSym)
{
if (!sec_nrings || default_keyring) /* add default secret rings */
keydb_add_resource ("secring" EXTSEP_S "gpg", 0, 1);
@@ -2335,17 +2384,18 @@ main( int argc, char **argv )
break;
case aEncr: /* encrypt the given file */
- if( argc > 1 )
- wrong_args(_("--encrypt [filename]"));
- if( (rc = encode_crypt(fname,remusr)) )
- log_error("%s: encryption failed: %s\n",
- print_fname_stdin(fname), gpg_strerror (rc) );
+ if(multifile)
+ encode_crypt_files(argc, argv, remusr);
+ else
+ {
+ if( argc > 1 )
+ wrong_args(_("--encrypt [filename]"));
+ if( (rc = encode_crypt(fname,remusr)) )
+ log_error("%s: encryption failed: %s\n",
+ print_fname_stdin(fname), gpg_strerror (rc) );
+ }
break;
- case aEncrFiles: /* encrypt the given files */
- encode_crypt_files(argc, argv, remusr);
- break;
-
case aSign: /* sign the given file */
sl = NULL;
if( detached_sig ) { /* sign all files */
@@ -2397,26 +2447,30 @@ main( int argc, char **argv )
break;
case aVerify:
- if( (rc = verify_signatures( argc, argv ) ))
- log_error("verify signatures failed: %s\n", gpg_strerror (rc) );
- break;
-
- case aVerifyFiles:
- if( (rc = verify_files( argc, argv ) ))
- log_error("verify files failed: %s\n", gpg_strerror (rc) );
+ if(multifile)
+ {
+ if( (rc = verify_files( argc, argv ) ))
+ log_error("verify files failed: %s\n", gpg_strerror (rc) );
+ }
+ else
+ {
+ if( (rc = verify_signatures( argc, argv ) ))
+ log_error("verify signatures failed: %s\n", gpg_strerror (rc) );
+ }
break;
case aDecrypt:
- if( argc > 1 )
- wrong_args(_("--decrypt [filename]"));
- if( (rc = decrypt_message( fname ) ))
- log_error("decrypt_message failed: %s\n", gpg_strerror (rc) );
+ if(multifile)
+ decrypt_messages(argc, argv);
+ else
+ {
+ if( argc > 1 )
+ wrong_args(_("--decrypt [filename]"));
+ if( (rc = decrypt_message( fname ) ))
+ log_error("decrypt_message failed: %s\n", gpg_strerror (rc) );
+ }
break;
- case aDecryptFiles:
- decrypt_messages(argc, argv);
- break;
-
case aSignKey: /* sign the key given as argument */
if( argc != 1 )
wrong_args(_("--sign-key user-id"));
@@ -2900,8 +2954,6 @@ print_hex( MD_HANDLE md, int algo, const char *fname )
if(algo==DIGEST_ALGO_RMD160)
indent+=printf("RMD160 = ");
- else if(algo==DIGEST_ALGO_TIGER)
- indent+=printf(" TIGER = ");
else if(algo>0)
indent+=printf("%6s = ", gcry_md_algo_name (algo));
else
@@ -3018,9 +3070,6 @@ print_mds( const char *fname, int algo )
gcry_md_enable (md, GCRY_MD_MD5 );
gcry_md_enable (md, GCRY_MD_SHA1 );
gcry_md_enable (md, GCRY_MD_RMD160 );
-#ifdef USE_TIGER192
- gcry_md_enable (md, GCRY_MD_TIGER );
-#endif
#ifdef USE_SHA256
gcry_md_enable (md, GCRY_MD_SHA256 );
#endif
@@ -3043,9 +3092,6 @@ print_mds( const char *fname, int algo )
print_hashline( md, GCRY_MD_MD5, fname );
print_hashline( md, GCRY_MD_SHA1, fname );
print_hashline( md, GCRY_MD_RMD160, fname );
-#ifdef USE_TIGER192
- print_hashline( md, GCRY_MD_TIGER, fname );
-#endif
#ifdef USE_SHA256
print_hashline( md, GCRY_MD_SHA256, fname );
#endif
@@ -3062,9 +3108,6 @@ print_mds( const char *fname, int algo )
print_hex( md, GCRY_MD_MD5, fname );
print_hex( md, GCRY_MD_SHA1, fname );
print_hex( md, GCRY_MD_RMD160, fname );
-#ifdef USE_TIGER192
- print_hex( md, GCRY_MD_TIGER, fname );
-#endif
#ifdef USE_SHA256
print_hex( md, GCRY_MD_SHA256, fname );
#endif
@@ -3132,13 +3175,13 @@ add_notation_data( const char *string, int which )
/* we only support printable text - therefore we enforce the use
* of only printable characters (an empty value is valid) */
for( s++; *s ; s++ ) {
- if( iscntrl(*s) ) {
+ if( *s & 0x80 )
+ highbit = 1;
+ else if( iscntrl(*s) ) {
log_error(_("a notation value must not use "
"any control characters\n") );
return;
}
- else if( *s & 0x80 )
- highbit = 1;
}
if( highbit ) /* must use UTF8 encoding */
@@ -3183,3 +3226,39 @@ add_policy_url( const char *string, int which )
if(critical)
sl->flags |= 1;
}
+
+
+static void
+add_keyserver_url( const char *string, int which )
+{
+ int i,critical=0;
+ STRLIST sl;
+
+ if(*string=='!')
+ {
+ string++;
+ critical=1;
+ }
+
+ for(i=0;i<strlen(string);i++)
+ if(string[i]&0x80 || iscntrl(string[i]))
+ break;
+
+ if(i==0 || i<strlen(string))
+ {
+ if(which)
+ BUG();
+ else
+ log_error(_("the given signature preferred"
+ " keyserver URL is invalid\n"));
+ }
+
+ if(which)
+ BUG();
+ else
+ sl=add_to_strlist( &opt.sig_keyserver_url, string );
+
+ if(critical)
+ sl->flags |= 1;
+}
+
diff --git a/g10/getkey.c b/g10/getkey.c
index 7eda9384c..f51b8f2df 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -572,7 +572,7 @@ classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc )
memset (desc, 0, sizeof *desc);
/* skip leading spaces. Fixme: what is with trailing spaces? */
- for(s = name; *s && isspace(*s); s++ )
+ for(s = name; *s && spacep (s); s++ )
;
switch (*s) {
@@ -653,7 +653,7 @@ classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc )
}
/* check if a hexadecimal number is terminated by EOS or blank */
- if (hexlength && s[hexlength] && !isspace(s[hexlength])) {
+ if (hexlength && s[hexlength] && !spacep (s+hexlength)) {
if (hexprefix) /* a "0x" prefix without correct */
return 0; /* termination is an error */
else /* The first chars looked like */
@@ -1593,8 +1593,6 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
else if ( k->pkt->pkttype == PKT_SIGNATURE && uidnode )
{
PKT_signature *sig = k->pkt->pkt.signature;
- u32 dummy;
- int dum2;
if(sig->keyid[0] != kid[0] || sig->keyid[1]!=kid[1])
{
@@ -1610,7 +1608,7 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
ultimate trust flag. */
if(get_pubkey_fast(ultimate_pk,sig->keyid)==0
&& check_key_signature2(keyblock,k,ultimate_pk,
- NULL,&dummy,&dum2)==0
+ NULL, NULL, NULL, NULL)==0
&& get_ownertrust(ultimate_pk)==TRUST_ULTIMATE)
{
free_public_key(ultimate_pk);
diff --git a/g10/gpgv.c b/g10/gpgv.c
index fb96fad5c..596b09fcb 100644
--- a/g10/gpgv.c
+++ b/g10/gpgv.c
@@ -1,5 +1,6 @@
/* gpgv.c - The GnuPG signature verify utility
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ * 2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -155,8 +156,9 @@ main( int argc, char **argv )
opt.trust_model = TM_ALWAYS;
opt.batch = 1;
-#if defined (__MINGW32__)
- opt.homedir = read_w32_registry_string( NULL, "Software\\GNU\\GnuPG", "HomeDir" );
+#if defined (_WIN32)
+ opt.homedir = read_w32_registry_string( NULL, "Software\\GNU\\GnuPG",
+ "HomeDir" );
#else
opt.homedir = getenv("GNUPGHOME");
#endif
@@ -221,6 +223,14 @@ g10_exit( int rc )
}
+
+void
+read_trust_options (byte *trust_model,ulong *created,ulong *nextcheck,
+ byte *marginals,byte *completes,byte *cert_depth)
+{
+}
+
+
/* Stub:
* We have to override the trustcheck from pkclist.c becuase
* this utility assumes that all keys in the keyring are trustworthy
diff --git a/g10/import.c b/g10/import.c
index 84d60a1b3..9c323243a 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -1,5 +1,6 @@
-/* import.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+/* import.c - Import OpenPGP key material
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ * 2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -168,6 +169,8 @@ import_keys_internal( iobuf_t inp, char **fnames, int nnames,
else {
rc = import( inp2, fname, stats, options );
iobuf_close(inp2);
+ /* Must invalidate that ugly cache to actually close it. */
+ iobuf_ioctl (NULL, 2, 0, (char*)fname);
if( rc )
log_error("import from `%s' failed: %s\n", fname,
gpg_strerror (rc) );
@@ -589,7 +592,8 @@ import_one( const char *fname, KBNODE keyblock,
clear_kbnode_flags( keyblock );
- if((options&IMPORT_REPAIR_PKS_SUBKEY_BUG) && fix_pks_corruption(keyblock))
+ if((options&IMPORT_REPAIR_PKS_SUBKEY_BUG) && fix_pks_corruption(keyblock)
+ && opt.verbose)
log_info(_("key %08lX: PKS subkey corruption repaired\n"),
(ulong)keyid[1]);
@@ -611,11 +615,9 @@ import_one( const char *fname, KBNODE keyblock,
}
if( !delete_inv_parts( fname, keyblock, keyid, options ) ) {
- if( !opt.quiet ) {
- log_info( _("key %08lX: no valid user IDs\n"),
- (ulong)keyid[1]);
+ log_error ( _("key %08lX: no valid user IDs\n"), (ulong)keyid[1]);
+ if( !opt.quiet )
log_info(_("this may be caused by a missing self-signature\n"));
- }
stats->no_user_id++;
return 0;
}
@@ -979,8 +981,8 @@ import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats )
pk = xcalloc (1, sizeof *pk );
rc = get_pubkey( pk, keyid );
if( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY ) {
- log_info( _("key %08lX: no public key - "
- "can't apply revocation certificate\n"), (ulong)keyid[1]);
+ log_error ( _("key %08lX: no public key - "
+ "can't apply revocation certificate\n"), (ulong)keyid[1]);
rc = 0;
goto leave;
}
@@ -1030,12 +1032,12 @@ import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats )
if( onode->pkt->pkttype == PKT_USER_ID )
break;
else if( onode->pkt->pkttype == PKT_SIGNATURE
- && onode->pkt->pkt.signature->sig_class == 0x20
- && keyid[0] == onode->pkt->pkt.signature->keyid[0]
- && keyid[1] == onode->pkt->pkt.signature->keyid[1] ) {
- rc = 0;
- goto leave; /* yes, we already know about it */
- }
+ && !cmp_signatures(node->pkt->pkt.signature,
+ onode->pkt->pkt.signature))
+ {
+ rc = 0;
+ goto leave; /* yes, we already know about it */
+ }
}
@@ -1125,17 +1127,20 @@ chk_self_sigs( const char *fname, KBNODE keyblock,
rc = check_key_signature( keyblock, n, NULL);
if( rc )
{
- char *p=utf8_to_native(unode->pkt->pkt.user_id->name,
- strlen(unode->pkt->pkt.user_id->name),0);
- log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
- _("key %08lX: unsupported public key "
- "algorithm on user id \"%s\"\n"):
- _("key %08lX: invalid self-signature "
- "on user id \"%s\"\n"),
- (ulong)keyid[1],p);
- xfree (p);
- }
- else
+ if (opt.verbose)
+ {
+ char *p=utf8_to_native(unode->pkt->pkt.user_id->name,
+ strlen(unode->pkt->pkt.user_id->name),0);
+ log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
+ _("key %08lX: unsupported public key "
+ "algorithm on user id \"%s\"\n"):
+ _("key %08lX: invalid self-signature "
+ "on user id \"%s\"\n"),
+ (ulong)keyid[1],p);
+ xfree (p);
+ }
+ }
+ else
unode->flag |= 1; /* mark that signature checked */
}
}
@@ -1144,39 +1149,49 @@ chk_self_sigs( const char *fname, KBNODE keyblock,
like the rest of gpg. If the standard gets
revocation targets, this may need to be revised. */
- if( !knode ) {
- log_info( _("key %08lX: no subkey for subkey "
- "binding signature\n"),(ulong)keyid[1]);
- n->flag |= 4; /* delete this */
- }
- else {
- rc = check_key_signature( keyblock, n, NULL);
- if( rc ) {
- log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
- _("key %08lX: unsupported public key algorithm\n"):
+ if( !knode )
+ {
+ if (opt.verbose)
+ log_info( _("key %08lX: no subkey for subkey "
+ "binding signature\n"),(ulong)keyid[1]);
+ n->flag |= 4; /* delete this */
+ }
+ else
+ {
+ rc = check_key_signature( keyblock, n, NULL);
+ if( rc )
+ {
+ if (opt.verbose)
+ log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
+ _("key %08lX: unsupported public key algorithm\n"):
_("key %08lX: invalid subkey binding\n"),
- (ulong)keyid[1]);
- n->flag|=4;
- }
- else {
- /* It's valid, so is it newer? */
- if(sig->timestamp>=bsdate) {
- knode->flag |= 1; /* the subkey is valid */
- if(bsnode) {
- bsnode->flag|=4; /* Delete the last binding
- sig since this one is
- newer */
- log_info(_("key %08lX: removed multiple subkey "
- "binding\n"),(ulong)keyid[1]);
- }
-
- bsnode=n;
- bsdate=sig->timestamp;
- }
- else
- n->flag|=4; /* older */
- }
- }
+ (ulong)keyid[1]);
+ n->flag|=4;
+ }
+ else
+ {
+ /* It's valid, so is it newer? */
+ if(sig->timestamp>=bsdate)
+ {
+ knode->flag |= 1; /* the subkey is valid */
+ if(bsnode)
+ {
+ bsnode->flag|=4; /* Delete the last binding
+ sig since this one is
+ newer */
+ if (opt.verbose)
+ log_info(_("key %08lX: removed multiple "
+ "subkey binding\n"),
+ (ulong)keyid[1]);
+ }
+
+ bsnode=n;
+ bsdate=sig->timestamp;
+ }
+ else
+ n->flag|=4; /* older */
+ }
+ }
}
else if( sig->sig_class == 0x28 ) {
/* We don't actually mark the subkey as revoked right
@@ -1186,14 +1201,16 @@ chk_self_sigs( const char *fname, KBNODE keyblock,
See the comment in getkey.c:merge_selfsigs_subkey for
more */
if( !knode ) {
+ if (opt.verbose)
log_info( _("key %08lX: no subkey for subkey "
"revocation signature\n"),(ulong)keyid[1]);
- n->flag |= 4; /* delete this */
+ n->flag |= 4; /* delete this */
}
else {
rc = check_key_signature( keyblock, n, NULL);
if( rc ) {
- log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
+ if (opt.verbose)
+ log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
_("key %08lX: unsupported public key algorithm\n"):
_("key %08lX: invalid subkey revocation\n"),
(ulong)keyid[1]);
@@ -1206,8 +1223,10 @@ chk_self_sigs( const char *fname, KBNODE keyblock,
rsnode->flag|=4; /* Delete the last revocation
sig since this one is
newer */
- log_info(_("key %08lX: removed multiple subkey "
- "revocation signatures\n"),(ulong)keyid[1]);
+ if (opt.verbose)
+ log_info(_("key %08lX: removed multiple subkey "
+ "revocation signatures\n"),
+ (ulong)keyid[1]);
}
rsnode=n;
@@ -1291,23 +1310,25 @@ delete_inv_parts( const char *fname, KBNODE keyblock,
!node->pkt->pkt.signature->flags.exportable &&
!(options&IMPORT_ALLOW_LOCAL_SIGS) &&
seckey_available( node->pkt->pkt.signature->keyid ) ) {
- /* here we violate the rfc a bit by still allowing
+ /* Here we violate the rfc a bit by still allowing
* to import non-exportable signature when we have the
* the secret key used to create this signature - it
- * seems that this makes sense */
+ * seems that this makes sense. */
+ if (opt.verbose)
log_info( _("key %08lX: non exportable signature "
"(class %02x) - skipped\n"),
- (ulong)keyid[1],
+ (ulong)keyid[1],
node->pkt->pkt.signature->sig_class );
- delete_kbnode( node );
+ delete_kbnode( node );
}
else if( node->pkt->pkttype == PKT_SIGNATURE
&& node->pkt->pkt.signature->sig_class == 0x20 ) {
if( uid_seen ) {
+ if (opt.verbose)
log_error( _("key %08lX: revocation certificate "
- "at wrong place - skipped\n"),
+ "at wrong place - skipped\n"),
(ulong)keyid[1]);
- delete_kbnode( node );
+ delete_kbnode( node );
}
else {
/* If the revocation cert is from a different key than
@@ -1321,9 +1342,10 @@ delete_inv_parts( const char *fname, KBNODE keyblock,
int rc = check_key_signature( keyblock, node, NULL);
if( rc )
{
- log_error( _("key %08lX: invalid revocation "
- "certificate: %s - skipped\n"),
- (ulong)keyid[1], gpg_strerror (rc));
+ if (opt.verbose)
+ log_info ( _("key %08lX: invalid revocation "
+ "certificate: %s - skipped\n"),
+ (ulong)keyid[1], gpg_strerror (rc));
delete_kbnode( node );
}
}
@@ -1333,17 +1355,19 @@ delete_inv_parts( const char *fname, KBNODE keyblock,
(node->pkt->pkt.signature->sig_class == 0x18 ||
node->pkt->pkt.signature->sig_class == 0x28) &&
!subkey_seen ) {
- log_error( _("key %08lX: subkey signature "
+ if (opt.verbose)
+ log_info ( _("key %08lX: subkey signature "
"in wrong place - skipped\n"),
(ulong)keyid[1]);
- delete_kbnode( node );
+ delete_kbnode( node );
}
else if( node->pkt->pkttype == PKT_SIGNATURE
&& !IS_CERT(node->pkt->pkt.signature))
{
- log_error(_("key %08lX: unexpected signature class (0x%02X) -"
- " skipped\n"),(ulong)keyid[1],
- node->pkt->pkt.signature->sig_class);
+ if (opt.verbose)
+ log_info (_("key %08lX: unexpected signature class (0x%02X) -"
+ " skipped\n"),(ulong)keyid[1],
+ node->pkt->pkt.signature->sig_class);
delete_kbnode(node);
}
else if( (node->flag & 4) ) /* marked for deletion */
@@ -1439,8 +1463,9 @@ collapse_uids( KBNODE *keyblock )
kid1 = keyid_from_sk( n->pkt->pkt.secret_key, NULL );
else
kid1 = 0;
- log_info(_("key %08lX: duplicated user ID detected - merged\n"),
- (ulong)kid1);
+ if (!opt.quiet)
+ log_info (_("key %08lX: duplicated user ID detected - merged\n"),
+ (ulong)kid1);
return 1;
}
@@ -1557,23 +1582,27 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
break;
else if( onode->pkt->pkttype == PKT_SIGNATURE
&& onode->pkt->pkt.signature->sig_class == 0x20
- && node->pkt->pkt.signature->keyid[0]
- == onode->pkt->pkt.signature->keyid[0]
- && node->pkt->pkt.signature->keyid[1]
- == onode->pkt->pkt.signature->keyid[1] ) {
- found = 1;
- break;
- }
+ && !cmp_signatures(onode->pkt->pkt.signature,
+ node->pkt->pkt.signature))
+ {
+ found = 1;
+ break;
+ }
}
if( !found ) {
- char *p=get_user_id_printable (keyid);
KBNODE n2 = clone_kbnode(node);
insert_kbnode( keyblock_orig, n2, 0 );
n2->flag |= 1;
++*n_sigs;
- log_info(_("key %08lX: \"%s\" revocation certificate added\n"),
- (ulong)keyid[1],p);
- xfree (p);
+
+ if (!opt.quiet)
+ {
+ char *p=get_user_id_printable (keyid);
+ log_info(_("key %08lX: \"%s\" "
+ "revocation certificate added\n"),
+ (ulong)keyid[1],p);
+ xfree (p);
+ }
}
}
}
@@ -1602,8 +1631,9 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
insert_kbnode( keyblock_orig, n2, 0 );
n2->flag |= 1;
++*n_sigs;
- log_info( _("key %08lX: direct key signature added\n"),
- (ulong)keyid[1]);
+ if (!opt.quiet)
+ log_info( _("key %08lX: direct key signature added\n"),
+ (ulong)keyid[1]);
}
}
}
@@ -1771,20 +1801,12 @@ merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
|| n->pkt->pkt.signature->sig_class == 0x28 )
continue; /* skip signatures which are only valid on subkeys */
found = 0;
- for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next){
- if( n2->pkt->pkttype == PKT_SIGNATURE
- && n->pkt->pkt.signature->keyid[0]
- == n2->pkt->pkt.signature->keyid[0]
- && n->pkt->pkt.signature->keyid[1]
- == n2->pkt->pkt.signature->keyid[1]
- && n->pkt->pkt.signature->timestamp
- <= n2->pkt->pkt.signature->timestamp
- && n->pkt->pkt.signature->sig_class
- == n2->pkt->pkt.signature->sig_class ) {
- found++;
- break;
- }
- }
+ for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next)
+ if(!cmp_signatures(n->pkt->pkt.signature,n2->pkt->pkt.signature))
+ {
+ found++;
+ break;
+ }
if( !found ) {
/* This signature is new or newer, append N to DST.
* We add a clone to the original keyblock, because this
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 85f2b92e9..bd41772fd 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -56,6 +56,7 @@ static int menu_addrevoker( KBNODE pub_keyblock,
static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock );
static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock );
+static int menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock );
static int menu_select_uid( KBNODE keyblock, int idx );
static int menu_select_key( KBNODE keyblock, int idx );
static int count_uids( KBNODE keyblock );
@@ -135,7 +136,7 @@ print_and_check_one_sig( KBNODE keyblock, KBNODE node,
break;
}
if( sigrc != '?' || print_without_key ) {
- tty_printf("%s%c%c %c%c%c%c%c%c %08lX %s ",
+ tty_printf("%s%c%c %c%c%c%c%c%c ",
is_rev? "rev":"sig",sigrc,
(sig->sig_class-0x10>0 &&
sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ',
@@ -145,8 +146,15 @@ print_and_check_one_sig( KBNODE keyblock, KBNODE node,
sig->flags.notation?'N':' ',
sig->flags.expired?'X':' ',
(sig->trust_depth>9)?'T':
- (sig->trust_depth>0)?'0'+sig->trust_depth:' ',
- (ulong)sig->keyid[1], datestr_from_sig(sig));
+ (sig->trust_depth>0)?'0'+sig->trust_depth:' ');
+ if(opt.list_options&LIST_SHOW_LONG_KEYID)
+ tty_printf("%08lX%08lX",(ulong)sig->keyid[0],(ulong)sig->keyid[1]);
+ else
+ tty_printf("%08lX",(ulong)sig->keyid[1]);
+ tty_printf(" %s", datestr_from_sig(sig));
+ if(opt.list_options&LIST_SHOW_SIG_EXPIRE)
+ tty_printf(" %s",expirestr_from_sig(sig));
+ tty_printf(" ");
if( sigrc == '%' )
tty_printf("[%s] ", gpg_strerror (rc) );
else if( sigrc == '?' )
@@ -168,6 +176,9 @@ print_and_check_one_sig( KBNODE keyblock, KBNODE node,
if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATION))
show_notation(sig,3,0);
+
+ if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER))
+ show_keyserver_url(sig,3,0);
}
return (sigrc == '!');
@@ -500,12 +511,47 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified,
tty_printf(_(" Unable to sign.\n"));
}
}
- else if(!uidnode->pkt->pkt.user_id->created)
+ else if(uidnode->pkt->pkt.user_id->is_expired)
{
- tty_printf(_("WARNING: user ID \"%s\" is not "
- "self-signed.\n"),user);
+ tty_printf(_("User ID \"%s\" is expired."),user);
+
+ if(opt.expert)
+ {
+ tty_printf("\n");
+ /* No, so remove the mark and continue */
+ if(!cpr_get_answer_is_yes("sign_uid.expire_okay",
+ _("Are you sure you "
+ "still want to sign "
+ "it? (y/N) ")))
+ uidnode->flag &= ~NODFLG_MARK_A;
+ }
+ else
+ {
+ uidnode->flag &= ~NODFLG_MARK_A;
+ tty_printf(_(" Unable to sign.\n"));
+ }
}
+ else if(!uidnode->pkt->pkt.user_id->created && !selfsig)
+ {
+ tty_printf(_("User ID \"%s\" is not self-signed."),
+ user);
+ if(opt.expert)
+ {
+ tty_printf("\n");
+ /* No, so remove the mark and continue */
+ if(!cpr_get_answer_is_yes("sign_uid.nosig_okay",
+ _("Are you sure you "
+ "still want to sign "
+ "it? (y/N) ")))
+ uidnode->flag &= ~NODFLG_MARK_A;
+ }
+ else
+ {
+ uidnode->flag &= ~NODFLG_MARK_A;
+ tty_printf(_(" Unable to sign.\n"));
+ }
+ }
xfree (user);
}
}
@@ -739,7 +785,8 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified,
while(class==0)
{
- answer = cpr_get("sign_uid.class",_("Your selection? "));
+ answer = cpr_get("sign_uid.class",_("Your selection? "
+ "(enter '?' for more information): "));
if(answer[0]=='\0')
class=0x10+opt.def_cert_check_level; /* Default */
@@ -970,8 +1017,10 @@ change_passphrase( KBNODE keyblock )
" this is probably a *bad* idea!\n\n"));
if( cpr_get_answer_is_yes("change_passwd.empty.okay",
_("Do you really want to do this? ")))
+ {
changed++;
- break;
+ break;
+ }
}
else { /* okay */
rc = 0;
@@ -1067,7 +1116,8 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY, cmdADDREVOKER,
cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, cmdEXPIRE,
cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF, cmdUPDPREF,
- cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST, cmdNOP };
+ cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
+ cmdNOP };
static struct { const char *name;
enum cmdids id;
int need_sk;
@@ -1108,10 +1158,14 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
{ N_("toggle") , cmdTOGGLE , 1,0,0, N_("toggle between secret "
"and public key listing") },
{ N_("t" ) , cmdTOGGLE , 1,0,0, NULL },
- { N_("pref") , cmdPREF , 0,1,0, N_("list preferences (expert)") },
- { N_("showpref"), cmdSHOWPREF , 0,1,0, N_("list preferences (verbose)") },
+ { N_("pref") , cmdPREF , 0,1,0,
+ N_("list preferences (expert)")},
+ { N_("showpref"), cmdSHOWPREF , 0,1,0,
+ N_("list preferences (verbose)")},
{ N_("setpref") , cmdSETPREF , 1,1,0, N_("set preference list") },
{ N_("updpref") , cmdUPDPREF , 1,1,0, N_("updated preferences") },
+ { N_("keyserver"),cmdPREFKS , 1,1,0,
+ N_("set preferred keyserver URL")},
{ N_("passwd") , cmdPASSWD , 1,1,0, N_("change the passphrase") },
{ N_("trust") , cmdTRUST , 0,1,0, N_("change the ownertrust") },
{ N_("revsig") , cmdREVSIG , 0,1,0, N_("revoke signatures") },
@@ -1238,7 +1292,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
cmd = cmdLIST;
else if( *answer == CONTROL_D )
cmd = cmdQUIT;
- else if( isdigit( *answer ) ) {
+ else if( digitp( answer ) ) {
cmd = cmdSELUID;
arg_number = atoi(answer);
}
@@ -1565,6 +1619,14 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
}
break;
+ case cmdPREFKS:
+ if( menu_set_keyserver_url ( keyblock, sec_keyblock ) ) {
+ merge_keys_and_selfsig( keyblock );
+ modified = 1;
+ redisplay = 1;
+ }
+ break;
+
case cmdNOP:
break;
@@ -1950,6 +2012,7 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
int i, rc;
int do_warn = 0;
byte pk_version=0;
+ PKT_public_key *primary=NULL;
if (opt.with_colons)
{
@@ -1979,7 +2042,8 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
do_warn = 1;
}
- pk_version=pk->version;
+ pk_version = pk->version;
+ primary = pk;
}
if(with_revoker) {
@@ -2006,19 +2070,27 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
}
}
- tty_printf(_("%s%c %4u%c/%08lX created: %s expires: %s"),
- node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
- (node->flag & NODFLG_SELKEY)? '*':' ',
- nbits_from_pk( pk ),
- pubkey_letter( pk->pubkey_algo ),
- (ulong)keyid_from_pk(pk,NULL),
- datestr_from_pk(pk),
- expirestr_from_pk(pk) );
+ keyid_from_pk(pk,NULL);
+ tty_printf("%s%c %4u%c/",
+ node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
+ (node->flag & NODFLG_SELKEY)? '*':' ',
+ nbits_from_pk( pk ),
+ pubkey_letter( pk->pubkey_algo ));
+
+ if(opt.list_options&LIST_SHOW_LONG_KEYID)
+ tty_printf("%08lX",(ulong)pk->keyid[0]);
+
+ tty_printf("%08lX ",(ulong)pk->keyid[1]);
+ tty_printf(_("created: %s expires: %s"),
+ datestr_from_pk(pk),
+ expirestr_from_pk(pk) );
tty_printf("\n");
if( node->pkt->pkttype == PKT_PUBLIC_KEY )
{
tty_printf(" ");
+ if(opt.list_options&LIST_SHOW_LONG_KEYID)
+ tty_printf(" ");
tty_printf(_("trust: %-13s"), otrust);
tty_printf(_("validity: %s"), trust );
tty_printf("\n");
@@ -2072,6 +2144,9 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
PKT_user_id *uid = node->pkt->pkt.user_id;
++i;
if( !only_marked || (only_marked && (node->flag & NODFLG_MARK_A))){
+ if(opt.list_options&LIST_SHOW_VALIDITY && primary)
+ tty_printf("[%8.8s] ",
+ trust_value_to_string(get_validity(primary,uid)));
if( only_marked )
tty_printf(" ");
else if( node->flag & NODFLG_SELUID )
@@ -2599,16 +2674,23 @@ menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
answer=cpr_get_utf8("keyedit.add_revoker",
_("Enter the user ID of the designated revoker: "));
if(answer[0]=='\0' || answer[0]=='\004')
- goto fail;
-
+ {
+ xfree(answer); answer = NULL;
+ goto fail;
+ }
+
rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
if(rc)
{
log_error (_("key `%s' not found: %s\n"),answer,gpg_strerror (rc));
+ xfree (answer); answer = NULL;
continue;
}
+ xfree (answer); answer = NULL;
+
+
fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
if(fprlen!=20)
{
@@ -2788,7 +2870,8 @@ menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
&& ( mainkey || sub_pk ) ) {
PKT_signature *sig = node->pkt->pkt.signature;
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
- && ( (mainkey && uid && (sig->sig_class&~3) == 0x10)
+ && ( (mainkey && uid
+ && uid->created && (sig->sig_class&~3) == 0x10)
|| (!mainkey && sig->sig_class == 0x18) ) ) {
/* this is a selfsignature which is to be replaced */
PKT_signature *newsig;
@@ -3084,6 +3167,101 @@ menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
}
+
+static int
+menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock )
+{
+ PKT_secret_key *sk; /* copy of the main sk */
+ PKT_public_key *main_pk;
+ PKT_user_id *uid;
+ KBNODE node;
+ u32 keyid[2];
+ int selected, select_all;
+ int modified = 0;
+ char *answer;
+
+ no_primary_warning(pub_keyblock,1);
+
+ answer=cpr_get_utf8("keyedit.add_keyserver",
+ _("Enter your preferred keyserver URL: "));
+ if(answer[0]=='\0' || answer[0]=='\004')
+ {
+ xfree(answer);
+ return 0;
+ }
+
+ select_all = !count_selected_uids (pub_keyblock);
+
+ node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
+ sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
+
+ /* Now we can actually change the self signature(s) */
+ main_pk = NULL;
+ uid = NULL;
+ selected = 0;
+ for ( node=pub_keyblock; node; node = node->next ) {
+ if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+ break; /* ready */
+
+ if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
+ main_pk = node->pkt->pkt.public_key;
+ keyid_from_pk( main_pk, keyid );
+ }
+ else if ( node->pkt->pkttype == PKT_USER_ID ) {
+ uid = node->pkt->pkt.user_id;
+ selected = select_all || (node->flag & NODFLG_SELUID);
+ }
+ else if ( main_pk && uid && selected
+ && node->pkt->pkttype == PKT_SIGNATURE ) {
+ PKT_signature *sig = node->pkt->pkt.signature;
+ if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
+ && (uid && (sig->sig_class&~3) == 0x10) ) {
+ if( sig->version < 4 ) {
+ char *user=utf8_to_native(uid->name,strlen(uid->name),0);
+
+ log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
+ user);
+ xfree(user);
+ }
+ else {
+ /* This is a selfsignature which is to be replaced
+ * We have to ignore v3 signatures because they are
+ * not able to carry the preferences */
+ PKT_signature *newsig;
+ PACKET *newpkt;
+ int rc;
+
+ rc = update_keysig_packet (&newsig, sig,
+ main_pk, uid, NULL,
+ sk,
+ keygen_add_keyserver_url,
+ answer );
+ if( rc ) {
+ log_error ("update_keysig_packet failed: %s\n",
+ gpg_strerror (rc));
+ xfree(answer);
+ free_secret_key( sk );
+ return 0;
+ }
+ /* replace the packet */
+ newpkt = xcalloc (1, sizeof *newpkt );
+ newpkt->pkttype = PKT_SIGNATURE;
+ newpkt->pkt.signature = newsig;
+ free_packet( node->pkt );
+ xfree (node->pkt);
+ node->pkt = newpkt;
+ modified = 1;
+ }
+ }
+ }
+ }
+
+ xfree(answer);
+ free_secret_key( sk );
+ return modified;
+}
+
+
/****************
* Select one user id or remove all selection if index is 0.
* Returns: True if the selection changed;
diff --git a/g10/keygen.c b/g10/keygen.c
index bc98cee17..38e9115b3 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -1,6 +1,6 @@
/* keygen.c - generate a key pair
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
- * Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ * 2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -147,7 +147,12 @@ do_add_key_flags (PKT_signature *sig, unsigned int use)
buf[0] = 0;
if (use & PUBKEY_USAGE_SIG)
- buf[0] |= 0x01 | 0x02;
+ {
+ if(sig->sig_class==0x18)
+ buf[0] |= 0x02; /* Don't set the certify flag for subkeys */
+ else
+ buf[0] |= 0x01 | 0x02;
+ }
if (use & PUBKEY_USAGE_ENC)
buf[0] |= 0x04 | 0x08;
if (use & PUBKEY_USAGE_AUTH)
@@ -587,6 +592,18 @@ keygen_add_std_prefs( PKT_signature *sig, void *opaque )
return 0;
}
+
+int
+keygen_add_keyserver_url(PKT_signature *sig, void *opaque)
+{
+ const char *url=opaque;
+
+ build_sig_subpkt(sig,SIGSUBPKT_PREF_KS,url,strlen(url));
+
+ return 0;
+}
+
+
int
keygen_add_revkey(PKT_signature *sig, void *opaque)
{
@@ -1138,10 +1155,10 @@ gen_rsa(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
static int
check_valid_days( const char *s )
{
- if( !isdigit(*s) )
+ if( !digitp(s) )
return 0;
for( s++; *s; s++)
- if( !isdigit(*s) )
+ if( !digitp(s) )
break;
if( !*s )
return 1;
@@ -1219,15 +1236,18 @@ ask_algo (int addmode, unsigned int *r_usage)
_("Create anyway? ")))
{
algo = PUBKEY_ALGO_ELGAMAL;
+ *r_usage = PUBKEY_USAGE_ENC | PUBKEY_USAGE_SIG;
break;
}
}
else if( algo == 3 && addmode ) {
algo = PUBKEY_ALGO_ELGAMAL_E;
+ *r_usage = PUBKEY_USAGE_ENC;
break;
}
else if( algo == 2 ) {
algo = PUBKEY_ALGO_DSA;
+ *r_usage = PUBKEY_USAGE_SIG;
break;
}
else
@@ -1489,7 +1509,7 @@ ask_user_id( int mode )
if( strpbrk( aname, "<>" ) )
tty_printf(_("Invalid character in name\n"));
- else if( isdigit(*aname) )
+ else if( digitp(aname) )
tty_printf(_("Name may not start with a digit\n"));
else if( strlen(aname) < 5 )
tty_printf(_("Name must be at least 5 characters long\n"));
@@ -1503,7 +1523,7 @@ ask_user_id( int mode )
amail = cpr_get("keygen.email",_("Email address: "));
trim_spaces(amail);
cpr_kill_prompt();
- if( !*amail )
+ if( !*amail || opt.allow_freeform_uid )
break; /* no email address is okay */
else if( has_invalid_email_chars(amail)
|| count_chr(amail,'@') != 1
@@ -1551,7 +1571,8 @@ ask_user_id( int mode )
tty_printf(_("You selected this USER-ID:\n \"%s\"\n\n"), uid);
/* fixme: add a warning if this user-id already exists */
- if( !*amail && (strchr( aname, '@' ) || strchr( acomment, '@'))) {
+ if( !*amail && !opt.allow_freeform_uid
+ && (strchr( aname, '@' ) || strchr( acomment, '@'))) {
fail = 1;
tty_printf(_("Please don't put the email address "
"into the real name or the comment\n") );
@@ -1608,7 +1629,7 @@ ask_user_id( int mode )
}
xfree (answer);
if( !amail && !acomment && !amail )
- break;
+ break;
xfree (uid); uid = NULL;
}
if( uid ) {
@@ -1754,7 +1775,7 @@ 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( isdigit( *r->u.value ) )
+ if( digitp( r->u.value ) )
i = atoi( r->u.value );
else
i = openpgp_pk_map_name ( r->u.value );
@@ -2295,6 +2316,11 @@ generate_keypair( const char *fname )
strcpy( r->u.value, "1024" );
r->next = para;
para = r;
+ r = xcalloc (1, sizeof *r + 20 );
+ r->key = pKEYUSAGE;
+ strcpy( r->u.value, "sign" );
+ r->next = para;
+ para = r;
algo = PUBKEY_ALGO_ELGAMAL_E;
r = xcalloc (1, sizeof *r + 20 );
@@ -2302,6 +2328,12 @@ generate_keypair( const char *fname )
sprintf( r->u.value, "%d", algo );
r->next = para;
para = r;
+ r = xcalloc (1, sizeof *r + 20 );
+ r->key = pSUBKEYUSAGE;
+ strcpy( r->u.value, "encrypt" );
+ r->next = para;
+ r->next = para;
+ para = r;
}
else
{
diff --git a/g10/keylist.c b/g10/keylist.c
index 081782785..f4344f204 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -1,6 +1,6 @@
-/* keylist.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
- * Free Software Foundation, Inc.
+/* keylist.c - List all or selected keys
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ * 2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -58,10 +58,46 @@ static FILE *attrib_fp=NULL;
void
public_key_list( STRLIST list )
{
- if( !list )
- list_all(0);
- else
- list_one( list, 0 );
+ if(opt.with_colons)
+ {
+ byte trust_model,marginals,completes,cert_depth;
+ ulong created,nextcheck;
+
+ read_trust_options(&trust_model,&created,&nextcheck,
+ &marginals,&completes,&cert_depth);
+
+ printf("tru:");
+
+ if(nextcheck && nextcheck <= make_timestamp())
+ printf("o");
+ if(trust_model!=opt.trust_model)
+ printf("t");
+ if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
+ {
+ if(marginals!=opt.marginals_needed)
+ printf("m");
+ if(completes!=opt.completes_needed)
+ printf("c");
+ if(cert_depth!=opt.max_cert_depth)
+ printf("d");
+ }
+
+ printf(":%d:%lu:%lu",trust_model,created,nextcheck);
+
+ /* Only show marginals, completes, and cert_depth in the classic
+ or PGP trust models since they are not meaningful
+ otherwise. */
+
+ if(trust_model==TM_PGP || trust_model==TM_CLASSIC)
+ printf(":%d:%d:%d",marginals,completes,cert_depth);
+
+ printf("\n");
+ }
+
+ if( !list )
+ list_all(0);
+ else
+ list_one( list, 0 );
}
void
@@ -152,7 +188,6 @@ show_policy_url(PKT_signature *sig,int indent,int mode)
for(i=0;i<indent;i++)
putchar(' ');
- /* This isn't UTF8 as it is a URL(?) */
if(crit)
str=_("Critical signature policy: ");
else
@@ -161,7 +196,7 @@ show_policy_url(PKT_signature *sig,int indent,int mode)
log_info("%s",str);
else
printf("%s",str);
- print_string(fp,p,len,0);
+ print_utf8_string(fp,p,len);
fprintf(fp,"\n");
}
@@ -170,6 +205,48 @@ show_policy_url(PKT_signature *sig,int indent,int mode)
}
}
+
+/*
+ mode=0 for stdout.
+ mode=1 for log_info + status messages
+ mode=2 for status messages only
+*/
+/* TODO: use this */
+void
+show_keyserver_url(PKT_signature *sig,int indent,int mode)
+{
+ const byte *p;
+ size_t len;
+ int seq=0,crit;
+ FILE *fp=mode?log_get_stream():stdout;
+
+ while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&len,&seq,&crit)))
+ {
+ if(mode!=2)
+ {
+ int i;
+ char *str;
+
+ for(i=0;i<indent;i++)
+ putchar(' ');
+
+ if(crit)
+ str=_("Critical preferred keyserver: ");
+ else
+ str=_("Preferred keyserver: ");
+ if(mode)
+ log_info("%s",str);
+ else
+ printf("%s",str);
+ print_utf8_string(fp,p,len);
+ fprintf(fp,"\n");
+ }
+
+ /* TODO: put in a status-fd tag for preferred keyservers */
+ }
+}
+
+
/*
mode=0 for stdout.
mode=1 for log_info + status messages
@@ -788,6 +865,9 @@ list_keyblock_print ( KBNODE keyblock, int secret, int fpr, void *opaque )
if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATION))
show_notation(sig,3,0);
+ if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER))
+ show_keyserver_url(sig,3,0);
+
/* fixme: check or list other sigs here */
}
}
@@ -820,7 +900,7 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
pk = NULL;
sk = node->pkt->pkt.secret_key;
keyid_from_sk( sk, keyid );
- printf("sec:u:%u:%d:%08lX%08lX:%s:%s:::",
+ printf("sec::%u:%d:%08lX%08lX:%s:%s:::",
nbits_from_sk( sk ),
sk->pubkey_algo,
(ulong)keyid[0],(ulong)keyid[1],
@@ -886,13 +966,17 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
if( any ) {
int i;
char *str=uid->attrib_data?"uat":"uid";
- if ( uid->is_revoked )
+ /* If we're listing a secret key, leave out the
+ validity values for now. FIXME: This should be
+ handled better in 1.9. */
+ if ( sk )
+ printf("%s:::::",str);
+ else if ( uid->is_revoked )
printf("%s:r::::",str);
else if ( uid->is_expired )
printf("%s:e::::",str);
- else if ( opt.no_expensive_trust_checks ) {
+ else if ( opt.no_expensive_trust_checks )
printf("%s:::::",str);
- }
else {
int uid_validity;
@@ -1010,8 +1094,10 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
}
else if( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) {
PKT_signature *sig = node->pkt->pkt.signature;
- int sigrc;
+ int sigrc, fprokay=0;
char *sigstr;
+ size_t fplen;
+ byte fparray[MAX_FINGERPRINT_LEN];
if( !any ) { /* no user id, (maybe a revocation follows)*/
if( sig->sig_class == 0x20 )
@@ -1045,8 +1131,14 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
continue;
}
if( opt.check_sigs ) {
+ PKT_public_key *signer_pk=NULL;
+
fflush(stdout);
- rc = check_key_signature( keyblock, node, NULL );
+ if(opt.no_sig_cache)
+ signer_pk = xcalloc (1, sizeof(PKT_public_key));
+
+ rc = check_key_signature2( keyblock, node, NULL, signer_pk,
+ NULL, NULL, NULL );
switch( gpg_err_code (rc) ) {
case 0: sigrc = '!'; break;
case GPG_ERR_BAD_SIGNATURE: sigrc = '-'; break;
@@ -1054,6 +1146,16 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
case GPG_ERR_UNUSABLE_PUBKEY: sigrc = '?'; break;
default: sigrc = '%'; break;
}
+
+ if(opt.no_sig_cache)
+ {
+ if(!rc)
+ {
+ fingerprint_from_pk (signer_pk, fparray, &fplen);
+ fprokay=1;
+ }
+ free_public_key(signer_pk);
+ }
}
else {
rc = 0;
@@ -1087,7 +1189,20 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
print_string( stdout, p, n, ':' );
xfree (p);
}
- printf(":%02x%c:\n", sig->sig_class,sig->flags.exportable?'x':'l');
+ printf(":%02x%c:", sig->sig_class,sig->flags.exportable?'x':'l');
+ if(opt.no_sig_cache && opt.check_sigs && fprokay)
+ {
+ size_t i;
+
+ printf(":");
+
+ for (i=0; i < fplen ; i++ )
+ printf ("%02X", fparray[i] );
+
+ printf(":");
+ }
+
+ printf("\n");
/* fixme: check or list other sigs here */
}
}
diff --git a/g10/keyring.c b/g10/keyring.c
index 4639e9462..03a22667c 100644
--- a/g10/keyring.c
+++ b/g10/keyring.c
@@ -1382,6 +1382,13 @@ keyring_rebuild_cache (void *token)
{
if (node->pkt->pkttype == PKT_SIGNATURE)
{
+ /* Note that this doesn't cache the result of a
+ revocation issued by a designated revoker. This is
+ because the pk in question does not carry the revkeys
+ as we haven't merged the key and selfsigs. It is
+ questionable whether this matters very much since
+ there are very very few designated revoker revocation
+ packets out there. */
check_key_signature (keyblock, node, NULL);
sigcount++;
}
diff --git a/g10/keyserver.c b/g10/keyserver.c
index e4f56ca3b..445c07620 100644
--- a/g10/keyserver.c
+++ b/g10/keyserver.c
@@ -170,7 +170,8 @@ parse_keyserver_uri(char *uri,const char *configname,unsigned int configlineno)
opt.keyserver_scheme="hkp";
opt.keyserver_options.broken_http_proxy=1;
}
- else if(ascii_strcasecmp(opt.keyserver_scheme,"x-hkp")==0)
+ else if(ascii_strcasecmp(opt.keyserver_scheme,"x-hkp")==0
+ || ascii_strcasecmp(opt.keyserver_scheme,"http")==0)
{
/* Canonicalize this to "hkp" so it works with both the internal
and external keyserver interface. */
@@ -203,7 +204,7 @@ parse_keyserver_uri(char *uri,const char *configname,unsigned int configlineno)
ch=opt.keyserver_port;
while(*ch!='\0')
{
- if(!isdigit(*ch))
+ if(!digitp(ch))
return GPG_ERR_BAD_URI;
ch++;
@@ -340,7 +341,7 @@ parse_keyrec(char *keystring)
/* Remove trailing whitespace */
for(i=strlen(keystring);i>0;i--)
- if(isspace(keystring[i-1]))
+ if(ascii_isspace(keystring[i-1]))
keystring[i-1]='\0';
else
break;
@@ -978,7 +979,7 @@ keyserver_spawn(int action,STRLIST list,
/* remove trailing whitespace */
plen=strlen(ptr);
- while(plen>0 && isspace(ptr[plen-1]))
+ while(plen>0 && ascii_isspace(ptr[plen-1]))
plen--;
plen[ptr]='\0';
diff --git a/g10/main.h b/g10/main.h
index 320a543de..76562fa91 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -151,7 +151,8 @@ int sign_symencrypt_file (const char *fname, STRLIST locusr);
int check_revocation_keys (PKT_public_key *pk, PKT_signature *sig);
int check_key_signature( KBNODE root, KBNODE node, int *is_selfsig );
int check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
- int *is_selfsig, u32 *r_expiredate, int *r_expired );
+ PKT_public_key *ret_pk, int *is_selfsig,
+ u32 *r_expiredate, int *r_expired );
/*-- delkey.c --*/
int delete_keys( STRLIST names, int secret, int allow_both );
@@ -170,6 +171,7 @@ PKT_user_id *keygen_get_std_prefs (void);
int keygen_add_key_expire( PKT_signature *sig, void *opaque );
int keygen_add_std_prefs( PKT_signature *sig, void *opaque );
int keygen_upd_std_prefs( PKT_signature *sig, void *opaque );
+int keygen_add_keyserver_url(PKT_signature *sig, void *opaque);
int keygen_add_revkey(PKT_signature *sig, void *opaque);
int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
@@ -232,6 +234,7 @@ void reorder_keyblock (KBNODE keyblock);
void list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque );
void print_fingerprint (PKT_public_key *pk, PKT_secret_key *sk, int mode);
void show_policy_url(PKT_signature *sig,int indent,int mode);
+void show_keyserver_url(PKT_signature *sig,int indent,int mode);
void show_notation(PKT_signature *sig,int indent,int mode);
void dump_attribs(const PKT_user_id *uid,
PKT_public_key *pk,PKT_secret_key *sk);
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 3689525ef..40b9bd20a 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -668,15 +668,12 @@ proc_compressed( CTX c, PACKET *pkt )
* Returns: 0 = valid signature or an error code
*/
static int
-do_check_sig( CTX c, KBNODE node, int *is_selfsig, int *is_expkey )
+do_check_sig( CTX c, KBNODE node, int *is_selfsig,
+ int *is_expkey, int *is_revkey )
{
PKT_signature *sig;
MD_HANDLE md = NULL, md2 = NULL;
- int algo, rc, dum2;
- u32 dummy;
-
- if(!is_expkey)
- is_expkey=&dum2;
+ int algo, rc;
assert( node->pkt->pkttype == PKT_SIGNATURE );
if( is_selfsig )
@@ -732,9 +729,9 @@ do_check_sig( CTX c, KBNODE node, int *is_selfsig, int *is_expkey )
}
else
return GPG_ERR_SIG_CLASS;
- rc = signature_check2( sig, md, &dummy, is_expkey );
+ rc = signature_check2( sig, md, NULL, is_expkey, is_revkey, NULL );
if( gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE && md2 )
- rc = signature_check2( sig, md2, &dummy, is_expkey );
+ rc = signature_check2( sig, md2, NULL, is_expkey, is_revkey, NULL );
gcry_md_close (md);
gcry_md_close (md2);
@@ -958,7 +955,8 @@ list_node( CTX c, KBNODE node )
if( opt.check_sigs ) {
fflush(stdout);
switch( gpg_err_code (rc2=do_check_sig( c, node,
- &is_selfsig, NULL )) ) {
+ &is_selfsig,
+ NULL, NULL )) ) {
case 0: sigrc = '!'; break;
case GPG_ERR_BAD_SIGNATURE: sigrc = '-'; break;
case GPG_ERR_NO_PUBKEY:
@@ -1217,7 +1215,7 @@ check_sig_and_print( CTX c, KBNODE node )
{
PKT_signature *sig = node->pkt->pkt.signature;
const char *astr, *tstr;
- int rc, is_expkey=0;
+ int rc, is_expkey=0, is_revkey=0;
if( opt.skip_verify ) {
log_info(_("signature verification suppressed\n"));
@@ -1281,19 +1279,51 @@ check_sig_and_print( CTX c, KBNODE node )
tstr = asctimestamp(sig->timestamp);
astr = gcry_pk_algo_name (sig->pubkey_algo);
- log_info(_("Signature made %.*s using %s key ID %08lX\n"),
- (int)strlen(tstr), tstr, astr? astr: "?", (ulong)sig->keyid[1] );
+ if(opt.verify_options&VERIFY_SHOW_LONG_KEYID)
+ {
+ log_info(_("Signature made %.*s\n"),(int)strlen(tstr), tstr);
+ log_info(_(" using %s key %08lX%08lX\n"),
+ astr? astr: "?",(ulong)sig->keyid[0],(ulong)sig->keyid[1] );
+ }
+ else
+ log_info(_("Signature made %.*s using %s key ID %08lX\n"),
+ (int)strlen(tstr), tstr, astr? astr: "?",
+ (ulong)sig->keyid[1] );
- rc = do_check_sig(c, node, NULL, &is_expkey );
+ rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
if( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
&& opt.keyserver_scheme && opt.keyserver_options.auto_key_retrieve) {
if( keyserver_import_keyid ( sig->keyid )==0 )
- rc = do_check_sig(c, node, NULL, &is_expkey );
+ rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
}
+
+
+ /* If the key still isn't found, try to inform the user where it
+ can be found. */
+ if(gpg_err_code (rc)==GPG_ERR_NO_PUBKEY && sig->flags.pref_ks)
+ {
+ const byte *p;
+ int seq=0;
+ size_t n;
+
+ while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&n,&seq,NULL)))
+ {
+ /* According to my favorite copy editor, in English
+ grammar, you say "at" if the key is located on a web
+ page, but "from" if it is located on a keyserver. I'm
+ not going to even try to make two strings here :) */
+ log_info(_("Key available at: ") );
+ print_string( log_get_stream(), p, n, 0 );
+ putc( '\n', log_get_stream() );
+ }
+ }
+
+
if( !rc || gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE ) {
KBNODE un, keyblock;
int count=0, statno;
char keyid_str[50];
+ PKT_public_key *pk=NULL;
if(rc)
statno=STATUS_BADSIG;
@@ -1301,6 +1331,8 @@ check_sig_and_print( CTX c, KBNODE node )
statno=STATUS_EXPSIG;
else if(is_expkey)
statno=STATUS_EXPKEYSIG;
+ else if(is_revkey)
+ statno=STATUS_REVKEYSIG;
else
statno=STATUS_GOODSIG;
@@ -1311,6 +1343,13 @@ check_sig_and_print( CTX c, KBNODE node )
/* find and print the primary user ID */
for( un=keyblock; un; un = un->next ) {
+ int valid;
+
+ if(un->pkt->pkttype==PKT_PUBLIC_KEY)
+ {
+ pk=un->pkt->pkt.public_key;
+ continue;
+ }
if( un->pkt->pkttype != PKT_USER_ID )
continue;
if ( !un->pkt->pkt.user_id->created )
@@ -1325,6 +1364,13 @@ check_sig_and_print( CTX c, KBNODE node )
if ( un->pkt->pkt.user_id->attrib_data )
continue;
+ assert(pk);
+
+ /* Get it before we print anything to avoid interrupting
+ the output with the "please do a --check-trustdb"
+ line. */
+ valid=get_validity(pk,un->pkt->pkt.user_id);
+
keyid_str[17] = 0; /* cut off the "[uncertain]" part */
write_status_text_and_buffer (statno, keyid_str,
un->pkt->pkt.user_id->name,
@@ -1336,7 +1382,11 @@ check_sig_and_print( CTX c, KBNODE node )
: _("Good signature from \""));
print_utf8_string( log_get_stream(), un->pkt->pkt.user_id->name,
un->pkt->pkt.user_id->len );
- fputs("\"\n", log_get_stream() );
+ if(opt.verify_options&VERIFY_SHOW_VALIDITY)
+ fprintf (log_get_stream(),
+ "\" [%s]\n",trust_value_to_string(valid));
+ else
+ fputs("\"\n", log_get_stream() );
count++;
}
if( !count ) { /* just in case that we have no valid textual
@@ -1380,10 +1430,7 @@ check_sig_and_print( CTX c, KBNODE node )
/* If we have a good signature and already printed
* the primary user ID, print all the other user IDs */
if ( count && !rc ) {
- PKT_public_key *pk=NULL;
for( un=keyblock; un; un = un->next ) {
- if(un->pkt->pkttype==PKT_PUBLIC_KEY)
- pk=un->pkt->pkt.public_key;
if( un->pkt->pkttype != PKT_USER_ID )
continue;
if ( un->pkt->pkt.user_id->is_revoked )
@@ -1407,28 +1454,46 @@ check_sig_and_print( CTX c, KBNODE node )
log_info( _(" aka \""));
print_utf8_string( log_get_stream(), un->pkt->pkt.user_id->name,
un->pkt->pkt.user_id->len );
- fputs("\"\n", log_get_stream() );
+ if(opt.verify_options&VERIFY_SHOW_VALIDITY)
+ fprintf (log_get_stream(), "\" [%s]\n",
+ trust_value_to_string(get_validity(pk,
+ un->pkt->
+ pkt.user_id)));
+ else
+ fputs("\"\n", log_get_stream() );
}
}
release_kbnode( keyblock );
if( !rc )
{
- show_notation(sig,0,1);
- show_policy_url(sig,0,1);
- }
+ if(opt.verify_options&VERIFY_SHOW_POLICY)
+ show_policy_url(sig,0,1);
+ else
+ show_policy_url(sig,0,2);
+
+ if(opt.verify_options&VERIFY_SHOW_KEYSERVER)
+ show_keyserver_url(sig,0,1);
+ else
+ show_keyserver_url(sig,0,2);
+
+ if(opt.verify_options&VERIFY_SHOW_NOTATION)
+ show_notation(sig,0,1);
+ else
+ show_notation(sig,0,2);
+ }
if( !rc && is_status_enabled() ) {
/* print a status response with the fingerprint */
- PKT_public_key *pk = xcalloc (1, sizeof *pk );
+ PKT_public_key *vpk = xcalloc (1, sizeof *vpk );
- if( !get_pubkey( pk, sig->keyid ) ) {
+ if( !get_pubkey( vpk, sig->keyid ) ) {
byte array[MAX_FINGERPRINT_LEN], *p;
char buf[MAX_FINGERPRINT_LEN*4+90], *bufp;
size_t i, n;
bufp = buf;
- fingerprint_from_pk( pk, array, &n );
+ fingerprint_from_pk( vpk, array, &n );
p = array;
for(i=0; i < n ; i++, p++, bufp += 2)
sprintf(bufp, "%02X", *p );
@@ -1442,27 +1507,27 @@ check_sig_and_print( CTX c, KBNODE node )
sig->version,sig->pubkey_algo,sig->digest_algo,
sig->sig_class);
bufp = bufp + strlen (bufp);
- if (!pk->is_primary) {
+ if (!vpk->is_primary) {
u32 akid[2];
- akid[0] = pk->main_keyid[0];
- akid[1] = pk->main_keyid[1];
- free_public_key (pk);
- pk = xcalloc (1, sizeof *pk );
- if (get_pubkey (pk, akid)) {
+ akid[0] = vpk->main_keyid[0];
+ akid[1] = vpk->main_keyid[1];
+ free_public_key (vpk);
+ vpk = xcalloc (1, sizeof *vpk );
+ if (get_pubkey (vpk, akid)) {
/* impossible error, we simply return a zeroed out fpr */
n = MAX_FINGERPRINT_LEN < 20? MAX_FINGERPRINT_LEN : 20;
memset (array, 0, n);
}
else
- fingerprint_from_pk( pk, array, &n );
+ fingerprint_from_pk( vpk, array, &n );
}
p = array;
for(i=0; i < n ; i++, p++, bufp += 2)
sprintf(bufp, "%02X", *p );
write_status_text( STATUS_VALIDSIG, buf );
}
- free_public_key( pk );
+ free_public_key( vpk );
}
if( !rc )
diff --git a/g10/misc.c b/g10/misc.c
index 4abe75661..e122f0c5c 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -369,6 +369,8 @@ pct_expando(const char *string,struct expando_args *args)
if(args->sk)
keyid_from_sk(args->sk,sk_keyid);
+ /* This is used so that %k works in photoid command strings in
+ --list-secret-keys (which of course has a sk, but no pk). */
if(!args->pk && args->sk)
keyid_from_sk(args->sk,pk_keyid);
@@ -430,16 +432,37 @@ pct_expando(const char *string,struct expando_args *args)
}
break;
- case 'f': /* fingerprint */
+ case 'p': /* primary pk fingerprint of a sk */
+ case 'f': /* pk fingerprint */
+ case 'g': /* sk fingerprint */
{
byte array[MAX_FINGERPRINT_LEN];
size_t len;
int i;
- if(args->pk)
+ if( ch[1]=='p' && args->sk)
+ {
+ if(args->sk->is_primary)
+ fingerprint_from_sk(args->sk,array,&len);
+ else if(args->sk->main_keyid[0] || args->sk->main_keyid[1])
+ {
+ PKT_public_key *pk= xcalloc(1, sizeof(PKT_public_key));
+
+ if(get_pubkey_fast(pk,args->sk->main_keyid)==0)
+ fingerprint_from_pk(pk,array,&len);
+ else
+ memset(array,0,(len=MAX_FINGERPRINT_LEN));
+ free_public_key(pk);
+ }
+ else
+ memset(array,0,(len=MAX_FINGERPRINT_LEN));
+ }
+ else if( ch[1]=='f' && args->pk)
fingerprint_from_pk(args->pk,array,&len);
+ else if( ch[1]=='g' && args->sk)
+ fingerprint_from_sk(args->sk,array,&len);
else
- memset(array,0, (len=MAX_FINGERPRINT_LEN));
+ memset(array, 0, (len=MAX_FINGERPRINT_LEN));
if(idx+(len*2)<maxlen)
{
diff --git a/g10/options.h b/g10/options.h
index 9eda2e252..a4cbc3834 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -101,7 +101,7 @@ struct {
unsigned int emulate_bugs; /* bug emulation flags EMUBUG_xxxx */
int shm_coprocess;
const char *set_filename;
- const char *comment_string;
+ STRLIST comments;
int throw_keyid;
const char *photo_viewer;
int s2k_mode;
@@ -153,6 +153,7 @@ struct {
STRLIST cert_notation_data;
STRLIST sig_policy_url;
STRLIST cert_policy_url;
+ STRLIST sig_keyserver_url;
int use_embedded_filename;
int allow_non_selfsigned_uid;
int allow_freeform_uid;
@@ -230,16 +231,22 @@ struct {
#define EXPORT_SEXP_FORMAT 16
-#define LIST_SHOW_PHOTOS 1
-#define LIST_SHOW_POLICY 2
-#define LIST_SHOW_NOTATION 4
-#define LIST_SHOW_KEYRING 8
-#define LIST_SHOW_VALIDITY 16
-#define LIST_SHOW_LONG_KEYID 32
+#define LIST_SHOW_PHOTOS 1
+#define LIST_SHOW_POLICY 2
+#define LIST_SHOW_NOTATION 4
+#define LIST_SHOW_KEYSERVER 8
+#define LIST_SHOW_VALIDITY 16
+#define LIST_SHOW_LONG_KEYID 32
+#define LIST_SHOW_KEYRING 64
+#define LIST_SHOW_SIG_EXPIRE 128
-#define VERIFY_SHOW_PHOTOS 1
-#define VERIFY_SHOW_POLICY 2
-#define VERIFY_SHOW_NOTATION 4
+
+#define VERIFY_SHOW_PHOTOS 1
+#define VERIFY_SHOW_POLICY 2
+#define VERIFY_SHOW_NOTATION 4
+#define VERIFY_SHOW_KEYSERVER 8
+#define VERIFY_SHOW_VALIDITY 16
+#define VERIFY_SHOW_LONG_KEYID 32
#endif /*G10_OPTIONS_H*/
diff --git a/g10/options.skel b/g10/options.skel
index e50f66ffe..3d15f811c 100644
--- a/g10/options.skel
+++ b/g10/options.skel
@@ -90,10 +90,10 @@
# support).
#
# Example HKP keyserver:
-# x-hkp://pgp.mit.edu
+# hkp://subkeys.pgp.net
#
# Example email keyserver:
-# mailto:pgp-public-keys@keys.nl.pgp.net
+# mailto:pgp-public-keys@keys.pgp.net
#
# Example LDAP keyservers:
# ldap://pgp.surfnet.nl:11370
@@ -101,7 +101,7 @@
#
# Regular URL syntax applies, and you can set an alternate port
# through the usual method:
-# x-hkp://keyserver.example.net:22742
+# hkp://keyserver.example.net:22742
#
# If you have problems connecting to a HKP server through a buggy http
# proxy, you can use keyserver option broken-http-proxy (see below),
@@ -109,10 +109,14 @@
# regarding proxies (keyserver option honor-http-proxy)
#
# Most users just set the name and type of their preferred keyserver.
-# Most servers do synchronize with each other and DNS round-robin may
-# give you a quasi-random server each time.
-
-#keyserver x-hkp://pgp.mit.edu
+# Note that most servers (with the notable exception of
+# ldap://keyserver.pgp.com) synchronize changes with each other. Note
+# also that a single server name may actually point to multiple
+# servers via DNS round-robin. hkp://subkeys.pgp.net is an example of
+# such a "server", which spreads the load over a number of physical
+# servers.
+
+keyserver hkp://subkeys.pgp.net
#keyserver mailto:pgp-public-keys@keys.nl.pgp.net
#keyserver ldap://pgp.surfnet.nl:11370
#keyserver ldap://keyserver.pgp.com
diff --git a/g10/packet.h b/g10/packet.h
index dc5b1583a..2d87c9c7d 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -132,8 +132,9 @@ typedef struct {
unsigned unknown_critical:1;
unsigned exportable:1;
unsigned revocable:1;
- unsigned policy_url:1; /* Policy URL is present */
- unsigned notation:1; /* At least one notation is present */
+ unsigned policy_url:1; /* At least one policy URL is present */
+ unsigned notation:1; /* At least one notation is present */
+ unsigned pref_ks:1; /* At least one preferred keyserver is present */
unsigned expired:1;
} flags;
u32 keyid[2]; /* 64 bit keyid */
@@ -463,8 +464,8 @@ int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );
/*-- sig-check.c --*/
int signature_check( PKT_signature *sig, MD_HANDLE digest );
-int signature_check2( PKT_signature *sig, MD_HANDLE digest,
- u32 *r_expiredate, int *r_expired );
+int signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate,
+ int *r_expired, int *r_revoked, PKT_public_key *ret_pk );
/*-- seckey-cert.c --*/
int is_secret_key_protected( PKT_secret_key *sk );
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index f70cc3f69..c922eb5d9 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -367,9 +367,29 @@ parse( iobuf_t inp, PACKET *pkt, int onlykeypkts, off_t *retpos,
lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
if( !lenbytes ) {
pktlen = 0; /* don't know the value */
- if( pkttype != PKT_COMPRESSED )
- iobuf_set_block_mode(inp, 1);
- }
+ switch (pkttype) {
+ case PKT_ENCRYPTED:
+ case PKT_PLAINTEXT:
+ /* These partial length encodings are from an very
+ early GnuPG release and deprecated. However we
+ still support them read-wise. Note, that we should
+ not allow them for any key related packets, because
+ this might render a keyring unusable if an errenous
+ packet indicated this mode but not complying to it
+ gets imported. */
+ iobuf_set_block_mode(inp, 1);
+ break;
+
+ case PKT_COMPRESSED:
+ break; /* the orginal pgp 2 way. */
+
+ default:
+ log_error ("%s: old style partial length "
+ "for invalid packet type\n", iobuf_where(inp) );
+ rc = gpg_error (GPG_ERR_INV_PACKET);
+ goto leave;
+ }
+ }
else {
for( ; lenbytes; lenbytes-- ) {
pktlen <<= 8;
@@ -860,7 +880,8 @@ dump_sig_subpkt( int hashed, int type, int critical,
printf(" %02X", buffer[i]);
break;
case SIGSUBPKT_PREF_KS:
- p = "preferred key server";
+ fputs("preferred key server: ", stdout );
+ print_string( stdout, buffer, length, ')' );
break;
case SIGSUBPKT_PRIMARY_UID:
p = "primary user ID";
@@ -936,6 +957,7 @@ parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
case SIGSUBPKT_PREF_HASH:
case SIGSUBPKT_PREF_COMPR:
case SIGSUBPKT_POLICY:
+ case SIGSUBPKT_PREF_KS:
case SIGSUBPKT_FEATURES:
case SIGSUBPKT_REGEXP:
return 0;
@@ -992,9 +1014,11 @@ can_handle_critical( const byte *buffer, size_t n, int type )
case SIGSUBPKT_KEY_FLAGS:
case SIGSUBPKT_PRIMARY_UID:
case SIGSUBPKT_FEATURES:
- case SIGSUBPKT_POLICY: /* Is it enough to show the policy? */
case SIGSUBPKT_TRUST:
case SIGSUBPKT_REGEXP:
+ /* Is it enough to show the policy or keyserver? */
+ case SIGSUBPKT_POLICY:
+ case SIGSUBPKT_PREF_KS:
return 1;
default:
@@ -1220,11 +1244,8 @@ parse_signature( iobuf_t inp, int pkttype, unsigned long pktlen,
goto leave;
}
if( n ) {
- /* we add 8 extra bytes so that we have space for the signature
- * status cache. Well we are wasting this if there is a cache
- * packet already, but in the other case it avoids an realloc */
- sig->unhashed = xmalloc (sizeof(*sig->unhashed) + n + 8 - 1 );
- sig->unhashed->size = n + 8;
+ sig->unhashed = xmalloc (sizeof(*sig->unhashed) + n - 1 );
+ sig->unhashed->size = n;
sig->unhashed->len = n;
if( iobuf_read(inp, sig->unhashed->data, n ) != n ) {
log_error("premature eof while reading "
@@ -1259,17 +1280,19 @@ parse_signature( iobuf_t inp, int pkttype, unsigned long pktlen,
}
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL );
- if( !p )
- log_error("signature packet without timestamp\n");
- else
- sig->timestamp = buffer_to_u32(p);
+ if(p)
+ sig->timestamp = buffer_to_u32(p);
+ else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110))
+ log_error("signature packet without timestamp\n");
+
p = parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL );
- if( !p )
- log_error("signature packet without keyid\n");
- else {
- sig->keyid[0] = buffer_to_u32(p);
- sig->keyid[1] = buffer_to_u32(p+4);
+ if( p )
+ {
+ sig->keyid[0] = buffer_to_u32(p);
+ sig->keyid[1] = buffer_to_u32(p+4);
}
+ else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110))
+ log_error("signature packet without keyid\n");
p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL);
if(p)
@@ -1281,6 +1304,10 @@ parse_signature( iobuf_t inp, int pkttype, unsigned long pktlen,
if(p)
sig->flags.policy_url=1;
+ p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,NULL);
+ if(p)
+ sig->flags.pref_ks=1;
+
p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,NULL);
if(p)
sig->flags.notation=1;
diff --git a/g10/passphrase.c b/g10/passphrase.c
index d00340109..ac7e71591 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -29,7 +29,7 @@
#include <sys/socket.h>
#include <sys/un.h>
#endif
-#if defined (__MINGW32__) || defined (__CYGWIN32__)
+#if defined (_WIN32) || defined (__CYGWIN32__)
# include <windows.h>
#endif
#include <errno.h>
@@ -101,7 +101,7 @@ static char *fd_passwd = NULL;
static char *next_pw = NULL;
static char *last_pw = NULL;
-#if defined (__MINGW32__)
+#if defined (_WIN32)
static int read_fd = 0;
static int write_fd = 0;
#endif
@@ -191,7 +191,7 @@ read_passphrase_from_fd( int fd )
static int
writen ( int fd, const void *buf, size_t nbytes )
{
-#if defined (__MINGW32__)
+#if defined (_WIN32)
DWORD nwritten, nleft = nbytes;
while (nleft > 0) {
@@ -234,7 +234,7 @@ writen ( int fd, const void *buf, size_t nbytes )
static int
readn ( int fd, void *buf, size_t buflen, size_t *ret_nread )
{
-#if defined (__MINGW32__)
+#if defined (_WIN32)
DWORD nread, nleft = buflen;
while (nleft > 0) {
@@ -328,7 +328,7 @@ readline (int fd, char *buf, size_t buflen)
#if !defined (__riscos__)
-#if !defined (__MINGW32__)
+#if !defined (_WIN32)
/* For the new Assuan protocol we may have to send options */
static int
agent_send_option (int fd, const char *name, const char *value)
@@ -376,7 +376,11 @@ agent_send_all_options (int fd)
}
if (!opt.ttyname)
- dft_ttyname = tty_get_ttyname ();
+ {
+ dft_ttyname = getenv ("GPG_TTY");
+ if ((!dft_ttyname || !*dft_ttyname) && tty_get_ttyname ())
+ dft_ttyname = tty_get_ttyname ();
+ }
if (opt.ttyname || dft_ttyname)
{
if (agent_send_option (fd, "ttyname",
@@ -433,7 +437,7 @@ agent_send_all_options (int fd)
#endif
return rc;
}
-#endif /*!__MINGW32__*/
+#endif /*!_WIN32*/
/*
@@ -444,7 +448,7 @@ agent_send_all_options (int fd)
static int
agent_open (int *ret_prot)
{
-#if defined (__MINGW32__)
+#if defined (_WIN32)
int fd;
char *infostr, *p;
HANDLE h;
@@ -589,7 +593,7 @@ agent_open (int *ret_prot)
static void
agent_close ( int fd )
{
-#if defined (__MINGW32__)
+#if defined (_WIN32)
HANDLE h = OpenEvent(EVENT_ALL_ACCESS, FALSE, "gpg_agent");
ResetEvent(h);
#else
diff --git a/g10/photoid.c b/g10/photoid.c
index 1dd6edeca..00cc7a273 100644
--- a/g10/photoid.c
+++ b/g10/photoid.c
@@ -22,7 +22,7 @@
#include <errno.h>
#include <stdio.h>
#include <string.h>
-#ifdef __MINGW32__
+#ifdef _WIN32
# include <windows.h>
# ifndef VER_PLATFORM_WIN32_WINDOWS
# define VER_PLATFORM_WIN32_WINDOWS 1
@@ -223,7 +223,7 @@ char *image_type_to_string(byte type,int style)
#if !defined(FIXED_PHOTO_VIEWER) && !defined(DISABLE_PHOTO_VIEWER)
static const char *get_default_photo_command(void)
{
-#if defined(__MINGW32__)
+#if defined(_WIN32)
OSVERSIONINFO osvi;
memset(&osvi,0,sizeof(osvi));
diff --git a/g10/pkclist.c b/g10/pkclist.c
index 5a4aa250f..71e6492e8 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -1164,10 +1164,6 @@ algo_available( preftype_t preftype, int algo, void *hint )
&& algo != DIGEST_ALGO_SHA256))
return 0;
- /* TIGER is not allowed any longer according to 2440bis. */
- if( RFC2440 && algo == DIGEST_ALGO_TIGER )
- return 0;
-
return algo && !gcry_md_test_algo( algo );
}
else if( preftype == PREFTYPE_ZIP )
diff --git a/g10/revoke.c b/g10/revoke.c
index cf1bfe17a..161bd2b82 100644
--- a/g10/revoke.c
+++ b/g10/revoke.c
@@ -608,7 +608,7 @@ ask_revocation_reason( int key_rev, int cert_rev, int hint )
return NULL; /* cancel */
if( hint && !*answer )
n = hint;
- else if(!isdigit( *answer ) )
+ else if(!digitp( answer ) )
n = -1;
else
n = atoi(answer);
diff --git a/g10/sig-check.c b/g10/sig-check.c
index 4547c6e12..b0c89cba3 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -43,8 +43,9 @@ struct cmp_help_context_s {
MD_HANDLE md;
};
-static int do_check( PKT_public_key *pk, PKT_signature *sig,
- MD_HANDLE digest, int *r_expired );
+
+static int do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
+ int *r_expired, int *r_revoked, PKT_public_key *ret_pk);
/****************
* Check the signature which is contained in SIG.
@@ -54,20 +55,16 @@ static int do_check( PKT_public_key *pk, PKT_signature *sig,
int
signature_check( PKT_signature *sig, MD_HANDLE digest )
{
- u32 dummy;
- int dum2;
- return signature_check2( sig, digest, &dummy, &dum2 );
+ return signature_check2( sig, digest, NULL, NULL, NULL, NULL );
}
int
-signature_check2( PKT_signature *sig, MD_HANDLE digest,
- u32 *r_expiredate, int *r_expired )
+signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate,
+ int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
{
PKT_public_key *pk = xcalloc (1, sizeof *pk );
int rc=0;
- *r_expiredate = 0;
-
/* Sanity check that the md has a context for the hash that the
sig is expecting. This can happen if a onepass sig header does
not match the actual sig, and also if the clearsign "Hash:"
@@ -83,8 +80,9 @@ signature_check2( PKT_signature *sig, MD_HANDLE digest,
rc=GPG_ERR_BAD_PUBKEY; /* you cannot have a good sig from an
invalid subkey */
else {
- *r_expiredate = pk->expiredate;
- rc = do_check( pk, sig, digest, r_expired );
+ if (r_expiredate)
+ *r_expiredate = pk->expiredate;
+ rc = do_check( pk, sig, digest, r_expired, r_revoked, ret_pk );
}
free_public_key( pk );
@@ -135,11 +133,15 @@ signature_check2( PKT_signature *sig, MD_HANDLE digest,
static int
-do_check_messages( PKT_public_key *pk, PKT_signature *sig, int *r_expired )
+do_check_messages( PKT_public_key *pk, PKT_signature *sig,
+ int *r_expired, int *r_revoked )
{
u32 cur_time;
- *r_expired = 0;
+ if (r_expired)
+ *r_expired = 0;
+ if (r_revoked)
+ *r_revoked = 0;
if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
log_info(_("key %08lX: this is a PGP generated "
"ElGamal key which is NOT secure for signatures!\n"),
@@ -182,22 +184,26 @@ do_check_messages( PKT_public_key *pk, PKT_signature *sig, int *r_expired )
sprintf(buf,"%lu",(ulong)pk->expiredate);
write_status_text(STATUS_KEYEXPIRED,buf);
write_status(STATUS_SIGEXPIRED);
- *r_expired = 1;
+ if (r_expired)
+ *r_expired = 1;
}
+ if(pk->is_revoked && r_revoked)
+ *r_revoked=1;
+
return 0;
}
static int
do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
- int *r_expired )
+ int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
{
gcry_mpi_t result = NULL;
int rc=0;
struct cmp_help_context_s ctx;
- if( (rc=do_check_messages(pk,sig,r_expired)) )
+ if( (rc=do_check_messages(pk,sig,r_expired,r_revoked)) )
return rc;
if( (rc=gcry_md_test_algo(sig->digest_algo)) )
return rc;
@@ -280,6 +286,9 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
}
+ if(!rc && ret_pk)
+ copy_public_key(ret_pk,pk);
+
return rc;
}
@@ -406,16 +415,19 @@ check_revocation_keys(PKT_public_key *pk,PKT_signature *sig)
int
check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
{
- u32 dummy;
- int dum2;
- return check_key_signature2(root, node, NULL, is_selfsig, &dummy, &dum2 );
+ return check_key_signature2(root, node, NULL, NULL, is_selfsig, NULL, NULL);
}
/* If check_pk is set, then use it to check the signature in node
- rather than getting it from root or the keydb. */
+ rather than getting it from root or the keydb. If ret_pk is set,
+ fill in the public key that was used to verify the signature.
+ ret_pk is only meaningful when the verification was successful. */
+/* TODO: add r_revoked here as well. It has the same problems as
+ r_expiredate and r_expired and the cache. */
int
check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
- int *is_selfsig, u32 *r_expiredate, int *r_expired )
+ PKT_public_key *ret_pk, int *is_selfsig,
+ u32 *r_expiredate, int *r_expired )
{
MD_HANDLE md;
PKT_public_key *pk;
@@ -425,8 +437,10 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
if( is_selfsig )
*is_selfsig = 0;
- *r_expiredate = 0;
- *r_expired = 0;
+ if( r_expiredate )
+ *r_expiredate = 0;
+ if( r_expired )
+ *r_expired = 0;
assert( node->pkt->pkttype == PKT_SIGNATURE );
assert( root->pkt->pkttype == PKT_PUBLIC_KEY );
@@ -444,7 +458,9 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
*is_selfsig = 1;
}
- if((rc=do_check_messages(pk,sig,r_expired)))
+ /* BUG: This is wrong for non-self-sigs. Needs to be the
+ actual pk */
+ if((rc=do_check_messages(pk,sig,r_expired,NULL)))
return rc;
return sig->flags.valid? 0 : gpg_error (GPG_ERR_BAD_SIGNATURE);
}
@@ -464,7 +480,7 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
{
gcry_md_open (&md, algo, 0 );
hash_public_key( md, pk );
- rc = do_check( pk, sig, md, r_expired );
+ rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
cache_sig_result ( sig, rc );
gcry_md_close(md);
}
@@ -476,12 +492,12 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
gcry_md_open (&md, algo, 0 );
hash_public_key( md, pk );
hash_public_key( md, snode->pkt->pkt.public_key );
- rc = do_check( pk, sig, md, r_expired );
+ rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
cache_sig_result ( sig, rc );
gcry_md_close(md);
}
else {
- if (!opt.quiet)
+ if (opt.verbose)
log_info (_("key %08lX: no subkey for subkey "
"revocation signature\n"),
(ulong)keyid_from_pk (pk, NULL));
@@ -502,7 +518,7 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
gcry_md_open (&md, algo, 0 );
hash_public_key( md, pk );
hash_public_key( md, snode->pkt->pkt.public_key );
- rc = do_check( pk, sig, md, r_expired );
+ rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
cache_sig_result ( sig, rc );
gcry_md_close(md);
}
@@ -517,7 +533,7 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
else if( sig->sig_class == 0x1f ) { /* direct key signature */
gcry_md_open (&md, algo, 0 );
hash_public_key( md, pk );
- rc = do_check( pk, sig, md, r_expired );
+ rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
cache_sig_result ( sig, rc );
gcry_md_close(md);
}
@@ -535,12 +551,13 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
{
if( is_selfsig )
*is_selfsig = 1;
- rc = do_check( pk, sig, md, r_expired );
+ rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
}
else if (check_pk)
- rc=do_check(check_pk,sig,md,r_expired);
+ rc=do_check(check_pk,sig,md,r_expired, NULL, ret_pk);
else
- rc = signature_check2( sig, md, r_expiredate, r_expired );
+ rc = signature_check2( sig, md, r_expiredate, r_expired,
+ NULL, ret_pk);
cache_sig_result ( sig, rc );
gcry_md_close(md);
diff --git a/g10/sign.c b/g10/sign.c
index 493bfb4d9..640e36fe0 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -55,12 +55,12 @@ void __stdcall Sleep(ulong);
static int recipient_digest_algo=0;
/****************
- * Create a notation. It is assumed that the stings in STRLIST
- * are already checked to contain only printable data and have a valid
- * NAME=VALUE format.
+ * Create a notation. We assume thIt is assumed that the strings in
+ * the STRLISTs of the opt struct are already checked to contain only
+ * printable data and have a valid NAME=VALUE format.
*/
static void
-mk_notation_and_policy( PKT_signature *sig,
+mk_notation_policy_etc( PKT_signature *sig,
PKT_public_key *pk, PKT_secret_key *sk )
{
const char *string;
@@ -74,18 +74,25 @@ mk_notation_and_policy( PKT_signature *sig,
args.pk=pk;
args.sk=sk;
+ /* It is actually impossible to get here when making a v3 key
+ signature since keyedit.c:sign_uids will automatically bump a
+ signature with a notation or policy url up to v4, but it is
+ good to do these checks anyway. */
+
/* notation data */
if(IS_SIG(sig) && opt.sig_notation_data)
{
if(sig->version<4)
- log_info("can't put notation data into v3 signatures\n");
+ log_error(_("can't put notation data into v3 (PGP 2.x style) "
+ "signatures\n"));
else
nd=opt.sig_notation_data;
}
else if( IS_CERT(sig) && opt.cert_notation_data )
{
if(sig->version<4)
- log_info("can't put notation data into v3 key signatures\n");
+ log_error(_("can't put notation data into v3 (PGP 2.x style) "
+ "key signatures\n"));
else
nd=opt.cert_notation_data;
}
@@ -125,21 +132,20 @@ mk_notation_and_policy( PKT_signature *sig,
xfree (buf);
}
- if(opt.list_options&LIST_SHOW_NOTATION)
- show_notation(sig,0,0);
-
/* set policy URL */
if( IS_SIG(sig) && opt.sig_policy_url )
{
if(sig->version<4)
- log_info("can't put a policy URL into v3 signatures\n");
+ log_error(_("can't put a policy URL into v3 (PGP 2.x style) "
+ "signatures\n"));
else
pu=opt.sig_policy_url;
}
else if( IS_CERT(sig) && opt.cert_policy_url )
{
if(sig->version<4)
- log_info("can't put a policy URL into v3 key signatures\n");
+ log_error(_("can't put a policy URL into v3 key (PGP 2.x style) "
+ "signatures\n"));
else
pu=opt.cert_policy_url;
}
@@ -163,8 +169,34 @@ mk_notation_and_policy( PKT_signature *sig,
xfree (s);
}
- if(opt.list_options&LIST_SHOW_POLICY)
- show_policy_url(sig,0,0);
+ /* preferred keyserver URL */
+ if( IS_SIG(sig) && opt.sig_keyserver_url )
+ {
+ if(sig->version<4)
+ log_info (_("can't put a preferred keyserver URL "
+ "into v3 signatures\n"));
+ else
+ pu=opt.sig_keyserver_url;
+ }
+
+ for(;pu;pu=pu->next)
+ {
+ string = pu->d;
+
+ s=pct_expando(string,&args);
+ if(!s)
+ {
+ log_error(_("WARNING: unable to %%-expand preferred keyserver URL"
+ " (too large). Using unexpanded.\n"));
+ s=xstrdup(string);
+ }
+
+ build_sig_subpkt(sig,SIGSUBPKT_PREF_KS|
+ ((pu->flags & 1)?SIGSUBPKT_FLAG_CRITICAL:0),
+ s,strlen(s));
+
+ xfree(s);
+ }
}
@@ -621,7 +653,8 @@ write_signature_packets (SK_LIST sk_list, iobuf_t out, MD_HANDLE hash,
sig = xcalloc (1,sizeof *sig);
if(opt.force_v3_sigs || RFC1991)
sig->version=3;
- else if(duration || opt.sig_policy_url || opt.sig_notation_data)
+ else if(duration || opt.sig_policy_url
+ || opt.sig_notation_data || opt.sig_keyserver_url)
sig->version=4;
else
sig->version=sk->version;
@@ -640,7 +673,7 @@ write_signature_packets (SK_LIST sk_list, iobuf_t out, MD_HANDLE hash,
if (sig->version >= 4)
build_sig_subpkt_from_sig (sig);
- mk_notation_and_policy (sig, NULL, sk);
+ mk_notation_policy_etc (sig, NULL, sk);
hash_sigversion_to_magic (md, sig);
gcry_md_final (md);
@@ -1308,7 +1341,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
sig->sig_class = sigclass;
if( sig->version >= 4 )
build_sig_subpkt_from_sig( sig );
- mk_notation_and_policy( sig, pk, sk );
+ mk_notation_policy_etc ( sig, pk, sk );
/* Crucial that the call to mksubpkt comes LAST before the calls
to finalize the sig as that makes it possible for the mksubpkt
diff --git a/g10/signal.c b/g10/signal.c
index 90c0841d8..9f50fbe3a 100644
--- a/g10/signal.c
+++ b/g10/signal.c
@@ -1,5 +1,5 @@
/* signal.c - signal handling
- * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -42,7 +42,7 @@ static void
init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign )
{
#ifndef HAVE_DOSISH_SYSTEM
-#ifdef HAVE_SIGACTION
+#if defined(HAVE_SIGACTION) && defined(HAVE_STRUCT_SIGACTION)
struct sigaction oact, nact;
if (check_ign) {
@@ -132,7 +132,7 @@ void
pause_on_sigusr( int which )
{
#ifndef HAVE_DOSISH_SYSTEM
-#ifdef HAVE_SIGPROCMASK
+#if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T)
sigset_t mask, oldmask;
assert( which == 1 );
@@ -150,8 +150,8 @@ pause_on_sigusr( int which )
while (!caught_sigusr1)
sigpause(SIGUSR1);
caught_sigusr1 = 0;
- sigrelse(SIGUSR1); ????
-#endif /*!HAVE_SIGPROCMASK*/
+ sigrelse(SIGUSR1);
+#endif /*!HAVE_SIGPROCMASK && HAVE_SISET_T*/
#endif
}
@@ -161,7 +161,7 @@ do_block( int block )
{
#ifndef HAVE_DOSISH_SYSTEM
static int is_blocked;
-#ifdef HAVE_SIGPROCMASK
+#if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T)
static sigset_t oldmask;
if( block ) {
@@ -180,13 +180,22 @@ do_block( int block )
is_blocked = 0;
}
#else /*!HAVE_SIGPROCMASK*/
- static void (*disposition[MAXSIG])();
+
+#if defined(NSIG)
+# define SIGSMAX (NSIG)
+#elif defined(MAXSIG)
+# define SIGSMAX (MAXSIG+1)
+#else
+# error "define SIGSMAX to the number of signals on your platform plus one"
+#endif
+
+ static void (*disposition[SIGSMAX])(int);
int sig;
if( block ) {
if( is_blocked )
log_bug("signals are already blocked\n");
- for (sig=1; sig < MAXSIG; sig++) {
+ for (sig=1; sig < SIGSMAX; sig++) {
disposition[sig] = sigset (sig, SIG_HOLD);
}
is_blocked = 1;
@@ -194,7 +203,7 @@ do_block( int block )
else {
if( !is_blocked )
log_bug("signals are not blocked\n");
- for (sig=1; sig < MAXSIG; sig++) {
+ for (sig=1; sig < SIGSMAX; sig++) {
sigset (sig, disposition[sig]);
}
is_blocked = 0;
diff --git a/g10/status.c b/g10/status.c
index 4414b33e9..aa55020be 100644
--- a/g10/status.c
+++ b/g10/status.c
@@ -129,6 +129,7 @@ get_status_string ( int no )
case STATUS_SIGEXPIRED : s = "SIGEXPIRED deprecated-use-keyexpired-instead"; break;
case STATUS_EXPSIG : s = "EXPSIG"; break;
case STATUS_EXPKEYSIG : s = "EXPKEYSIG"; break;
+ case STATUS_REVKEYSIG : s = "REVKEYSIG"; break;
case STATUS_ATTRIBUTE : s = "ATTRIBUTE"; break;
default: s = "?"; break;
}
diff --git a/g10/status.h b/g10/status.h
index 4a0bcd45b..d8de81080 100644
--- a/g10/status.h
+++ b/g10/status.h
@@ -99,6 +99,7 @@
#define STATUS_ATTRIBUTE 67
#define STATUS_IMPORT_OK 68
#define STATUS_IMPORT_CHECK 69
+#define STATUS_REVKEYSIG 70
/*-- status.c --*/
void set_status_fd ( int fd );
diff --git a/g10/tdbdump.c b/g10/tdbdump.c
index 3f9e8b388..5eb482959 100644
--- a/g10/tdbdump.c
+++ b/g10/tdbdump.c
@@ -154,7 +154,7 @@ import_ownertrust( const char *fname )
break; /* can't continue */
}
for(p = line; *p && *p != ':' ; p++ )
- if( !isxdigit(*p) )
+ if( !hexdigitp (p) )
break;
if( *p != ':' ) {
log_error (_("\b%s: error: missing colon\n"), fname );
diff --git a/g10/tdbio.c b/g10/tdbio.c
index 39239be20..d1b5ed32a 100644
--- a/g10/tdbio.c
+++ b/g10/tdbio.c
@@ -337,6 +337,9 @@ tdbio_sync()
}
+#if 0
+/* The transaction code is disabled in the 1.2.x branch, as it is not
+ yet used. It will be enabled in 1.3.x. */
/****************
* Simple transactions system:
@@ -408,6 +411,8 @@ tdbio_cancel_transaction()
return 0;
}
+#endif /* transaction code */
+
/********************************************************
diff --git a/g10/trustdb.c b/g10/trustdb.c
index 16bd96e49..864334f4f 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -591,6 +591,31 @@ trustdb_pending_check(void)
return pending_check_trustdb;
}
+void
+read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck,
+ byte *marginals,byte *completes,byte *cert_depth)
+{
+ TRUSTREC opts;
+
+ init_trustdb();
+
+ read_record(0,&opts,RECTYPE_VER);
+
+ if(trust_model)
+ *trust_model=opts.r.ver.trust_model;
+ if(created)
+ *created=opts.r.ver.created;
+ if(nextcheck)
+ *nextcheck=opts.r.ver.nextcheck;
+ if(marginals)
+ *marginals=opts.r.ver.marginals;
+ if(completes)
+ *completes=opts.r.ver.completes;
+ if(cert_depth)
+ *cert_depth=opts.r.ver.cert_depth;
+}
+
+
/***********************************************
*********** Ownertrust et al. ****************
@@ -1573,10 +1598,14 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist,
signed (but not self-signed) uid does carry trust, of a sort,
even if it is a statement being made by people other than the
key owner "through" the uids on the key owner's key. I'm
- going with the latter. -dshaw */
+ going with the latter. However, if the user ID was
+ explicitly revoked, or passively allowed to expire, that
+ should stop validity through the user ID until it is
+ resigned. -dshaw */
- /* && node->pkt->pkt.user_id->created) */
- if (node->pkt->pkttype == PKT_USER_ID)
+ if (node->pkt->pkttype == PKT_USER_ID
+ && !node->pkt->pkt.user_id->is_revoked
+ && !node->pkt->pkt.user_id->is_expired)
{
if (uidnode && issigned)
{
@@ -1590,12 +1619,11 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist,
}
uidnode = node;
uid=uidnode->pkt->pkt.user_id;
-#if 0
- /* If the selfsig is going to expire... This is disabled as
- we do count un-self-signed uids in the web of trust. */
+
+ /* If the selfsig is going to expire... */
if(uid->expiredate && uid->expiredate<*next_expire)
*next_expire = uid->expiredate;
-#endif
+
issigned = 0;
get_validity_counts(pk,uid);
mark_usable_uid_certs (kb, uidnode, main_kid, klist,
diff --git a/g10/trustdb.h b/g10/trustdb.h
index 720385a06..414c37702 100644
--- a/g10/trustdb.h
+++ b/g10/trustdb.h
@@ -64,6 +64,9 @@ int enum_cert_paths( void **context, ulong *lid,
void enum_cert_paths_print( void **context, FILE *fp,
int refresh, ulong selected_lid );
+void read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck,
+ byte *marginals,byte *completes,byte *cert_depth);
+
unsigned int get_ownertrust (PKT_public_key *pk);
unsigned int get_min_ownertrust (PKT_public_key *pk);
int get_ownertrust_info (PKT_public_key *pk);
diff --git a/include/ChangeLog b/include/ChangeLog
index 380d63b45..5b343f5a0 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,14 @@
+2003-09-04 David Shaw <dshaw@jabberwocky.com>
+
+ * cipher.h: Drop TIGER/192 support.
+
+ * types.h: Prefer using uint64_t when creating a 64-bit unsigned
+ type. This avoids a warning on compilers that support but complain
+ about unsigned long long.
+
+ * util.h: Make sure that only ascii is passed to isfoo
+ functions. (From Werner on stable branch).
+
2003-09-04 Werner Koch <wk@gnupg.org>
* cipher.h (PUBKEY_USAGE_AUTH): Added.
diff --git a/include/cipher.h b/include/cipher.h
index 90cedb051..e7e36c6d5 100644
--- a/include/cipher.h
+++ b/include/cipher.h
@@ -53,7 +53,6 @@
#define DIGEST_ALGO_MD5 GCRY_MD_MD5
#define DIGEST_ALGO_SHA1 GCRY_MD_SHA1
#define DIGEST_ALGO_RMD160 GCRY_MD_RMD160
-#define DIGEST_ALGO_TIGER GCRY_MD_TIGER
#define DIGEST_ALGO_SHA256 GCRY_MD_SHA256
#define DIGEST_ALGO_SHA384 GCRY_MD_SHA384
#define DIGEST_ALGO_SHA512 GCRY_MD_SHA512
diff --git a/include/types.h b/include/types.h
index 838897aa5..dff512061 100644
--- a/include/types.h
+++ b/include/types.h
@@ -101,7 +101,11 @@ typedef unsigned long u32;
*/
#ifndef HAVE_U64_TYPEDEF
#undef u64 /* maybe there is a macro with this name */
-#if SIZEOF_UNSIGNED_INT == 8
+#if SIZEOF_UINT64_T == 8
+typedef uint64_t u64;
+#define U64_C(c) (UINT64_C(c))
+#define HAVE_U64_TYPEDEF
+#elif SIZEOF_UNSIGNED_INT == 8
typedef unsigned int u64;
#define U64_C(c) (c ## U)
#define HAVE_U64_TYPEDEF
@@ -113,10 +117,6 @@ typedef unsigned long u64;
typedef unsigned long long u64;
#define U64_C(c) (c ## ULL)
#define HAVE_U64_TYPEDEF
-#elif SIZEOF_UINT64_T == 8
-typedef uint64_t u64;
-#define U64_C(c) (UINT64_C(c))
-#define HAVE_U64_TYPEDEF
#endif
#endif