doc/
2005-10-01 Marcus Brinkmann <marcus@g10code.de> * gpgme.texi (Signature Notation Data): New section. (Verify): Added more about the notation data structure. gpgme/ 2005-10-01 Marcus Brinkmann <marcus@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@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.
This commit is contained in:
parent
c6ee58ef55
commit
b3304042aa
11
NEWS
11
NEWS
@ -33,10 +33,13 @@ Noteworthy changes in version 1.1.0 (unreleased)
|
||||
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_STATUS_PLAINTEXT NEW
|
||||
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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
|
2
TODO
2
TODO
@ -37,6 +37,8 @@ Hey Emacs, this is -*- outline -*- mode!
|
||||
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
|
||||
|
@ -1,3 +1,8 @@
|
||||
2005-10-01 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* gpgme.texi (Signature Notation Data): New section.
|
||||
(Verify): Added more about the notation data structure.
|
||||
|
||||
2005-09-30 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* gpgme.texi (Data Buffer I/O Operations, Data Buffer Meta-Data):
|
||||
|
@ -209,6 +209,7 @@ Sign
|
||||
|
||||
* 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 @@ the context.
|
||||
@cindex signature, verification
|
||||
@cindex cryptographic operation, verification
|
||||
@cindex cryptographic operation, signature check
|
||||
@cindex signature notation data
|
||||
@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,9 +3804,45 @@ linked list, or @code{NULL} if this is the last element.
|
||||
The name of the notation field. If this is @code{NULL}, then the
|
||||
member @code{value} will contain a policy URL.
|
||||
|
||||
@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.
|
||||
|
||||
@item int value_len
|
||||
The length of the @code{value} field. For strings the length is
|
||||
counted without the trailing binary zero.
|
||||
|
||||
@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
|
||||
@code{flags} is a bitwise-or combination of one or multiple of the
|
||||
following bit values:
|
||||
|
||||
@table @code
|
||||
@item GPGME_SIG_NOTATION_HUMAN_READABLE
|
||||
The @code{GPGME_SIG_NOTATION_HUMAN_READABLE} symbol specifies that the
|
||||
notation data is in human readable form
|
||||
|
||||
@item GPGME_SIG_NOTATION_CRITICAL
|
||||
The @code{GPGME_SIG_NOTATION_CRITICAL} symbol specifies that the
|
||||
notation data is critical.
|
||||
|
||||
@end table
|
||||
|
||||
@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.
|
||||
|
||||
@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.
|
||||
|
||||
@end table
|
||||
@end deftp
|
||||
|
||||
@ -4258,6 +4297,7 @@ set is changed).
|
||||
@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 @@ context.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@node Signature Notation Data
|
||||
@subsubsection Signature Notation Data
|
||||
@cindex notation data
|
||||
@cindex signature notation data
|
||||
@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.
|
||||
|
||||
@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.
|
||||
@end deftypefun
|
||||
|
||||
@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
|
||||
@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
|
||||
@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
|
||||
@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.
|
||||
@end deftypefun
|
||||
|
||||
@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.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@node Encrypt
|
||||
@subsection Encrypt
|
||||
@cindex encryption
|
||||
|
@ -1,3 +1,26 @@
|
||||
2005-10-01 Marcus Brinkmann <marcus@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@g10code.de>
|
||||
|
||||
* data.h (struct gpgme_data): New member file_name.
|
||||
|
@ -72,7 +72,7 @@ libgpgme_real_la_SOURCES = \
|
||||
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 \
|
||||
|
@ -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 @@ struct gpgme_context
|
||||
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;
|
||||
|
@ -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.
|
||||
|
||||
|
@ -429,6 +429,71 @@ gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, gpgme_protocol_t proto,
|
||||
file_name, home_dir);
|
||||
}
|
||||
|
||||
|
||||
/* 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 (¬ation, 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)
|
||||
|
@ -144,5 +144,12 @@ EXPORTS
|
||||
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
|
||||
|
||||
|
@ -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.
|
||||
|
||||
@ -312,6 +312,46 @@ gpgme_protocol_t;
|
||||
|
||||
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
|
||||
@ -818,6 +858,22 @@ const char *gpgme_get_sig_string_attr (gpgme_ctx_t c, int idx,
|
||||
gpgme_error_t gpgme_get_sig_key (gpgme_ctx_t ctx, int idx, gpgme_key_t *r_key)
|
||||
_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. */
|
||||
|
||||
@ -1209,16 +1265,6 @@ gpgme_error_t gpgme_op_sign (gpgme_ctx_t ctx,
|
||||
|
||||
|
||||
/* 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
|
||||
|
@ -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_1.1 {
|
||||
|
||||
gpgme_data_set_file_name;
|
||||
gpgme_data_get_file_name;
|
||||
|
||||
gpgme_sig_notation_clear;
|
||||
gpgme_sig_notation_add;
|
||||
gpgme_sig_notation_get;
|
||||
};
|
||||
|
||||
|
||||
|
19
gpgme/ops.h
19
gpgme/ops.h
@ -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 _gpgme_op_trustlist_event_cb (void *data, gpgme_event_io_t type,
|
||||
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 */
|
||||
|
@ -1255,6 +1255,91 @@ append_args_from_signers (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
|
||||
}
|
||||
|
||||
|
||||
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 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
|
||||
|
||||
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 @@ gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
|
||||
|
||||
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))
|
||||
{
|
||||
|
123
gpgme/sig-notation.c
Normal file
123
gpgme/sig-notation.c
Normal file
@ -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;
|
||||
}
|
@ -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 @@ release_op_data (void *hook)
|
||||
{
|
||||
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 @@ parse_notation (gpgme_signature_t sig, gpgme_status_code_t code, char *args)
|
||||
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 (¬ation, 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, ¬ation->name, len);
|
||||
err = _gpgme_decode_percent_string (args, ¬ation->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, ¬ation->value, len);
|
||||
err = _gpgme_decode_percent_string (args, ¬ation->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 @@ parse_notation (gpgme_signature_t sig, gpgme_status_code_t code, char *args)
|
||||
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);
|
||||
|
@ -1,3 +1,11 @@
|
||||
2005-10-01 Marcus Brinkmann <marcus@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@g10code.de>
|
||||
|
||||
* gpg/Makefile.am (TESTS): Add t-filename.
|
||||
|
@ -26,7 +26,7 @@ TESTS_ENVIRONMENT = GNUPGHOME=. GPG_AGENT_INFO=
|
||||
# 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
|
||||
|
27
tests/gpg/gpg.conf
Normal file
27
tests/gpg/gpg.conf
Normal file
@ -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
|
166
tests/gpg/t-sig-notation.c
Normal file
166
tests/gpg/t-sig-notation.c
Normal file
@ -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@me",
|
||||
"Just Squeeze Me",
|
||||
GPGME_SIG_NOTATION_HUMAN_READABLE },
|
||||
{ "leave@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;
|
||||
}
|
@ -136,10 +136,14 @@ check_result (gpgme_verify_result_t result, unsigned int summary, char *fpr,
|
||||
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++;
|
||||
|
Loading…
Reference in New Issue
Block a user