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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Mon Jan 31 11:02:21 2005 UTC (20 years, 1 month ago) by twoaday
File MIME type: text/plain
File size: 10968 byte(s)
WinPT initial checkin.


1 twoaday 2 /* 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( Interal_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