Imported Upstream version 1.14.0
[platform/upstream/gpgme.git] / tests / run-sign.c
1 /* run-sign.c  - Helper to perform a sign operation
2  * Copyright (C) 2009 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, see <https://gnu.org/licenses/>.
18  * SPDX-License-Identifier: LGPL-2.1-or-later
19  */
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 <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 #include <gpgme.h>
32
33 #define PGM "run-sign"
34
35 #include "run-support.h"
36
37
38 static int verbose;
39
40 static gpg_error_t
41 status_cb (void *opaque, const char *keyword, const char *value)
42 {
43   (void)opaque;
44   printf ("status_cb: %s %s\n", keyword, value);
45   return 0;
46 }
47
48
49 static void
50 print_result (gpgme_sign_result_t result, gpgme_sig_mode_t type)
51 {
52   gpgme_invalid_key_t invkey;
53   gpgme_new_signature_t sig;
54
55   (void)type;
56
57   for (invkey = result->invalid_signers; invkey; invkey = invkey->next)
58     printf ("Signing key `%s' not used: %s <%s>\n",
59             nonnull (invkey->fpr),
60             gpg_strerror (invkey->reason), gpg_strsource (invkey->reason));
61
62   for (sig = result->signatures; sig; sig = sig->next)
63     {
64       printf ("Key fingerprint: %s\n", nonnull (sig->fpr));
65       printf ("Signature type : %d\n", sig->type);
66       printf ("Public key algo: %d\n", sig->pubkey_algo);
67       printf ("Hash algo .....: %d\n", sig->hash_algo);
68       printf ("Creation time .: %ld\n", sig->timestamp);
69       printf ("Sig class .....: 0x%u\n", sig->sig_class);
70     }
71 }
72
73
74
75 static int
76 show_usage (int ex)
77 {
78   fputs ("usage: " PGM " [options] FILE\n\n"
79          "Options:\n"
80          "  --verbose        run in verbose mode\n"
81          "  --status         print status lines from the backend\n"
82          "  --openpgp        use the OpenPGP protocol (default)\n"
83          "  --cms            use the CMS protocol\n"
84          "  --uiserver       use the UI server\n"
85          "  --loopback       use a loopback pinentry\n"
86          "  --key NAME       use key NAME for signing\n"
87          "  --sender MBOX    use MBOX as sender address\n"
88          "  --include-key-block  use this option with gpg\n"
89          , stderr);
90   exit (ex);
91 }
92
93
94 int
95 main (int argc, char **argv)
96 {
97   int last_argc = -1;
98   gpgme_error_t err;
99   gpgme_ctx_t ctx;
100   const char *key_string = NULL;
101   gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
102   gpgme_sig_mode_t sigmode = GPGME_SIG_MODE_NORMAL;
103   gpgme_data_t in, out;
104   gpgme_sign_result_t result;
105   int print_status = 0;
106   int use_loopback = 0;
107   int include_key_block = 0;
108   const char *sender = NULL;
109   const char *s;
110
111   if (argc)
112     { argc--; argv++; }
113
114   while (argc && last_argc != argc )
115     {
116       last_argc = argc;
117       if (!strcmp (*argv, "--"))
118         {
119           argc--; argv++;
120           break;
121         }
122       else if (!strcmp (*argv, "--help"))
123         show_usage (0);
124       else if (!strcmp (*argv, "--verbose"))
125         {
126           verbose = 1;
127           argc--; argv++;
128         }
129       else if (!strcmp (*argv, "--status"))
130         {
131           print_status = 1;
132           argc--; argv++;
133         }
134       else if (!strcmp (*argv, "--openpgp"))
135         {
136           protocol = GPGME_PROTOCOL_OpenPGP;
137           argc--; argv++;
138         }
139       else if (!strcmp (*argv, "--cms"))
140         {
141           protocol = GPGME_PROTOCOL_CMS;
142           argc--; argv++;
143         }
144       else if (!strcmp (*argv, "--uiserver"))
145         {
146           protocol = GPGME_PROTOCOL_UISERVER;
147           argc--; argv++;
148         }
149       else if (!strcmp (*argv, "--key"))
150         {
151           argc--; argv++;
152           if (!argc)
153             show_usage (1);
154           key_string = *argv;
155           argc--; argv++;
156         }
157       else if (!strcmp (*argv, "--sender"))
158         {
159           argc--; argv++;
160           if (!argc)
161             show_usage (1);
162           sender = *argv;
163           argc--; argv++;
164         }
165       else if (!strcmp (*argv, "--loopback"))
166         {
167           use_loopback = 1;
168           argc--; argv++;
169         }
170       else if (!strcmp (*argv, "--include-key-block"))
171         {
172           include_key_block = 1;
173           argc--; argv++;
174         }
175       else if (!strncmp (*argv, "--", 2))
176         show_usage (1);
177
178     }
179
180   if (argc != 1)
181     show_usage (1);
182
183   if (key_string && protocol == GPGME_PROTOCOL_UISERVER)
184     {
185       fprintf (stderr, PGM ": ignoring --key in UI-server mode\n");
186       key_string = NULL;
187     }
188
189   init_gpgme (protocol);
190
191   err = gpgme_new (&ctx);
192   fail_if_err (err);
193   gpgme_set_protocol (ctx, protocol);
194   gpgme_set_armor (ctx, 1);
195   if (print_status)
196     gpgme_set_status_cb (ctx, status_cb, NULL);
197   if (use_loopback)
198     gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_LOOPBACK);
199
200   if (key_string)
201     {
202       gpgme_key_t akey;
203
204       err = gpgme_get_key (ctx, key_string, &akey, 1);
205       if (err)
206         {
207           fprintf (stderr, PGM ": get key '%s' failed: %s\n",
208                    key_string, gpg_strerror (err));
209           exit (1);
210         }
211       err = gpgme_signers_add (ctx, akey);
212       fail_if_err (err);
213       gpgme_key_unref (akey);
214     }
215
216   if (sender)
217     {
218       err = gpgme_set_sender (ctx, sender);
219       fail_if_err (err);
220     }
221
222   if (include_key_block)
223     {
224       err = gpgme_set_ctx_flag (ctx, "include-key-block", "1");
225       if (err)
226         {
227           fprintf (stderr, PGM ": error setting include-key-block:  %s\n",
228                    gpgme_strerror (err));
229           exit (1);
230         }
231     }
232
233   err = gpgme_data_new_from_file (&in, *argv, 1);
234   if (err)
235     {
236       fprintf (stderr, PGM ": error reading `%s': %s\n",
237                *argv, gpg_strerror (err));
238       exit (1);
239     }
240
241   err = gpgme_data_new (&out);
242   fail_if_err (err);
243
244   err = gpgme_op_sign (ctx, in, out, sigmode);
245   result = gpgme_op_sign_result (ctx);
246   if (result)
247     print_result (result, sigmode);
248   if (err)
249     {
250       fprintf (stderr, PGM ": signing failed: %s\n", gpg_strerror (err));
251       exit (1);
252     }
253
254   if ((s = gpgme_get_ctx_flag (ctx, "redraw")) && *s)
255     fputs ("Screen redraw suggested\n", stdout);
256
257   fputs ("Begin Output:\n", stdout);
258   print_data (out);
259   fputs ("End Output.\n", stdout);
260   gpgme_data_release (out);
261
262   gpgme_data_release (in);
263
264   gpgme_release (ctx);
265   return 0;
266 }