diff --git a/doc/gpg.texi b/doc/gpg.texi index d0aa0100e..a72505f9b 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2933,6 +2933,13 @@ smartcard, and "%%" results in a single "%". %k, %K, and %f are only meaningful when making a key signature (certification), and %c is only meaningful when using the OpenPGP smartcard. +@item --known-notation @var{name} +@opindex known-notation +Adds @var{name} to a list of known critical signature notations. The +effect of this is that gpg will not mark a signature with a critical +signature notation of that name as bad. Note that gpg already knows +by default about a few critical signatures notation names. + @item --sig-policy-url @var{string} @itemx --cert-policy-url @var{string} @itemx --set-policy-url @var{string} diff --git a/g10/gpg.c b/g10/gpg.c index c117de375..e18eefe72 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -109,6 +109,7 @@ enum cmd_and_opt_values oCertNotation, oShowNotation, oNoShowNotation, + oKnownNotation, aEncrFiles, aEncrSym, aDecryptFiles, @@ -673,6 +674,7 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_s (oSetNotation, "set-notation", "@"), ARGPARSE_s_s (oSigNotation, "sig-notation", "@"), ARGPARSE_s_s (oCertNotation, "cert-notation", "@"), + ARGPARSE_s_s (oKnownNotation, "known-notation", "@"), ARGPARSE_group (302, N_( "@\n(See the man page for a complete listing of all commands and options)\n" @@ -3301,6 +3303,7 @@ main (int argc, char **argv) break; case oSigNotation: add_notation_data( pargs.r.ret_str, 0 ); break; case oCertNotation: add_notation_data( pargs.r.ret_str, 1 ); break; + case oKnownNotation: register_known_notation (pargs.r.ret_str); break; case oShowNotation: deprecated_warning(configname,configlineno,"--show-notation", "--list-options ","show-notations"); diff --git a/g10/packet.h b/g10/packet.h index e76e6af4e..6d01b10b5 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -610,6 +610,9 @@ char *issuer_fpr_string (PKT_signature *sig); /*-- parse-packet.c --*/ + +void register_known_notation (const char *string); + /* Sets the packet list mode to MODE (i.e., whether we are dumping a packet or not). Returns the current mode. This allows for temporarily suspending dumping by doing the following: diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 8d0be1983..ff348ec69 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -43,11 +43,15 @@ #define MAX_COMMENT_PACKET_LENGTH ( 64 * 1024) #define MAX_ATTR_PACKET_LENGTH ( 16 * 1024*1024) - static int mpi_print_mode; static int list_mode; static estream_t listfp; +/* A linked list of known notation names. Note that the FLAG is used + * to store the length of the name to speed up the check. */ +static strlist_t known_notations_list; + + static int parse (parse_packet_ctx_t ctx, PACKET *pkt, int onlykeypkts, off_t * retpos, int *skip, IOBUF out, int do_skip #if DEBUG_PARSE_PACKET @@ -186,6 +190,36 @@ mpi_read (iobuf_t inp, unsigned int *ret_nread, int secure) } +/* Register STRING as a known critical notation name. */ +void +register_known_notation (const char *string) +{ + strlist_t sl; + + if (!known_notations_list) + { + sl = add_to_strlist (&known_notations_list, + "preferred-email-encoding@pgp.com"); + sl->flags = 32; + sl = add_to_strlist (&known_notations_list, "pka-address@gnupg.org"); + sl->flags = 21; + } + if (!string) + return; /* Only initialized the default known notations. */ + + /* In --set-notation we use an exclamation mark to indicate a + * critical notation. As a convenience skip this here. */ + if (*string == '!') + string++; + + if (!*string || strlist_find (known_notations_list, string)) + return; /* Empty string or already registered. */ + + sl = add_to_strlist (&known_notations_list, string); + sl->flags = strlen (string); +} + + int set_packet_list_mode (int mode) { @@ -1602,14 +1636,24 @@ parse_one_sig_subpkt (const byte * buffer, size_t n, int type) /* Return true if we understand the critical notation. */ static int -can_handle_critical_notation (const byte * name, size_t len) +can_handle_critical_notation (const byte *name, size_t len) { - if (len == 32 && memcmp (name, "preferred-email-encoding@pgp.com", 32) == 0) - return 1; - if (len == 21 && memcmp (name, "pka-address@gnupg.org", 21) == 0) - return 1; + strlist_t sl; - return 0; + register_known_notation (NULL); /* Make sure it is initialized. */ + + for (sl = known_notations_list; sl; sl = sl->next) + if (sl->flags == len && !memcmp (sl->d, name, len)) + return 1; /* Known */ + + if (opt.verbose) + { + log_info(_("Unknown critical signature notation: ") ); + print_utf8_buffer (log_get_stream(), name, len); + log_printf ("\n"); + } + + return 0; /* Unknown. */ }