2003-04-28  Marcus Brinkmann  <marcus@g10code.de>

	* gpgme.texi (Verify): Rewritten to take into account new and
	deprecated functions and data types.

gpgme/
2003-04-28  Marcus Brinkmann  <marcus@g10code.de>

	* gpgme.h (struct _gpgme_sig_notation): New structure.
	(GpgmeSigNotation): New type.
	(struct _gpgme_signature): New structure.
	(GpgmeSignature): New type.
	(struct _gpgme_op_verify_result): New structure.
	(GpgmeVerifyResult): New type.
	(gpgme_op_verify_result): New prototype.
	(gpgme_get_notation): Remove prototype.
	* ops.h (_gpgme_op_verify_init_result): New prototype.
	(_gpgme_verify_status_handler): Change first argument to void *.
	* util.h (_gpgme_decode_percent_string, _gpgme_map_gnupg_error):
	New prototypes.
	* conversion.c (_gpgme_decode_percent_string): New function.
	(gnupg_errors): New static global.
	(_gpgme_map_gnupg_error): New function.
	* gpgme.c (gpgme_release): Don't release CTX->notation.
	(gpgme_get_notation): Remove function.
	* decrypt-verify.c (_gpgme_op_decrypt_verify_start): Call
	_gpgme_op_verify_init_result.
	* verify.c: Do not include <stdio.h>, <assert.h> and "key.h", but
	do include "gpgme.h".
	(struct verify_result): Replace with ...
	(op_data_t): ... this type.
	(release_verify_result): Remove function.
	(release_op_data): New function.
	(is_token): Remove function.
	(skip_token): Remove function.
	(copy_token): Remove function.
	(gpgme_op_verify_result): New function.
	(calc_sig_summary): Rewritten.
	(finish_sig): Remove function.
	(parse_new_sig): New function.
	(parse_valid_sig): New function.
	(parse_notation): New function.
	(parse_trust): New function.
	(parse_error): New function.
	(_gpgme_verify_status_handler): Rewritten.  Change first argument
	to void *.
	(_gpgme_op_verify_start): Rework error handling.  Call
	_gpgme_op_verify_init_result.
	(gpgme_op_verify): Do not release or clear CTX->notation.
	(gpgme_get_sig_status): Rewritten.
	(gpgme_get_sig_string_attr): Likewise.
	(gpgme_get_sig_ulong_attr): Likewise.
	(gpgme_get_sig_key): Likewise.
This commit is contained in:
Marcus Brinkmann 2003-04-28 23:59:03 +00:00
parent 16c4687a9c
commit 30cdf13284
15 changed files with 1440 additions and 832 deletions

19
NEWS
View File

@ -86,14 +86,17 @@ Noteworthy changes in version 0.4.1 (unreleased)
information about the result of an encryption operation in information about the result of an encryption operation in
a GpgmeEncryptResult object. a GpgmeEncryptResult object.
* The new gpgme_op_encrypt_result function provides detailed
information about the result of an encryption operation in
a GpgmeEncryptResult object.
* The new gpgme_op_decrypt_result function provides detailed * The new gpgme_op_decrypt_result function provides detailed
information about the result of an encryption operation in information about the result of an encryption operation in
a GpgmeDecryptResult object. a GpgmeDecryptResult object.
* The new gpgme_op_verify_result function provides detailed
information about the result of an verify operation in
a GpgmeVerifyResult object. Because of this, the GPGME_SIG_STAT_*
values, gpgme_get_sig_status, gpgme_get_sig_ulong_attr,
gpgme_get_sig_string_attr and gpgme_get_sig_key are now deprecated,
and gpgme_get_notation is removed.
* Interface changes relative to the 0.4.0 release: * Interface changes relative to the 0.4.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GpgmeIOCb CHANGED: Return type from void to GpgmeError. GpgmeIOCb CHANGED: Return type from void to GpgmeError.
@ -136,6 +139,14 @@ GpgmeEncryptResult NEW
gpgme_op_encrypt_result NEW gpgme_op_encrypt_result NEW
GpgmeDecryptResult NEW GpgmeDecryptResult NEW
gpgme_op_decrypt_result NEW gpgme_op_decrypt_result NEW
GpgmeVerifyResult NEW
gpgme_op_verify_result NEW
gpgme_get_notation REMOVED: Access verify result directly instead.
gpgme_get_sig_key DEPRECATED: Use gpgme_get_key with fingerprint.
gpgme_get_sig_ulong_attr DEPRECATED: Use verify result directly.
gpgme_get_sig_string_attr DEPRECATED: Use verify result directly.
GPGME_SIG_STAT_* DEPRECATED: Use error value in sig status.
gpgme_get_sig_status DEPRECATED: Use verify result directly.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noteworthy changes in version 0.4.0 (2002-12-23) Noteworthy changes in version 0.4.0 (2002-12-23)

7
TODO
View File

