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
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
information about the result of an encryption operation in
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:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GpgmeIOCb CHANGED: Return type from void to GpgmeError.
@ -136,6 +139,14 @@ GpgmeEncryptResult NEW
gpgme_op_encrypt_result NEW
GpgmeDecryptResult 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)

7
TODO
View File

@ -14,6 +14,13 @@ Hey Emacs, this is -*- outline -*- mode!
*** GPGME_Busy, GPGME_No_Request
*** GPGME_No_Passphrase
*** 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:
** 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>
* gpgme.texi (Verify): Rewritten to take into account new and
deprecated functions and data types.
* gpgme.texi (Decrypt): Descript gpgme_op_decrypt_result and
GpgmeDecryptResult.

View File

@ -2805,7 +2805,199 @@ next operation is started on the context.
@cindex signature, verification
@cindex cryptographic operation, verification
@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}
@tindex GpgmeSigStat
@ -2855,188 +3047,183 @@ have a different status. You can get each key's status with
@end table
@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}})
The function @code{gpgme_get_sig_status} receives information about a
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 function @code{gpgme_get_sig_status} is equivalent to:
The status of the signature will be returned in @var{r_stat} if it is
not @code{NULL}. The creation time stamp of the signature will be
returned in @var{r_created} if it is not @var{NULL}.
@example
GpgmeVerifyResult result;
GpgmeSignature sig;
The function returns a statically allocated string that contains the
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
no verification could be performed.
result = gpgme_op_verify_result (ctx);
sig = result->signatures;
while (sig && idx)
@{
sig = sig->next;
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
@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
to retrieve more detailed information. @var{ctx} should be the context
used for the last signature verification, @var{idx} is used to enumerate
over all signatures starting with @code{0} and @var{whatidx} should be
@code{0} unless otherwise stated.
The function @code{gpgme_get_sig_string_attr} is equivalent to:
The following values may be used for @var{what}:
@table @code
@item GPGME_ATTR_FPR
Return the fingerprint of the key used to create the signature.
@example
GpgmeVerifyResult result;
GpgmeSignature sig;
@item GPGME_ATTR_ERRTOK
Return a token with a more detailed error description. A @var{whatidx}
of @code{0} returns an error token associated with validity calculation,
a value of @code{1} return an error token related to the certificate
checking.
result = gpgme_op_verify_result (ctx);
sig = result->signatures;
@end table
while (sig && idx)
@{
sig = sig->next;
idx--;
@}
if (!sig || idx)
return NULL;
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
@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
for attributes which can be represented by an @code{unsigned long} data
type. @var{ctx} should be the context used for the last signature
verification, @var{idx} is used to enumerate over all signatures
starting with @code{0} and @var{whatidx} should be @code{0} unless
otherwise stated.
The function @code{gpgme_get_sig_ulong_attr} is equivalent to:
The following values may be used for @var{what}:
@table @code
@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}.
@example
GpgmeVerifyResult result;
GpgmeSignature sig;
@item GPGME_ATTR_EXPIRE
Return the expiration time of the signature in seconds since Epoch.
result = gpgme_op_verify_result (ctx);
sig = result->signatures;
@item GPGME_ATTR_VALIDITY
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
is one of @code{GPGME_VALIDITY_UNKNOWN}, @code{GPGME_VALIDITY_NEVER},
@code{GPGME_VALIDITY_MARGINAL} or @code{GPGME_VALIDITY_FULL}.
while (sig && idx)
@{
sig = sig->next;
idx--;
@}
if (!sig || idx)
return 0;
@item GPGME_ATTR_SIG_STATUS
This is the same value as returned by @code{gpgme_get_sig_status}.
switch (what)
@{
case GPGME_ATTR_CREATED:
return sig->timestamp;
@item GPGME_ATTR_SIG_SUMMARY
This returns a bit vector giving a summary of the signature status.
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.
case GPGME_ATTR_EXPIRE:
return sig->exp_timestamp;
The defined bits are:
@table @code
@item GPGME_SIGSUM_VALID
The signature is fully valid.
case GPGME_ATTR_VALIDITY:
return (unsigned long) sig->validity;
@item GPGME_SIGSUM_GREEN
The signature is good but one might want to display some extra
information. Check the other bits.
case GPGME_ATTR_SIG_STATUS:
switch (sig->status)
@{
case GPGME_No_Error:
return GPGME_SIG_STAT_GOOD;
@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.
case GPGME_Bad_Signature:
return GPGME_SIG_STAT_BAD;
@item GPGME_SIGSUM_KEY_REVOKED
The key or at least one certificate has been revoked.
case GPGME_No_Public_Key:
return GPGME_SIG_STAT_NOKEY;
@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.
case GPGME_No_Data:
return GPGME_SIG_STAT_NOSIG;
@item GPGME_SIGSUM_SIG_EXPIRED
The signature has expired.
case GPGME_Sig_Expired:
return GPGME_SIG_STAT_GOOD_EXP;
@item GPGME_SIGSUM_KEY_MISSING
Can't verifydue to a missing key o certificate.
case GPGME_Key_Expired:
return GPGME_SIG_STAT_GOOD_EXPKEY;
@item GPGME_SIGSUM_CRL_MISSING
The CRL (or an equivalent mechanism) is not available.
default:
return GPGME_SIG_STAT_ERROR;
@}
@item GPGME_SIGSUM_CRL_TOO_OLD
Available CRL is too old.
case GPGME_ATTR_SIG_SUMMARY:
return sig->summary;
@item GPGME_SIGSUM_BAD_POLICY
A policy requirement was not met.
@item GPGME_SIGSUM_SYS_ERROR
A system error occured.
@end table
@end table
default:
break;
@}
return 0;
@end example
@end deftypefun
@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}
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 @code{gpgme_get_sig_key} is equivalent to:
The function is a convenient way to retrieve the keys belonging to the
fingerprints returned by @code{gpgme_get_sig_status}.
@example
GpgmeVerifyResult result;
GpgmeSignature sig;
The function returns @code{GPGME_No_Error} if the key could be
returned, @code{GPGME_Invalid_Value} if @var{r_key} is not a valid
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
result = gpgme_op_verify_result (ctx);
sig = result->signatures;
@deftypefun {char *} gpgme_get_notation (@w{GpgmeCtx @var{ctx}})
The function @code{gpgme_get_notation} can be used to retrieve
notation data from the last signature check in the context @var{ctx}.
while (sig && idx)
@{
sig = sig->next;
idx--;
@}
if (!sig || idx)
return GPGME_EOF;
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 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.
return gpgme_get_key (ctx, sig->fpr, r_key, 0, 0);
@end example
@end deftypefun
@ -3204,7 +3391,7 @@ The hash algorithm used to create this signature.
@item unsigned long class
The signature class of this signature.
@item long int created
@item long int timestamp
The creation timestamp of this signature.
@item char *fpr

