Imported Upstream version 1.8.0
[platform/upstream/gpgme.git] / tests / gpg / t-verify.c
1 /* t-verify.c - Regression test.
2    Copyright (C) 2000 Werner Koch (dd9jn)
3    Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH
4
5    This file is part of GPGME.
6
7    GPGME is free software; you can redistribute it and/or modify it
8    under the terms of the GNU Lesser General Public License as
9    published by the Free Software Foundation; either version 2.1 of
10    the License, or (at your option) any later version.
11
12    GPGME is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
16
17    You should have received a copy of the GNU Lesser General Public
18    License along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, USA.  */
21
22 /* We need to include config.h so that we know whether we are building
23    with large file system (LFS) support. */
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31
32 #include <gpgme.h>
33
34 #include "t-support.h"
35
36 \f
37 static const char test_text1[] = "Just GNU it!\n";
38 static const char test_text1f[]= "Just GNU it?\n";
39 static const char test_sig1[] =
40 #if 0
41 "-----BEGIN PGP SIGNATURE-----\n"
42 "\n"
43 "iEYEABECAAYFAjoKgjIACgkQLXJ8x2hpdzQMSwCeO/xUrhysZ7zJKPf/FyXA//u1\n"
44 "ZgIAn0204PBR7yxSdQx6CFxugstNqmRv\n"
45 "=yku6\n"
46 "-----END PGP SIGNATURE-----\n"
47 #elif 0
48 "-----BEGIN PGP SIGNATURE-----\n"
49 "Version: GnuPG v1.0.4-2 (GNU/Linux)\n"
50 "Comment: For info see http://www.gnupg.org\n"
51 "\n"
52 "iJcEABECAFcFAjoS8/E1FIAAAAAACAAkZm9vYmFyLjF0aGlzIGlzIGEgbm90YXRp\n"
53 "b24gZGF0YSB3aXRoIDIgbGluZXMaGmh0dHA6Ly93d3cuZ3Uub3JnL3BvbGljeS8A\n"
54 "CgkQLXJ8x2hpdzQLyQCbBW/fgU8ZeWSlWPM1F8umHX17bAAAoIfSNDSp5zM85XcG\n"
55 "iwxMrf+u8v4r\n"
56 "=88Zo\n"
57 "-----END PGP SIGNATURE-----\n"
58 #elif 1
59 "-----BEGIN PGP SIGNATURE-----\n"
60 "\n"
61 "iN0EABECAJ0FAjoS+i9FFIAAAAAAAwA5YmFyw7bDpMO8w58gZGFzIHdhcmVuIFVt\n"
62 "bGF1dGUgdW5kIGpldHp0IGVpbiBwcm96ZW50JS1aZWljaGVuNRSAAAAAAAgAJGZv\n"
63 "b2Jhci4xdGhpcyBpcyBhIG5vdGF0aW9uIGRhdGEgd2l0aCAyIGxpbmVzGhpodHRw\n"
64 "Oi8vd3d3Lmd1Lm9yZy9wb2xpY3kvAAoJEC1yfMdoaXc0JBIAoIiLlUsvpMDOyGEc\n"
65 "dADGKXF/Hcb+AKCJWPphZCphduxSvrzH0hgzHdeQaA==\n"
66 "=nts1\n"
67 "-----END PGP SIGNATURE-----\n"
68 #endif
69 ;
70 static const char test_sig2[] =
71 "-----BEGIN PGP MESSAGE-----\n"
72 "\n"
73 "owGbwMvMwCSoW1RzPCOz3IRxjXQSR0lqcYleSUWJTZOvjVdpcYmCu1+oQmaJIleH\n"
74 "GwuDIBMDGysTSIqBi1MApi+nlGGuwDeHao53HBr+FoVGP3xX+kvuu9fCMJvl6IOf\n"
75 "y1kvP4y+8D5a11ang0udywsA\n"
76 "=Crq6\n"
77 "-----END PGP MESSAGE-----\n";
78
79 /* A message with a prepended but unsigned plaintext packet. */
80 static const char double_plaintext_sig[] =
81 "-----BEGIN PGP MESSAGE-----\n"
82 "\n"
83 "rDRiCmZvb2Jhci50eHRF4pxNVGhpcyBpcyBteSBzbmVha3kgcGxhaW50ZXh0IG1l\n"
84 "c3NhZ2UKowGbwMvMwCSoW1RzPCOz3IRxTWISa6JebnG666MFD1wzSzJSixQ81XMV\n"
85 "UlITUxTyixRyKxXKE0uSMxQyEosVikvyCwpSU/S4FNCArq6Ce1F+aXJGvoJvYlGF\n"
86 "erFCTmJxiUJ5flFKMVeHGwuDIBMDGysTyA4GLk4BmO036xgWzMgzt9V85jCtfDFn\n"
87 "UqVooWlGXHwNw/xg/fVzt9VNbtjtJ/fhUqYo0/LyCGEA\n"
88 "=6+AK\n"
89 "-----END PGP MESSAGE-----\n";
90
91
92
93
94 static void
95 check_result (gpgme_verify_result_t result, unsigned int summary,
96               const char *fpr,
97               gpgme_error_t status, int notation)
98 {
99   gpgme_signature_t sig;
100
101   sig = result->signatures;
102   if (!sig || sig->next)
103     {
104       fprintf (stderr, "%s:%i: Unexpected number of signatures\n",
105                __FILE__, __LINE__);
106       exit (1);
107     }
108   if (sig->summary != summary)
109     {
110       fprintf (stderr, "%s:%i: Unexpected signature summary: "
111                "want=0x%x have=0x%x\n",
112                __FILE__, __LINE__, summary, sig->summary);
113       exit (1);
114     }
115   if (strcmp (sig->fpr, fpr))
116     {
117       fprintf (stderr, "%s:%i: Unexpected fingerprint: %s\n",
118                __FILE__, __LINE__, sig->fpr);
119       exit (1);
120     }
121   if (gpgme_err_code (sig->status) != status)
122     {
123       fprintf (stderr, "%s:%i: Unexpected signature status: %s\n",
124                __FILE__, __LINE__, gpgme_strerror (sig->status));
125       exit (1);
126     }
127   if (notation)
128     {
129       static struct {
130         const char *name;
131         const char *value;
132         int seen;
133       } expected_notations[] = {
134         { "bar",
135           "\xc3\xb6\xc3\xa4\xc3\xbc\xc3\x9f"
136           " das waren Umlaute und jetzt ein prozent%-Zeichen" },
137         { "foobar.1",
138           "this is a notation data with 2 lines" },
139         { NULL,
140           "http://www.gu.org/policy/" }
141       };
142       int i;
143       gpgme_sig_notation_t r;
144
145       for (i=0; i < DIM(expected_notations); i++ )
146         expected_notations[i].seen = 0;
147
148       for (r = sig->notations; r; r = r->next)
149         {
150           int any = 0;
151           for (i=0; i < DIM(expected_notations); i++)
152             {
153               if ( ((r->name && expected_notations[i].name
154                      && !strcmp (r->name, expected_notations[i].name)
155                      && r->name_len
156                      == strlen (expected_notations[i].name))
157                     || (!r->name && !expected_notations[i].name
158                         && r->name_len == 0))
159                    && r->value
160                    && !strcmp (r->value, expected_notations[i].value)
161                    && r->value_len == strlen (expected_notations[i].value))
162                 {
163                   expected_notations[i].seen++;
164                   any++;
165                 }
166             }
167           if (!any)
168             {
169               fprintf (stderr, "%s:%i: Unexpected notation data\n",
170                        __FILE__, __LINE__);
171               exit (1);
172             }
173         }
174       for (i=0; i < DIM(expected_notations); i++ )
175         {
176           if (expected_notations[i].seen != 1)
177             {
178               fprintf (stderr, "%s:%i: Missing or duplicate notation data\n",
179                        __FILE__, __LINE__);
180               exit (1);
181             }
182         }
183     }
184   if (sig->wrong_key_usage)
185     {
186       fprintf (stderr, "%s:%i: Unexpectedly wrong key usage\n",
187                __FILE__, __LINE__);
188       exit (1);
189     }
190   if (sig->validity != GPGME_VALIDITY_UNKNOWN)
191     {
192       fprintf (stderr, "%s:%i: Unexpected validity: %i\n",
193                __FILE__, __LINE__, sig->validity);
194       exit (1);
195     }
196   if (gpgme_err_code (sig->validity_reason) != GPG_ERR_NO_ERROR)
197     {
198       fprintf (stderr, "%s:%i: Unexpected validity reason: %s\n",
199                __FILE__, __LINE__, gpgme_strerror (sig->validity_reason));
200       exit (1);
201     }
202 }
203
204
205 int
206 main (int argc, char *argv[])
207 {
208   gpgme_ctx_t ctx;
209   gpgme_error_t err;
210   gpgme_data_t sig, text;
211   gpgme_verify_result_t result;
212   const char *s;
213
214   (void)argc;
215   (void)argv;
216
217   init_gpgme (GPGME_PROTOCOL_OpenPGP);
218
219   err = gpgme_new (&ctx);
220   fail_if_err (err);
221
222   /* Checking a valid message.  */
223   err = gpgme_data_new_from_mem (&text, test_text1, strlen (test_text1), 0);
224   fail_if_err (err);
225   err = gpgme_data_new_from_mem (&sig, test_sig1, strlen (test_sig1), 0);
226   fail_if_err (err);
227   err = gpgme_op_verify (ctx, sig, text, NULL);
228   fail_if_err (err);
229   result = gpgme_op_verify_result (ctx);
230   check_result (result, 0, "A0FF4590BB6122EDEF6E3C542D727CC768697734",
231                 GPG_ERR_NO_ERROR, 1);
232
233   /* Checking a manipulated message.  */
234   gpgme_data_release (text);
235   err = gpgme_data_new_from_mem (&text, test_text1f, strlen (test_text1f), 0);
236   fail_if_err (err);
237   gpgme_data_seek (sig, 0, SEEK_SET);
238   err = gpgme_op_verify (ctx, sig, text, NULL);
239   fail_if_err (err);
240   result = gpgme_op_verify_result (ctx);
241   check_result (result, GPGME_SIGSUM_RED, "2D727CC768697734",
242                 GPG_ERR_BAD_SIGNATURE, 0);
243
244   /* Checking a normal signature.  */
245   gpgme_data_release (sig);
246   gpgme_data_release (text);
247   err = gpgme_data_new_from_mem (&sig, test_sig2, strlen (test_sig2), 0);
248   fail_if_err (err);
249   err = gpgme_data_new (&text);
250   fail_if_err (err);
251   err = gpgme_op_verify (ctx, sig, NULL, text);
252   fail_if_err (err);
253   result = gpgme_op_verify_result (ctx);
254   check_result (result, 0, "A0FF4590BB6122EDEF6E3C542D727CC768697734",
255                 GPG_ERR_NO_ERROR, 0);
256
257
258   /* Checking an invalid message.  */
259   gpgme_data_release (sig);
260   gpgme_data_release (text);
261   err = gpgme_data_new_from_mem (&sig, double_plaintext_sig,
262                                  strlen (double_plaintext_sig), 0);
263   fail_if_err (err);
264   err = gpgme_data_new (&text);
265   fail_if_err (err);
266   err = gpgme_op_verify (ctx, sig, NULL, text);
267   if (gpgme_err_code (err) != GPG_ERR_BAD_DATA)
268     {
269       fprintf (stderr, "%s:%i: Double plaintext message not detected\n",
270                __FILE__, __LINE__);
271       exit (1);
272     }
273
274   /* Checking that set/get_sernder works.  */
275   err = gpgme_set_sender (ctx, "foo@example.org");
276   fail_if_err (err);
277   s = gpgme_get_sender (ctx);
278   if (!s || strcmp (s, "foo@example.org"))
279     {
280       fprintf (stderr, "%s:%i: gpgme_{set,get}_sender mismatch\n",
281                __FILE__, __LINE__);
282       exit (1);
283     }
284
285   err = gpgme_set_sender (ctx, "<bar@example.org>");
286   fail_if_err (err);
287   s = gpgme_get_sender (ctx);
288   if (!s || strcmp (s, "bar@example.org"))
289     {
290       fprintf (stderr, "%s:%i: gpgme_{set,get}_sender mismatch\n",
291                __FILE__, __LINE__);
292       exit (1);
293     }
294
295   err = gpgme_set_sender (ctx, "Foo bar (comment) <foo@example.org>");
296   fail_if_err (err);
297   s = gpgme_get_sender (ctx);
298   if (!s || strcmp (s, "foo@example.org"))
299     {
300       fprintf (stderr, "%s:%i: gpgme_{set,get}_sender mismatch\n",
301                __FILE__, __LINE__);
302       exit (1);
303     }
304
305   err = gpgme_set_sender (ctx, "foo");
306   if (gpgme_err_code (err) != GPG_ERR_INV_VALUE)
307     {
308       fprintf (stderr, "%s:%i: gpgme_set_sender didn't detect bogus address\n",
309                __FILE__, __LINE__);
310       exit (1);
311     }
312   /* (the former address should still be there.)  */
313   s = gpgme_get_sender (ctx);
314   if (!s || strcmp (s, "foo@example.org"))
315     {
316       fprintf (stderr, "%s:%i: gpgme_{set,get}_sender mismatch\n",
317                __FILE__, __LINE__);
318       exit (1);
319     }
320
321
322   gpgme_data_release (sig);
323   gpgme_data_release (text);
324   gpgme_release (ctx);
325   return 0;
326 }