core: Add 'is_mime' flags to the verify and decrypt results.
[gpgme.git] / src / encrypt-sign.c
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, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, USA.  */
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 \f
35 static gpgme_error_t
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
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
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, NULL);
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
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
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
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_BEG3 (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_LOG3 ("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_LOG1 ("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
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_BEG3 (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_LOG3 ("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_LOG1 ("recipients = '%s'", recpstring);
213         }
214     }
215
216   err = encrypt_sign_start (ctx, 0, recp, recpstring, flags, plain, cipher);
217   return err;
218 }