View File

@ -1,5 +1,51 @@
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.
(GpgmeDecryptResult): New type.
(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;
}
/* 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
_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)
return err;
err = _gpgme_op_verify_init_result (ctx);
if (err)
return err;
if (!cipher)
return GPGME_No_Data;
if (!plain)

View File

@ -68,7 +68,6 @@ gpgme_release (GpgmeCtx ctx)
_gpgme_fd_table_deinit (&ctx->fdt);
_gpgme_release_result (ctx);
gpgme_key_release (ctx->tmp_key);
gpgme_data_release (ctx->notation);
gpgme_signers_clear (ctx);
if (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:
* @c: the context

View File

@ -188,23 +188,6 @@ typedef enum
}
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. */
typedef enum
{
@ -406,9 +389,6 @@ GpgmeError gpgme_new (GpgmeCtx *ctx);
/* Release the context 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. */
GpgmeError gpgme_set_protocol (GpgmeCtx ctx, GpgmeProtocol proto);
@ -831,7 +811,7 @@ struct _gpgme_new_signature
GpgmePubKeyAlgo pubkey_algo;
GpgmeHashAlgo hash_algo;
unsigned long class;
long int created;
long int timestamp;
char *fpr;
};
typedef struct _gpgme_new_signature *GpgmeNewSignature;
@ -856,6 +836,75 @@ GpgmeError gpgme_op_sign (GpgmeCtx ctx,
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. */
GpgmeError gpgme_op_verify_start (GpgmeCtx ctx, GpgmeData sig,
GpgmeData signed_text, GpgmeData plaintext);
@ -863,6 +912,7 @@ GpgmeError gpgme_op_verify (GpgmeCtx ctx, GpgmeData sig,
GpgmeData signed_text, GpgmeData plaintext);
/* Import. */
enum
{
/* 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) 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);
/*-- verify.c --*/
GpgmeError _gpgme_verify_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
/* From verify.c. */
GpgmeError _gpgme_op_verify_init_result (GpgmeCtx ctx);
GpgmeError _gpgme_verify_status_handler (void *priv, GpgmeStatusCode code,
char *args);

View File

@ -149,7 +149,7 @@ parse_sig_created (char *args, GpgmeNewSignature *sigp)
}
args = tail;
sig->created = strtol (args, &tail, 0);
sig->timestamp = strtol (args, &tail, 0);
if (errno || args == tail || *tail != ' ')
{
/* 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. */
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 */

File diff suppressed because it is too large Load Diff

View File

@ -112,6 +112,7 @@ status_string (GpgmeSigStat status)
return s;
}
static const char *
validity_string (GpgmeValidity val)
{
@ -132,7 +133,7 @@ validity_string (GpgmeValidity val)
static void
print_sig_stat ( GpgmeCtx ctx, GpgmeSigStat status )
print_sig_stat (GpgmeCtx ctx, GpgmeSigStat status)
{
const char *s;
time_t created;
@ -141,18 +142,20 @@ print_sig_stat ( GpgmeCtx ctx, GpgmeSigStat 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,
idx, (unsigned long) created,
gpgme_get_sig_ulong_attr (ctx, idx, GPGME_ATTR_EXPIRE, 0),
status_string(status) );
status_string (status));
printf ("sig %d: fpr/keyid: `%s' validity: %s\n",
idx, s,
validity_string (gpgme_get_sig_ulong_attr
(ctx, idx, GPGME_ATTR_VALIDITY, 0)) );
if ( !gpgme_get_sig_key (ctx, idx, &key) ) {
char *p = gpgme_key_get_as_xml ( key );
printf ("sig %d: key object:\n%s\n", idx, p );
(ctx, idx, GPGME_ATTR_VALIDITY, 0)));
if (!gpgme_get_sig_key (ctx, idx, &key))
{
char *p = gpgme_key_get_as_xml (key);
printf ("sig %d: key object:\n%s\n", idx, p);
free (p);
gpgme_key_release (key);
}
@ -160,12 +163,14 @@ print_sig_stat ( GpgmeCtx ctx, GpgmeSigStat status )
}
int
main (int argc, char **argv )
main (int argc, char *argv[])
{
GpgmeCtx ctx;
GpgmeError err;
GpgmeData sig, text;
GpgmeSigStat status;
GpgmeVerifyResult result;
GpgmeSigNotation notation;
char *nota;
int n = 0;
size_t len;
@ -174,16 +179,17 @@ main (int argc, char **argv )
err = gpgme_new (&ctx);
fail_if_err (err);
do {
err = gpgme_data_new_from_mem ( &text,
test_text1, strlen (test_text1), 0 );
do
{
err = gpgme_data_new_from_mem (&text,
test_text1, strlen (test_text1), 0);
fail_if_err (err);
#if 1
err = gpgme_data_new_from_mem ( &sig,
test_sig1, strlen (test_sig1), 0 );
#else
err = gpgme_data_new_from_file ( &sig, "xx1", 1 );
#endif
#if 1
err = gpgme_data_new_from_mem (&sig,
test_sig1, strlen (test_sig1), 0);
#else
err = gpgme_data_new_from_file (&sig, "xx1", 1);
#endif
fail_if_err (err);
puts ("checking a valid message:\n");
@ -201,8 +207,21 @@ main (int argc, char **argv )
exit (1);
}
if ((nota = gpgme_get_notation (ctx)))
printf ("---Begin Notation---\n%s---End Notation---\n", nota );
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");
}
puts ("checking a manipulated message:\n");
gpgme_data_release (text);
@ -223,8 +242,21 @@ main (int argc, char **argv )
fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__);
exit (1);
}
if ((nota = gpgme_get_notation (ctx)))
printf ("---Begin Notation---\n%s---End Notation---\n", nota );
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");
}
puts ("checking a normal signature:");
gpgme_data_release (sig);
@ -256,14 +288,26 @@ main (int argc, char **argv )
fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__);
exit (1);
}
if ((nota = gpgme_get_notation (ctx)))
printf ("---Begin Notation---\n%s---End Notation---\n", nota);
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);
} 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;
GpgmeData sig, text;
GpgmeSigStat status;
GpgmeVerifyResult result;
GpgmeSigNotation notation;
char *nota;
int n = 0;
@ -194,8 +196,21 @@ main (int argc, char **argv )
}
print_sig_stat (ctx, status);
if ( (nota=gpgme_get_notation (ctx)) )
printf ("---Begin Notation---\n%s---End Notation---\n", nota);
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");
}
puts ("checking a manipulated message:\n");
gpgme_data_release (text);
@ -212,8 +227,21 @@ main (int argc, char **argv )
}
print_sig_stat (ctx, status);
if ((nota=gpgme_get_notation (ctx)))
printf ("---Begin Notation---\n%s---End Notation---\n", nota);
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);
gpgme_data_release (text);