doc/
2003-04-27 Marcus Brinkmann <marcus@g10code.de> * gpgme.texi (Creating a Signature): Add info about GpgmeNewSignature, GpgmeSignResult and gpgme_op_sign_result. (Crypto Operations): Add GpgmeInvalidUserID. (Algorithms): New chapter. gpgme/ 2003-04-27 Marcus Brinkmann <marcus@g10code.de> * gpgme.h (GpgmePubKeyAlgo, GpgmeHashAlgo, GpgmeInvalidUserID, GpgmeNewSignature, GpgmeSignResult): New data types. (gpgme_op_sign_result, gpgme_pubkey_algo_name, gpgme_hash_algo_name): New prototypes. * gpgme.c (gpgme_pubkey_algo_name): New function. (gpgme_hash_algo_name): Likewise. * ops.h (_gpgme_parse_inv_userid, _gpgme_op_sign_init_result): New prototype. (_gpgme_op_sign_status_handler): Fix prototype. * op-support.c: Include <errno.h> and <string.h>. (_gpgme_parse_inv_userid): New function. * sign.c: Include <errno.h> and "gpgme.h", but not <stdio.h>, <assert.h> and "util.h". (SKIP_TOKEN_OR_RETURN): Remove macro. (struct sign_result): Change to op_data_t type and rework it. (release_sign_result): Rename to ... (release_op_data): ... this and rewrite it. (append_xml_info): Remove function. (gpgme_op_sign_result): New function. (parse_sig_created): New function. (_gpgme_sign_status_handler): Change first argument to void *. Rewrite the function to use the new result structure and functions. (_gpgme_op_sign_init_result): New function. (_gpgme_op_sign_start): Rename to ... (sign_start): ... this. Call _gpgme_op_sign_init_result. (gpgme_op_sign_start): Use sign_start instead _gpgme_op_sign_start. (gpgme_op_sign): Likewise.
This commit is contained in:
parent
e254482818
commit
2971894b27
12
NEWS
12
NEWS
@ -78,6 +78,10 @@ Noteworthy changes in version 0.4.1 (unreleased)
|
|||||||
GpgmeImportResult and GpgmeImportStatus objects. Thus, the
|
GpgmeImportResult and GpgmeImportStatus objects. Thus, the
|
||||||
gpgme_op_import_ext variant is deprecated.
|
gpgme_op_import_ext variant is deprecated.
|
||||||
|
|
||||||
|
* The new gpgme_op_sign_result function provides detailed information
|
||||||
|
about the result of a signing operation in GpgmeSignResult,
|
||||||
|
GpgmeInvalidUserID and GpgmeNewSignature objects.
|
||||||
|
|
||||||
* 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.
|
||||||
@ -108,6 +112,14 @@ gpgme_op_import_ext DEPRECATED: Use gpgme_op_import_result.
|
|||||||
gpgme_op_import_result NEW
|
gpgme_op_import_result NEW
|
||||||
GpgmeImportStatus NEW
|
GpgmeImportStatus NEW
|
||||||
GpgmeImportResult NEW
|
GpgmeImportResult NEW
|
||||||
|
GpgmePubKeyAlgo NEW
|
||||||
|
GpgmeHashAlgo NEW
|
||||||
|
GpgmeInvalidUserID NEW
|
||||||
|
GpgmeNewSignature NEW
|
||||||
|
GpgmeSignResult NEW
|
||||||
|
gpgme_op_sign_result NEW
|
||||||
|
gpgme_pubkey_algo_name NEW
|
||||||
|
gpgme_hash_algo_name NEW
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Noteworthy changes in version 0.4.0 (2002-12-23)
|
Noteworthy changes in version 0.4.0 (2002-12-23)
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
2003-04-27 Marcus Brinkmann <marcus@g10code.de>
|
2003-04-27 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
* gpgme.texi (Creating a Signature): Add info about
|
||||||
|
GpgmeNewSignature, GpgmeSignResult and gpgme_op_sign_result.
|
||||||
|
(Crypto Operations): Add GpgmeInvalidUserID.
|
||||||
|
(Algorithms): New chapter.
|
||||||
|
|
||||||
* gpgme.texi (Deleting Keys): Document
|
* gpgme.texi (Deleting Keys): Document
|
||||||
GPGME_Ambiguous_Specification.
|
GPGME_Ambiguous_Specification.
|
||||||
(Error Values): Remove GPGME_Invalid_Type and GPGME_Invalid_Mode.
|
(Error Values): Remove GPGME_Invalid_Type and GPGME_Invalid_Mode.
|
||||||
|
201
doc/gpgme.texi
201
doc/gpgme.texi
@ -73,6 +73,7 @@ This is Edition @value{EDITION}, last updated @value{UPDATED}, of
|
|||||||
* Introduction:: How to use this manual.
|
* Introduction:: How to use this manual.
|
||||||
* Preparation:: What you should do before using the library.
|
* Preparation:: What you should do before using the library.
|
||||||
* Protocols and Engines:: Supported crypto protocols.
|
* Protocols and Engines:: Supported crypto protocols.
|
||||||
|
* Algorithms:: Supported algorithms.
|
||||||
* Error Handling:: Error numbers and their meanings.
|
* Error Handling:: Error numbers and their meanings.
|
||||||
* Exchanging Data:: Passing data to and from @acronym{GPGME}.
|
* Exchanging Data:: Passing data to and from @acronym{GPGME}.
|
||||||
* Contexts:: Handling @acronym{GPGME} contexts.
|
* Contexts:: Handling @acronym{GPGME} contexts.
|
||||||
@ -114,6 +115,11 @@ Protocols and Engines
|
|||||||
* OpenPGP:: Support for the OpenPGP protocol.
|
* OpenPGP:: Support for the OpenPGP protocol.
|
||||||
* Cryptographic Message Syntax:: Support for the CMS.
|
* Cryptographic Message Syntax:: Support for the CMS.
|
||||||
|
|
||||||
|
Algorithms
|
||||||
|
|
||||||
|
* Public Key Algorithms:: A list of all public key algorithms.
|
||||||
|
* Hash Algorithms:: A list of all hash algorithms.
|
||||||
|
|
||||||
Error Handling
|
Error Handling
|
||||||
|
|
||||||
* Error Values:: A list of all error values used.
|
* Error Values:: A list of all error values used.
|
||||||
@ -728,6 +734,110 @@ GnuPG.
|
|||||||
The @acronym{CMS} protocol is specified by @code{GPGME_PROTOCOL_CMS}.
|
The @acronym{CMS} protocol is specified by @code{GPGME_PROTOCOL_CMS}.
|
||||||
|
|
||||||
|
|
||||||
|
@node Algorithms
|
||||||
|
@chapter Algorithms
|
||||||
|
@cindex algorithms
|
||||||
|
|
||||||
|
The crypto backends support a variety of algorithms used in public key
|
||||||
|
cryptography. The following sections list the identifiers used to
|
||||||
|
denote such an algorithm.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Public Key Algorithms:: A list of all public key algorithms.
|
||||||
|
* Hash Algorithms:: A list of all hash algorithms.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Public Key Algorithms
|
||||||
|
@section Public Key Algorithms
|
||||||
|
@cindex algorithms, public key
|
||||||
|
@cindex public key algorithms
|
||||||
|
|
||||||
|
Public key algorithms are used for encryption, decryption, signing and
|
||||||
|
verification of signatures.
|
||||||
|
|
||||||
|
@deftp {Data type} {enum GpgmePubKeyAlgo}
|
||||||
|
@tindex GpgmePubKeyAlgo
|
||||||
|
The @code{GpgmePubKeyAlgo} type specifies the set of all public key
|
||||||
|
algorithms that are supported by @acronym{GPGME}. Possible values
|
||||||
|
are:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item GPGME_PK_RSA
|
||||||
|
This value indicates the RSA (Rivest, Shamir, Adleman) algorithm.
|
||||||
|
|
||||||
|
@item GPGME_PK_RSA_E
|
||||||
|
Deprecated. This value indicates the RSA (Rivest, Shamir, Adleman)
|
||||||
|
algorithm for encryption and decryption only.
|
||||||
|
|
||||||
|
@item GPGME_PK_RSA_S
|
||||||
|
Deprecated. This value indicates the RSA (Rivest, Shamir, Adleman)
|
||||||
|
algorithm for signing and verification only.
|
||||||
|
|
||||||
|
@item GPGME_PK_DSA
|
||||||
|
This value indicates DSA, the Digital Signature Algorithm.
|
||||||
|
|
||||||
|
@item GPGME_PK_ELG
|
||||||
|
This value indicates ElGamal.
|
||||||
|
|
||||||
|
@item GPGME_PK_ELG_E
|
||||||
|
This value also indicates ElGamal and is used specifically in GnuPG.
|
||||||
|
@end table
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftypefun {const char *} gpgme_pubkey_algo_name (@w{GpgmePubKeyAlgo @var{algo}})
|
||||||
|
The function @code{gpgme_pubkey_algo_name} returns a pointer to a
|
||||||
|
statically allocated string containing a description of the public key
|
||||||
|
algorithm @var{algo}. This string can be used to output the name of
|
||||||
|
the public key algorithm to the user.
|
||||||
|
|
||||||
|
If @var{algo} is not a valid public key algorithm, @code{NULL} is
|
||||||
|
returned.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
@node Hash Algorithms
|
||||||
|
@section Hash Algorithms
|
||||||
|
@cindex algorithms, hash
|
||||||
|
@cindex algorithms, message digest
|
||||||
|
@cindex hash algorithms
|
||||||
|
@cindex message digest algorithms
|
||||||
|
|
||||||
|
Hash (message digest) algorithms are used to compress a long message
|
||||||
|
to make it suitable for public key cryptography.
|
||||||
|
|
||||||
|
@deftp {Data type} {enum GpgmeHashAlgo}
|
||||||
|
@tindex GpgmeHashAlgo
|
||||||
|
The @code{GpgmeHashAlgo} type specifies the set of all hash algorithms
|
||||||
|
that are supported by @acronym{GPGME}. Possible values are:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item GPGME_MD_MD5
|
||||||
|
@item GPGME_MD_SHA1
|
||||||
|
@item GPGME_MD_RMD160
|
||||||
|
@item GPGME_MD_MD2
|
||||||
|
@item GPGME_MD_TIGER
|
||||||
|
@item GPGME_MD_HAVAL
|
||||||
|
@item GPGME_MD_SHA256
|
||||||
|
@item GPGME_MD_SHA384
|
||||||
|
@item GPGME_MD_SHA512
|
||||||
|
@item GPGME_MD_MD4
|
||||||
|
@item GPGME_MD_CRC32
|
||||||
|
@item GPGME_MD_CRC32_RFC1510
|
||||||
|
@item GPGME_MD_CRC24_RFC2440
|
||||||
|
@end table
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftypefun {const char *} gpgme_hash_algo_name (@w{GpgmeHashAlgo @var{algo}})
|
||||||
|
The function @code{gpgme_hash_algo_name} returns a pointer to a
|
||||||
|
statically allocated string containing a description of the hash
|
||||||
|
algorithm @var{algo}. This string can be used to output the name of
|
||||||
|
the hash algorithm to the user.
|
||||||
|
|
||||||
|
If @var{algo} is not a valid hash algorithm, @code{NULL} is returned.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
@node Error Handling
|
@node Error Handling
|
||||||
@chapter Error Handling
|
@chapter Error Handling
|
||||||
@cindex error handling
|
@cindex error handling
|
||||||
@ -2308,6 +2418,9 @@ The function @code{gpgme_op_import} adds the keys in the data buffer
|
|||||||
The format of @var{keydata} can be @var{ASCII} armored, for example,
|
The format of @var{keydata} can be @var{ASCII} armored, for example,
|
||||||
but the details are specific to the crypto engine.
|
but the details are specific to the crypto engine.
|
||||||
|
|
||||||
|
After the operation completed successfully, the result can be
|
||||||
|
retrieved with @code{gpgme_op_import_result}.
|
||||||
|
|
||||||
The function returns @code{GPGME_No_Error} if the import was completed
|
The function returns @code{GPGME_No_Error} if the import was completed
|
||||||
successfully, @code{GPGME_Invalid_Value} if @var{keydata} if @var{ctx}
|
successfully, @code{GPGME_Invalid_Value} if @var{keydata} if @var{ctx}
|
||||||
or @var{keydata} is not a valid pointer, and @code{GPGME_No_Data} if
|
or @var{keydata} is not a valid pointer, and @code{GPGME_No_Data} if
|
||||||
@ -2333,7 +2446,8 @@ import. The structure contains the following members:
|
|||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item GpgmeImportStatus next
|
@item GpgmeImportStatus next
|
||||||
This is a pointer to the next status object in the list.
|
This is a pointer to the next status structure in the linked list, or
|
||||||
|
@code{NULL} if this is the last element.
|
||||||
|
|
||||||
@item char *fpr
|
@item char *fpr
|
||||||
This is the fingerprint of the key that was considered.
|
This is the fingerprint of the key that was considered.
|
||||||
@ -2592,10 +2706,34 @@ The function @code{gpgme_trust_item_release} destroys a
|
|||||||
@code{GpgmeTrustItem} object and releases all associated resources.
|
@code{GpgmeTrustItem} object and releases all associated resources.
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
@node Crypto Operations
|
@node Crypto Operations
|
||||||
@section Crypto Operations
|
@section Crypto Operations
|
||||||
@cindex cryptographic operation
|
@cindex cryptographic operation
|
||||||
|
|
||||||
|
Sometimes, the result of a crypto operation returns a list of invalid
|
||||||
|
user IDs encountered in processing the request. The following
|
||||||
|
structure is used to hold information about such an user ID.
|
||||||
|
|
||||||
|
@deftp {Data type} {GpgmeInvalidUserID}
|
||||||
|
This is a pointer to a structure used to store a part of the result of
|
||||||
|
a crypto operation which takes user IDs as one input parameter. The
|
||||||
|
structure contains the following members:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item GpgmeInvalidUserID next
|
||||||
|
This is a pointer to the next invalid user ID structure in the linked
|
||||||
|
list, or @code{NULL} if this is the last element.
|
||||||
|
|
||||||
|
@item char *id
|
||||||
|
The invalid user ID encountered.
|
||||||
|
|
||||||
|
@item GpgmeError reason
|
||||||
|
An error code describing the reason why the user ID was found invalid.
|
||||||
|
@end table
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Decrypt:: Decrypting a ciphertext.
|
* Decrypt:: Decrypting a ciphertext.
|
||||||
* Verify:: Verifying a signature.
|
* Verify:: Verifying a signature.
|
||||||
@ -2994,8 +3132,8 @@ the data object @var{plain} and returns it in the data object
|
|||||||
@acronym{ASCII} armor and text mode attributes set for the context
|
@acronym{ASCII} armor and text mode attributes set for the context
|
||||||
@var{ctx} and the requested signature mode @var{mode}.
|
@var{ctx} and the requested signature mode @var{mode}.
|
||||||
|
|
||||||
More information about the signatures is available with
|
After the operation completed successfully, the result can be
|
||||||
@code{gpgme_get_op_info}. @xref{Detailed Results}.
|
retrieved with @code{gpgme_op_sign_result}.
|
||||||
|
|
||||||
If an S/MIME signed message is created using the CMS crypto engine,
|
If an S/MIME signed message is created using the CMS crypto engine,
|
||||||
the number of certificates to include in the message can be specified
|
the number of certificates to include in the message can be specified
|
||||||
@ -3020,6 +3158,63 @@ started successfully, and @code{GPGME_Invalid_Value} if @var{ctx},
|
|||||||
@var{plain} or @var{sig} is not a valid pointer.
|
@var{plain} or @var{sig} is not a valid pointer.
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftp {Data type} {GpgmeNewSignature}
|
||||||
|
This is a pointer to a structure used to store a part of the result of
|
||||||
|
a @code{gpgme_op_sign} operation. The structure contains the
|
||||||
|
following members:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item GpgmeNewSignature next
|
||||||
|
This is a pointer to the next new signature structure in the linked
|
||||||
|
list, or @code{NULL} if this is the last element.
|
||||||
|
|
||||||
|
@item GpgmeSigMode type
|
||||||
|
The type of this signature.
|
||||||
|
|
||||||
|
@item GpgmePubKeyAlgo
|
||||||
|
The public key algorithm used to create this signature.
|
||||||
|
|
||||||
|
@item GpgmeHashAlgo
|
||||||
|
The hash algorithm used to create this signature.
|
||||||
|
|
||||||
|
@item unsigned long class
|
||||||
|
The signature class of this signature.
|
||||||
|
|
||||||
|
@item long int created
|
||||||
|
The creation timestamp of this signature.
|
||||||
|
|
||||||
|
@item char *fpr
|
||||||
|
The fingerprint of the key which was used to create this signature.
|
||||||
|
@end table
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftp {Data type} {GpgmeSignResult}
|
||||||
|
This is a pointer to a structure used to store the result of a
|
||||||
|
@code{gpgme_op_sign} operation. After successfully generating a
|
||||||
|
signature, you can retrieve the pointer to the result with
|
||||||
|
@code{gpgme_op_sign_result}. The structure contains the following
|
||||||
|
members:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item GpgmeInvalidUserID invalid_signers
|
||||||
|
A linked list with information about all invalid user IDs for which a
|
||||||
|
signature could not be created.
|
||||||
|
|
||||||
|
@item GpgmeNewSignature signatures
|
||||||
|
A linked list with information about all signatures created.
|
||||||
|
@end table
|
||||||
|
@end deftp
|
||||||
|
|
||||||
|
@deftypefun GpgmeSignResult gpgme_op_sign_result (@w{GpgmeCtx @var{ctx}})
|
||||||
|
The function @code{gpgme_op_sign_result} returns a
|
||||||
|
@code{GpgmeSignResult} pointer to a structure holding the result of a
|
||||||
|
@code{gpgme_op_sign} operation. The pointer is only valid if the last
|
||||||
|
operation on the context was a @code{gpgme_op_sign} or
|
||||||
|
@code{gpgme_op_sign_start} operation, and if this operation finished
|
||||||
|
successfully. The returned pointer is only valid until the next
|
||||||
|
operation is started on the context.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
@node Encrypt
|
@node Encrypt
|
||||||
@subsection Encrypt
|
@subsection Encrypt
|
||||||
|
@ -1,5 +1,36 @@
|
|||||||
2003-04-27 Marcus Brinkmann <marcus@g10code.de>
|
2003-04-27 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
* gpgme.h (GpgmePubKeyAlgo, GpgmeHashAlgo, GpgmeInvalidUserID,
|
||||||
|
GpgmeNewSignature, GpgmeSignResult): New data types.
|
||||||
|
(gpgme_op_sign_result, gpgme_pubkey_algo_name,
|
||||||
|
gpgme_hash_algo_name): New prototypes.
|
||||||
|
* gpgme.c (gpgme_pubkey_algo_name): New function.
|
||||||
|
(gpgme_hash_algo_name): Likewise.
|
||||||
|
* ops.h (_gpgme_parse_inv_userid, _gpgme_op_sign_init_result): New
|
||||||
|
prototype.
|
||||||
|
(_gpgme_op_sign_status_handler): Fix prototype.
|
||||||
|
* op-support.c: Include <errno.h> and <string.h>.
|
||||||
|
(_gpgme_parse_inv_userid): New function.
|
||||||
|
* sign.c: Include <errno.h> and "gpgme.h", but not <stdio.h>,
|
||||||
|
<assert.h> and "util.h".
|
||||||
|
(SKIP_TOKEN_OR_RETURN): Remove macro.
|
||||||
|
(struct sign_result): Change to op_data_t type and rework it.
|
||||||
|
(release_sign_result): Rename to ...
|
||||||
|
(release_op_data): ... this and rewrite it.
|
||||||
|
(append_xml_info): Remove function.
|
||||||
|
(gpgme_op_sign_result): New function.
|
||||||
|
(parse_sig_created): New function.
|
||||||
|
(_gpgme_sign_status_handler): Change first argument to void *.
|
||||||
|
Rewrite the function to use the new result structure and functions.
|
||||||
|
(_gpgme_op_sign_init_result): New function.
|
||||||
|
(_gpgme_op_sign_start): Rename to ...
|
||||||
|
(sign_start): ... this. Call _gpgme_op_sign_init_result.
|
||||||
|
(gpgme_op_sign_start): Use sign_start instead _gpgme_op_sign_start.
|
||||||
|
(gpgme_op_sign): Likewise.
|
||||||
|
|
||||||
|
* encrypt-sign.c (_gpgme_op_encrypt_sign_start): Call
|
||||||
|
_gpgme_op_sign_init_result.
|
||||||
|
|
||||||
* delete.c: Include <errno.h> and "gpgme.h", but not "util.h" or
|
* delete.c: Include <errno.h> and "gpgme.h", but not "util.h" or
|
||||||
"key.h".
|
"key.h".
|
||||||
(enum delete_problem): Move into function delete_status_handler.
|
(enum delete_problem): Move into function delete_status_handler.
|
||||||
|
@ -51,6 +51,10 @@ _gpgme_op_encrypt_sign_start (GpgmeCtx ctx, int synchronous,
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
err = _gpgme_op_sign_init_result (ctx);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
if (!plain)
|
if (!plain)
|
||||||
return GPGME_No_Data;
|
return GPGME_No_Data;
|
||||||
if (!cipher)
|
if (!cipher)
|
||||||
|
@ -521,3 +521,82 @@ gpgme_get_io_cbs (GpgmeCtx ctx, struct GpgmeIOCbs *io_cbs)
|
|||||||
if (ctx && io_cbs)
|
if (ctx && io_cbs)
|
||||||
*io_cbs = ctx->io_cbs;
|
*io_cbs = ctx->io_cbs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
gpgme_pubkey_algo_name (GpgmePubKeyAlgo algo)
|
||||||
|
{
|
||||||
|
switch (algo)
|
||||||
|
{
|
||||||
|
case GPGME_PK_RSA:
|
||||||
|
return "RSA";
|
||||||
|
|
||||||
|
case GPGME_PK_RSA_E:
|
||||||
|
return "RSA-E";
|
||||||
|
|
||||||
|
case GPGME_PK_RSA_S:
|
||||||
|
return "RSA-S";
|
||||||
|
|
||||||
|
case GPGME_PK_ELG_E:
|
||||||
|
return "ELG-E";
|
||||||
|
|
||||||
|
case GPGME_PK_DSA:
|
||||||
|
return "DSA";
|
||||||
|
|
||||||
|
case GPGME_PK_ELG:
|
||||||
|
return "ELG";
|
||||||
|
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
gpgme_hash_algo_name (GpgmeHashAlgo algo)
|
||||||
|
{
|
||||||
|
switch (algo)
|
||||||
|
{
|
||||||
|
case GPGME_MD_MD5:
|
||||||
|
return "MD5";
|
||||||
|
|
||||||
|
case GPGME_MD_SHA1:
|
||||||
|
return "SHA1";
|
||||||
|
|
||||||
|
case GPGME_MD_RMD160:
|
||||||
|
return "RMD160";
|
||||||
|
|
||||||
|
case GPGME_MD_MD2:
|
||||||
|
return "MD2";
|
||||||
|
|
||||||
|
case GPGME_MD_TIGER:
|
||||||
|
return "TIGER";
|
||||||
|
|
||||||
|
case GPGME_MD_HAVAL:
|
||||||
|
return "HAVAL";
|
||||||
|
|
||||||
|
case GPGME_MD_SHA256:
|
||||||
|
return "SHA256";
|
||||||
|
|
||||||
|
case GPGME_MD_SHA384:
|
||||||
|
return "SHA384";
|
||||||
|
|
||||||
|
case GPGME_MD_SHA512:
|
||||||
|
return "SHA512";
|
||||||
|
|
||||||
|
case GPGME_MD_MD4:
|
||||||
|
return "MD4";
|
||||||
|
|
||||||
|
case GPGME_MD_CRC32:
|
||||||
|
return "CRC32";
|
||||||
|
|
||||||
|
case GPGME_MD_CRC32_RFC1510:
|
||||||
|
return "CRC32-RFC1510";
|
||||||
|
|
||||||
|
case GPGME_MD_CRC24_RFC2440:
|
||||||
|
return "CRC24-RFC2440";
|
||||||
|
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -138,6 +138,41 @@ typedef enum
|
|||||||
}
|
}
|
||||||
GpgmeDataEncoding;
|
GpgmeDataEncoding;
|
||||||
|
|
||||||
|
|
||||||
|
/* Public key algorithms from libgcrypt. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GPGME_PK_RSA = 1,
|
||||||
|
GPGME_PK_RSA_E = 2,
|
||||||
|
GPGME_PK_RSA_S = 3,
|
||||||
|
GPGME_PK_ELG_E = 16,
|
||||||
|
GPGME_PK_DSA = 17,
|
||||||
|
GPGME_PK_ELG = 20
|
||||||
|
}
|
||||||
|
GpgmePubKeyAlgo;
|
||||||
|
|
||||||
|
|
||||||
|
/* Hash algorithms from libgcrypt. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GPGME_MD_NONE = 0,
|
||||||
|
GPGME_MD_MD5 = 1,
|
||||||
|
GPGME_MD_SHA1 = 2,
|
||||||
|
GPGME_MD_RMD160 = 3,
|
||||||
|
GPGME_MD_MD2 = 5,
|
||||||
|
GPGME_MD_TIGER = 6, /* TIGER/192. */
|
||||||
|
GPGME_MD_HAVAL = 7, /* HAVAL, 5 pass, 160 bit. */
|
||||||
|
GPGME_MD_SHA256 = 8,
|
||||||
|
GPGME_MD_SHA384 = 9,
|
||||||
|
GPGME_MD_SHA512 = 10,
|
||||||
|
GPGME_MD_MD4 = 301,
|
||||||
|
GPGME_MD_CRC32 = 302,
|
||||||
|
GPGME_MD_CRC32_RFC1510 = 303,
|
||||||
|
GPGME_MD_CRC24_RFC2440 = 304
|
||||||
|
}
|
||||||
|
GpgmeHashAlgo;
|
||||||
|
|
||||||
|
|
||||||
/* The possible signature stati. */
|
/* The possible signature stati. */
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@ -426,6 +461,16 @@ void gpgme_set_progress_cb (GpgmeCtx c, GpgmeProgressCb cb, void *hook_value);
|
|||||||
void gpgme_get_progress_cb (GpgmeCtx ctx, GpgmeProgressCb *cb,
|
void gpgme_get_progress_cb (GpgmeCtx ctx, GpgmeProgressCb *cb,
|
||||||
void **hook_value);
|
void **hook_value);
|
||||||
|
|
||||||
|
|
||||||
|
/* Return a statically allocated string with the name of the public
|
||||||
|
key algorithm ALGO, or NULL if that name is not known. */
|
||||||
|
const char *gpgme_pubkey_algo_name (GpgmePubKeyAlgo algo);
|
||||||
|
|
||||||
|
/* Return a statically allocated string with the name of the hash
|
||||||
|
algorithm ALGO, or NULL if that name is not known. */
|
||||||
|
const char *gpgme_hash_algo_name (GpgmeHashAlgo algo);
|
||||||
|
|
||||||
|
|
||||||
/* Delete all signers from CTX. */
|
/* Delete all signers from CTX. */
|
||||||
void gpgme_signers_clear (GpgmeCtx ctx);
|
void gpgme_signers_clear (GpgmeCtx ctx);
|
||||||
|
|
||||||
@ -710,10 +755,18 @@ const char *gpgme_trust_item_get_string_attr (GpgmeTrustItem item,
|
|||||||
attribute appears more than once in the key. */
|
attribute appears more than once in the key. */
|
||||||
int gpgme_trust_item_get_int_attr (GpgmeTrustItem item, GpgmeAttr what,
|
int gpgme_trust_item_get_int_attr (GpgmeTrustItem item, GpgmeAttr what,
|
||||||
const void *reserved, int idx);
|
const void *reserved, int idx);
|
||||||
|
|
||||||
|
/* Crypto Operations. */
|
||||||
|
|
||||||
|
struct _gpgme_invalid_user_id
|
||||||
|
{
|
||||||
|
struct _gpgme_invalid_user_id *next;
|
||||||
|
char *id;
|
||||||
|
GpgmeError reason;
|
||||||
|
};
|
||||||
|
typedef struct _gpgme_invalid_user_id *GpgmeInvalidUserID;
|
||||||
|
|
||||||
/* Crypto operation function. */
|
|
||||||
|
|
||||||
/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
|
/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
|
||||||
store the resulting ciphertext in CIPHER. */
|
store the resulting ciphertext in CIPHER. */
|
||||||
GpgmeError gpgme_op_encrypt_start (GpgmeCtx ctx,
|
GpgmeError gpgme_op_encrypt_start (GpgmeCtx ctx,
|
||||||
@ -747,8 +800,32 @@ GpgmeError gpgme_op_decrypt_verify_start (GpgmeCtx ctx,
|
|||||||
GpgmeError gpgme_op_decrypt_verify (GpgmeCtx ctx,
|
GpgmeError gpgme_op_decrypt_verify (GpgmeCtx ctx,
|
||||||
GpgmeData cipher, GpgmeData plain);
|
GpgmeData cipher, GpgmeData plain);
|
||||||
|
|
||||||
/* Sign the plaintext PLAIN and store the signature in SIG. Only
|
|
||||||
detached signatures are supported for now. */
|
/* Signing. */
|
||||||
|
struct _gpgme_new_signature
|
||||||
|
{
|
||||||
|
struct _gpgme_new_signature *next;
|
||||||
|
GpgmeSigMode type;
|
||||||
|
GpgmePubKeyAlgo pubkey_algo;
|
||||||
|
GpgmeHashAlgo hash_algo;
|
||||||
|
unsigned long class;
|
||||||
|
long int created;
|
||||||
|
char *fpr;
|
||||||
|
};
|
||||||
|
typedef struct _gpgme_new_signature *GpgmeNewSignature;
|
||||||
|
|
||||||
|
struct _gpgme_op_sign_result
|
||||||
|
{
|
||||||
|
/* The list of invalid signers. */
|
||||||
|
GpgmeInvalidUserID invalid_signers;
|
||||||
|
GpgmeNewSignature signatures;
|
||||||
|
};
|
||||||
|
typedef struct _gpgme_op_sign_result *GpgmeSignResult;
|
||||||
|
|
||||||
|
/* Retrieve a pointer to the result of the signing operation. */
|
||||||
|
GpgmeSignResult gpgme_op_sign_result (GpgmeCtx ctx);
|
||||||
|
|
||||||
|
/* Sign the plaintext PLAIN and store the signature in SIG. */
|
||||||
GpgmeError gpgme_op_sign_start (GpgmeCtx ctx,
|
GpgmeError gpgme_op_sign_start (GpgmeCtx ctx,
|
||||||
GpgmeData plain, GpgmeData sig,
|
GpgmeData plain, GpgmeData sig,
|
||||||
GpgmeSigMode mode);
|
GpgmeSigMode mode);
|
||||||
@ -756,6 +833,7 @@ GpgmeError gpgme_op_sign (GpgmeCtx ctx,
|
|||||||
GpgmeData plain, GpgmeData sig,
|
GpgmeData plain, GpgmeData sig,
|
||||||
GpgmeSigMode mode);
|
GpgmeSigMode mode);
|
||||||
|
|
||||||
|
|
||||||
/* Verify within CTX that SIG is a valid signature for TEXT. */
|
/* Verify within CTX that SIG is a valid signature for TEXT. */
|
||||||
GpgmeError gpgme_op_verify_start (GpgmeCtx ctx, GpgmeData sig,
|
GpgmeError gpgme_op_verify_start (GpgmeCtx ctx, GpgmeData sig,
|
||||||
GpgmeData signed_text, GpgmeData plaintext);
|
GpgmeData signed_text, GpgmeData plaintext);
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "gpgme.h"
|
#include "gpgme.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
@ -105,3 +107,79 @@ _gpgme_op_reset (GpgmeCtx ctx, int type)
|
|||||||
_gpgme_engine_set_io_cbs (ctx->engine, &io_cbs);
|
_gpgme_engine_set_io_cbs (ctx->engine, &io_cbs);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GpgmeError
|
||||||
|
_gpgme_parse_inv_userid (char *args, GpgmeInvalidUserID *userid)
|
||||||
|
{
|
||||||
|
GpgmeInvalidUserID inv_userid;
|
||||||
|
char *tail;
|
||||||
|
long int reason;
|
||||||
|
|
||||||
|
inv_userid = malloc (sizeof (*inv_userid));
|
||||||
|
if (!inv_userid)
|
||||||
|
return GPGME_Out_Of_Core;
|
||||||
|
inv_userid->next = NULL;
|
||||||
|
errno = 0;
|
||||||
|
reason = strtol (args, &tail, 0);
|
||||||
|
if (errno || args == tail || *tail != ' ')
|
||||||
|
{
|
||||||
|
/* The crypto backend does not behave. */
|
||||||
|
free (inv_userid);
|
||||||
|
return GPGME_General_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (reason)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 0:
|
||||||
|
inv_userid->reason = GPGME_Unknown_Reason;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
inv_userid->reason = GPGME_Not_Found;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
inv_userid->reason = GPGME_Ambiguous_Specification;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
inv_userid->reason = GPGME_Wrong_Key_Usage;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
inv_userid->reason = GPGME_Key_Revoked;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
inv_userid->reason = GPGME_Key_Expired;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
inv_userid->reason = GPGME_No_CRL_Known;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
inv_userid->reason = GPGME_CRL_Too_Old;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
inv_userid->reason = GPGME_Policy_Mismatch;
|
||||||
|
|
||||||
|
case 9:
|
||||||
|
inv_userid->reason = GPGME_No_Secret_Key;
|
||||||
|
|
||||||
|
case 10:
|
||||||
|
inv_userid->reason = GPGME_Key_Not_Trusted;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*tail == ' ')
|
||||||
|
tail++;
|
||||||
|
if (*tail)
|
||||||
|
{
|
||||||
|
inv_userid->id = strdup (tail);
|
||||||
|
if (!inv_userid->id)
|
||||||
|
{
|
||||||
|
free (inv_userid);
|
||||||
|
return GPGME_Out_Of_Core;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
inv_userid->id = NULL;
|
||||||
|
|
||||||
|
*userid = inv_userid;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
24
gpgme/ops.h
24
gpgme/ops.h
@ -57,12 +57,22 @@ GpgmeError _gpgme_data_outbound_handler (void *opaque, int fd);
|
|||||||
GpgmeError _gpgme_key_new ( GpgmeKey *r_key );
|
GpgmeError _gpgme_key_new ( GpgmeKey *r_key );
|
||||||
GpgmeError _gpgme_key_new_secret ( GpgmeKey *r_key );
|
GpgmeError _gpgme_key_new_secret ( GpgmeKey *r_key );
|
||||||
|
|
||||||
/*-- op-support.c --*/
|
|
||||||
|
/* From op-support.c. */
|
||||||
|
|
||||||
|
/* Find or create the op data object of type TYPE. */
|
||||||
GpgmeError _gpgme_op_data_lookup (GpgmeCtx ctx, ctx_op_data_type type,
|
GpgmeError _gpgme_op_data_lookup (GpgmeCtx ctx, ctx_op_data_type type,
|
||||||
void **hook, int size,
|
void **hook, int size,
|
||||||
void (*cleanup) (void *));
|
void (*cleanup) (void *));
|
||||||
|
|
||||||
|
/* Prepare a new operation on CTX. */
|
||||||
GpgmeError _gpgme_op_reset (GpgmeCtx ctx, int synchronous);
|
GpgmeError _gpgme_op_reset (GpgmeCtx ctx, int synchronous);
|
||||||
|
|
||||||
|
/* Parse the invalid user ID status line in ARGS and return the result
|
||||||
|
in USERID. */
|
||||||
|
GpgmeError _gpgme_parse_inv_userid (char *args, GpgmeInvalidUserID *userid);
|
||||||
|
|
||||||
|
|
||||||
/*-- verify.c --*/
|
/*-- verify.c --*/
|
||||||
GpgmeError _gpgme_verify_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
|
GpgmeError _gpgme_verify_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
|
||||||
char *args);
|
char *args);
|
||||||
@ -74,10 +84,18 @@ GpgmeError _gpgme_decrypt_start (GpgmeCtx ctx, int synchronous,
|
|||||||
GpgmeData ciph, GpgmeData plain,
|
GpgmeData ciph, GpgmeData plain,
|
||||||
void *status_handler);
|
void *status_handler);
|
||||||
|
|
||||||
/*-- sign.c --*/
|
|
||||||
GpgmeError _gpgme_sign_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
|
/* From sign.c. */
|
||||||
|
|
||||||
|
/* Create an initial op data object for signing. Needs to be called
|
||||||
|
once before calling _gpgme_sign_status_handler. */
|
||||||
|
GpgmeError _gpgme_op_sign_init_result (GpgmeCtx ctx);
|
||||||
|
|
||||||
|
/* Process a status line for signing operations. */
|
||||||
|
GpgmeError _gpgme_sign_status_handler (void *priv, GpgmeStatusCode code,
|
||||||
char *args);
|
char *args);
|
||||||
|
|
||||||
|
|
||||||
/*-- encrypt.c --*/
|
/*-- encrypt.c --*/
|
||||||
GpgmeError _gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
|
GpgmeError _gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
|
||||||
char *args);
|
char *args);
|
||||||
|
351
gpgme/sign.c
351
gpgme/sign.c
@ -1,4 +1,4 @@
|
|||||||
/* sign.c - signing functions
|
/* sign.c - Signing function.
|
||||||
Copyright (C) 2000 Werner Koch (dd9jn)
|
Copyright (C) 2000 Werner Koch (dd9jn)
|
||||||
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
|
Copyright (C) 2001, 2002, 2003 g10 Code GmbH
|
||||||
|
|
||||||
@ -21,157 +21,203 @@
|
|||||||
#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 <errno.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "gpgme.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "ops.h"
|
#include "ops.h"
|
||||||
|
|
||||||
#define SKIP_TOKEN_OR_RETURN(a) do { \
|
|
||||||
while (*(a) && *(a) != ' ') (a)++; \
|
typedef struct
|
||||||
while (*(a) == ' ') (a)++; \
|
|
||||||
if (!*(a)) \
|
|
||||||
return; /* oops */ \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
struct sign_result
|
|
||||||
{
|
{
|
||||||
int okay;
|
struct _gpgme_op_sign_result result;
|
||||||
GpgmeData xmlinfo;
|
|
||||||
};
|
/* A pointer to the next pointer of the last invalid signer in
|
||||||
typedef struct sign_result *SignResult;
|
the list. This makes appending new invalid signers painless
|
||||||
|
while preserving the order. */
|
||||||
|
GpgmeInvalidUserID *last_signer_p;
|
||||||
|
|
||||||
|
/* Likewise for signature information. */
|
||||||
|
GpgmeNewSignature *last_sig_p;
|
||||||
|
} *op_data_t;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
release_sign_result (void *hook)
|
release_op_data (void *hook)
|
||||||
{
|
{
|
||||||
SignResult result = (SignResult) hook;
|
op_data_t opd = (op_data_t) hook;
|
||||||
|
GpgmeInvalidUserID invalid_signer = opd->result.invalid_signers;
|
||||||
|
GpgmeNewSignature sig = opd->result.signatures;
|
||||||
|
|
||||||
gpgme_data_release (result->xmlinfo);
|
while (invalid_signer)
|
||||||
|
{
|
||||||
|
GpgmeInvalidUserID next = invalid_signer->next;
|
||||||
|
free (invalid_signer->id);
|
||||||
|
free (invalid_signer);
|
||||||
|
invalid_signer = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse the args and save the information
|
while (sig)
|
||||||
<type> <pubkey algo> <hash algo> <class> <timestamp> <key fpr>
|
|
||||||
in an XML structure. With args of NULL the xml structure is
|
|
||||||
closed. */
|
|
||||||
static void
|
|
||||||
append_xml_siginfo (GpgmeData *rdh, char *args)
|
|
||||||
{
|
{
|
||||||
GpgmeData dh;
|
GpgmeNewSignature next = sig->next;
|
||||||
char helpbuf[100];
|
free (sig->fpr);
|
||||||
int i;
|
free (sig);
|
||||||
char *s;
|
sig = next;
|
||||||
unsigned long ul;
|
|
||||||
|
|
||||||
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, " </signature>\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args)
|
|
||||||
|
GpgmeSignResult
|
||||||
|
gpgme_op_sign_result (GpgmeCtx ctx)
|
||||||
{
|
{
|
||||||
/* Just close the XML containter. */
|
op_data_t opd;
|
||||||
_gpgme_data_append_string (dh, "</GnupgOperationInfo>\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_gpgme_data_append_string (dh, " <signature>\n");
|
|
||||||
|
|
||||||
_gpgme_data_append_string (dh,
|
|
||||||
*args == 'D' ? " <detached/>\n" :
|
|
||||||
*args == 'C' ? " <cleartext/>\n" :
|
|
||||||
*args == 'S' ? " <standard/>\n" : "");
|
|
||||||
SKIP_TOKEN_OR_RETURN (args);
|
|
||||||
|
|
||||||
sprintf (helpbuf, " <algo>%d</algo>\n", atoi (args));
|
|
||||||
_gpgme_data_append_string (dh, helpbuf);
|
|
||||||
SKIP_TOKEN_OR_RETURN (args);
|
|
||||||
|
|
||||||
i = atoi (args);
|
|
||||||
sprintf (helpbuf, " <hashalgo>%d</hashalgo>\n", atoi (args));
|
|
||||||
_gpgme_data_append_string (dh, helpbuf);
|
|
||||||
switch (i)
|
|
||||||
{
|
|
||||||
case 1: s = "pgp-md5"; break;
|
|
||||||
case 2: s = "pgp-sha1"; break;
|
|
||||||
case 3: s = "pgp-ripemd160"; break;
|
|
||||||
case 5: s = "pgp-md2"; break;
|
|
||||||
case 6: s = "pgp-tiger192"; break;
|
|
||||||
case 7: s = "pgp-haval-5-160"; break;
|
|
||||||
case 8: s = "pgp-sha256"; break;
|
|
||||||
case 9: s = "pgp-sha384"; break;
|
|
||||||
case 10: s = "pgp-sha512"; break;
|
|
||||||
default: s = "pgp-unknown"; break;
|
|
||||||
}
|
|
||||||
sprintf (helpbuf, " <micalg>%s</micalg>\n", s);
|
|
||||||
_gpgme_data_append_string (dh,helpbuf);
|
|
||||||
SKIP_TOKEN_OR_RETURN (args);
|
|
||||||
|
|
||||||
sprintf (helpbuf, " <sigclass>%.2s</sigclass>\n", args);
|
|
||||||
_gpgme_data_append_string (dh, helpbuf);
|
|
||||||
SKIP_TOKEN_OR_RETURN (args);
|
|
||||||
|
|
||||||
ul = strtoul (args, NULL, 10);
|
|
||||||
sprintf (helpbuf, " <created>%lu</created>\n", ul);
|
|
||||||
_gpgme_data_append_string (dh, helpbuf);
|
|
||||||
SKIP_TOKEN_OR_RETURN (args);
|
|
||||||
|
|
||||||
/* Count the length of the finperprint. */
|
|
||||||
for (i = 0; args[i] && args[i] != ' '; i++)
|
|
||||||
;
|
|
||||||
_gpgme_data_append_string (dh, " <fpr>");
|
|
||||||
_gpgme_data_append (dh, args, i);
|
|
||||||
_gpgme_data_append_string (dh, "</fpr>\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
GpgmeError
|
|
||||||
_gpgme_sign_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
|
|
||||||
{
|
|
||||||
SignResult result;
|
|
||||||
GpgmeError err;
|
GpgmeError err;
|
||||||
|
|
||||||
err = _gpgme_passphrase_status_handler (ctx, code, args);
|
err = _gpgme_op_data_lookup (ctx, OPDATA_SIGN, (void **) &opd, -1, NULL);
|
||||||
|
if (err || !opd)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &opd->result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static GpgmeError
|
||||||
|
parse_sig_created (char *args, GpgmeNewSignature *sigp)
|
||||||
|
{
|
||||||
|
GpgmeNewSignature sig;
|
||||||
|
char *tail;
|
||||||
|
|
||||||
|
sig = malloc (sizeof (*sig));
|
||||||
|
if (!sig)
|
||||||
|
return GPGME_Out_Of_Core;
|
||||||
|
|
||||||
|
sig->next = NULL;
|
||||||
|
switch (*args)
|
||||||
|
{
|
||||||
|
case 'S':
|
||||||
|
sig->type = GPGME_SIG_MODE_NORMAL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'D':
|
||||||
|
sig->type = GPGME_SIG_MODE_DETACH;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'C':
|
||||||
|
sig->type = GPGME_SIG_MODE_CLEAR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* The backend engine is not behaving. */
|
||||||
|
free (sig);
|
||||||
|
return GPGME_General_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
args++;
|
||||||
|
if (*args != ' ')
|
||||||
|
{
|
||||||
|
free (sig);
|
||||||
|
return GPGME_General_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
sig->pubkey_algo = strtol (args, &tail, 0);
|
||||||
|
if (errno || args == tail || *tail != ' ')
|
||||||
|
{
|
||||||
|
/* The crypto backend does not behave. */
|
||||||
|
free (sig);
|
||||||
|
return GPGME_General_Error;
|
||||||
|
}
|
||||||
|
args = tail;
|
||||||
|
|
||||||
|
sig->hash_algo = strtol (args, &tail, 0);
|
||||||
|
if (errno || args == tail || *tail != ' ')
|
||||||
|
{
|
||||||
|
/* The crypto backend does not behave. */
|
||||||
|
free (sig);
|
||||||
|
return GPGME_General_Error;
|
||||||
|
}
|
||||||
|
args = tail;
|
||||||
|
|
||||||
|
sig->class = strtol (args, &tail, 0);
|
||||||
|
if (errno || args == tail || *tail != ' ')
|
||||||
|
{
|
||||||
|
/* The crypto backend does not behave. */
|
||||||
|
free (sig);
|
||||||
|
return GPGME_General_Error;
|
||||||
|
}
|
||||||
|
args = tail;
|
||||||
|
|
||||||
|
sig->created = strtol (args, &tail, 0);
|
||||||
|
if (errno || args == tail || *tail != ' ')
|
||||||
|
{
|
||||||
|
/* The crypto backend does not behave. */
|
||||||
|
free (sig);
|
||||||
|
return GPGME_General_Error;
|
||||||
|
}
|
||||||
|
args = tail;
|
||||||
|
while (*args == ' ')
|
||||||
|
args++;
|
||||||
|
|
||||||
|
if (!*args)
|
||||||
|
{
|
||||||
|
/* The crypto backend does not behave. */
|
||||||
|
free (sig);
|
||||||
|
return GPGME_General_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
tail = strchr (args, ' ');
|
||||||
|
if (tail)
|
||||||
|
*tail = '\0';
|
||||||
|
|
||||||
|
sig->fpr = strdup (args);
|
||||||
|
if (!sig->fpr)
|
||||||
|
{
|
||||||
|
free (sig);
|
||||||
|
return GPGME_Out_Of_Core;
|
||||||
|
}
|
||||||
|
*sigp = sig;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GpgmeError
|
||||||
|
_gpgme_sign_status_handler (void *priv, GpgmeStatusCode code, char *args)
|
||||||
|
{
|
||||||
|
GpgmeCtx ctx = (GpgmeCtx) priv;
|
||||||
|
GpgmeError err;
|
||||||
|
op_data_t opd;
|
||||||
|
|
||||||
|
err = _gpgme_passphrase_status_handler (priv, code, args);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = _gpgme_op_data_lookup (ctx, OPDATA_SIGN, (void **) &opd, -1, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case GPGME_STATUS_EOF:
|
case GPGME_STATUS_SIG_CREATED:
|
||||||
err = _gpgme_op_data_lookup (ctx, OPDATA_SIGN, (void **) &result,
|
err = parse_sig_created (args, opd->last_sig_p);
|
||||||
-1, NULL);
|
if (err)
|
||||||
if (!err)
|
return err;
|
||||||
{
|
|
||||||
if (result && result->okay)
|
opd->last_sig_p = &(*opd->last_sig_p)->next;
|
||||||
{
|
|
||||||
append_xml_siginfo (&result->xmlinfo, NULL);
|
|
||||||
_gpgme_set_op_info (ctx, result->xmlinfo);
|
|
||||||
result->xmlinfo = NULL;
|
|
||||||
}
|
|
||||||
else if (!result || !result->okay)
|
|
||||||
/* FIXME: choose a better error code? */
|
|
||||||
err = GPGME_No_Data;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPGME_STATUS_SIG_CREATED:
|
case GPGME_STATUS_INV_RECP:
|
||||||
/* FIXME: We have no error return for multiple signatures. */
|
err = _gpgme_parse_inv_userid (args, opd->last_signer_p);
|
||||||
err = _gpgme_op_data_lookup (ctx, OPDATA_SIGN, (void **) &result,
|
if (err)
|
||||||
sizeof (*result), release_sign_result);
|
return err;
|
||||||
append_xml_siginfo (&result->xmlinfo, args);
|
|
||||||
result->okay = 1;
|
opd->last_signer_p = &(*opd->last_signer_p)->next;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GPGME_STATUS_EOF:
|
||||||
|
if (opd->result.invalid_signers)
|
||||||
|
return GPGME_Invalid_UserID;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -180,9 +226,25 @@ _gpgme_sign_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GpgmeError
|
||||||
|
_gpgme_op_sign_init_result (GpgmeCtx ctx)
|
||||||
|
{
|
||||||
|
GpgmeError err;
|
||||||
|
op_data_t opd;
|
||||||
|
|
||||||
|
err = _gpgme_op_data_lookup (ctx, OPDATA_SIGN, (void **) &opd,
|
||||||
|
sizeof (*opd), release_op_data);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
opd->last_signer_p = &opd->result.invalid_signers;
|
||||||
|
opd->last_sig_p = &opd->result.signatures;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static GpgmeError
|
static GpgmeError
|
||||||
_gpgme_op_sign_start (GpgmeCtx ctx, int synchronous,
|
sign_start (GpgmeCtx ctx, int synchronous, GpgmeData plain, GpgmeData sig,
|
||||||
GpgmeData plain, GpgmeData sig,
|
|
||||||
GpgmeSigMode mode)
|
GpgmeSigMode mode)
|
||||||
{
|
{
|
||||||
GpgmeError err;
|
GpgmeError err;
|
||||||
@ -191,6 +253,10 @@ _gpgme_op_sign_start (GpgmeCtx ctx, int synchronous,
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
err = _gpgme_op_sign_init_result (ctx);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
if (mode != GPGME_SIG_MODE_NORMAL && mode != GPGME_SIG_MODE_DETACH
|
if (mode != GPGME_SIG_MODE_NORMAL && mode != GPGME_SIG_MODE_DETACH
|
||||||
&& mode != GPGME_SIG_MODE_CLEAR)
|
&& mode != GPGME_SIG_MODE_CLEAR)
|
||||||
return GPGME_Invalid_Value;
|
return GPGME_Invalid_Value;
|
||||||
@ -217,38 +283,21 @@ _gpgme_op_sign_start (GpgmeCtx ctx, int synchronous,
|
|||||||
ctx /* FIXME */);
|
ctx /* FIXME */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Sign the plaintext PLAIN and store the signature in SIG. */
|
||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_op_sign_start (GpgmeCtx ctx, GpgmeData in, GpgmeData out,
|
gpgme_op_sign_start (GpgmeCtx ctx, GpgmeData plain, GpgmeData sig,
|
||||||
GpgmeSigMode mode)
|
GpgmeSigMode mode)
|
||||||
{
|
{
|
||||||
return _gpgme_op_sign_start (ctx, 0, in, out, mode);
|
return sign_start (ctx, 0, plain, sig, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gpgme_op_sign:
|
/* Sign the plaintext PLAIN and store the signature in SIG. */
|
||||||
* @ctx: The context
|
|
||||||
* @in: Data to be signed
|
|
||||||
* @out: Detached signature
|
|
||||||
* @mode: Signature creation mode
|
|
||||||
*
|
|
||||||
* Create a detached signature for @in and write it to @out.
|
|
||||||
* The data will be signed using either the default key or the ones
|
|
||||||
* defined through @ctx.
|
|
||||||
* The defined modes for signature create are:
|
|
||||||
* <literal>
|
|
||||||
* GPGME_SIG_MODE_NORMAL (or 0)
|
|
||||||
* GPGME_SIG_MODE_DETACH
|
|
||||||
* GPGME_SIG_MODE_CLEAR
|
|
||||||
* </literal>
|
|
||||||
* Note that the settings done by gpgme_set_armor() and gpgme_set_textmode()
|
|
||||||
* are ignore for @mode GPGME_SIG_MODE_CLEAR.
|
|
||||||
*
|
|
||||||
* Return value: 0 on success or an error code.
|
|
||||||
**/
|
|
||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_op_sign (GpgmeCtx ctx, GpgmeData in, GpgmeData out, GpgmeSigMode mode)
|
gpgme_op_sign (GpgmeCtx ctx, GpgmeData plain, GpgmeData sig, GpgmeSigMode mode)
|
||||||
{
|
{
|
||||||
GpgmeError err = _gpgme_op_sign_start (ctx, 1, in, out, mode);
|
GpgmeError err = sign_start (ctx, 1, plain, sig, mode);
|
||||||
if (!err)
|
if (!err)
|
||||||
err = _gpgme_wait_one (ctx);
|
err = _gpgme_wait_one (ctx);
|
||||||
return err;
|
return err;
|
||||||
|
Loading…
Reference in New Issue
Block a user