From: Werner Koch Date: Mon, 26 Feb 2007 10:36:08 +0000 (+0000) Subject: Detect and bailo out on double plaintext messages. X-Git-Tag: gpgme-1.2.0@1385~175 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=87ed9ee210879c68f700cdd980d71c6be70b31e2;p=gpgme.git Detect and bailo out on double plaintext messages. --- diff --git a/trunk/NEWS b/trunk/NEWS index 3ec841a..f0f07fa 100644 --- a/trunk/NEWS +++ b/trunk/NEWS @@ -1,3 +1,9 @@ +Noteworthy changes in version 1.1.4 +------------------------------------------------ + + * Detect and bail out on double plaintext messages. + + Noteworthy changes in version 1.1.3 (2007-01-29) ------------------------------------------------ diff --git a/trunk/gpgme/ChangeLog b/trunk/gpgme/ChangeLog index 0d190cd..5c31489 100644 --- a/trunk/gpgme/ChangeLog +++ b/trunk/gpgme/ChangeLog @@ -1,3 +1,11 @@ +2007-02-26 Werner Koch + + * verify.c (op_data_t): New element PLAINTEXT_SEEN. + (_gpgme_verify_status_handler): Return an error if more than one + plaintext has been seen. + (parse_error): New arg SET_STATUS. Also detect it based on an + ERROR status (gpg > 1.4.6). + 2007-01-26 Werner Koch * w32-io.c (build_commandline): Fixed stupid quoting bug. diff --git a/trunk/gpgme/gpgme.h b/trunk/gpgme/gpgme.h index dcf897c..9164886 100644 --- a/trunk/gpgme/gpgme.h +++ b/trunk/gpgme/gpgme.h @@ -72,7 +72,7 @@ extern "C" { AM_PATH_GPGME macro) check that this header matches the installed library. Warning: Do not edit the next line. configure will do that for you! */ -#define GPGME_VERSION "1.1.3-cvs1202" +#define GPGME_VERSION "1.1.3" diff --git a/trunk/gpgme/verify.c b/trunk/gpgme/verify.c index 8596bbc..d36206f 100644 --- a/trunk/gpgme/verify.c +++ b/trunk/gpgme/verify.c @@ -40,6 +40,7 @@ typedef struct gpgme_signature_t current_sig; int did_prepare_new_sig; int only_newsig_seen; + int plaintext_seen; } *op_data_t; @@ -549,8 +550,11 @@ parse_trust (gpgme_signature_t sig, gpgme_status_code_t code, char *args) } +/* Parse an error status line and if SET_STATUS is true update the + result status as appropriate. With SET_STATUS being false, only + check for an error. */ static gpgme_error_t -parse_error (gpgme_signature_t sig, char *args) +parse_error (gpgme_signature_t sig, char *args, int set_status) { gpgme_error_t err; char *where = strchr (args, ' '); @@ -572,7 +576,16 @@ parse_error (gpgme_signature_t sig, char *args) err = _gpgme_map_gnupg_error (which); - if (!strcmp (where, "verify.findkey")) + if (!strcmp (where, "proc_pkt.plaintext") + && gpg_err_code (err) == GPG_ERR_BAD_DATA) + { + /* This indicates a double plaintext. The only solid way to + handle this is by failing the oepration. */ + return gpg_error (GPG_ERR_BAD_DATA); + } + else if (!set_status) + ; + else if (!strcmp (where, "verify.findkey")) sig->status = err; else if (!strcmp (where, "verify.keyusage") && gpg_err_code (err) == GPG_ERR_WRONG_KEY_USAGE) @@ -670,9 +683,9 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args) case GPGME_STATUS_ERROR: opd->only_newsig_seen = 0; - /* The error status is informational, so we don't return an - error code if we are not ready to process this status. */ - return sig ? parse_error (sig, args) : 0; + /* Some error stati are informational, so we don't return an + error code if we are not ready to process this status. */ + return parse_error (sig, args, !!sig ); case GPGME_STATUS_EOF: if (sig && !opd->did_prepare_new_sig) @@ -703,6 +716,8 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args) break; case GPGME_STATUS_PLAINTEXT: + if (++opd->only_newsig_seen > 1) + return gpg_error (GPG_ERR_BAD_DATA); err = _gpgme_parse_plaintext (args, &opd->result.file_name); if (err) return err; @@ -816,8 +831,9 @@ gpgme_get_sig_key (gpgme_ctx_t ctx, int idx, gpgme_key_t *r_key) successful verify operation in R_STAT (if non-null). The creation time stamp of the signature is returned in R_CREATED (if non-null). The function returns a string containing the fingerprint. */ -const char *gpgme_get_sig_status (gpgme_ctx_t ctx, int idx, - _gpgme_sig_stat_t *r_stat, time_t *r_created) +const char * +gpgme_get_sig_status (gpgme_ctx_t ctx, int idx, + _gpgme_sig_stat_t *r_stat, time_t *r_created) { gpgme_verify_result_t result; gpgme_signature_t sig; @@ -876,8 +892,9 @@ const char *gpgme_get_sig_status (gpgme_ctx_t ctx, int idx, number of the signature after a successful verify operation. WHAT is an attribute where GPGME_ATTR_EXPIRE is probably the most useful one. WHATIDX is to be passed as 0 for most attributes . */ -unsigned long gpgme_get_sig_ulong_attr (gpgme_ctx_t ctx, int idx, - _gpgme_attr_t what, int whatidx) +unsigned long +gpgme_get_sig_ulong_attr (gpgme_ctx_t ctx, int idx, + _gpgme_attr_t what, int whatidx) { gpgme_verify_result_t result; gpgme_signature_t sig; @@ -939,8 +956,9 @@ unsigned long gpgme_get_sig_ulong_attr (gpgme_ctx_t ctx, int idx, } -const char *gpgme_get_sig_string_attr (gpgme_ctx_t ctx, int idx, - _gpgme_attr_t what, int whatidx) +const char * +gpgme_get_sig_string_attr (gpgme_ctx_t ctx, int idx, + _gpgme_attr_t what, int whatidx) { gpgme_verify_result_t result; gpgme_signature_t sig; diff --git a/trunk/tests/ChangeLog b/trunk/tests/ChangeLog index 3db4b94..f83207f 100644 --- a/trunk/tests/ChangeLog +++ b/trunk/tests/ChangeLog @@ -1,3 +1,8 @@ +2007-02-26 Werner Koch + + * gpg/t-verify.c (double_plaintext_sig): New. + (main): Check it. + 2006-12-02 Marcus Brinkmann * gpgsm/t-keylist.c (main): Skip unknown keys. Newer versions of diff --git a/trunk/tests/gpg/t-verify.c b/trunk/tests/gpg/t-verify.c index 22f0477..0efd06f 100644 --- a/trunk/tests/gpg/t-verify.c +++ b/trunk/tests/gpg/t-verify.c @@ -76,6 +76,20 @@ static const char test_sig2[] = "=Crq6\n" "-----END PGP MESSAGE-----\n"; +/* A message with a prepended but unsigned plaintext packet. */ +static const char double_plaintext_sig[] = +"-----BEGIN PGP MESSAGE-----\n" +"\n" +"rDRiCmZvb2Jhci50eHRF4pxNVGhpcyBpcyBteSBzbmVha3kgcGxhaW50ZXh0IG1l\n" +"c3NhZ2UKowGbwMvMwCSoW1RzPCOz3IRxTWISa6JebnG666MFD1wzSzJSixQ81XMV\n" +"UlITUxTyixRyKxXKE0uSMxQyEosVikvyCwpSU/S4FNCArq6Ce1F+aXJGvoJvYlGF\n" +"erFCTmJxiUJ5flFKMVeHGwuDIBMDGysTyA4GLk4BmO036xgWzMgzt9V85jCtfDFn\n" +"UqVooWlGXHwNw/xg/fVzt9VNbtjtJ/fhUqYo0/LyCGEA\n" +"=6+AK\n" +"-----END PGP MESSAGE-----\n"; + + + static void check_result (gpgme_verify_result_t result, unsigned int summary, char *fpr, @@ -235,6 +249,23 @@ main (int argc, char *argv[]) check_result (result, 0, "A0FF4590BB6122EDEF6E3C542D727CC768697734", GPG_ERR_NO_ERROR, 0); + + /* Checking an invalid message. */ + gpgme_data_release (sig); + gpgme_data_release (text); + err = gpgme_data_new_from_mem (&sig, double_plaintext_sig, + strlen (double_plaintext_sig), 0); + fail_if_err (err); + err = gpgme_data_new (&text); + fail_if_err (err); + err = gpgme_op_verify (ctx, sig, NULL, text); + if (gpg_err_code (err) != GPG_ERR_BAD_DATA) + { + fprintf (stderr, "%s:%i: Double plaintext message not detected\n", + __FILE__, __LINE__); + exit (1); + } + gpgme_data_release (sig); gpgme_data_release (text); gpgme_release (ctx);