typo fix in comment.
[gpgme.git] / gpgme / encrypt-sign.c
1 /* encrypt-sign.c -  encrypt and verify 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 static void
34 encrypt_sign_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
35 {
36   char *encrypt_info = 0;
37   int encrypt_info_len;
38
39   _gpgme_encrypt_status_handler (ctx, code, args);
40
41   if (code == STATUS_EOF)
42     {
43       encrypt_info = gpgme_data_release_and_get_mem (ctx->op_info,
44                                                      &encrypt_info_len);
45       ctx->op_info = NULL;
46     }
47   _gpgme_sign_status_handler (ctx, code, args);
48   if (code == STATUS_EOF && encrypt_info)
49     _gpgme_data_append (ctx->op_info, encrypt_info, encrypt_info_len);
50 }
51
52
53 static GpgmeError
54 _gpgme_op_encrypt_sign_start (GpgmeCtx ctx, int synchronous,
55                               GpgmeRecipients recp,
56                               GpgmeData plain, GpgmeData cipher)
57 {
58   GpgmeError err = 0;
59
60   err = _gpgme_op_reset (ctx, synchronous);
61   if (err)
62     goto leave;
63
64   err = _gpgme_passphrase_start (ctx);
65   if (err)
66     goto leave;
67
68   _gpgme_engine_set_status_handler (ctx->engine,
69                                     encrypt_sign_status_handler, ctx);
70   _gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
71
72   /* Check the supplied data */
73   if (gpgme_data_get_type (plain) == GPGME_DATA_TYPE_NONE)
74     {
75       err = mk_error (No_Data);
76       goto leave;
77     }
78   _gpgme_data_set_mode (plain, GPGME_DATA_MODE_OUT);
79   if (!cipher || gpgme_data_get_type (cipher) != GPGME_DATA_TYPE_NONE)
80     {
81       err = mk_error (Invalid_Value);
82       goto leave;
83     }
84   _gpgme_data_set_mode (cipher, GPGME_DATA_MODE_IN);
85
86   err = _gpgme_engine_op_encrypt_sign (ctx->engine, recp, plain, cipher,
87                                        ctx->use_armor, ctx /* FIXME */);
88
89   if (!err)     /* And kick off the process.  */
90     err = _gpgme_engine_start (ctx->engine, ctx);
91
92  leave:
93   if (err)
94     {
95       ctx->pending = 0; 
96       _gpgme_engine_release (ctx->engine);
97       ctx->engine = NULL;
98     }
99   return err;
100 }
101
102 GpgmeError
103 gpgme_op_encrypt_sign_start (GpgmeCtx ctx, GpgmeRecipients recp,
104                               GpgmeData plain, GpgmeData cipher)
105 {
106   return _gpgme_op_encrypt_sign_start (ctx, 0, recp, plain, cipher);
107 }
108
109
110 /**
111  * gpgme_op_encrypt_sign:
112  * @ctx: The context
113  * @recp: The set of recipients
114  * @plain: plaintext input
115  * @cipher: signed ciphertext
116  * 
117  * This function encrypts @plain for all recipients in recp, signs it,
118  * and returns the ciphertext in @out.  The function does wait for the
119  * result.
120  * 
121  * Return value:  0 on success or an errorcode. 
122  **/
123 GpgmeError
124 gpgme_op_encrypt_sign (GpgmeCtx ctx, GpgmeRecipients recp,
125                        GpgmeData plain, GpgmeData cipher)
126 {
127   GpgmeError err = _gpgme_op_encrypt_sign_start (ctx, 1, recp, plain, cipher);
128
129   if (!err)
130     {
131       err = _gpgme_wait_one (ctx);
132       /* Old gpg versions don't return status info for invalid
133          recipients, so we simply check whether we got any output at
134          all, and if not we assume that we don't have valid
135          recipients.  */
136       if (!ctx->error && gpgme_data_get_type (cipher) == GPGME_DATA_TYPE_NONE)
137         ctx->error = mk_error (No_Recipients);
138       err = ctx->error;
139     }
140   return err;
141 }