@ -14,6 +14,13 @@ Hey Emacs, this is -*- outline -*- mode!
*** GPGME_Busy, GPGME_No_Request *** GPGME_Busy, GPGME_No_Request
*** GPGME_No_Passphrase *** GPGME_No_Passphrase
*** GPGME_Invalid_Recipient, GPGME_No_Recipients *** GPGME_Invalid_Recipient, GPGME_No_Recipients
*** GPGME_No_Passphrase
*** gpgme_op_import_ext
*** gpgme_get_sig_key
*** gpgme_get_sig_ulong_attr
*** gpgme_get_sig_string_attr
*** GPGME_SIG_STAT_*
*** gpgme_get_sig_status
* Thread support: * Thread support:
** Build thread modules for static linking (which just suck in the ** Build thread modules for static linking (which just suck in the

View File

@ -1,5 +1,8 @@
2003-04-28 Marcus Brinkmann <marcus@g10code.de> 2003-04-28 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Verify): Rewritten to take into account new and
deprecated functions and data types.
* gpgme.texi (Decrypt): Descript gpgme_op_decrypt_result and * gpgme.texi (Decrypt): Descript gpgme_op_decrypt_result and
GpgmeDecryptResult. GpgmeDecryptResult.

View File

@ -2805,7 +2805,199 @@ next operation is started on the context.
@cindex signature, verification @cindex signature, verification
@cindex cryptographic operation, verification @cindex cryptographic operation, verification
@cindex cryptographic operation, signature check @cindex cryptographic operation, signature check
@cindex signature, status
@deftypefun GpgmeError gpgme_op_verify (@w{GpgmeCtx @var{ctx}}, @w{GpgmeData @var{sig}}, @w{GpgmeData @var{signed_text}}, @w{GpgmeData @var{plain}})
The function @code{gpgme_op_verify} verifies that the signature in the
data object @var{sig} is a valid signature. If @var{sig} is a
detached signature, then the signed text should be provided in
@var{signed_text} and @var{plain} should be a null pointer.
Otherwise, if @var{sig} is a normal (or cleartext) signature,
@var{signed_text} should be a null pointer and @var{plain} should be a
writable data object that will contain the plaintext after successful
verification.
The results of the individual signature verifications can be retrieved
with @code{gpgme_op_verify_result}.
The function returns @code{GPGME_No_Error} if the operation could be
completed successfully, @code{GPGME_Invalid_Value} if @var{ctx},
@var{sig}, @var{plain} or @var{r_stat} is not a valid pointer,
@code{GPGME_No_Data} if @var{sig} does not contain any data to verify,
and passes through any errors that are reported by the crypto engine
support routines.
@end deftypefun
@deftypefun GpgmeError gpgme_op_verify_start (@w{GpgmeCtx @var{ctx}}, @w{GpgmeData @var{sig}}, @w{GpgmeData @var{signed_text}}, @w{GpgmeData @var{plain}})
The function @code{gpgme_op_verify_start} initiates a
@code{gpgme_op_verify} operation. It can be completed by calling
@code{gpgme_wait} on the context. @xref{Waiting For Completion}.
The function returns @code{GPGME_No_Error} if the operation could be
started successfully, @code{GPGME_Invalid_Value} if @var{ctx},
@var{sig}, @var{plain} or @var{r_stat} is not a valid pointer, and
@code{GPGME_No_Data} if @var{sig} or @var{plain} does not contain any
data to verify.
@end deftypefun
@deftp {Data type} {GpgmeSigNotation}
This is a pointer to a structure used to store a part of the result of
a @code{gpgme_op_verify} operation. The structure contains the
following members:
@table @code
@item GpgmeSigNotation next
This is a pointer to the next new signature notation structure in the
linked list, or @code{NULL} if this is the last element.
@item char *name
The name of the notation field. If this is @code{NULL}, then the
member @code{value} will contain a policy URL.
@item char *value
The value of the notation field. If @code{name} is @code{NULL}, then
this is a policy URL.
@end table
@end deftp
@deftp {Data type} {GpgmeSignature}
This is a pointer to a structure used to store a part of the result of
a @code{gpgme_op_verify} operation. The structure contains the
following members:
@table @code
@item GpgmeSignature next
This is a pointer to the next new signature structure in the linked
list, or @code{NULL} if this is the last element.
@item unsigned int summary;
This is a bit vector giving a summary of the signature status. It
provides an easy interface to a defined semantic of the signature
status. Checking just one bit is sufficient to see whether a
signature is valid without any restrictions.
The defined bits are:
@table @code
@item GPGME_SIGSUM_VALID
The signature is fully valid.
@item GPGME_SIGSUM_GREEN
The signature is good but one might want to display some extra
information. Check the other bits.
@item GPGME_SIGSUM_RED
The signature is bad. It might be useful to checkother bits and
display moe information, i.e. a revoked certificate might not render a
signature invalid when the message was received prior to the cause for
the revocation.
@item GPGME_SIGSUM_KEY_REVOKED
The key or at least one certificate has been revoked.
@item GPGME_SIGSUM_KEY_EXPIRED
The key or one of the certificates has expired. It is probably a good
idea to display the date of the expiration.
@item GPGME_SIGSUM_SIG_EXPIRED
The signature has expired.
@item GPGME_SIGSUM_KEY_MISSING
Can't verifydue to a missing key o certificate.
@item GPGME_SIGSUM_CRL_MISSING
The CRL (or an equivalent mechanism) is not available.
@item GPGME_SIGSUM_CRL_TOO_OLD
Available CRL is too old.
@item GPGME_SIGSUM_BAD_POLICY
A policy requirement was not met.
@item GPGME_SIGSUM_SYS_ERROR
A system error occured.
@end table
@item char *fpr
This is the fingerprint or key ID of the signature.
@item GpgmeError status
This is the status of the signature. In particular, the following
status codes are of interest:
@table @code
@item GPGME_No_Error
This status indicates that the signature is valid. For the combined
result this status means that all signatures are valid.
@item GPGME_Sig_Expired
This status indicates that the signature is valid but expired. For
the combined result this status means that all signatures are valid
and expired.
@item GPGME_Key_Expired
This status indicates that the signature is valid but the key used to
verify the signature has expired. For the combined result this status
means that all signatures are valid and all keys are expired.
@item GPGME_Bad_Signature
This status indicates that the signature is invalid. For the combined
result this status means that all signatures are invalid.
@item GPGME_No_Public_Key
This status indicates that the signature could not be verified due to
a missing key. For the combined result this status means that all
signatures could not be checked due to missing keys.
@item GPGME_General_Error
This status indicates that there was some other error which prevented
the signature verification.
@end table
@item GpgmeSigNotation notations
This is a linked list with the notation data and policy URLs.
@item unsigned long timestamp
The creation timestamp of this signature.
@item unsigned long exp_timestamp
The expiration timestamp of this signature, or 0 if the signature does
not expire.
@item int wrong_key_usage : 1;
@item GpgmeValidity validity
@item GpgmeError validity_reason
@end table
@end deftp
@deftp {Data type} {GpgmeVerifyResult}
This is a pointer to a structure used to store the result of a
@code{gpgme_op_verify} operation. After successfully verifying a
signature, you can retrieve the pointer to the result with
@code{gpgme_op_verify_result}. The structure contains the following
member:
@table @code
@item GpgmeSignature signatures
A linked list with information about all signatures for which a
verification was attempted.
@end table
@end deftp
@deftypefun GpgmeSignResult gpgme_op_verify_result (@w{GpgmeCtx @var{ctx}})
The function @code{gpgme_op_verify_result} returns a
@code{GpgmeVerifyResult} pointer to a structure holding the result of
a @code{gpgme_op_verify} operation. The pointer is only valid if the
last operation on the context was a @code{gpgme_op_verify} or
@code{gpgme_op_verify_start} operation, and if this operation finished
successfully. The returned pointer is only valid until the next
operation is started on the context.
@end deftypefun
The following interfaces are deprecated and only provided for backward
compatibility. Don't use them. They will be removed in a future
version of @acronym{GPGME}.
@deftp {Data type} {enum GpgmeSigStat} @deftp {Data type} {enum GpgmeSigStat}
@tindex GpgmeSigStat @tindex GpgmeSigStat
@ -2855,188 +3047,183 @@ have a different status. You can get each key's status with
@end table @end table
@end deftp @end deftp
@deftypefun GpgmeError gpgme_op_verify (@w{GpgmeCtx @var{ctx}}, @w{GpgmeData @var{sig}}, @w{GpgmeData @var{signed_text}}, @w{GpgmeData @var{plain}})
The function @code{gpgme_op_verify} verifies that the signature in the
data object @var{sig} is a valid signature. If @var{sig} is a
detached signature, then the signed text should be provided in
@var{signed_text} and @var{plain} should be a null pointer.
Otherwise, if @var{sig} is a normal (or cleartext) signature,
@var{signed_text} should be a null pointer and @var{plain} should be a
writable data object that will contain the plaintext after successful
verification.
The results of the individual signature verifications can be retrieved
with @code{gpgme_get_sig_status} and @code{gpgme_get_sig_key}.
The function returns @code{GPGME_No_Error} if the operation could be
completed successfully, @code{GPGME_Invalid_Value} if @var{ctx},
@var{sig}, @var{plain} or @var{r_stat} is not a valid pointer,
@code{GPGME_No_Data} if @var{sig} does not contain any data to verify,
and passes through any errors that are reported by the crypto engine
support routines.
@end deftypefun
@deftypefun GpgmeError gpgme_op_verify_start (@w{GpgmeCtx @var{ctx}}, @w{GpgmeData @var{sig}}, @w{GpgmeData @var{signed_text}}, @w{GpgmeData @var{plain}})
The function @code{gpgme_op_verify_start} initiates a
@code{gpgme_op_verify} operation. It can be completed by calling
@code{gpgme_wait} on the context. @xref{Waiting For Completion}.
The function returns @code{GPGME_No_Error} if the operation could be
started successfully, @code{GPGME_Invalid_Value} if @var{ctx},
@var{sig}, @var{plain} or @var{r_stat} is not a valid pointer, and
@code{GPGME_No_Data} if @var{sig} or @var{plain} does not contain any
data to verify.
@end deftypefun
@deftypefun {const char *} gpgme_get_sig_status (@w{GpgmeCtx @var{ctx}}, @w{int @var{idx}}, @w{GpgmeSigStat *@var{r_stat}}, @w{time_t *@var{r_created}}) @deftypefun {const char *} gpgme_get_sig_status (@w{GpgmeCtx @var{ctx}}, @w{int @var{idx}}, @w{GpgmeSigStat *@var{r_stat}}, @w{time_t *@var{r_created}})
The function @code{gpgme_get_sig_status} receives information about a The function @code{gpgme_get_sig_status} is equivalent to:
signature after the @code{gpgme_op_verify} or
@code{gpgme_op_verify_decrypt} operation. A single detached signature @example
can contain signatures by more than one key. The @var{idx} specifies GpgmeVerifyResult result;
which signature's information should be retrieved, starting from GpgmeSignature sig;
@var{0}.
The status of the signature will be returned in @var{r_stat} if it is result = gpgme_op_verify_result (ctx);
not @code{NULL}. The creation time stamp of the signature will be sig = result->signatures;
returned in @var{r_created} if it is not @var{NULL}.
The function returns a statically allocated string that contains the while (sig && idx)
fingerprint of the key which signed the plaintext, or @code{NULL} if @{
@var{ctx} is not a valid pointer, the operation is still pending, or sig = sig->next;
no verification could be performed. idx--;
@}
if (!sig || idx)
return NULL;
if (r_stat)
@{
switch (sig->status)
@{
case GPGME_No_Error:
*r_stat = GPGME_SIG_STAT_GOOD;
break;
case GPGME_Bad_Signature:
*r_stat = GPGME_SIG_STAT_BAD;
break;
case GPGME_No_Public_Key:
*r_stat = GPGME_SIG_STAT_NOKEY;
break;
case GPGME_No_Data:
*r_stat = GPGME_SIG_STAT_NOSIG;
break;
case GPGME_Sig_Expired:
*r_stat = GPGME_SIG_STAT_GOOD_EXP;
break;
case GPGME_Key_Expired:
*r_stat = GPGME_SIG_STAT_GOOD_EXPKEY;
break;
default:
*r_stat = GPGME_SIG_STAT_ERROR;
break;
@}
@}
if (r_created)
*r_created = sig->timestamp;
return sig->fpr;
@end example
@end deftypefun @end deftypefun
@deftypefun {const char *} gpgme_get_sig_string_attr (@w{GpgmeCtx @var{ctx}}, @w{int @var{idx}}, @w{GpgmeAttr @var{what}}, @w{int @var{whatidx}}) @deftypefun {const char *} gpgme_get_sig_string_attr (@w{GpgmeCtx @var{ctx}}, @w{int @var{idx}}, @w{GpgmeAttr @var{what}}, @w{int @var{whatidx}})
This function is similar to @code{gpgme_get_sig_status} but may be used The function @code{gpgme_get_sig_string_attr} is equivalent to:
to retrieve more detailed information. @var{ctx} should be the context
used for the last signature verification, @var{idx} is used to enumerate @example
over all signatures starting with @code{0} and @var{whatidx} should be GpgmeVerifyResult result;
@code{0} unless otherwise stated. GpgmeSignature sig;
The following values may be used for @var{what}: result = gpgme_op_verify_result (ctx);
@table @code sig = result->signatures;
@item GPGME_ATTR_FPR
Return the fingerprint of the key used to create the signature.
@item GPGME_ATTR_ERRTOK while (sig && idx)
Return a token with a more detailed error description. A @var{whatidx} @{
of @code{0} returns an error token associated with validity calculation, sig = sig->next;
a value of @code{1} return an error token related to the certificate idx--;
checking. @}
if (!sig || idx)
return NULL;
@end table switch (what)
@{
case GPGME_ATTR_FPR:
return sig->fpr;
case GPGME_ATTR_ERRTOK:
if (whatidx == 1)
return sig->wrong_key_usage ? "Wrong_Key_Usage" : "";
else
return "";
default:
break;
@}
return NULL;
@end example
@end deftypefun @end deftypefun
@deftypefun {const char *} gpgme_get_sig_ulong_attr (@w{GpgmeCtx @var{ctx}}, @w{int @var{idx}}, @w{GpgmeAttr @var{waht}}, @w{int @var{whatidx}}) @deftypefun {const char *} gpgme_get_sig_ulong_attr (@w{GpgmeCtx @var{ctx}}, @w{int @var{idx}}, @w{GpgmeAttr @var{waht}}, @w{int @var{whatidx}})
This function is similar to @code{gpgme_get_sig_string_attr} but used The function @code{gpgme_get_sig_ulong_attr} is equivalent to:
for attributes which can be represented by an @code{unsigned long} data
type. @var{ctx} should be the context used for the last signature @example
verification, @var{idx} is used to enumerate over all signatures GpgmeVerifyResult result;
starting with @code{0} and @var{whatidx} should be @code{0} unless GpgmeSignature sig;
otherwise stated.
The following values may be used for @var{what}: result = gpgme_op_verify_result (ctx);
@table @code sig = result->signatures;
@item GPGME_ATTR_CREATED
Return the creation time of the signature in seconds since Epoch. This
is the same value as returned by @code{gpgme_get_sig_status}.
@item GPGME_ATTR_EXPIRE while (sig && idx)
Return the expiration time of the signature in seconds since Epoch. @{
sig = sig->next;
idx--;
@}
if (!sig || idx)
return 0;
@item GPGME_ATTR_VALIDITY switch (what)
Returns the validity of the key used to create the signature. This is a @{
shortcut function which avoids an extra key lookup. The value returned case GPGME_ATTR_CREATED:
is one of @code{GPGME_VALIDITY_UNKNOWN}, @code{GPGME_VALIDITY_NEVER}, return sig->timestamp;
@code{GPGME_VALIDITY_MARGINAL} or @code{GPGME_VALIDITY_FULL}.
@item GPGME_ATTR_SIG_STATUS case GPGME_ATTR_EXPIRE:
This is the same value as returned by @code{gpgme_get_sig_status}. return sig->exp_timestamp;
@item GPGME_ATTR_SIG_SUMMARY case GPGME_ATTR_VALIDITY:
This returns a bit vector giving a summary of the signature status. return (unsigned long) sig->validity;
Itprovides an easy interface to a defined semantic of the signature
status. Checking just one bit is sufficient to see whether a signature
is valid without any restrictions.
The defined bits are: case GPGME_ATTR_SIG_STATUS:
@table @code switch (sig->status)
@item GPGME_SIGSUM_VALID @{
The signature is fully valid. case GPGME_No_Error:
return GPGME_SIG_STAT_GOOD;
case GPGME_Bad_Signature:
return GPGME_SIG_STAT_BAD;
case GPGME_No_Public_Key:
return GPGME_SIG_STAT_NOKEY;
case GPGME_No_Data:
return GPGME_SIG_STAT_NOSIG;
case GPGME_Sig_Expired:
return GPGME_SIG_STAT_GOOD_EXP;
case GPGME_Key_Expired:
return GPGME_SIG_STAT_GOOD_EXPKEY;
default:
return GPGME_SIG_STAT_ERROR;
@}
@item GPGME_SIGSUM_GREEN case GPGME_ATTR_SIG_SUMMARY:
The signature is good but one might want to display some extra return sig->summary;
information. Check the other bits.
@item GPGME_SIGSUM_RED default:
The signature is bad. It might be useful to checkother bits and break;
display moe information, i.e. a revoked certificate might not render a @}
signature invalid when the message was received prior to the cause for return 0;
the revocation. @end example
@item GPGME_SIGSUM_KEY_REVOKED
The key or at least one certificate has been revoked.
@item GPGME_SIGSUM_KEY_EXPIRED
The key or one of the certificates has expired. It is probably a good
idea to display the date of the expiration.
@item GPGME_SIGSUM_SIG_EXPIRED
The signature has expired.
@item GPGME_SIGSUM_KEY_MISSING
Can't verifydue to a missing key o certificate.
@item GPGME_SIGSUM_CRL_MISSING
The CRL (or an equivalent mechanism) is not available.
@item GPGME_SIGSUM_CRL_TOO_OLD
Available CRL is too old.
@item GPGME_SIGSUM_BAD_POLICY
A policy requirement was not met.
@item GPGME_SIGSUM_SYS_ERROR
A system error occured.
@end table
@end table
@end deftypefun @end deftypefun
@deftypefun {const char *} gpgme_get_sig_key (@w{GpgmeCtx @var{ctx}}, @w{int @var{idx}}, @w{GpgmeKey *@var{r_key}}) @deftypefun {const char *} gpgme_get_sig_key (@w{GpgmeCtx @var{ctx}}, @w{int @var{idx}}, @w{GpgmeKey *@var{r_key}})
The function @code{gpgme_get_sig_status} receives a @code{GpgmeKey} The function @code{gpgme_get_sig_key} is equivalent to:
object for the key which was used to verify the signature after the
@code{gpgme_op_verify} or @code{gpgme_op_verify_decrypt} operation. A
single detached signature can contain signatures by more than one key.
The @var{idx} specifies which signature's information should be
retrieved, starting from @var{0}. The key will have on reference for
the user.
The function is a convenient way to retrieve the keys belonging to the @example
fingerprints returned by @code{gpgme_get_sig_status}. GpgmeVerifyResult result;
GpgmeSignature sig;
The function returns @code{GPGME_No_Error} if the key could be result = gpgme_op_verify_result (ctx);
returned, @code{GPGME_Invalid_Value} if @var{r_key} is not a valid sig = result->signatures;
pointer, @code{GPGME_Invalid_Key} if the fingerprint is not valid,
@code{GPGME_EOF} if @var{idx} is too large, or some other error value
if a problem occurred requesting the key.
@end deftypefun
@deftypefun {char *} gpgme_get_notation (@w{GpgmeCtx @var{ctx}}) while (sig && idx)
The function @code{gpgme_get_notation} can be used to retrieve @{
notation data from the last signature check in the context @var{ctx}. sig = sig->next;
idx--;
@}
if (!sig || idx)
return GPGME_EOF;
If there is notation data available from the last signature check, return gpgme_get_key (ctx, sig->fpr, r_key, 0, 0);
this function may be used to return this notation data as a string. @end example
The string is an XML representation of that data embedded in a
<notation> container. The user has to release the string with
@code{free}.
The function returns a string if the notation data is available or
@code{NULL} if there is no such data available.
@end deftypefun @end deftypefun
@ -3204,7 +3391,7 @@ The hash algorithm used to create this signature.
@item unsigned long class @item unsigned long class
The signature class of this signature. The signature class of this signature.
@item long int created @item long int timestamp
The creation timestamp of this signature. The creation timestamp of this signature.
@item char *fpr @item char *fpr

View File

@ -1,5 +1,51 @@
2003-04-28 Marcus Brinkmann <marcus@g10code.de> 2003-04-28 Marcus Brinkmann <marcus@g10code.de>
* gpgme.h (struct _gpgme_sig_notation): New structure.
(GpgmeSigNotation): New type.
(struct _gpgme_signature): New structure.
(GpgmeSignature): New type.
(struct _gpgme_op_verify_result): New structure.
(GpgmeVerifyResult): New type.
(gpgme_op_verify_result): New prototype.
(gpgme_get_notation): Remove prototype.
* ops.h (_gpgme_op_verify_init_result): New prototype.
(_gpgme_verify_status_handler): Change first argument to void *.
* util.h (_gpgme_decode_percent_string, _gpgme_map_gnupg_error):
New prototypes.
* conversion.c (_gpgme_decode_percent_string): New function.
(gnupg_errors): New static global.
(_gpgme_map_gnupg_error): New function.
* gpgme.c (gpgme_release): Don't release CTX->notation.
(gpgme_get_notation): Remove function.
* decrypt-verify.c (_gpgme_op_decrypt_verify_start): Call
_gpgme_op_verify_init_result.
* verify.c: Do not include <stdio.h>, <assert.h> and "key.h", but
do include "gpgme.h".
(struct verify_result): Replace with ...
(op_data_t): ... this type.
(release_verify_result): Remove function.
(release_op_data): New function.
(is_token): Remove function.
(skip_token): Remove function.
(copy_token): Remove function.
(gpgme_op_verify_result): New function.
(calc_sig_summary): Rewritten.
(finish_sig): Remove function.
(parse_new_sig): New function.
(parse_valid_sig): New function.
(parse_notation): New function.
(parse_trust): New function.
(parse_error): New function.
(_gpgme_verify_status_handler): Rewritten. Change first argument
to void *.
(_gpgme_op_verify_start): Rework error handling. Call
_gpgme_op_verify_init_result.
(gpgme_op_verify): Do not release or clear CTX->notation.
(gpgme_get_sig_status): Rewritten.
(gpgme_get_sig_string_attr): Likewise.
(gpgme_get_sig_ulong_attr): Likewise.
(gpgme_get_sig_key): Likewise.
* gpgme.h (struct _gpgme_op_decrypt_result): New structure. * gpgme.h (struct _gpgme_op_decrypt_result): New structure.
(GpgmeDecryptResult): New type. (GpgmeDecryptResult): New type.
(gpgme_op_decrypt_result): New prototype. (gpgme_op_decrypt_result): New prototype.

View File

@ -161,6 +161,178 @@ _gpgme_decode_c_string (const char *src, char **destp, int len)
return 0; return 0;
} }
/* Decode the percent escaped string SRC and store the result in the
buffer *DESTP which is LEN bytes long. If LEN is zero, then a
large enough buffer is allocated with malloc and *DESTP is set to
the result. Currently, LEN is only used to specify if allocation
is desired or not, the caller is expected to make sure that *DESTP
is large enough if LEN is not zero. */
GpgmeError
_gpgme_decode_percent_string (const char *src, char **destp, int len)
{
char *dest;
/* Set up the destination buffer. */
if (len)
{
if (len < strlen (src) + 1)
return GPGME_General_Error;
dest = *destp;
}
else
{
/* The converted string will never be larger than the original
string. */
dest = malloc (strlen (src) + 1);
if (!dest)
return GPGME_Out_Of_Core;
*destp = dest;
}
/* Convert the string. */
while (*src)
{
if (*src != '%')
{
*(dest++) = *(src++);
continue;
}
else
{
int val = _gpgme_hextobyte (&src[1]);
if (val == -1)
{
/* Should not happen. */
*(dest++) = *(src++);
if (*src)
*(dest++) = *(src++);
if (*src)
*(dest++) = *(src++);
}
else
{
if (!val)
{
/* A binary zero is not representable in a C
string. */
*(dest++) = '\\';
*(dest++) = '0';
}
else
*((unsigned char *) dest++) = val;
src += 3;
}
}
}
*(dest++) = 0;
return 0;
}
static struct
{
char *name;
GpgmeError err;
} gnupg_errors[] =
{
{ "EOF", GPGME_EOF },
{ "No_Error", GPGME_No_Error },
{ "General_Error", GPGME_General_Error },
{ "Out_Of_Core", GPGME_Out_Of_Core },
{ "Invalid_Value", GPGME_Invalid_Value },
{ "IO_Error", GPGME_General_Error },
{ "Resource_Limit", GPGME_General_Error },
{ "Internal_Error", GPGME_General_Error },
{ "Bad_Certificate", GPGME_Invalid_Key },
{ "Bad_Certificate_Chain", GPGME_General_Error },
{ "Missing_Certificate", GPGME_No_Public_Key },
{ "No_Data", GPGME_No_Data },
{ "Bad_Signature", GPGME_Bad_Signature },
{ "Not_Implemented", GPGME_Not_Implemented },
{ "Conflict", GPGME_Conflict },
{ "Bug", GPGME_General_Error },
{ "Read_Error", GPGME_General_Error },
{ "Write_Error", GPGME_General_Error },
{ "Invalid_Line", GPGME_General_Error },
{ "Incomplete_Line", GPGME_General_Error },
{ "Invalid_Response", GPGME_General_Error },
{ "Agent_Error", GPGME_General_Error },
{ "No_Public_Key", GPGME_No_Public_Key },
{ "No_Secret_Key", GPGME_No_Secret_Key },
{ "File_Open_Error", GPGME_General_Error },
{ "File_Create_Error", GPGME_General_Error },
{ "File_Error", GPGME_General_Error },
{ "Not_Supported", GPGME_General_Error },
{ "Invalid_Data", GPGME_General_Error },
{ "Assuan_Server_Fault", GPGME_General_Error },
{ "Assuan_Error", GPGME_General_Error },
{ "Invalid_Session_Key", GPGME_General_Error },
{ "Invalid_Sexp", GPGME_General_Error },
{ "Unsupported_Algorithm", GPGME_Unsupported_Algorithm },
{ "No_PIN_Entry", GPGME_Invalid_Engine },
{ "PIN_Entry_Error", GPGME_Invalid_Engine },
{ "Bad_PIN", GPGME_Bad_Passphrase },
{ "Bad_Passphrase", GPGME_Bad_Passphrase },
{ "Invalid_Name", GPGME_General_Error },
{ "Bad_Public_Key", GPGME_General_Error },
{ "Bad_Secret_Key", GPGME_General_Error },
{ "Bad_Data", GPGME_General_Error },
{ "Invalid_Parameter", GPGME_General_Error },
{ "Tribute_to_D_A", GPGME_General_Error },
{ "No_Dirmngr", GPGME_Invalid_Engine },
{ "Dirmngr_Error", GPGME_General_Error },
{ "Certificate_Revoked", GPGME_Key_Revoked },
{ "No_CRL_Known", GPGME_No_CRL_Known },
{ "CRL_Too_Old", GPGME_CRL_Too_Old },
{ "Line_Too_Long", GPGME_General_Error },
{ "Not_Trusted", GPGME_Key_Not_Trusted },
{ "Canceled", GPGME_Canceled },
{ "Bad_CA_Certificate", GPGME_General_Error },
{ "Certificate_Expired", GPGME_Key_Expired },
{ "Certificate_Too_Young", GPGME_Invalid_Key },
{ "Unsupported_Certificate", GPGME_General_Error },
{ "Unknown_Sexp", GPGME_General_Error },
{ "Unsupported_Protection", GPGME_General_Error },
{ "Corrupted_Protection", GPGME_General_Error },
{ "Ambiguous_Name", GPGME_Ambiguous_Specification },
{ "Card_Error", GPGME_General_Error },
{ "Card_Reset", GPGME_General_Error },
{ "Card_Removed", GPGME_General_Error },
{ "Invalid_Card", GPGME_General_Error },
{ "Card_Not_Present", GPGME_General_Error },
{ "No_PKCS15_App", GPGME_General_Error },
{ "Not_Confirmed", GPGME_General_Error },
{ "Configuration_Error", GPGME_General_Error },
{ "No_Policy_Match", GPGME_Policy_Mismatch },
{ "Invalid_Index", GPGME_General_Error },
{ "Invalid_Id", GPGME_General_Error },
{ "No_Scdaemon", GPGME_Invalid_Engine },
{ "Scdaemon_Error", GPGME_General_Error },
{ "Unsupported_Protocol", GPGME_General_Error },
{ "Bad_PIN_Method", GPGME_General_Error },
{ "Card_Not_Initialized", GPGME_General_Error },
{ "Unsupported_Operation", GPGME_General_Error },
{ "Wrong_Key_Usage", GPGME_Wrong_Key_Usage }
};
GpgmeError
_gpgme_map_gnupg_error (char *err)
{
int i;
for (i = 0; i < DIM (gnupg_errors); i++)
if (!strcmp (gnupg_errors[i].name, err))
return gnupg_errors[i].err;
return GPGME_General_Error;
}
GpgmeError GpgmeError
_gpgme_data_append (GpgmeData dh, const char *buffer, size_t length) _gpgme_data_append (GpgmeData dh, const char *buffer, size_t length)

