[svn] gpgme - r1105 - in trunk: . doc gpgme tests tests/gpg

svn author marcus cvs at cvs.gnupg.org
Sat Oct 1 04:33:37 CEST 2005


Author: marcus
Date: 2005-10-01 04:33:35 +0200 (Sat, 01 Oct 2005)
New Revision: 1105

Added:
   trunk/gpgme/sig-notation.c
   trunk/tests/gpg/gpg.conf
   trunk/tests/gpg/t-sig-notation.c
Modified:
   trunk/NEWS
   trunk/TODO
   trunk/doc/ChangeLog
   trunk/doc/gpgme.texi
   trunk/gpgme/ChangeLog
   trunk/gpgme/Makefile.am
   trunk/gpgme/context.h
   trunk/gpgme/data.h
   trunk/gpgme/gpgme.c
   trunk/gpgme/gpgme.def
   trunk/gpgme/gpgme.h
   trunk/gpgme/libgpgme.vers
   trunk/gpgme/ops.h
   trunk/gpgme/rungpg.c
   trunk/gpgme/verify.c
   trunk/tests/ChangeLog
   trunk/tests/gpg/Makefile.am
   trunk/tests/gpg/t-verify.c
Log:
doc/
2005-10-01  Marcus Brinkmann  <marcus at g10code.de>

	* gpgme.texi (Signature Notation Data): New section.
	(Verify): Added more about the notation data structure.

gpgme/
2005-10-01  Marcus Brinkmann  <marcus at g10code.de>

	* gpgme.def: Add gpgme_data_set_file_name,
	gpgme_data_get_file_name, gpgme_sig_notation_clear,
	gpgme_sig_notation_add and gpgme_sig_notation_get.
	* libgpgme.vers: Add gpgme_sig_notation_clear,
	gpgme_sig_notation_add and gpgme_sig_notation_get.
	* Makefile.am (libgpgme_real_la_SOURCES): Add sig-notation.c.
	* context.h (struct gpgme_context): New field sig_notations.
	* gpgme.h (struct _gpgme_sig_notation): New member value_len and
	critical.
	(GPGME_SIG_NOTATION_CRITICAL): New symbol.
	(gpgme_sig_notation_flags_t): New type.
	(gpgme_sig_notation_add, gpgme_sig_notation_clear,
	gpgme_sig_notation_get): New prototypes.
	* ops.h (_gpgme_sig_notation_create, _gpgme_sig_notation_free):
	New prototypes.
	* sig-notation.c (_gpgme_sig_notation_free): New file.
	* verify.c (parse_notation): Use support functions.
	(release_op_data): Likewise.
	* rungpg.c (append_args_from_sig_notations): New function.
	(gpg_encrypt_sign, gpg_sign): Call it.


tests/
2005-10-01  Marcus Brinkmann  <marcus at g10code.de>

	* gpg/Makefile.am (TESTS): Add t-sig-notation.
	* gpg/t-sig-notation.c (check_result): New file.
	* gpg/t-verify.c (check_result): Also check the length of the
	notation data.
	* gpg/gpg.conf: New file.


Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/NEWS	2005-10-01 02:33:35 UTC (rev 1105)
@@ -33,10 +33,13 @@
    to local government regulations.
 
  * You can associate a filename with a data object using the new
-   gpgme_data_set_filename() function.  This filename will be stored
+   function gpgme_data_set_filename().  This filename will be stored
    in the output when encrypting or signing the data and will be
    returned when decrypting or verifying the output data.
 
+ * You can now set notation data at signature creation with the new
+   function gpgme_sig_notation_add().
+
  * Interface changes relative to the 1.0.3 release:
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 gpgme_set_engine_info		NEW
@@ -51,6 +54,12 @@
 gpgme_key_t			EXTENDED: New field is_qualified.
 gpgme_subkey_t			EXTENDED: New field is_qualified.
 gpgme_data_set_filename		NEW
+gpgme_sig_notation_flags_t	NEW
+GPGME_SIG_NOTATION_HUMAN_READABLE NEW
+GPGME_SIG_NOTATAION_CRITICAL	NEW
+gpgme_sig_notation_clear	NEW
+gpgme_sig_notation_add		NEW
+gpgme_sig_notation_get		NEW
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 

Modified: trunk/TODO
===================================================================
--- trunk/TODO	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/TODO	2005-10-01 02:33:35 UTC (rev 1105)
@@ -37,6 +37,8 @@
    There is a configure time warning, though.
 
 * New features:
+** Extended notation support.  When gpg supports arbitrary binary
+   notation data, provide a user interface for that.
 ** notification system
    We need a simple notification system, probably a simple callback
    with a string and some optional arguments.  This is for example

Modified: trunk/doc/ChangeLog
===================================================================
--- trunk/doc/ChangeLog	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/doc/ChangeLog	2005-10-01 02:33:35 UTC (rev 1105)
@@ -1,3 +1,8 @@
+2005-10-01  Marcus Brinkmann  <marcus at g10code.de>
+
+	* gpgme.texi (Signature Notation Data): New section.
+	(Verify): Added more about the notation data structure.
+
 2005-09-30  Marcus Brinkmann  <marcus at g10code.de>
 
 	* gpgme.texi (Data Buffer I/O Operations, Data Buffer Meta-Data):

