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