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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (show annotations)
Wed Apr 13 11:10:53 2005 UTC (19 years, 10 months ago) by twoaday
File MIME type: text/plain
File size: 10964 byte(s)
Fix signature ownertrust code.


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 _gpgme_gpg_add_arg (ctx->gpg, "-u");
245 _gpgme_gpg_add_arg_concat (ctx->gpg, s, "!");
246 _gpgme_gpg_add_arg (ctx->gpg, "--encrypt-to");
247 _gpgme_gpg_add_arg (ctx->gpg, s);
248 }
249 gpgme_key_unref (key);
250 }
251
252 _gpgme_append_gpg_args_from_recipients( recp, ctx->gpg );
253 if( gpgme_data_get_type( plain ) == GPGME_DATA_TYPE_NONE ) {
254 rc = mk_error( No_Data );
255 goto leave;
256 }
257
258 _gpgme_data_set_mode( plain, GPGME_DATA_MODE_OUT );
259
260 if( !ciph || gpgme_data_get_type(ciph) != GPGME_DATA_TYPE_NONE ) {
261 rc = mk_error( No_Data );
262 goto leave;
263 }
264
265 _gpgme_data_set_mode( ciph, GPGME_DATA_MODE_IN );
266
267 if( ctx->use_tmpfiles ) {
268 _gpgme_gpg_add_arg ( ctx->gpg, "--output" );
269 _gpgme_gpg_add_arg ( ctx->gpg, _gpgme_get_tmpfile(0) );
270 _gpgme_data_write_to_tmpfile( plain );
271 _gpgme_gpg_add_arg ( ctx->gpg, _gpgme_get_tmpfile(1) );
272 }
273 else {
274 _gpgme_gpg_add_arg ( ctx->gpg, "--output" );
275 _gpgme_gpg_add_arg ( ctx->gpg, "-" );
276 _gpgme_gpg_add_data ( ctx->gpg, ciph, 1 );
277 _gpgme_gpg_add_arg ( ctx->gpg, "--" );
278 _gpgme_gpg_add_data ( ctx->gpg, plain, 0 );
279 }
280
281 rc = _gpgme_gpg_spawn( ctx->gpg, ctx );
282
283 leave:
284 if ( rc ) {
285 ctx->pending = 0;
286 _gpgme_gpg_release( &ctx->gpg );
287 }
288 return rc;
289
290 } /* gpgme_op_sign_encrypt_start */
291
292
293 gpgme_error_t
294 gpgme_op_sign_encrypt( gpgme_ctx_t ctx, gpgme_recipients_t rset,
295 gpgme_data_t in, gpgme_data_t out )
296 {
297 gpgme_error_t rc;
298
299 rc = gpgme_op_sign_encrypt_start( ctx, rset, in, out );
300 if( !rc ) {
301 gpgme_wait( ctx, 1 );
302 ctx->pending = 0;
303 if( ctx->use_tmpfiles ) {
304 _gpgme_data_read_from_tmpfile( out );
305 _gpgme_del_tmpfiles( ctx->wipe_fnc );
306 }
307 if( ctx->result_type != RESULT_TYPE_SIGN_ENCRYPT )
308 rc = mk_error( General_Error );
309 else if ( ctx->out_of_core )
310 rc = mk_error( Out_Of_Core );
311 else {
312 assert( ctx->result.sign_enc );
313 if( ctx->result.sign_enc->no_passphrase )
314 rc = mk_error( No_Passphrase );
315 else if( ctx->result.sign_enc->bad_passphrase )
316 rc = mk_error( Bad_Passphrase );
317 else if( ctx->result.sign_enc->idea_cipher )
318 rc = mk_error( Cipher_IDEA );
319 else if( gpgme_get_process_rc( ctx ) )
320 rc = mk_error( Internal_GPG_Problem );
321 else if( !ctx->result.sign_enc->okay )
322 rc = mk_error( Signing_Failed );
323 }
324 }
325 return rc;
326 } /* gpgme_op_sign_encrypt */
327
328
329 gpgme_error_t
330 gpgme_op_clip_sign_encrypt( gpgme_ctx_t ctx, gpgme_recipients_t rset,
331 const char * keyid, int opts )
332 {
333 gpgme_error_t err;
334 gpgme_data_t plain = NULL;
335 gpgme_data_t ciph = NULL;
336 gpgme_key_t key = NULL;
337
338 if( !keyid )
339 return mk_error( General_Error );
340
341 if( opts & GPGME_CTRL_FORCETRUST )
342 gpgme_control( ctx, GPGME_CTRL_FORCETRUST, 1 );
343 if( opts & GPGME_CTRL_TMPFILES )
344 gpgme_control( ctx, GPGME_CTRL_TMPFILES, 1 );
345 gpgme_control( ctx, GPGME_CTRL_ARMOR, 1 );
346
347 key = _gpgme_key_new_fromkeyid( keyid );
348 if( !key )
349 return mk_error( General_Error );
350
351 err = gpgme_data_new_from_clipboard (&plain);
352 if( !err )
353 err = gpgme_data_new( &ciph );
354 if( !err )
355 err = gpgme_signers_add( ctx, key );
356 if( !err )
357 err = gpgme_op_sign_encrypt( ctx, rset, plain, ciph );
358 if( !err ) {
359 gpgme_data_change_version( &ciph );
360 gpgme_data_release_and_set_clipboard( ciph );
361 }
362 gpgme_data_release( plain );
363 gpgme_key_release( key );
364
365 return err;
366 } /* gpgme_op_clip_sign_encrypt */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26