Modified: trunk/doc/gpgme.texi
===================================================================
--- trunk/doc/gpgme.texi	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/doc/gpgme.texi	2005-10-01 02:33:35 UTC (rev 1105)
@@ -209,6 +209,7 @@
 
 * Selecting Signers::             How to choose the keys to sign with.
 * Creating a Signature::          How to create a signature.
+* Signature Notation Data::       How to add notation data to a signature.
 
 Encrypt
 
@@ -3753,6 +3754,8 @@
 @cindex signature, verification
 @cindex cryptographic operation, verification
 @cindex cryptographic operation, signature check
+ at cindex signature notation data
+ at cindex notation data
 
 @deftypefun gpgme_error_t gpgme_op_verify (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_data_t @var{sig}}, @w{gpgme_data_t @var{signed_text}}, @w{gpgme_data_t @var{plain}})
 The function @code{gpgme_op_verify} verifies that the signature in the
@@ -3801,10 +3804,46 @@
 The name of the notation field.  If this is @code{NULL}, then the
 member @code{value} will contain a policy URL.
 
+ at item int name_len
+The length of the @code{name} field.  For strings the length is
+counted without the trailing binary zero.
+
 @item char *value
 The value of the notation field.  If @code{name} is @code{NULL}, then
 this is a policy URL.
+
+ at item int value_len
+The length of the @code{value} field.  For strings the length is
+counted without the trailing binary zero.
+
+ at item gpgme_sig_notation_flags_t flags
+The accumulated flags field.  This field contains the flags associated
+with the notation data in an accumulated form which can be used as an
+argument to the function @code{gpgme_sig_notation_add}.  The value
+ at code{flags} is a bitwise-or combination of one or multiple of the
+following bit values:
+
+ at table @code
+ at item GPGME_SIG_NOTATION_HUMAN_READABLE
+The @code{GPGME_SIG_NOTATION_HUMAN_READABLE} symbol specifies that the
+notation data is in human readable form
+
+ at item GPGME_SIG_NOTATION_CRITICAL
+The @code{GPGME_SIG_NOTATION_CRITICAL} symbol specifies that the
+notation data is critical.
+
 @end table
+
+ at item unsigned int human_readable : 1
+This is true if the @code{GPGME_SIG_NOTATION_HUMAN_READABLE} flag is
+set and false otherwise.  This flag is only valid for notation data,
+not for policy URLs.
+
+ at item unsigned int critical : 1
+This is true if the @code{GPGME_SIG_NOTATION_CRITICAL} flag is set and
+false otherwise.  This flag is valid for notation data and policy URLs.
+
+ at end table
 @end deftp
 
 @deftp {Data type} {gpgme_signature_t}
@@ -4258,6 +4297,7 @@
 @menu
 * Selecting Signers::             How to choose the keys to sign with.
 * Creating a Signature::          How to create a signature.
+* Signature Notation Data::       How to add notation data to a signature.
 @end menu
 
 
@@ -4406,6 +4446,58 @@
 @end deftypefun
 
 
+ at node Signature Notation Data
+ at subsubsection Signature Notation Data
+ at cindex notation data
+ at cindex signature notation data
+ at cindex policy URL
+
+Using the following functions, you can attach arbitrary notation data
+to a signature.  This information is then available to the user when
+the signature is verified.
+
+ at deftypefun void gpgme_sig_notation_clear (@w{gpgme_ctx_t @var{ctx}})
+The function @code{gpgme_sig_notation_clear} removes the notation data
+from the context @var{ctx}.  Subsequent signing operations from this
+context will not include any notation data.
+
+Every context starts with an empty notation data list.
+ at end deftypefun
+
+ at deftypefun gpgme_error_t gpgme_sig_notation_add (@w{gpgme_ctx_t @var{ctx}}, @w{const char *@var{name}}, @w{const char *@var{value}}, @w{gpgme_sig_notation_flags_t @var{flags}})
+The function @code{gpgme_sig_notation_add} adds the notation data with
+the name @var{name} and the value @var{value} to the context
+ at var{ctx}.
+
+Subsequent signing operations will include this notation data, as well
+as any other notation data that was added since the creation of the
+context or the last @code{gpgme_sig_notation_clear} operation.
+
+The arguments @var{name} and @var{value} must be @code{NUL}-terminated
+strings in human-readable form.  The flag
+ at code{GPGME_SIG_NOTATION_HUMAN_READABLE} is implied
+(non-human-readable notation data is currently not supported).  The
+strings must be in UTF-8 encoding.
+
+If @var{name} is @code{NULL}, then @var{value} should be a policy URL.
+
+The function @code{gpgme_sig_notation_add} returns the error code
+ at code{GPG_ERR_NO_ERROR} if the notation data could be added
+successfully, @code{GPG_ERR_INV_VALUE} if @var{ctx} is not a valid
+pointer, or if @var{name}, @var{value} and @var{flags} are an invalid
+combination.  The function also passes through any errors that are
+reported by the crypto engine support routines.
+ at end deftypefun
+
+ at deftypefun gpgme_sig_notation_t gpgme_sig_notation_get (@w{const gpgme_ctx_t @var{ctx}})
+The function @code{gpgme_sig_notation_get} returns the linked list of
+notation data structures that are contained in the context @var{ctx}.
+
+If @var{ctx} is not a valid pointer, or there is no notation data
+added for this context, @code{NULL} is returned.
+ at end deftypefun
+
+
 @node Encrypt
 @subsection Encrypt
 @cindex encryption

