aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2007-02-26 10:36:08 +0000
committerWerner Koch <[email protected]>2007-02-26 10:36:08 +0000
commit1786019d6891b4e4ff350ca800b1cd63a79c5806 (patch)
treecdc32bd6a3b235b738cf1278e68cdf0a3e012476
parent2007-01-29 Marcus Brinkmann <[email protected]> (diff)
downloadgpgme-1786019d6891b4e4ff350ca800b1cd63a79c5806.tar.gz
gpgme-1786019d6891b4e4ff350ca800b1cd63a79c5806.zip
Detect and bailo out on double plaintext messages.
-rw-r--r--NEWS6
-rw-r--r--gpgme/ChangeLog8
-rw-r--r--gpgme/gpgme.h2
-rw-r--r--gpgme/verify.c40
-rw-r--r--tests/ChangeLog5
-rw-r--r--tests/gpg/t-verify.c31
6 files changed, 80 insertions, 12 deletions
diff --git a/NEWS b/NEWS
index 3ec841ae..f0f07fa5 100644
--- a/NEWS
+++ b/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/gpgme/ChangeLog b/gpgme/ChangeLog
index 0d190cdf..5c31489e 100644
--- a/gpgme/ChangeLog
+++ b/gpgme/ChangeLog
@@ -1,3 +1,11 @@
+2007-02-26 Werner Koch <[email protected]>
+
+ * 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 <[email protected]>
* w32-io.c (build_commandline): Fixed stupid quoting bug.
diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h
index dcf897c8..9164886b 100644
--- a/gpgme/gpgme.h
+++ b/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/gpgme/verify.c b/gpgme/verify.c
index 8596bbc9..d36206f0 100644
--- a/gpgme/verify.c
+++ b/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/tests/ChangeLog b/tests/ChangeLog
index 3db4b94c..f83207fd 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,8 @@
+2007-02-26 Werner Koch <[email protected]>
+
+ * gpg/t-verify.c (double_plaintext_sig): New.
+ (main): Check it.
+
2006-12-02 Marcus Brinkmann <[email protected]>
* gpgsm/t-keylist.c (main): Skip unknown keys. Newer versions of
diff --git a/tests/gpg/t-verify.c b/tests/gpg/t-verify.c
index 22f04773..0efd06ff 100644
--- a/tests/gpg/t-verify.c
+++ b/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);