Line data Source code
1 : /* run-sign.c - Helper to perform a sign operation
2 : Copyright (C) 2009 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 <https://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-sign"
33 :
34 : #include "run-support.h"
35 :
36 :
37 : static int verbose;
38 :
39 : static gpg_error_t
40 0 : status_cb (void *opaque, const char *keyword, const char *value)
41 : {
42 : (void)opaque;
43 0 : printf ("status_cb: %s %s\n", keyword, value);
44 0 : return 0;
45 : }
46 :
47 :
48 : static void
49 0 : print_result (gpgme_sign_result_t result, gpgme_sig_mode_t type)
50 : {
51 : gpgme_invalid_key_t invkey;
52 : gpgme_new_signature_t sig;
53 :
54 : (void)type;
55 :
56 0 : for (invkey = result->invalid_signers; invkey; invkey = invkey->next)
57 0 : printf ("Signing key `%s' not used: %s <%s>\n",
58 0 : nonnull (invkey->fpr),
59 : gpg_strerror (invkey->reason), gpg_strsource (invkey->reason));
60 :
61 0 : for (sig = result->signatures; sig; sig = sig->next)
62 : {
63 0 : printf ("Key fingerprint: %s\n", nonnull (sig->fpr));
64 0 : printf ("Signature type : %d\n", sig->type);
65 0 : printf ("Public key algo: %d\n", sig->pubkey_algo);
66 0 : printf ("Hash algo .....: %d\n", sig->hash_algo);
67 0 : printf ("Creation time .: %ld\n", sig->timestamp);
68 0 : printf ("Sig class .....: 0x%u\n", sig->sig_class);
69 : }
70 0 : }
71 :
72 :
73 :
74 : static int
75 0 : show_usage (int ex)
76 : {
77 0 : 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 : " --uiserver use the UI server\n"
84 : " --loopback use a loopback pinentry\n"
85 : " --key NAME use key NAME for signing\n"
86 : " --sender MBOX use MBOX as sender address\n"
87 : , stderr);
88 0 : exit (ex);
89 : }
90 :
91 :
92 : int
93 0 : main (int argc, char **argv)
94 : {
95 0 : int last_argc = -1;
96 : gpgme_error_t err;
97 : gpgme_ctx_t ctx;
98 0 : const char *key_string = NULL;
99 0 : gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
100 0 : gpgme_sig_mode_t sigmode = GPGME_SIG_MODE_NORMAL;
101 : gpgme_data_t in, out;
102 : gpgme_sign_result_t result;
103 0 : int print_status = 0;
104 0 : int use_loopback = 0;
105 0 : const char *sender = NULL;
106 : const char *s;
107 :
108 0 : if (argc)
109 0 : { argc--; argv++; }
110 :
111 0 : while (argc && last_argc != argc )
112 : {
113 0 : last_argc = argc;
114 0 : if (!strcmp (*argv, "--"))
115 : {
116 0 : argc--; argv++;
117 0 : break;
118 : }
119 0 : else if (!strcmp (*argv, "--help"))
120 0 : show_usage (0);
121 0 : else if (!strcmp (*argv, "--verbose"))
122 : {
123 0 : verbose = 1;
124 0 : argc--; argv++;
125 : }
126 0 : else if (!strcmp (*argv, "--status"))
127 : {
128 0 : print_status = 1;
129 0 : argc--; argv++;
130 : }
131 0 : else if (!strcmp (*argv, "--openpgp"))
132 : {
133 0 : protocol = GPGME_PROTOCOL_OpenPGP;
134 0 : argc--; argv++;
135 : }
136 0 : else if (!strcmp (*argv, "--cms"))
137 : {
138 0 : protocol = GPGME_PROTOCOL_CMS;
139 0 : argc--; argv++;
140 : }
141 0 : else if (!strcmp (*argv, "--uiserver"))
142 : {
143 0 : protocol = GPGME_PROTOCOL_UISERVER;
144 0 : argc--; argv++;
145 : }
146 0 : else if (!strcmp (*argv, "--key"))
147 : {
148 0 : argc--; argv++;
149 0 : if (!argc)
150 0 : show_usage (1);
151 0 : key_string = *argv;
152 0 : argc--; argv++;
153 : }
154 0 : else if (!strcmp (*argv, "--sender"))
155 : {
156 0 : argc--; argv++;
157 0 : if (!argc)
158 0 : show_usage (1);
159 0 : sender = *argv;
160 0 : argc--; argv++;
161 : }
162 0 : else if (!strcmp (*argv, "--loopback"))
163 : {
164 0 : use_loopback = 1;
165 0 : argc--; argv++;
166 : }
167 0 : else if (!strncmp (*argv, "--", 2))
168 0 : show_usage (1);
169 :
170 : }
171 :
172 0 : if (argc != 1)
173 0 : show_usage (1);
174 :
175 0 : if (key_string && protocol == GPGME_PROTOCOL_UISERVER)
176 : {
177 0 : fprintf (stderr, PGM ": ignoring --key in UI-server mode\n");
178 0 : key_string = NULL;
179 : }
180 :
181 0 : init_gpgme (protocol);
182 :
183 0 : err = gpgme_new (&ctx);
184 0 : fail_if_err (err);
185 0 : gpgme_set_protocol (ctx, protocol);
186 0 : gpgme_set_armor (ctx, 1);
187 0 : if (print_status)
188 0 : gpgme_set_status_cb (ctx, status_cb, NULL);
189 0 : if (use_loopback)
190 0 : gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_LOOPBACK);
191 :
192 0 : if (key_string)
193 : {
194 : gpgme_key_t akey;
195 :
196 0 : err = gpgme_get_key (ctx, key_string, &akey, 1);
197 0 : if (err)
198 : {
199 0 : exit (1);
200 : }
201 0 : err = gpgme_signers_add (ctx, akey);
202 0 : fail_if_err (err);
203 0 : gpgme_key_unref (akey);
204 : }
205 :
206 0 : if (sender)
207 : {
208 0 : err = gpgme_set_sender (ctx, sender);
209 0 : fail_if_err (err);
210 : }
211 :
212 0 : err = gpgme_data_new_from_file (&in, *argv, 1);
213 0 : if (err)
214 : {
215 0 : fprintf (stderr, PGM ": error reading `%s': %s\n",
216 : *argv, gpg_strerror (err));
217 0 : exit (1);
218 : }
219 :
220 0 : err = gpgme_data_new (&out);
221 0 : fail_if_err (err);
222 :
223 0 : err = gpgme_op_sign (ctx, in, out, sigmode);
224 0 : result = gpgme_op_sign_result (ctx);
225 0 : if (result)
226 0 : print_result (result, sigmode);
227 0 : if (err)
228 : {
229 0 : fprintf (stderr, PGM ": signing failed: %s\n", gpg_strerror (err));
230 0 : exit (1);
231 : }
232 :
233 0 : if ((s = gpgme_get_ctx_flag (ctx, "redraw")) && *s)
234 0 : fputs ("Screen redraw suggested\n", stdout);
235 :
236 0 : fputs ("Begin Output:\n", stdout);
237 0 : print_data (out);
238 0 : fputs ("End Output.\n", stdout);
239 0 : gpgme_data_release (out);
240 :
241 0 : gpgme_data_release (in);
242 :
243 0 : gpgme_release (ctx);
244 0 : return 0;
245 : }
|