Imported Upstream version 1.16.0
[platform/upstream/gpgme.git] / tests / gpg / t-edit-sign.c
1 /* t-edit-sign.c - Regression test.
2  * Copyright (C) 2000 Werner Koch (dd9jn)
3  * Copyright (C) 2001, 2002, 2003, 2004, 2021 g10 Code GmbH
4  * Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
5  *
6  * This file is part of GPGME.
7  *
8  * GPGME is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as
10  * published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * GPGME is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this program; if not, see <https://gnu.org/licenses/>.
20  * SPDX-License-Identifier: LGPL-2.1-or-later
21  */
22
23 /* We need to include config.h so that we know whether we are building
24    with large file system (LFS) support. */
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <assert.h>
33 #include <errno.h>
34 #include <unistd.h>
35 #include <errno.h>
36
37 #include <gpgme.h>
38
39 #include "t-support.h"
40
41
42 static void
43 flush_data (gpgme_data_t dh)
44 {
45   char buf[100];
46   int ret;
47
48   ret = gpgme_data_seek (dh, 0, SEEK_SET);
49   if (ret)
50     fail_if_err (gpgme_error_from_errno (errno));
51   while ((ret = gpgme_data_read (dh, buf, 100)) > 0)
52     fwrite (buf, ret, 1, stdout);
53   if (ret < 0)
54     fail_if_err (gpgme_error_from_errno (errno));
55 }
56
57
58 gpgme_error_t
59 interact_fnc (void *opaque, const char *status, const char *args, int fd)
60 {
61   const char *result = NULL;
62   gpgme_data_t out = (gpgme_data_t) opaque;
63
64   fputs ("[-- Response --]\n", stdout);
65   flush_data (out);
66
67   fprintf (stdout, "[-- Code: %s, %s --]\n", status, args);
68
69   if (fd >= 0)
70     {
71       if (!strcmp (args, "keyedit.prompt"))
72         {
73           static int step = 0;
74
75           switch (step)
76             {
77             case 0:
78               result = "fpr";
79               break;
80             case 1:
81               /* This fixes the primary user ID so the keylisting
82                  tests will have predictable output.  */
83               result = "1";
84               break;
85             case 2:
86               result = "sign";
87               break;
88
89             default:
90               result = "quit";
91               break;
92             }
93           step++;
94         }
95       else if (!strcmp (args, "keyedit.save.okay"))
96         result = "Y";
97       else if (!strcmp (args, "sign_uid.okay"))
98         result = "Y";
99     }
100
101   if (result)
102     {
103       gpgme_io_writen (fd, result, strlen (result));
104       gpgme_io_writen (fd, "\n", 1);
105     }
106   return 0;
107 }
108
109
110 int
111 main (int argc, char **argv)
112 {
113   gpgme_ctx_t ctx;
114   gpgme_error_t err;
115   gpgme_data_t out = NULL;
116   const char *signer_fpr = "A0FF4590BB6122EDEF6E3C542D727CC768697734"; /* Alpha Test */
117   gpgme_key_t signing_key = NULL;
118   const char *key_fpr = "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2"; /* Bravo Test */
119   gpgme_key_t key = NULL;
120   gpgme_key_t signed_key = NULL;
121   gpgme_user_id_t signed_uid = NULL;
122   gpgme_key_sig_t key_sig = NULL;
123   char *agent_info;
124   int mode;
125
126   (void)argc;
127   (void)argv;
128
129   init_gpgme (GPGME_PROTOCOL_OpenPGP);
130
131   err = gpgme_new (&ctx);
132   fail_if_err (err);
133
134   /* Sign the key */
135   agent_info = getenv("GPG_AGENT_INFO");
136   if (!(agent_info && strchr (agent_info, ':')))
137     gpgme_set_passphrase_cb (ctx, passphrase_cb, 0);
138
139   err = gpgme_get_key (ctx, signer_fpr, &signing_key, 1);
140   fail_if_err (err);
141   err = gpgme_signers_add (ctx, signing_key);
142   fail_if_err (err);
143
144   err = gpgme_set_ctx_flag (ctx, "cert-expire", "42d");
145   fail_if_err (err);
146
147   err = gpgme_get_key (ctx, key_fpr, &key, 0);
148   fail_if_err (err);
149
150   err = gpgme_data_new (&out);
151   fail_if_err (err);
152
153   err = gpgme_op_interact (ctx, key, 0, interact_fnc, out, out);
154   fail_if_err (err);
155
156   fputs ("[-- Last response --]\n", stdout);
157   flush_data (out);
158
159   gpgme_data_release (out);
160   gpgme_key_unref (key);
161   gpgme_key_unref (signing_key);
162
163   /* Verify the key signature */
164   mode  = gpgme_get_keylist_mode (ctx);
165   mode |= GPGME_KEYLIST_MODE_SIGS;
166   err = gpgme_set_keylist_mode (ctx, mode);
167   fail_if_err (err);
168   err = gpgme_get_key (ctx, key_fpr, &signed_key, 0);
169   fail_if_err (err);
170
171   signed_uid = key->uids;
172   if (!signed_uid)
173     {
174       fprintf (stderr, "Signed key has no user IDs\n");
175       exit (1);
176     }
177   if (!signed_uid->signatures || !signed_uid->signatures->next)
178     {
179       fprintf (stderr, "Signed user ID has less signatures than expected\n");
180       exit (1);
181     }
182   key_sig = signed_uid->signatures->next;
183   if (strcmp ("2D727CC768697734", key_sig->keyid))
184     {
185       fprintf (stderr, "Unexpected key ID in second user ID sig: %s\n",
186                 key_sig->keyid);
187       exit (1);
188     }
189   if (key_sig->expires != key_sig->timestamp + 42*86400L)
190     {
191       fprintf (stderr, "Key signature unexpectedly does not expire in 42 days\n");
192       fprintf (stderr, "signature date: %ld, expiration date: %ld\n",
193                key_sig->timestamp, key_sig->expires);
194       exit (1);
195     }
196
197   gpgme_key_unref (signed_key);
198   gpgme_release (ctx);
199
200   return 0;
201 }