a2e82a0e36a3cd17b0e71ff68cd26fb8296636dd
[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
63   for (recp = result->recipients; recp && recp->next; recp = recp->next)
64     {
65       printf ("recipient %d\n", count++);
66       printf ("  status ....: %s\n", gpgme_strerror (recp->status));
67       printf ("  keyid: %s\n", nonnull (recp->keyid));
68       printf ("  algo ...: %s\n", gpgme_pubkey_algo_name (recp->pubkey_algo));
69     }
70 }
71
72
73 static int
74 show_usage (int ex)
75 {
76   fputs ("usage: " PGM " [options] FILE\n\n"
77          "Options:\n"
78          "  --verbose        run in verbose mode\n"
79          "  --status         print status lines from the backend\n"
80          "  --openpgp        use the OpenPGP protocol (default)\n"
81          "  --cms            use the CMS protocol\n"
82          "  --export-session-key            show the session key\n"
83          "  --override-session-key STRING   use STRING as session key\n"
84          "  --request-origin STRING         use STRING as request origin\n"
85          "  --no-symkey-cache               disable the use of that cache\n"
86          "  --unwrap         remove only the encryption layer\n"
87          , stderr);
88   exit (ex);
89 }
90
91
92 int
93 main (int argc, char **argv)
94 {
95   int last_argc = -1;
96   gpgme_error_t err;
97   gpgme_ctx_t ctx;
98   gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
99   gpgme_decrypt_flags_t flags = 0;
100   FILE *fp_in = NULL;
101   gpgme_data_t in = NULL;
102   gpgme_data_t out = NULL;
103   gpgme_decrypt_result_t result;
104   int print_status = 0;
105   int export_session_key = 0;
106   const char *override_session_key = NULL;
107   const char *request_origin = NULL;
108   int no_symkey_cache = 0;
109   int raw_output = 0;
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, "--export-session-key"))
145         {
146           export_session_key = 1;
147           argc--; argv++;
148         }
149       else if (!strcmp (*argv, "--override-session-key"))
150         {
151           argc--; argv++;
152           if (!argc)
153             show_usage (1);
154           override_session_key = *argv;
155           argc--; argv++;
156         }
157       else if (!strcmp (*argv, "--request-origin"))
158         {
159           argc--; argv++;
160           if (!argc)
161             show_usage (1);
162           request_origin = *argv;
163           argc--; argv++;
164         }
165       else if (!strcmp (*argv, "--no-symkey-cache"))
166         {
167           no_symkey_cache = 1;
168           argc--; argv++;
169         }
170       else if (!strcmp (*argv, "--unwrap"))
171         {
172           flags |= GPGME_DECRYPT_UNWRAP;
173           raw_output = 1;
174           argc--; argv++;
175         }
176       else if (!strncmp (*argv, "--", 2))
177         show_usage (1);
178
179     }
180
181   if (argc < 1 || argc > 2)
182     show_usage (1);
183
184   fp_in = fopen (argv[0], "rb");
185   if (!fp_in)
186     {
187       err = gpgme_error_from_syserror ();
188       fprintf (stderr, PGM ": can't open `%s': %s\n",
189                argv[0], gpgme_strerror (err));
190       exit (1);
191     }
192
193   init_gpgme (protocol);
194
195   err = gpgme_new (&ctx);
196   fail_if_err (err);
197   gpgme_set_protocol (ctx, protocol);
198   if (print_status)
199     {
200       gpgme_set_status_cb (ctx, status_cb, NULL);
201       gpgme_set_ctx_flag (ctx, "full-status", "1");
202     }
203   if (export_session_key)
204     {
205       err = gpgme_set_ctx_flag (ctx, "export-session-key", "1");
206       if (err)
207         {
208           fprintf (stderr, PGM ": error requesting exported session key: %s\n",
209                    gpgme_strerror (err));
210           exit (1);
211         }
212     }
213   if (override_session_key)
214     {
215       err = gpgme_set_ctx_flag (ctx, "override-session-key",
216                                 override_session_key);
217       if (err)
218         {
219           fprintf (stderr, PGM ": error setting overriding session key: %s\n",
220                    gpgme_strerror (err));
221           exit (1);
222         }
223     }
224
225   if (request_origin)
226     {
227       err = gpgme_set_ctx_flag (ctx, "request-origin", request_origin);
228       if (err)
229         {
230           fprintf (stderr, PGM ": error setting request_origin: %s\n",
231                    gpgme_strerror (err));
232           exit (1);
233         }
234     }
235
236   if (no_symkey_cache)
237     {
238       err = gpgme_set_ctx_flag (ctx, "no-symkey-cache", "1");
239       if (err)
240         {
241           fprintf (stderr, PGM ": error setting no-symkey-cache:  %s\n",
242                    gpgme_strerror (err));
243           exit (1);
244         }
245     }
246
247   err = gpgme_data_new_from_stream (&in, fp_in);
248   if (err)
249     {
250       fprintf (stderr, PGM ": error allocating data object: %s\n",
251                gpgme_strerror (err));
252       exit (1);
253     }
254
255   err = gpgme_data_new (&out);
256   if (err)
257     {
258       fprintf (stderr, PGM ": error allocating data object: %s\n",
259                gpgme_strerror (err));
260       exit (1);
261     }
262
263   err = gpgme_op_decrypt_ext (ctx, flags, in, out);
264   result = gpgme_op_decrypt_result (ctx);
265   if (err)
266     {
267       fprintf (stderr, PGM ": decrypt failed: %s\n", gpgme_strerror (err));
268       exit (1);
269     }
270   if (result)
271     {
272       if (!raw_output)
273         print_result (result);
274       if (!raw_output)
275         fputs ("Begin Output:\n", stdout);
276       print_data (out);
277       if (!raw_output)
278         fputs ("End Output.\n", stdout);
279     }
280
281   gpgme_data_release (out);
282   gpgme_data_release (in);
283
284   gpgme_release (ctx);
285   return 0;
286 }