/[winpt]/trunk/MyGPGME/sign-encrypt.c
ViewVC logotype

Contents of /trunk/MyGPGME/sign-encrypt.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (show annotations)
Mon Apr 4 07:01:43 2005 UTC (19 years, 11 months ago) by twoaday
File MIME type: text/plain
File size: 10969 byte(s)
2005-03-22  Timo Schulz  <twoaday@freakmail.de>
                                                                                
        * editcard.c: Support new status-fd entries SC_OP_SUCCESS
        and SC_OP_FAILURE.
        * editkey.c (cmd_addrev_handler): Check if context != NULL.
        * import.c (import_command_handler): Wrong function signature.
        Noted by Kurt Fitzner.
        * types.h: Fixed encrypt_result_s. Noted by Kurt.
        * gpgme.h (gpgme_editkey_addrev_set): Changed return type.
        Kudos to Kurt.
        * key.c: Removed some unreachable code. By Kurt.
                                                                                


1 /* sign-encrypt.c - Sign & Encrypt functions
2 * Copyright (C) 2001-2004 Timo Schulz
3 *
4 * This file is part of MyGPGME.
5 *
6 * MyGPGME is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * MyGPGME is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21 #include <string.h>
22 #include <stdio.h>
23 #include <assert.h>
24
25 #include <windows.h>
26
27 #include "util.h"
28 #include "context.h"
29 #include "ops.h"
30
31 struct sign_encrypt_result_s {
32 void * last_pw_handle;
33 char * userid_hint;
34 char * passphrase_info;
35 char cardno[32+1];
36 int no_passphrase;
37 int okay;
38 int bad_passphrase;
39 int idea_cipher;
40 };
41
42
43 void
44 _gpgme_release_sign_encrypt_result( _sign_encrypt_result_t res )
45 {
46 if( res ) {
47 safe_free( res->userid_hint );
48 safe_free( res->passphrase_info );
49 safe_free( res );
50 }
51 }
52
53
54 static void
55 sign_encrypt_status_handler( gpgme_ctx_t ctx, gpg_status_code_t code, char *args )
56 {
57 char * p;
58 int i=0;
59
60 if( ctx->out_of_core )
61 return;
62
63 if( ctx->result_type == RESULT_TYPE_NONE ) {
64 assert( !ctx->result.sign_enc );
65 ctx->result.sign_enc = calloc ( 1, sizeof * ctx->result.sign_enc );
66 if( !ctx->result.sign_enc ) {
67 ctx->out_of_core = 1;
68 return;
69 }
70 ctx->result_type = RESULT_TYPE_SIGN_ENCRYPT;
71 }
72 assert( ctx->result_type == RESULT_TYPE_SIGN_ENCRYPT );
73
74 switch( code ) {
75 case STATUS_EOF:
76 break;
77
78 case STATUS_USERID_HINT:
79 safe_free( ctx->result.sign_enc->userid_hint );
80 ctx->result.sign_enc->userid_hint = strdup( args );
81 if( !ctx->result.sign_enc->userid_hint ) {
82 ctx->out_of_core = 1;
83 return;
84 }
85 break;
86
87 case STATUS_BAD_PASSPHRASE:
88 DEBUG0( "Bad passphrase - once again please\n" );
89 ctx->result.sign_enc->bad_passphrase++;
90 break;
91
92 case STATUS_GOOD_PASSPHRASE:
93 ctx->result.sign_enc->bad_passphrase = 0;
94 break;
95
96 case STATUS_RSA_OR_IDEA:
97 ctx->result.sign_enc->idea_cipher = 1;
98 break;
99
100 case STATUS_NEED_PASSPHRASE:
101 case STATUS_NEED_PASSPHRASE_SYM:
102 safe_free( ctx->result.sign_enc->passphrase_info );
103 ctx->result.sign_enc->passphrase_info = strdup( args );
104 if( !ctx->result.sign_enc->passphrase_info ) {
105 ctx->out_of_core = 1;
106 return;
107 }
108 break;
109
110 case STATUS_MISSING_PASSPHRASE:
111 DEBUG0( "missing passphrase - stop\n" );
112 ctx->result.sign_enc->no_passphrase = 1;
113 break;
114
115 case STATUS_SIG_CREATED:
116 ctx->result.sign_enc->okay = 1;
117 break;
118
119 case STATUS_PROGRESS:
120 if( ctx->cb.progress )
121 _gpgme_progress_handler( ctx, args );
122 break;
123
124 case STATUS_CARDCTRL:
125 if( args[i++] != '3' )
126 break;
127 i++;
128 p = ctx->result.sign_enc->cardno;
129 for( ; i-1 < DIM(ctx->result.sign_enc->cardno) && args[i]; i++ )
130 *p++ = args[i];
131 *p = 0;
132 break;
133
134 default:
135 break;
136 }
137 }
138
139
140 static const char*
141 command_handler( void *opqaue, gpg_status_code_t code, const char *key )
142 {
143 gpgme_ctx_t c = opqaue;
144
145 if( c->result_type == RESULT_TYPE_NONE ) {
146 assert ( !c->result.sign_enc );
147 c->result.sign_enc = calloc ( 1, sizeof *c->result.sign_enc );
148 if( !c->result.sign_enc ) {
149 c->out_of_core = 1;
150 return NULL;
151 }
152 c->result_type = RESULT_TYPE_SIGN_ENCRYPT;
153 }
154
155 if( !key || !c->cb.passphrase )
156 return NULL;
157
158 if( code == STATUS_GET_HIDDEN
159 && (!strcmp( key, "passphrase.enter" )
160 || !strcmp( key, "passphrase.pin.ask" )) ) {
161 const char * userid_hint = c->result.sign_enc->userid_hint;
162 const char * passphrase_info = c->result.sign_enc->passphrase_info;
163 const char * cardno = c->result.sign_enc->cardno;
164 int bad_passphrase = c->result.sign_enc->bad_passphrase;
165 int is_card=0;
166 char * buf;
167 const char * s;
168
169 c->result.sign_enc->bad_passphrase = 0;
170 is_card = !strcmp( key, "passphrase.pin.ask" );
171 if( !userid_hint )
172 userid_hint = "[User ID hint missing]";
173 if( !passphrase_info )
174 passphrase_info = "[passphrase info missing]";
175 buf = malloc( 20 + strlen( userid_hint )
176 + strlen( passphrase_info ) + 3 );
177 if( !buf ) {
178 c->out_of_core = 1;
179 return NULL;
180 }
181 sprintf( buf, "%s\n%s\n%s",
182 bad_passphrase? "TRY_AGAIN":"ENTER_PASSPHRASE",
183 userid_hint, passphrase_info );
184
185 s = c->cb.passphrase( c->cb.passphrase_value,
186 is_card? cardno : buf,
187 &c->result.sign_enc->last_pw_handle );
188 safe_free( buf );
189 return s;
190 }
191
192 return NULL;
193 }
194
195
196 gpgme_error_t
197 gpgme_op_sign_encrypt_start( gpgme_ctx_t ctx, gpgme_recipients_t recp,
198 gpgme_data_t plain, gpgme_data_t ciph )
199 {
200 gpgme_key_t key;
201 int rc = 0;
202 int i;
203
204 fail_on_pending_request( ctx );
205 ctx->pending = 1;
206
207 if( !gpgme_recipients_count( recp ) ) {
208 rc = mk_error( No_Recipients );
209 goto leave;
210 }
211
212 _gpgme_gpg_release( &ctx->gpg );
213 rc = _gpgme_gpg_new( &ctx->gpg );
214 if( rc )
215 goto leave;
216
217 if( ctx->use_logging )
218 _gpgme_gpg_set_logging_handler( ctx->gpg, ctx );
219 _gpgme_gpg_set_status_handler( ctx->gpg, sign_encrypt_status_handler, ctx );
220 if ( ctx->cb.passphrase ) {
221 rc = _gpgme_gpg_set_command_handler( ctx->gpg, command_handler, ctx );
222 if( rc )
223 goto leave;
224 }
225 else if( ctx->passphrase_value ) {
226 rc = _gpgme_add_passphrase( ctx );
227 if( rc )
228 goto leave;
229 }
230
231 _gpgme_gpg_add_arg( ctx->gpg, "--encrypt" );
232 _gpgme_gpg_add_arg( ctx->gpg, "--sign" );
233 if( ctx->use_armor )
234 _gpgme_gpg_add_arg( ctx->gpg, "--armor" );
235 if( ctx->cb.progress )
236 _gpgme_gpg_add_arg( ctx->gpg, "--enable-progress-filter" );
237 if( ctx->force_trust || _gpgme_recipients_all_valid( recp ) )
238 _gpgme_gpg_add_arg( ctx->gpg, "--always-trust" );
239
240 for( i = 0; (key = gpgme_signers_enum (ctx, i)); i++ ) {
241 const char * s;
242 s = gpgme_key_get_string_attr( key, GPGME_ATTR_KEYID, NULL, 0 );
243 if (s)
244 {
245 _gpgme_gpg_add_arg (ctx->gpg, "-u");
246 _gpgme_gpg_add_arg_concat (ctx->gpg, s, "!");
247 _gpgme_gpg_add_arg (ctx->gpg, "--encrypt-to");
248 _gpgme_gpg_add_arg (ctx->gpg, s);
249 }
250 gpgme_key_unref (key);
251 }
252
253 _gpgme_append_gpg_args_from_recipients( recp, ctx->gpg );
254 if( gpgme_data_get_type( plain ) == GPGME_DATA_TYPE_NONE ) {
255 rc = mk_error( No_Data );
256 goto leave;
257 }
258
259 _gpgme_data_set_mode( plain, GPGME_DATA_MODE_OUT );
260
261 if( !ciph || gpgme_data_get_type(ciph) != GPGME_DATA_TYPE_NONE ) {
262 rc = mk_error( No_Data );
263 goto leave;
264 }
265
266 _gpgme_data_set_mode( ciph, GPGME_DATA_MODE_IN );
267
268 if( ctx->use_tmpfiles ) {
269 _gpgme_gpg_add_arg ( ctx->gpg, "--output" );
270 _gpgme_gpg_add_arg ( ctx->gpg, _gpgme_get_tmpfile(0) );
271 _gpgme_data_write_to_tmpfile( plain );
272 _gpgme_gpg_add_arg ( ctx->gpg, _gpgme_get_tmpfile(1) );
273 }
274 else {
275 _gpgme_gpg_add_arg ( ctx->gpg, "--output" );
276 _gpgme_gpg_add_arg ( ctx->gpg, "-" );
277 _gpgme_gpg_add_data ( ctx->gpg, ciph, 1 );
278 _gpgme_gpg_add_arg ( ctx->gpg, "--" );
279 _gpgme_gpg_add_data ( ctx->gpg, plain, 0 );
280 }
281
282 rc = _gpgme_gpg_spawn( ctx->gpg, ctx );
283
284 leave:
285 if ( rc ) {
286 ctx->pending = 0;
287 _gpgme_gpg_release( &ctx->gpg );
288 }
289 return rc;
290
291 } /* gpgme_op_sign_encrypt_start */
292
293
294 gpgme_error_t
295 gpgme_op_sign_encrypt( gpgme_ctx_t ctx, gpgme_recipients_t rset,
296 gpgme_data_t in, gpgme_data_t out )
297 {
298 gpgme_error_t rc;
299
300 rc = gpgme_op_sign_encrypt_start( ctx, rset, in, out );
301 if( !rc ) {
302 gpgme_wait( ctx, 1 );
303 ctx->pending = 0;
304 if( ctx->use_tmpfiles ) {
305 _gpgme_data_read_from_tmpfile( out );
306 _gpgme_del_tmpfiles( ctx->wipe_fnc );
307 }
308 if( ctx->result_type != RESULT_TYPE_SIGN_ENCRYPT )
309 rc = mk_error( General_Error );
310 else if ( ctx->out_of_core )
311 rc = mk_error( Out_Of_Core );
312 else {
313 assert( ctx->result.sign_enc );
314 if( ctx->result.sign_enc->no_passphrase )
315 rc = mk_error( No_Passphrase );
316 else if( ctx->result.sign_enc->bad_passphrase )
317 rc = mk_error( Bad_Passphrase );
318 else if( ctx->result.sign_enc->idea_cipher )
319 rc = mk_error( Cipher_IDEA );
320 else if( gpgme_get_process_rc( ctx ) )
321 rc = mk_error( Internal_GPG_Problem );
322 else if( !ctx->result.sign_enc->okay )
323 rc = mk_error( Signing_Failed );
324 }
325 }
326 return rc;
327 } /* gpgme_op_sign_encrypt */
328
329
330 gpgme_error_t
331 gpgme_op_clip_sign_encrypt( gpgme_ctx_t ctx, gpgme_recipients_t rset,
332 const char * keyid, int opts )
333 {
334 gpgme_error_t err;
335 gpgme_data_t plain = NULL;
336 gpgme_data_t ciph = NULL;
337 gpgme_key_t key = NULL;
338
339 if( !keyid )
340 return mk_error( General_Error );
341
342 if( opts & GPGME_CTRL_FORCETRUST )
343 gpgme_control( ctx, GPGME_CTRL_FORCETRUST, 1 );
344 if( opts & GPGME_CTRL_TMPFILES )
345 gpgme_control( ctx, GPGME_CTRL_TMPFILES, 1 );
346 gpgme_control( ctx, GPGME_CTRL_ARMOR, 1 );
347
348 key = _gpgme_key_new_fromkeyid( keyid );
349 if( !key )
350 return mk_error( General_Error );
351
352 err = gpgme_data_new_from_clipboard (&plain);
353 if( !err )
354 err = gpgme_data_new( &ciph );
355 if( !err )
356 err = gpgme_signers_add( ctx, key );
357 if( !err )
358 err = gpgme_op_sign_encrypt( ctx, rset, plain, ciph );
359 if( !err ) {
360 gpgme_data_change_version( &ciph );
361 gpgme_data_release_and_set_clipboard( ciph );
362 }
363 gpgme_data_release( plain );
364 gpgme_key_release( key );
365
366 return err;
367 } /* gpgme_op_clip_sign_encrypt */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26