1 /* encrypt.c - Encrypt function.
2 Copyright (C) 2000 Werner Koch (dd9jn)
3 Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH
5 This file is part of GPGME.
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.
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.
17 You should have received a copy of the GNU Lesser General Public
18 License along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
37 struct _gpgme_op_encrypt_result result;
39 /* A pointer to the next pointer of the last invalid recipient in
40 the list. This makes appending new invalid recipients painless
41 while preserving the order. */
42 gpgme_invalid_key_t *lastp;
47 release_op_data (void *hook)
49 op_data_t opd = (op_data_t) hook;
50 gpgme_invalid_key_t invalid_recipient = opd->result.invalid_recipients;
52 while (invalid_recipient)
54 gpgme_invalid_key_t next = invalid_recipient->next;
55 if (invalid_recipient->fpr)
56 free (invalid_recipient->fpr);
57 free (invalid_recipient);
58 invalid_recipient = next;
63 gpgme_encrypt_result_t
64 gpgme_op_encrypt_result (gpgme_ctx_t ctx)
70 TRACE_BEG (DEBUG_CTX, "gpgme_op_encrypt_result", ctx);
72 err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, &hook, -1, NULL);
77 TRACE_SUC0 ("result=(null)");
81 if (_gpgme_debug_trace ())
83 gpgme_invalid_key_t invkeys = opd->result.invalid_recipients;
88 TRACE_LOG3 ("invalid_recipients[%i] = %s (%s)",
89 i, invkeys->fpr ? invkeys->fpr : "(null)",
90 gpg_strerror (invkeys->reason));
91 invkeys = invkeys->next;
96 TRACE_SUC1 ("result=%p", &opd->result);
102 _gpgme_encrypt_status_handler (void *priv, gpgme_status_code_t code,
105 gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
110 err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, &hook, -1, NULL);
117 case GPGME_STATUS_EOF:
118 if (opd->result.invalid_recipients)
119 return gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
122 case GPGME_STATUS_INV_RECP:
123 err = _gpgme_parse_inv_recp (args, opd->lastp);
127 opd->lastp = &(*opd->lastp)->next;
130 case GPGME_STATUS_NO_RECP:
131 /* Should not happen, because we require at least one recipient. */
132 return gpg_error (GPG_ERR_GENERAL);
142 encrypt_sym_status_handler (void *priv, gpgme_status_code_t code, char *args)
146 err = _gpgme_progress_status_handler (priv, code, args);
148 err = _gpgme_passphrase_status_handler (priv, code, args);
154 encrypt_status_handler (void *priv, gpgme_status_code_t code, char *args)
156 return _gpgme_progress_status_handler (priv, code, args)
157 || _gpgme_encrypt_status_handler (priv, code, args);
162 _gpgme_op_encrypt_init_result (gpgme_ctx_t ctx)
168 err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, &hook, sizeof (*opd),
174 opd->lastp = &opd->result.invalid_recipients;
180 encrypt_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
181 gpgme_encrypt_flags_t flags,
182 gpgme_data_t plain, gpgme_data_t cipher)
187 err = _gpgme_op_reset (ctx, synchronous);
191 err = _gpgme_op_encrypt_init_result (ctx);
199 return gpg_error (GPG_ERR_NO_DATA);
201 return gpg_error (GPG_ERR_INV_VALUE);
203 return gpg_error (GPG_ERR_INV_VALUE);
205 if (symmetric && ctx->passphrase_cb)
207 /* Symmetric encryption requires a passphrase. */
208 err = _gpgme_engine_set_command_handler
209 (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
214 _gpgme_engine_set_status_handler (ctx->engine,
216 ? encrypt_sym_status_handler
217 : encrypt_status_handler,
220 return _gpgme_engine_op_encrypt (ctx->engine, recp, flags, plain, cipher,
226 gpgme_op_encrypt_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
227 gpgme_encrypt_flags_t flags,
228 gpgme_data_t plain, gpgme_data_t cipher)
230 TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt_start", ctx,
231 "flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher);
233 if (_gpgme_debug_trace () && recp)
239 TRACE_LOG3 ("recipient[%i] = %p (%s)", i,recp[i],
240 (recp[i]->subkeys && !recp[i]->subkeys->fpr) ?
241 recp[i]->subkeys->fpr : "invalid");
246 return TRACE_ERR (encrypt_start (ctx, 0, recp, flags, plain, cipher));
250 /* Encrypt plaintext PLAIN within CTX for the recipients RECP and
251 store the resulting ciphertext in CIPHER. */
253 gpgme_op_encrypt (gpgme_ctx_t ctx, gpgme_key_t recp[],
254 gpgme_encrypt_flags_t flags,
255 gpgme_data_t plain, gpgme_data_t cipher)
259 TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt", ctx,
260 "flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher);
262 if (_gpgme_debug_trace () && recp)
268 TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
269 (recp[i]->subkeys && !recp[i]->subkeys->fpr) ?
270 recp[i]->subkeys->fpr : "invalid");
275 err = encrypt_start (ctx, 1, recp, flags, plain, cipher);
277 err = _gpgme_wait_one (ctx);
278 return TRACE_ERR (err);