View File

@ -48,6 +48,10 @@ _gpgme_op_decrypt_verify_start (GpgmeCtx ctx, int synchronous,
if (err) if (err)
return err; return err;
err = _gpgme_op_verify_init_result (ctx);
if (err)
return err;
if (!cipher) if (!cipher)
return GPGME_No_Data; return GPGME_No_Data;
if (!plain) if (!plain)

View File

@ -68,7 +68,6 @@ gpgme_release (GpgmeCtx ctx)
_gpgme_fd_table_deinit (&ctx->fdt); _gpgme_fd_table_deinit (&ctx->fdt);
_gpgme_release_result (ctx); _gpgme_release_result (ctx);
gpgme_key_release (ctx->tmp_key); gpgme_key_release (ctx->tmp_key);
gpgme_data_release (ctx->notation);
gpgme_signers_clear (ctx); gpgme_signers_clear (ctx);
if (ctx->signers) if (ctx->signers)
free (ctx->signers); free (ctx->signers);
@ -94,26 +93,6 @@ _gpgme_release_result (GpgmeCtx ctx)
} }
/**
* gpgme_get_notation:
* @c: the context
*
* If there is notation data available from the last signature check,
* this function may be used to return this notation data as a string.
* The string is an XML represantaton of that data embedded in a
* %&lt;notation&gt; container.
*
* Return value: An XML string or NULL if no notation data is available.
**/
char *
gpgme_get_notation (GpgmeCtx ctx)
{
if (!ctx->notation)
return NULL;
return _gpgme_data_get_as_string (ctx->notation);
}
/** /**
* gpgme_get_op_info: * gpgme_get_op_info:
* @c: the context * @c: the context

View File

@ -188,23 +188,6 @@ typedef enum
} }
GpgmeSigStat; GpgmeSigStat;
/* Flags used with the GPGME_ATTR_SIG_SUMMARY. */
enum
{
GPGME_SIGSUM_VALID = 0x0001, /* The signature is fully valid. */
GPGME_SIGSUM_GREEN = 0x0002, /* The signature is good. */
GPGME_SIGSUM_RED = 0x0004, /* The signature is bad. */
GPGME_SIGSUM_KEY_REVOKED = 0x0010, /* One key has been revoked. */
GPGME_SIGSUM_KEY_EXPIRED = 0x0020, /* One key has expired. */
GPGME_SIGSUM_SIG_EXPIRED = 0x0040, /* The signature has expired. */
GPGME_SIGSUM_KEY_MISSING = 0x0080, /* Can't verify: key missing. */
GPGME_SIGSUM_CRL_MISSING = 0x0100, /* CRL not available. */
GPGME_SIGSUM_CRL_TOO_OLD = 0x0200, /* Available CRL is too old. */
GPGME_SIGSUM_BAD_POLICY = 0x0400, /* A policy was not met. */
GPGME_SIGSUM_SYS_ERROR = 0x0800 /* A system error occured. */
};
/* The available signature modes. */ /* The available signature modes. */
typedef enum typedef enum
{ {
@ -406,9 +389,6 @@ GpgmeError gpgme_new (GpgmeCtx *ctx);
/* Release the context CTX. */ /* Release the context CTX. */
void gpgme_release (GpgmeCtx ctx); void gpgme_release (GpgmeCtx ctx);
/* Retrieve more info about performed signature check. */
char *gpgme_get_notation (GpgmeCtx ctx);
/* Set the protocol to be used by CTX to PROTO. */ /* Set the protocol to be used by CTX to PROTO. */
GpgmeError gpgme_set_protocol (GpgmeCtx ctx, GpgmeProtocol proto); GpgmeError gpgme_set_protocol (GpgmeCtx ctx, GpgmeProtocol proto);
@ -831,7 +811,7 @@ struct _gpgme_new_signature
GpgmePubKeyAlgo pubkey_algo; GpgmePubKeyAlgo pubkey_algo;
GpgmeHashAlgo hash_algo; GpgmeHashAlgo hash_algo;
unsigned long class; unsigned long class;
long int created; long int timestamp;
char *fpr; char *fpr;
}; };
typedef struct _gpgme_new_signature *GpgmeNewSignature; typedef struct _gpgme_new_signature *GpgmeNewSignature;
@ -856,6 +836,75 @@ GpgmeError gpgme_op_sign (GpgmeCtx ctx,
GpgmeSigMode mode); GpgmeSigMode mode);
/* 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 *GpgmeSigNotation;
/* Flags used for the SUMMARY field in a GpgmeSignature. */
enum
{
GPGME_SIGSUM_VALID = 0x0001, /* The signature is fully valid. */
GPGME_SIGSUM_GREEN = 0x0002, /* The signature is good. */
GPGME_SIGSUM_RED = 0x0004, /* The signature is bad. */
GPGME_SIGSUM_KEY_REVOKED = 0x0010, /* One key has been revoked. */
GPGME_SIGSUM_KEY_EXPIRED = 0x0020, /* One key has expired. */
GPGME_SIGSUM_SIG_EXPIRED = 0x0040, /* The signature has expired. */
GPGME_SIGSUM_KEY_MISSING = 0x0080, /* Can't verify: key missing. */
GPGME_SIGSUM_CRL_MISSING = 0x0100, /* CRL not available. */
GPGME_SIGSUM_CRL_TOO_OLD = 0x0200, /* Available CRL is too old. */
GPGME_SIGSUM_BAD_POLICY = 0x0400, /* A policy was not met. */
GPGME_SIGSUM_SYS_ERROR = 0x0800 /* A system error occured. */
};
struct _gpgme_signature
{
struct _gpgme_signature *next;
/* A summary of the signature status. */
unsigned int summary;
/* The fingerprint or key ID of the signature. */
char *fpr;
/* The status of the signature. */
GpgmeError status;
/* Notation data and policy URLs. */
GpgmeSigNotation notations;
/* Signature creation time. */
unsigned long timestamp;
/* Signature exipration time or 0. */
unsigned long exp_timestamp;
int wrong_key_usage : 1;
/* Internal to GPGME, do not use. */
int _unused : 31;
GpgmeValidity validity;
GpgmeError validity_reason;
};
typedef struct _gpgme_signature *GpgmeSignature;
struct _gpgme_op_verify_result
{
GpgmeSignature signatures;
};
typedef struct _gpgme_op_verify_result *GpgmeVerifyResult;
/* Retrieve a pointer to the result of the verify operation. */
GpgmeVerifyResult gpgme_op_verify_result (GpgmeCtx ctx);
/* Verify within CTX that SIG is a valid signature for TEXT. */ /* Verify within CTX that SIG is a valid signature for TEXT. */
GpgmeError gpgme_op_verify_start (GpgmeCtx ctx, GpgmeData sig, GpgmeError gpgme_op_verify_start (GpgmeCtx ctx, GpgmeData sig,
GpgmeData signed_text, GpgmeData plaintext); GpgmeData signed_text, GpgmeData plaintext);
@ -863,6 +912,7 @@ GpgmeError gpgme_op_verify (GpgmeCtx ctx, GpgmeData sig,
GpgmeData signed_text, GpgmeData plaintext); GpgmeData signed_text, GpgmeData plaintext);
/* Import. */
enum enum
{ {
/* The key was new. */ /* The key was new. */

View File

@ -1,4 +1,4 @@
/* ops.h - internal operations stuff /* ops.h - Internal operation support.
Copyright (C) 2000 Werner Koch (dd9jn) Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003 g10 Code GmbH Copyright (C) 2001, 2002, 2003 g10 Code GmbH
@ -73,8 +73,9 @@ GpgmeError _gpgme_op_reset (GpgmeCtx ctx, int synchronous);
GpgmeError _gpgme_parse_inv_userid (char *args, GpgmeInvalidUserID *userid); GpgmeError _gpgme_parse_inv_userid (char *args, GpgmeInvalidUserID *userid);
/*-- verify.c --*/ /* From verify.c. */
GpgmeError _gpgme_verify_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, GpgmeError _gpgme_op_verify_init_result (GpgmeCtx ctx);
GpgmeError _gpgme_verify_status_handler (void *priv, GpgmeStatusCode code,
char *args); char *args);

View File

@ -149,7 +149,7 @@ parse_sig_created (char *args, GpgmeNewSignature *sigp)
} }
args = tail; args = tail;
sig->created = strtol (args, &tail, 0); sig->timestamp = strtol (args, &tail, 0);
if (errno || args == tail || *tail != ' ') if (errno || args == tail || *tail != ' ')
{ {
/* The crypto backend does not behave. */ /* The crypto backend does not behave. */

View File

@ -74,5 +74,15 @@ int _gpgme_hextobyte (const unsigned char *str);
is large enough if LEN is not zero. */ is large enough if LEN is not zero. */
GpgmeError _gpgme_decode_c_string (const char *src, char **destp, int len); GpgmeError _gpgme_decode_c_string (const char *src, char **destp, int len);
/* Decode the percent escaped string SRC and store the result in the
buffer *DESTP which is LEN bytes long. If LEN is zero, then a
large enough buffer is allocated with malloc and *DESTP is set to
the result. Currently, LEN is only used to specify if allocation
is desired or not, the caller is expected to make sure that *DESTP
is large enough if LEN is not zero. */
GpgmeError _gpgme_decode_percent_string (const char *src, char **destp,
int len);
GpgmeError _gpgme_map_gnupg_error (char *err);
#endif /* UTIL_H */ #endif /* UTIL_H */

File diff suppressed because it is too large Load Diff

View File

@ -112,6 +112,7 @@ status_string (GpgmeSigStat status)
return s; return s;
} }
static const char * static const char *
validity_string (GpgmeValidity val) validity_string (GpgmeValidity val)
{ {
@ -132,138 +133,181 @@ validity_string (GpgmeValidity val)
static void static void
print_sig_stat ( GpgmeCtx ctx, GpgmeSigStat status ) print_sig_stat (GpgmeCtx ctx, GpgmeSigStat status)
{ {
const char *s; const char *s;
time_t created; time_t created;
int idx; int idx;
GpgmeKey key; GpgmeKey key;
printf ("Verification Status: %s\n", status_string (status)); printf ("Verification Status: %s\n", status_string (status));
for(idx=0; (s=gpgme_get_sig_status (ctx, idx, &status, &created)); idx++ ) { for (idx = 0; (s = gpgme_get_sig_status (ctx, idx, &status, &created)); idx++)
printf ("sig %d: created: %lu expires: %lu status: %s\n", {
idx, (unsigned long)created, printf ("sig %d: created: %lu expires: %lu status: %s\n",
gpgme_get_sig_ulong_attr (ctx, idx, GPGME_ATTR_EXPIRE, 0), idx, (unsigned long) created,
status_string(status) ); gpgme_get_sig_ulong_attr (ctx, idx, GPGME_ATTR_EXPIRE, 0),
printf ("sig %d: fpr/keyid: `%s' validity: %s\n", status_string (status));
idx, s, printf ("sig %d: fpr/keyid: `%s' validity: %s\n",
validity_string (gpgme_get_sig_ulong_attr idx, s,
(ctx, idx, GPGME_ATTR_VALIDITY, 0)) ); validity_string (gpgme_get_sig_ulong_attr
if ( !gpgme_get_sig_key (ctx, idx, &key) ) { (ctx, idx, GPGME_ATTR_VALIDITY, 0)));
char *p = gpgme_key_get_as_xml ( key ); if (!gpgme_get_sig_key (ctx, idx, &key))
printf ("sig %d: key object:\n%s\n", idx, p ); {
free (p); char *p = gpgme_key_get_as_xml (key);
gpgme_key_release (key); printf ("sig %d: key object:\n%s\n", idx, p);
free (p);
gpgme_key_release (key);
} }
} }
} }
int int
main (int argc, char **argv ) main (int argc, char *argv[])
{ {
GpgmeCtx ctx; GpgmeCtx ctx;
GpgmeError err; GpgmeError err;
GpgmeData sig, text; GpgmeData sig, text;
GpgmeSigStat status; GpgmeSigStat status;
char *nota; GpgmeVerifyResult result;
int n = 0; GpgmeSigNotation notation;
size_t len; char *nota;
int j; int n = 0;
size_t len;
int j;
err = gpgme_new (&ctx); err = gpgme_new (&ctx);
fail_if_err (err); fail_if_err (err);
do { do
err = gpgme_data_new_from_mem ( &text, {
test_text1, strlen (test_text1), 0 ); err = gpgme_data_new_from_mem (&text,
fail_if_err (err); test_text1, strlen (test_text1), 0);
#if 1 fail_if_err (err);
err = gpgme_data_new_from_mem ( &sig, #if 1
test_sig1, strlen (test_sig1), 0 ); err = gpgme_data_new_from_mem (&sig,
#else test_sig1, strlen (test_sig1), 0);
err = gpgme_data_new_from_file ( &sig, "xx1", 1 ); #else
#endif err = gpgme_data_new_from_file (&sig, "xx1", 1);
fail_if_err (err); #endif
fail_if_err (err);
puts ("checking a valid message:\n"); puts ("checking a valid message:\n");
err = gpgme_op_verify (ctx, sig, text, NULL); err = gpgme_op_verify (ctx, sig, text, NULL);
fail_if_err (err); fail_if_err (err);
if (!gpgme_get_sig_status (ctx, 0, &status, NULL)) if (!gpgme_get_sig_status (ctx, 0, &status, NULL))
{ {
fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__); fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__);
exit (1); exit (1);
} }
print_sig_stat (ctx, status); print_sig_stat (ctx, status);
if (status != GPGME_SIG_STAT_GOOD) if (status != GPGME_SIG_STAT_GOOD)
{ {
fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__); fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__);
exit (1); exit (1);
} }
if ((nota = gpgme_get_notation (ctx))) result = gpgme_op_verify_result (ctx);
printf ("---Begin Notation---\n%s---End Notation---\n", nota ); notation = result->signatures->notations;
if (notation)
puts ("checking a manipulated message:\n"); {
gpgme_data_release (text); printf ("---Begin Notation---\n");
err = gpgme_data_new_from_mem (&text, while (notation)
test_text1f, strlen (test_text1f), 0); {
fail_if_err (err); if (notation->name)
gpgme_data_rewind (sig); printf ("%s: %s\n", notation->name, notation->value);
err = gpgme_op_verify (ctx, sig, text, NULL); else
fail_if_err (err); printf ("Policy URL: %s\n", notation->value);
if (!gpgme_get_sig_status (ctx, 0, &status, NULL)) notation = notation->next;
{ }
fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__); printf ("---End Notation---\n");
exit (1); }
}
print_sig_stat (ctx, status); puts ("checking a manipulated message:\n");
if (status != GPGME_SIG_STAT_BAD) gpgme_data_release (text);
{ err = gpgme_data_new_from_mem (&text,
fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__); test_text1f, strlen (test_text1f), 0);
exit (1); fail_if_err (err);
} gpgme_data_rewind (sig);
if ((nota = gpgme_get_notation (ctx))) err = gpgme_op_verify (ctx, sig, text, NULL);
printf ("---Begin Notation---\n%s---End Notation---\n", nota ); fail_if_err (err);
if (!gpgme_get_sig_status (ctx, 0, &status, NULL))
puts ("checking a normal signature:"); {
gpgme_data_release (sig); fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__);
gpgme_data_release (text); exit (1);
err = gpgme_data_new_from_mem (&sig, test_sig2, strlen (test_sig2), 0); }
fail_if_err (err); print_sig_stat (ctx, status);
err = gpgme_data_new (&text); if (status != GPGME_SIG_STAT_BAD)
fail_if_err (err); {
err = gpgme_op_verify (ctx, sig, NULL, text); fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__);
fail_if_err (err); exit (1);
if (!gpgme_get_sig_status (ctx, 0, &status, NULL)) }
{ result = gpgme_op_verify_result (ctx);
fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__); notation = result->signatures->notations;
exit (1); if (notation)
} {
printf ("---Begin Notation---\n");
nota = gpgme_data_release_and_get_mem (text, &len); while (notation)
for (j = 0; j < len; j++) {
if (notation->name)
printf ("%s: %s\n", notation->name, notation->value);
else
printf ("Policy URL: %s\n", notation->value);
notation = notation->next;
}
printf ("---End Notation---\n");
}
puts ("checking a normal signature:");
gpgme_data_release (sig);
gpgme_data_release (text);
err = gpgme_data_new_from_mem (&sig, test_sig2, strlen (test_sig2), 0);
fail_if_err (err);
err = gpgme_data_new (&text);
fail_if_err (err);
err = gpgme_op_verify (ctx, sig, NULL, text);
fail_if_err (err);
if (!gpgme_get_sig_status (ctx, 0, &status, NULL))
{
fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__);
exit (1);
}
nota = gpgme_data_release_and_get_mem (text, &len);
for (j = 0; j < len; j++)
putchar (nota[j]); putchar (nota[j]);
if (strncmp (nota, test_text1, strlen (test_text1))) if (strncmp (nota, test_text1, strlen (test_text1)))
{ {
fprintf (stderr, "%s:%d: Wrong plaintext\n", __FILE__, __LINE__); fprintf (stderr, "%s:%d: Wrong plaintext\n", __FILE__, __LINE__);
exit (1); exit (1);
} }
print_sig_stat (ctx, status); print_sig_stat (ctx, status);
if (status != GPGME_SIG_STAT_GOOD) if (status != GPGME_SIG_STAT_GOOD)
{ {
fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__); fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__);
exit (1); exit (1);
} }
result = gpgme_op_verify_result (ctx);
notation = result->signatures->notations;
if (notation)
{
printf ("---Begin Notation---\n");
while (notation)
{
if (notation->name)
printf ("%s: %s\n", notation->name, notation->value);
else
printf ("Policy URL: %s\n", notation->value);
notation = notation->next;
}
printf ("---End Notation---\n");
}
gpgme_data_release (sig);
}
while (argc > 1 && !strcmp (argv[1], "--loop") && ++n < 20);
if ((nota = gpgme_get_notation (ctx))) gpgme_release (ctx);
printf ("---Begin Notation---\n%s---End Notation---\n", nota); return 0;
gpgme_data_release (sig);
} while ( argc > 1 && !strcmp( argv[1], "--loop" ) && ++n < 20 );
gpgme_release (ctx);
return 0;
} }

