421ddbcbe8368383d0ab8045f96cabfba2b1865d
[gpgme.git] / gpgme / decrypt.c
1 /* decrypt.c -  decrypt functions
2  *      Copyright (C) 2000 Werner Koch (dd9jn)
3  *      Copyright (C) 2001, 2002 g10 Code GmbH
4  *
5  * This file is part of GPGME.
6  *
7  * GPGME is free software; you can redistribute it and/or modify
8  * it 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.
11  *
12  * GPGME is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <assert.h>
27
28 #include "util.h"
29 #include "context.h"
30 #include "ops.h"
31
32
33 struct decrypt_result_s
34 {
35   int okay;
36   int failed;
37 };
38
39
40 void
41 _gpgme_release_decrypt_result (DecryptResult result)
42 {
43   if (!result)
44     return;
45   xfree (result);
46 }
47
48
49 void
50 _gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
51 {
52   _gpgme_passphrase_status_handler (ctx, code, args);
53
54   if (ctx->error)
55     return;
56   test_and_allocate_result (ctx, decrypt);
57
58   switch (code)
59     {
60     case STATUS_EOF:
61       if (ctx->result.decrypt->failed)
62         ctx->error = mk_error (Decryption_Failed);
63       else if (!ctx->result.decrypt->okay)
64         ctx->error = mk_error (No_Data);
65       break;
66
67     case STATUS_DECRYPTION_OKAY:
68       ctx->result.decrypt->okay = 1;
69       break;
70
71     case STATUS_DECRYPTION_FAILED:
72       ctx->result.decrypt->failed = 1;
73       break;
74         
75     default:
76       /* Ignore all other codes.  */
77       break;
78     }
79 }
80
81
82 GpgmeError
83 _gpgme_decrypt_start (GpgmeCtx ctx, int synchronous,
84                       GpgmeData ciph, GpgmeData plain, void *status_handler)
85 {
86   GpgmeError err = 0;
87
88   err = _gpgme_op_reset (ctx, synchronous);
89   if (err)
90     goto leave;
91
92   /* Check the supplied data.  */
93   if (!ciph || gpgme_data_get_type (ciph) == GPGME_DATA_TYPE_NONE)
94     {
95       err = mk_error (No_Data);
96       goto leave;
97     }
98   _gpgme_data_set_mode (ciph, GPGME_DATA_MODE_OUT);
99
100   if (gpgme_data_get_type (plain) != GPGME_DATA_TYPE_NONE)
101     {
102       err = mk_error (Invalid_Value);
103       goto leave;
104     }
105   _gpgme_data_set_mode (plain, GPGME_DATA_MODE_IN);
106
107   err = _gpgme_passphrase_start (ctx);
108   if (err)
109     goto leave;
110
111   _gpgme_engine_set_status_handler (ctx->engine, status_handler, ctx);
112   _gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
113
114   err = _gpgme_engine_op_decrypt (ctx->engine, ciph, plain);
115
116   if (!err)     /* And kick off the process.  */
117     err = _gpgme_engine_start (ctx->engine, ctx);
118
119  leave:
120   if (err)
121     {
122       ctx->pending = 0; 
123       _gpgme_engine_release (ctx->engine);
124       ctx->engine = NULL;
125     }
126   return err;
127 }
128
129
130 GpgmeError
131 gpgme_op_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain)
132 {
133   return _gpgme_decrypt_start (ctx, 0, ciph, plain,
134                                _gpgme_decrypt_status_handler);
135 }
136
137
138 /**
139  * gpgme_op_decrypt:
140  * @ctx: The context
141  * @in: ciphertext input
142  * @out: plaintext output
143  * 
144  * This function decrypts @in to @out.
145  * Other parameters are take from the context @ctx.
146  * The function does wait for the result.
147  * 
148  * Return value:  0 on success or an errorcode. 
149  **/
150 GpgmeError
151 gpgme_op_decrypt (GpgmeCtx ctx, GpgmeData in, GpgmeData out)
152 {
153   GpgmeError err = _gpgme_decrypt_start (ctx, 1, in, out,
154                                          _gpgme_decrypt_status_handler);
155   if (!err)
156     err = _gpgme_wait_one (ctx);
157   return err;
158 }