Modified: trunk/gpgme/ChangeLog
===================================================================
--- trunk/gpgme/ChangeLog	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/gpgme/ChangeLog	2005-10-01 02:33:35 UTC (rev 1105)
@@ -1,3 +1,26 @@
+2005-10-01  Marcus Brinkmann  <marcus at g10code.de>
+
+	* gpgme.def: Add gpgme_data_set_file_name,
+	gpgme_data_get_file_name, gpgme_sig_notation_clear,
+	gpgme_sig_notation_add and gpgme_sig_notation_get.
+	* libgpgme.vers: Add gpgme_sig_notation_clear,
+	gpgme_sig_notation_add and gpgme_sig_notation_get.
+	* Makefile.am (libgpgme_real_la_SOURCES): Add sig-notation.c.
+	* context.h (struct gpgme_context): New field sig_notations.
+	* gpgme.h (struct _gpgme_sig_notation): New member value_len and
+	critical.
+	(GPGME_SIG_NOTATION_CRITICAL): New symbol.
+	(gpgme_sig_notation_flags_t): New type.
+	(gpgme_sig_notation_add, gpgme_sig_notation_clear,
+	gpgme_sig_notation_get): New prototypes.
+	* ops.h (_gpgme_sig_notation_create, _gpgme_sig_notation_free):
+	New prototypes.
+	* sig-notation.c (_gpgme_sig_notation_free): New file.
+	* verify.c (parse_notation): Use support functions.
+	(release_op_data): Likewise.
+	* rungpg.c (append_args_from_sig_notations): New function.
+	(gpg_encrypt_sign, gpg_sign): Call it.
+
 2005-09-30  Marcus Brinkmann  <marcus at g10code.de>
 
 	* data.h (struct gpgme_data): New member file_name.

Modified: trunk/gpgme/Makefile.am
===================================================================
--- trunk/gpgme/Makefile.am	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/gpgme/Makefile.am	2005-10-01 02:33:35 UTC (rev 1105)
@@ -72,7 +72,7 @@
 	gpgme.h util.h conversion.c get-env.c context.h ops.h		\
 	data.h data.c data-fd.c data-stream.c data-mem.c data-user.c	\
 	data-compat.c							\
-	signers.c							\
+	signers.c sig-notation.c					\
 	wait.c wait-global.c wait-private.c wait-user.c wait.h		\
 	op-support.c							\
 	encrypt.c encrypt-sign.c decrypt.c decrypt-verify.c verify.c	\

Modified: trunk/gpgme/context.h
===================================================================
--- trunk/gpgme/context.h	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/gpgme/context.h	2005-10-01 02:33:35 UTC (rev 1105)
@@ -1,6 +1,6 @@
 /* context.h - Definitions for a GPGME context.
    Copyright (C) 2000 Werner Koch (dd9jn)
-   Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH
 
    This file is part of GPGME.
  
@@ -91,6 +91,9 @@
   unsigned int signers_size;
   gpgme_key_t *signers;
 
+  /* The signature notations for this context.  */
+  gpgme_sig_notation_t sig_notations;
+
   /* The locale for the pinentry.  */
   char *lc_ctype;
   char *lc_messages;

