1 /* encrypt.c - Encrypt function.
2 Copyright (C) 2000 Werner Koch (dd9jn)
3 Copyright (C) 2001, 2002, 2003 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 General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (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 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GPGME; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
35 struct _gpgme_op_encrypt_result result;
37 /* A pointer to the next pointer of the last invalid recipient in
38 the list. This makes appending new invalid recipients painless
39 while preserving the order. */
40 gpgme_invalid_key_t *lastp;
45 release_op_data (void *hook)
47 op_data_t opd = (op_data_t) hook;
48 gpgme_invalid_key_t invalid_recipient = opd->result.invalid_recipients;
50 while (invalid_recipient)
52 gpgme_invalid_key_t next = invalid_recipient->next;
53 if (invalid_recipient->fpr)
54 free (invalid_recipient->fpr);
55 invalid_recipient = next;
60 gpgme_encrypt_result_t
61 gpgme_op_encrypt_result (gpgme_ctx_t ctx)
67 err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, &hook, -1, NULL);
78 _gpgme_encrypt_status_handler (void *priv, gpgme_status_code_t code,
81 gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
86 err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, &hook, -1, NULL);
93 case GPGME_STATUS_EOF:
94 if (opd->result.invalid_recipients)
95 return gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
98 case GPGME_STATUS_INV_RECP:
99 err = _gpgme_parse_inv_recp (args, opd->lastp);
103 opd->lastp = &(*opd->lastp)->next;
106 case GPGME_STATUS_NO_RECP:
107 /* Should not happen, because we require at least one recipient. */
108 return gpg_error (GPG_ERR_GENERAL);
118 encrypt_sym_status_handler (void *priv, gpgme_status_code_t code, char *args)
122 err = _gpgme_progress_status_handler (priv, code, args);
124 err = _gpgme_passphrase_status_handler (priv, code, args);
130 encrypt_status_handler (void *priv, gpgme_status_code_t code, char *args)
132 return _gpgme_progress_status_handler (priv, code, args)
133 || _gpgme_encrypt_status_handler (priv, code, args);
138 _gpgme_op_encrypt_init_result (gpgme_ctx_t ctx)
144 err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, &hook, sizeof (*opd),
150 opd->lastp = &opd->result.invalid_recipients;
156 encrypt_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[],
157 gpgme_encrypt_flags_t flags,
158 gpgme_data_t plain, gpgme_data_t cipher)
163 err = _gpgme_op_reset (ctx, synchronous);
167 err = _gpgme_op_encrypt_init_result (ctx);
175 return gpg_error (GPG_ERR_NO_DATA);
177 return gpg_error (GPG_ERR_INV_VALUE);
179 return gpg_error (GPG_ERR_INV_VALUE);
181 if (symmetric && ctx->passphrase_cb)
183 /* Symmetric encryption requires a passphrase. */
184 err = _gpgme_engine_set_command_handler
185 (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
190 _gpgme_engine_set_status_handler (ctx->engine,
192 ? encrypt_sym_status_handler
193 : encrypt_status_handler,
196 return _gpgme_engine_op_encrypt (ctx->engine, recp, flags, plain, cipher,
202 gpgme_op_encrypt_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
203 gpgme_encrypt_flags_t flags,
204 gpgme_data_t plain, gpgme_data_t cipher)
206 return encrypt_start (ctx, 0, recp, flags, plain, cipher);
210 /* Encrypt plaintext PLAIN within CTX for the recipients RECP and
211 store the resulting ciphertext in CIPHER. */
213 gpgme_op_encrypt (gpgme_ctx_t ctx, gpgme_key_t recp[],
214 gpgme_encrypt_flags_t flags,
215 gpgme_data_t plain, gpgme_data_t cipher)
217 gpgme_error_t err = encrypt_start (ctx, 1, recp, flags, plain, cipher);
219 err = _gpgme_wait_one (ctx);