/[winpt]/trunk/MyGPGME/decrypt.c
ViewVC logotype

Annotation of /trunk/MyGPGME/decrypt.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21 - (hide annotations)
Wed Jul 27 11:17:44 2005 UTC (19 years, 7 months ago) by twoaday
File MIME type: text/plain
File size: 19777 byte(s)
2005-07-22  Timo Schulz  <twoaday@freakmail.de>
 
        * gpgme.c (_gpgme_add_comment): Forgot to alloc an extra
        byte for the '0'. This fixes a lot of crashes related to
        file operations.
        * keylist.c (gpgme_op_keylist_getkey): Use the param for
        'pub' or 'sec' mode.
        * keycache.c (gpgme_keycache_update_key): If the key is
        not in the cache, add it and if the cache contain secret
        key, sync it with the pub cache.
        * editkey.c (edit_key_colon_handler): Allocate 1 byte for
        the NUL-char.  This also fixes a lot of reported crashes
        related to the showpref feature.
 


1 twoaday 2 /* decrypt.c - decrypt functions
2     * Copyright (C) 2000 Werner Koch (dd9jn)
3 twoaday 9 * Copyright (C) 2001-2005 Timo Schulz
4 twoaday 2 *
5     * This file is part of MyGPGME.
6     *
7     * MyGPGME 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     * MyGPGME 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 <stdio.h>
23     #include <stdlib.h>
24     #include <string.h>
25     #include <assert.h>
26     #include <windows.h>
27    
28     #include "util.h"
29     #include "context.h"
30     #include "ops.h"
31    
32     struct decrypt_result_s {
33     gpgme_sig_t sig;
34     int no_data;
35     int no_seckey;
36     int no_passphrase;
37     int idea_cipher;
38     int okay;
39     int sig_okay;
40     int failed;
41     int bad_mdc;
42     int bad_armor;
43     int bad_passphrase;
44     int key_algo;
45     int file_start;
46     int file_done;
47     char keyid[16+1];
48     char cardno[32+1];
49 twoaday 21 void *last_pw_handle;
50     char *userid_hint;
51     char *passphrase_info;
52     char *file_name;
53     struct {
54     int mode;
55     long times;
56     char *name;
57     } plain;
58 twoaday 2 };
59    
60    
61     void
62     gpgme_decrypt_get_sig_ctx (gpgme_ctx_t ctx, gpgme_sig_t * r_sig)
63     {
64     if (!ctx)
65     return;
66     if (r_sig)
67     *r_sig = NULL;
68     if (ctx && ctx->result.decrypt->sig) {
69     _gpgme_sig_ref (ctx->result.decrypt->sig);
70     if (r_sig)
71     *r_sig = ctx->result.decrypt->sig;
72     }
73     } /* gpgme_decrypt_get_sig_ctx */
74    
75    
76     void
77 twoaday 21 gpgme_decrypt_get_status (gpgme_ctx_t ctx, char * keyid,
78     gpgme_op_flags_t * r_flags)
79 twoaday 2 {
80     gpgme_op_flags_t flags = 0;
81     _decrypt_result_t res;
82    
83 twoaday 21 if (!keyid)
84 twoaday 2 return;
85 twoaday 21 if (ctx->result_type != RESULT_TYPE_DECRYPT)
86 twoaday 2 return;
87 twoaday 21 if (!ctx->result.decrypt->okay
88     && ctx->result.decrypt->no_seckey) {
89     strcpy (keyid, ctx->result.decrypt->keyid);
90 twoaday 2 flags |= GPGME_OPFLAG_NOSECKEY;
91     }
92     res = ctx->result.decrypt;
93     if (res->bad_armor)
94     flags |= GPGME_OPFLAG_BADARMOR;
95     if (res->bad_mdc)
96     flags |= GPGME_OPFLAG_BADMDC;
97     if (r_flags)
98     *r_flags = flags;
99     } /* gpgme_decrypt_get_status */
100    
101    
102     void
103     _gpgme_release_decrypt_result( _decrypt_result_t res )
104     {
105     if( res ) {
106 twoaday 21 safe_free (res->passphrase_info);
107     safe_free (res->userid_hint);
108     safe_free (res->file_name);
109     safe_free (res->plain.name);
110     gpgme_sig_release(res->sig);
111     safe_free (res);
112 twoaday 2 }
113     } /* _gpgme_release_decrypt_result */
114    
115    
116     static gpgme_error_t
117     create_result_struct (gpgme_ctx_t ctx)
118     {
119     assert( !ctx->result.decrypt );
120     ctx->result.decrypt = calloc( 1, sizeof * ctx->result.decrypt );
121     if( !ctx->result.decrypt )
122     return mk_error( Out_Of_Core );
123     ctx->result_type = RESULT_TYPE_DECRYPT;
124     return 0;
125     } /* create_result_struct */
126    
127    
128     static void
129     list_status_handler( gpgme_ctx_t ctx, gpg_status_code_t code, char * args )
130     {
131     char keyid[32] = {0};
132    
133     if (ctx->out_of_core)
134     return;
135     if (code == STATUS_ENC_TO) {
136     keyid[0] = (char)atol (args+17);
137     strncpy (keyid+1, args, 16);
138     gpgme_recipients_add_name (ctx->enc_to, keyid);
139     }
140     } /* list_status_handler */
141    
142    
143     static gpgme_sig_t
144     add_signature( gpgme_ctx_t ctx )
145     {
146     gpgme_sig_t sig, s;
147     gpgme_error_t err;
148    
149     err = gpgme_sig_new( &sig );
150     if( err ) {
151     ctx->out_of_core = 1;
152     return NULL;
153     }
154     if( ctx->result.decrypt->file_name ) {
155     sig->file_name = strdup( ctx->result.decrypt->file_name );
156     if( !sig->file_name ) {
157     ctx->out_of_core = 1;
158     safe_free( sig );
159     return NULL;
160     }
161     }
162     if( !ctx->result.decrypt->sig )
163     ctx->result.decrypt->sig = sig;
164     else {
165     for( s = ctx->result.decrypt->sig; s->next; s=s->next )
166     ;
167     s->next = sig;
168     }
169     return sig;
170     } /* add_signature */
171    
172    
173     static void
174 twoaday 9 decrypt_status_handler (gpgme_ctx_t ctx, gpg_status_code_t code, char *args)
175 twoaday 2 {
176     static gpgme_sig_t sig = NULL;
177     static char keyid[16+1];
178     char *p = NULL, fpr[40+1];
179     int i = 0, j=0;
180     char ch = 0;
181    
182     if (ctx->out_of_core)
183     return;
184    
185     if (ctx->result_type == RESULT_TYPE_NONE) {
186     if (create_result_struct (ctx)) {
187     ctx->out_of_core = 1;
188     return;
189     }
190     }
191    
192     assert (ctx->result_type == RESULT_TYPE_DECRYPT);
193    
194     if (code == STATUS_GOODSIG || code == STATUS_REVKEYSIG
195     || code == STATUS_EXPKEYSIG || code == STATUS_BADSIG
196     || code == STATUS_ERRSIG) {
197     sig = add_signature (ctx);
198     if (!sig || ctx->out_of_core)
199     return;
200     }
201    
202     _gpgme_nodata_status_handler (code, args, &ctx->result.decrypt->no_data);
203     _gpgme_pass_status_handler (code, args, &ctx->result.decrypt->bad_passphrase,
204     &ctx->result.decrypt->no_data,
205     &ctx->result.decrypt->passphrase_info);
206 twoaday 9 if (sig && (code >= STATUS_TRUST_UNDEFINED && code <= STATUS_TRUST_ULTIMATE)) {
207 twoaday 2 _gpgme_sigtrust_status_handler (code, args, &sig->trust);
208 twoaday 9 DEBUG1("sig_trust: %d", sig->trust);
209     }
210 twoaday 2
211 twoaday 9 switch (code) {
212 twoaday 2 case STATUS_EOF:
213     break;
214    
215     case STATUS_USERID_HINT:
216 twoaday 9 safe_free (ctx->result.decrypt->userid_hint);
217     p = ctx->result.decrypt->userid_hint = strdup (args);
218 twoaday 2 if (!p) {
219     ctx->out_of_core = 1;
220     return;
221     }
222     break;
223    
224     case STATUS_DECRYPTION_OKAY:
225     ctx->result.decrypt->okay = 1;
226     break;
227    
228     case STATUS_DECRYPTION_FAILED:
229     ctx->result.decrypt->failed = 1;
230     break;
231    
232     case STATUS_RSA_OR_IDEA:
233     ctx->result.decrypt->idea_cipher = 1;
234     break;
235    
236     case STATUS_SIG_ID:
237 twoaday 9 DEBUG0 ("Plaintext was signed!\n");
238 twoaday 2 break;
239    
240     case STATUS_NO_SECKEY:
241     ctx->result.decrypt->no_seckey++;
242 twoaday 9 strncpy (ctx->result.decrypt->keyid, args, 16);
243 twoaday 2 break;
244    
245     case STATUS_NO_PUBKEY:
246     sig->sigstat = GPGME_SIG_STAT_NOKEY;
247     break;
248 twoaday 21
249     case STATUS_PLAINTEXT:
250     i=0;
251     while (args[i] && args[i] == ' ')
252     i++;
253     ctx->result.decrypt->plain.mode = strtoul (args+i, NULL, 10);
254     while (args[i] && args[i] != ' ')
255     i++;
256     i++;
257     ctx->result.decrypt->plain.times = strtoul (args+i, NULL, 10);
258     while (args[i] && args[i] != ' ')
259     i++;
260     i++;
261     safe_free (ctx->result.decrypt->plain.name);
262     if (args[i]) {
263     p = ctx->result.decrypt->plain.name = strdup (args+i);
264     if (!p)
265     ctx->out_of_core = 1;
266     }
267     break;
268 twoaday 2
269     case STATUS_VALIDSIG:
270     p = fpr;
271     for( i = 0; i < DIM(fpr) && args[i] && args[i] != ' ' ; i++ )
272     *p++ = args[i];
273     *p = 0;
274     /* skip the formatted date */
275     while ( args[i] && args[i] == ' ')
276     i++;
277     while ( args[i] && args[i] != ' ')
278     i++;
279     /* and get the timestamp */
280     sig->created = strtoul( args + i, NULL, 10 );
281     ctx->result.decrypt->sig_okay = 1;
282     break;
283    
284     case STATUS_GOODSIG:
285     case STATUS_BADSIG:
286 twoaday 9 if (code == STATUS_GOODSIG)
287 twoaday 2 sig->sigstat = GPGME_SIG_STAT_GOOD;
288     else
289     sig->sigstat = GPGME_SIG_STAT_BAD;
290     strncpy( sig->id, args, 16 );
291     sig->user_id = p = calloc (1, strlen (args + 16) + 2);
292     if (!p)
293     {
294     ctx->out_of_core = 1;
295     return;
296     }
297     strcpy (p, args + 16);
298     break;
299    
300     case STATUS_EXPKEYSIG:
301     case STATUS_REVKEYSIG:
302     if( code == STATUS_EXPKEYSIG )
303     sig->sigstat = GPGME_SIG_STAT_E_GOOD;
304     else if( code == STATUS_REVKEYSIG )
305     sig->sigstat = GPGME_SIG_STAT_R_GOOD;
306     for( i=0, p=sig->id; args[i] && args[i] != ' '; i++ )
307     *p++ = args[i];
308     *p = '\0';
309     p = sig->user_id = calloc( 1, strlen( args+i ) + 2 );
310     if( !p ) {
311     ctx->out_of_core = 1;
312     return;
313     }
314     j=0;
315 twoaday 9 while (args[i])
316 twoaday 2 p[j++] = args[i++];
317     p[j++] = '\0';
318     break;
319    
320     case STATUS_ERRSIG:
321     sig->sigstat = GPGME_SIG_STAT_ERROR;
322     break;
323    
324     case STATUS_BADMDC:
325     ctx->result.decrypt->bad_mdc = 1;
326     break;
327    
328     case STATUS_BADARMOR:
329     ctx->result.decrypt->bad_armor = 1;
330     break;
331    
332     case STATUS_FILE_START:
333     if (*args == '3') {
334     safe_free (ctx->result.decrypt->file_name);
335     p = ctx->result.decrypt->file_name = strdup (args+2);
336 twoaday 21 if (!p) {
337 twoaday 2 ctx->out_of_core = 1;
338     return;
339     }
340     }
341     ctx->result.decrypt->file_start++;
342     if (ctx->cb.interactiv)
343     ctx->cb.interactiv (ctx->cb.interactiv_value, code, NULL, args+2);
344     break;
345    
346     case STATUS_FILE_DONE:
347     ctx->result.decrypt->file_done++;
348 twoaday 21 if (ctx->cb.interactiv)
349     ctx->cb.interactiv (ctx->cb.interactiv_value, code, NULL, NULL);
350 twoaday 2 break;
351    
352     case STATUS_CARDCTRL:
353     ch = args[i++];
354     if (ch == '4') {
355     ctx->result.decrypt->no_seckey = -1;
356     break;
357     }
358     if (ch != '3')
359     break;
360     i++;
361     p = ctx->result.decrypt->cardno;
362     for (; i-1 < DIM (ctx->result.decrypt->cardno) && args[i]; i++)
363     *p++ = args[i];
364     *p = 0;
365     break;
366    
367     default:
368     break; /* ignore all other codes */
369     }
370     } /* decrypt_status_handler */
371    
372    
373     static const char *
374     decrypt_command_handler (void * opaque, gpg_status_code_t code, const char * key)
375     {
376     gpgme_ctx_t c = opaque;
377    
378     if (!code) {
379     /* We have been called for cleanup */
380     if (c->cb.passphrase) {
381     c->cb.passphrase (c->cb.passphrase_value, NULL,
382     &c->result.decrypt->last_pw_handle);
383     }
384     return NULL;
385     }
386    
387     if (!key || !c->cb.passphrase)
388     return NULL;
389    
390     if (c->result_type == RESULT_TYPE_NONE) {
391     if (create_result_struct (c)) {
392     c->out_of_core = 1;
393     return NULL;
394     }
395     }
396    
397     if( code == STATUS_GET_HIDDEN
398     && (!strcmp( key, "passphrase.enter" )
399     || !strcmp( key, "passphrase.pin.ask" )) ) {
400     const char * userid_hint = c->result.decrypt->userid_hint;
401     const char * passphrase_info = c->result.decrypt->passphrase_info;
402     const char * cardno = c->result.decrypt->cardno;
403     int bad_passphrase = c->result.decrypt->bad_passphrase;
404     int is_card=0;
405     char * buf;
406     const char *s;
407    
408     c->result.decrypt->bad_passphrase = 0;
409     is_card = !strcmp (key, "passphrase.pin.ask");
410     if (!userid_hint)
411     userid_hint = "[User ID hint missing]";
412     if (!passphrase_info)
413     passphrase_info = "[passphrase info missing]";
414     buf = malloc (20 + strlen (userid_hint)
415     + strlen (passphrase_info) + 3);
416     if( !buf ) {
417     c->out_of_core = 1;
418     return NULL;
419     }
420     sprintf (buf, "%s\n%s\n%s", bad_passphrase? "TRY_AGAIN":"ENTER_PASSPHRASE",
421     userid_hint, passphrase_info);
422     s = c->cb.passphrase (c->cb.passphrase_value, is_card? cardno : buf,
423     &c->result.decrypt->last_pw_handle);
424     safe_free (buf);
425     return s;
426     }
427     else if( (code == STATUS_GET_BOOL
428     && !strcmp( key, "openfile.overwrite.okay" ))
429     || (code == STATUS_GET_LINE && !strcmp( key, "openfile.askoutname" )) )
430     if (c->cb.interactiv)
431     return c->cb.interactiv( c->cb.interactiv_value, code, key, NULL );
432    
433     return NULL;
434     } /* decrypt_command_handler */
435    
436    
437     static gpgme_error_t
438     list_keys_start( gpgme_ctx_t ctx, gpgme_data_t ciph, const char * file,
439     gpgme_recipients_t * r_keys )
440     {
441     gpgme_error_t rc;
442     gpgme_recipients_t keys;
443     FILE * fp;
444     const char * s;
445     char * p;
446    
447     if (!r_keys)
448     return mk_error (Invalid_Value);
449     if (ciph && file || !ciph && !file)
450     return mk_error (Invalid_Mode);
451    
452     *r_keys = NULL;
453     fail_on_pending_request( ctx );
454     ctx->pending = 1;
455    
456     _gpgme_gpg_release( &ctx->gpg );
457     rc = _gpgme_gpg_new( &ctx->gpg );
458     if( rc )
459     return rc;
460    
461     if( ciph ) {
462     p = _gpgme_data_get_as_string( ciph );
463     if( !p )
464     return mk_error( Out_Of_Core );
465    
466     s = _gpgme_get_tmpfile( 0 );
467     fp = fopen( s, "wb" );
468     if( !fp ) {
469     safe_free( p );
470     return mk_error( File_Error );
471     }
472     fwrite (p, 1, strlen (p), fp);
473     fclose (fp);
474     safe_free (p);
475     }
476     else
477     s = file;
478    
479     rc = gpgme_recipients_new( &keys );
480     if( rc )
481     return rc;
482     ctx->enc_to = keys;
483    
484     _gpgme_gpg_set_status_handler( ctx->gpg, list_status_handler, ctx );
485     _gpgme_gpg_add_arg( ctx->gpg, "--list-only" );
486     _gpgme_gpg_add_arg( ctx->gpg, s );
487    
488     rc = _gpgme_gpg_spawn( ctx->gpg, ctx );
489     if( rc ) {
490     ctx->pending = 0;
491     _gpgme_gpg_release( &ctx->gpg );
492     gpgme_recipients_release( keys ); keys = NULL;
493     }
494     *r_keys = keys;
495     return rc;
496     } /* list_keys_start */
497    
498    
499     /* It either works with a file or a data object but not with both! */
500     gpgme_error_t
501     gpgme_op_list_keys( gpgme_data_t ciph, const char * file,
502     gpgme_recipients_t * r_rset )
503     {
504     gpgme_ctx_t ctx = NULL;
505     gpgme_error_t err;
506    
507     if( !r_rset )
508     return mk_error (Invalid_Value);
509     *r_rset = NULL;
510     err = gpgme_new( &ctx );
511     if( !err )
512     err = list_keys_start( ctx, ciph, file, r_rset );
513     if( !err ) {
514     gpgme_wait( ctx, 1 );
515     ctx->pending = 0;
516     }
517     gpgme_release( ctx );
518     return err;
519     } /* gpgme_op_list_keys */
520    
521    
522     static gpgme_error_t
523     file_decrypt_start( gpgme_ctx_t ctx, const char ** input, size_t nfiles,
524     const char * output )
525     {
526     gpgme_error_t rc;
527    
528     if( !input )
529     return mk_error( Invalid_Value );
530    
531     fail_on_pending_request( ctx );
532     ctx->pending = 1;
533    
534     _gpgme_gpg_release( &ctx->gpg );
535     rc = _gpgme_gpg_new( &ctx->gpg );
536     if( rc )
537     return rc;
538    
539     _gpgme_gpg_set_status_handler( ctx->gpg, decrypt_status_handler, ctx );
540     if( !ctx->use_pass_fd )
541     _gpgme_gpg_set_command_handler( ctx->gpg, decrypt_command_handler, ctx );
542     else {
543     rc = _gpgme_add_passphrase( ctx );
544     if( rc ) {
545     _gpgme_gpg_release( &ctx->gpg );
546     return rc;
547     }
548     }
549    
550     if( !ctx->cb.interactiv )
551     _gpgme_gpg_add_arg( ctx->gpg, "--yes" );
552     if( nfiles > 1 || !output )
553     _gpgme_gpg_add_arg( ctx->gpg, "--no-mangle-dos-filenames" );
554     if( ctx->pipemode || nfiles > 1 )
555     _gpgme_gpg_add_arg( ctx->gpg, "--decrypt-files" );
556     else
557     _gpgme_gpg_add_arg( ctx->gpg, "--decrypt" );
558    
559     /* cannot use --output with --decrypt-files */
560     if( nfiles == 1 && !ctx->pipemode && output ) {
561     _gpgme_gpg_add_arg( ctx->gpg, "--output" );
562     _gpgme_gpg_add_arg( ctx->gpg, output );
563     }
564    
565     while( nfiles-- )
566     _gpgme_gpg_add_arg( ctx->gpg, *input++ );
567    
568     rc = _gpgme_gpg_spawn( ctx->gpg, ctx );
569     if( rc ) {
570     ctx->pending = 0;
571     _gpgme_gpg_release( &ctx->gpg );
572     }
573    
574     return rc;
575     } /* file_decrypt_start */
576    
577    
578     static gpgme_error_t
579     decrypt_start( gpgme_ctx_t ctx, gpgme_data_t ciph, gpgme_data_t plain )
580     {
581     int rc = 0;
582    
583 twoaday 17 fail_on_pending_request (ctx);
584 twoaday 2 ctx->pending = 1;
585    
586 twoaday 17 _gpgme_release_result (ctx);
587 twoaday 2 ctx->out_of_core = 0;
588    
589     /* create a process object */
590     _gpgme_gpg_release( &ctx->gpg );
591     rc = _gpgme_gpg_new( &ctx->gpg );
592     if( rc )
593     goto leave;
594    
595     _gpgme_gpg_set_status_handler( ctx->gpg, decrypt_status_handler, ctx );
596     if( ctx->use_logging )
597     _gpgme_gpg_set_logging_handler( ctx->gpg, ctx );
598     if( ctx->cb.passphrase ) {
599     rc = _gpgme_gpg_set_command_handler( ctx->gpg, decrypt_command_handler, ctx );
600     if ( rc )
601     goto leave;
602     }
603     else if( ctx->passphrase_value ) {
604     rc = _gpgme_add_passphrase( ctx );
605     if( rc )
606     goto leave;
607     }
608    
609     /* build the commandline */
610     _gpgme_gpg_add_arg( ctx->gpg, "--decrypt" );
611     /* Check the supplied data */
612     if( !ciph || gpgme_data_get_type( ciph ) == GPGME_DATA_TYPE_NONE ) {
613     rc = mk_error( No_Data );
614     goto leave;
615     }
616     _gpgme_data_set_mode( ciph, GPGME_DATA_MODE_OUT );
617     if( gpgme_data_get_type( plain ) != GPGME_DATA_TYPE_NONE ) {
618     rc = mk_error( Invalid_Value );
619     goto leave;
620     }
621     _gpgme_data_set_mode( plain, GPGME_DATA_MODE_IN );
622    
623     /* Tell the gpg object about the data */
624     _gpgme_gpg_add_arg ( ctx->gpg, "--output" );
625     _gpgme_gpg_add_arg ( ctx->gpg, "-" );
626     _gpgme_gpg_add_data( ctx->gpg, plain, 1 );
627     _gpgme_gpg_add_data( ctx->gpg, ciph, 0 );
628    
629     /* and kick off the process */
630     rc = _gpgme_gpg_spawn( ctx->gpg, ctx );
631    
632     leave:
633     if( rc ) {
634     ctx->pending = 0;
635     _gpgme_gpg_release( &ctx->gpg );
636     }
637     return rc;
638     } /* decrypt_start */
639    
640    
641     static gpgme_error_t
642     get_decrypt_result( gpgme_ctx_t ctx )
643     {
644     gpgme_error_t err;
645     struct decrypt_result_s * res;
646    
647     assert( ctx->result.decrypt );
648     res = ctx->result.decrypt;
649     if( ctx->result_type != RESULT_TYPE_DECRYPT )
650     err = mk_error( General_Error );
651     else if (res->okay || res->sig_okay)
652     err = 0;
653     else if( ctx->out_of_core )
654     err = mk_error( Out_Of_Core );
655     else if( res->no_passphrase )
656     err = mk_error( No_Passphrase );
657     else if( res->bad_passphrase )
658     err = mk_error( Bad_Passphrase );
659     else if( res->no_seckey)
660     err = mk_error( No_Seckey );
661     else if( res->idea_cipher )
662     err = mk_error( Cipher_IDEA );
663     else if( res->failed || (res->file_start != res->file_done) )
664     err = mk_error( Decryption_Failed );
665     else if( !res->okay || !res->no_data )
666     err = mk_error( No_Data );
667     else if( gpgme_get_process_rc( ctx ) )
668 twoaday 7 err = mk_error( Internal_GPG_Problem );
669 twoaday 2 return err;
670     } /* get_decrypt_result */
671    
672    
673     /**
674     * gpgme_op_decrypt:
675     * @c: The context
676     * @ciph: ciphertext input
677     * @plain: plaintext output
678     *
679     * This function decrypts @in to @out.
680     * Other parameters are take from the context @c.
681     * The function does wait for the result.
682     *
683     * Return value: 0 on success or an errorcode.
684     **/
685     gpgme_error_t
686     gpgme_op_decrypt( gpgme_ctx_t ctx, gpgme_data_t ciph, gpgme_data_t plain )
687    
688     {
689     gpgme_error_t err;
690    
691     err = decrypt_start( ctx, ciph, plain );
692     if( !err ) {
693     gpgme_wait( ctx, 1 );
694     ctx->pending = 0;
695     err = get_decrypt_result( ctx );
696     }
697     return err;
698     } /* gpgme_op_decrypt */
699    
700    
701     gpgme_error_t
702     gpgme_op_file_decrypt( gpgme_ctx_t ctx, const char * ciph, const char * plain )
703     {
704     gpgme_error_t err;
705     const char * files[1];
706    
707     files[0] = ciph;
708    
709     err = file_decrypt_start( ctx, files, 1, plain );
710     if( !err ) {
711     gpgme_wait( ctx, 1 );
712     err = get_decrypt_result( ctx );
713     ctx->pending = 0;
714     }
715     return err;
716     } /* gpgme_op_file_decrypt */
717    
718    
719     gpgme_error_t
720     gpgme_op_files_decrypt( gpgme_ctx_t ctx, const char ** files, size_t nfiles )
721     {
722     gpgme_error_t err;
723    
724     err = file_decrypt_start( ctx, files, nfiles, NULL );
725     if( !err ) {
726     gpgme_wait( ctx, 1 );
727     err = get_decrypt_result( ctx );
728     ctx->pending = 0;
729     }
730     return err;
731     }
732    
733    
734     gpgme_error_t
735     gpgme_op_clip_decrypt( gpgme_ctx_t ctx )
736     {
737     gpgme_error_t err;
738     gpgme_data_t ciph = NULL;
739     gpgme_data_t plain = NULL;
740    
741     err = gpgme_data_new_from_clipboard (&ciph);
742     if( !err )
743     err = gpgme_data_new( &plain );
744     if( !err )
745     err = gpgme_op_decrypt( ctx, ciph, plain );
746    
747     gpgme_data_release_and_set_clipboard( plain );
748     gpgme_data_release( ciph );
749    
750     return err;
751     } /* gpgme_op_clip_decrypt */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26