f4c475440a08506821040f139af5caf2ed58ad7a
[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->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          "  --unwrap         remove only the encryption layer\n"
86          , stderr);
87   exit (ex);
88 }
89
90
91 int
92 main (int argc, char **argv)
93 {
94   int last_argc = -1;
95   gpgme_error_t err;
96   gpgme_ctx_t ctx;
97   gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
98   gpgme_decrypt_flags_t flags = 0;
99   FILE *fp_in = NULL;
100   gpgme_data_t in = NULL;
101   gpgme_data_t out = NULL;
102   gpgme_decrypt_result_t result;
103   int print_status = 0;
104   int export_session_key = 0;
105   const char *override_session_key = NULL;
106   const char *request_origin = NULL;
107   int raw_output = 0;
108
109   if (argc)
110     { argc--; argv++; }
111
112   while (argc && last_argc != argc )
113     {
114       last_argc = argc;
115       if (!strcmp (*argv, "--"))
116         {
117           argc--; argv++;
118           break;
119         }
120       else if (!strcmp (*argv, "--help"))
121         show_usage (0);
122       else if (!strcmp (*argv, "--verbose"))
123         {
124           verbose = 1;
125           argc--; argv++;
126         }
127       else if (!strcmp (*argv, "--status"))
128         {
129           print_status = 1;
130           argc--; argv++;
131         }
132       else if (!strcmp (*argv, "--openpgp"))
133         {
134           protocol = GPGME_PROTOCOL_OpenPGP;
135           argc--; argv++;
136         }
137       else if (!strcmp (*argv, "--cms"))
138         {
139           protocol = GPGME_PROTOCOL_CMS;
140           argc--; argv++;
141         }
142       else if (!strcmp (*argv, "--export-session-key"))
143         {
144           export_session_key = 1;
145           argc--; argv++;
146         }
147       else if (!strcmp (*argv, "--override-session-key"))
148         {
149           argc--; argv++;
150           if (!argc)
151             show_usage (1);
152           override_session_key = *argv;
153           argc--; argv++;
154         }
155       else if (!strcmp (*argv, "--request-origin"))
156         {
157           argc--; argv++;
158           if (!argc)
159             show_usage (1);
160           request_origin = *argv;
161           argc--; argv++;
162         }
163       else if (!strcmp (*argv, "--unwrap"))
164         {
165           flags |= GPGME_DECRYPT_UNWRAP;
166           raw_output = 1;
167           argc--; argv++;
168         }
169       else if (!strncmp (*argv, "--", 2))
170         show_usage (1);
171
172     }
173
174   if (argc < 1 || argc > 2)
175     show_usage (1);
176
177   fp_in = fopen (argv[0], "rb");
178   if (!fp_in)
179     {
180       err = gpgme_error_from_syserror ();
181       fprintf (stderr, PGM ": can't open `%s': %s\n",
182                argv[0], gpgme_strerror (err));
183       exit (1);
184     }
185
186   init_gpgme (protocol);
187
188   err = gpgme_new (&ctx);
189   fail_if_err (err);
190   gpgme_set_protocol (ctx, protocol);
191   if (print_status)
192     {
193       gpgme_set_status_cb (ctx, status_cb, NULL);
194       gpgme_set_ctx_flag (ctx, "full-status", "1");
195     }
196   if (export_session_key)
197     {
198       err = gpgme_set_ctx_flag (ctx, "export-session-key", "1");
199       if (err)
200         {
201           fprintf (stderr, PGM ": error requesting exported session key: %s\n",
202                    gpgme_strerror (err));
203           exit (1);
204         }
205     }
206   if (override_session_key)
207     {
208       err = gpgme_set_ctx_flag (ctx, "override-session-key",
209                                 override_session_key);
210       if (err)
211         {
212           fprintf (stderr, PGM ": error setting overriding session key: %s\n",
213                    gpgme_strerror (err));
214           exit (1);
215         }
216     }
217
218   if (request_origin)
219     {
220       err = gpgme_set_ctx_flag (ctx, "request-origin", request_origin);
221       if (err)
222         {
223           fprintf (stderr, PGM ": error setting request_origin: %s\n",
224                    gpgme_strerror (err));
225           exit (1);
226         }
227     }
228
229   err = gpgme_data_new_from_stream (&in, fp_in);
230   if (err)
231     {
232       fprintf (stderr, PGM ": error allocating data object: %s\n",
233                gpgme_strerror (err));
234       exit (1);
235     }
236
237   err = gpgme_data_new (&out);
238   if (err)
239     {
240       fprintf (stderr, PGM ": error allocating data object: %s\n",
241                gpgme_strerror (err));
242       exit (1);
243     }
244
245   err = gpgme_op_decrypt_ext (ctx, flags, in, out);
246   result = gpgme_op_decrypt_result (ctx);
247   if (err)
248     {
249       fprintf (stderr, PGM ": decrypt failed: %s\n", gpgme_strerror (err));
250       exit (1);
251     }
252   if (result)
253     {
254       if (!raw_output)
255         print_result (result);
256       if (!raw_output)
257         fputs ("Begin Output:\n", stdout);
258       print_data (out);
259       if (!raw_output)
260         fputs ("End Output.\n", stdout);
261     }
262
263   gpgme_data_release (out);
264   gpgme_data_release (in);
265
266   gpgme_release (ctx);
267   return 0;
268 }