diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/build-packet.c | 35 | ||||
-rw-r--r-- | g10/gpg.c | 7 | ||||
-rw-r--r-- | g10/gpgv.c | 7 | ||||
-rw-r--r-- | g10/import.c | 4 | ||||
-rw-r--r-- | g10/keydb.h | 14 | ||||
-rw-r--r-- | g10/keyedit.c | 4 | ||||
-rw-r--r-- | g10/keylist.c | 49 | ||||
-rw-r--r-- | g10/main.h | 1 | ||||
-rw-r--r-- | g10/mainproc.c | 5 | ||||
-rw-r--r-- | g10/options.h | 4 | ||||
-rw-r--r-- | g10/packet.h | 16 | ||||
-rw-r--r-- | g10/sign.c | 71 |
12 files changed, 179 insertions, 38 deletions
diff --git a/g10/build-packet.c b/g10/build-packet.c index 57a67d9f4..0eb83463f 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -1577,17 +1577,18 @@ notation_value_to_human_readable_string (struct notation *notation) return xstrdup (notation->value); } -/* Turn the notation described by the string STRING into a notation. - - STRING has the form: - - -name - Delete the notation. - - [email protected]=value - Normal notation - - [email protected]=value - Notation with critical bit set. - - The caller must free the result using free_notation(). */ +/* Turn the notation described by the string STRING into a notation. + * + * STRING has the form: + * + * - -name - Delete the notation. + * - [email protected]=value - Normal notation + * - [email protected]=value - Notation with critical bit set. + * + * The caller must free the result using free_notation(). */ struct notation * -string_to_notation(const char *string,int is_utf8) +string_to_notation (const char *string, int is_utf8) { const char *s; int saw_at=0; @@ -1676,6 +1677,22 @@ string_to_notation(const char *string,int is_utf8) return NULL; } + +/* Turn the notation described by NAME and VALUE into a notation. + * This will be a human readble non-critical notation. + * The caller must free the result using free_notation(). */ +struct notation * +name_value_to_notation (const char *name, const char *value) +{ + struct notation *notation; + + notation = xcalloc (1, sizeof *notation); + notation->name = xstrdup (name); + notation->value = xstrdup (value); + return notation; +} + + /* Like string_to_notation, but store opaque data rather than human readable data. */ struct notation * @@ -1059,6 +1059,7 @@ static struct compatibility_flags_s compatibility_flags [] = { COMPAT_PARALLELIZED, "parallelized" }, { COMPAT_T7014_OLD, "t7014-old" }, { COMPAT_COMPR_KEYS, "compr-keys" }, + { COMPAT_NO_MANU, "no-manu" }, { 0, NULL } }; @@ -2116,6 +2117,8 @@ parse_list_options(char *str) NULL}, {"show-user-notations",LIST_SHOW_USER_NOTATIONS,NULL, N_("show user-supplied notations during signature listings")}, + {"show-hidden-notations",LIST_SHOW_HIDDEN_NOTATIONS,NULL, + NULL}, {"show-x509-notations",LIST_SHOW_X509_NOTATIONS,NULL, NULL }, {"store-x509-notations",LIST_STORE_X509_NOTATIONS,NULL, NULL }, {"show-keyserver-urls",LIST_SHOW_KEYSERVER_URLS,NULL, @@ -3498,7 +3501,9 @@ main (int argc, char **argv) NULL}, {"show-user-notations",VERIFY_SHOW_USER_NOTATIONS,NULL, N_("show user-supplied notations during signature verification")}, - {"show-keyserver-urls",VERIFY_SHOW_KEYSERVER_URLS,NULL, + {"show-hidden-notations",VERIFY_SHOW_HIDDEN_NOTATIONS,NULL, + NULL}, + {"show-keyserver-urls",VERIFY_SHOW_KEYSERVER_URLS,NULL, N_("show preferred keyserver URLs during signature verification")}, {"show-uid-validity",VERIFY_SHOW_UID_VALIDITY,NULL, N_("show user ID validity during signature verification")}, diff --git a/g10/gpgv.c b/g10/gpgv.c index 6d3d25f50..686fc8891 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -58,6 +58,7 @@ enum cmd_and_opt_values { oQuiet = 'q', oVerbose = 'v', oOutput = 'o', + oPrintNotation = 'N', oBatch = 500, oKeyring, oIgnoreTimeConflict, @@ -91,6 +92,8 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oWeakDigest, "weak-digest", N_("|ALGO|reject signatures made with ALGO")), ARGPARSE_s_n (oEnableSpecialFilenames, "enable-special-filenames", "@"), + ARGPARSE_s_s (oPrintNotation, "print-notation", + N_("|NAME|print the notation NAME to stdout")), ARGPARSE_s_s (oDebug, "debug", "@"), ARGPARSE_s_s (oAssertPubkeyAlgo,"assert-pubkey-algo", "@"), @@ -267,6 +270,10 @@ main( int argc, char **argv ) } break; + case oPrintNotation: + append_to_strlist (&opt.print_notations, pargs.r.ret_str); + break; + default : pargs.err = ARGPARSE_PRINT_ERROR; break; } } diff --git a/g10/import.c b/g10/import.c index 5985d177b..6e33ac976 100644 --- a/g10/import.c +++ b/g10/import.c @@ -3541,7 +3541,9 @@ list_standalone_revocation (ctrl_t ctrl, PKT_signature *sig, int sigrc) show_notation (sig, 3, 0, ((opt.list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) + - ((opt.list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : 0)); + ((opt.list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : 0) + + + ((opt.list_options & LIST_SHOW_HIDDEN_NOTATIONS) ? 4:0)); if (sig->flags.pref_ks && (opt.list_options & LIST_SHOW_KEYSERVER_URLS)) diff --git a/g10/keydb.h b/g10/keydb.h index 68bc81840..255110cc7 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -37,14 +37,14 @@ || IS_SUBKEY_REV(s) \ || IS_ATTST_SIGS(s) ) #define IS_SIG(s) (!IS_CERT(s)) -#define IS_KEY_SIG(s) ((s)->sig_class == 0x1f) -#define IS_UID_SIG(s) (((s)->sig_class & ~3) == 0x10) +#define IS_KEY_SIG(s) ((s)->sig_class == SIGCLASS_KEY) +#define IS_UID_SIG(s) (((s)->sig_class & ~3) == SIGCLASS_CERT) #define IS_ATTST_SIGS(s) ((s)->sig_class == 0x16) -#define IS_SUBKEY_SIG(s) ((s)->sig_class == 0x18) -#define IS_BACK_SIG(s) ((s)->sig_class == 0x19) -#define IS_KEY_REV(s) ((s)->sig_class == 0x20) -#define IS_UID_REV(s) ((s)->sig_class == 0x30) -#define IS_SUBKEY_REV(s) ((s)->sig_class == 0x28) +#define IS_SUBKEY_SIG(s) ((s)->sig_class == SIGCLASS_SUBKEY) +#define IS_BACK_SIG(s) ((s)->sig_class == SIGCLASS_BACKSIG) +#define IS_KEY_REV(s) ((s)->sig_class == SIGCLASS_KEYREV) +#define IS_UID_REV(s) ((s)->sig_class == SIGCLASS_CERTREV) +#define IS_SUBKEY_REV(s) ((s)->sig_class == SIGCLASS_SUBREV) struct getkey_ctx_s; typedef struct getkey_ctx_s *GETKEY_CTX; diff --git a/g10/keyedit.c b/g10/keyedit.c index b0f8ea5ed..1afaad6a9 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -299,7 +299,9 @@ keyedit_print_one_sig (ctrl_t ctrl, estream_t fp, ((opt. list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) + ((opt. - list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : 0)); + list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : 0) + + ((opt. + list_options & LIST_SHOW_HIDDEN_NOTATIONS) ? 4:0)); if (sig->flags.pref_ks && ((opt.list_options & LIST_SHOW_KEYSERVER_URLS) || extended)) diff --git a/g10/keylist.c b/g10/keylist.c index 7bd25de74..42e9f65f5 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -638,6 +638,7 @@ show_keyserver_url (PKT_signature * sig, int indent, int mode) * Defined bits in WHICH: * 1 - standard notations * 2 - user notations + * 4 - print notations normally hidden */ void show_notation (PKT_signature * sig, int indent, int mode, int which) @@ -653,6 +654,9 @@ show_notation (PKT_signature * sig, int indent, int mode, int which) /* There may be multiple notations in the same sig. */ for (nd = notations; nd; nd = nd->next) { + if (!(which & 4) && !strcmp (nd->name, "manu")) + continue; + if (mode != 2) { int has_at = !!strchr (nd->name, '@'); @@ -705,6 +709,41 @@ show_notation (PKT_signature * sig, int indent, int mode, int which) } +/* Output all the notation data in SIG matching a name given by + * --print-notation to stdout. */ +void +print_matching_notations (PKT_signature *sig) +{ + notation_t nd, notations; + strlist_t sl; + const char *s; + + if (!opt.print_notations) + return; + + notations = sig_to_notation (sig); + for (nd = notations; nd; nd = nd->next) + { + for (sl=opt.print_notations; sl; sl = sl->next) + if (!strcmp (sl->d, nd->name)) + break; + if (!sl || !*nd->value) + continue; + es_fprintf (es_stdout, "%s: ", nd->name); + for (s = nd->value; *s; s++) + { + if (*s == '\n') + es_fprintf (es_stdout, "\n%*s", (int)strlen (nd->name)+2, ""); + else if (*s >= ' ' || *s != '\t') + es_putc (*s, es_stdout); + } + es_putc ('\n', es_stdout); + } + + free_notation (notations); +} + + static void print_signature_stats (struct keylist_context *s) { @@ -1522,11 +1561,11 @@ list_signature_print (ctrl_t ctrl, kbnode_t keyblock, kbnode_t node, if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS)) show_notation (sig, 3, 0, ((opt. - list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) - + - ((opt. - list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : - 0)); + list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) + + ((opt. + list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : 0) + + ((opt. + list_options & LIST_SHOW_HIDDEN_NOTATIONS) ? 4 : 0)); if (sig->flags.notation && (opt.list_options diff --git a/g10/main.h b/g10/main.h index c0a3d5fa2..5d96b5e27 100644 --- a/g10/main.h +++ b/g10/main.h @@ -488,6 +488,7 @@ void show_preferences (PKT_user_id *uid, int indent, int mode, int verbose); 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,int which); +void print_matching_notations (PKT_signature *sig); void dump_attribs (const PKT_user_id *uid, PKT_public_key *pk); void set_attrib_fd(int fd); void print_key_info (ctrl_t ctrl, estream_t fp, int indent, diff --git a/g10/mainproc.c b/g10/mainproc.c index ebbe4a6a7..5a7961099 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -2492,9 +2492,12 @@ check_sig_and_print (CTX c, kbnode_t node) show_notation (sig, 0, 1, (((opt.verify_options&VERIFY_SHOW_STD_NOTATIONS)?1:0) - + ((opt.verify_options&VERIFY_SHOW_USER_NOTATIONS)?2:0))); + + ((opt.verify_options&VERIFY_SHOW_USER_NOTATIONS)?2:0) + + ((opt.verify_options &VERIFY_SHOW_HIDDEN_NOTATIONS)? 4:0) + )); else show_notation (sig, 0, 2, 0); + print_matching_notations (sig); } /* Fill PKSTRBUF with the algostring in case we later need it. */ diff --git a/g10/options.h b/g10/options.h index fe81a0baf..28fc2207a 100644 --- a/g10/options.h +++ b/g10/options.h @@ -214,6 +214,7 @@ struct int no_encrypt_to; int encrypt_to_default_key; int interactive; + strlist_t print_notations; /* Name of notations to print. */ struct notation *sig_notations; struct notation *cert_notations; strlist_t sig_policy_url; @@ -400,6 +401,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define COMPAT_PARALLELIZED 1 /* Use threaded hashing for signatures. */ #define COMPAT_T7014_OLD 2 /* Use initial T7014 test data. */ #define COMPAT_COMPR_KEYS 4 /* Allow import of compressed keys. (T7014) */ +#define COMPAT_NO_MANU 8 /* Do not include a "manu" notation. */ /* Compliance test macros. */ #define GNUPG (opt.compliance==CO_GNUPG || opt.compliance==CO_DE_VS) @@ -466,6 +468,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define LIST_STORE_X509_NOTATIONS (1<<18) #define LIST_SHOW_OWNERTRUST (1<<19) #define LIST_SHOW_TRUSTSIG (1<<20) +#define LIST_SHOW_HIDDEN_NOTATIONS (1<<21) #define VERIFY_SHOW_PHOTOS (1<<0) #define VERIFY_SHOW_POLICY_URLS (1<<1) @@ -476,6 +479,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define VERIFY_SHOW_UID_VALIDITY (1<<5) #define VERIFY_SHOW_UNUSABLE_UIDS (1<<6) #define VERIFY_SHOW_PRIMARY_UID_ONLY (1<<9) +#define VERIFY_SHOW_HIDDEN_NOTATIONS (1<<21) #define KEYSERVER_HTTP_PROXY (1<<0) #define KEYSERVER_TIMEOUT (1<<1) diff --git a/g10/packet.h b/g10/packet.h index ac6df7d5c..8162ad802 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -69,6 +69,21 @@ /* The usage bits which define encryption. */ #define PUBKEY_USAGE_XENC_MASK (PUBKEY_USAGE_ENC | PUBKEY_USAGE_RENC) +/* The signature classes. */ +#define SIGCLASS_DATA 0x00 /* Signature on a binary document. */ +#define SIGCLASS_TEXT 0x01 /* Signature on a text document. */ +#define SIGCLASS_SALONE 0x02 /* Standalone signature. */ +#define SIGCLASS_CERT 0x10 /* User ID certification signature. */ +#define SIGCLASS_CERT11 0x11 /* User ID certification signature. */ +#define SIGCLASS_CERT12 0x12 /* User ID certification signature. */ +#define SIGCLASS_CERT13 0x13 /* User ID certification signature. */ +#define SIGCLASS_SUBKEY 0x18 /* Key binding signature. */ +#define SIGCLASS_BACKSIG 0x19 /* Primary key binding signature. */ +#define SIGCLASS_KEY 0x1f /* Direct key signature (on primary key) */ +#define SIGCLASS_KEYREV 0x20 /* Key revoction signature. */ +#define SIGCLASS_SUBREV 0x28 /* Subkey revocation signature. */ +#define SIGCLASS_CERTREV 0x30 /* Certification revocation signature. */ + /* Bitflags to convey hints on what kind of signature is created. */ #define SIGNHINT_KEYSIG 1 #define SIGNHINT_SELFSIG 2 @@ -899,6 +914,7 @@ void build_attribute_subpkt(PKT_user_id *uid,byte type, const void *buf,u32 buflen, const void *header,u32 headerlen); struct notation *string_to_notation(const char *string,int is_utf8); +struct notation *name_value_to_notation (const char *name, const char *value); struct notation *blob_to_notation(const char *name, const char *data, size_t len); struct notation *sig_to_notation(PKT_signature *sig); diff --git a/g10/sign.c b/g10/sign.c index 399d5d76d..b3bda581c 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -66,18 +66,21 @@ typedef struct pt_extra_hash_data_s *pt_extra_hash_data_t; /* - * Create notations and other stuff. It is assumed that the strings in - * STRLIST are already checked to contain only printable data and have - * a valid NAME=VALUE format. + * Create notations and other stuff. It is assumed that the strings + * in STRLIST are already checked to contain only printable data and + * have a valid NAME=VALUE format. If with_manu is set a "manu" + * notation is also added: a value of 1 includes it in the standard + * way and a value of 23 assumes that the data is de-vs compliant. */ static void mk_notation_policy_etc (ctrl_t ctrl, PKT_signature *sig, - PKT_public_key *pk, PKT_public_key *pksk) + PKT_public_key *pk, PKT_public_key *pksk, int with_manu) { const char *string; char *p = NULL; strlist_t pu = NULL; struct notation *nd = NULL; + struct notation *ndmanu = NULL; struct expando_args args; log_assert (sig->version >= 4); @@ -94,6 +97,15 @@ mk_notation_policy_etc (ctrl_t ctrl, PKT_signature *sig, else if (IS_CERT(sig) && opt.cert_notations) nd = opt.cert_notations; + if (with_manu) + { + ndmanu = name_value_to_notation + ("manu", + gnupg_manu_notation_value (with_manu == 23? CO_DE_VS : CO_GNUPG)); + ndmanu->next = nd; + nd = ndmanu; + } + if (nd) { struct notation *item; @@ -113,6 +125,10 @@ mk_notation_policy_etc (ctrl_t ctrl, PKT_signature *sig, xfree (item->altvalue); item->altvalue = NULL; } + /* Restore the original nd and release ndmanu. */ + nd = ndmanu; + ndmanu->next = NULL; + free_notation (ndmanu); } /* Set policy URL. */ @@ -809,7 +825,7 @@ write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass ) /* * Helper to write the plaintext (literal data) packet. At - * R_EXTRAHASH a malloced object with the with the extra data hashed + * R_EXTRAHASH a malloced object with the extra data hashed * into v5 signatures is stored. */ static int @@ -920,7 +936,7 @@ write_plaintext_packet (iobuf_t out, iobuf_t inp, /* * Write the signatures from the SK_LIST to OUT. HASH must be a * non-finalized hash which will not be changes here. EXTRAHASH is - * either NULL or the extra data tro be hashed into v5 signatures. + * either NULL or the extra data to be hashed into v5 signatures. */ static int write_signature_packets (ctrl_t ctrl, @@ -930,6 +946,7 @@ write_signature_packets (ctrl_t ctrl, int status_letter, const char *cache_nonce) { SK_LIST sk_rover; + int with_manu; /* Loop over the certificates with secret keys. */ for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) @@ -966,7 +983,16 @@ write_signature_packets (ctrl_t ctrl, BUG (); build_sig_subpkt_from_sig (sig, pk, 0); - mk_notation_policy_etc (ctrl, sig, NULL, pk); + + if (opt.compliance == CO_DE_VS + && gnupg_rng_is_compliant (CO_DE_VS)) + with_manu = 23; /* FIXME: Also check that the algos are compliant?*/ + else if (!(opt.compat_flags & COMPAT_NO_MANU)) + with_manu = 1; + else + with_manu = 0; + + mk_notation_policy_etc (ctrl, sig, NULL, pk, with_manu); if (opt.flags.include_key_block && IS_SIG (sig)) err = mk_sig_subpkt_key_block (ctrl, sig, pk); else @@ -1813,10 +1839,15 @@ make_keysig_packet (ctrl_t ctrl, gcry_md_hd_t md; u32 pk_keyid[2], pksk_keyid[2]; unsigned int signhints; + int with_manu; - log_assert ((sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x1F - || sigclass == 0x20 || sigclass == 0x18 || sigclass == 0x19 - || sigclass == 0x30 || sigclass == 0x28 ); + log_assert ((sigclass&~3) == SIGCLASS_CERT + || sigclass == SIGCLASS_KEY + || sigclass == SIGCLASS_KEYREV + || sigclass == SIGCLASS_SUBKEY + || sigclass == SIGCLASS_BACKSIG + || sigclass == SIGCLASS_CERTREV + || sigclass == SIGCLASS_SUBREV ); if (pksk->version >= 5) sigversion = 5; @@ -1853,14 +1884,15 @@ make_keysig_packet (ctrl_t ctrl, /* Hash the public key certificate. */ hash_public_key (md, pk); - if (sigclass == 0x18 || sigclass == 0x19 || sigclass == 0x28) + if (sigclass == SIGCLASS_SUBKEY || sigclass == SIGCLASS_BACKSIG + || sigclass == SIGCLASS_SUBREV) { /* Hash the subkey binding/backsig/revocation. */ hash_public_key (md, subpk); if ((subpk->pubkey_usage & PUBKEY_USAGE_RENC)) signhints |= SIGNHINT_ADSK; } - else if (sigclass != 0x1F && sigclass != 0x20) + else if (sigclass != SIGCLASS_KEY && sigclass != SIGCLASS_KEYREV) { /* Hash the user id. */ hash_uid (md, sigversion, uid); @@ -1879,7 +1911,20 @@ make_keysig_packet (ctrl_t ctrl, sig->sig_class = sigclass; build_sig_subpkt_from_sig (sig, pksk, signhints); - mk_notation_policy_etc (ctrl, sig, pk, pksk); + + with_manu = 0; + if ((signhints & SIGNHINT_SELFSIG) /* Only for self-signatures. */ + && ((sigclass&~3) == SIGCLASS_CERT /* on UIDs and subkeys. */ + || sigclass == SIGCLASS_SUBKEY)) + { + if (opt.compliance == CO_DE_VS + && gnupg_rng_is_compliant (CO_DE_VS)) + with_manu = 23; /* Always in de-vs mode. */ + else if (!(opt.compat_flags & COMPAT_NO_MANU)) + with_manu = 1; + } + + mk_notation_policy_etc (ctrl, sig, pk, pksk, with_manu); /* Crucial that the call to mksubpkt comes LAST before the calls * to finalize the sig as that makes it possible for the mksubpkt |