Modified: trunk/gpgme/data.h
===================================================================
--- trunk/gpgme/data.h	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/gpgme/data.h	2005-10-01 02:33:35 UTC (rev 1105)
@@ -1,5 +1,5 @@
 /* data.h - Internal data object abstraction interface.
-   Copyright (C) 2002, 2004 g10 Code GmbH
+   Copyright (C) 2002, 2004, 2005 g10 Code GmbH
  
    This file is part of GPGME.
  

Modified: trunk/gpgme/gpgme.c
===================================================================
--- trunk/gpgme/gpgme.c	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/gpgme/gpgme.c	2005-10-01 02:33:35 UTC (rev 1105)
@@ -430,6 +430,71 @@
 }
 
 
+/* Clear all notation data from the context.  */
+void
+gpgme_sig_notation_clear (gpgme_ctx_t ctx)
+{
+  gpgme_sig_notation_t notation;
+
+  if (!ctx)
+    return;
+
+  notation = ctx->sig_notations;
+  while (notation)
+    {
+      gpgme_sig_notation_t next_notation = notation->next;
+      _gpgme_sig_notation_free (notation);
+      notation = next_notation;
+    }
+}
+
+
+/* Add the human-readable notation data with name NAME and value VALUE
+   to the context CTX, using the flags FLAGS.  If NAME is NULL, then
+   VALUE should be a policy URL.  The flag
+   GPGME_SIG_NOTATION_HUMAN_READABLE is forced to be true for notation
+   data, and false for policy URLs.  */
+gpgme_error_t
+gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name,
+			const char *value, gpgme_sig_notation_flags_t flags)
+{
+  gpgme_error_t err;
+  gpgme_sig_notation_t notation;
+  gpgme_sig_notation_t *lastp;
+
+  if (!ctx)
+     gpg_error (GPG_ERR_INV_VALUE);
+
+  if (name)
+    flags |= GPGME_SIG_NOTATION_HUMAN_READABLE;
+  else
+    flags &= ~GPGME_SIG_NOTATION_HUMAN_READABLE;
+
+  err = _gpgme_sig_notation_create (&notation, name, name ? strlen (name) : 0,
+				    value, value ? strlen (value) : 0, flags);
+  if (err)
+    return err;
+
+  lastp = &ctx->sig_notations;
+  while (*lastp)
+    lastp = &(*lastp)->next;
+
+  *lastp = notation;
+  return 0;
+}
+
+
+/* Get the sig notations for this context.  */
+gpgme_sig_notation_t
+gpgme_sig_notation_get (gpgme_ctx_t ctx)
+{
+  if (!ctx)
+    return NULL;
+
+  return ctx->sig_notations;
+}
+  
+
 const char *
 gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
 {

Modified: trunk/gpgme/gpgme.def
===================================================================
--- trunk/gpgme/gpgme.def	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/gpgme/gpgme.def	2005-10-01 02:33:35 UTC (rev 1105)
@@ -144,5 +144,12 @@
     gpgme_ctx_get_engine_info             @113 
     gpgme_ctx_set_engine_info             @114
 
+    gpgme_data_set_file_name		  @115
+    gpgme_data_get_file_name		  @116
+
+    gpgme_sig_notation_clear		  @117
+    gpgme_sig_notation_add		  @118
+    gpgme_sig_notation_get		  @119
+
 ; END
 

Modified: trunk/gpgme/gpgme.h
===================================================================
--- trunk/gpgme/gpgme.h	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/gpgme/gpgme.h	2005-10-01 02:33:35 UTC (rev 1105)
@@ -1,6 +1,6 @@
 /* gpgme.h - Public interface to GnuPG Made Easy.
    Copyright (C) 2000 Werner Koch (dd9jn)
-   Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH
 
    This file is part of GPGME.
  
@@ -313,6 +313,46 @@
 typedef unsigned int gpgme_keylist_mode_t;
 
 
+/* Signature notations.  */
+
+/* The available signature notation flags.  */
+#define GPGME_SIG_NOTATION_HUMAN_READABLE	1
+#define GPGME_SIG_NOTATION_CRITICAL		2
+
+typedef unsigned int gpgme_sig_notation_flags_t;
+
+struct _gpgme_sig_notation
+{
+  struct _gpgme_sig_notation *next;
+
+  /* If NAME is a null pointer, then VALUE contains a policy URL
+     rather than a notation.  */
+  char *name;
+
+  /* The value of the notation data.  */
+  char *value;
+
+  /* The length of the name of the notation data.  */
+  int name_len;
+
+  /* The length of the value of the notation data.  */
+  int value_len;
+
+  /* The accumulated flags.  */
+  gpgme_sig_notation_flags_t flags;
+
+  /* Notation data is human-readable.  */
+  unsigned int human_readable : 1;
+
+  /* Notation data is critical.  */
+  unsigned int critical : 1;
+
+  /* Internal to GPGME, do not use.  */
+  int _unused : 30;
+};
+typedef struct _gpgme_sig_notation *gpgme_sig_notation_t;
+
+
 /* The possible stati for the edit operation.  */
 typedef enum
   {
@@ -819,6 +859,22 @@
      _GPGME_DEPRECATED;
 
 
+/* Clear all notation data from the context.  */
+void gpgme_sig_notation_clear (gpgme_ctx_t ctx);
+
+/* Add the human-readable notation data with name NAME and value VALUE
+   to the context CTX, using the flags FLAGS.  If NAME is NULL, then
+   VALUE should be a policy URL.  The flag
+   GPGME_SIG_NOTATION_HUMAN_READABLE is forced to be true for notation
+   data, and false for policy URLs.  */
+gpgme_error_t gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name,
+				      const char *value,
+				      gpgme_sig_notation_flags_t flags);
+
+/* Get the sig notations for this context.  */
+gpgme_sig_notation_t gpgme_sig_notation_get (gpgme_ctx_t ctx);
+
+
 /* Run control.  */
 
 /* The type of an I/O callback function.  */
@@ -1209,17 +1265,7 @@
 
 
 /* Verify.  */
-struct _gpgme_sig_notation
-{
-  struct _gpgme_sig_notation *next;
 
-  /* If NAME is a null pointer, then VALUE contains a policy URL
-     rather than a notation.  */
-  char *name;
-  char *value;
-};
-typedef struct _gpgme_sig_notation *gpgme_sig_notation_t;
-
 /* Flags used for the SUMMARY field in a gpgme_signature_t.  */
 typedef enum
   {

Modified: trunk/gpgme/libgpgme.vers
===================================================================
--- trunk/gpgme/libgpgme.vers	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/gpgme/libgpgme.vers	2005-10-01 02:33:35 UTC (rev 1105)
@@ -1,5 +1,5 @@
 # libgpgme.vers - List of symbols to export.
-# Copyright (C) 2002, 2004 g10 Code GmbH
+# Copyright (C) 2002, 2004, 2005 g10 Code GmbH
 #
 # This file is part of GPGME.
 #
@@ -30,6 +30,10 @@
 
     gpgme_data_set_file_name;
     gpgme_data_get_file_name;
+
+    gpgme_sig_notation_clear;
+    gpgme_sig_notation_add;
+    gpgme_sig_notation_get;
 };
 
 

Modified: trunk/gpgme/ops.h
===================================================================
--- trunk/gpgme/ops.h	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/gpgme/ops.h	2005-10-01 02:33:35 UTC (rev 1105)
@@ -1,6 +1,6 @@
 /* ops.h - Internal operation support.
    Copyright (C) 2000 Werner Koch (dd9jn)
-   Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH
  
    This file is part of GPGME.
  
@@ -138,11 +138,26 @@
 				   void *type_data);
 
 
-/*-- version.c --*/
+/* From version.c.  */
+
 /* Return true if MY_VERSION is at least REQ_VERSION, and false
    otherwise.  */
 int _gpgme_compare_versions (const char *my_version,
 			     const char *req_version);
 char *_gpgme_get_program_version (const char *const path);
 
+
+/* From sig-notation.c.  */
+
+/* Create a new, empty signature notation data object.  */
+gpgme_error_t _gpgme_sig_notation_create (gpgme_sig_notation_t *notationp,
+					  const char *name, int name_len,
+					  const char *value, int value_len,
+					  gpgme_sig_notation_flags_t flags);
+
+/* Free the signature notation object and all associated resources.
+   The object must already be removed from any linked list as the next
+   pointer is ignored.  */
+void _gpgme_sig_notation_free (gpgme_sig_notation_t notation);
+
 #endif /* OPS_H */

Modified: trunk/gpgme/rungpg.c
===================================================================
--- trunk/gpgme/rungpg.c	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/gpgme/rungpg.c	2005-10-01 02:33:35 UTC (rev 1105)
@@ -1256,6 +1256,91 @@
 
 
 static gpgme_error_t
+append_args_from_sig_notations (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
+{
+  gpgme_error_t err = 0;
+  gpgme_sig_notation_t notation;
+
+  notation = gpgme_sig_notation_get (ctx);
+
+  while (!err && notation)
+    {
+      if (notation->name
+	  && !(notation->flags & GPGME_SIG_NOTATION_HUMAN_READABLE))
+	err = gpg_error (GPG_ERR_INV_VALUE);
+      else if (notation->name)
+	{
+	  char *arg;
+
+	  /* Maximum space needed is one byte for the "critical" flag,
+	     the name, one byte for '=', the value, and a terminating
+	     '\0'.  */
+
+	  arg = malloc (1 + notation->name_len + 1 + notation->value_len + 1);
+	  if (!arg)
+	    err = gpg_error_from_errno (errno);
+
+	  if (!err)
+	    {
+	      char *argp = arg;
+
+	      if (notation->critical)
+		*(argp++) = '!';
+
+	      memcpy (argp, notation->name, notation->name_len);
+	      argp += notation->name_len;
+
+	      *(argp++) = '=';
+
+	      /* We know that notation->name is '\0' terminated.  */
+	      strcpy (argp, notation->value);
+	    }
+
+	  if (!err)
+	    err = add_arg (gpg, "--sig-notation");
+	  if (!err)
+	    err = add_arg (gpg, arg);
+
+	  if (arg)
+	    free (arg);
+	}
+      else
+	{
+	  /* This is a policy URL.  */
+
+	  char *value;
+
+	  if (notation->critical)
+	    {
+	      value = malloc (1 + notation->value_len + 1);
+	      if (!value)
+		err = gpg_error_from_errno (errno);
+	      else
+		{
+		  value[0] = '!';
+		  /* We know that notation->value is '\0' terminated.  */
+		  strcpy (&value[1], notation->value);
+		}
+	    }
+	  else
+	    value = notation->value;
+
+	  if (!err)
+	    err = add_arg (gpg, "--sig-policy-url");
+	  if (!err)
+	    err = add_arg (gpg, value);
+
+	  if (value != notation->value)
+	    free (value);
+      	}
+
+      notation = notation->next;
+    }
+  return err;
+}
+
+
+static gpgme_error_t
 gpg_edit (void *engine, int type, gpgme_key_t key, gpgme_data_t out,
 	  gpgme_ctx_t ctx /* FIXME */)
 {
@@ -1383,6 +1468,8 @@
 
   if (!err)
     err = append_args_from_signers (gpg, ctx);
+  if (!err)
+    err = append_args_from_sig_notations (gpg, ctx);
 
   /* Tell the gpg object about the data.  */
   if (!err)
@@ -1608,6 +1695,8 @@
 
   if (!err)
     err = append_args_from_signers (gpg, ctx);
+  if (!err)
+    err = append_args_from_sig_notations (gpg, ctx);
 
   if (gpgme_data_get_file_name (in))
     {

Added: trunk/gpgme/sig-notation.c
===================================================================
--- trunk/gpgme/sig-notation.c	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/gpgme/sig-notation.c	2005-10-01 02:33:35 UTC (rev 1105)
@@ -0,0 +1,123 @@
+/* sig-notation.c - Signature notation data support.
+   Copyright (C) 2005 g10 Code GmbH
+
+   This file is part of GPGME.
+ 
+   GPGME is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+   
+   GPGME is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+   
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "gpgme.h"
+#include "util.h"
+#include "context.h"
+#include "ops.h"
+
+
+/* Free the signature notation object and all associated resources.
+   The object must already be removed from any linked list as the next
+   pointer is ignored.  */
+void
+_gpgme_sig_notation_free (gpgme_sig_notation_t notation)
+{
+  if (notation->name)
+    free (notation->name);
+
+  if (notation->value)
+    free (notation->value);
+
+  free (notation);
+}
+
+
+/* Set the flags of NOTATION to FLAGS.  */
+static void
+sig_notation_set_flags (gpgme_sig_notation_t notation,
+			gpgme_sig_notation_flags_t flags)
+{
+  /* We copy the flags into individual bits to make them easier
+     accessible individually for the user.  */
+  notation->human_readable = flags & GPGME_SIG_NOTATION_HUMAN_READABLE ? 1 : 0;
+  notation->critical = flags & GPGME_SIG_NOTATION_CRITICAL ? 1 : 0; 
+
+  notation->flags = flags;
+}
+
+
+/* Create a new, empty signature notation data object.  */
+gpgme_error_t
+_gpgme_sig_notation_create (gpgme_sig_notation_t *notationp,
+			    const char *name, int name_len,
+			    const char *value, int value_len,
+			    gpgme_sig_notation_flags_t flags)
+{
+  gpgme_error_t err = 0;
+  gpgme_sig_notation_t notation;
+
+  /* Currently, we require all notations to be human-readable.  */
+  if (name && !(flags & GPGME_SIG_NOTATION_HUMAN_READABLE))
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  notation = calloc (1, sizeof (*notation));
+  if (!notation)
+    return gpg_error_from_errno (errno);
+
+  if (name_len)
+    {
+      /* We add a trailing '\0' for stringification in the good
+	 case.  */
+      notation->name = malloc (name_len + 1);
+      if (!notation->name)
+	{
+	  err = gpg_error_from_errno (errno);
+	  goto err;
+	}
+
+      memcpy (notation->name, name, name_len);
+      notation->name[name_len] = '\0';
+      notation->name_len = name_len;
+    }
+
+  if (value_len)
+    {
+      /* We add a trailing '\0' for stringification in the good
+	 case.  */
+      notation->value = malloc (value_len + 1);
+      if (!notation->value)
+	{
+	  err = gpg_error_from_errno (errno);
+	  goto err;
+	}
+
+      memcpy (notation->value, value, value_len);
+      notation->value[value_len] = '\0';
+      notation->value_len = value_len;
+    }
+
+  sig_notation_set_flags (notation, flags);
+
+  *notationp = notation;
+  return 0;
+
+ err:
+  _gpgme_sig_notation_free (notation);
+  return err;
+}

Modified: trunk/gpgme/verify.c
===================================================================
--- trunk/gpgme/verify.c	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/gpgme/verify.c	2005-10-01 02:33:35 UTC (rev 1105)
@@ -1,6 +1,6 @@
 /* verify.c - Signature verification.
    Copyright (C) 2000 Werner Koch (dd9jn)
-   Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH
+   Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH
 
    This file is part of GPGME.
  
@@ -58,10 +58,7 @@
 	{
 	  gpgme_sig_notation_t next_nota = notation->next;
 
-	  if (notation->name)
-	    free (notation->name);
-	  if (notation->value)
-	    free (notation->value);
+	  _gpgme_sig_notation_free (notation);
 	  notation = next_nota;
 	}
 
@@ -431,51 +428,39 @@
 	   previous one.  The crypto backend misbehaves.  */
 	return gpg_error (GPG_ERR_INV_ENGINE);
 
-      notation = malloc (sizeof (*sig));
-      if (!notation)
-	return gpg_error_from_errno (errno);
-      notation->next = NULL;
+      err = _gpgme_sig_notation_create (&notation, NULL, 0, NULL, 0, 0);
+      if (err)
+	return err;
 
       if (code == GPGME_STATUS_NOTATION_NAME)
 	{
-	  int len = strlen (args) + 1;
-
-	  notation->name = malloc (len);
-	  if (!notation->name)
-	    {
-	      int saved_errno = errno;
-	      free (notation);
-	      return gpg_error_from_errno (saved_errno);
-	    }
-	  err = _gpgme_decode_percent_string (args, &notation->name, len);
+	  err = _gpgme_decode_percent_string (args, &notation->name, 0);
 	  if (err)
 	    {
-	      free (notation->name);
-	      free (notation);
+	      _gpgme_sig_notation_free (notation);
 	      return err;
 	    }
 
-	  notation->value = NULL;
+	  notation->name_len = strlen (notation->name);
+
+	  /* FIXME: For now we fake the human-readable flag.  The
+	     critical flag can not be reported as it is not
+	     provided.  */
+	  notation->flags = GPGME_SIG_NOTATION_HUMAN_READABLE;
+	  notation->human_readable = 1;
 	}
       else
 	{
-	  int len = strlen (args) + 1;
+	  /* This is a policy URL.  */
 
-	  notation->name = NULL;
-	  notation->value = malloc (len);
-	  if (!notation->value)
-	    {
-	      int saved_errno = errno;
-	      free (notation);
-	      return gpg_error_from_errno (saved_errno);
-	    }
-	  err = _gpgme_decode_percent_string (args, &notation->value, len);
+	  err = _gpgme_decode_percent_string (args, &notation->value, 0);
 	  if (err)
 	    {
-	      free (notation->value);
-	      free (notation);
+	      _gpgme_sig_notation_free (notation);
 	      return err;
 	    }
+
+	  notation->value_len = strlen (notation->value);
 	}
       *lastp = notation;
     }
@@ -515,6 +500,8 @@
       err = _gpgme_decode_percent_string (args, &dest, len);
       if (err)
 	return err;
+
+      notation->value_len += strlen (dest);
     }
   else
     return gpg_error (GPG_ERR_INV_ENGINE);

Modified: trunk/tests/ChangeLog
===================================================================
--- trunk/tests/ChangeLog	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/tests/ChangeLog	2005-10-01 02:33:35 UTC (rev 1105)
@@ -1,3 +1,11 @@
+2005-10-01  Marcus Brinkmann  <marcus at g10code.de>
+
+	* gpg/Makefile.am (TESTS): Add t-sig-notation.
+	* gpg/t-sig-notation.c (check_result): New file.
+	* gpg/t-verify.c (check_result): Also check the length of the
+	notation data.
+	* gpg/gpg.conf: New file.
+
 2005-09-30  Marcus Brinkmann  <marcus at g10code.de>
 
 	* gpg/Makefile.am (TESTS): Add t-filename.

Modified: trunk/tests/gpg/Makefile.am
===================================================================
--- trunk/tests/gpg/Makefile.am	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/tests/gpg/Makefile.am	2005-10-01 02:33:35 UTC (rev 1105)
@@ -26,7 +26,7 @@
 # The keylist tests must come after the import and the edit test.
 noinst_HEADERS = t-support.h
 TESTS = t-encrypt t-encrypt-sym t-encrypt-sign t-sign t-signers	\
-	t-decrypt t-verify t-decrypt-verify \
+	t-decrypt t-verify t-decrypt-verify t-sig-notation \
 	t-export t-import t-trustlist t-eventloop t-edit \
 	t-keylist t-keylist-sig t-thread1 t-wait t-encrypt-large \
 	t-file-name

Added: trunk/tests/gpg/gpg.conf
===================================================================
--- trunk/tests/gpg/gpg.conf	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/tests/gpg/gpg.conf	2005-10-01 02:33:35 UTC (rev 1105)
@@ -0,0 +1,27 @@
+# Options for GnuPG
+# Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Unless you specify which option file to use (with the command line
+# option "--options filename"), GnuPG uses the file ~/.gnupg/gpg.conf
+# by default.
+#
+# An options file can contain any long options which are available in
+# GnuPG. If the first non white space character of a line is a '#',
+# this line is ignored.  Empty lines are also ignored.
+#
+# See the man page for a list of options.
+
+# By default GnuPG creates version 3 signatures for data files.  This
+# is not strictly OpenPGP compliant but PGP 6 and most versions of PGP
+# 7 require them.  To disable this behavior, you may use this option
+# or --openpgp.
+
+no-force-v3-sigs

Added: trunk/tests/gpg/t-sig-notation.c
===================================================================
--- trunk/tests/gpg/t-sig-notation.c	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/tests/gpg/t-sig-notation.c	2005-10-01 02:33:35 UTC (rev 1105)
@@ -0,0 +1,166 @@
+/* t-sig-notation.c - Regression test.
+   Copyright (C) 2005 g10 Code GmbH
+
+   This file is part of GPGME.
+ 
+   GPGME is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+   
+   GPGME is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+   
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+/* We need to include config.h so that we know whether we are building
+   with large file system (LFS) support. */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <gpgme.h>
+
+#include "t-support.h"
+
+
+static struct {
+  const char *name;
+  const char *value;
+  gpgme_sig_notation_flags_t flags;
+  int seen;
+} expected_notations[] = { 
+  { "laughing at me",
+    "Just Squeeze Me",
+    GPGME_SIG_NOTATION_HUMAN_READABLE },
+  { "leave at home",
+    "Right Now",
+    GPGME_SIG_NOTATION_HUMAN_READABLE | GPGME_SIG_NOTATION_CRITICAL },
+  { NULL, 
+    "http://www.gnu.org/policy/",
+    0 }
+};
+
+static void
+check_result (gpgme_verify_result_t result)
+{
+  int i;
+  gpgme_sig_notation_t r;
+  
+  gpgme_signature_t sig;
+
+  sig = result->signatures;
+  if (!sig || sig->next)
+    {
+      fprintf (stderr, "%s:%i: Unexpected number of signatures\n",
+	       __FILE__, __LINE__);
+      exit (1);
+    }
+
+  for (i=0; i < DIM(expected_notations); i++ )
+    expected_notations[i].seen = 0;
+  
+  for (r = result->signatures->notations; r; r = r->next)
+    {
+      int any = 0;
+      for (i=0; i < DIM(expected_notations); i++)
+	{
+	  if ( ((r->name && expected_notations[i].name
+		 && !strcmp (r->name, expected_notations[i].name)
+		 && r->name_len
+		 == strlen (expected_notations[i].name))
+		|| (!r->name && !expected_notations[i].name
+		    && r->name_len == 0))
+	       && r->value
+	       && !strcmp (r->value, expected_notations[i].value)
+	       && r->value_len == strlen (expected_notations[i].value)
+	       && r->flags
+	       == (expected_notations[i].flags & ~GPGME_SIG_NOTATION_CRITICAL)
+	       && r->human_readable
+	       == !!(r->flags & GPGME_SIG_NOTATION_HUMAN_READABLE)
+	       && r->critical == 0)
+	    {
+	      expected_notations[i].seen++;
+	      any++;
+	    }
+	}
+      if (!any)
+	{
+	  fprintf (stderr, "%s:%i: Unexpected notation data\n",
+		   __FILE__, __LINE__);
+	  exit (1);
+	}
+    }
+  for (i=0; i < DIM(expected_notations); i++ )
+    {
+      if (expected_notations[i].seen != 1)
+	{
+	  fprintf (stderr, "%s:%i: Missing or duplicate notation data\n",
+		   __FILE__, __LINE__);
+	  exit (1);
+	}
+    }
+}
+
+
+int 
+main (int argc, char *argv[])
+{
+  gpgme_ctx_t ctx;
+  gpgme_error_t err;
+  gpgme_data_t in, out;
+  gpgme_verify_result_t result;
+  char *agent_info;
+  int i;
+
+  init_gpgme (GPGME_PROTOCOL_OpenPGP);
+
+  err = gpgme_new (&ctx);
+  fail_if_err (err);
+
+  agent_info = getenv ("GPG_AGENT_INFO");
+  if (!(agent_info && strchr (agent_info, ':')))
+    gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);
+
+  err = gpgme_data_new_from_mem (&in, "Hallo Leute\n", 12, 0);
+  fail_if_err (err);
+  err = gpgme_data_new (&out);
+  fail_if_err (err);
+
+  for (i = 0; i < sizeof (expected_notations) / sizeof (expected_notations[0]);
+       i++)
+    {
+      err = gpgme_sig_notation_add (ctx, expected_notations[i].name,
+				    expected_notations[i].value,
+				    expected_notations[i].flags);
+      fail_if_err (err);
+    }
+  
+  err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_NORMAL);
+  fail_if_err (err);
+
+  gpgme_data_release (in);
+  err = gpgme_data_new (&in);
+  fail_if_err (err);
+
+  gpgme_data_seek (out, 0, SEEK_SET);
+
+  err = gpgme_op_verify (ctx, out, NULL, in);
+  fail_if_err (err);
+  result = gpgme_op_verify_result (ctx);
+  check_result (result);
+
+  gpgme_data_release (in);
+  gpgme_data_release (out);
+  gpgme_release (ctx);
+  return 0;
+}

Modified: trunk/tests/gpg/t-verify.c
===================================================================
--- trunk/tests/gpg/t-verify.c	2005-09-30 14:17:47 UTC (rev 1104)
+++ trunk/tests/gpg/t-verify.c	2005-10-01 02:33:35 UTC (rev 1105)
@@ -136,10 +136,14 @@
           for (i=0; i < DIM(expected_notations); i++)
             {
               if ( ((r->name && expected_notations[i].name
-                     && !strcmp (r->name, expected_notations[i].name))
-                    || (!r->name && !expected_notations[i].name))
+                     && !strcmp (r->name, expected_notations[i].name)
+		     && r->name_len
+		     == strlen (expected_notations[i].name))
+                    || (!r->name && !expected_notations[i].name
+			&& r->name_len == 0))
                    && r->value
-                   && !strcmp (r->value, expected_notations[i].value))
+                   && !strcmp (r->value, expected_notations[i].value)
+		   && r->value_len == strlen (expected_notations[i].value))
                 {
                   expected_notations[i].seen++;
                   any++;




More information about the Gnupg-commits mailing list