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.
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)
*** 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
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.
@cindex signature, verification
@cindex cryptographic operation, verification
@cindex cryptographic operation, signature check
-@cindex signature, status
-
-@deftp {Data type} {enum GpgmeSigStat}
-@tindex GpgmeSigStat
-The @code{GpgmeSigStat} type holds the result of a signature check, or
-the combined result of all signatures. The following results are
-possible:
-
-@table @code
-@item GPGME_SIG_STAT_NONE
-This status should not occur in normal operation.
-
-@item GPGME_SIG_STAT_GOOD
-This status indicates that the signature is valid. For the combined
-result this status means that all signatures are valid.
-
-@item GPGME_SIG_STAT_GOOD_EXP
-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_SIG_STAT_GOOD_EXPKEY
-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_SIG_STAT_BAD
-This status indicates that the signature is invalid. For the combined
-result this status means that all signatures are invalid.
-
-@item GPGME_SIG_STAT_NOKEY
-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_SIG_STAT_NOSIG
-This status indicates that the signature data provided was not a real
-signature.
-
-@item GPGME_SIG_STAT_ERROR
-This status indicates that there was some other error which prevented
-the signature verification.
-
-@item GPGME_SIG_STAT_DIFF
-For the combined result this status means that at least two signatures
-have a different status. You can get each key's status with
-@code{gpgme_get_sig_status}.
-@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
verification.
The results of the individual signature verifications can be retrieved
-with @code{gpgme_get_sig_status} and @code{gpgme_get_sig_key}.
+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},
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 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}.
-
-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.
-@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.
+@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:
-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.
+@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 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.
+@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 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 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}.
-
-@item GPGME_ATTR_EXPIRE
-Return the expiration time of the signature in seconds since Epoch.
+@end deftp
-@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}.
+@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:
-@item GPGME_ATTR_SIG_STATUS
-This is the same value as returned by @code{gpgme_get_sig_status}.
+@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 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.
+@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_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
-@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 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}.
-The function is a convenient way to retrieve the keys belonging to the
-fingerprints returned by @code{gpgme_get_sig_status}.
+@deftp {Data type} {enum GpgmeSigStat}
+@tindex GpgmeSigStat
+The @code{GpgmeSigStat} type holds the result of a signature check, or
+the combined result of all signatures. The following results are
+possible:
-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.
+@table @code
+@item GPGME_SIG_STAT_NONE
+This status should not occur in normal operation.
+
+@item GPGME_SIG_STAT_GOOD
+This status indicates that the signature is valid. For the combined
+result this status means that all signatures are valid.
+
+@item GPGME_SIG_STAT_GOOD_EXP
+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_SIG_STAT_GOOD_EXPKEY
+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_SIG_STAT_BAD
+This status indicates that the signature is invalid. For the combined
+result this status means that all signatures are invalid.
+
+@item GPGME_SIG_STAT_NOKEY
+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_SIG_STAT_NOSIG
+This status indicates that the signature data provided was not a real
+signature.
+
+@item GPGME_SIG_STAT_ERROR
+This status indicates that there was some other error which prevented
+the signature verification.
+
+@item GPGME_SIG_STAT_DIFF
+For the combined result this status means that at least two signatures
+have a different status. You can get each key's status with
+@code{gpgme_get_sig_status}.
+@end table
+@end deftp
+
+@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} is equivalent to:
+
+@example
+ GpgmeVerifyResult result;
+ GpgmeSignature sig;
+
+ 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}})
+The function @code{gpgme_get_sig_string_attr} is equivalent to:
+
+@example
+ GpgmeVerifyResult result;
+ GpgmeSignature sig;
+
+ result = gpgme_op_verify_result (ctx);
+ sig = result->signatures;
+
+ 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}})
+The function @code{gpgme_get_sig_ulong_attr} is equivalent to:
+
+@example
+ GpgmeVerifyResult result;
+ GpgmeSignature sig;
+
+ result = gpgme_op_verify_result (ctx);
+ sig = result->signatures;
+
+ while (sig && idx)
+ @{
+ sig = sig->next;
+ idx--;
+ @}
+ if (!sig || idx)
+ return 0;
+
+ switch (what)
+ @{
+ case GPGME_ATTR_CREATED:
+ return sig->timestamp;
+
+ case GPGME_ATTR_EXPIRE:
+ return sig->exp_timestamp;
+
+ case GPGME_ATTR_VALIDITY:
+ return (unsigned long) sig->validity;
+
+ case GPGME_ATTR_SIG_STATUS:
+ switch (sig->status)
+ @{
+ 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;
+ @}
+
+ case GPGME_ATTR_SIG_SUMMARY:
+ return sig->summary;
+
+ default:
+ break;
+ @}
+ return 0;
+@end example
@end deftypefun
-@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}.
+@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_key} is equivalent to:
+
+@example
+ GpgmeVerifyResult result;
+ GpgmeSignature sig;
+
+ result = gpgme_op_verify_result (ctx);
+ sig = result->signatures;
-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}.
+ while (sig && idx)
+ @{
+ sig = sig->next;
+ idx--;
+ @}
+ if (!sig || idx)
+ return GPGME_EOF;
-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
@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
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.
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;
+}
+
+\f
+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;
+}
+
\f
GpgmeError
_gpgme_data_append (GpgmeData dh, const char *buffer, size_t length)
if (err)
return err;
+ err = _gpgme_op_verify_init_result (ctx);
+ if (err)
+ return err;
+
if (!cipher)
return GPGME_No_Data;
if (!plain)
_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);
}
-/**
- * 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
- * %<notation> 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
}
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
{
/* 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);
GpgmePubKeyAlgo pubkey_algo;
GpgmeHashAlgo hash_algo;
unsigned long class;
- long int created;
+ long int timestamp;
char *fpr;
};
typedef struct _gpgme_new_signature *GpgmeNewSignature;
GpgmeSigMode mode);
\f
+/* 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);
GpgmeData signed_text, GpgmeData plaintext);
\f
+/* Import. */
enum
{
/* The key was new. */
-/* ops.h - internal operations stuff
+/* ops.h - Internal operation support.
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
GpgmeError _gpgme_parse_inv_userid (char *args, GpgmeInvalidUserID *userid);
\f
-/*-- 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);
\f
}
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. */
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 */
#if HAVE_CONFIG_H
#include <config.h>
#endif
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <assert.h>
+#include <errno.h>
+#include "gpgme.h"
#include "util.h"
#include "context.h"
#include "ops.h"
-#include "key.h"
-
-struct verify_result
+\f
+typedef struct
{
- GpgmeSigStat status;
- GpgmeSigStat expstatus; /* Only used by finish_sig. */
- GpgmeData notation; /* We store an XML fragment here. */
- int collecting; /* Private to finish_sig(). */
- int notation_in_data; /* Private to add_notation(). */
- char fpr[41]; /* Fingerprint of a good signature or keyid of
- a bad one. */
- ulong timestamp; /* Signature creation time. */
- ulong exptimestamp; /* Signature exipration time or 0. */
- GpgmeValidity validity;
- int wrong_key_usage;
- char trust_errtok[31]; /* Error token send with the trust status. */
-};
-typedef struct verify_result *VerifyResult;
+ struct _gpgme_op_verify_result result;
+
+ GpgmeSignature current_sig;
+} *op_data_t;
static void
-release_verify_result (void *hook)
+release_op_data (void *hook)
{
- VerifyResult result = (VerifyResult) hook;
+ op_data_t opd = (op_data_t) hook;
+ GpgmeSignature sig = opd->result.signatures;
- gpgme_data_release (result->notation);
-}
+ while (sig)
+ {
+ GpgmeSignature next = sig->next;
+ GpgmeSigNotation notation = sig->notations;
+ while (notation)
+ {
+ GpgmeSigNotation next_nota = notation->next;
-/* Check whether STRING starts with TOKEN and return true in this
- case. This is case insensitive. If NEXT is not NULL return the
- number of bytes to be added to STRING to get to the next token; a
- returned value of 0 indicates end of line. */
-static int
-is_token (const char *string, const char *token, size_t *next)
-{
- size_t n = 0;
+ if (notation->name)
+ free (notation->name);
+ if (notation->value)
+ free (notation->value);
+ notation = next_nota;
+ }
- for (;*string && *token && *string == *token; string++, token++, n++)
- ;
- if (*token || (*string != ' ' && !*string))
- return 0;
- if (next)
- {
- for (; *string == ' '; string++, n++)
- ;
- *next = n;
+ if (sig->fpr)
+ free (sig->fpr);
+ free (sig);
+ sig = next;
}
- return 1;
}
-static int
-skip_token (const char *string, size_t *next)
+
+GpgmeVerifyResult
+gpgme_op_verify_result (GpgmeCtx ctx)
{
- size_t n = 0;
+ op_data_t opd;
+ GpgmeError err;
- for (;*string && *string != ' '; string++, n++)
- ;
- for (;*string == ' '; string++, n++)
- ;
- if (!*string)
- return 0;
- if (next)
- *next = n;
- return 1;
-}
+ err = _gpgme_op_data_lookup (ctx, OPDATA_VERIFY, (void **) &opd, -1, NULL);
+ if (err || !opd)
+ return NULL;
+ return &opd->result;
+}
-static size_t
-copy_token (const char *string, char *buffer, size_t length)
+\f
+/* Build a summary vector from RESULT. */
+static void
+calc_sig_summary (GpgmeSignature sig)
{
- const char *s = string;
- char *p = buffer;
- size_t i;
-
- for (i = 1; i < length && *s && *s != ' ' ; i++)
- *p++ = *s++;
- *p = 0;
- /* continue scanning in case the copy was truncated */
- while (*s && *s != ' ')
- s++;
- return s - string;
-}
+ unsigned long sum = 0;
+ if (sig->validity == GPGME_VALIDITY_FULL
+ || sig->validity == GPGME_VALIDITY_ULTIMATE)
+ {
+ if (sig->status == GPGME_No_Error
+ || sig->status == GPGME_Sig_Expired
+ || sig->status == GPGME_Key_Expired)
+ sum |= GPGME_SIGSUM_GREEN;
+ }
+ else if (sig->validity == GPGME_VALIDITY_NEVER)
+ {
+ if (sig->status == GPGME_No_Error
+ || sig->status == GPGME_Sig_Expired
+ || sig->status == GPGME_Key_Expired)
+ sum |= GPGME_SIGSUM_RED;
+ }
+ else if (sig->status == GPGME_Bad_Signature)
+ sum |= GPGME_SIGSUM_RED;
+
+ /* FIXME: handle the case when key and message are expired. */
+ if (sig->status == GPGME_Sig_Expired)
+ sum |= GPGME_SIGSUM_SIG_EXPIRED;
+ else if (sig->status == GPGME_Key_Expired)
+ sum |= GPGME_SIGSUM_KEY_EXPIRED;
+ else if (sig->status == GPGME_No_Public_Key)
+ sum |= GPGME_SIGSUM_KEY_MISSING;
+ else if (sig->status)
+ sum |= GPGME_SIGSUM_SYS_ERROR;
+
+ if (sig->validity_reason == GPGME_Key_Revoked)
+ sum |= GPGME_SIGSUM_KEY_REVOKED;
+ else if (sig->validity_reason == GPGME_No_CRL_Known)
+ sum |= GPGME_SIGSUM_CRL_MISSING;
+ else if (sig->validity_reason == GPGME_CRL_Too_Old)
+ sum |= GPGME_SIGSUM_CRL_TOO_OLD;
+ else if (sig->validity_reason == GPGME_Policy_Mismatch)
+ sum |= GPGME_SIGSUM_BAD_POLICY;
+ else if (sig->validity_reason)
+ sum |= GPGME_SIGSUM_SYS_ERROR;
+
+ if (sig->wrong_key_usage)
+ sum |= GPGME_SIGSUM_BAD_POLICY;
+
+ /* Set the valid flag when the signature is unquestionable
+ valid. */
+ if ((sum & GPGME_SIGSUM_GREEN) && !(sum & ~GPGME_SIGSUM_GREEN))
+ sum |= GPGME_SIGSUM_VALID;
+
+ sig->summary = sum;
+}
+
-/* FIXME: Check that we are adding this to the correct signature. */
static GpgmeError
-add_notation (VerifyResult result, GpgmeStatusCode code, const char *notation)
+parse_new_sig (op_data_t opd, GpgmeStatusCode code, char *args)
{
- GpgmeData dh = result->notation;
+ GpgmeSignature sig;
+ char *end = strchr (args, ' ');
- if (!dh)
+ if (end)
{
- if (gpgme_data_new (&dh))
- return GPGME_Out_Of_Core;
- result->notation = dh;
- _gpgme_data_append_string (dh, " <notation>\n");
+ *end = '\0';
+ end++;
}
- if (code == GPGME_STATUS_NOTATION_DATA)
+ sig = calloc (1, sizeof (*sig));
+ if (!sig)
+ return GPGME_Out_Of_Core;
+ if (!opd->result.signatures)
+ opd->result.signatures = sig;
+ if (opd->current_sig)
+ opd->current_sig->next = sig;
+ opd->current_sig = sig;
+
+ switch (code)
{
- if (!result->notation_in_data)
- _gpgme_data_append_string (dh, " <data>");
- _gpgme_data_append_percentstring_for_xml (dh, notation);
- result->notation_in_data = 1;
- return 0;
+ case GPGME_STATUS_GOODSIG:
+ sig->status = GPGME_No_Error;
+ break;
+
+ case GPGME_STATUS_EXPSIG:
+ sig->status = GPGME_Sig_Expired;
+ break;
+
+ case GPGME_STATUS_EXPKEYSIG:
+ sig->status = GPGME_Key_Expired;
+ break;
+
+ case GPGME_STATUS_BADSIG:
+ sig->status = GPGME_Bad_Signature;
+ break;
+
+ case GPGME_STATUS_ERRSIG:
+ if (end)
+ {
+ int i = 0;
+ /* The return code is the 6th argument, if it is 9, the
+ problem is a missing key. */
+ while (end && i < 4)
+ end = strchr (end, ' ');
+ if (end && end[0] && (!end[1] || !end[1] == ' '))
+ {
+ switch (end[0])
+ {
+ case '4':
+ sig->status = GPGME_Unsupported_Algorithm;
+ break;
+
+ case 9:
+ sig->status = GPGME_No_Public_Key;
+ break;
+
+ default:
+ sig->status = GPGME_General_Error;
+ }
+ }
+ }
+ else
+ sig->status = GPGME_General_Error;
+ break;
+
+ default:
+ return GPGME_General_Error;
}
- if (result->notation_in_data)
+ if (*args)
{
- _gpgme_data_append_string (dh, "</data>\n");
- result->notation_in_data = 0;
+ sig->fpr = strdup (args);
+ if (!sig->fpr)
+ return GPGME_Out_Of_Core;
}
+ return 0;
+}
- if (code == GPGME_STATUS_NOTATION_NAME)
+
+static GpgmeError
+parse_valid_sig (GpgmeSignature sig, char *args)
+{
+ char *end = strchr (args, ' ');
+
+ if (end)
{
- _gpgme_data_append_string (dh, " <name>");
- _gpgme_data_append_percentstring_for_xml (dh, notation);
- _gpgme_data_append_string (dh, "</name>\n");
+ *end = '\0';
+ end++;
}
- else if (code == GPGME_STATUS_POLICY_URL)
+
+ if (!*args)
+ /* We require at least the fingerprint. */
+ return GPGME_General_Error;
+
+ if (sig->fpr)
+ free (sig->fpr);
+ sig->fpr = strdup (args);
+ if (!sig->fpr)
+ return GPGME_Out_Of_Core;
+
+ end = strchr (end, ' ');
+ if (end)
{
- _gpgme_data_append_string (dh, " <policy>");
- _gpgme_data_append_percentstring_for_xml (dh, notation);
- _gpgme_data_append_string (dh, "</policy>\n");
+ char *tail;
+ errno = 0;
+ sig->timestamp = strtol (end, &tail, 0);
+ if (errno || end == tail || (*tail && *tail != ' '))
+ return GPGME_General_Error;
+ end = tail;
+
+ sig->exp_timestamp = strtol (end, &tail, 0);
+ if (errno || end == tail || (*tail && *tail != ' '))
+ return GPGME_General_Error;
}
- else
- assert (0);
return 0;
}
-/* Finish a pending signature info collection. */
-static void
-finish_sig (VerifyResult result)
+static GpgmeError
+parse_notation (GpgmeSignature sig, GpgmeStatusCode code, char *args)
{
- struct ctx_op_data *op_data;
-
- /* We intimately know that gpgme_op_data_lookup appends the data to
- the op_data structure. We can use this here to change the type
- knowing only the hook value. */
- op_data = (struct ctx_op_data *) ((void *) result
- - sizeof (struct ctx_op_data));
- op_data->type = OPDATA_VERIFY;
-}
+ GpgmeError err;
+ GpgmeSigNotation *lastp = &sig->notations;
+ GpgmeSigNotation notation = sig->notations;
+ char *end = strchr (args, ' ');
+ if (end)
+ *end = '\0';
-GpgmeError
-_gpgme_verify_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
-{
- VerifyResult result;
- GpgmeError err;
- char *p;
- size_t n;
- int i;
+ if (code == GPGME_STATUS_NOTATION_NAME || code == GPGME_STATUS_POLICY_URL)
+ {
+ /* FIXME: We could keep a pointer to the last notation in the list. */
+ while (notation && notation->value)
+ {
+ lastp = ¬ation->next;
+ notation = notation->next;
+ }
- err = _gpgme_op_data_lookup (ctx, OPDATA_VERIFY_COLLECTING, (void **) &result,
- -1, NULL);
- if (err)
- return err;
+ if (notation)
+ /* There is another notation name without data for the
+ previous one. The crypto backend misbehaves. */
+ return GPGME_General_Error;
+
+ notation = malloc (sizeof (*sig));
+ if (!notation)
+ return GPGME_Out_Of_Core;
+ notation->next = NULL;
- if (code == GPGME_STATUS_GOODSIG || code == GPGME_STATUS_EXPSIG
- || code == GPGME_STATUS_EXPKEYSIG || code == GPGME_STATUS_BADSIG
- || code == GPGME_STATUS_ERRSIG)
+ if (code == GPGME_STATUS_NOTATION_NAME)
+ {
+ int len = strlen (args) + 1;
+
+ notation->name = malloc (len);
+ if (!notation->name)
+ {
+ free (notation);
+ return GPGME_Out_Of_Core;
+ }
+ err = _gpgme_decode_percent_string (args, ¬ation->name, len);
+ if (err)
+ return err;
+
+ notation->value = NULL;
+ }
+ else
+ {
+ int len = strlen (args) + 1;
+
+ notation->name = NULL;
+ notation->value = malloc (len);
+ if (!notation->value)
+ {
+ free (notation);
+ return GPGME_Out_Of_Core;
+ }
+ err = _gpgme_decode_percent_string (args, ¬ation->value, len);
+ if (err)
+ return err;
+ }
+ *lastp = notation;
+ }
+ else if (code == GPGME_STATUS_NOTATION_DATA)
{
- /* A new signature starts. */
- if (result)
- finish_sig (result);
- err = _gpgme_op_data_lookup (ctx, OPDATA_VERIFY_COLLECTING, (void **) &result,
- sizeof (*result), release_verify_result);
+ int len = strlen (args) + 1;
+ char *dest;
+
+ /* FIXME: We could keep a pointer to the last notation in the list. */
+ while (notation && notation->next)
+ {
+ lastp = ¬ation->next;
+ notation = notation->next;
+ }
+
+ if (!notation || !notation->name)
+ /* There is notation data without a previous notation
+ name. The crypto backend misbehaves. */
+ return GPGME_General_Error;
+
+ if (!notation->value)
+ {
+ dest = notation->value = malloc (len);
+ if (!dest)
+ return GPGME_Out_Of_Core;
+ }
+ else
+ {
+ int cur_len = strlen (notation->value);
+ dest = realloc (notation->value, len + strlen (notation->value));
+ if (!dest)
+ return GPGME_Out_Of_Core;
+ notation->value = dest;
+ dest += cur_len;
+ }
+
+ err = _gpgme_decode_percent_string (args, &dest, len);
if (err)
return err;
}
+ else
+ return GPGME_General_Error;
+ return 0;
+}
+
+
+static GpgmeError
+parse_trust (GpgmeSignature sig, GpgmeStatusCode code, char *args)
+{
+ char *end = strchr (args, ' ');
+
+ if (end)
+ *end = '\0';
switch (code)
{
- case GPGME_STATUS_NODATA:
- case GPGME_STATUS_UNEXPECTED:
- if (!result)
- return GPGME_General_Error;
- result->status = GPGME_SIG_STAT_NOSIG;
+ case GPGME_STATUS_TRUST_UNDEFINED:
+ default:
+ sig->validity = GPGME_VALIDITY_UNKNOWN;
break;
- case GPGME_STATUS_GOODSIG:
- if (!result)
- return GPGME_General_Error;
- result->expstatus = GPGME_SIG_STAT_GOOD;
+ case GPGME_STATUS_TRUST_NEVER:
+ sig->validity = GPGME_VALIDITY_NEVER;
break;
- case GPGME_STATUS_EXPSIG:
- if (!result)
- return GPGME_General_Error;
- result->expstatus = GPGME_SIG_STAT_GOOD_EXP;
+ case GPGME_STATUS_TRUST_MARGINAL:
+ sig->validity = GPGME_VALIDITY_MARGINAL;
break;
- case GPGME_STATUS_EXPKEYSIG:
- if (!result)
- return GPGME_General_Error;
- result->expstatus = GPGME_SIG_STAT_GOOD_EXPKEY;
+ case GPGME_STATUS_TRUST_FULLY:
+ case GPGME_STATUS_TRUST_ULTIMATE:
+ sig->validity = GPGME_VALIDITY_FULL;
break;
+ }
- case GPGME_STATUS_VALIDSIG:
- if (!result)
- return GPGME_General_Error;
- result->status = GPGME_SIG_STAT_GOOD;
- i = copy_token (args, result->fpr, DIM (result->fpr));
- /* Skip the formatted date. */
- while (args[i] && args[i] == ' ')
- i++;
- while (args[i] && args[i] != ' ')
- i++;
- /* And get the timestamp. */
- result->timestamp = strtoul (args + i, &p, 10);
- if (args[i])
- result->exptimestamp = strtoul (p, NULL, 10);
- break;
+ if (*args)
+ sig->validity_reason = _gpgme_map_gnupg_error (args);
+
+ return 0;
+}
- case GPGME_STATUS_BADSIG:
- if (!result)
- return GPGME_General_Error;
- result->status = GPGME_SIG_STAT_BAD;
- /* Store the keyID in the fpr field. */
- copy_token (args, result->fpr, DIM (result->fpr));
- break;
+static GpgmeError
+parse_error (GpgmeSignature sig, char *args)
+{
+ GpgmeError err;
+ char *where = strchr (args, ' ');
+ char *which;
+
+ if (where)
+ {
+ *where = '\0';
+ which = where + 1;
+
+ where = strchr (which, ' ');
+ if (where)
+ *where = '\0';
+
+ where = args;
+ }
+ else
+ return GPGME_General_Error;
+
+ err = _gpgme_map_gnupg_error (which);
+
+ if (!strcmp (where, "verify.findkey"))
+ sig->status = err;
+ else if (!strcmp (where, "verify.keyusage") && err == GPGME_Wrong_Key_Usage)
+ sig->wrong_key_usage = 1;
+
+ return 0;
+}
+
+
+GpgmeError
+_gpgme_verify_status_handler (void *priv, GpgmeStatusCode code, char *args)
+{
+ GpgmeCtx ctx = (GpgmeCtx) priv;
+ GpgmeError err;
+ op_data_t opd;
+ GpgmeSignature sig;
+
+ err = _gpgme_op_data_lookup (ctx, OPDATA_VERIFY, (void **) &opd, -1, NULL);
+ if (err)
+ return err;
+
+ sig = opd->current_sig;
+
+ switch (code)
+ {
+ case GPGME_STATUS_GOODSIG:
+ case GPGME_STATUS_EXPSIG:
+ case GPGME_STATUS_EXPKEYSIG:
+ case GPGME_STATUS_BADSIG:
case GPGME_STATUS_ERRSIG:
- if (!result)
+ if (sig)
+ calc_sig_summary (sig);
+ return parse_new_sig (opd, code, args);
+
+ case GPGME_STATUS_VALIDSIG:
+ return sig ? parse_valid_sig (sig, args) : GPGME_General_Error;
+
+ case GPGME_STATUS_NODATA:
+ case GPGME_STATUS_UNEXPECTED:
+ if (!sig)
return GPGME_General_Error;
- /* The return code is the 6th argument, if it is 9, the problem
- is a missing key. Note that this is not emitted by gpgsm */
- for (p = args, i = 0; p && *p && i < 5; i++)
- {
- p = strchr (p, ' ');
- if (p)
- while (*p == ' ')
- p++;
- }
- if (p && *(p++) == '9' && (*p == '\0' || *p == ' '))
- result->status = GPGME_SIG_STAT_NOKEY;
- else
- result->status = GPGME_SIG_STAT_ERROR;
- /* Store the keyID in the fpr field. */
- copy_token (args, result->fpr, DIM (result->fpr));
+ sig->status = GPGME_No_Data;
break;
case GPGME_STATUS_NOTATION_NAME:
case GPGME_STATUS_NOTATION_DATA:
case GPGME_STATUS_POLICY_URL:
- if (!result)
- return GPGME_General_Error;
- err = add_notation (result, code, args);
- if (err)
- return err;
- break;
+ return sig ? parse_notation (sig, code, args) : GPGME_General_Error;
case GPGME_STATUS_TRUST_UNDEFINED:
- if (!result)
- return GPGME_General_Error;
- result->validity = GPGME_VALIDITY_UNKNOWN;
- copy_token (args, result->trust_errtok,
- DIM(result->trust_errtok));
- break;
case GPGME_STATUS_TRUST_NEVER:
- if (!result)
- return GPGME_General_Error;
- result->validity = GPGME_VALIDITY_NEVER;
- copy_token (args, result->trust_errtok,
- DIM(result->trust_errtok));
- break;
case GPGME_STATUS_TRUST_MARGINAL:
- if (!result)
- return GPGME_General_Error;
- if (result->status == GPGME_SIG_STAT_GOOD)
- result->validity = GPGME_VALIDITY_MARGINAL;
- copy_token (args, result->trust_errtok,
- DIM(result->trust_errtok));
- break;
case GPGME_STATUS_TRUST_FULLY:
case GPGME_STATUS_TRUST_ULTIMATE:
- if (!result)
- return GPGME_General_Error;
- if (result->status == GPGME_SIG_STAT_GOOD)
- result->validity = GPGME_VALIDITY_FULL;
- break;
-
- case GPGME_STATUS_END_STREAM:
- break;
+ return sig ? parse_trust (sig, code, args) : GPGME_General_Error;
case GPGME_STATUS_ERROR:
- if (!result)
- return GPGME_General_Error;
- /* Generic error, we need this for gpgsm (and maybe for gpg in future)
- to get error descriptions. */
- if (is_token (args, "verify.findkey", &n) && n)
- {
- args += n;
- if (is_token (args, "No_Public_Key", NULL))
- result->status = GPGME_SIG_STAT_NOKEY;
- else
- result->status = GPGME_SIG_STAT_ERROR;
-
- }
- else if (skip_token (args, &n) && n)
- {
- args += n;
- if (is_token (args, "Wrong_Key_Usage", NULL))
- result->wrong_key_usage = 1;
- }
- break;
+ return sig ? parse_error (sig, args) : GPGME_General_Error;
case GPGME_STATUS_EOF:
- if (result)
- {
- finish_sig (result);
-
- /* FIXME: Put all notation data into one XML fragment. */
- if (result->notation)
- {
- GpgmeData dh = result->notation;
-
- if (result->notation_in_data)
- {
- _gpgme_data_append_string (dh, "</data>\n");
- result->notation_in_data = 0;
- }
- _gpgme_data_append_string (dh, "</notation>\n");
- ctx->notation = dh;
- result->notation = NULL;
- }
- }
+ if (sig)
+ calc_sig_summary (sig);
break;
-
+
default:
- /* Ignore all other codes. */
break;
}
return 0;
}
+GpgmeError
+_gpgme_op_verify_init_result (GpgmeCtx ctx)
+{
+ op_data_t opd;
+
+ return _gpgme_op_data_lookup (ctx, OPDATA_VERIFY, (void **) &opd,
+ sizeof (*opd), release_op_data);
+}
+
+
static GpgmeError
-_gpgme_op_verify_start (GpgmeCtx ctx, int synchronous,
- GpgmeData sig, GpgmeData signed_text, GpgmeData plaintext)
+_gpgme_op_verify_start (GpgmeCtx ctx, int synchronous, GpgmeData sig,
+ GpgmeData signed_text, GpgmeData plaintext)
{
- int err = 0;
+ GpgmeError err;
err = _gpgme_op_reset (ctx, synchronous);
if (err)
- goto leave;
+ return err;
+
+ err = _gpgme_op_verify_init_result (ctx);
+ if (err)
+ return err;
_gpgme_engine_set_status_handler (ctx->engine, _gpgme_verify_status_handler,
ctx);
- /* Check the supplied data. */
if (!sig)
- {
- err = GPGME_No_Data;
- goto leave;
- }
+ return GPGME_No_Data;
if (!signed_text && !plaintext)
- {
- err = GPGME_Invalid_Value;
- goto leave;
- }
- err = _gpgme_engine_op_verify (ctx->engine, sig, signed_text, plaintext);
+ return GPGME_Invalid_Value;
- leave:
- if (err)
- {
- _gpgme_engine_release (ctx->engine);
- ctx->engine = NULL;
- }
- return err;
+ return _gpgme_engine_op_verify (ctx->engine, sig, signed_text, plaintext);
}
+/* Decrypt ciphertext CIPHER and make a signature verification within
+ CTX and store the resulting plaintext in PLAIN. */
GpgmeError
gpgme_op_verify_start (GpgmeCtx ctx, GpgmeData sig, GpgmeData signed_text,
GpgmeData plaintext)
}
-/**
- * gpgme_op_verify:
- * @c: the context
- * @sig: the signature data
- * @text: the signed text
- *
- * Perform a signature check on the signature given in @sig. If @text
- * is a new and uninitialized data object, it is assumed that @sig
- * contains a normal or cleartext signature, and the plaintext is
- * returned in @text upon successful verification.
- *
- * If @text is initialized, it is assumed that @sig is a detached
- * signature for the material given in @text.
- *
- * Return value: 0 on success or an errorcode if something not related to
- * the signature itself did go wrong.
- **/
+/* Decrypt ciphertext CIPHER and make a signature verification within
+ CTX and store the resulting plaintext in PLAIN. */
GpgmeError
gpgme_op_verify (GpgmeCtx ctx, GpgmeData sig, GpgmeData signed_text,
GpgmeData plaintext)
{
GpgmeError err;
- gpgme_data_release (ctx->notation);
- ctx->notation = NULL;
-
err = _gpgme_op_verify_start (ctx, 1, sig, signed_text, plaintext);
if (!err)
err = _gpgme_wait_one (ctx);
return err;
}
+\f
+/* Compatibility interfaces. */
-/**
- * gpgme_get_sig_status:
- * @c: Context
- * @idx: Index of the signature starting at 0
- * @r_stat: Returns the status
- * @r_created: Returns the creation timestamp
- *
- * Return information about an already verified signatures.
- *
- * The result of this operation is returned in @r_stat which can take these
- * values:
- * GPGME_SIG_STAT_NONE: No status - should not happen
- * GPGME_SIG_STAT_GOOD: The signature is valid
- * GPGME_SIG_STAT_BAD: The signature is not valid
- * GPGME_SIG_STAT_NOKEY: The signature could not be checked due to a
- * missing key
- * GPGME_SIG_STAT_NOSIG: This is not a signature
- * GPGME_SIG_STAT_ERROR: Due to some other error the check could not be done.
- * GPGME_SIG_STAT_DIFF: There is more than 1 signature and they have not
- * the same status.
- * GPGME_SIG_STAT_GOOD_EXP: The signature is good but has expired.
- * GPGME_SIG_STAT_GOOD_KEYEXP: The signature is good but the key has expired.
- *
- *
- * Return value: The fingerprint or NULL in case of an problem or
- * when there are no more signatures.
- **/
-const char *
-gpgme_get_sig_status (GpgmeCtx ctx, int idx,
- GpgmeSigStat *r_stat, time_t *r_created)
+/* Get the key used to create signature IDX in CTX and return it in
+ R_KEY. */
+GpgmeError
+gpgme_get_sig_key (GpgmeCtx ctx, int idx, GpgmeKey *r_key)
{
- struct ctx_op_data *op_data;
- VerifyResult result;
+ GpgmeVerifyResult result;
+ GpgmeSignature sig;
- if (!ctx)
- return NULL; /* No results yet or verification error. */
+ result = gpgme_op_verify_result (ctx);
+ sig = result->signatures;
- op_data = ctx->op_data;
- while (op_data)
- {
- while (op_data && op_data->type != OPDATA_VERIFY)
- op_data = op_data->next;
- if (idx-- == 0)
- break;
- op_data = op_data->next;
- }
- if (!op_data)
- return NULL; /* No more signatures. */
-
- result = (VerifyResult) op_data->hook;
- if (r_stat)
- *r_stat = result->status;
- if (r_created)
- *r_created = result->timestamp;
- return result->fpr;
-}
-
-
-/* Build a summary vector from RESULT. */
-static unsigned long
-calc_sig_summary (VerifyResult result)
-{
- unsigned long sum = 0;
-
- if (result->validity == GPGME_VALIDITY_FULL
- || result->validity == GPGME_VALIDITY_ULTIMATE)
- {
- if (result->status == GPGME_SIG_STAT_GOOD
- || result->status == GPGME_SIG_STAT_GOOD_EXP
- || result->status == GPGME_SIG_STAT_GOOD_EXPKEY)
- sum |= GPGME_SIGSUM_GREEN;
- }
- else if (result->validity == GPGME_VALIDITY_NEVER)
+ while (sig && idx)
{
- if (result->status == GPGME_SIG_STAT_GOOD
- || result->status == GPGME_SIG_STAT_GOOD_EXP
- || result->status == GPGME_SIG_STAT_GOOD_EXPKEY)
- sum |= GPGME_SIGSUM_RED;
+ sig = sig->next;
+ idx--;
}
- else if (result->status == GPGME_SIG_STAT_BAD)
- sum |= GPGME_SIGSUM_RED;
-
- /* fixme: handle the case when key and message are expired. */
- if (result->status == GPGME_SIG_STAT_GOOD_EXP)
- sum |= GPGME_SIGSUM_SIG_EXPIRED;
- else if (result->status == GPGME_SIG_STAT_GOOD_EXPKEY)
- sum |= GPGME_SIGSUM_KEY_EXPIRED;
- else if (result->status == GPGME_SIG_STAT_NOKEY)
- sum |= GPGME_SIGSUM_KEY_MISSING;
- else if (result->status == GPGME_SIG_STAT_ERROR)
- sum |= GPGME_SIGSUM_SYS_ERROR;
-
- if ( !strcmp (result->trust_errtok, "Certificate_Revoked"))
- sum |= GPGME_SIGSUM_KEY_REVOKED;
- else if ( !strcmp (result->trust_errtok, "No_CRL_Known"))
- sum |= GPGME_SIGSUM_CRL_MISSING;
- else if ( !strcmp (result->trust_errtok, "CRL_Too_Old"))
- sum |= GPGME_SIGSUM_CRL_TOO_OLD;
- else if ( !strcmp (result->trust_errtok, "No_Policy_Match"))
- sum |= GPGME_SIGSUM_BAD_POLICY;
- else if (*result->trust_errtok)
- sum |= GPGME_SIGSUM_SYS_ERROR;
-
- if (result->wrong_key_usage)
- sum |= GPGME_SIGSUM_BAD_POLICY;
-
- /* Set the valid flag when the signature is unquestionable
- valid. */
- if ((sum & GPGME_SIGSUM_GREEN) && !(sum & ~GPGME_SIGSUM_GREEN))
- sum |= GPGME_SIGSUM_VALID;
+ if (!sig || idx)
+ return GPGME_EOF;
- return sum;
+ return gpgme_get_key (ctx, sig->fpr, r_key, 0, 0);
}
-const char *
-gpgme_get_sig_string_attr (GpgmeCtx ctx, int idx, GpgmeAttr what, int whatidx)
+/* Retrieve the signature status of signature IDX in CTX after a
+ successful verify operation in R_STAT (if non-null). The creation
+ time stamp of the signature is returned in R_CREATED (if non-null).
+ The function returns a string containing the fingerprint. */
+const char *gpgme_get_sig_status (GpgmeCtx ctx, int idx,
+ GpgmeSigStat *r_stat, time_t *r_created)
{
- struct ctx_op_data *op_data;
- VerifyResult result;
+ GpgmeVerifyResult result;
+ GpgmeSignature sig;
- if (!ctx)
- return NULL; /* No results yet or verification error. */
+ result = gpgme_op_verify_result (ctx);
+ sig = result->signatures;
- op_data = ctx->op_data;
- while (op_data)
+ while (sig && idx)
{
- while (op_data && op_data->type != OPDATA_VERIFY)
- op_data = op_data->next;
- if (idx-- == 0)
- break;
- op_data = op_data->next;
+ sig = sig->next;
+ idx--;
}
- if (!op_data)
- return NULL; /* No more signatures. */
+ if (!sig || idx)
+ return NULL;
- result = (VerifyResult) op_data->hook;
- switch (what)
+ if (r_stat)
{
- case GPGME_ATTR_FPR:
- return result->fpr;
- case GPGME_ATTR_ERRTOK:
- if (whatidx == 1)
- return result->wrong_key_usage? "Wrong_Key_Usage":"";
- else
- return result->trust_errtok;
- default:
- break;
+ 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;
+ }
}
- return NULL;
+ if (r_created)
+ *r_created = sig->timestamp;
+ return sig->fpr;
}
-unsigned long
-gpgme_get_sig_ulong_attr (GpgmeCtx ctx, int idx, GpgmeAttr what, int reserved)
+/* Retrieve certain attributes of a signature. IDX is the index
+ number of the signature after a successful verify operation. WHAT
+ is an attribute where GPGME_ATTR_EXPIRE is probably the most useful
+ one. WHATIDX is to be passed as 0 for most attributes . */
+unsigned long gpgme_get_sig_ulong_attr (GpgmeCtx ctx, int idx,
+ GpgmeAttr what, int whatidx)
{
- struct ctx_op_data *op_data;
- VerifyResult result;
+ GpgmeVerifyResult result;
+ GpgmeSignature sig;
- if (!ctx)
- return 0; /* No results yet or verification error. */
+ result = gpgme_op_verify_result (ctx);
+ sig = result->signatures;
- op_data = ctx->op_data;
- while (op_data)
+ while (sig && idx)
{
- while (op_data && op_data->type != OPDATA_VERIFY)
- op_data = op_data->next;
- if (idx-- == 0)
- break;
- op_data = op_data->next;
+ sig = sig->next;
+ idx--;
}
- if (!op_data)
- return 0; /* No more signatures. */
+ if (!sig || idx)
+ return 0;
- result = (VerifyResult) op_data->hook;
switch (what)
{
case GPGME_ATTR_CREATED:
- return result->timestamp;
+ return sig->timestamp;
+
case GPGME_ATTR_EXPIRE:
- return result->exptimestamp;
+ return sig->exp_timestamp;
+
case GPGME_ATTR_VALIDITY:
- return (unsigned long) result->validity;
+ return (unsigned long) sig->validity;
+
case GPGME_ATTR_SIG_STATUS:
- return (unsigned long) result->status;
+ switch (sig->status)
+ {
+ 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;
+ }
+
case GPGME_ATTR_SIG_SUMMARY:
- return calc_sig_summary (result);
+ return sig->summary;
+
default:
break;
}
}
-/**
- * gpgme_get_sig_key:
- * @c: context
- * @idx: Index of the signature starting at 0
- * @r_key: Returns the key object
- *
- * Return a key object which was used to check the signature.
- *
- * Return value: An Errorcode or 0 for success. GPGME_EOF is returned to
- * indicate that there are no more signatures.
- **/
-GpgmeError
-gpgme_get_sig_key (GpgmeCtx ctx, int idx, GpgmeKey *r_key)
+const char *gpgme_get_sig_string_attr (GpgmeCtx ctx, int idx,
+ GpgmeAttr what, int whatidx)
{
- struct ctx_op_data *op_data;
- VerifyResult result;
+ GpgmeVerifyResult result;
+ GpgmeSignature sig;
- if (!ctx || !r_key)
- return GPGME_Invalid_Value;
+ result = gpgme_op_verify_result (ctx);
+ sig = result->signatures;
- op_data = ctx->op_data;
- while (op_data)
+ while (sig && idx)
{
- while (op_data && op_data->type != OPDATA_VERIFY)
- op_data = op_data->next;
- if (idx-- == 0)
- break;
- op_data = op_data->next;
+ sig = sig->next;
+ idx--;
}
- if (!op_data)
- return GPGME_EOF;
+ if (!sig || idx)
+ return NULL;
+
+ switch (what)
+ {
+ case GPGME_ATTR_FPR:
+ return sig->fpr;
- result = (VerifyResult) op_data->hook;
+ case GPGME_ATTR_ERRTOK:
+ if (whatidx == 1)
+ return sig->wrong_key_usage ? "Wrong_Key_Usage" : "";
+ else
+ return "";
+ default:
+ break;
+ }
- return gpgme_get_key (ctx, result->fpr, r_key, 0, 0);
+ return NULL;
}
return s;
}
+
static const char *
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;
- int idx;
- GpgmeKey key;
+ const char *s;
+ time_t created;
+ int idx;
+ 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++ ) {
- printf ("sig %d: created: %lu expires: %lu status: %s\n",
- idx, (unsigned long)created,
- gpgme_get_sig_ulong_attr (ctx, idx, GPGME_ATTR_EXPIRE, 0),
- 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 );
- free (p);
- gpgme_key_release (key);
+ 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,
+ gpgme_get_sig_ulong_attr (ctx, idx, GPGME_ATTR_EXPIRE, 0),
+ 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);
+ free (p);
+ gpgme_key_release (key);
}
}
}
int
-main (int argc, char **argv )
+main (int argc, char *argv[])
{
- GpgmeCtx ctx;
- GpgmeError err;
- GpgmeData sig, text;
- GpgmeSigStat status;
- char *nota;
- int n = 0;
- size_t len;
- int j;
-
- err = gpgme_new (&ctx);
- fail_if_err (err);
+ GpgmeCtx ctx;
+ GpgmeError err;
+ GpgmeData sig, text;
+ GpgmeSigStat status;
+ GpgmeVerifyResult result;
+ GpgmeSigNotation notation;
+ char *nota;
+ int n = 0;
+ size_t len;
+ int j;
- 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
- fail_if_err (err);
+ err = gpgme_new (&ctx);
+ fail_if_err (err);
- puts ("checking a valid message:\n");
- err = gpgme_op_verify (ctx, sig, text, NULL);
- fail_if_err (err);
- if (!gpgme_get_sig_status (ctx, 0, &status, NULL))
- {
- fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__);
- exit (1);
- }
- print_sig_stat (ctx, status);
- if (status != GPGME_SIG_STAT_GOOD)
- {
- 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 );
-
- puts ("checking a manipulated message:\n");
- gpgme_data_release (text);
- err = gpgme_data_new_from_mem (&text,
- test_text1f, strlen (test_text1f), 0);
- fail_if_err (err);
- gpgme_data_rewind (sig);
- err = gpgme_op_verify (ctx, sig, text, NULL);
- fail_if_err (err);
- if (!gpgme_get_sig_status (ctx, 0, &status, NULL))
- {
- fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__);
- exit (1);
- }
- print_sig_stat (ctx, status);
- if (status != GPGME_SIG_STAT_BAD)
- {
- 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 );
+ 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
+ fail_if_err (err);
- 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);
- }
+ puts ("checking a valid message:\n");
+ err = gpgme_op_verify (ctx, sig, text, NULL);
+ fail_if_err (err);
+ if (!gpgme_get_sig_status (ctx, 0, &status, NULL))
+ {
+ fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__);
+ exit (1);
+ }
+ print_sig_stat (ctx, status);
+ if (status != GPGME_SIG_STAT_GOOD)
+ {
+ fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__);
+ exit (1);
+ }
- nota = gpgme_data_release_and_get_mem (text, &len);
- for (j = 0; j < len; j++)
+ 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);
+ err = gpgme_data_new_from_mem (&text,
+ test_text1f, strlen (test_text1f), 0);
+ fail_if_err (err);
+ gpgme_data_rewind (sig);
+ err = gpgme_op_verify (ctx, sig, text, NULL);
+ fail_if_err (err);
+ if (!gpgme_get_sig_status (ctx, 0, &status, NULL))
+ {
+ fprintf (stderr, "%s:%d: No signature\n", __FILE__, __LINE__);
+ exit (1);
+ }
+ print_sig_stat (ctx, status);
+ if (status != GPGME_SIG_STAT_BAD)
+ {
+ fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__);
+ 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");
+ }
+
+ 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]);
- if (strncmp (nota, test_text1, strlen (test_text1)))
- {
- fprintf (stderr, "%s:%d: Wrong plaintext\n", __FILE__, __LINE__);
- exit (1);
- }
-
- print_sig_stat (ctx, status);
- if (status != GPGME_SIG_STAT_GOOD)
- {
- 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);
+ if (strncmp (nota, test_text1, strlen (test_text1)))
+ {
+ fprintf (stderr, "%s:%d: Wrong plaintext\n", __FILE__, __LINE__);
+ exit (1);
+ }
+
+ print_sig_stat (ctx, status);
+ if (status != GPGME_SIG_STAT_GOOD)
+ {
+ fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__);
+ 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);
- gpgme_data_release (sig);
-
-} while ( argc > 1 && !strcmp( argv[1], "--loop" ) && ++n < 20 );
- gpgme_release (ctx);
-
- return 0;
+ gpgme_release (ctx);
+ return 0;
}
GpgmeError err;
GpgmeData sig, text;
GpgmeSigStat status;
+ GpgmeVerifyResult result;
+ GpgmeSigNotation notation;
char *nota;
int n = 0;
}
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);
}
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);