core: Add support for mixed symmetric and asym enc
[gpgme.git] / tests / run-encrypt.c
1 /* run-encrypt.c  - Helper to perform an encrypt operation
2  * Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
18  */
19
20 /* We need to include config.h so that we know whether we are building
21    with large file system (LFS) support. */
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 #include <gpgme.h>
31
32 #define PGM "run-encrypt"
33
34 #include "run-support.h"
35
36
37 static int verbose;
38
39 static gpg_error_t
40 status_cb (void *opaque, const char *keyword, const char *value)
41 {
42   (void)opaque;
43   printf ("status_cb: %s %s\n", keyword, value);
44   return 0;
45 }
46
47
48 static void
49 print_result (gpgme_encrypt_result_t result)
50 {
51   gpgme_invalid_key_t invkey;
52
53   for (invkey = result->invalid_recipients; invkey; invkey = invkey->next)
54     printf ("Encryption key `%s' not used: %s <%s>\n",
55             nonnull (invkey->fpr),
56             gpg_strerror (invkey->reason), gpg_strsource (invkey->reason));
57 }
58
59
60
61 static int
62 show_usage (int ex)
63 {
64   fputs ("usage: " PGM " [options] FILE\n\n"
65          "Options:\n"
66          "  --verbose        run in verbose mode\n"
67          "  --status         print status lines from the backend\n"
68          "  --openpgp        use the OpenPGP protocol (default)\n"
69          "  --cms            use the CMS protocol\n"
70          "  --uiserver       use the UI server\n"
71          "  --loopback       use a loopback pinentry\n"
72          "  --key NAME       encrypt to key NAME\n"
73          "  --symmetric      encrypt symmetric (OpenPGP only)\n"
74          , stderr);
75   exit (ex);
76 }
77
78
79 int
80 main (int argc, char **argv)
81 {
82   int last_argc = -1;
83   gpgme_error_t err;
84   gpgme_ctx_t ctx;
85   const char *key_string = NULL;
86   gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
87   gpgme_data_t in, out;
88   gpgme_encrypt_result_t result;
89   int print_status = 0;
90   int use_loopback = 0;
91   char *keyargs[10];
92   gpgme_key_t keys[10+1];
93   int keycount = 0;
94   int i;
95   gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST;
96
97   if (argc)
98     { argc--; argv++; }
99
100   if (DIM(keys) != DIM(keyargs)+1)
101     abort ();
102
103   while (argc && last_argc != argc )
104     {
105       last_argc = argc;
106       if (!strcmp (*argv, "--"))
107         {
108           argc--; argv++;
109           break;
110         }
111       else if (!strcmp (*argv, "--help"))
112         show_usage (0);
113       else if (!strcmp (*argv, "--verbose"))
114         {
115           verbose = 1;
116           argc--; argv++;
117         }
118       else if (!strcmp (*argv, "--status"))
119         {
120           print_status = 1;
121           argc--; argv++;
122         }
123       else if (!strcmp (*argv, "--openpgp"))
124         {
125           protocol = GPGME_PROTOCOL_OpenPGP;
126           argc--; argv++;
127         }
128       else if (!strcmp (*argv, "--cms"))
129         {
130           protocol = GPGME_PROTOCOL_CMS;
131           argc--; argv++;
132         }
133       else if (!strcmp (*argv, "--uiserver"))
134         {
135           protocol = GPGME_PROTOCOL_UISERVER;
136           argc--; argv++;
137         }
138       else if (!strcmp (*argv, "--key"))
139         {
140           argc--; argv++;
141           if (!argc)
142             show_usage (1);
143           if (keycount == DIM (keyargs))
144             show_usage (1);
145           keyargs[keycount++] = *argv;
146           argc--; argv++;
147         }
148       else if (!strcmp (*argv, "--loopback"))
149         {
150           use_loopback = 1;
151           argc--; argv++;
152         }
153       else if (!strcmp (*argv, "--symmetric"))
154         {
155           flags |= GPGME_ENCRYPT_SYMMETRIC;
156           argc--; argv++;
157         }
158       else if (!strncmp (*argv, "--", 2))
159         show_usage (1);
160
161     }
162
163   if (argc != 1)
164     show_usage (1);
165
166   if (key_string && protocol == GPGME_PROTOCOL_UISERVER)
167     {
168       fprintf (stderr, PGM ": ignoring --key in UI-server mode\n");
169       key_string = NULL;
170     }
171
172   if (!key_string)
173     key_string = "test";
174
175   init_gpgme (protocol);
176
177   err = gpgme_new (&ctx);
178   fail_if_err (err);
179   gpgme_set_protocol (ctx, protocol);
180   gpgme_set_armor (ctx, 1);
181   if (print_status)
182     gpgme_set_status_cb (ctx, status_cb, NULL);
183   if (use_loopback)
184     {
185       gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_LOOPBACK);
186       gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);
187     }
188
189   for (i=0; i < keycount; i++)
190     {
191       err = gpgme_get_key (ctx, keyargs[i], &keys[i], 0);
192       fail_if_err (err);
193     }
194   keys[i] = NULL;
195
196   err = gpgme_data_new_from_file (&in, *argv, 1);
197   if (err)
198     {
199       fprintf (stderr, PGM ": error reading `%s': %s\n",
200                *argv, gpg_strerror (err));
201       exit (1);
202     }
203
204   err = gpgme_data_new (&out);
205   fail_if_err (err);
206
207   err = gpgme_op_encrypt (ctx, keycount ? keys : NULL, flags, in, out);
208   result = gpgme_op_encrypt_result (ctx);
209   if (result)
210     print_result (result);
211   if (err)
212     {
213       fprintf (stderr, PGM ": encrypting failed: %s\n", gpg_strerror (err));
214       exit (1);
215     }
216
217   fputs ("Begin Output:\n", stdout);
218   print_data (out);
219   fputs ("End Output.\n", stdout);
220   gpgme_data_release (out);
221
222   gpgme_data_release (in);
223
224   for (i=0; i < keycount; i++)
225     gpgme_key_unref (keys[i]);
226   gpgme_release (ctx);
227   return 0;
228 }