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

Annotation of /trunk/MyGPGME/decrypt.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (hide annotations)
Wed Aug 10 11:33:35 2005 UTC (19 years, 6 months ago) by twoaday
File MIME type: text/plain
File size: 19739 byte(s)
2005-08-06  Timo Schulz  <twoaday@freakmail.de>
 
        * wptGPGME.cpp (keycache_update): Reload OpenPGP parts
        of the secret key.
        (keycache_init): cache name of secret keyring.
        * wptKeyList.cpp (keylist_upd_key): Do not add long keyid.
        (get_key_type): Do not assume 'ultimate' means key pair.
        * wptKeyEditDlgs.cpp (diff_time): New.
        (keyedit_addsubkey_dlg_proc): Changed design and use
        diff_time. Drop checks for invalid keylength (< 1024, > 4096)
        because the combo box automatically handles this.
        * wptKeyManager.cpp (km_set_implicit_trust): Return error code.
        * wptGPG.cpp (get_backup_name): New.
        (gnupg_backup_keyrings): Rotate backup names, from 0..3.
        * wptClipImportDialog.cpp (clip_import_dlg_proc): Free memory.
        * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Use 0x short keyid and
        not the long keyid.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26