1 /* encrypt-sign.c - encrypt and verify functions
2 * Copyright (C) 2000 Werner Koch (dd9jn)
3 * Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH
4 *
5 * This file is part of GPGME.
6 *
7 * GPGME is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * GPGME is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, see <https://gnu.org/licenses/>.
19 * SPDX-License-Identifier: LGPL-2.1-or-later
20 */
21
22 #if HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
28
29 #include "gpgme.h"
30 #include "debug.h"
31 #include "context.h"
32 #include "ops.h"
33
34
35 static gpgme_error_t
encrypt_sign_status_handler(void * priv,gpgme_status_code_t code,char * args)36 encrypt_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
37 {
38 gpgme_error_t err;
39
40 err = _gpgme_progress_status_handler (priv, code, args);
41 if (!err)
42 err = _gpgme_encrypt_status_handler (priv, code, args);
43 if (!err)
44 err = _gpgme_sign_status_handler (priv, code, args);
45 return err;
46 }
47
48
49 static gpgme_error_t
encrypt_sym_status_handler(void * priv,gpgme_status_code_t code,char * args)50 encrypt_sym_status_handler (void *priv, gpgme_status_code_t code, char *args)
51 {
52 gpgme_error_t err;
53
54 err = _gpgme_progress_status_handler (priv, code, args);
55 if (!err)
56 err = _gpgme_sign_status_handler (priv, code, args);
57 if (!err)
58 err = _gpgme_passphrase_status_handler (priv, code, args);
59 return err;
60 }
61
62
63 static gpgme_error_t
encrypt_sign_start(gpgme_ctx_t ctx,int synchronous,gpgme_key_t recp[],const char * recpstring,gpgme_encrypt_flags_t flags,gpgme_data_t plain,gpgme_data_t cipher)64 encrypt_sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
65 const char *recpstring,
66 gpgme_encrypt_flags_t flags,
67 gpgme_data_t plain, gpgme_data_t cipher)
68 {
69 gpgme_error_t err;
70 int symmetric;
71
72 err = _gpgme_op_reset (ctx, synchronous);
73 if (err)
74 return err;
75
76 symmetric = (!recp && !recpstring) || (flags & GPGME_ENCRYPT_SYMMETRIC);
77
78 if (!plain)
79 return gpg_error (GPG_ERR_NO_DATA);
80 if (!cipher)
81 return gpg_error (GPG_ERR_INV_VALUE);
82 if (recp && !*recp)
83 return gpg_error (GPG_ERR_INV_VALUE);
84
85 err = _gpgme_op_encrypt_init_result (ctx);
86 if (err)
87 return err;
88
89 err = _gpgme_op_sign_init_result (ctx);
90 if (err)
91 return err;
92
93 if (ctx->passphrase_cb)
94 {
95 err = _gpgme_engine_set_command_handler
96 (ctx->engine, _gpgme_passphrase_command_handler, ctx);
97 if (err)
98 return err;
99 }
100
101 _gpgme_engine_set_status_handler (ctx->engine,
102 symmetric
103 ? encrypt_sym_status_handler
104 : encrypt_sign_status_handler,
105 ctx);
106
107 return _gpgme_engine_op_encrypt_sign (ctx->engine, recp, recpstring,
108 flags, plain,
109 cipher, ctx->use_armor,
110 ctx /* FIXME */);
111 }
112
113
114 /* Old version of gpgme_op_encrypt_sign_ext_start w/o RECPSTRING. */
115 gpgme_error_t
gpgme_op_encrypt_sign_start(gpgme_ctx_t ctx,gpgme_key_t recp[],gpgme_encrypt_flags_t flags,gpgme_data_t plain,gpgme_data_t cipher)116 gpgme_op_encrypt_sign_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
117 gpgme_encrypt_flags_t flags,
118 gpgme_data_t plain, gpgme_data_t cipher)
119 {
120 return gpgme_op_encrypt_sign_ext_start (ctx, recp, NULL,
121 flags, plain, cipher);
122 }
123
124
125 /* Old version of gpgme_op_encrypt_sign_ext w/o RECPSTRING. */
126 gpgme_error_t
gpgme_op_encrypt_sign(gpgme_ctx_t ctx,gpgme_key_t recp[],gpgme_encrypt_flags_t flags,gpgme_data_t plain,gpgme_data_t cipher)127 gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
128 gpgme_encrypt_flags_t flags,
129 gpgme_data_t plain, gpgme_data_t cipher)
130 {
131 return gpgme_op_encrypt_sign_ext (ctx, recp, NULL, flags, plain, cipher);
132 }
133
134
135 /* Encrypt plaintext PLAIN within CTX for the recipients RECP and
136 * store the resulting ciphertext in CIPHER. Also sign the ciphertext
137 * with the signers in CTX. */
138 gpgme_error_t
gpgme_op_encrypt_sign_ext(gpgme_ctx_t ctx,gpgme_key_t recp[],const char * recpstring,gpgme_encrypt_flags_t flags,gpgme_data_t plain,gpgme_data_t cipher)139 gpgme_op_encrypt_sign_ext (gpgme_ctx_t ctx, gpgme_key_t recp[],
140 const char *recpstring,
141 gpgme_encrypt_flags_t flags,
142 gpgme_data_t plain, gpgme_data_t cipher)
143 {
144 gpgme_error_t err;
145
146 TRACE_BEG (DEBUG_CTX, "gpgme_op_encrypt_sign", ctx,
147 "flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher);
148
149 if (!ctx)
150 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
151
152 if (_gpgme_debug_trace () && (recp || recpstring))
153 {
154 if (recp)
155 {
156 int i = 0;
157
158 while (recp[i])
159 {
160 TRACE_LOG ("recipient[%i] = %p (%s)", i, recp[i],
161 (recp[i]->subkeys && recp[i]->subkeys->fpr) ?
162 recp[i]->subkeys->fpr : "invalid");
163 i++;
164 }
165 }
166 else
167 {
168 TRACE_LOG ("recipients = '%s'", recpstring);
169 }
170 }
171
172 err = encrypt_sign_start (ctx, 1, recp, recpstring, flags, plain, cipher);
173 if (!err)
174 err = _gpgme_wait_one (ctx);
175 return TRACE_ERR (err);
176 }
177
178
179 /* Encrypt plaintext PLAIN within CTX for the recipients RECP and
180 store the resulting ciphertext in CIPHER. Also sign the ciphertext
181 with the signers in CTX. */
182 gpgme_error_t
gpgme_op_encrypt_sign_ext_start(gpgme_ctx_t ctx,gpgme_key_t recp[],const char * recpstring,gpgme_encrypt_flags_t flags,gpgme_data_t plain,gpgme_data_t cipher)183 gpgme_op_encrypt_sign_ext_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
184 const char *recpstring,
185 gpgme_encrypt_flags_t flags,
186 gpgme_data_t plain, gpgme_data_t cipher)
187 {
188 gpgme_error_t err;
189
190 TRACE_BEG (DEBUG_CTX, "gpgme_op_encrypt_sign_start", ctx,
191 "flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher);
192
193 if (!ctx)
194 return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
195
196 if (_gpgme_debug_trace () && (recp || recpstring))
197 {
198 if (recp)
199 {
200 int i = 0;
201
202 while (recp[i])
203 {
204 TRACE_LOG ("recipient[%i] = %p (%s)", i, recp[i],
205 (recp[i]->subkeys && recp[i]->subkeys->fpr) ?
206 recp[i]->subkeys->fpr : "invalid");
207 i++;
208 }
209 }
210 else
211 {
212 TRACE_LOG ("recipients = '%s'", recpstring);
213 }
214 }
215
216 err = encrypt_sign_start (ctx, 0, recp, recpstring, flags, plain, cipher);
217 return err;
218 }
219