aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/build-packet.c35
-rw-r--r--g10/gpg.c7
-rw-r--r--g10/gpgv.c7
-rw-r--r--g10/import.c4
-rw-r--r--g10/keydb.h14
-rw-r--r--g10/keyedit.c4
-rw-r--r--g10/keylist.c49
-rw-r--r--g10/main.h1
-rw-r--r--g10/mainproc.c5
-rw-r--r--g10/options.h4
-rw-r--r--g10/packet.h16
-rw-r--r--g10/sign.c71
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 *
diff --git a/g10/gpg.c b/g10/gpg.c
index 296d5fceb..5cd546ba0 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -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