doc/
[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
80 static void
81 check_result (gpgme_verify_result_t result, unsigned int summary, char *fpr,
82               gpgme_error_t status, int notation)
83 {
84   gpgme_signature_t sig;
85
86   sig = result->signatures;
87   if (!sig || sig->next)
88     {
89       fprintf (stderr, "%s:%i: Unexpected number of signatures\n",
90                __FILE__, __LINE__);
91       exit (1);
92     }
93   if (sig->summary != summary)
94     {
95       fprintf (stderr, "%s:%i: Unexpected signature summary: "
96                "want=0x%x have=0x%x\n",
97                __FILE__, __LINE__, summary, sig->summary);
98       exit (1);
99     }
100   if (strcmp (sig->fpr, fpr))
101     {
102       fprintf (stderr, "%s:%i: Unexpected fingerprint: %s\n",
103                __FILE__, __LINE__, sig->fpr);
104       exit (1);
105     }
106   if (gpg_err_code (sig->status) != status)
107     {
108       fprintf (stderr, "%s:%i: Unexpected signature status: %s\n",
109                __FILE__, __LINE__, gpg_strerror (sig->status));
110       exit (1);
111     }
112   if (notation)
113     {
114       static struct {
115         const char *name;
116         const char *value;
117         int seen;
118       } expected_notations[] = {
119         { "bar",
120           "\xc3\xb6\xc3\xa4\xc3\xbc\xc3\x9f"
121           " das waren Umlaute und jetzt ein prozent%-Zeichen" },
122         { "foobar.1",
123           "this is a notation data with 2 lines" },
124         { NULL, 
125           "http://www.gu.org/policy/" }
126       };
127       int i;
128       gpgme_sig_notation_t r;
129
130       for (i=0; i < DIM(expected_notations); i++ )
131         expected_notations[i].seen = 0;
132
133       for (r = sig->notations; r; r = r->next)
134         {
135           int any = 0;
136           for (i=0; i < DIM(expected_notations); i++)
137             {
138               if ( ((r->name && expected_notations[i].name
139                      && !strcmp (r->name, expected_notations[i].name)
140                      && r->name_len
141                      == strlen (expected_notations[i].name))
142                     || (!r->name && !expected_notations[i].name
143                         && r->name_len == 0))
144                    && r->value
145                    && !strcmp (r->value, expected_notations[i].value)
146                    && r->value_len == strlen (expected_notations[i].value))
147                 {
148                   expected_notations[i].seen++;
149                   any++;
150                 }
151             }
152           if (!any)
153             {
154               fprintf (stderr, "%s:%i: Unexpected notation data\n",
155                        __FILE__, __LINE__);
156               exit (1);
157             }
158         }
159       for (i=0; i < DIM(expected_notations); i++ )
160         {
161           if (expected_notations[i].seen != 1)
162             {
163               fprintf (stderr, "%s:%i: Missing or duplicate notation data\n",
164                        __FILE__, __LINE__);
165               exit (1);
166             }
167         }
168     }
169   if (sig->wrong_key_usage)
170     {
171       fprintf (stderr, "%s:%i: Unexpectedly wrong key usage\n",
172                __FILE__, __LINE__);
173       exit (1);
174     }
175   if (sig->validity != GPGME_VALIDITY_UNKNOWN)
176     {
177       fprintf (stderr, "%s:%i: Unexpected validity: %i\n",
178                __FILE__, __LINE__, sig->validity);
179       exit (1);
180     }
181   if (gpg_err_code (sig->validity_reason) != GPG_ERR_NO_ERROR)
182     {
183       fprintf (stderr, "%s:%i: Unexpected validity reason: %s\n",
184                __FILE__, __LINE__, gpgme_strerror (sig->validity_reason));
185       exit (1);
186     }
187 }
188
189
190 int 
191 main (int argc, char *argv[])
192 {
193   gpgme_ctx_t ctx;
194   gpgme_error_t err;
195   gpgme_data_t sig, text;
196   gpgme_verify_result_t result;
197
198   init_gpgme (GPGME_PROTOCOL_OpenPGP);
199
200   err = gpgme_new (&ctx);
201   fail_if_err (err);
202
203   /* Checking a valid message.  */
204   err = gpgme_data_new_from_mem (&text, test_text1, strlen (test_text1), 0);
205   fail_if_err (err);
206   err = gpgme_data_new_from_mem (&sig, test_sig1, strlen (test_sig1), 0);
207   fail_if_err (err);
208   err = gpgme_op_verify (ctx, sig, text, NULL);
209   fail_if_err (err);
210   result = gpgme_op_verify_result (ctx);
211   check_result (result, 0, "A0FF4590BB6122EDEF6E3C542D727CC768697734",
212                 GPG_ERR_NO_ERROR, 1);
213
214   /* Checking a manipulated message.  */
215   gpgme_data_release (text);
216   err = gpgme_data_new_from_mem (&text, test_text1f, strlen (test_text1f), 0);
217   fail_if_err (err);
218   gpgme_data_seek (sig, 0, SEEK_SET);
219   err = gpgme_op_verify (ctx, sig, text, NULL);
220   fail_if_err (err);
221   result = gpgme_op_verify_result (ctx);
222   check_result (result, GPGME_SIGSUM_RED, "2D727CC768697734",
223                 GPG_ERR_BAD_SIGNATURE, 0);
224
225   /* Checking a normal signature.  */
226   gpgme_data_release (sig);
227   gpgme_data_release (text);
228   err = gpgme_data_new_from_mem (&sig, test_sig2, strlen (test_sig2), 0);
229   fail_if_err (err);
230   err = gpgme_data_new (&text);
231   fail_if_err (err);
232   err = gpgme_op_verify (ctx, sig, NULL, text);
233   fail_if_err (err);
234   result = gpgme_op_verify_result (ctx);
235   check_result (result, 0, "A0FF4590BB6122EDEF6E3C542D727CC768697734",
236                 GPG_ERR_NO_ERROR, 0);
237
238   gpgme_data_release (sig);
239   gpgme_data_release (text);
240   gpgme_release (ctx);
241   return 0;
242 }