tests: Fix version comparison.
[gpgme.git] / tests / gpg / t-sig-notation.c
1 /* t-sig-notation.c - Regression test.
2    Copyright (C) 2005 g10 Code GmbH
3
4    This file is part of GPGME.
5  
6    GPGME is free software; you can redistribute it and/or modify it
7    under the terms of the GNU Lesser General Public License as
8    published by the Free Software Foundation; either version 2.1 of
9    the License, or (at your option) any later version.
10    
11    GPGME is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15    
16    You should have received a copy of the GNU Lesser General Public
17    License along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19    02111-1307, USA.  */
20
21 /* We need to include config.h so that we know whether we are building
22    with large file system (LFS) support. */
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <assert.h>
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
38 /* GnuPG prior to 2.1.13 did not report the critical flag
39    correctly.  */
40 int have_correct_sig_data;
41
42 static struct {
43   const char *name;
44   const char *value;
45   gpgme_sig_notation_flags_t flags;
46   int seen;
47 } expected_notations[] = { 
48   { "laughing@me",
49     "Just Squeeze Me",
50     GPGME_SIG_NOTATION_HUMAN_READABLE },
51   { "preferred-email-encoding@pgp.com",
52     "pgpmime",
53     GPGME_SIG_NOTATION_HUMAN_READABLE | GPGME_SIG_NOTATION_CRITICAL },
54   { NULL, 
55     "http://www.gnu.org/policy/",
56     0 }
57 };
58
59 static void
60 check_result (gpgme_verify_result_t result)
61 {
62   int i;
63   gpgme_sig_notation_t r;
64   
65   gpgme_signature_t sig;
66
67   sig = result->signatures;
68   if (!sig || sig->next)
69     {
70       fprintf (stderr, "%s:%i: Unexpected number of signatures\n",
71                __FILE__, __LINE__);
72       exit (1);
73     }
74
75   for (i=0; i < DIM(expected_notations); i++ )
76     expected_notations[i].seen = 0;
77   
78   for (r = result->signatures->notations; r; r = r->next)
79     {
80       int any = 0;
81       for (i=0; i < DIM(expected_notations); i++)
82         {
83           if ( ((r->name && expected_notations[i].name
84                  && !strcmp (r->name, expected_notations[i].name)
85                  && r->name_len
86                  == strlen (expected_notations[i].name))
87                 || (!r->name && !expected_notations[i].name
88                     && r->name_len == 0))
89                && r->value
90                && !strcmp (r->value, expected_notations[i].value)
91                && r->value_len == strlen (expected_notations[i].value)
92                && r->flags
93                   == (have_correct_sig_data
94                       ? expected_notations[i].flags
95                       : expected_notations[i].flags
96                         & ~GPGME_SIG_NOTATION_CRITICAL)
97                && r->human_readable
98                == !!(r->flags & GPGME_SIG_NOTATION_HUMAN_READABLE)
99                && r->critical
100                   == (have_correct_sig_data
101                       ? !!(r->flags & GPGME_SIG_NOTATION_CRITICAL)
102                       : 0))
103             {
104               expected_notations[i].seen++;
105               any++;
106             }
107         }
108       if (!any)
109         {
110           fprintf (stderr, "%s:%i: Unexpected notation data\n",
111                    __FILE__, __LINE__);
112           exit (1);
113         }
114     }
115   for (i=0; i < DIM(expected_notations); i++ )
116     {
117       if (expected_notations[i].seen != 1)
118         {
119           fprintf (stderr, "%s:%i: Missing or duplicate notation data\n",
120                    __FILE__, __LINE__);
121           exit (1);
122         }
123     }
124 }
125
126
127 int 
128 main (int argc, char *argv[])
129 {
130   gpgme_ctx_t ctx;
131   gpgme_error_t err;
132   gpgme_data_t in, out;
133   gpgme_verify_result_t result;
134   char *agent_info;
135   int i;
136   gpgme_engine_info_t engine_info;
137
138   init_gpgme (GPGME_PROTOCOL_OpenPGP);
139
140   err = gpgme_get_engine_info (&engine_info);
141   fail_if_err (err);
142   for (; engine_info; engine_info = engine_info->next)
143     if (engine_info->protocol == GPGME_PROTOCOL_OpenPGP)
144       break;
145   assert (engine_info);
146
147   /* GnuPG prior to 2.1.13 did not report the critical flag
148      correctly.  */
149   have_correct_sig_data =
150     ! (strncmp ("1.", engine_info->version, 2) == 0
151        || (strncmp ("2.1.1", engine_info->version, 5) == 0
152            && (engine_info->version[5] == 0
153                || engine_info->version[5] < '3')));
154
155   err = gpgme_new (&ctx);
156   fail_if_err (err);
157
158   agent_info = getenv ("GPG_AGENT_INFO");
159   if (!(agent_info && strchr (agent_info, ':')))
160     gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);
161
162   err = gpgme_data_new_from_mem (&in, "Hallo Leute\n", 12, 0);
163   fail_if_err (err);
164   err = gpgme_data_new (&out);
165   fail_if_err (err);
166
167   for (i = 0; i < sizeof (expected_notations) / sizeof (expected_notations[0]);
168        i++)
169     {
170       err = gpgme_sig_notation_add (ctx, expected_notations[i].name,
171                                     expected_notations[i].value,
172                                     expected_notations[i].flags);
173       fail_if_err (err);
174     }
175   
176   err = gpgme_op_sign (ctx, in, out, GPGME_SIG_MODE_NORMAL);
177   fail_if_err (err);
178
179   gpgme_data_release (in);
180   err = gpgme_data_new (&in);
181   fail_if_err (err);
182
183   gpgme_data_seek (out, 0, SEEK_SET);
184
185   err = gpgme_op_verify (ctx, out, NULL, in);
186   fail_if_err (err);
187   result = gpgme_op_verify_result (ctx);
188   check_result (result);
189
190   gpgme_data_release (in);
191   gpgme_data_release (out);
192   gpgme_release (ctx);
193   return 0;
194 }