From 7d0eebf41a7374a3dc66c9fc138e5470bea0af42 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Sun, 3 Mar 2002 16:46:33 +0000 Subject: [PATCH] doc/ 2002-03-03 Marcus Brinkmann * gpgme.texi (Verify): Document verification of normal and cleartext signatures. gpgme/ 2002-03-03 Marcus Brinkmann * rungpg.c (_gpgme_gpg_op_verify): If TEXT is of mode GPGME_DATA_MODE_IN, construct a command line that stores the plaintext in TEXT. * verify.c (gpgme_op_verify_start): Accept TEXT being uninitialized, and in this case interpret SIG as a normal or cleartext signature and TEXT as a return data object. * engine-gpgsm.c (_gpgme_gpgsm_op_verify): Likewise. tests/ 2002-03-03 Marcus Brinkmann * gpg/t-verify.c (main): Add a few more sanity checks, and a check for normal signatures. --- NEWS | 5 ++++ doc/ChangeLog | 5 ++++ doc/gpgme.texi | 17 ++++++++----- gpgme/ChangeLog | 10 ++++++++ gpgme/engine-gpgsm.c | 17 ++++++++++--- gpgme/rungpg.c | 41 ++++++++++++++++++++---------- gpgme/verify.c | 20 +++++++++++---- tests/ChangeLog | 5 ++++ tests/gpg/t-verify.c | 60 ++++++++++++++++++++++++++++++++++++-------- 9 files changed, 143 insertions(+), 37 deletions(-) diff --git a/NEWS b/NEWS index 682f262..ec9db4b 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,10 @@ the ciphertext is not usable for all requested recipients. Information about invalid recipients is available with gpgme_get_op_info. + * gpgme_op_verify now allows to pass an uninitialized data object as + its plaintext argument to check for normal and cleartext + signatures. The plaintext is then returned in the data object. + * New interfaces gpgme_set_include_certs and gpgme_get_include_certs to set and get the number of certifications to include in S/MIME signed messages. @@ -18,6 +22,7 @@ * Interface changes relative to the 0.3.3 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gpgme_op_encrypt CHANGED: Can fail with GPGME_Invalid_Recipients +gpgme_op_verify EXTENDED: Accepts uninitialized text argument gpgme_set_include_certs NEW gpgme_get_include_certs NEW gpgme_op_encrypt_sign NEW diff --git a/doc/ChangeLog b/doc/ChangeLog index 56be628..88d4fbf 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,8 @@ +2002-03-03 Marcus Brinkmann + + * gpgme.texi (Verify): Document verification of normal and + cleartext signatures. + 2002-02-27 Marcus Brinkmann * gpgme.texi (Listing Keys): Document gpgme_op_keylist_ext_start. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index a012abb..f691e50 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -1907,9 +1907,14 @@ have a different status. You can get each key's status with @end deftp @deftypefun GpgmeError gpgme_op_verify (@w{GpgmeCtx @var{ctx}}, @w{GpgmeData @var{sig}}, @w{GpgmeData @var{plain}}, @w{GpgmeSigStat *@var{r_stat}}) -The function @code{gpgme_op_verify} verifies that the detached -signature in the data object @var{sig} is a valid signature for the -plaintext in the data object @var{plain}. +The function @code{gpgme_op_verify} verifies that the signature in the +data object @var{sig} is a valid signature. If @var{plain} is +initialized with plaintext data, it is assumed that @var{sig} is a +detached signature, and its validity for the plaintext given in +@var{plain} is verified. If @var{plain} is an uninitialized data +object, it is assumed that @var{sig} is a normal (or cleartext) +signature, and the plaintext is available in @var{plain} after +successful verification. The combined status of all signatures is returned in @var{r_stat}. The results of the individual signature verifications can be retrieved @@ -1918,9 +1923,9 @@ with @code{gpgme_get_sig_status} and @code{gpgme_get_sig_key}. The function returns @code{GPGME_No_Error} if the operation could be completed successfully, @code{GPGME_Invalid_Value} if @var{ctx}, @var{sig}, @var{plain} or @var{r_stat} is not a valid pointer, -@code{GPGME_No_Data} if @var{sig} or @var{plain} does not contain any -data to verify, and passes through any errors that are reported by the -crypto engine support routines. +@code{GPGME_No_Data} if @var{sig} does not contain any data to verify, +and passes through any errors that are reported by the crypto engine +support routines. @end deftypefun @deftypefun GpgmeError gpgme_op_verify_start (@w{GpgmeCtx @var{ctx}}, @w{GpgmeData @var{sig}}, @w{GpgmeData @var{plain}}) diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 9172ffe..1294c54 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,13 @@ +2002-03-03 Marcus Brinkmann + + * rungpg.c (_gpgme_gpg_op_verify): If TEXT is of mode + GPGME_DATA_MODE_IN, construct a command line that stores the + plaintext in TEXT. + * verify.c (gpgme_op_verify_start): Accept TEXT being + uninitialized, and in this case interpret SIG as a normal or + cleartext signature and TEXT as a return data object. + * engine-gpgsm.c (_gpgme_gpgsm_op_verify): Likewise. + 2002-03-03 Marcus Brinkmann * engine-gpgsm.c (_gpgme_gpgsm_op_keylist_ext) [!ENABLE_GPGSM]: diff --git a/gpgme/engine-gpgsm.c b/gpgme/engine-gpgsm.c index 067c08c..c2d28b5 100644 --- a/gpgme/engine-gpgsm.c +++ b/gpgme/engine-gpgsm.c @@ -755,9 +755,20 @@ _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData text) err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server, 0); if (err) return err; - gpgsm->message_data = text; - err = gpgsm_set_fd (gpgsm->assuan_ctx, "MESSAGE", gpgsm->message_fd_server, - 0); + if (_gpgme_data_get_mode (text) == GPGME_DATA_MODE_IN) + { + /* Normal or cleartext signature. */ + gpgsm->output_data = text; + err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server, + 0); + } + else + { + /* Detached signature. */ + gpgsm->message_data = text; + err = gpgsm_set_fd (gpgsm->assuan_ctx, "MESSAGE", + gpgsm->message_fd_server, 0); + } if (err) return err; _gpgme_io_close (gpgsm->output_fd); diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c index dc69acb..be639b9 100644 --- a/gpgme/rungpg.c +++ b/gpgme/rungpg.c @@ -1553,29 +1553,44 @@ _gpgme_gpg_op_verify (GpgObject gpg, GpgmeData sig, GpgmeData text) { GpgmeError err = 0; - if (gpg->pm.used) + if (_gpgme_data_get_mode (text) == GPGME_DATA_MODE_IN) { - err = _gpgme_gpg_add_arg (gpg, gpg->pm.used ? "--pipemode" : "--verify"); + /* Normal or cleartext signature. */ + + err = _gpgme_gpg_add_arg (gpg, "--output"); if (!err) - err = _gpgme_gpg_add_arg (gpg, "--"); + err = _gpgme_gpg_add_arg (gpg, "-"); if (!err) - err = _gpgme_gpg_add_pm_data (gpg, sig, 0); + err = _gpgme_gpg_add_data (gpg, sig, 0); if (!err) - err = _gpgme_gpg_add_pm_data (gpg, text, 1); + err = _gpgme_gpg_add_data (gpg, text, 1); } else { - err = _gpgme_gpg_add_arg (gpg, "--verify"); - if (!err) - err = _gpgme_gpg_add_arg (gpg, "--"); - if (!err) - err = _gpgme_gpg_add_data (gpg, sig, -1); - if (text) + if (gpg->pm.used) + { + err = _gpgme_gpg_add_arg (gpg, gpg->pm.used ? "--pipemode" : "--verify"); + if (!err) + err = _gpgme_gpg_add_arg (gpg, "--"); + if (!err) + err = _gpgme_gpg_add_pm_data (gpg, sig, 0); + if (!err) + err = _gpgme_gpg_add_pm_data (gpg, text, 1); + } + else { + err = _gpgme_gpg_add_arg (gpg, "--verify"); if (!err) - err = _gpgme_gpg_add_arg (gpg, "-"); + err = _gpgme_gpg_add_arg (gpg, "--"); if (!err) - err = _gpgme_gpg_add_data (gpg, text, 0); + err = _gpgme_gpg_add_data (gpg, sig, -1); + if (text) + { + if (!err) + err = _gpgme_gpg_add_arg (gpg, "-"); + if (!err) + err = _gpgme_gpg_add_data (gpg, text, 0); + } } } return err; diff --git a/gpgme/verify.c b/gpgme/verify.c index fd5debf..13b83c2 100644 --- a/gpgme/verify.c +++ b/gpgme/verify.c @@ -284,13 +284,17 @@ gpgme_op_verify_start (GpgmeCtx ctx, GpgmeData sig, GpgmeData text) err = mk_error (No_Data); goto leave; } - if (text && gpgme_data_get_type (text) == GPGME_DATA_TYPE_NONE) + if (!text) { - err = mk_error (No_Data); + err = mk_error (Invalid_Value); goto leave; } _gpgme_data_set_mode (sig, GPGME_DATA_MODE_OUT); - if (text) /* Detached signature. */ + if (gpgme_data_get_type (text) == GPGME_DATA_TYPE_NONE) + /* Normal or cleartext signature. */ + _gpgme_data_set_mode (text, GPGME_DATA_MODE_IN); + else + /* Detached signature. */ _gpgme_data_set_mode (text, GPGME_DATA_MODE_OUT); err = _gpgme_engine_op_verify (ctx->engine, sig, text); @@ -330,8 +334,14 @@ _gpgme_intersect_stati (VerifyResult result) * @text: the signed text * @r_stat: returns the status of the signature * - * Perform a signature check on the signature given in @sig. Currently it is - * assumed that this is a detached signature for the material given in @text. + * Perform a signature check on the signature given in @sig. If @text + * is a new and uninitialized data object, it is assumed that @sig + * contains a normal or cleartext signature, and the plaintext is + * returned in @text upon successful verification. + * + * If @text is initialized, it is assumed that @sig is a detached + * signature for the material given in @text. + * * The result of this operation is returned in @r_stat which can take these * values: * GPGME_SIG_STAT_NONE: No status - should not happen diff --git a/tests/ChangeLog b/tests/ChangeLog index 5eaf471..0d62f7a 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,8 @@ +2002-03-03 Marcus Brinkmann + + * gpg/t-verify.c (main): Add a few more sanity checks, and a check + for normal signatures. + 2002-02-26 Marcus Brinkmann * gpg/t-encrypt-sign.c: New file. diff --git a/tests/gpg/t-verify.c b/tests/gpg/t-verify.c index 6b4a28e..9e1b4bf 100644 --- a/tests/gpg/t-verify.c +++ b/tests/gpg/t-verify.c @@ -59,7 +59,14 @@ static const char test_sig1[] = "-----END PGP SIGNATURE-----\n" #endif ; - +static const char test_sig2[] = +"-----BEGIN PGP MESSAGE-----\n" +"\n" +"owGbwMvMwCSoW1RzPCOz3IRxjXQSR0lqcYleSUWJTZOvjVdpcYmCu1+oQmaJIleH\n" +"GwuDIBMDGysTSIqBi1MApi+nlGGuwDeHao53HBr+FoVGP3xX+kvuu9fCMJvl6IOf\n" +"y1kvP4y+8D5a11ang0udywsA\n" +"=Crq6\n" +"-----END PGP MESSAGE-----\n"; #define fail_if_err(a) do { if(a) { \ @@ -133,6 +140,7 @@ main (int argc, char **argv ) GpgmeSigStat status; char *nota; int n = 0; + int i, j; err = gpgme_new (&ctx); fail_if_err (err); @@ -151,11 +159,13 @@ main (int argc, char **argv ) puts ("checking a valid message:\n"); err = gpgme_op_verify (ctx, sig, text, &status ); - print_sig_stat ( ctx, status ); - print_sig_stat ( ctx, status ); - print_sig_stat ( ctx, status ); - print_sig_stat ( ctx, status ); fail_if_err (err); + print_sig_stat ( ctx, status ); + if (status != GPGME_SIG_STAT_GOOD) + { + fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__); + exit (1); + } if ( (nota=gpgme_get_notation (ctx)) ) printf ("---Begin Notation---\n%s---End Notation---\n", nota ); @@ -167,20 +177,50 @@ main (int argc, char **argv ) fail_if_err (err); gpgme_data_rewind ( sig ); err = gpgme_op_verify (ctx, sig, text, &status ); - - print_sig_stat ( ctx, status ); fail_if_err (err); + + print_sig_stat (ctx, status); + if (status != GPGME_SIG_STAT_BAD) + { + fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__); + exit (1); + } if ( (nota=gpgme_get_notation (ctx)) ) printf ("---Begin Notation---\n%s---End Notation---\n", nota ); + puts ("checking a normal signature:"); gpgme_data_release (sig); gpgme_data_release (text); + err = gpgme_data_new_from_mem (&sig, test_sig2, strlen (test_sig2), 0); + fail_if_err (err); + err = gpgme_data_new (&text); + fail_if_err (err); + err = gpgme_op_verify (ctx, sig, text, &status); + fail_if_err (err); + + nota = gpgme_data_release_and_get_mem (text, &i); + for (j = 0; j < i; j++) + putchar (nota[j]); + if (strncmp (nota, test_text1, strlen (test_text1))) + { + fprintf (stderr, "%s:%d: Wrong plaintext\n", __FILE__, __LINE__); + exit (1); + } + + print_sig_stat (ctx, status); + if (status != GPGME_SIG_STAT_GOOD) + { + fprintf (stderr, "%s:%d: Wrong sig stat\n", __FILE__, __LINE__); + exit (1); + } + + if ((nota = gpgme_get_notation (ctx))) + printf ("---Begin Notation---\n%s---End Notation---\n", nota); + + gpgme_data_release (sig); } while ( argc > 1 && !strcmp( argv[1], "--loop" ) && ++n < 20 ); gpgme_release (ctx); return 0; } - - - -- 2.26.2