core: Extend decryption result with symkey_algo.
[gpgme.git] / tests / run-decrypt.c
1 /* run-decrypt.c  - Helper to perform a verify operation
2    Copyright (C) 2009 g10 Code GmbH
3                  2016 by Bundesamt für Sicherheit in der Informationstechnik
4                  Software engineering by Intevation GmbH
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://www.gnu.org/licenses/>.
20 */
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 #define PGM "run-decrypt"
35
36 #include "run-support.h"
37
38
39 static int verbose;
40
41 static gpg_error_t
42 status_cb (void *opaque, const char *keyword, const char *value)
43 {
44   (void)opaque;
45   fprintf (stderr, "status_cb: %s %s\n", keyword, value);
46   return 0;
47 }
48
49
50 static void
51 print_result (gpgme_decrypt_result_t result)
52 {
53   gpgme_recipient_t recp;
54   int count = 0;
55
56   printf ("Original file name: %s\n", nonnull(result->file_name));
57   printf ("Wrong key usage: %i\n", result->wrong_key_usage);
58   printf ("Unsupported algorithm: %s\n",
59           nonnull(result->unsupported_algorithm));
60   if (result->session_key)
61     printf ("Session key: %s\n", result->session_key);
62   printf ("Symmetric algorithm: %s\n", result->symkey_algo);
63
64   for (recp = result->recipients; recp && recp->next; recp = recp->next)
65     {
66       printf ("recipient %d\n", count++);
67       printf ("  status ....: %s\n", gpgme_strerror (recp->status));
68       printf ("  keyid: %s\n", nonnull (recp->keyid));
69       printf ("  algo ...: %s\n", gpgme_pubkey_algo_name (recp->pubkey_algo));
70     }
71 }
72
73
74 static int
75 show_usage (int ex)
76 {
77   fputs ("usage: " PGM " [options] FILE\n\n"
78          "Options:\n"
79          "  --verbose        run in verbose mode\n"
80          "  --status         print status lines from the backend\n"
81          "  --openpgp        use the OpenPGP protocol (default)\n"
82          "  --cms            use the CMS protocol\n"
83          "  --export-session-key            show the session key\n"
84          "  --override-session-key STRING   use STRING as session key\n"
85          "  --request-origin STRING         use STRING as request origin\n"
86          "  --no-symkey-cache               disable the use of that cache\n"
87          "  --unwrap         remove only the encryption layer\n"
88          , stderr);
89   exit (ex);
90 }
91
92
93 int
94 main (int argc, char **argv)
95 {
96   int last_argc = -1;
97   gpgme_error_t err;
98   gpgme_ctx_t ctx;
99   gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
100   gpgme_decrypt_flags_t flags = 0;
101   FILE *fp_in = NULL;
102   gpgme_data_t in = NULL;
103   gpgme_data_t out = NULL;
104   gpgme_decrypt_result_t result;
105   int print_status = 0;
106   int export_session_key = 0;
107   const char *override_session_key = NULL;
108   const char *request_origin = NULL;
109   int no_symkey_cache = 0;
110   int raw_output = 0;
111
112   if (argc)
113     { argc--; argv++; }
114
115   while (argc && last_argc != argc )
116     {
117       last_argc = argc;
118       if (!strcmp (*argv, "--"))
119         {
120           argc--; argv++;
121           break;
122         }
123       else if (!strcmp (*argv, "--help"))
124         show_usage (0);
125       else if (!strcmp (*argv, "--verbose"))
126         {
127           verbose = 1;
128           argc--; argv++;
129         }
130       else if (!strcmp (*argv, "--status"))
131         {
132           print_status = 1;
133           argc--; argv++;
134         }
135       else if (!strcmp (*argv, "--openpgp"))
136         {
137           protocol = GPGME_PROTOCOL_OpenPGP;
138           argc--; argv++;
139         }
140       else if (!strcmp (*argv, "--cms"))
141         {
142           protocol = GPGME_PROTOCOL_CMS;
143           argc--; argv++;
144         }
145       else if (!strcmp (*argv, "--export-session-key"))
146         {
147           export_session_key = 1;
148           argc--; argv++;
149         }
150       else if (!strcmp (*argv, "--override-session-key"))
151         {
152           argc--; argv++;
153           if (!argc)
154             show_usage (1);
155           override_session_key = *argv;
156           argc--; argv++;
157         }
158       else if (!strcmp (*argv, "--request-origin"))
159         {
160           argc--; argv++;
161           if (!argc)
162             show_usage (1);
163           request_origin = *argv;
164           argc--; argv++;
165         }
166       else if (!strcmp (*argv, "--no-symkey-cache"))
167         {
168           no_symkey_cache = 1;
169           argc--; argv++;
170         }
171       else if (!strcmp (*argv, "--unwrap"))
172         {
173           flags |= GPGME_DECRYPT_UNWRAP;
174           raw_output = 1;
175           argc--; argv++;
176         }
177       else if (!strncmp (*argv, "--", 2))
178         show_usage (1);
179
180     }
181
182   if (argc < 1 || argc > 2)
183     show_usage (1);
184
185   fp_in = fopen (argv[0], "rb");
186   if (!fp_in)
187     {
188       err = gpgme_error_from_syserror ();
189       fprintf (stderr, PGM ": can't open `%s': %s\n",
190                argv[0], gpgme_strerror (err));
191       exit (1);
192     }
193
194   init_gpgme (protocol);
195
196   err = gpgme_new (&ctx);
197   fail_if_err (err);
198   gpgme_set_protocol (ctx, protocol);
199   if (print_status)
200     {
201       gpgme_set_status_cb (ctx, status_cb, NULL);
202       gpgme_set_ctx_flag (ctx, "full-status", "1");
203     }
204   if (export_session_key)
205     {
206       err = gpgme_set_ctx_flag (ctx, "export-session-key", "1");
207       if (err)
208         {
209           fprintf (stderr, PGM ": error requesting exported session key: %s\n",
210                    gpgme_strerror (err));
211           exit (1);
212         }
213     }
214   if (override_session_key)
215     {
216       err = gpgme_set_ctx_flag (ctx, "override-session-key",
217                                 override_session_key);
218       if (err)
219         {
220           fprintf (stderr, PGM ": error setting overriding session key: %s\n",
221                    gpgme_strerror (err));
222           exit (1);
223         }
224     }
225
226   if (request_origin)
227     {
228       err = gpgme_set_ctx_flag (ctx, "request-origin", request_origin);
229       if (err)
230         {
231           fprintf (stderr, PGM ": error setting request_origin: %s\n",
232                    gpgme_strerror (err));
233           exit (1);
234         }
235     }
236
237   if (no_symkey_cache)
238     {
239       err = gpgme_set_ctx_flag (ctx, "no-symkey-cache", "1");
240       if (err)
241         {
242           fprintf (stderr, PGM ": error setting no-symkey-cache:  %s\n",
243                    gpgme_strerror (err));
244           exit (1);
245         }
246     }
247
248   err = gpgme_data_new_from_stream (&in, fp_in);
249   if (err)
250     {
251       fprintf (stderr, PGM ": error allocating data object: %s\n",
252                gpgme_strerror (err));
253       exit (1);
254     }
255
256   err = gpgme_data_new (&out);
257   if (err)
258     {
259       fprintf (stderr, PGM ": error allocating data object: %s\n",
260                gpgme_strerror (err));
261       exit (1);
262     }
263
264   err = gpgme_op_decrypt_ext (ctx, flags, in, out);
265   result = gpgme_op_decrypt_result (ctx);
266   if (err)
267     {
268       fprintf (stderr, PGM ": decrypt failed: %s\n", gpgme_strerror (err));
269       exit (1);
270     }
271   if (result)
272     {
273       if (!raw_output)
274         print_result (result);
275       if (!raw_output)
276         fputs ("Begin Output:\n", stdout);
277       print_data (out);
278       if (!raw_output)
279         fputs ("End Output.\n", stdout);
280     }
281
282   gpgme_data_release (out);
283   gpgme_data_release (in);
284
285   gpgme_release (ctx);
286   return 0;
287 }