View File

@ -169,6 +169,8 @@ main (int argc, char **argv )
GpgmeError err; GpgmeError err;
GpgmeData sig, text; GpgmeData sig, text;
GpgmeSigStat status; GpgmeSigStat status;
GpgmeVerifyResult result;
GpgmeSigNotation notation;
char *nota; char *nota;
int n = 0; int n = 0;
@ -194,8 +196,21 @@ main (int argc, char **argv )
} }
print_sig_stat (ctx, status); print_sig_stat (ctx, status);
if ( (nota=gpgme_get_notation (ctx)) ) result = gpgme_op_verify_result (ctx);
printf ("---Begin Notation---\n%s---End Notation---\n", nota); notation = result->signatures->notations;
if (notation)
{
printf ("---Begin Notation---\n");
while (notation)
{
if (notation->name)
printf ("%s: %s\n", notation->name, notation->value);
else
printf ("Policy URL: %s\n", notation->value);
notation = notation->next;
}
printf ("---End Notation---\n");
}
puts ("checking a manipulated message:\n"); puts ("checking a manipulated message:\n");
gpgme_data_release (text); gpgme_data_release (text);
@ -212,8 +227,21 @@ main (int argc, char **argv )
} }
print_sig_stat (ctx, status); print_sig_stat (ctx, status);
if ((nota=gpgme_get_notation (ctx))) result = gpgme_op_verify_result (ctx);
printf ("---Begin Notation---\n%s---End Notation---\n", nota); notation = result->signatures->notations;
if (notation)
{
printf ("---Begin Notation---\n");
while (notation)
{
if (notation->name)
printf ("%s: %s\n", notation->name, notation->value);
else
printf ("Policy URL: %s\n", notation->value);
notation = notation->next;
}
printf ("---End Notation---\n");
}
gpgme_data_release (sig); gpgme_data_release (sig);
gpgme_data_release (text); gpgme_data_release (text);