doc/
2003-04-30 Marcus Brinkmann <marcus@g10code.de> * gpgme.texi (Key Listing Mode): Add GPGME_KEYLIST_MODE_SIGS. (Manipulating Keys): Add obsoleteness note. (Key Signatures): Likewise. (Information About Keys): Likewise. (Key Management): Add new data types GpgmeSubkey, GpgmeKeySig, GpgmeUserID, and all the information about GpgmeKey. gpgme/ 2003-04-30 Marcus Brinkmann <marcus@g10code.de> * gpgme.h (struct _gpgme_key): New structure. (GpgmeKey): Define using _gpgme_key. (struct _gpgme_subkey): New structure. (GpgmeSubKey): New type. (struct _gpgme_key_sig): New structure. (GpgmeKeySig): New type. (struct _gpgme_user_id): New structure. (GpgmeUserID): New type. (struct _gpgme_op_keylist_result): New structure. (GpgmeKeyListResult): New type. (gpgme_op_keylist_result): New function. (gpgme_key_get_as_xml): Remove prototype. * context.h (struct gpgme_context_s): Remove members tmp_key, tmp_uid, key_cond and key_queue. (struct key_queue_item_s): Remove structure. (struct user_id_s): Remove structure. (struct gpgme_recipients_s): Replace with simple GpgmeUserID list. * gpgme.c (gpgme_release): Do not release CTX->tmp_key. * ops.h (_gpgme_key_add_subkey, _gpgme_key_append_name, _gpgme_key_add_sig, _gpgme_trust_item_new): New prototypes. * rungpg.c (command_cb): Return GpgmeError instead int. New variable ERR. Use it to hold return value of cmd handler. (gpg_delete): Access fingerprint of key directly. (append_args_from_signers): Likewise. (gpg_edit): Likewise. (append_args_from_recipients): Use GpgmeUserID for recipient list. * engine-gpgsm.c: Do not include "key.h". (gpgsm_delete): Access fingerprint of key directly. (gpgsm_sign): Likewise. (set_recipients): Use GpgmeUserID for recipients. Invert invalid user ID flag. * key.h: File removed. * key.c: Completely reworked to use exposed GpgmeKey data types. * keylist.c: Likewise. * recipient.c: Completely reworked to use GpgmeUserID. tests/ 2003-04-30 Marcus Brinkmann <marcus@g10code.de> * gpg/t-keylist.c: Rewritten. * gpgsm/t-keylist.c (main): Rewritten. * gpg/t-edit.c (main): Do not use gpgme_key_get_as_xml. Use gpgme_key_unref instead gpgme_key_release. * gpg/t-signers.c (main): Use gpgme_key_unref instead gpgme_key_release.
This commit is contained in:
parent
18fb96bdcd
commit
ba333bf07e
29
NEWS
29
NEWS
@ -4,7 +4,8 @@ Noteworthy changes in version 0.4.1 (unreleased)
|
|||||||
* GPGME_ATTR_IS_SECRET is not anymore representable as a string.
|
* GPGME_ATTR_IS_SECRET is not anymore representable as a string.
|
||||||
|
|
||||||
* gpgme_op_verify and gpgme_op_decrypt_verify don't return a status
|
* gpgme_op_verify and gpgme_op_decrypt_verify don't return a status
|
||||||
summary anymore. Use gpgme_get_sig_status to retrieve the individual stati.
|
summary anymore. Use gpgme_get_sig_status to retrieve the individual
|
||||||
|
stati.
|
||||||
|
|
||||||
* GpgmeIOCb changed from a void function to a function returning a
|
* GpgmeIOCb changed from a void function to a function returning a
|
||||||
GpgmeError value. However, it will always return 0, so you can
|
GpgmeError value. However, it will always return 0, so you can
|
||||||
@ -87,7 +88,7 @@ Noteworthy changes in version 0.4.1 (unreleased)
|
|||||||
a GpgmeEncryptResult object.
|
a GpgmeEncryptResult object.
|
||||||
|
|
||||||
* The new gpgme_op_decrypt_result function provides detailed
|
* The new gpgme_op_decrypt_result function provides detailed
|
||||||
information about the result of an encryption operation in
|
information about the result of a decryption operation in
|
||||||
a GpgmeDecryptResult object.
|
a GpgmeDecryptResult object.
|
||||||
|
|
||||||
* The new gpgme_op_verify_result function provides detailed
|
* The new gpgme_op_verify_result function provides detailed
|
||||||
@ -106,6 +107,19 @@ Noteworthy changes in version 0.4.1 (unreleased)
|
|||||||
* Keys are not cached internally anymore, so the force_update argument
|
* Keys are not cached internally anymore, so the force_update argument
|
||||||
to gpgme_get_key has been removed.
|
to gpgme_get_key has been removed.
|
||||||
|
|
||||||
|
* GpgmeKey objects have now directly accessible data so the
|
||||||
|
gpgme_key_get_string_attr, gpgme_key_get_ulong_attr,
|
||||||
|
gpgme_key_sig_get_string_attr and gpgme_key_sig_get_ulong_attr
|
||||||
|
functions are deprecated. Also, gpgme_key_release is now
|
||||||
|
deprecated. The gpgme_key_get_as_xml function has been dropped.
|
||||||
|
|
||||||
|
* Because all interfaces using attributes are deprecated, the
|
||||||
|
GpgmeAttr data type is also deprecated.
|
||||||
|
|
||||||
|
* The new gpgme_op_keylist_result function provides detailed
|
||||||
|
information about the result of a key listing operation in
|
||||||
|
a GpgmeKeyListResult object.
|
||||||
|
|
||||||
* Interface changes relative to the 0.4.0 release:
|
* Interface changes relative to the 0.4.0 release:
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
GpgmeIOCb CHANGED: Return type from void to GpgmeError.
|
GpgmeIOCb CHANGED: Return type from void to GpgmeError.
|
||||||
@ -163,6 +177,17 @@ gpgme_trust_item_release DEPRECATED: Use gpgme_trust_item_unref.
|
|||||||
gpgme_trust_item_get_string_attr DEPRECATED
|
gpgme_trust_item_get_string_attr DEPRECATED
|
||||||
gpgme_trust_item_get_ulong_attr DEPRECATED
|
gpgme_trust_item_get_ulong_attr DEPRECATED
|
||||||
gpgme_get_key CHANGED: Removed force_update argument.
|
gpgme_get_key CHANGED: Removed force_update argument.
|
||||||
|
GpgmeSubKey NEW
|
||||||
|
GpgmeKeySig NEW
|
||||||
|
GpgmeUserID NEW
|
||||||
|
GpgmeKey CHANGED: Now has user accessible data members.
|
||||||
|
gpgme_key_get_string_attr DEPRECATED
|
||||||
|
gpgme_key_get_ulong_attr DEPRECATED
|
||||||
|
gpgme_key_sig_get_string_attr DEPRECATED
|
||||||
|
gpgme_key_sig_get_ulong_attr DEPRECATED
|
||||||
|
gpgme_key_get_as_xml REMOVED
|
||||||
|
GpgmeKeyListResult NEW
|
||||||
|
gpgme_op_keylist_result NEW
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Noteworthy changes in version 0.4.0 (2002-12-23)
|
Noteworthy changes in version 0.4.0 (2002-12-23)
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
2003-04-30 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
* gpgme.texi (Key Listing Mode): Add GPGME_KEYLIST_MODE_SIGS.
|
||||||
|
(Manipulating Keys): Add obsoleteness note.
|
||||||
|
(Key Signatures): Likewise.
|
||||||
|
(Information About Keys): Likewise.
|
||||||
|
(Key Management): Add new data types GpgmeSubkey, GpgmeKeySig,
|
||||||
|
GpgmeUserID, and all the information about GpgmeKey.
|
||||||
|
|
||||||
2003-04-29 Marcus Brinkmann <marcus@g10code.de>
|
2003-04-29 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* gpgme.texi (Listing Keys): Remove force_update argument from
|
* gpgme.texi (Listing Keys): Remove force_update argument from
|
||||||
|
351
doc/gpgme.texi
351
doc/gpgme.texi
@ -1647,6 +1647,10 @@ source should be should be searched for keys in the keylisting
|
|||||||
operation. The type of external source is dependant on the crypto
|
operation. The type of external source is dependant on the crypto
|
||||||
engine used. For example, it can be a remote keyserver or LDAP
|
engine used. For example, it can be a remote keyserver or LDAP
|
||||||
certificate server.
|
certificate server.
|
||||||
|
|
||||||
|
@item GPGME_KEYLIST_MODE_SIGS
|
||||||
|
The @code{GPGME_KEYLIST_MODE_SIGS} symbol specifies that the key
|
||||||
|
signatures should be included in the listed keys.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
At least one of @code{GPGME_KEYLIST_MODE_LOCAL} and
|
At least one of @code{GPGME_KEYLIST_MODE_LOCAL} and
|
||||||
@ -1785,11 +1789,230 @@ signers are specified. This is always done by specifying the
|
|||||||
respective keys that should be used for the operation. The following
|
respective keys that should be used for the operation. The following
|
||||||
section describes how such keys can be selected and manipulated.
|
section describes how such keys can be selected and manipulated.
|
||||||
|
|
||||||
@deftp {Data type} GpgmeKey
|
@deftp {Data type} GpgmeSubkey
|
||||||
The @code{GpgmeKey} type is a handle for a public or secret key, and
|
The @code{GpgmeSubKey} type is a pointer to a subkey structure. Sub
|
||||||
is used to select the key for operations involving it.
|
keys are one component of a @code{GpgmeKey} object. In fact, subkeys
|
||||||
|
are those parts that contains the real information about the
|
||||||
|
individual cryptographic keys that belong to the same key object. One
|
||||||
|
@code{GpgmeKey} can contain several subkeys. The first subkey in the
|
||||||
|
linked list is also called the primary key.
|
||||||
|
|
||||||
A key can contain several user IDs and sub keys.
|
The subkey structure has the following members:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item GpgmeSubkey next
|
||||||
|
This is a pointer to the next subkey structure in the linked list, or
|
||||||
|
@code{NULL} if this is the last element.
|
||||||
|
|
||||||
|
@item unsigned int revoked : 1
|
||||||
|
This is true if the subkey is revoked.
|
||||||
|
|
||||||
|
@item unsigned int expired : 1
|
||||||
|
This is true if the subkey is expired.
|
||||||
|
|
||||||
|
@item unsigned int disabled : 1
|
||||||
|
This is true if the subkey is disabled.
|
||||||
|
|
||||||
|
@item unsigned int invalid : 1
|
||||||
|
This is true if the subkey is invalid.
|
||||||
|
|
||||||
|
@item unsigned int can_encrypt : 1
|
||||||
|
This is true if the subkey can be used for encryption.
|
||||||
|
|
||||||
|
@item unsigned int can_sign : 1
|
||||||
|
This is true if the subkey can be used for signing.
|
||||||
|
|
||||||
|
@item unsigned int can_certify : 1
|
||||||
|
This is true if the subkey can be used for certification.
|
||||||
|
|
||||||
|
@item unsigned int secret : 1
|
||||||
|
This is true if the subkey is a secret key.
|
||||||
|
|
||||||
|
@item GpgmePubKeyAlgo pubkey_algo
|
||||||
|
This is the public key algorithm supported by this subkey.
|
||||||
|
|
||||||
|
@item unsigned int length
|
||||||
|
This is the length of the subkey (in bits).
|
||||||
|
|
||||||
|
@item char *keyid
|
||||||
|
This is the key ID of the subkey in hexadecimal digits.
|
||||||
|
|
||||||
|
@item char *fpr
|
||||||
|
This is the fingerprint of the subkey in hexadecimal digits, if
|
||||||
|
available. This is usually only available for the primary key.
|
||||||
|
|
||||||
|
@item long int timestamp
|
||||||
|
This is the creation timestamp of the subkey. This is -1 if the
|
||||||
|
timestamp is invalid, and 0 if it is not available.
|
||||||
|
|
||||||
|
@item long int expires
|
||||||
|
This is the expiration timestamp of the subkey, or 0 if the subkey
|
||||||
|
does not expire.
|
||||||
|
@end table
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftp {Data type} GpgmeKeySig
|
||||||
|
The @code{GpgmeKeySig} type is a pointer to a key signature structure.
|
||||||
|
Key signatures are one component of a @code{GpgmeKey} object, and
|
||||||
|
validate user IDs on the key.
|
||||||
|
|
||||||
|
The signatures on a key are only available if the key was retrieved
|
||||||
|
via a listing operation with the @code{GPGME_KEYLIST_MODE_SIGS} mode
|
||||||
|
enabled, because it is expensive to retrieve all signatures of a key.
|
||||||
|
|
||||||
|
The key signature structure has the following members:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item GpgmeKeySig next
|
||||||
|
This is a pointer to the next key signature structure in the linked
|
||||||
|
list, or @code{NULL} if this is the last element.
|
||||||
|
|
||||||
|
@item unsigned int revoked : 1
|
||||||
|
This is true if the key signature is a revocation signature.
|
||||||
|
|
||||||
|
@item unsigned int expired : 1
|
||||||
|
This is true if the key signature is expired.
|
||||||
|
|
||||||
|
@item unsigned int invalid : 1
|
||||||
|
This is true if the key signature is invalid.
|
||||||
|
|
||||||
|
@item unsigned int disabled : 1
|
||||||
|
This is true if the key signature is exportable.
|
||||||
|
|
||||||
|
@item GpgmePubKeyAlgo pubkey_algo
|
||||||
|
This is the public key algorithm used to create the signature.
|
||||||
|
|
||||||
|
@item char *keyid
|
||||||
|
This is the key ID of the key (in hexadecimal digits) used to create
|
||||||
|
the signature.
|
||||||
|
|
||||||
|
@item long int timestamp
|
||||||
|
This is the creation timestamp of the key signature. This is -1 if
|
||||||
|
the timestamp is invalid, and 0 if it is not available.
|
||||||
|
|
||||||
|
@item long int expires
|
||||||
|
This is the expiration timestamp of the key signature, or 0 if the key
|
||||||
|
signature does not expire.
|
||||||
|
|
||||||
|
@item GpgmeError status
|
||||||
|
This is the status of the signature and has the same meaning as the
|
||||||
|
member of the same name in a @code{GpgmeSignature} object.
|
||||||
|
|
||||||
|
@item unsigned int class
|
||||||
|
This specifies the signature class of the key signature. The meaning
|
||||||
|
is specific to the crypto engine.
|
||||||
|
|
||||||
|
@item char *uid
|
||||||
|
This is the main user ID of the key used to create the signature.
|
||||||
|
|
||||||
|
@item char *name
|
||||||
|
This is the name component of @code{uid}, if available.
|
||||||
|
|
||||||
|
@item char *comment
|
||||||
|
This is the comment component of @code{uid}, if available.
|
||||||
|
|
||||||
|
@item char *email
|
||||||
|
This is the email component of @code{uid}, if available.
|
||||||
|
@end table
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftp {Data type} GpgmeUserID
|
||||||
|
A user ID is a component of a @code{GpgmeKey} object. One key can
|
||||||
|
have many user IDs. The first one in the list is the main (or
|
||||||
|
primary) user ID.
|
||||||
|
|
||||||
|
The user ID structure has the following members.
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item GpgmeUserID next
|
||||||
|
This is a pointer to the next user ID structure in the linked list, or
|
||||||
|
@code{NULL} if this is the last element.
|
||||||
|
|
||||||
|
@item unsigned int revoked : 1
|
||||||
|
This is true if the user ID is revoked.
|
||||||
|
|
||||||
|
@item unsigned int invalid : 1
|
||||||
|
This is true if the user ID is invalid.
|
||||||
|
|
||||||
|
@item GpgmeValidity validity
|
||||||
|
This specifies the validity of the user ID.
|
||||||
|
|
||||||
|
@item char *uid
|
||||||
|
This is the user ID string.
|
||||||
|
|
||||||
|
@item char *name
|
||||||
|
This is the name component of @code{uid}, if available.
|
||||||
|
|
||||||
|
@item char *comment
|
||||||
|
This is the comment component of @code{uid}, if available.
|
||||||
|
|
||||||
|
@item char *email
|
||||||
|
This is the email component of @code{uid}, if available.
|
||||||
|
|
||||||
|
@item GpgmeKeySig signatures
|
||||||
|
This is a linked list with the signatures on this user ID.
|
||||||
|
@end table
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftp {Data type} GpgmeKey
|
||||||
|
The @code{GpgmeKey} type is a pointer to a key object. It has the
|
||||||
|
following members:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item unsigned int revoked : 1
|
||||||
|
This is true if the key is revoked.
|
||||||
|
|
||||||
|
@item unsigned int expired : 1
|
||||||
|
This is true if the key is expired.
|
||||||
|
|
||||||
|
@item unsigned int disabled : 1
|
||||||
|
This is true if the key is disabled.
|
||||||
|
|
||||||
|
@item unsigned int invalid : 1
|
||||||
|
This is true if the key is invalid.
|
||||||
|
|
||||||
|
@item unsigned int can_encrypt : 1
|
||||||
|
This is true if the key (ie one of its subkeys) can be used for
|
||||||
|
encryption.
|
||||||
|
|
||||||
|
@item unsigned int can_sign : 1
|
||||||
|
This is true if the key (ie one of its subkeys) can be used for
|
||||||
|
signing.
|
||||||
|
|
||||||
|
@item unsigned int can_certify : 1
|
||||||
|
This is true if the key (ie one of its subkeys) can be used for
|
||||||
|
certification.
|
||||||
|
|
||||||
|
@item unsigned int secret : 1
|
||||||
|
This is true if the key is a secret key.
|
||||||
|
|
||||||
|
@item GpgmeProtocol protocol
|
||||||
|
This is the protocol supported by this key.
|
||||||
|
|
||||||
|
@item char *issuer_serial
|
||||||
|
If @code{protocol} is @code{GPGME_PROTOCOL_CMS}, then this is the
|
||||||
|
issuer serial.
|
||||||
|
|
||||||
|
@item char *issuer_name
|
||||||
|
If @code{protocol} is @code{GPGME_PROTOCOL_CMS}, then this is the
|
||||||
|
issuer name.
|
||||||
|
|
||||||
|
@item char *chain_id
|
||||||
|
If @code{protocol} is @code{GPGME_PROTOCOL_CMS}, then this is the
|
||||||
|
chain ID, which can be used to built the certificate chain.
|
||||||
|
|
||||||
|
@item GpgmeValidity owner_trust
|
||||||
|
If @code{protocol} is @code{GPGME_PROTOCOL_OpenPGP}, then this is the
|
||||||
|
owner trust.
|
||||||
|
|
||||||
|
@item GpgmeSubkey subkeys
|
||||||
|
This is a linked list with the subkeys of the key. The first subkey
|
||||||
|
in the list is the primary key and usually available.
|
||||||
|
|
||||||
|
@item GpgmeUserID uids
|
||||||
|
This is a linked list with the user IDs of the key. The first user ID
|
||||||
|
in the list is the main (or primary) user ID.
|
||||||
|
@end table
|
||||||
@end deftp
|
@end deftp
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
@ -1880,6 +2103,10 @@ there is not enough memory for the operation.
|
|||||||
The function @code{gpgme_op_keylist_next} ends a pending key list
|
The function @code{gpgme_op_keylist_next} ends a pending key list
|
||||||
operation in the context @var{ctx}.
|
operation in the context @var{ctx}.
|
||||||
|
|
||||||
|
After the operation completed successfully, the result of the key
|
||||||
|
listing operation can be retrieved with
|
||||||
|
@code{gpgme_op_keylist_result}.
|
||||||
|
|
||||||
The function returns @code{GPGME_Invalid_Value} if @var{ctx} is not a
|
The function returns @code{GPGME_Invalid_Value} if @var{ctx} is not a
|
||||||
valid pointer, and @code{GPGME_Out_Of_Core} if at some time during the
|
valid pointer, and @code{GPGME_Out_Of_Core} if at some time during the
|
||||||
operation there was not enough memory available.
|
operation there was not enough memory available.
|
||||||
@ -1914,6 +2141,29 @@ if (err)
|
|||||||
@}
|
@}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
@deftp {Data type} {GpgmeKeyListResult}
|
||||||
|
This is a pointer to a structure used to store the result of a
|
||||||
|
@code{gpgme_op_keylist_*} operation. After successfully ending a key
|
||||||
|
listing operation, you can retrieve the pointer to the result with
|
||||||
|
@code{gpgme_op_keylist_result}. The structure contains the following
|
||||||
|
member:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item unsigned int truncated : 1
|
||||||
|
This is true if the crypto backend had to truncate the result, and
|
||||||
|
less than the desired keys could be listed.
|
||||||
|
@end table
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftypefun GpgmeKeyListResult gpgme_op_keylist_result (@w{GpgmeCtx @var{ctx}})
|
||||||
|
The function @code{gpgme_op_keylist_result} returns a
|
||||||
|
@code{GpgmeKeyListResult} pointer to a structure holding the result of
|
||||||
|
a @code{gpgme_op_keylist_*} operation. The pointer is only valid if
|
||||||
|
the last operation on the context was a key listing operation, and if
|
||||||
|
this operation finished successfully. The returned pointer is only
|
||||||
|
valid until the next operation is started on the context.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
In a simple program, for which a blocking operation is acceptable, the
|
In a simple program, for which a blocking operation is acceptable, the
|
||||||
following function can be used to retrieve a single key.
|
following function can be used to retrieve a single key.
|
||||||
|
|
||||||
@ -1939,14 +2189,44 @@ available.
|
|||||||
@cindex key, attributes
|
@cindex key, attributes
|
||||||
@cindex attributes, of a key
|
@cindex attributes, of a key
|
||||||
|
|
||||||
@deftypefun {char *} gpgme_key_get_as_xml (@w{GpgmeKey @var{key}})
|
Please see the beginning of this section for more information about
|
||||||
The function @code{gpgme_key_get_as_xml} returns a string in
|
@code{GpgmeKey} objects.
|
||||||
@acronym{XML} format describing the key @var{key}. The user has to
|
|
||||||
release the string with @code{free}.
|
|
||||||
|
|
||||||
The function returns @code{NULL} if @var{key} is not a valid pointer,
|
@deftp {Data type} GpgmeValidity
|
||||||
or there is not enough memory available.
|
The @code{GpgmeValidity} type is used to specify the validity of a user ID
|
||||||
@end deftypefun
|
in a key. The following validities are defined:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item GPGME_VALIDITY_UNKNOWN
|
||||||
|
The user ID is of unknown validity. The string representation of this
|
||||||
|
validity is ``?''.
|
||||||
|
|
||||||
|
@item GPGME_VALIDITY_UNDEFINED
|
||||||
|
The validity of the user ID is undefined. The string representation of this
|
||||||
|
validity is ``q''.
|
||||||
|
|
||||||
|
@item GPGME_VALIDITY_NEVER
|
||||||
|
The user ID is never valid. The string representation of this
|
||||||
|
validity is ``n''.
|
||||||
|
|
||||||
|
@item GPGME_VALIDITY_MARGINAL
|
||||||
|
The user ID is marginally valid. The string representation of this
|
||||||
|
validity is ``m''.
|
||||||
|
|
||||||
|
@item GPGME_VALIDITY_FULL
|
||||||
|
The user ID is fully valid. The string representation of this
|
||||||
|
validity is ``f''.
|
||||||
|
|
||||||
|
@item GPGME_VALIDITY_ULTIMATE
|
||||||
|
The user ID is ultimately valid. The string representation of this
|
||||||
|
validity is ``u''.
|
||||||
|
@end table
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
|
||||||
|
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} GpgmeAttr
|
@deftp {Data type} GpgmeAttr
|
||||||
The @code{GpgmeAttr} type is used to specify a key or trust item
|
The @code{GpgmeAttr} type is used to specify a key or trust item
|
||||||
@ -2080,37 +2360,6 @@ is representable as a string.
|
|||||||
@end table
|
@end table
|
||||||
@end deftp
|
@end deftp
|
||||||
|
|
||||||
@deftp {Data type} GpgmeValidity
|
|
||||||
The @code{GpgmeValidity} type is used to specify the validity of a user ID
|
|
||||||
in a key. The following validities are defined:
|
|
||||||
|
|
||||||
@table @code
|
|
||||||
@item GPGME_VALIDITY_UNKNOWN
|
|
||||||
The user ID is of unknown validity. The string representation of this
|
|
||||||
validity is ``?''.
|
|
||||||
|
|
||||||
@item GPGME_VALIDITY_UNDEFINED
|
|
||||||
The validity of the user ID is undefined. The string representation of this
|
|
||||||
validity is ``q''.
|
|
||||||
|
|
||||||
@item GPGME_VALIDITY_NEVER
|
|
||||||
The user ID is never valid. The string representation of this
|
|
||||||
validity is ``n''.
|
|
||||||
|
|
||||||
@item GPGME_VALIDITY_MARGINAL
|
|
||||||
The user ID is marginally valid. The string representation of this
|
|
||||||
validity is ``m''.
|
|
||||||
|
|
||||||
@item GPGME_VALIDITY_FULL
|
|
||||||
The user ID is fully valid. The string representation of this
|
|
||||||
validity is ``f''.
|
|
||||||
|
|
||||||
@item GPGME_VALIDITY_ULTIMATE
|
|
||||||
The user ID is ultimately valid. The string representation of this
|
|
||||||
validity is ``u''.
|
|
||||||
@end table
|
|
||||||
@end deftp
|
|
||||||
|
|
||||||
@deftypefun {const char *} gpgme_key_get_string_attr (@w{GpgmeKey @var{key}}, @w{GpgmeAttr @var{what}}, @w{const void *@var{reserved}}, @w{int @var{idx}})
|
@deftypefun {const char *} gpgme_key_get_string_attr (@w{GpgmeKey @var{key}}, @w{GpgmeAttr @var{what}}, @w{const void *@var{reserved}}, @w{int @var{idx}})
|
||||||
The function @code{gpgme_key_get_string_attr} returns the value of the
|
The function @code{gpgme_key_get_string_attr} returns the value of the
|
||||||
string-representable attribute @var{what} of key @var{key}. If the
|
string-representable attribute @var{what} of key @var{key}. If the
|
||||||
@ -2145,6 +2394,10 @@ or @var{reserved} not @code{NULL}.
|
|||||||
@cindex key, signatures
|
@cindex key, signatures
|
||||||
@cindex signatures, on a key
|
@cindex signatures, on a key
|
||||||
|
|
||||||
|
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 signatures on a key are only available if the key was retrieved
|
The signatures on a key are only available if the key was retrieved
|
||||||
via a listing operation with the @code{GPGME_KEYLIST_MODE_SIGS} mode
|
via a listing operation with the @code{GPGME_KEYLIST_MODE_SIGS} mode
|
||||||
enabled, because it is expensive to retrieve all signatures of a key.
|
enabled, because it is expensive to retrieve all signatures of a key.
|
||||||
@ -2253,12 +2506,18 @@ the key @var{key}.
|
|||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
|
||||||
@deftypefun void gpgme_key_unref (@w{GpgmeKey @var{key}})
|
@deftypefun void gpgme_key_unref (@w{GpgmeKey @var{key}})
|
||||||
@deftypefunx void gpgme_key_release (@w{GpgmeKey @var{key}})
|
|
||||||
The function @code{gpgme_key_unref} releases a reference for the key
|
The function @code{gpgme_key_unref} releases a reference for the key
|
||||||
@var{key}. If this was the last reference, the key will be destroyed
|
@var{key}. If this was the last reference, the key will be destroyed
|
||||||
and all resources associated to it will be released.
|
and all resources associated to it will be released.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
The function @code{gpgme_key_release} is an alias for
|
|
||||||
|
The following interface is deprecated and only provided for backward
|
||||||
|
compatibility. Don't use it. It will be removed in a future version
|
||||||
|
of @acronym{GPGME}.
|
||||||
|
|
||||||
|
@deftypefun void gpgme_key_release (@w{GpgmeKey @var{key}})
|
||||||
|
The function @code{gpgme_key_release} is equivalent to
|
||||||
@code{gpgme_key_unref}.
|
@code{gpgme_key_unref}.
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
|
||||||
@ -2610,10 +2869,10 @@ value of 2 refers to a user ID.
|
|||||||
@item int level
|
@item int level
|
||||||
This is the trust level.
|
This is the trust level.
|
||||||
|
|
||||||
@item char *otrust
|
@item char *owner_trust
|
||||||
The owner trust if @code{type} is 1.
|
The owner trust if @code{type} is 1.
|
||||||
|
|
||||||
@item char *val
|
@item char *validity
|
||||||
The calculated validity.
|
The calculated validity.
|
||||||
|
|
||||||
@item char *name
|
@item char *name
|
||||||
|
@ -1,3 +1,42 @@
|
|||||||
|
2003-04-30 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
* gpgme.h (struct _gpgme_key): New structure.
|
||||||
|
(GpgmeKey): Define using _gpgme_key.
|
||||||
|
(struct _gpgme_subkey): New structure.
|
||||||
|
(GpgmeSubKey): New type.
|
||||||
|
(struct _gpgme_key_sig): New structure.
|
||||||
|
(GpgmeKeySig): New type.
|
||||||
|
(struct _gpgme_user_id): New structure.
|
||||||
|
(GpgmeUserID): New type.
|
||||||
|
(struct _gpgme_op_keylist_result): New structure.
|
||||||
|
(GpgmeKeyListResult): New type.
|
||||||
|
(gpgme_op_keylist_result): New function.
|
||||||
|
(gpgme_key_get_as_xml): Remove prototype.
|
||||||
|
* context.h (struct gpgme_context_s): Remove members tmp_key,
|
||||||
|
tmp_uid, key_cond and key_queue.
|
||||||
|
(struct key_queue_item_s): Remove structure.
|
||||||
|
(struct user_id_s): Remove structure.
|
||||||
|
(struct gpgme_recipients_s): Replace with simple
|
||||||
|
GpgmeUserID list.
|
||||||
|
* gpgme.c (gpgme_release): Do not release CTX->tmp_key.
|
||||||
|
* ops.h (_gpgme_key_add_subkey, _gpgme_key_append_name,
|
||||||
|
_gpgme_key_add_sig, _gpgme_trust_item_new): New prototypes.
|
||||||
|
* rungpg.c (command_cb): Return GpgmeError instead int.
|
||||||
|
New variable ERR. Use it to hold return value of cmd handler.
|
||||||
|
(gpg_delete): Access fingerprint of key directly.
|
||||||
|
(append_args_from_signers): Likewise.
|
||||||
|
(gpg_edit): Likewise.
|
||||||
|
(append_args_from_recipients): Use GpgmeUserID for recipient list.
|
||||||
|
* engine-gpgsm.c: Do not include "key.h".
|
||||||
|
(gpgsm_delete): Access fingerprint of key directly.
|
||||||
|
(gpgsm_sign): Likewise.
|
||||||
|
(set_recipients): Use GpgmeUserID for recipients. Invert invalid
|
||||||
|
user ID flag.
|
||||||
|
* key.h: File removed.
|
||||||
|
* key.c: Completely reworked to use exposed GpgmeKey data types.
|
||||||
|
* keylist.c: Likewise.
|
||||||
|
* recipient.c: Completely reworked to use GpgmeUserID.
|
||||||
|
|
||||||
2003-04-29 Marcus Brinkmann <marcus@g10code.de>
|
2003-04-29 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* gpgme.h (gpgme_get_key): Remove force_update argument.
|
* gpgme.h (gpgme_get_key): Remove force_update argument.
|
||||||
|
@ -56,15 +56,8 @@ struct ctx_op_data
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct key_queue_item_s
|
/* The context defines an environment in which crypto operations can
|
||||||
{
|
be performed (sequentially). */
|
||||||
struct key_queue_item_s *next;
|
|
||||||
GpgmeKey key;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Currently we need it at several places, so we put the definition
|
|
||||||
into this header file. */
|
|
||||||
struct gpgme_context_s
|
struct gpgme_context_s
|
||||||
{
|
{
|
||||||
/* The protocol used by this context. */
|
/* The protocol used by this context. */
|
||||||
@ -98,13 +91,6 @@ struct gpgme_context_s
|
|||||||
/* Last operation info. */
|
/* Last operation info. */
|
||||||
GpgmeData op_info;
|
GpgmeData op_info;
|
||||||
|
|
||||||
/* Used by keylist.c. */
|
|
||||||
GpgmeKey tmp_key;
|
|
||||||
struct user_id_s *tmp_uid;
|
|
||||||
/* Something new is available. */
|
|
||||||
volatile int key_cond;
|
|
||||||
struct key_queue_item_s *key_queue;
|
|
||||||
|
|
||||||
/* The user provided passphrase callback and its hook value. */
|
/* The user provided passphrase callback and its hook value. */
|
||||||
GpgmePassphraseCb passphrase_cb;
|
GpgmePassphraseCb passphrase_cb;
|
||||||
void *passphrase_cb_value;
|
void *passphrase_cb_value;
|
||||||
@ -119,31 +105,12 @@ struct gpgme_context_s
|
|||||||
struct GpgmeIOCbs io_cbs;
|
struct GpgmeIOCbs io_cbs;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Forward declaration of a structure to store certification
|
|
||||||
signatures. */
|
|
||||||
struct certsig_s;
|
|
||||||
|
|
||||||
/* Structure to store user IDs. */
|
|
||||||
struct user_id_s
|
|
||||||
{
|
|
||||||
struct user_id_s *next;
|
|
||||||
unsigned int revoked : 1;
|
|
||||||
unsigned int invalid : 1;
|
|
||||||
GpgmeValidity validity;
|
|
||||||
struct certsig_s *certsigs;
|
|
||||||
struct certsig_s *last_certsig;
|
|
||||||
const char *name_part; /* All 3 point into strings behind name */
|
|
||||||
const char *email_part; /* or to read-only strings. */
|
|
||||||
const char *comment_part;
|
|
||||||
char name[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
/* A recipient is defined by a user ID, but we define it as an opaque
|
||||||
|
type for the user. */
|
||||||
struct gpgme_recipients_s
|
struct gpgme_recipients_s
|
||||||
{
|
{
|
||||||
struct user_id_s *list;
|
GpgmeUserID list;
|
||||||
int checked; /* Whether the recipients are all valid. */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* CONTEXT_H */
|
#endif /* CONTEXT_H */
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
#include "ops.h"
|
#include "ops.h"
|
||||||
#include "wait.h"
|
#include "wait.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "key.h"
|
|
||||||
#include "sema.h"
|
#include "sema.h"
|
||||||
|
|
||||||
#include "assuan.h"
|
#include "assuan.h"
|
||||||
@ -873,7 +872,7 @@ gpgsm_delete (void *engine, GpgmeKey key, int allow_secret)
|
|||||||
{
|
{
|
||||||
GpgsmObject gpgsm = engine;
|
GpgsmObject gpgsm = engine;
|
||||||
GpgmeError err;
|
GpgmeError err;
|
||||||
char *fpr = (char *) gpgme_key_get_string_attr (key, GPGME_ATTR_FPR, NULL, 0);
|
char *fpr = key->subkeys ? key->subkeys->fpr : NULL;
|
||||||
char *linep = fpr;
|
char *linep = fpr;
|
||||||
char *line;
|
char *line;
|
||||||
int length = 8; /* "DELKEYS " */
|
int length = 8; /* "DELKEYS " */
|
||||||
@ -942,17 +941,17 @@ set_recipients (GpgsmObject gpgsm, GpgmeRecipients recp)
|
|||||||
ASSUAN_CONTEXT ctx = gpgsm->assuan_ctx;
|
ASSUAN_CONTEXT ctx = gpgsm->assuan_ctx;
|
||||||
char *line;
|
char *line;
|
||||||
int linelen;
|
int linelen;
|
||||||
struct user_id_s *r;
|
GpgmeUserID uid;
|
||||||
int valid_recipients = 0;
|
int invalid_recipients = 0;
|
||||||
|
|
||||||
linelen = 10 + 40 + 1; /* "RECIPIENT " + guess + '\0'. */
|
linelen = 10 + 40 + 1; /* "RECIPIENT " + guess + '\0'. */
|
||||||
line = malloc (10 + 40 + 1);
|
line = malloc (10 + 40 + 1);
|
||||||
if (!line)
|
if (!line)
|
||||||
return GPGME_Out_Of_Core;
|
return GPGME_Out_Of_Core;
|
||||||
strcpy (line, "RECIPIENT ");
|
strcpy (line, "RECIPIENT ");
|
||||||
for (r = recp->list; r; r = r->next)
|
for (uid = recp->list; uid; uid = uid->next)
|
||||||
{
|
{
|
||||||
int newlen = 11 + strlen (r->name);
|
int newlen = 11 + strlen (uid->uid);
|
||||||
if (linelen < newlen)
|
if (linelen < newlen)
|
||||||
{
|
{
|
||||||
char *newline = realloc (line, newlen);
|
char *newline = realloc (line, newlen);
|
||||||
@ -964,22 +963,20 @@ set_recipients (GpgsmObject gpgsm, GpgmeRecipients recp)
|
|||||||
line = newline;
|
line = newline;
|
||||||
linelen = newlen;
|
linelen = newlen;
|
||||||
}
|
}
|
||||||
strcpy (&line[10], r->name);
|
strcpy (&line[10], uid->uid);
|
||||||
|
|
||||||
err = gpgsm_assuan_simple_command (ctx, line, gpgsm->status.fnc,
|
err = gpgsm_assuan_simple_command (ctx, line, gpgsm->status.fnc,
|
||||||
gpgsm->status.fnc_value);
|
gpgsm->status.fnc_value);
|
||||||
if (!err)
|
if (err == GPGME_Invalid_Key)
|
||||||
valid_recipients = 1;
|
invalid_recipients = 1;
|
||||||
else if (err != GPGME_Invalid_Key)
|
else if (err)
|
||||||
{
|
{
|
||||||
free (line);
|
free (line);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free (line);
|
free (line);
|
||||||
if (!valid_recipients && gpgsm->status.fnc)
|
return invalid_recipients ? GPGME_Invalid_UserID : 0;
|
||||||
gpgsm->status.fnc (gpgsm->status.fnc_value, GPGME_STATUS_NO_RECP, "");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1302,8 +1299,7 @@ gpgsm_sign (void *engine, GpgmeData in, GpgmeData out, GpgmeSigMode mode,
|
|||||||
|
|
||||||
for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
|
for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
|
||||||
{
|
{
|
||||||
const char *s = gpgme_key_get_string_attr (key, GPGME_ATTR_FPR,
|
const char *s = key->subkeys ? key->subkeys->fpr : NULL;
|
||||||
NULL, 0);
|
|
||||||
if (s && strlen (s) < 80)
|
if (s && strlen (s) < 80)
|
||||||
{
|
{
|
||||||
char buf[100];
|
char buf[100];
|
||||||
|
@ -67,11 +67,9 @@ gpgme_release (GpgmeCtx ctx)
|
|||||||
_gpgme_engine_release (ctx->engine);
|
_gpgme_engine_release (ctx->engine);
|
||||||
_gpgme_fd_table_deinit (&ctx->fdt);
|
_gpgme_fd_table_deinit (&ctx->fdt);
|
||||||
_gpgme_release_result (ctx);
|
_gpgme_release_result (ctx);
|
||||||
gpgme_key_release (ctx->tmp_key);
|
|
||||||
gpgme_signers_clear (ctx);
|
gpgme_signers_clear (ctx);
|
||||||
if (ctx->signers)
|
if (ctx->signers)
|
||||||
free (ctx->signers);
|
free (ctx->signers);
|
||||||
/* FIXME: Release the key_queue. */
|
|
||||||
free (ctx);
|
free (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
245
gpgme/gpgme.h
245
gpgme/gpgme.h
@ -63,10 +63,8 @@ typedef struct gpgme_data_s *GpgmeData;
|
|||||||
struct gpgme_recipients_s;
|
struct gpgme_recipients_s;
|
||||||
typedef struct gpgme_recipients_s *GpgmeRecipients;
|
typedef struct gpgme_recipients_s *GpgmeRecipients;
|
||||||
|
|
||||||
/* A key from the keyring. */
|
|
||||||
struct gpgme_key_s;
|
/* Public data types provided by GPGME. */
|
||||||
typedef struct gpgme_key_s *GpgmeKey;
|
|
||||||
|
|
||||||
|
|
||||||
/* The error numbers used by GPGME. */
|
/* The error numbers used by GPGME. */
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -343,6 +341,7 @@ typedef enum
|
|||||||
}
|
}
|
||||||
GpgmeStatusCode;
|
GpgmeStatusCode;
|
||||||
|
|
||||||
|
|
||||||
/* The engine information structure. */
|
/* The engine information structure. */
|
||||||
struct _gpgme_engine_info
|
struct _gpgme_engine_info
|
||||||
{
|
{
|
||||||
@ -362,7 +361,221 @@ struct _gpgme_engine_info
|
|||||||
};
|
};
|
||||||
typedef struct _gpgme_engine_info *GpgmeEngineInfo;
|
typedef struct _gpgme_engine_info *GpgmeEngineInfo;
|
||||||
|
|
||||||
|
|
||||||
|
/* A subkey from a key. */
|
||||||
|
struct _gpgme_subkey
|
||||||
|
{
|
||||||
|
struct _gpgme_subkey *next;
|
||||||
|
|
||||||
|
/* True if subkey is revoked. */
|
||||||
|
unsigned int revoked : 1;
|
||||||
|
|
||||||
|
/* True if subkey is expired. */
|
||||||
|
unsigned int expired : 1;
|
||||||
|
|
||||||
|
/* True if subkey is disabled. */
|
||||||
|
unsigned int disabled : 1;
|
||||||
|
|
||||||
|
/* True if subkey is invalid. */
|
||||||
|
unsigned int invalid : 1;
|
||||||
|
|
||||||
|
/* True if subkey can be used for encryption. */
|
||||||
|
unsigned int can_encrypt : 1;
|
||||||
|
|
||||||
|
/* True if subkey can be used for signing. */
|
||||||
|
unsigned int can_sign : 1;
|
||||||
|
|
||||||
|
/* True if subkey can be used for certification. */
|
||||||
|
unsigned int can_certify : 1;
|
||||||
|
|
||||||
|
/* True if subkey is secret. */
|
||||||
|
unsigned int secret : 1;
|
||||||
|
|
||||||
|
/* Internal to GPGME, do not use. */
|
||||||
|
unsigned int _unused : 24;
|
||||||
|
|
||||||
|
/* Public key algorithm supported by this subkey. */
|
||||||
|
GpgmePubKeyAlgo pubkey_algo;
|
||||||
|
|
||||||
|
/* Length of the subkey. */
|
||||||
|
unsigned int length;
|
||||||
|
|
||||||
|
/* The key ID of the subkey. */
|
||||||
|
char *keyid;
|
||||||
|
|
||||||
|
/* Internal to GPGME, do not use. */
|
||||||
|
char _keyid[16 + 1];
|
||||||
|
|
||||||
|
/* The fingerprint of the subkey in hex digit form. */
|
||||||
|
char *fpr;
|
||||||
|
|
||||||
|
/* The creation timestamp, -1 if invalid, 0 if not available. */
|
||||||
|
long int timestamp;
|
||||||
|
|
||||||
|
/* The expiration timestamp, 0 if the subkey does not expire. */
|
||||||
|
long int expires;
|
||||||
|
};
|
||||||
|
typedef struct _gpgme_subkey *GpgmeSubkey;
|
||||||
|
|
||||||
|
/* A signature on a user ID. */
|
||||||
|
struct _gpgme_key_sig
|
||||||
|
{
|
||||||
|
struct _gpgme_key_sig *next;
|
||||||
|
|
||||||
|
/* True if the signature is revoked. */
|
||||||
|
unsigned int revoked : 1;
|
||||||
|
|
||||||
|
/* True if the signature is expired. */
|
||||||
|
unsigned int expired : 1;
|
||||||
|
|
||||||
|
/* True if the signature is invalid. */
|
||||||
|
unsigned int invalid : 1;
|
||||||
|
|
||||||
|
/* True if the signature should be exported. */
|
||||||
|
unsigned int exportable : 1;
|
||||||
|
|
||||||
|
/* Internal to GPGME, do not use. */
|
||||||
|
unsigned int _unused : 28;
|
||||||
|
|
||||||
|
/* The public key algorithm used to create the signature. */
|
||||||
|
GpgmePubKeyAlgo pubkey_algo;
|
||||||
|
|
||||||
|
/* The key ID of key used to create the signature. */
|
||||||
|
char *keyid;
|
||||||
|
|
||||||
|
/* Internal to GPGME, do not use. */
|
||||||
|
char _keyid[16 + 1];
|
||||||
|
|
||||||
|
/* The creation timestamp, -1 if invalid, 0 if not available. */
|
||||||
|
long int timestamp;
|
||||||
|
|
||||||
|
/* The expiration timestamp, 0 if the subkey does not expire. */
|
||||||
|
long int expires;
|
||||||
|
|
||||||
|
/* Same as in GpgmeSignature. */
|
||||||
|
GpgmeError status;
|
||||||
|
|
||||||
|
/* Crypto backend specific signature class. */
|
||||||
|
unsigned int class;
|
||||||
|
|
||||||
|
/* The user ID string. */
|
||||||
|
char *uid;
|
||||||
|
|
||||||
|
/* The name part of the user ID. */
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
/* The email part of the user ID. */
|
||||||
|
char *email;
|
||||||
|
|
||||||
|
/* The comment part of the user ID. */
|
||||||
|
char *comment;
|
||||||
|
};
|
||||||
|
typedef struct _gpgme_key_sig *GpgmeKeySig;
|
||||||
|
|
||||||
|
/* An user ID from a key. */
|
||||||
|
struct _gpgme_user_id
|
||||||
|
{
|
||||||
|
struct _gpgme_user_id *next;
|
||||||
|
|
||||||
|
/* True if the user ID is revoked. */
|
||||||
|
unsigned int revoked : 1;
|
||||||
|
|
||||||
|
/* True if the user ID is invalid. */
|
||||||
|
unsigned int invalid : 1;
|
||||||
|
|
||||||
|
/* Internal to GPGME, do not use. */
|
||||||
|
unsigned int _unused : 30;
|
||||||
|
|
||||||
|
/* The validity of the user ID. */
|
||||||
|
GpgmeValidity validity;
|
||||||
|
|
||||||
|
/* The user ID string. */
|
||||||
|
char *uid;
|
||||||
|
|
||||||
|
/* The name part of the user ID. */
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
/* The email part of the user ID. */
|
||||||
|
char *email;
|
||||||
|
|
||||||
|
/* The comment part of the user ID. */
|
||||||
|
char *comment;
|
||||||
|
|
||||||
|
/* The signatures of the user ID. */
|
||||||
|
GpgmeKeySig signatures;
|
||||||
|
|
||||||
|
/* Internal to GPGME, do not use. */
|
||||||
|
GpgmeKeySig _last_keysig;
|
||||||
|
};
|
||||||
|
typedef struct _gpgme_user_id *GpgmeUserID;
|
||||||
|
|
||||||
|
/* A key from the keyring. */
|
||||||
|
struct _gpgme_key
|
||||||
|
{
|
||||||
|
/* Internal to GPGME, do not use. */
|
||||||
|
unsigned int _refs;
|
||||||
|
|
||||||
|
/* True if key is revoked. */
|
||||||
|
unsigned int revoked : 1;
|
||||||
|
|
||||||
|
/* True if key is expired. */
|
||||||
|
unsigned int expired : 1;
|
||||||
|
|
||||||
|
/* True if key is disabled. */
|
||||||
|
unsigned int disabled : 1;
|
||||||
|
|
||||||
|
/* True if key is invalid. */
|
||||||
|
unsigned int invalid : 1;
|
||||||
|
|
||||||
|
/* True if key can be used for encryption. */
|
||||||
|
unsigned int can_encrypt : 1;
|
||||||
|
|
||||||
|
/* True if key can be used for signing. */
|
||||||
|
unsigned int can_sign : 1;
|
||||||
|
|
||||||
|
/* True if key can be used for certification. */
|
||||||
|
unsigned int can_certify : 1;
|
||||||
|
|
||||||
|
/* True if key is secret. */
|
||||||
|
unsigned int secret : 1;
|
||||||
|
|
||||||
|
/* Internal to GPGME, do not use. */
|
||||||
|
unsigned int _unused : 24;
|
||||||
|
|
||||||
|
/* This is the protocol supported by this key. */
|
||||||
|
GpgmeProtocol protocol;
|
||||||
|
|
||||||
|
/* If protocol is GPGME_PROTOCOL_CMS, this string contains the
|
||||||
|
issuer serial. */
|
||||||
|
char *issuer_serial;
|
||||||
|
|
||||||
|
/* If protocol is GPGME_PROTOCOL_CMS, this string contains the
|
||||||
|
issuer name. */
|
||||||
|
char *issuer_name;
|
||||||
|
|
||||||
|
/* If protocol is GPGME_PROTOCOL_CMS, this string contains the chain
|
||||||
|
ID. */
|
||||||
|
char *chain_id;
|
||||||
|
|
||||||
|
/* If protocol is GPGME_PROTOCOL_OpenPGP, this field contains the
|
||||||
|
owner trust. */
|
||||||
|
GpgmeValidity owner_trust;
|
||||||
|
|
||||||
|
/* The subkeys of the key. */
|
||||||
|
GpgmeSubkey subkeys;
|
||||||
|
|
||||||
|
/* The user IDs of the key. */
|
||||||
|
GpgmeUserID uids;
|
||||||
|
|
||||||
|
/* Internal to GPGME, do not use. */
|
||||||
|
GpgmeSubkey _last_subkey;
|
||||||
|
|
||||||
|
/* Internal to GPGME, do not use. */
|
||||||
|
GpgmeUserID _last_uid;
|
||||||
|
};
|
||||||
|
typedef struct _gpgme_key *GpgmeKey;
|
||||||
|
|
||||||
|
|
||||||
/* Types for callback functions. */
|
/* Types for callback functions. */
|
||||||
|
|
||||||
/* Request a passphrase from the user. */
|
/* Request a passphrase from the user. */
|
||||||
@ -693,10 +906,6 @@ void gpgme_key_ref (GpgmeKey key);
|
|||||||
void gpgme_key_unref (GpgmeKey key);
|
void gpgme_key_unref (GpgmeKey key);
|
||||||
void gpgme_key_release (GpgmeKey key);
|
void gpgme_key_release (GpgmeKey key);
|
||||||
|
|
||||||
/* Get the data from key KEY in a XML string, which has to be released
|
|
||||||
with free by the user. */
|
|
||||||
char *gpgme_key_get_as_xml (GpgmeKey key);
|
|
||||||
|
|
||||||
/* Return the value of the attribute WHAT of KEY, which has to be
|
/* Return the value of the attribute WHAT of KEY, which has to be
|
||||||
representable by a string. IDX specifies the sub key or
|
representable by a string. IDX specifies the sub key or
|
||||||
user ID for attributes related to sub keys or user IDs. */
|
user ID for attributes related to sub keys or user IDs. */
|
||||||
@ -1045,7 +1254,19 @@ GpgmeError gpgme_op_edit (GpgmeCtx ctx, GpgmeKey key,
|
|||||||
GpgmeEditCb fnc, void *fnc_value,
|
GpgmeEditCb fnc, void *fnc_value,
|
||||||
GpgmeData out);
|
GpgmeData out);
|
||||||
|
|
||||||
|
|
||||||
/* Key management functions */
|
/* Key management functions */
|
||||||
|
struct _gpgme_op_keylist_result
|
||||||
|
{
|
||||||
|
unsigned int truncated : 1;
|
||||||
|
|
||||||
|
/* Internal to GPGME, do not use. */
|
||||||
|
unsigned int _unused : 31;
|
||||||
|
};
|
||||||
|
typedef struct _gpgme_op_keylist_result *GpgmeKeyListResult;
|
||||||
|
|
||||||
|
/* Retrieve a pointer to the result of the key listing operation. */
|
||||||
|
GpgmeKeyListResult gpgme_op_keylist_result (GpgmeCtx ctx);
|
||||||
|
|
||||||
/* Start a keylist operation within CTX, searching for keys which
|
/* Start a keylist operation within CTX, searching for keys which
|
||||||
match PATTERN. If SECRET_ONLY is true, only secret keys are
|
match PATTERN. If SECRET_ONLY is true, only secret keys are
|
||||||
@ -1082,16 +1303,16 @@ struct _gpgme_trust_item
|
|||||||
int level;
|
int level;
|
||||||
|
|
||||||
/* The owner trust if TYPE is 1. */
|
/* The owner trust if TYPE is 1. */
|
||||||
char *otrust;
|
char *owner_trust;
|
||||||
|
|
||||||
/* Internal to GPGME, do not use. */
|
/* Internal to GPGME, do not use. */
|
||||||
char _otrust[2];
|
char _owner_trust[2];
|
||||||
|
|
||||||
/* The calculated validity. */
|
/* The calculated validity. */
|
||||||
char *val;
|
char *validity;
|
||||||
|
|
||||||
/* Internal to GPGME, do not use. */
|
/* Internal to GPGME, do not use. */
|
||||||
char _val[2];
|
char _validity[2];
|
||||||
|
|
||||||
/* The user name if TYPE is 2. */
|
/* The user name if TYPE is 2. */
|
||||||
char *name;
|
char *name;
|
||||||
|
773
gpgme/key.c
773
gpgme/key.c
File diff suppressed because it is too large
Load Diff
538
gpgme/keylist.c
538
gpgme/keylist.c
@ -28,89 +28,80 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "gpgme.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "ops.h"
|
#include "ops.h"
|
||||||
#include "key.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
struct keylist_result
|
struct key_queue_item_s
|
||||||
{
|
{
|
||||||
int truncated;
|
struct key_queue_item_s *next;
|
||||||
GpgmeData xmlinfo;
|
GpgmeKey key;
|
||||||
};
|
};
|
||||||
typedef struct keylist_result *KeylistResult;
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
struct _gpgme_op_keylist_result result;
|
||||||
|
|
||||||
|
GpgmeKey tmp_key;
|
||||||
|
GpgmeUserID tmp_uid;
|
||||||
|
/* Something new is available. */
|
||||||
|
int key_cond;
|
||||||
|
struct key_queue_item_s *key_queue;
|
||||||
|
} *op_data_t;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
release_keylist_result (void *hook)
|
release_op_data (void *hook)
|
||||||
{
|
{
|
||||||
KeylistResult result = (KeylistResult) hook;
|
op_data_t opd = (op_data_t) hook;
|
||||||
|
struct key_queue_item_s *key = opd->key_queue;
|
||||||
|
|
||||||
if (result->xmlinfo)
|
if (opd->tmp_key)
|
||||||
gpgme_data_release (result->xmlinfo);
|
gpgme_key_unref (opd->tmp_key);
|
||||||
|
if (opd->tmp_uid)
|
||||||
|
free (opd->tmp_uid);
|
||||||
|
while (key)
|
||||||
|
{
|
||||||
|
struct key_queue_item_s *next = key->next;
|
||||||
|
|
||||||
|
gpgme_key_unref (key->key);
|
||||||
|
key = next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Append some XML info. args is currently ignore but we might want
|
GpgmeKeyListResult
|
||||||
to add more information in the future (like source of the
|
gpgme_op_keylist_result (GpgmeCtx ctx)
|
||||||
keylisting. With args of NULL the XML structure is closed. */
|
|
||||||
static void
|
|
||||||
append_xml_keylistinfo (GpgmeData *rdh, char *args)
|
|
||||||
{
|
|
||||||
GpgmeData dh;
|
|
||||||
|
|
||||||
if (!*rdh)
|
|
||||||
{
|
|
||||||
if (gpgme_data_new (rdh))
|
|
||||||
return; /* FIXME: We are ignoring out-of-core. */
|
|
||||||
dh = *rdh;
|
|
||||||
_gpgme_data_append_string (dh, "<GnupgOperationInfo>\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dh = *rdh;
|
|
||||||
_gpgme_data_append_string (dh, " </keylisting>\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!args)
|
|
||||||
{
|
|
||||||
/* Just close the XML containter. */
|
|
||||||
_gpgme_data_append_string (dh, "</GnupgOperationInfo>\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_gpgme_data_append_string (dh, " <keylisting>\n <truncated/>\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static GpgmeError
|
|
||||||
keylist_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
|
|
||||||
{
|
{
|
||||||
|
op_data_t opd;
|
||||||
GpgmeError err;
|
GpgmeError err;
|
||||||
KeylistResult result;
|
|
||||||
|
|
||||||
err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &result,
|
err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &opd, -1, NULL);
|
||||||
sizeof (*result), release_keylist_result);
|
if (err || !opd)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &opd->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static GpgmeError
|
||||||
|
keylist_status_handler (void *priv, GpgmeStatusCode code, char *args)
|
||||||
|
{
|
||||||
|
GpgmeCtx ctx = (GpgmeCtx) priv;
|
||||||
|
GpgmeError err;
|
||||||
|
op_data_t opd;
|
||||||
|
|
||||||
|
err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &opd, -1, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case GPGME_STATUS_TRUNCATED:
|
case GPGME_STATUS_TRUNCATED:
|
||||||
result->truncated = 1;
|
opd->result.truncated = 1;
|
||||||
break;
|
|
||||||
|
|
||||||
case GPGME_STATUS_EOF:
|
|
||||||
if (result->truncated)
|
|
||||||
append_xml_keylistinfo (&result->xmlinfo, "1");
|
|
||||||
if (result->xmlinfo)
|
|
||||||
{
|
|
||||||
append_xml_keylistinfo (&result->xmlinfo, NULL);
|
|
||||||
_gpgme_set_op_info (ctx, result->xmlinfo);
|
|
||||||
result->xmlinfo = NULL;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -139,21 +130,21 @@ set_mainkey_trust_info (GpgmeKey key, const char *src)
|
|||||||
switch (*src)
|
switch (*src)
|
||||||
{
|
{
|
||||||
case 'e':
|
case 'e':
|
||||||
key->keys.flags.expired = 1;
|
key->subkeys->expired = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
key->keys.flags.revoked = 1;
|
key->subkeys->revoked = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
/* Note that gpg 1.3 won't print that anymore but only uses
|
/* Note that gpg 1.3 won't print that anymore but only uses
|
||||||
the capabilities field. */
|
the capabilities field. */
|
||||||
key->keys.flags.disabled = 1;
|
key->subkeys->disabled = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
key->keys.flags.invalid = 1;
|
key->subkeys->invalid = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
src++;
|
src++;
|
||||||
@ -164,7 +155,7 @@ set_mainkey_trust_info (GpgmeKey key, const char *src)
|
|||||||
static void
|
static void
|
||||||
set_userid_flags (GpgmeKey key, const char *src)
|
set_userid_flags (GpgmeKey key, const char *src)
|
||||||
{
|
{
|
||||||
struct user_id_s *uid = key->last_uid;
|
GpgmeUserID uid = key->_last_uid;
|
||||||
|
|
||||||
assert (uid);
|
assert (uid);
|
||||||
/* Look at letters and stop at the first digit. */
|
/* Look at letters and stop at the first digit. */
|
||||||
@ -202,7 +193,7 @@ set_userid_flags (GpgmeKey key, const char *src)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_subkey_trust_info (struct subkey_s *subkey, const char *src)
|
set_subkey_trust_info (GpgmeSubkey subkey, const char *src)
|
||||||
{
|
{
|
||||||
/* Look at letters and stop at the first digit. */
|
/* Look at letters and stop at the first digit. */
|
||||||
while (*src && !isdigit (*src))
|
while (*src && !isdigit (*src))
|
||||||
@ -210,19 +201,19 @@ set_subkey_trust_info (struct subkey_s *subkey, const char *src)
|
|||||||
switch (*src)
|
switch (*src)
|
||||||
{
|
{
|
||||||
case 'e':
|
case 'e':
|
||||||
subkey->flags.expired = 1;
|
subkey->expired = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
subkey->flags.revoked = 1;
|
subkey->revoked = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
subkey->flags.disabled = 1;
|
subkey->disabled = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
subkey->flags.invalid = 1;
|
subkey->invalid = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
src++;
|
src++;
|
||||||
@ -238,15 +229,15 @@ set_mainkey_capability (GpgmeKey key, const char *src)
|
|||||||
switch (*src)
|
switch (*src)
|
||||||
{
|
{
|
||||||
case 'e':
|
case 'e':
|
||||||
key->keys.flags.can_encrypt = 1;
|
key->subkeys->can_encrypt = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
key->keys.flags.can_sign = 1;
|
key->subkeys->can_sign = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
key->keys.flags.can_certify = 1;
|
key->subkeys->can_certify = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
@ -256,19 +247,19 @@ set_mainkey_capability (GpgmeKey key, const char *src)
|
|||||||
and D, so that a future gpg version will be able to
|
and D, so that a future gpg version will be able to
|
||||||
disable certain subkeys. Currently it is expected that
|
disable certain subkeys. Currently it is expected that
|
||||||
gpg sets this for the primary key. */
|
gpg sets this for the primary key. */
|
||||||
key->keys.flags.disabled = 1;
|
key->subkeys->disabled = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'E':
|
case 'E':
|
||||||
key->gloflags.can_encrypt = 1;
|
key->can_encrypt = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'S':
|
case 'S':
|
||||||
key->gloflags.can_sign = 1;
|
key->can_sign = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'C':
|
case 'C':
|
||||||
key->gloflags.can_certify = 1;
|
key->can_certify = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
src++;
|
src++;
|
||||||
@ -277,22 +268,22 @@ set_mainkey_capability (GpgmeKey key, const char *src)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_subkey_capability (struct subkey_s *subkey, const char *src)
|
set_subkey_capability (GpgmeSubkey subkey, const char *src)
|
||||||
{
|
{
|
||||||
while (*src)
|
while (*src)
|
||||||
{
|
{
|
||||||
switch (*src)
|
switch (*src)
|
||||||
{
|
{
|
||||||
case 'e':
|
case 'e':
|
||||||
subkey->flags.can_encrypt = 1;
|
subkey->can_encrypt = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
subkey->flags.can_sign = 1;
|
subkey->can_sign = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
subkey->flags.can_certify = 1;
|
subkey->can_certify = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
src++;
|
src++;
|
||||||
@ -308,23 +299,23 @@ set_ownertrust (GpgmeKey key, const char *src)
|
|||||||
switch (*src)
|
switch (*src)
|
||||||
{
|
{
|
||||||
case 'n':
|
case 'n':
|
||||||
key->otrust = GPGME_VALIDITY_NEVER;
|
key->owner_trust = GPGME_VALIDITY_NEVER;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'm':
|
case 'm':
|
||||||
key->otrust = GPGME_VALIDITY_MARGINAL;
|
key->owner_trust = GPGME_VALIDITY_MARGINAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
key->otrust = GPGME_VALIDITY_FULL;
|
key->owner_trust = GPGME_VALIDITY_FULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
key->otrust = GPGME_VALIDITY_ULTIMATE;
|
key->owner_trust = GPGME_VALIDITY_ULTIMATE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
key->otrust = GPGME_VALIDITY_UNKNOWN;
|
key->owner_trust = GPGME_VALIDITY_UNKNOWN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
src++;
|
src++;
|
||||||
@ -332,14 +323,14 @@ set_ownertrust (GpgmeKey key, const char *src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* We have read an entire key into ctx->tmp_key and should now finish
|
/* We have read an entire key into tmp_key and should now finish it.
|
||||||
it. It is assumed that this releases ctx->tmp_key. */
|
It is assumed that this releases tmp_key. */
|
||||||
static void
|
static void
|
||||||
finish_key (GpgmeCtx ctx)
|
finish_key (GpgmeCtx ctx, op_data_t opd)
|
||||||
{
|
{
|
||||||
GpgmeKey key = ctx->tmp_key;
|
GpgmeKey key = opd->tmp_key;
|
||||||
|
|
||||||
ctx->tmp_key = NULL;
|
opd->tmp_key = NULL;
|
||||||
|
|
||||||
if (key)
|
if (key)
|
||||||
_gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_KEY, key);
|
_gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_KEY, key);
|
||||||
@ -348,28 +339,37 @@ finish_key (GpgmeCtx ctx)
|
|||||||
|
|
||||||
/* Note: We are allowed to modify LINE. */
|
/* Note: We are allowed to modify LINE. */
|
||||||
static GpgmeError
|
static GpgmeError
|
||||||
keylist_colon_handler (GpgmeCtx ctx, char *line)
|
keylist_colon_handler (void *priv, char *line)
|
||||||
{
|
{
|
||||||
|
GpgmeCtx ctx = (GpgmeCtx) priv;
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
RT_NONE, RT_SIG, RT_UID, RT_SUB, RT_PUB, RT_FPR, RT_SSB, RT_SEC,
|
RT_NONE, RT_SIG, RT_UID, RT_SUB, RT_PUB, RT_FPR,
|
||||||
RT_CRT, RT_CRS, RT_REV
|
RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV
|
||||||
}
|
}
|
||||||
rectype = RT_NONE;
|
rectype = RT_NONE;
|
||||||
#define NR_FIELDS 13
|
#define NR_FIELDS 13
|
||||||
char *field[NR_FIELDS];
|
char *field[NR_FIELDS];
|
||||||
int fields = 0;
|
int fields = 0;
|
||||||
GpgmeKey key = ctx->tmp_key;
|
op_data_t opd;
|
||||||
struct subkey_s *subkey = NULL;
|
GpgmeError err;
|
||||||
struct certsig_s *certsig = NULL;
|
GpgmeKey key;
|
||||||
|
GpgmeSubkey subkey = NULL;
|
||||||
|
GpgmeKeySig keysig = NULL;
|
||||||
|
|
||||||
DEBUG3 ("keylist_colon_handler ctx = %p, key = %p, line = %s\n",
|
DEBUG3 ("keylist_colon_handler ctx = %p, key = %p, line = %s\n",
|
||||||
ctx, key, line ? line : "(null)");
|
ctx, key, line ? line : "(null)");
|
||||||
|
|
||||||
|
err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &opd, -1, NULL);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
key = opd->tmp_key;
|
||||||
|
|
||||||
if (!line)
|
if (!line)
|
||||||
{
|
{
|
||||||
/* End Of File. */
|
/* End Of File. */
|
||||||
finish_key (ctx);
|
finish_key (ctx, opd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,67 +385,22 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
rectype = RT_SIG;
|
rectype = RT_SIG;
|
||||||
else if (!strcmp (field[0], "rev"))
|
else if (!strcmp (field[0], "rev"))
|
||||||
rectype = RT_REV;
|
rectype = RT_REV;
|
||||||
|
else if (!strcmp (field[0], "pub"))
|
||||||
|
rectype = RT_PUB;
|
||||||
|
else if (!strcmp (field[0], "sec"))
|
||||||
|
rectype = RT_SEC;
|
||||||
|
else if (!strcmp (field[0], "crt"))
|
||||||
|
rectype = RT_CRT;
|
||||||
|
else if (!strcmp (field[0], "crs"))
|
||||||
|
rectype = RT_CRS;
|
||||||
|
else if (!strcmp (field[0], "fpr") && key)
|
||||||
|
rectype = RT_FPR;
|
||||||
else if (!strcmp (field[0], "uid") && key)
|
else if (!strcmp (field[0], "uid") && key)
|
||||||
rectype = RT_UID;
|
rectype = RT_UID;
|
||||||
else if (!strcmp (field[0], "sub") && key)
|
else if (!strcmp (field[0], "sub") && key)
|
||||||
{
|
rectype = RT_SUB;
|
||||||
/* Start a new subkey. */
|
|
||||||
rectype = RT_SUB;
|
|
||||||
if (!(subkey = _gpgme_key_add_subkey (key)))
|
|
||||||
return GPGME_Out_Of_Core;
|
|
||||||
}
|
|
||||||
else if (!strcmp (field[0], "ssb") && key)
|
else if (!strcmp (field[0], "ssb") && key)
|
||||||
{
|
rectype = RT_SSB;
|
||||||
/* Start a new secret subkey. */
|
|
||||||
rectype = RT_SSB;
|
|
||||||
if (!(subkey = _gpgme_key_add_secret_subkey (key)))
|
|
||||||
return GPGME_Out_Of_Core;
|
|
||||||
}
|
|
||||||
else if (!strcmp (field[0], "pub"))
|
|
||||||
{
|
|
||||||
/* Start a new keyblock. */
|
|
||||||
if (_gpgme_key_new (&key))
|
|
||||||
/* The only kind of error we can get. */
|
|
||||||
return GPGME_Out_Of_Core;
|
|
||||||
rectype = RT_PUB;
|
|
||||||
finish_key (ctx);
|
|
||||||
assert (!ctx->tmp_key);
|
|
||||||
ctx->tmp_key = key;
|
|
||||||
}
|
|
||||||
else if (!strcmp (field[0], "sec"))
|
|
||||||
{
|
|
||||||
/* Start a new keyblock, */
|
|
||||||
if (_gpgme_key_new_secret (&key))
|
|
||||||
return GPGME_Out_Of_Core;
|
|
||||||
rectype = RT_SEC;
|
|
||||||
finish_key (ctx);
|
|
||||||
assert (!ctx->tmp_key);
|
|
||||||
ctx->tmp_key = key;
|
|
||||||
}
|
|
||||||
else if (!strcmp (field[0], "crt"))
|
|
||||||
{
|
|
||||||
/* Start a new certificate. */
|
|
||||||
if (_gpgme_key_new (&key))
|
|
||||||
return GPGME_Out_Of_Core;
|
|
||||||
key->x509 = 1;
|
|
||||||
rectype = RT_CRT;
|
|
||||||
finish_key (ctx);
|
|
||||||
assert (!ctx->tmp_key);
|
|
||||||
ctx->tmp_key = key;
|
|
||||||
}
|
|
||||||
else if (!strcmp (field[0], "crs"))
|
|
||||||
{
|
|
||||||
/* Start a new certificate. */
|
|
||||||
if (_gpgme_key_new_secret (&key))
|
|
||||||
return GPGME_Out_Of_Core;
|
|
||||||
key->x509 = 1;
|
|
||||||
rectype = RT_CRS;
|
|
||||||
finish_key (ctx);
|
|
||||||
assert (!ctx->tmp_key);
|
|
||||||
ctx->tmp_key = key;
|
|
||||||
}
|
|
||||||
else if (!strcmp (field[0], "fpr") && key)
|
|
||||||
rectype = RT_FPR;
|
|
||||||
else
|
else
|
||||||
rectype = RT_NONE;
|
rectype = RT_NONE;
|
||||||
|
|
||||||
@ -453,29 +408,32 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
this, clear the user ID pointer when encountering anything but a
|
this, clear the user ID pointer when encountering anything but a
|
||||||
signature. */
|
signature. */
|
||||||
if (rectype != RT_SIG && rectype != RT_REV)
|
if (rectype != RT_SIG && rectype != RT_REV)
|
||||||
ctx->tmp_uid = NULL;
|
opd->tmp_uid = NULL;
|
||||||
|
|
||||||
switch (rectype)
|
switch (rectype)
|
||||||
{
|
{
|
||||||
case RT_CRT:
|
|
||||||
case RT_CRS:
|
|
||||||
/* Field 8 has the X.509 serial number. */
|
|
||||||
if (fields >= 8)
|
|
||||||
{
|
|
||||||
key->issuer_serial = strdup (field[7]);
|
|
||||||
if (!key->issuer_serial)
|
|
||||||
return GPGME_Out_Of_Core;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Field 10 is not used for gpg due to --fixed-list-mode option
|
|
||||||
but GPGSM stores the issuer name. */
|
|
||||||
if (fields >= 10 && _gpgme_decode_c_string (field[9],
|
|
||||||
&key->issuer_name, 0))
|
|
||||||
return GPGME_Out_Of_Core;
|
|
||||||
/* Fall through! */
|
|
||||||
|
|
||||||
case RT_PUB:
|
case RT_PUB:
|
||||||
case RT_SEC:
|
case RT_SEC:
|
||||||
|
case RT_CRT:
|
||||||
|
case RT_CRS:
|
||||||
|
/* Start a new keyblock. */
|
||||||
|
err = _gpgme_key_new (&key);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
err = _gpgme_key_add_subkey (key, &subkey);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
gpgme_key_unref (key);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rectype == RT_SEC || rectype == RT_CRS)
|
||||||
|
key->secret = 1;
|
||||||
|
if (rectype == RT_CRT || rectype == RT_CRS)
|
||||||
|
key->protocol = GPGME_PROTOCOL_CMS;
|
||||||
|
finish_key (ctx, opd);
|
||||||
|
opd->tmp_key = key;
|
||||||
|
|
||||||
/* Field 2 has the trust info. */
|
/* Field 2 has the trust info. */
|
||||||
if (fields >= 2)
|
if (fields >= 2)
|
||||||
set_mainkey_trust_info (key, field[1]);
|
set_mainkey_trust_info (key, field[1]);
|
||||||
@ -486,7 +444,7 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
int i = atoi (field[2]);
|
int i = atoi (field[2]);
|
||||||
/* Ignore invalid values. */
|
/* Ignore invalid values. */
|
||||||
if (i > 1)
|
if (i > 1)
|
||||||
key->keys.key_len = i;
|
subkey->length = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Field 4 has the public key algorithm. */
|
/* Field 4 has the public key algorithm. */
|
||||||
@ -494,25 +452,39 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
{
|
{
|
||||||
int i = atoi (field[3]);
|
int i = atoi (field[3]);
|
||||||
if (i >= 1 && i < 128)
|
if (i >= 1 && i < 128)
|
||||||
key->keys.key_algo = i;
|
subkey->pubkey_algo = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Field 5 has the long keyid. */
|
/* Field 5 has the long keyid. */
|
||||||
if (fields >= 5 && strlen (field[4]) == DIM(key->keys.keyid) - 1)
|
if (fields >= 5 && strlen (field[4]) == DIM(subkey->_keyid) - 1)
|
||||||
strcpy (key->keys.keyid, field[4]);
|
strcpy (subkey->_keyid, field[4]);
|
||||||
|
|
||||||
/* Field 6 has the timestamp (seconds). */
|
/* Field 6 has the timestamp (seconds). */
|
||||||
if (fields >= 6)
|
if (fields >= 6)
|
||||||
key->keys.timestamp = parse_timestamp (field[5]);
|
subkey->timestamp = parse_timestamp (field[5]);
|
||||||
|
|
||||||
/* Field 7 has the expiration time (seconds). */
|
/* Field 7 has the expiration time (seconds). */
|
||||||
if (fields >= 7)
|
if (fields >= 7)
|
||||||
key->keys.expires_at = parse_timestamp (field[6]);
|
subkey->expires = parse_timestamp (field[6]);
|
||||||
|
|
||||||
|
/* Field 8 has the X.509 serial number. */
|
||||||
|
if (fields >= 8 && (rectype == RT_CRT || rectype == RT_CRS))
|
||||||
|
{
|
||||||
|
key->issuer_serial = strdup (field[7]);
|
||||||
|
if (!key->issuer_serial)
|
||||||
|
return GPGME_Out_Of_Core;
|
||||||
|
}
|
||||||
|
|
||||||
/* Field 9 has the ownertrust. */
|
/* Field 9 has the ownertrust. */
|
||||||
if (fields >= 9)
|
if (fields >= 9)
|
||||||
set_ownertrust (key, field[8]);
|
set_ownertrust (key, field[8]);
|
||||||
|
|
||||||
|
/* Field 10 is not used for gpg due to --fixed-list-mode option
|
||||||
|
but GPGSM stores the issuer name. */
|
||||||
|
if (fields >= 10 && (rectype == RT_CRT || rectype == RT_CRS))
|
||||||
|
if (_gpgme_decode_c_string (field[9], &key->issuer_name, 0))
|
||||||
|
return GPGME_Out_Of_Core;
|
||||||
|
|
||||||
/* Field 11 has the signature class. */
|
/* Field 11 has the signature class. */
|
||||||
|
|
||||||
/* Field 12 has the capabilities. */
|
/* Field 12 has the capabilities. */
|
||||||
@ -522,6 +494,14 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
|
|
||||||
case RT_SUB:
|
case RT_SUB:
|
||||||
case RT_SSB:
|
case RT_SSB:
|
||||||
|
/* Start a new subkey. */
|
||||||
|
err = _gpgme_key_add_subkey (key, &subkey);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (rectype == RT_SSB)
|
||||||
|
subkey->secret = 1;
|
||||||
|
|
||||||
/* Field 2 has the trust info. */
|
/* Field 2 has the trust info. */
|
||||||
if (fields >= 2)
|
if (fields >= 2)
|
||||||
set_subkey_trust_info (subkey, field[1]);
|
set_subkey_trust_info (subkey, field[1]);
|
||||||
@ -532,7 +512,7 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
int i = atoi (field[2]);
|
int i = atoi (field[2]);
|
||||||
/* Ignore invalid values. */
|
/* Ignore invalid values. */
|
||||||
if (i > 1)
|
if (i > 1)
|
||||||
subkey->key_len = i;
|
subkey->length = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Field 4 has the public key algorithm. */
|
/* Field 4 has the public key algorithm. */
|
||||||
@ -540,12 +520,12 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
{
|
{
|
||||||
int i = atoi (field[3]);
|
int i = atoi (field[3]);
|
||||||
if (i >= 1 && i < 128)
|
if (i >= 1 && i < 128)
|
||||||
subkey->key_algo = i;
|
subkey->pubkey_algo = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Field 5 has the long keyid. */
|
/* Field 5 has the long keyid. */
|
||||||
if (fields >= 5 && strlen (field[4]) == DIM(subkey->keyid) - 1)
|
if (fields >= 5 && strlen (field[4]) == DIM(subkey->_keyid) - 1)
|
||||||
strcpy (subkey->keyid, field[4]);
|
strcpy (subkey->_keyid, field[4]);
|
||||||
|
|
||||||
/* Field 6 has the timestamp (seconds). */
|
/* Field 6 has the timestamp (seconds). */
|
||||||
if (fields >= 6)
|
if (fields >= 6)
|
||||||
@ -553,7 +533,7 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
|
|
||||||
/* Field 7 has the expiration time (seconds). */
|
/* Field 7 has the expiration time (seconds). */
|
||||||
if (fields >= 7)
|
if (fields >= 7)
|
||||||
subkey->expires_at = parse_timestamp (field[6]);
|
subkey->expires = parse_timestamp (field[6]);
|
||||||
|
|
||||||
/* Field 8 is reserved (LID). */
|
/* Field 8 is reserved (LID). */
|
||||||
/* Field 9 has the ownertrust. */
|
/* Field 9 has the ownertrust. */
|
||||||
@ -576,17 +556,17 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
{
|
{
|
||||||
if (field[1])
|
if (field[1])
|
||||||
set_userid_flags (key, field[1]);
|
set_userid_flags (key, field[1]);
|
||||||
ctx->tmp_uid = key->last_uid;
|
opd->tmp_uid = key->_last_uid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RT_FPR:
|
case RT_FPR:
|
||||||
/* Field 10 has the fingerprint (take only the first one). */
|
/* Field 10 has the fingerprint (take only the first one). */
|
||||||
if (fields >= 10 && !key->keys.fingerprint && field[9] && *field[9])
|
if (fields >= 10 && !key->subkeys->fpr && field[9] && *field[9])
|
||||||
{
|
{
|
||||||
key->keys.fingerprint = strdup (field[9]);
|
key->subkeys->fpr = strdup (field[9]);
|
||||||
if (!key->keys.fingerprint)
|
if (!key->subkeys->fpr)
|
||||||
return GPGME_Out_Of_Core;
|
return GPGME_Out_Of_Core;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,13 +581,13 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
|
|
||||||
case RT_SIG:
|
case RT_SIG:
|
||||||
case RT_REV:
|
case RT_REV:
|
||||||
if (!ctx->tmp_uid)
|
if (!opd->tmp_uid)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Start a new (revoked) signature. */
|
/* Start a new (revoked) signature. */
|
||||||
assert (ctx->tmp_uid == key->last_uid);
|
assert (opd->tmp_uid == key->_last_uid);
|
||||||
certsig = _gpgme_key_add_certsig (key, (fields >= 10) ? field[9] : NULL);
|
keysig = _gpgme_key_add_sig (key, (fields >= 10) ? field[9] : NULL);
|
||||||
if (!certsig)
|
if (!keysig)
|
||||||
return GPGME_Out_Of_Core;
|
return GPGME_Out_Of_Core;
|
||||||
|
|
||||||
/* Field 2 has the calculated trust ('!', '-', '?', '%'). */
|
/* Field 2 has the calculated trust ('!', '-', '?', '%'). */
|
||||||
@ -615,23 +595,23 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
switch (field[1][0])
|
switch (field[1][0])
|
||||||
{
|
{
|
||||||
case '!':
|
case '!':
|
||||||
certsig->sig_stat = GPGME_SIG_STAT_GOOD;
|
keysig->status = GPGME_No_Error;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '-':
|
case '-':
|
||||||
certsig->sig_stat = GPGME_SIG_STAT_BAD;
|
keysig->status = GPGME_Bad_Signature;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
certsig->sig_stat = GPGME_SIG_STAT_NOKEY;
|
keysig->status = GPGME_No_Public_Key;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '%':
|
case '%':
|
||||||
certsig->sig_stat = GPGME_SIG_STAT_ERROR;
|
keysig->status = GPGME_General_Error;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
certsig->sig_stat = GPGME_SIG_STAT_NONE;
|
keysig->status = GPGME_No_Error;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -640,20 +620,20 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
{
|
{
|
||||||
int i = atoi (field[3]);
|
int i = atoi (field[3]);
|
||||||
if (i >= 1 && i < 128)
|
if (i >= 1 && i < 128)
|
||||||
certsig->algo = i;
|
keysig->pubkey_algo = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Field 5 has the long keyid. */
|
/* Field 5 has the long keyid. */
|
||||||
if (fields >= 5 && strlen (field[4]) == DIM(certsig->keyid) - 1)
|
if (fields >= 5 && strlen (field[4]) == DIM(keysig->_keyid) - 1)
|
||||||
strcpy (certsig->keyid, field[4]);
|
strcpy (keysig->_keyid, field[4]);
|
||||||
|
|
||||||
/* Field 6 has the timestamp (seconds). */
|
/* Field 6 has the timestamp (seconds). */
|
||||||
if (fields >= 6)
|
if (fields >= 6)
|
||||||
certsig->timestamp = parse_timestamp (field[5]);
|
keysig->timestamp = parse_timestamp (field[5]);
|
||||||
|
|
||||||
/* Field 7 has the expiration time (seconds). */
|
/* Field 7 has the expiration time (seconds). */
|
||||||
if (fields >= 7)
|
if (fields >= 7)
|
||||||
certsig->expires_at = parse_timestamp (field[6]);
|
keysig->expires = parse_timestamp (field[6]);
|
||||||
|
|
||||||
/* Field 11 has the signature class (eg, 0x30 means revoked). */
|
/* Field 11 has the signature class (eg, 0x30 means revoked). */
|
||||||
if (fields >= 11)
|
if (fields >= 11)
|
||||||
@ -662,12 +642,12 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
int class = _gpgme_hextobyte (field[10]);
|
int class = _gpgme_hextobyte (field[10]);
|
||||||
if (class >= 0)
|
if (class >= 0)
|
||||||
{
|
{
|
||||||
certsig->sig_class = class;
|
keysig->class = class;
|
||||||
if (class == 0x30)
|
if (class == 0x30)
|
||||||
certsig->flags.revoked = 1;
|
keysig->revoked = 1;
|
||||||
}
|
}
|
||||||
if (field[10][2] == 'x')
|
if (field[10][2] == 'x')
|
||||||
certsig->flags.exportable = 1;
|
keysig->exportable = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -682,162 +662,134 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
void
|
void
|
||||||
_gpgme_op_keylist_event_cb (void *data, GpgmeEventIO type, void *type_data)
|
_gpgme_op_keylist_event_cb (void *data, GpgmeEventIO type, void *type_data)
|
||||||
{
|
{
|
||||||
|
GpgmeError err;
|
||||||
GpgmeCtx ctx = (GpgmeCtx) data;
|
GpgmeCtx ctx = (GpgmeCtx) data;
|
||||||
GpgmeKey key = (GpgmeKey) type_data;
|
GpgmeKey key = (GpgmeKey) type_data;
|
||||||
|
op_data_t opd;
|
||||||
struct key_queue_item_s *q, *q2;
|
struct key_queue_item_s *q, *q2;
|
||||||
|
|
||||||
assert (type == GPGME_EVENT_NEXT_KEY);
|
assert (type == GPGME_EVENT_NEXT_KEY);
|
||||||
|
|
||||||
|
err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &opd, -1, NULL);
|
||||||
|
if (err)
|
||||||
|
return;
|
||||||
|
|
||||||
q = malloc (sizeof *q);
|
q = malloc (sizeof *q);
|
||||||
if (!q)
|
if (!q)
|
||||||
{
|
{
|
||||||
gpgme_key_release (key);
|
gpgme_key_unref (key);
|
||||||
/* FIXME return GPGME_Out_Of_Core; */
|
/* FIXME return GPGME_Out_Of_Core; */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
q->key = key;
|
q->key = key;
|
||||||
q->next = NULL;
|
q->next = NULL;
|
||||||
/* FIXME: Lock queue. Use a tail pointer? */
|
/* FIXME: Use a tail pointer? */
|
||||||
if (!(q2 = ctx->key_queue))
|
if (!(q2 = opd->key_queue))
|
||||||
ctx->key_queue = q;
|
opd->key_queue = q;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (; q2->next; q2 = q2->next)
|
for (; q2->next; q2 = q2->next)
|
||||||
;
|
;
|
||||||
q2->next = q;
|
q2->next = q;
|
||||||
}
|
}
|
||||||
ctx->key_cond = 1;
|
opd->key_cond = 1;
|
||||||
/* FIXME: Unlock queue. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/* Start a keylist operation within CTX, searching for keys which
|
||||||
* gpgme_op_keylist_start:
|
match PATTERN. If SECRET_ONLY is true, only secret keys are
|
||||||
* @c: context
|
returned. */
|
||||||
* @pattern: a GnuPG user ID or NULL for all
|
|
||||||
* @secret_only: List only keys where the secret part is available
|
|
||||||
*
|
|
||||||
* Note that this function also cancels a pending key listing
|
|
||||||
* operaton. To actually retrieve the key, use
|
|
||||||
* gpgme_op_keylist_next().
|
|
||||||
*
|
|
||||||
* Return value: 0 on success or an errorcode.
|
|
||||||
**/
|
|
||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_op_keylist_start (GpgmeCtx ctx, const char *pattern, int secret_only)
|
gpgme_op_keylist_start (GpgmeCtx ctx, const char *pattern, int secret_only)
|
||||||
{
|
{
|
||||||
GpgmeError err = 0;
|
GpgmeError err;
|
||||||
|
op_data_t opd;
|
||||||
|
|
||||||
err = _gpgme_op_reset (ctx, 2);
|
err = _gpgme_op_reset (ctx, 2);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
return err;
|
||||||
|
|
||||||
gpgme_key_release (ctx->tmp_key);
|
err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &opd,
|
||||||
ctx->tmp_key = NULL;
|
sizeof (*opd), release_op_data);
|
||||||
/* Fixme: Release key_queue. */
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
_gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
|
_gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
|
||||||
|
|
||||||
err = _gpgme_engine_set_colon_line_handler (ctx->engine,
|
err = _gpgme_engine_set_colon_line_handler (ctx->engine,
|
||||||
keylist_colon_handler, ctx);
|
keylist_colon_handler, ctx);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
return err;
|
||||||
|
|
||||||
err = _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only,
|
return _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only,
|
||||||
ctx->keylist_mode);
|
ctx->keylist_mode);
|
||||||
|
|
||||||
leave:
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
_gpgme_engine_release (ctx->engine);
|
|
||||||
ctx->engine = NULL;
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/* Start a keylist operation within CTX, searching for keys which
|
||||||
* gpgme_op_keylist_ext_start:
|
match PATTERN. If SECRET_ONLY is true, only secret keys are
|
||||||
* @c: context
|
returned. */
|
||||||
* @pattern: a NULL terminated array of search patterns
|
|
||||||
* @secret_only: List only keys where the secret part is available
|
|
||||||
* @reserved: Should be 0.
|
|
||||||
*
|
|
||||||
* Note that this function also cancels a pending key listing
|
|
||||||
* operaton. To actually retrieve the key, use
|
|
||||||
* gpgme_op_keylist_next().
|
|
||||||
*
|
|
||||||
* Return value: 0 on success or an errorcode.
|
|
||||||
**/
|
|
||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_op_keylist_ext_start (GpgmeCtx ctx, const char *pattern[],
|
gpgme_op_keylist_ext_start (GpgmeCtx ctx, const char *pattern[],
|
||||||
int secret_only, int reserved)
|
int secret_only, int reserved)
|
||||||
{
|
{
|
||||||
GpgmeError err = 0;
|
GpgmeError err;
|
||||||
|
op_data_t opd;
|
||||||
|
|
||||||
err = _gpgme_op_reset (ctx, 2);
|
err = _gpgme_op_reset (ctx, 2);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
return err;
|
||||||
|
|
||||||
gpgme_key_release (ctx->tmp_key);
|
err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &opd,
|
||||||
ctx->tmp_key = NULL;
|
sizeof (*opd), release_op_data);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
_gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
|
_gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
|
||||||
err = _gpgme_engine_set_colon_line_handler (ctx->engine,
|
err = _gpgme_engine_set_colon_line_handler (ctx->engine,
|
||||||
keylist_colon_handler, ctx);
|
keylist_colon_handler, ctx);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
return err;
|
||||||
|
|
||||||
err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only,
|
return _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only,
|
||||||
reserved, ctx->keylist_mode);
|
reserved, ctx->keylist_mode);
|
||||||
|
|
||||||
leave:
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
_gpgme_engine_release (ctx->engine);
|
|
||||||
ctx->engine = NULL;
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/* Return the next key from the keylist in R_KEY. */
|
||||||
* gpgme_op_keylist_next:
|
|
||||||
* @c: Context
|
|
||||||
* @r_key: Returned key object
|
|
||||||
*
|
|
||||||
* Return the next key from the key listing started with
|
|
||||||
* gpgme_op_keylist_start(). The caller must free the key using
|
|
||||||
* gpgme_key_release(). If the last key has already been returned the
|
|
||||||
* last time the function was called, %GPGME_EOF is returned and the
|
|
||||||
* operation is finished.
|
|
||||||
*
|
|
||||||
* Return value: 0 on success, %GPGME_EOF or another error code.
|
|
||||||
**/
|
|
||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_op_keylist_next (GpgmeCtx ctx, GpgmeKey *r_key)
|
gpgme_op_keylist_next (GpgmeCtx ctx, GpgmeKey *r_key)
|
||||||
{
|
{
|
||||||
|
GpgmeError err;
|
||||||
struct key_queue_item_s *queue_item;
|
struct key_queue_item_s *queue_item;
|
||||||
|
op_data_t opd;
|
||||||
|
|
||||||
if (!r_key)
|
if (!ctx || !r_key)
|
||||||
return GPGME_Invalid_Value;
|
return GPGME_Invalid_Value;
|
||||||
*r_key = NULL;
|
*r_key = NULL;
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return GPGME_Invalid_Value;
|
return GPGME_Invalid_Value;
|
||||||
|
|
||||||
if (!ctx->key_queue)
|
err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &opd, -1, NULL);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (!opd->key_queue)
|
||||||
{
|
{
|
||||||
GpgmeError err = _gpgme_wait_on_condition (ctx, &ctx->key_cond);
|
err = _gpgme_wait_on_condition (ctx, &opd->key_cond);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
if (!ctx->key_cond)
|
|
||||||
|
if (!opd->key_cond)
|
||||||
return GPGME_EOF;
|
return GPGME_EOF;
|
||||||
ctx->key_cond = 0;
|
|
||||||
assert (ctx->key_queue);
|
opd->key_cond = 0;
|
||||||
|
assert (opd->key_queue);
|
||||||
}
|
}
|
||||||
queue_item = ctx->key_queue;
|
queue_item = opd->key_queue;
|
||||||
ctx->key_queue = queue_item->next;
|
opd->key_queue = queue_item->next;
|
||||||
if (!ctx->key_queue)
|
if (!opd->key_queue)
|
||||||
ctx->key_cond = 0;
|
opd->key_cond = 0;
|
||||||
|
|
||||||
*r_key = queue_item->key;
|
*r_key = queue_item->key;
|
||||||
free (queue_item);
|
free (queue_item);
|
||||||
@ -845,13 +797,7 @@ gpgme_op_keylist_next (GpgmeCtx ctx, GpgmeKey *r_key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/* Terminate a pending keylist operation within CTX. */
|
||||||
* gpgme_op_keylist_end:
|
|
||||||
* @c: Context
|
|
||||||
*
|
|
||||||
* Ends the keylist operation and allows to use the context for some
|
|
||||||
* other operation next.
|
|
||||||
**/
|
|
||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_op_keylist_end (GpgmeCtx ctx)
|
gpgme_op_keylist_end (GpgmeCtx ctx)
|
||||||
{
|
{
|
||||||
|
23
gpgme/ops.h
23
gpgme/ops.h
@ -53,10 +53,6 @@ GpgmeError _gpgme_data_append_percentstring_for_xml ( GpgmeData dh,
|
|||||||
GpgmeError _gpgme_data_inbound_handler (void *opaque, int fd);
|
GpgmeError _gpgme_data_inbound_handler (void *opaque, int fd);
|
||||||
GpgmeError _gpgme_data_outbound_handler (void *opaque, int fd);
|
GpgmeError _gpgme_data_outbound_handler (void *opaque, int fd);
|
||||||
|
|
||||||
/*-- key.c --*/
|
|
||||||
GpgmeError _gpgme_key_new ( GpgmeKey *r_key );
|
|
||||||
GpgmeError _gpgme_key_new_secret ( GpgmeKey *r_key );
|
|
||||||
|
|
||||||
|
|
||||||
/* From op-support.c. */
|
/* From op-support.c. */
|
||||||
|
|
||||||
@ -119,12 +115,27 @@ GpgmeError _gpgme_progress_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
|
|||||||
char *args);
|
char *args);
|
||||||
|
|
||||||
|
|
||||||
/*-- keylist.c --*/
|
/* From key.c. */
|
||||||
|
GpgmeError _gpgme_key_new (GpgmeKey *r_key);
|
||||||
|
GpgmeError _gpgme_key_add_subkey (GpgmeKey key, GpgmeSubkey *r_subkey);
|
||||||
|
GpgmeError _gpgme_key_append_name (GpgmeKey key, char *src);
|
||||||
|
GpgmeKeySig _gpgme_key_add_sig (GpgmeKey key, char *src);
|
||||||
|
|
||||||
|
|
||||||
|
/* From keylist.c. */
|
||||||
void _gpgme_op_keylist_event_cb (void *data, GpgmeEventIO type, void *type_data);
|
void _gpgme_op_keylist_event_cb (void *data, GpgmeEventIO type, void *type_data);
|
||||||
|
|
||||||
/*-- trustlist.c --*/
|
|
||||||
|
/* From trust-item.c. */
|
||||||
|
|
||||||
|
/* Create a new trust item. */
|
||||||
|
GpgmeError _gpgme_trust_item_new (GpgmeTrustItem *r_item);
|
||||||
|
|
||||||
|
|
||||||
|
/* From trustlist.c. */
|
||||||
void _gpgme_op_trustlist_event_cb (void *data, GpgmeEventIO type, void *type_data);
|
void _gpgme_op_trustlist_event_cb (void *data, GpgmeEventIO type, void *type_data);
|
||||||
|
|
||||||
|
|
||||||
/*-- version.c --*/
|
/*-- version.c --*/
|
||||||
const char *_gpgme_compare_versions (const char *my_version,
|
const char *_gpgme_compare_versions (const char *my_version,
|
||||||
const char *req_version);
|
const char *req_version);
|
||||||
|
@ -21,220 +21,143 @@
|
|||||||
#if HAVE_CONFIG_H
|
#if HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "util.h"
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* gpgme_recipients_new:
|
/* Create a new uninitialized recipient object and return it in R_RSET. */
|
||||||
* @r_rset: Returns the new object.
|
|
||||||
*
|
|
||||||
* Create a new uninitialized Reciepient set Object.
|
|
||||||
*
|
|
||||||
* Return value: 0 on success or an error code.
|
|
||||||
**/
|
|
||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_recipients_new (GpgmeRecipients *r_rset)
|
gpgme_recipients_new (GpgmeRecipients *r_rset)
|
||||||
{
|
{
|
||||||
GpgmeRecipients rset;
|
GpgmeRecipients rset;
|
||||||
|
|
||||||
rset = calloc ( 1, sizeof *rset );
|
rset = calloc (1, sizeof *rset);
|
||||||
if (!rset)
|
if (!rset)
|
||||||
return GPGME_Out_Of_Core;
|
return GPGME_Out_Of_Core;
|
||||||
*r_rset = rset;
|
*r_rset = rset;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gpgme_recipients_release:
|
/* Release the recipient object RSET. */
|
||||||
* @rset: Recipient Set object
|
|
||||||
*
|
|
||||||
* Free the given object.
|
|
||||||
**/
|
|
||||||
void
|
void
|
||||||
gpgme_recipients_release ( GpgmeRecipients rset )
|
gpgme_recipients_release (GpgmeRecipients rset)
|
||||||
{
|
{
|
||||||
if (rset) {
|
GpgmeUserID uid = rset->list;
|
||||||
struct user_id_s *u, *u2;
|
|
||||||
|
|
||||||
for (u = rset->list; u; u = u2) {
|
while (uid)
|
||||||
u2 = u->next;
|
{
|
||||||
free(u);
|
GpgmeUserID next_uid = uid->next;
|
||||||
}
|
|
||||||
|
free (uid);
|
||||||
|
uid = next_uid;
|
||||||
}
|
}
|
||||||
free ( rset );
|
free (rset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/* Add the name NAME to the recipient set RSET with the given key
|
||||||
* gpgme_recipients_add_name:
|
validity VALIDITY. */
|
||||||
* @rset: Recipient Set object
|
|
||||||
* @name: user name or keyID
|
|
||||||
*
|
|
||||||
* Add a name to the recipient Set.
|
|
||||||
*
|
|
||||||
* Return value: 0 on success or an error code
|
|
||||||
**/
|
|
||||||
GpgmeError
|
|
||||||
gpgme_recipients_add_name (GpgmeRecipients rset, const char *name )
|
|
||||||
{
|
|
||||||
return gpgme_recipients_add_name_with_validity (
|
|
||||||
rset, name, GPGME_VALIDITY_UNKNOWN
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gpgme_recipients_add_name_with_validity:
|
|
||||||
* @rset: Recipient Set object
|
|
||||||
* @name: user name or keyID
|
|
||||||
* @val: Validity value
|
|
||||||
*
|
|
||||||
* Same as gpgme_recipients_add_name() but with explictly given key
|
|
||||||
* validity. Use one of the constants
|
|
||||||
* %GPGME_VALIDITY_UNKNOWN, %GPGME_VALIDITY_UNDEFINED,
|
|
||||||
* %GPGME_VALIDITY_NEVER, %GPGME_VALIDITY_MARGINAL,
|
|
||||||
* %GPGME_VALIDITY_FULL, %GPGME_VALIDITY_ULTIMATE
|
|
||||||
* for the validity. %GPGME_VALIDITY_UNKNOWN is implicitly used by
|
|
||||||
* gpgme_recipients_add_name().
|
|
||||||
*
|
|
||||||
* Return value: o on success or an error value.
|
|
||||||
**/
|
|
||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_recipients_add_name_with_validity (GpgmeRecipients rset,
|
gpgme_recipients_add_name_with_validity (GpgmeRecipients rset,
|
||||||
const char *name,
|
const char *name,
|
||||||
GpgmeValidity val )
|
GpgmeValidity validity)
|
||||||
{
|
{
|
||||||
struct user_id_s *r;
|
GpgmeUserID uid;
|
||||||
|
|
||||||
if (!name || !rset )
|
if (!name || !rset)
|
||||||
return GPGME_Invalid_Value;
|
return GPGME_Invalid_Value;
|
||||||
r = malloc ( sizeof *r + strlen (name) );
|
uid = malloc (sizeof (*uid) + strlen (name));
|
||||||
if (!r)
|
if (!uid)
|
||||||
return GPGME_Out_Of_Core;
|
return GPGME_Out_Of_Core;
|
||||||
r->validity = val;
|
uid->validity = validity;
|
||||||
r->name_part = "";
|
uid->name = "";
|
||||||
r->email_part = "";
|
uid->email = "";
|
||||||
r->comment_part = "";
|
uid->comment = "";
|
||||||
strcpy (r->name, name );
|
uid->uid = ((char *) uid) + sizeof (*uid);
|
||||||
r->next = rset->list;
|
strcpy (uid->uid, name);
|
||||||
rset->list = r;
|
uid->next = rset->list;
|
||||||
return 0;
|
rset->list = uid;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Add the name NAME to the recipient set RSET. Same as
|
||||||
|
gpgme_recipients_add_name_with_validity with validitiy
|
||||||
|
GPGME_VALIDITY_UNKNOWN. */
|
||||||
|
GpgmeError
|
||||||
|
gpgme_recipients_add_name (GpgmeRecipients rset, const char *name)
|
||||||
|
{
|
||||||
|
return gpgme_recipients_add_name_with_validity (rset, name,
|
||||||
|
GPGME_VALIDITY_UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gpgme_recipients_count:
|
/* Return the number of recipients in the set. */
|
||||||
* @rset: Recipient Set object
|
|
||||||
*
|
|
||||||
* Return value: The number of recipients in the set.
|
|
||||||
**/
|
|
||||||
unsigned int
|
unsigned int
|
||||||
gpgme_recipients_count ( const GpgmeRecipients rset )
|
gpgme_recipients_count (const GpgmeRecipients rset)
|
||||||
{
|
{
|
||||||
struct user_id_s *r;
|
GpgmeUserID uid = rset->list;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
|
||||||
if ( rset ) {
|
while (uid)
|
||||||
for (r=rset->list ; r; r = r->next )
|
{
|
||||||
count++;
|
count++;
|
||||||
|
uid = uid->next;
|
||||||
}
|
}
|
||||||
return count;
|
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Start an enumeration on the recipient set RSET. The caller must
|
||||||
/**
|
pass the address of a void pointer which is used as the iterator
|
||||||
* gpgme_recipients_enum_open:
|
object. */
|
||||||
* @rset: Recipient Set object
|
|
||||||
* @ctx: Enumerator
|
|
||||||
*
|
|
||||||
* Start an enumeration on the Recipient Set object. The caller must pass
|
|
||||||
* the address of a void pointer which is used as the enumerator object.
|
|
||||||
*
|
|
||||||
* Return value: 0 on success or an error code.
|
|
||||||
*
|
|
||||||
* See also: gpgme_recipients_enum_read(), gpgme_recipients_enum_close().
|
|
||||||
**/
|
|
||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_recipients_enum_open ( const GpgmeRecipients rset, void **ctx )
|
gpgme_recipients_enum_open (const GpgmeRecipients rset, void **iter)
|
||||||
{
|
{
|
||||||
if (!rset || !ctx)
|
*iter = rset->list;
|
||||||
return GPGME_Invalid_Value;
|
return 0;
|
||||||
|
|
||||||
*ctx = rset->list;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* Return the name of the next recipient in the set RSET. */
|
||||||
* gpgme_recipients_enum_read:
|
|
||||||
* @rset: Recipient Set object
|
|
||||||
* @ctx: Enumerator
|
|
||||||
*
|
|
||||||
* Return the name of the next user name from the given recipient
|
|
||||||
* set. This name is valid as along as the @rset is valid and until
|
|
||||||
* the next call to this function.
|
|
||||||
*
|
|
||||||
* Return value: name or NULL for no more names.
|
|
||||||
*
|
|
||||||
* See also: gpgme_recipients_enum_read(), gpgme_recipients_enum_close().
|
|
||||||
**/
|
|
||||||
const char *
|
const char *
|
||||||
gpgme_recipients_enum_read ( const GpgmeRecipients rset, void **ctx )
|
gpgme_recipients_enum_read (const GpgmeRecipients rset, void **iter)
|
||||||
{
|
{
|
||||||
struct user_id_s *r;
|
GpgmeUserID uid;
|
||||||
|
|
||||||
if (!rset || !ctx)
|
|
||||||
return NULL; /* oops */
|
|
||||||
|
|
||||||
r = *ctx;
|
|
||||||
if ( r ) {
|
|
||||||
const char *s = r->name;
|
|
||||||
r = r->next;
|
|
||||||
*ctx = r;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
uid = *iter;
|
||||||
|
if (!uid)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
*iter = uid->next;
|
||||||
|
return uid->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* Release the iterator for this object. */
|
||||||
* gpgme_recipients_enum_close:
|
|
||||||
* @rset: Recipient Set object
|
|
||||||
* @ctx: Enumerator
|
|
||||||
*
|
|
||||||
* Release the enumerator @rset for this object.
|
|
||||||
*
|
|
||||||
* Return value: 0 on success or %GPGME_Invalid_Value;
|
|
||||||
*
|
|
||||||
* See also: gpgme_recipients_enum_read(), gpgme_recipients_enum_close().
|
|
||||||
**/
|
|
||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_recipients_enum_close ( const GpgmeRecipients rset, void **ctx )
|
gpgme_recipients_enum_close (const GpgmeRecipients rset, void **iter)
|
||||||
{
|
{
|
||||||
if (!rset || !ctx)
|
/* Not really needed, but might catch the occasional mistake. */
|
||||||
return GPGME_Invalid_Value;
|
*iter = NULL;
|
||||||
*ctx = NULL;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_gpgme_recipients_all_valid ( const GpgmeRecipients rset )
|
_gpgme_recipients_all_valid (const GpgmeRecipients rset)
|
||||||
{
|
{
|
||||||
struct user_id_s *r;
|
GpgmeUserID uid = rset->list;
|
||||||
|
|
||||||
assert (rset);
|
while (uid)
|
||||||
for (r=rset->list ; r; r = r->next ) {
|
{
|
||||||
if (r->validity != GPGME_VALIDITY_FULL
|
if (uid->validity != GPGME_VALIDITY_FULL
|
||||||
&& r->validity != GPGME_VALIDITY_ULTIMATE )
|
&& uid->validity != GPGME_VALIDITY_ULTIMATE )
|
||||||
return 0; /*no*/
|
return 0;
|
||||||
|
uid = uid->next;
|
||||||
}
|
}
|
||||||
return 1; /*yes*/
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -437,9 +437,10 @@ gpg_set_colon_line_handler (void *engine, EngineColonLineHandler fnc,
|
|||||||
|
|
||||||
/* Here we handle --command-fd. This works closely together with the
|
/* Here we handle --command-fd. This works closely together with the
|
||||||
status handler. */
|
status handler. */
|
||||||
static int
|
static GpgmeError
|
||||||
command_cb (void *opaque, char *buffer, size_t length, size_t *nread)
|
command_cb (void *opaque, char *buffer, size_t length, size_t *nread)
|
||||||
{
|
{
|
||||||
|
GpgmeError err;
|
||||||
GpgObject gpg = opaque;
|
GpgObject gpg = opaque;
|
||||||
const char *value;
|
const char *value;
|
||||||
int value_len;
|
int value_len;
|
||||||
@ -462,8 +463,11 @@ command_cb (void *opaque, char *buffer, size_t length, size_t *nread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME catch error */
|
/* FIXME catch error */
|
||||||
gpg->cmd.fnc (gpg->cmd.fnc_value,
|
err = gpg->cmd.fnc (gpg->cmd.fnc_value,
|
||||||
gpg->cmd.code, gpg->cmd.keyword, &value);
|
gpg->cmd.code, gpg->cmd.keyword, &value);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
if (!value)
|
if (!value)
|
||||||
{
|
{
|
||||||
DEBUG0 ("command_cb: no data from user cb\n");
|
DEBUG0 ("command_cb: no data from user cb\n");
|
||||||
@ -1200,11 +1204,10 @@ gpg_delete (void *engine, GpgmeKey key, int allow_secret)
|
|||||||
err = add_arg (gpg, "--");
|
err = add_arg (gpg, "--");
|
||||||
if (!err)
|
if (!err)
|
||||||
{
|
{
|
||||||
const char *s = gpgme_key_get_string_attr (key, GPGME_ATTR_FPR, NULL, 0);
|
if (!key->subkeys || !key->subkeys->fpr)
|
||||||
if (!s)
|
|
||||||
err = GPGME_Invalid_Key;
|
err = GPGME_Invalid_Key;
|
||||||
else
|
else
|
||||||
err = add_arg (gpg, s);
|
err = add_arg (gpg, key->subkeys->fpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
@ -1222,8 +1225,7 @@ append_args_from_signers (GpgObject gpg, GpgmeCtx ctx /* FIXME */)
|
|||||||
|
|
||||||
for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
|
for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
|
||||||
{
|
{
|
||||||
const char *s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID,
|
const char *s = key->subkeys ? key->subkeys->keyid : NULL;
|
||||||
NULL, 0);
|
|
||||||
if (s)
|
if (s)
|
||||||
{
|
{
|
||||||
if (!err)
|
if (!err)
|
||||||
@ -1255,7 +1257,7 @@ gpg_edit (void *engine, GpgmeKey key, GpgmeData out, GpgmeCtx ctx /* FIXME */)
|
|||||||
err = add_arg (gpg, "--");
|
err = add_arg (gpg, "--");
|
||||||
if (!err)
|
if (!err)
|
||||||
{
|
{
|
||||||
const char *s = gpgme_key_get_string_attr (key, GPGME_ATTR_FPR, NULL, 0);
|
const char *s = key->subkeys ? key->subkeys->fpr : NULL;
|
||||||
if (!s)
|
if (!s)
|
||||||
err = GPGME_Invalid_Key;
|
err = GPGME_Invalid_Key;
|
||||||
else
|
else
|
||||||
@ -1272,14 +1274,14 @@ static GpgmeError
|
|||||||
append_args_from_recipients (GpgObject gpg, const GpgmeRecipients rset)
|
append_args_from_recipients (GpgObject gpg, const GpgmeRecipients rset)
|
||||||
{
|
{
|
||||||
GpgmeError err = 0;
|
GpgmeError err = 0;
|
||||||
struct user_id_s *r;
|
GpgmeUserID uid;
|
||||||
|
|
||||||
assert (rset);
|
assert (rset);
|
||||||
for (r = rset->list; r; r = r->next)
|
for (uid = rset->list; uid; uid = uid->next)
|
||||||
{
|
{
|
||||||
err = add_arg (gpg, "-r");
|
err = add_arg (gpg, "-r");
|
||||||
if (!err)
|
if (!err)
|
||||||
err = add_arg (gpg, r->name);
|
err = add_arg (gpg, uid->uid);
|
||||||
if (err)
|
if (err)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -48,10 +48,10 @@ _gpgme_trust_item_new (GpgmeTrustItem *r_item)
|
|||||||
item->_refs = 1;
|
item->_refs = 1;
|
||||||
item->keyid = item->_keyid;
|
item->keyid = item->_keyid;
|
||||||
item->_keyid[16] = '\0';
|
item->_keyid[16] = '\0';
|
||||||
item->otrust = item->_otrust;
|
item->owner_trust = item->_owner_trust;
|
||||||
item->_otrust[1] = '\0';
|
item->_owner_trust[1] = '\0';
|
||||||
item->val = item->_val;
|
item->validity = item->_validity;
|
||||||
item->_val[1] = '\0';
|
item->_validity[1] = '\0';
|
||||||
*r_item = item;
|
*r_item = item;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -119,11 +119,11 @@ const char *gpgme_trust_item_get_string_attr (GpgmeTrustItem item,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GPGME_ATTR_OTRUST:
|
case GPGME_ATTR_OTRUST:
|
||||||
val = item->otrust;
|
val = item->owner_trust;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPGME_ATTR_VALIDITY:
|
case GPGME_ATTR_VALIDITY:
|
||||||
val = item->val;
|
val = item->validity;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPGME_ATTR_USERID:
|
case GPGME_ATTR_USERID:
|
||||||
|
@ -99,10 +99,10 @@ trustlist_colon_handler (void *priv, char *line)
|
|||||||
item->type = *p == 'K'? 1 : *p == 'U'? 2 : 0;
|
item->type = *p == 'K'? 1 : *p == 'U'? 2 : 0;
|
||||||
break;
|
break;
|
||||||
case 5: /* owner trust */
|
case 5: /* owner trust */
|
||||||
item->_otrust[0] = *p;
|
item->_owner_trust[0] = *p;
|
||||||
break;
|
break;
|
||||||
case 6: /* validity */
|
case 6: /* validity */
|
||||||
item->_val[0] = *p;
|
item->_validity[0] = *p;
|
||||||
break;
|
break;
|
||||||
case 9: /* user ID */
|
case 9: /* user ID */
|
||||||
item->name = strdup (p);
|
item->name = strdup (p);
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
2003-04-30 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
* gpg/t-keylist.c: Rewritten.
|
||||||
|
* gpgsm/t-keylist.c (main): Rewritten.
|
||||||
|
* gpg/t-edit.c (main): Do not use gpgme_key_get_as_xml. Use
|
||||||
|
gpgme_key_unref instead gpgme_key_release.
|
||||||
|
* gpg/t-signers.c (main): Use gpgme_key_unref instead
|
||||||
|
gpgme_key_release.
|
||||||
|
|
||||||
2003-04-29 Marcus Brinkmann <marcus@g10code.de>
|
2003-04-29 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* gpg/t-trustlist.c: Rewritten.
|
* gpg/t-trustlist.c: Rewritten.
|
||||||
|
@ -150,13 +150,6 @@ main (int argc, char **argv)
|
|||||||
err = gpgme_op_keylist_end (ctx);
|
err = gpgme_op_keylist_end (ctx);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
|
||||||
p = gpgme_key_get_as_xml (key);
|
|
||||||
if (p)
|
|
||||||
{
|
|
||||||
fputs (p, stdout);
|
|
||||||
free (p);
|
|
||||||
}
|
|
||||||
|
|
||||||
err = gpgme_op_edit (ctx, key, edit_fnc, out, out);
|
err = gpgme_op_edit (ctx, key, edit_fnc, out, out);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
|
||||||
@ -164,7 +157,7 @@ main (int argc, char **argv)
|
|||||||
flush_data (out);
|
flush_data (out);
|
||||||
|
|
||||||
gpgme_data_release (out);
|
gpgme_data_release (out);
|
||||||
gpgme_key_release (key);
|
gpgme_key_unref (key);
|
||||||
gpgme_release (ctx);
|
gpgme_release (ctx);
|
||||||
}
|
}
|
||||||
while (argc > 1 && !strcmp( argv[1], "--loop"));
|
while (argc > 1 && !strcmp( argv[1], "--loop"));
|
||||||
|
@ -1,170 +1,537 @@
|
|||||||
/* t-keylist.c - regression test
|
/* t-keylist.c - regression test
|
||||||
* Copyright (C) 2000 Werner Koch (dd9jn)
|
Copyright (C) 2000 Werner Koch (dd9jn)
|
||||||
* Copyright (C) 2001 g10 Code GmbH
|
Copyright (C) 2001, 2003 g10 Code GmbH
|
||||||
*
|
|
||||||
* This file is part of GPGME.
|
This file is part of GPGME.
|
||||||
*
|
|
||||||
* GPGME is free software; you can redistribute it and/or modify
|
GPGME is free software; you can redistribute it and/or modify it
|
||||||
* it under the terms of the GNU General Public License as published by
|
under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
(at your option) any later version.
|
||||||
*
|
|
||||||
* GPGME is distributed in the hope that it will be useful,
|
GPGME is distributed in the hope that it will be useful, but
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* GNU General Public License for more details.
|
General Public License for more details.
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
along with GPGME; if not, write to the Free Software Foundation,
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <gpgme.h>
|
#include <gpgme.h>
|
||||||
|
|
||||||
#define fail_if_err(a) do { if(a) { \
|
|
||||||
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
|
#define fail_if_err(err) \
|
||||||
__FILE__, __LINE__, gpgme_strerror(a)); \
|
do \
|
||||||
exit (1); } \
|
{ \
|
||||||
} while(0)
|
if (err) \
|
||||||
|
{ \
|
||||||
|
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
|
||||||
|
__FILE__, __LINE__, gpgme_strerror (err)); \
|
||||||
|
exit (1); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
static void
|
|
||||||
doit (GpgmeCtx ctx, const char *pattern)
|
struct
|
||||||
{
|
{
|
||||||
GpgmeError err;
|
char *fpr;
|
||||||
GpgmeKey key;
|
char *sec_keyid;
|
||||||
|
struct
|
||||||
err = gpgme_op_keylist_start (ctx, pattern, 0);
|
{
|
||||||
fail_if_err (err);
|
char *name;
|
||||||
|
char *comment;
|
||||||
while (!(err = gpgme_op_keylist_next (ctx, &key)))
|
char *email;
|
||||||
{
|
} uid[3];
|
||||||
char *p;
|
|
||||||
const char *s;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
printf ("<!-- Begin key object (%p) -->\n", key);
|
|
||||||
p = gpgme_key_get_as_xml (key);
|
|
||||||
if (p)
|
|
||||||
{
|
|
||||||
fputs (p, stdout);
|
|
||||||
free (p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fputs("<!-- Ooops: gpgme_key_get_as_xml failed -->\n", stdout);
|
|
||||||
|
|
||||||
for (i = 0; ; i++)
|
|
||||||
{
|
|
||||||
s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID, NULL, i);
|
|
||||||
if (!s)
|
|
||||||
break;
|
|
||||||
printf ("<!-- keyid.%d=%s -->\n", i, s);
|
|
||||||
s = gpgme_key_get_string_attr (key, GPGME_ATTR_ALGO, NULL, i);
|
|
||||||
printf ("<!-- algo.%d=%s -->\n", i, s);
|
|
||||||
s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEY_CAPS, NULL, i);
|
|
||||||
printf ("<!-- caps.%d=%s -->\n", i, s);
|
|
||||||
}
|
|
||||||
for (i = 0; ; i++)
|
|
||||||
{
|
|
||||||
s = gpgme_key_get_string_attr (key, GPGME_ATTR_NAME, NULL, i);
|
|
||||||
if (!s)
|
|
||||||
break;
|
|
||||||
printf ("<!-- name.%d=%s -->\n", i, s);
|
|
||||||
s = gpgme_key_get_string_attr (key, GPGME_ATTR_EMAIL, NULL, i);
|
|
||||||
printf ("<!-- email.%d=%s -->\n", i, s);
|
|
||||||
s = gpgme_key_get_string_attr (key, GPGME_ATTR_COMMENT, NULL, i);
|
|
||||||
printf ("<!-- comment.%d=%s -->\n", i, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
fputs ("<!-- usable for:", stdout);
|
|
||||||
if ( gpgme_key_get_ulong_attr (key, GPGME_ATTR_CAN_ENCRYPT, NULL, 0))
|
|
||||||
fputs (" encryption", stdout);
|
|
||||||
if ( gpgme_key_get_ulong_attr (key, GPGME_ATTR_CAN_SIGN, NULL, 0))
|
|
||||||
fputs (" signing", stdout);
|
|
||||||
if ( gpgme_key_get_ulong_attr (key, GPGME_ATTR_CAN_CERTIFY, NULL, 0))
|
|
||||||
fputs (" certification", stdout);
|
|
||||||
fputs (" -->\n", stdout );
|
|
||||||
|
|
||||||
printf ("<!-- End key object (%p) -->\n", key);
|
|
||||||
gpgme_key_release (key);
|
|
||||||
}
|
|
||||||
if (err != GPGME_EOF)
|
|
||||||
fail_if_err (err);
|
|
||||||
}
|
}
|
||||||
|
keys[] =
|
||||||
|
{
|
||||||
/*
|
{ "A0FF4590BB6122EDEF6E3C542D727CC768697734", "6AE6D7EE46A871F8",
|
||||||
* Check that there are no problems when we are using two context for
|
{ { "Alpha Test", "demo key", "alpha@example.net" },
|
||||||
* listing keys.
|
{ "Alice", "demo key", NULL },
|
||||||
*/
|
{ "Alfa Test", "demo key", "alfa@example.net" } } },
|
||||||
static void
|
{ "61EE841A2A27EB983B3B3C26413F4AF31AFDAB6C", "E71E72ACBC43DA60",
|
||||||
check_two_contexts (void)
|
{ { "Charlie Test", "demo key", "charlie@example.net" } } },
|
||||||
{
|
{ "3531152DE293E26A07F504BC318C1FAEFAEF6D1B", "B5C79E1A7272144D",
|
||||||
GpgmeError err;
|
{ { "Echelon", "demo key", NULL },
|
||||||
GpgmeCtx ctx1, ctx2;
|
{ "Echo Test", "demo key", "echo@example.net" },
|
||||||
GpgmeKey key;
|
{ "Eve", "demo key", NULL } } },
|
||||||
|
{ "C9C07DCC6621B9FB8D071B1D168410A48FC282E6", "247491CC9DCAD354",
|
||||||
err = gpgme_new(&ctx1); fail_if_err (err);
|
{ { "Golf Test", "demo key", "golf@example.net" } } },
|
||||||
err = gpgme_op_keylist_start(ctx1, "", 1);
|
{ "CD538D6CC9FB3D745ECDA5201FE8FC6F04259677", "C1C8EFDE61F76C73",
|
||||||
fail_if_err (err);
|
{ { "India Test", "demo key", "india@example.net" } } },
|
||||||
err = gpgme_new(&ctx2); fail_if_err (err);
|
{ "3FD11083779196C2ECDD9594AD1B0FAD43C2D0C7", "86CBB34A9AF64D02",
|
||||||
err = gpgme_op_keylist_start(ctx2, "", 1);
|
{ { "Kilo Test", "demo key", "kilo@example.net" } } },
|
||||||
fail_if_err (err);
|
{ "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2", "5381EA4EE29BA37F",
|
||||||
|
{ { "Bob", "demo key", NULL },
|
||||||
while ((err = gpgme_op_keylist_next (ctx2, &key)) != GPGME_EOF)
|
{ "Bravo Test", "demo key", "bravo@example.net" } } },
|
||||||
gpgme_key_release (key);
|
{ "6560C59C43D031C54D7C588EEBA9F240EB9DC9E6", "06F22880B0C45424",
|
||||||
|
{ { "Delta Test", "demo key", "delta@example.net" } } },
|
||||||
if (err != GPGME_EOF)
|
{ "56D33268F7FE693FBB594762D4BF57F37372E243", "0A32EE79EE45198E",
|
||||||
fail_if_err (err);
|
{ { "Foxtrot Test", "demo key", "foxtrot@example.net" } } },
|
||||||
while ((err=gpgme_op_keylist_next(ctx1, &key)) != GPGME_EOF)
|
{ "9E91CBB11E4D4135583EF90513DB965534C6E3F1", "76E26537D622AD0A",
|
||||||
gpgme_key_release (key);
|
{ { "Hotel Test", "demo key", "hotel@example.net" } } },
|
||||||
|
{ "F8F1EDC73995AB739AD54B380C820C71D2699313", "BD0B108735F8F136",
|
||||||
if (err != GPGME_EOF)
|
{ { "Juliet Test", "demo key", "juliet@example.net" } } },
|
||||||
fail_if_err (err);
|
{ "1DDD28CEF714F5B03B8C246937CAB51FB79103F8", "0363B449FE56350C",
|
||||||
}
|
{ { "Lima Test", "demo key", "lima@example.net" } } },
|
||||||
|
{ "2686AA191A278013992C72EBBE794852BE5CF886", "5F600A834F31EAE8",
|
||||||
|
{ { "Mallory", "demo key", NULL },
|
||||||
|
{ "Mike Test", "demo key", "mike@example.net" } } },
|
||||||
|
{ "5AB9D6D7BAA1C95B3BAA3D9425B00FD430CEC684", "4C1D63308B70E472",
|
||||||
|
{ { "November Test", "demo key", "november@example.net" } } },
|
||||||
|
{ "43929E89F8F79381678CAE515F6356BA6D9732AC", "FF0785712681619F",
|
||||||
|
{ { "Oscar Test", "demo key", "oscar@example.net" } } },
|
||||||
|
{ "6FAA9C201E5E26DCBAEC39FD5D15E01D3FF13206", "2764E18263330D9C",
|
||||||
|
{ { "Papa test", "demo key", "papa@example.net" } } },
|
||||||
|
{ "A7969DA1C3297AA96D49843F1C67EC133C661C84", "6CDCFC44A029ACF4",
|
||||||
|
{ { "Quebec Test", "demo key", "quebec@example.net" } } },
|
||||||
|
{ "38FBE1E4BF6A5E1242C8F6A13BDBEDB1777FBED3", "9FAB805A11D102EA",
|
||||||
|
{ { "Romeo Test", "demo key", "romeo@example.net" } } },
|
||||||
|
{ "045B2334ADD69FC221076841A5E67F7FA3AE3EA1", "93B88B0F0F1B50B4",
|
||||||
|
{ { "Sierra Test", "demo key", "sierra@example.net" } } },
|
||||||
|
{ "ECAC774F4EEEB0620767044A58CB9A4C85A81F38", "97B60E01101C0402",
|
||||||
|
{ { "Tango Test", "demo key", "tango@example.net" } } },
|
||||||
|
{ "0DBCAD3F08843B9557C6C4D4A94C0F75653244D6", "93079B915522BDB9",
|
||||||
|
{ { "Uniform Test", "demo key", "uniform@example.net" } } },
|
||||||
|
{ "E8143C489C8D41124DC40D0B47AF4B6961F04784", "04071FB807287134",
|
||||||
|
{ { "Victor Test", "demo key", "victor@example.org" } } },
|
||||||
|
{ "E8D6C90B683B0982BD557A99DEF0F7B8EC67DBDE", "D7FBB421FD6E27F6",
|
||||||
|
{ { "Whisky Test", "demo key", "whisky@example.net" } } },
|
||||||
|
{ "04C1DF62EFA0EBB00519B06A8979A6C5567FB34A", "5CC6F87F41E408BE",
|
||||||
|
{ { "XRay Test", "demo key", "xray@example.net" } } },
|
||||||
|
{ "ED9B316F78644A58D042655A9EEF34CD4B11B25F", "5ADFD255F7B080AD",
|
||||||
|
{ { "Yankee Test", "demo key", "yankee@example.net" } } },
|
||||||
|
{ "23FD347A419429BACCD5E72D6BC4778054ACD246", "EF9DC276A172C881",
|
||||||
|
{ { "Zulu Test", "demo key", "zulu@example.net" } } },
|
||||||
|
{ "ADAB7FCC1F4DE2616ECFA402AF82244F9CD9FD55", "087DD7E0381701C4",
|
||||||
|
{ { "Joe Random Hacker", "test key with passphrase \"x\"",
|
||||||
|
"joe@setq.org" } } },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
GpgmeCtx ctx;
|
|
||||||
GpgmeError err;
|
GpgmeError err;
|
||||||
int loop = 0;
|
GpgmeCtx ctx;
|
||||||
const char *pattern;
|
GpgmeKey key;
|
||||||
|
GpgmeKeyListResult result;
|
||||||
if (argc)
|
int i = 0;
|
||||||
{
|
|
||||||
argc--;
|
|
||||||
argv++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc && !strcmp( *argv, "--loop"))
|
|
||||||
{
|
|
||||||
loop = 1;
|
|
||||||
argc--; argv++;
|
|
||||||
}
|
|
||||||
pattern = argc? *argv : NULL;
|
|
||||||
|
|
||||||
err = gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP);
|
err = gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
|
||||||
err = gpgme_new (&ctx);
|
err = gpgme_new (&ctx);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
/* No validity calculation. */
|
|
||||||
gpgme_set_keylist_mode (ctx, 1);
|
err = gpgme_op_keylist_start (ctx, NULL, 0);
|
||||||
do
|
fail_if_err (err);
|
||||||
|
|
||||||
|
while (!(err = gpgme_op_keylist_next (ctx, &key)))
|
||||||
{
|
{
|
||||||
fprintf (stderr, "** pattern=`%s'\n", pattern ? pattern : "(null)");
|
if (!keys[i].fpr)
|
||||||
doit (ctx, pattern);
|
{
|
||||||
|
fprintf (stderr, "More keys returned than expected\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Global key flags. */
|
||||||
|
if (key->revoked)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly revoked\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->expired)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly expired\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->disabled)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly disabled\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->invalid)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly invalid\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->can_encrypt)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly unusable for encryption\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->can_sign)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly unusable for signing\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->can_certify)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly unusable for certifications\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->secret)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly secret\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->protocol != GPGME_PROTOCOL_OpenPGP)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key has unexpected protocol: %s\n",
|
||||||
|
gpgme_get_protocol_name (key->protocol));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->issuer_serial)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly carries issuer serial: %s\n",
|
||||||
|
key->issuer_serial);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->issuer_name)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly carries issuer name: %s\n",
|
||||||
|
key->issuer_name);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->chain_id)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly carries chain ID: %s\n",
|
||||||
|
key->chain_id);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->owner_trust != GPGME_VALIDITY_UNKNOWN)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key has unexpected owner trust: %i\n",
|
||||||
|
key->owner_trust);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->subkeys || !key->subkeys->next || key->subkeys->next->next)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key has unexpected number of subkeys\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Primary key. */
|
||||||
|
if (key->subkeys->revoked)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly revoked\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->expired)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly expired\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->disabled)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly disabled\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->invalid)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly invalid\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->can_encrypt)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly usable for encryption\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->subkeys->can_sign)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly unusable for signing\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->subkeys->can_certify)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly unusable for certifications\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->secret)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly secret\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->pubkey_algo != GPGME_PK_DSA)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key has unexpected public key algo: %s\n",
|
||||||
|
gpgme_pubkey_algo_name (key->subkeys->pubkey_algo));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->length != 1024)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key has unexpected length: %i\n",
|
||||||
|
key->subkeys->length);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (strcmp (key->subkeys->keyid, &keys[i].fpr[40 - 16]))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key has unexpected key ID: %s\n",
|
||||||
|
key->subkeys->keyid);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (strcmp (key->subkeys->fpr, keys[i].fpr))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key has unexpected fingerprint: %s\n",
|
||||||
|
key->subkeys->fpr);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->expires)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly expires: %lu\n",
|
||||||
|
key->subkeys->expires);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Secondary key. */
|
||||||
|
if (key->subkeys->next->revoked)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Secondary key unexpectedly revoked\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->next->expired)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Secondary key unexpectedly expired\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->next->disabled)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Secondary key unexpectedly disabled\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->next->invalid)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Secondary key unexpectedly invalid\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->subkeys->next->can_encrypt)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Secondary key unexpectedly unusable for encryption\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->next->can_sign)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Secondary key unexpectedly usable for signing\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->next->can_certify)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Secondary key unexpectedly usable for certifications\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->next->secret)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Secondary key unexpectedly secret\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->next->pubkey_algo != GPGME_PK_ELG_E)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Secondary key has unexpected public key algo: %s\n",
|
||||||
|
gpgme_pubkey_algo_name (key->subkeys->next->pubkey_algo));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->next->length != 1024)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Secondary key has unexpected length: %i\n",
|
||||||
|
key->subkeys->next->length);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (strcmp (key->subkeys->next->keyid, keys[i].sec_keyid))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Secondary key has unexpected key ID: %s\n",
|
||||||
|
key->subkeys->next->keyid);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->next->fpr)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Secondary key has unexpectedly a fingerprint: %s\n",
|
||||||
|
key->subkeys->next->fpr);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->next->expires)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Secondary key unexpectedly expires: %lu\n",
|
||||||
|
key->subkeys->next->expires);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: The below test will crash if we want to check for a
|
||||||
|
name, comment or email that doesn't exist in the key's user
|
||||||
|
IDs. */
|
||||||
|
if (!((!keys[i].uid[0].name && !key->uids)
|
||||||
|
|| (keys[i].uid[0].name && !keys[i].uid[1].name
|
||||||
|
&& key->uids && !key->uids->next)
|
||||||
|
|| (keys[i].uid[0].name && keys[i].uid[1].name
|
||||||
|
&& !keys[i].uid[2].name
|
||||||
|
&& key->uids && key->uids->next && !key->uids->next->next)
|
||||||
|
|| (keys[i].uid[0].name && keys[i].uid[1].name
|
||||||
|
&& keys[i].uid[2].name
|
||||||
|
&& key->uids && key->uids->next && key->uids->next->next
|
||||||
|
&& !key->uids->next->next->next)))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key has unexpected number of user IDs\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids && key->uids->revoked)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "First user ID unexpectedly revoked\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids && key->uids->invalid)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "First user ID unexpectedly invalid\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids && key->uids->validity != GPGME_VALIDITY_UNKNOWN)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "First user ID has unexpectedly validity: %i\n",
|
||||||
|
key->uids->validity);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids && key->uids->signatures)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "First user ID unexpectedly signed\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (keys[i].uid[0].name
|
||||||
|
&& strcmp (keys[i].uid[0].name, key->uids->name))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Unexpected name in first user ID: %s\n",
|
||||||
|
key->uids->name);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (keys[i].uid[0].comment
|
||||||
|
&& strcmp (keys[i].uid[0].comment, key->uids->comment))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Unexpected comment in first user ID: %s\n",
|
||||||
|
key->uids->comment);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (keys[i].uid[0].email
|
||||||
|
&& strcmp (keys[i].uid[0].email, key->uids->email))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Unexpected email in first user ID: %s\n",
|
||||||
|
key->uids->email);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids && key->uids->next && key->uids->next->revoked)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Second user ID unexpectedly revoked\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids && key->uids->next && key->uids->next->invalid)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Second user ID unexpectedly invalid\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids && key->uids->next
|
||||||
|
&& key->uids->next->validity != GPGME_VALIDITY_UNKNOWN)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Second user ID has unexpectedly validity: %i\n",
|
||||||
|
key->uids->next->validity);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids && key->uids->next && key->uids->next->signatures)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Second user ID unexpectedly signed\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (keys[i].uid[1].name
|
||||||
|
&& strcmp (keys[i].uid[1].name, key->uids->next->name))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Unexpected name in second user ID: %s\n",
|
||||||
|
key->uids->next->name);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (keys[i].uid[1].comment
|
||||||
|
&& strcmp (keys[i].uid[1].comment, key->uids->next->comment))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Unexpected comment in second user ID: %s\n",
|
||||||
|
key->uids->next->comment);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (keys[i].uid[1].email
|
||||||
|
&& strcmp (keys[i].uid[1].email, key->uids->next->email))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Unexpected email in second user ID: %s\n",
|
||||||
|
key->uids->next->email);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids && key->uids->next && key->uids->next->next
|
||||||
|
&& key->uids->next->next->revoked)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Third user ID unexpectedly revoked\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids && key->uids->next && key->uids->next->next
|
||||||
|
&& key->uids->next->next->invalid)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Third user ID unexpectedly invalid\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids && key->uids->next && key->uids->next->next
|
||||||
|
&& key->uids->next->next->validity != GPGME_VALIDITY_UNKNOWN)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Third user ID has unexpectedly validity: %i\n",
|
||||||
|
key->uids->next->next->validity);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids && key->uids->next && key->uids->next->next
|
||||||
|
&& key->uids->next->next->signatures)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Third user ID unexpectedly signed\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (keys[i].uid[2].name
|
||||||
|
&& strcmp (keys[i].uid[2].name, key->uids->next->next->name))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Unexpected name in third user ID: %s\n",
|
||||||
|
key->uids->next->next->name);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (keys[i].uid[2].comment
|
||||||
|
&& strcmp (keys[i].uid[2].comment, key->uids->next->next->comment))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Unexpected comment in third user ID: %s\n",
|
||||||
|
key->uids->next->next->comment);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (keys[i].uid[2].email
|
||||||
|
&& strcmp (keys[i].uid[2].email, key->uids->next->next->email))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Unexpected email in third user ID: %s\n",
|
||||||
|
key->uids->next->next->email);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
gpgme_key_unref (key);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
while (loop);
|
if (err != GPGME_EOF)
|
||||||
|
fail_if_err (err);
|
||||||
|
err = gpgme_op_keylist_end (ctx);
|
||||||
|
fail_if_err (err);
|
||||||
|
|
||||||
|
result = gpgme_op_keylist_result (ctx);
|
||||||
|
if (result->truncated)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key listing unexpectedly truncated\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keys[i].fpr)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Less keys returned than expected\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
gpgme_release (ctx);
|
gpgme_release (ctx);
|
||||||
|
|
||||||
check_two_contexts ();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ main (int argc, char *argv[])
|
|||||||
gpgme_data_release (in);
|
gpgme_data_release (in);
|
||||||
gpgme_release (ctx);
|
gpgme_release (ctx);
|
||||||
|
|
||||||
gpgme_key_release (key[0]);
|
gpgme_key_unref (key[0]);
|
||||||
gpgme_key_release (key[1]);
|
gpgme_key_unref (key[1]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,184 +1,351 @@
|
|||||||
/* t-keylist.c - regression test
|
/* t-keylist.c - regression test
|
||||||
* Copyright (C) 2000 Werner Koch (dd9jn)
|
Copyright (C) 2000 Werner Koch (dd9jn)
|
||||||
* Copyright (C) 2001 g10 Code GmbH
|
Copyright (C) 2001, 2003 g10 Code GmbH
|
||||||
*
|
|
||||||
* This file is part of GPGME.
|
This file is part of GPGME.
|
||||||
*
|
|
||||||
* GPGME is free software; you can redistribute it and/or modify
|
GPGME is free software; you can redistribute it and/or modify it
|
||||||
* it under the terms of the GNU General Public License as published by
|
under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
(at your option) any later version.
|
||||||
*
|
|
||||||
* GPGME is distributed in the hope that it will be useful,
|
GPGME is distributed in the hope that it will be useful, but
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* GNU General Public License for more details.
|
General Public License for more details.
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
along with GPGME; if not, write to the Free Software Foundation,
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <gpgme.h>
|
#include <gpgme.h>
|
||||||
|
|
||||||
#define fail_if_err(a) do { if(a) { \
|
|
||||||
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
|
#define fail_if_err(err) \
|
||||||
__FILE__, __LINE__, gpgme_strerror(a)); \
|
do \
|
||||||
exit (1); } \
|
{ \
|
||||||
} while(0)
|
if (err) \
|
||||||
|
{ \
|
||||||
|
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
|
||||||
|
__FILE__, __LINE__, gpgme_strerror (err)); \
|
||||||
|
exit (1); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
static void
|
|
||||||
doit ( GpgmeCtx ctx, const char *pattern, int secret )
|
struct
|
||||||
{
|
{
|
||||||
GpgmeError err;
|
char *fpr;
|
||||||
GpgmeKey key;
|
int secret;
|
||||||
|
unsigned long expires;
|
||||||
err = gpgme_op_keylist_start (ctx, pattern, secret );
|
char *issuer_serial;
|
||||||
fail_if_err (err);
|
char *issuer_name;
|
||||||
|
char *chain_id;
|
||||||
while ( !(err = gpgme_op_keylist_next ( ctx, &key )) ) {
|
char *uid;
|
||||||
char *p;
|
|
||||||
const char *s;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
printf ("<!-- Begin key object (%p) -->\n", key );
|
|
||||||
p = gpgme_key_get_as_xml ( key );
|
|
||||||
if ( p ) {
|
|
||||||
fputs ( p, stdout );
|
|
||||||
free (p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fputs("<!-- Ooops: gpgme_key_get_as_xml failed -->\n", stdout );
|
|
||||||
|
|
||||||
|
|
||||||
for (i=0; ; i++ ) {
|
|
||||||
s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID, NULL, i );
|
|
||||||
if (!s)
|
|
||||||
break;
|
|
||||||
printf ("<!-- keyid.%d=%s -->\n", i, s );
|
|
||||||
s = gpgme_key_get_string_attr (key, GPGME_ATTR_ALGO, NULL, i );
|
|
||||||
printf ("<!-- algo.%d=%s -->\n", i, s );
|
|
||||||
s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEY_CAPS, NULL, i );
|
|
||||||
printf ("<!-- caps.%d=%s -->\n", i, s );
|
|
||||||
}
|
|
||||||
for (i=0; ; i++ ) {
|
|
||||||
s = gpgme_key_get_string_attr (key, GPGME_ATTR_NAME, NULL, i );
|
|
||||||
if (!s)
|
|
||||||
break;
|
|
||||||
printf ("<!-- name.%d=%s -->\n", i, s );
|
|
||||||
s = gpgme_key_get_string_attr (key, GPGME_ATTR_EMAIL, NULL, i );
|
|
||||||
printf ("<!-- email.%d=%s -->\n", i, s );
|
|
||||||
s = gpgme_key_get_string_attr (key, GPGME_ATTR_COMMENT, NULL, i );
|
|
||||||
printf ("<!-- comment.%d=%s -->\n", i, s );
|
|
||||||
}
|
|
||||||
|
|
||||||
fputs ("<!-- usable for:", stdout );
|
|
||||||
if ( gpgme_key_get_ulong_attr (key, GPGME_ATTR_CAN_ENCRYPT, NULL, 0 ))
|
|
||||||
fputs (" encryption", stdout);
|
|
||||||
if ( gpgme_key_get_ulong_attr (key, GPGME_ATTR_CAN_SIGN, NULL, 0 ))
|
|
||||||
fputs (" signing", stdout);
|
|
||||||
if ( gpgme_key_get_ulong_attr (key, GPGME_ATTR_CAN_CERTIFY, NULL, 0 ))
|
|
||||||
fputs (" certification", stdout);
|
|
||||||
fputs (" -->\n", stdout );
|
|
||||||
|
|
||||||
printf ("<!-- End key object (%p) -->\n", key );
|
|
||||||
gpgme_key_release (key);
|
|
||||||
}
|
|
||||||
if ( err != GPGME_EOF )
|
|
||||||
fail_if_err (err);
|
|
||||||
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
p = gpgme_get_op_info (ctx, 0);
|
|
||||||
if (p)
|
|
||||||
{
|
|
||||||
fputs ("<!-- begin operation info -->\n", stdout);
|
|
||||||
fputs (p, stdout);
|
|
||||||
fputs ("<!-- end operation info -->\n", stdout);
|
|
||||||
free (p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check that there are no problems when we are using two context for
|
|
||||||
* listing keys.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
check_two_contexts (void)
|
|
||||||
{
|
|
||||||
GpgmeError err;
|
|
||||||
GpgmeCtx ctx1, ctx2;
|
|
||||||
GpgmeKey key;
|
|
||||||
|
|
||||||
err = gpgme_new(&ctx1);
|
|
||||||
fail_if_err (err);
|
|
||||||
gpgme_set_protocol (ctx1, GPGME_PROTOCOL_CMS);
|
|
||||||
|
|
||||||
err = gpgme_op_keylist_start(ctx1, "", 1);
|
|
||||||
fail_if_err (err);
|
|
||||||
err = gpgme_new(&ctx2); fail_if_err (err);
|
|
||||||
gpgme_set_protocol (ctx2, GPGME_PROTOCOL_CMS);
|
|
||||||
err = gpgme_op_keylist_start(ctx2, "", 1);
|
|
||||||
fail_if_err (err);
|
|
||||||
|
|
||||||
while ( (err=gpgme_op_keylist_next(ctx2, &key)) != GPGME_EOF) {
|
|
||||||
gpgme_key_release (key);
|
|
||||||
}
|
|
||||||
if (err != GPGME_EOF)
|
|
||||||
fail_if_err (err);
|
|
||||||
while ( (err=gpgme_op_keylist_next(ctx1, &key)) != GPGME_EOF) {
|
|
||||||
gpgme_key_release (key);
|
|
||||||
}
|
|
||||||
if (err != GPGME_EOF)
|
|
||||||
fail_if_err (err);
|
|
||||||
}
|
}
|
||||||
|
keys[] =
|
||||||
|
{
|
||||||
|
{ "3CF405464F66ED4A7DF45BBDD1E4282E33BDB76E", 1, 1038908198, "00",
|
||||||
|
"CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=D\xc3\xbcsseldorf,C=DE",
|
||||||
|
NULL,
|
||||||
|
"CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=D\xc3\xbcsseldorf,C=DE" },
|
||||||
|
{ "DFA56FB5FC41E3A8921F77AD1622EEFD9152A5AD", 0, 1009821790, "01",
|
||||||
|
"1.2.840.113549.1.9.1=#63657274696679407063612E64666E2E6465,"
|
||||||
|
"CN=DFN Top Level Certification Authority,OU=DFN-PCA,"
|
||||||
|
"O=Deutsches Forschungsnetz,C=DE", NULL,
|
||||||
|
"1.2.840.113549.1.9.1=#63657274696679407063612E64666E2E6465,"
|
||||||
|
"CN=DFN Top Level Certification Authority,OU=DFN-PCA,"
|
||||||
|
"O=Deutsches Forschungsnetz,C=DE" },
|
||||||
|
{ "2C8F3C356AB761CB3674835B792CDA52937F9285", 0, 1009735200, "15",
|
||||||
|
"1.2.840.113549.1.9.1=#63657274696679407063612E64666E2E6465,"
|
||||||
|
"CN=DFN Top Level Certification Authority,OU=DFN-PCA,"
|
||||||
|
"O=Deutsches Forschungsnetz,C=DE",
|
||||||
|
"DFA56FB5FC41E3A8921F77AD1622EEFD9152A5AD",
|
||||||
|
"1.2.840.113549.1.9.1=#63657274696679407063612E64666E2E6465,"
|
||||||
|
"CN=DFN Server Certification Authority,OU=DFN-PCA,"
|
||||||
|
"O=Deutsches Forschungsnetz,C=DE" },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv )
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
GpgmeCtx ctx;
|
GpgmeError err;
|
||||||
GpgmeError err;
|
GpgmeCtx ctx;
|
||||||
int loop = 0;
|
GpgmeKey key;
|
||||||
int secret = 0;
|
GpgmeKeyListResult result;
|
||||||
const char *pattern;
|
int i = 0;
|
||||||
|
|
||||||
if( argc ) {
|
err = gpgme_engine_check_version (GPGME_PROTOCOL_CMS);
|
||||||
argc--; argv++;
|
fail_if_err (err);
|
||||||
}
|
|
||||||
|
|
||||||
if (argc && !strcmp( *argv, "--loop" ) ) {
|
err = gpgme_new (&ctx);
|
||||||
loop = 1;
|
fail_if_err (err);
|
||||||
argc--; argv++;
|
gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS);
|
||||||
}
|
|
||||||
if (argc && !strcmp( *argv, "--secret" ) ) {
|
|
||||||
secret = 1;
|
|
||||||
argc--; argv++;
|
|
||||||
}
|
|
||||||
pattern = argc? *argv : NULL;
|
|
||||||
|
|
||||||
err = gpgme_engine_check_version (GPGME_PROTOCOL_CMS);
|
err = gpgme_op_keylist_start (ctx, NULL, 0);
|
||||||
|
fail_if_err (err);
|
||||||
|
|
||||||
|
while (!(err = gpgme_op_keylist_next (ctx, &key)))
|
||||||
|
{
|
||||||
|
if (!keys[i].fpr)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "More keys returned than expected\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Global key flags. */
|
||||||
|
if (key->revoked)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly revoked\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->expired)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly expired\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->disabled)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly disabled\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->invalid)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly invalid\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->can_encrypt != keys[i].secret)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly%s usable for encryption\n",
|
||||||
|
key->can_encrypt ? "" : " not");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->can_sign != keys[i].secret)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly%s usable for signing\n",
|
||||||
|
key->can_sign ? "" : " not");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->can_certify)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly unusable for certifications\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->secret != keys[i].secret)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly%s secret\n",
|
||||||
|
key->secret ? "" : " not");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->protocol != GPGME_PROTOCOL_CMS)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key has unexpected protocol: %s\n",
|
||||||
|
gpgme_get_protocol_name (key->protocol));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->issuer_serial)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly misses issuer serial\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (strcmp (key->issuer_serial, keys[i].issuer_serial))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key has unexpected issuer serial: %s\n",
|
||||||
|
key->issuer_serial);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->issuer_name)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly misses issuer name\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (strcmp (key->issuer_name, keys[i].issuer_name))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key has unexpected issuer name: %s\n",
|
||||||
|
key->issuer_name);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->chain_id && !keys[i].chain_id)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly carries chain ID: %s\n",
|
||||||
|
key->chain_id);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->chain_id && keys[i].chain_id)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly carries no chain ID\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->chain_id && strcmp (key->chain_id, keys[i].chain_id))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key carries unexpected chain ID: %s\n",
|
||||||
|
key->chain_id);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->owner_trust != GPGME_VALIDITY_UNKNOWN)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key has unexpected owner trust: %i\n",
|
||||||
|
key->owner_trust);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->subkeys || key->subkeys->next)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key has unexpected number of subkeys\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Primary key. */
|
||||||
|
if (key->subkeys->revoked)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly revoked\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->expired)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly expired\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->disabled)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly disabled\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->invalid)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly invalid\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->can_encrypt != keys[i].secret)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly%s usable for encryption\n",
|
||||||
|
key->subkeys->can_encrypt ? "" : " not");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->can_sign != keys[i].secret)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key unexpectedly%s usable for signing\n",
|
||||||
|
key->subkeys->can_sign ? "" : " not");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->subkeys->can_certify)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly unusable for certifications\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->secret)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly secret\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->pubkey_algo != GPGME_PK_RSA)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key has unexpected public key algo: %s\n",
|
||||||
|
gpgme_pubkey_algo_name (key->subkeys->pubkey_algo));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->length != 1024)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key has unexpected length: %i\n",
|
||||||
|
key->subkeys->length);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (strcmp (key->subkeys->keyid, &keys[i].fpr[40 - 16]))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key has unexpected key ID: %s\n",
|
||||||
|
key->subkeys->keyid);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (strcmp (key->subkeys->fpr, keys[i].fpr))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key has unexpected fingerprint: %s\n",
|
||||||
|
key->subkeys->fpr);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->subkeys->expires != keys[i].expires)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Primary key unexpectedly expires: %lu\n",
|
||||||
|
key->subkeys->expires);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!key->uids || key->uids->next)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Key has unexpected number of user IDs\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids->revoked)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "User ID unexpectedly revoked\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids->invalid)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "User ID unexpectedly invalid\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids->validity != GPGME_VALIDITY_UNKNOWN)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "User ID unexpectedly validity: %i\n",
|
||||||
|
key->uids->validity);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (key->uids->signatures)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "User ID unexpectedly signed\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->uids->name || key->uids->name[0])
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Unexpected name in user ID: %s\n",
|
||||||
|
key->uids->name);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->uids->comment || key->uids->comment[0])
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Unexpected comment in user ID: %s\n",
|
||||||
|
key->uids->comment);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->uids->email || key->uids->email[0])
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Unexpected email in user ID: %s\n",
|
||||||
|
key->uids->email);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!key->uids->uid || strcmp (key->uids->uid, keys[i].uid))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Unexpected uid in user ID: %s\n",
|
||||||
|
key->uids->uid);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
gpgme_key_unref (key);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (err != GPGME_EOF)
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
err = gpgme_op_keylist_end (ctx);
|
||||||
|
fail_if_err (err);
|
||||||
|
|
||||||
err = gpgme_new (&ctx);
|
result = gpgme_op_keylist_result (ctx);
|
||||||
fail_if_err (err);
|
if (result->truncated)
|
||||||
gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS);
|
{
|
||||||
|
fprintf (stderr, "Key listing unexpectedly truncated\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
gpgme_set_keylist_mode (ctx, 1); /* no validity calculation */
|
if (keys[i].fpr)
|
||||||
do {
|
{
|
||||||
fprintf (stderr, "** pattern=`%s'\n", pattern );
|
fprintf (stderr, "Less keys returned than expected\n");
|
||||||
doit ( ctx, pattern, secret );
|
exit (1);
|
||||||
} while ( loop );
|
}
|
||||||
gpgme_release (ctx);
|
|
||||||
|
|
||||||
check_two_contexts ();
|
gpgme_release (ctx);
|
||||||
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user