c056ac0af742c926bd74622bfc49b36ea0441d44
[gnupg.git] / g10 / mainproc.c
1 /* mainproc.c - handle packets
2  *      Copyright (c) 1997 by Werner Koch (dd9jn)
3  *
4  * This file is part of G10.
5  *
6  * G10 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  * G10 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 <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include "packet.h"
26 #include "iobuf.h"
27 #include "memory.h"
28 #include "options.h"
29 #include "util.h"
30 #include "cipher.h"
31 #include "keydb.h"
32 #include "filter.h"
33 #include "main.h"
34
35 static int opt_list=1;  /* and list the data packets to stdout */
36 #if 0
37 static void
38 do_free_last_user_id( CTX c )
39 {
40     if( c->last_user_id ) {
41         free_user_id( c->last_user_id );
42         c->last_user_id = NULL;
43     }
44 }
45 static void
46 do_free_last_pubkey( CTX c )
47 {
48     if( c->last_pubkey ) {
49         free_pubkey_cert( c->last_pubkey );
50         c->last_pubkey = NULL;
51     }
52 }
53 static void
54 do_free_last_seckey( CTX c )
55 {
56     if( c->last_seckey ) {
57         free_seckey_cert( c->last_seckey );
58         c->last_seckey = NULL;
59     }
60 }
61
62 static void
63 proc_pubkey_cert( CTX c, PACKET *pkt )
64 {
65     do_free_last_user_id( c );
66     do_free_last_seckey( c );
67     if( opt.check_sigs ) {
68         char *ustr = get_user_id_string(sig->keyid); /* sig ???? */
69         printstr(lvl0, "pub: %s\n", ustr );
70         m_free(ustr);
71     }
72     else
73         fputs( "pub: [Public Key Cerificate]\n", stdout );
74     c->last_pubkey = pkt->pkt.pubkey_cert;
75     pkt->pkt.pubkey_cert = NULL;
76     free_packet(pkt);
77     pkt->pkc_parent = c->last_pubkey; /* set this as parent */
78 }
79
80
81 static void
82 proc_seckey_cert( CTX c, PACKET *pkt )
83 {
84     int rc;
85
86     do_free_last_user_id( c );
87     do_free_last_pubkey( c );
88     if( opt_list )
89         fputs( "sec: (secret key certificate)\n", stdout );
90     rc = check_secret_key( pkt->pkt.seckey_cert );
91     if( opt_list ) {
92         if( !rc )
93             fputs( "     Secret key is good", stdout );
94         else
95             fputs( g10_errstr(rc), stdout);
96         putchar('\n');
97     }
98     else if( rc )
99         log_error("secret key certificate error: %s\n", g10_errstr(rc));
100     c->last_seckey = pkt->pkt.seckey_cert;
101     pkt->pkt.seckey_cert = NULL;
102     free_packet(pkt);
103     pkt->skc_parent = c->last_seckey; /* set this as parent */
104 }
105
106
107
108
109
110 int
111 proc_packets( IOBUF a )
112 {
113     PACKET *pkt;
114     PKT_pubkey_cert *last_pubkey = NULL;
115     PKT_seckey_cert *last_seckey = NULL;
116     PKT_user_id     *last_user_id = NULL;
117     DEK *dek = NULL;
118     PKT_signature *sig; /* CHECK: "might be used uninitialied" */
119     int rc, result;
120     MD_HANDLE md_handle; /* union to pass handles */
121     char *ustr;
122     int lvl0, lvl1;
123     int last_was_pubkey_enc = 0;
124     u32 keyid[2];
125     md_filter_context_t mfx;
126
127     memset( &mfx, 0, sizeof mfx );
128     lvl0 = opt.check_sigs? 1:0; /* stdout or /dev/null */
129     lvl1 = opt.check_sigs? 1:3; /* stdout or error */
130     pkt = m_alloc( sizeof *pkt );
131     init_packet(pkt);
132     while( (rc=parse_packet(a, pkt)) != -1 ) {
133         /* cleanup if we have an illegal data structure */
134         if( dek && pkt->pkttype != PKT_ENCR_DATA ) {
135             log_error("oops: valid pubkey enc packet not followed by data\n");
136             m_free(dek); dek = NULL; /* burn it */
137         }
138
139         if( rc ) {
140             free_packet(pkt);
141             continue;
142         }
143         switch( pkt->pkttype ) {
144           case PKT_PUBKEY_CERT: proc_pubkey_cert( c, pkt ); break;
145           case PKT_SECKEY_CERT: proc_seckey_cert( c, pkt ); break;
146           case PKT_USER_ID:
147             if( last_user_id ) {
148                 free_user_id( last_user_id );
149                 last_user_id = NULL;
150             }
151             if( opt_list ) {
152                  printf("uid: '%.*s'\n", pkt->pkt.user_id->len,
153                                          pkt->pkt.user_id->name );
154                  if( !pkt->pkc_parent && !pkt->skc_parent )
155                      puts("      (orphaned)");
156             }
157             if( pkt->pkc_parent ) {
158                 if( pkt->pkc_parent->pubkey_algo == PUBKEY_ALGO_ELGAMAL
159                     || pkt->pkc_parent->pubkey_algo == PUBKEY_ALGO_RSA ) {
160                     keyid_from_pkc( pkt->pkc_parent, keyid );
161                     cache_user_id( pkt->pkt.user_id, keyid );
162                 }
163             }
164
165             last_user_id = pkt->pkt.user_id;  /* save */
166             pkt->pkt.user_id = NULL;
167             free_packet(pkt);   /* fixme: free_packet is not a good name */
168             pkt->user_parent = last_user_id;  /* and set this as user */
169             break;
170
171           case PKT_SIGNATURE:
172             sig = pkt->pkt.signature;
173             ustr = get_user_id_string(sig->keyid);
174             result = -1;
175             if( sig->sig_class == 0x00 ) {
176                 if( mfx.rmd160 )
177                     result = 0;
178                 else
179                     printstr(lvl1,"sig?: %s: no plaintext for signature\n",
180                                                         ustr);
181             }
182             else if( sig->sig_class != 0x10 )
183                 printstr(lvl1,"sig?: %s: unknown signature class %02x\n",
184                                         ustr, sig->sig_class);
185             else if( !pkt->pkc_parent || !pkt->user_parent )
186                 printstr(lvl1,"sig?: %s: orphaned encoded packet\n", ustr);
187             else
188                 result = 0;
189
190             if( result )
191                 ;
192             else if( !opt.check_sigs && sig->sig_class != 0x00 ) {
193                 result = -1;
194                 printstr(lvl0, "sig: from %s\n", ustr );
195             }
196             else if(sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
197                 md_handle.algo = sig->d.elg.digest_algo;
198                 if( sig->d.elg.digest_algo == DIGEST_ALGO_RMD160 ) {
199                     if( sig->sig_class == 0x00 )
200                         md_handle.u.rmd = rmd160_copy( mfx.rmd160 );
201                     else {
202                         md_handle.u.rmd = rmd160_copy(pkt->pkc_parent->mfx.rmd160);
203                         rmd160_write(md_handle.u.rmd, pkt->user_parent->name,
204                                                       pkt->user_parent->len);
205                     }
206                     result = signature_check( sig, md_handle );
207                     rmd160_close(md_handle.u.rmd);
208                 }
209                 else if( sig->d.elg.digest_algo == DIGEST_ALGO_MD5
210                          && sig->sig_class != 0x00 ) {
211                     md_handle.u.md5 = md5_copy(pkt->pkc_parent->mfx.md5);
212                     md5_write(md_handle.u.md5, pkt->user_parent->name,
213                                                pkt->user_parent->len);
214                     result = signature_check( sig, md_handle );
215                     md5_close(md_handle.u.md5);
216                 }
217                 else
218                     result = G10ERR_DIGEST_ALGO;
219             }
220             else if(sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
221                 md_handle.algo = sig->d.rsa.digest_algo;
222                 if( sig->d.rsa.digest_algo == DIGEST_ALGO_RMD160 ) {
223                     if( sig->sig_class == 0x00 )
224                         md_handle.u.rmd = rmd160_copy( mfx.rmd160 );
225                     else {
226                         md_handle.u.rmd = rmd160_copy(pkt->pkc_parent->mfx.rmd160);
227                         rmd160_write(md_handle.u.rmd, pkt->user_parent->name,
228                                                       pkt->user_parent->len);
229                     }
230                     result = signature_check( sig, md_handle );
231                     rmd160_close(md_handle.u.rmd);
232                 }
233                 else if( sig->d.rsa.digest_algo == DIGEST_ALGO_MD5
234                          && sig->sig_class != 0x00 ) {
235                     md_handle.u.md5 = md5_copy(pkt->pkc_parent->mfx.md5);
236                     md5_write(md_handle.u.md5, pkt->user_parent->name,
237                                                pkt->user_parent->len);
238                     result = signature_check( sig, md_handle );
239                     md5_close(md_handle.u.md5);
240                 }
241                 else
242                     result = G10ERR_DIGEST_ALGO;
243             }
244             else
245                 result = G10ERR_PUBKEY_ALGO;
246
247             if( result == -1 )
248                 ;
249             else if( !result && sig->sig_class == 0x00 )
250                 printstr(1,    "sig: good signature from %s\n", ustr );
251             else if( !result )
252                 printstr(lvl0, "sig: good signature from %s\n", ustr );
253             else
254                 printstr(lvl1, "sig? %s: %s\n", ustr, g10_errstr(result));
255             free_packet(pkt);
256             m_free(ustr);
257             break;
258
259           case PKT_PUBKEY_ENC:
260             PKT_pubkey_enc *enc;
261
262             last_was_pubkey_enc = 1;
263             result = 0;
264             enc = pkt->pkt.pubkey_enc;
265             printf("enc: encrypted by a pubkey with keyid %08lX\n",
266                                                         enc->keyid[1] );
267             if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL
268                 || enc->pubkey_algo == PUBKEY_ALGO_RSA  ) {
269                 m_free(dek ); /* paranoid: delete a pending DEK */
270                 dek = m_alloc_secure( sizeof *dek );
271                 if( (result = get_session_key( enc, dek )) ) {
272                     /* error: delete the DEK */
273                     m_free(dek); dek = NULL;
274                 }
275             }
276             else
277                 result = G10ERR_PUBKEY_ALGO;
278
279             if( result == -1 )
280                 ;
281             else if( !result )
282                 fputs(  "     DEK is good", stdout );
283             else
284                 printf( "     %s", g10_errstr(result));
285             putchar('\n');
286             free_packet(pkt);
287             break;
288
289           case PKT_ENCR_DATA:
290             result = 0;
291             printf("dat: %sencrypted data\n", dek?"":"conventional ");
292             if( !dek && !last_was_pubkey_enc ) {
293                 /* assume this is conventional encrypted data */
294                 dek = m_alloc_secure( sizeof *dek );
295                 dek->algo = DEFAULT_CIPHER_ALGO;
296                 result = make_dek_from_passphrase( dek, 0 );
297             }
298             else if( !dek )
299                 result = G10ERR_NO_SECKEY;
300             if( !result )
301                 result = decrypt_data( pkt->pkt.encr_data, dek );
302             m_free(dek); dek = NULL;
303             if( result == -1 )
304                 ;
305             else if( !result )
306                 fputs(  "     encryption okay",stdout);
307             else
308                 printf( "     %s", g10_errstr(result));
309             putchar('\n');
310             free_packet(pkt);
311             last_was_pubkey_enc = 0;
312             break;
313
314           case PKT_PLAINTEXT:
315             PKT_plaintext *pt = pkt->pkt.plaintext;
316             printf("txt: plain text data name='%.*s'\n", pt->namelen, pt->name);
317             free_md_filter_context( &mfx );
318             mfx.rmd160 = rmd160_open(0);
319             result = handle_plaintext( pt, &mfx );
320             if( !result )
321                 fputs(  "     okay",stdout);
322             else
323                 printf( "     %s", g10_errstr(result));
324             putchar('\n');
325             free_packet(pkt);
326             last_was_pubkey_enc = 0;
327             break;
328
329           case PKT_COMPR_DATA:
330             PKT_compressed *zd = pkt->pkt.compressed;
331             printf("zip: compressed data packet\n");
332             result = handle_compressed( zd );
333             if( !result )
334                 fputs(  "     okay",stdout);
335             else
336                 printf( "     %s", g10_errstr(result));
337             putchar('\n');
338             free_packet(pkt);
339             last_was_pubkey_enc = 0;
340             break;
341
342           default:
343             free_packet(pkt);
344         }
345     }
346
347     if( last_user_id )
348         free_user_id( last_user_id );
349     if( last_seckey )
350         free_seckey_cert( last_seckey );
351     if( last_pubkey )
352         free_pubkey_cert( last_pubkey );
353     m_free(dek);
354     free_packet( pkt );
355     m_free( pkt );
356     free_md_filter_context( &mfx );
357     return 0;
358 }
359
360 #else /* old */
361 int
362 proc_packets( IOBUF a )
363 {
364     PACKET *pkt;
365     PKT_pubkey_cert *last_pubkey = NULL;
366     PKT_seckey_cert *last_seckey = NULL;
367     PKT_user_id     *last_user_id = NULL;
368     DEK *dek = NULL;
369     PKT_signature *sig; /* CHECK: "might be used uninitialied" */
370     int rc, result;
371     MD_HANDLE md_handle; /* union to pass handles */
372     char *ustr;
373     int lvl0, lvl1;
374     int last_was_pubkey_enc = 0;
375     u32 keyid[2];
376     md_filter_context_t mfx;
377
378     memset( &mfx, 0, sizeof mfx );
379     lvl0 = opt.check_sigs? 1:0; /* stdout or /dev/null */
380     lvl1 = opt.check_sigs? 1:3; /* stdout or error */
381     pkt = m_alloc( sizeof *pkt );
382     init_packet(pkt);
383     while( (rc=parse_packet(a, pkt)) != -1 ) {
384         if( dek && pkt->pkttype != PKT_ENCR_DATA ) {
385             log_error("oops: valid pubkey enc packet not followed by data\n");
386             m_free(dek); dek = NULL; /* burn it */
387         }
388
389         if( rc )
390             free_packet(pkt);
391         else if( pkt->pkttype == PKT_PUBKEY_CERT ) {
392             if( last_user_id ) {
393                 free_user_id( last_user_id );
394                 last_user_id = NULL;
395             }
396             if( last_pubkey ) {
397                 free_pubkey_cert( last_pubkey );
398                 last_pubkey = NULL;
399             }
400             if( opt.check_sigs ) {
401                 ustr = get_user_id_string(sig->keyid);
402                 printstr(lvl0, "pub: %s\n", ustr );
403                 m_free(ustr);
404             }
405             else
406                 fputs( "pub: [Public Key Cerificate]\n", stdout );
407             last_pubkey = pkt->pkt.pubkey_cert;
408             pkt->pkt.pubkey_cert = NULL;
409             free_packet(pkt);
410             pkt->pkc_parent = last_pubkey; /* set this as parent */
411         }
412         else if( pkt->pkttype == PKT_SECKEY_CERT ) {
413             if( last_user_id ) {
414                 free_user_id( last_user_id );
415                 last_user_id = NULL;
416             }
417             if( last_seckey ) {
418                 free_seckey_cert( last_seckey );
419                 last_seckey = NULL;
420             }
421             if( opt_list )
422                 fputs( "sec: (secret key certificate)\n", stdout );
423             rc = check_secret_key( pkt->pkt.seckey_cert );
424             if( opt_list ) {
425                 if( !rc )
426                     fputs( "     Secret key is good", stdout );
427                 else
428                     fputs( g10_errstr(rc), stdout);
429                 putchar('\n');
430             }
431             else if( rc )
432                 log_error("secret key certificate error: %s\n", g10_errstr(rc));
433             last_seckey = pkt->pkt.seckey_cert;
434             pkt->pkt.seckey_cert = NULL;
435             free_packet(pkt);
436             pkt->skc_parent = last_seckey; /* set this as parent */
437         }
438         else if( pkt->pkttype == PKT_USER_ID ) {
439             if( last_user_id ) {
440                 free_user_id( last_user_id );
441                 last_user_id = NULL;
442             }
443             if( opt_list ) {
444                  printf("uid: '%.*s'\n", pkt->pkt.user_id->len,
445                                          pkt->pkt.user_id->name );
446                  if( !pkt->pkc_parent && !pkt->skc_parent )
447                      puts("      (orphaned)");
448             }
449             if( pkt->pkc_parent ) {
450                 if( pkt->pkc_parent->pubkey_algo == PUBKEY_ALGO_ELGAMAL
451                     || pkt->pkc_parent->pubkey_algo == PUBKEY_ALGO_RSA ) {
452                     keyid_from_pkc( pkt->pkc_parent, keyid );
453                     cache_user_id( pkt->pkt.user_id, keyid );
454                 }
455             }
456
457             last_user_id = pkt->pkt.user_id;  /* save */
458             pkt->pkt.user_id = NULL;
459             free_packet(pkt);   /* fixme: free_packet is not a good name */
460             pkt->user_parent = last_user_id;  /* and set this as user */
461         }
462         else if( pkt->pkttype == PKT_SIGNATURE ) {
463             sig = pkt->pkt.signature;
464             ustr = get_user_id_string(sig->keyid);
465             result = -1;
466             if( sig->sig_class == 0x00 ) {
467                 if( mfx.rmd160 )
468                     result = 0;
469                 else
470                     printstr(lvl1,"sig?: %s: no plaintext for signature\n",
471                                                         ustr);
472             }
473             else if( sig->sig_class != 0x10 )
474                 printstr(lvl1,"sig?: %s: unknown signature class %02x\n",
475                                         ustr, sig->sig_class);
476             else if( !pkt->pkc_parent || !pkt->user_parent )
477                 printstr(lvl1,"sig?: %s: orphaned encoded packet\n", ustr);
478             else
479                 result = 0;
480
481             if( result )
482                 ;
483             else if( !opt.check_sigs && sig->sig_class != 0x00 ) {
484                 result = -1;
485                 printstr(lvl0, "sig: from %s\n", ustr );
486             }
487             else if(sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
488                 md_handle.algo = sig->d.elg.digest_algo;
489                 if( sig->d.elg.digest_algo == DIGEST_ALGO_RMD160 ) {
490                     if( sig->sig_class == 0x00 )
491                         md_handle.u.rmd = rmd160_copy( mfx.rmd160 );
492                     else {
493                         md_handle.u.rmd = rmd160_copy(pkt->pkc_parent->mfx.rmd160);
494                         rmd160_write(md_handle.u.rmd, pkt->user_parent->name,
495                                                       pkt->user_parent->len);
496                     }
497                     result = signature_check( sig, md_handle );
498                     rmd160_close(md_handle.u.rmd);
499                 }
500                 else if( sig->d.elg.digest_algo == DIGEST_ALGO_MD5
501                          && sig->sig_class != 0x00 ) {
502                     md_handle.u.md5 = md5_copy(pkt->pkc_parent->mfx.md5);
503                     md5_write(md_handle.u.md5, pkt->user_parent->name,
504                                                pkt->user_parent->len);
505                     result = signature_check( sig, md_handle );
506                     md5_close(md_handle.u.md5);
507                 }
508                 else
509                     result = G10ERR_DIGEST_ALGO;
510             }
511             else if(sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
512                 md_handle.algo = sig->d.rsa.digest_algo;
513                 if( sig->d.rsa.digest_algo == DIGEST_ALGO_RMD160 ) {
514                     if( sig->sig_class == 0x00 )
515                         md_handle.u.rmd = rmd160_copy( mfx.rmd160 );
516                     else {
517                         md_handle.u.rmd = rmd160_copy(pkt->pkc_parent->mfx.rmd160);
518                         rmd160_write(md_handle.u.rmd, pkt->user_parent->name,
519                                                       pkt->user_parent->len);
520                     }
521                     result = signature_check( sig, md_handle );
522                     rmd160_close(md_handle.u.rmd);
523                 }
524                 else if( sig->d.rsa.digest_algo == DIGEST_ALGO_MD5
525                          && sig->sig_class != 0x00 ) {
526                     md_handle.u.md5 = md5_copy(pkt->pkc_parent->mfx.md5);
527                     md5_write(md_handle.u.md5, pkt->user_parent->name,
528                                                pkt->user_parent->len);
529                     result = signature_check( sig, md_handle );
530                     md5_close(md_handle.u.md5);
531                 }
532                 else
533                     result = G10ERR_DIGEST_ALGO;
534             }
535             else
536                 result = G10ERR_PUBKEY_ALGO;
537
538             if( result == -1 )
539                 ;
540             else if( !result && sig->sig_class == 0x00 )
541                 printstr(1,    "sig: good signature from %s\n", ustr );
542             else if( !result )
543                 printstr(lvl0, "sig: good signature from %s\n", ustr );
544             else
545                 printstr(lvl1, "sig? %s: %s\n", ustr, g10_errstr(result));
546             free_packet(pkt);
547             m_free(ustr);
548         }
549         else if( pkt->pkttype == PKT_PUBKEY_ENC ) {
550             PKT_pubkey_enc *enc;
551
552             last_was_pubkey_enc = 1;
553             result = 0;
554             enc = pkt->pkt.pubkey_enc;
555             printf("enc: encrypted by a pubkey with keyid %08lX\n",
556                                                         enc->keyid[1] );
557             if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL
558                 || enc->pubkey_algo == PUBKEY_ALGO_RSA  ) {
559                 m_free(dek ); /* paranoid: delete a pending DEK */
560                 dek = m_alloc_secure( sizeof *dek );
561                 if( (result = get_session_key( enc, dek )) ) {
562                     /* error: delete the DEK */
563                     m_free(dek); dek = NULL;
564                 }
565             }
566             else
567                 result = G10ERR_PUBKEY_ALGO;
568
569             if( result == -1 )
570                 ;
571             else if( !result )
572                 fputs(  "     DEK is good", stdout );
573             else
574                 printf( "     %s", g10_errstr(result));
575             putchar('\n');
576             free_packet(pkt);
577         }
578         else if( pkt->pkttype == PKT_ENCR_DATA ) {
579             result = 0;
580             printf("dat: %sencrypted data\n", dek?"":"conventional ");
581             if( !dek && !last_was_pubkey_enc ) {
582                 /* assume this is conventional encrypted data */
583                 dek = m_alloc_secure( sizeof *dek );
584                 dek->algo = DEFAULT_CIPHER_ALGO;
585                 result = make_dek_from_passphrase( dek, 0 );
586             }
587             else if( !dek )
588                 result = G10ERR_NO_SECKEY;
589             if( !result )
590                 result = decrypt_data( pkt->pkt.encr_data, dek );
591             m_free(dek); dek = NULL;
592             if( result == -1 )
593                 ;
594             else if( !result )
595                 fputs(  "     encryption okay",stdout);
596             else
597                 printf( "     %s", g10_errstr(result));
598             putchar('\n');
599             free_packet(pkt);
600             last_was_pubkey_enc = 0;
601         }
602         else if( pkt->pkttype == PKT_PLAINTEXT ) {
603             PKT_plaintext *pt = pkt->pkt.plaintext;
604             printf("txt: plain text data name='%.*s'\n", pt->namelen, pt->name);
605             free_md_filter_context( &mfx );
606             mfx.rmd160 = rmd160_open(0);
607             result = handle_plaintext( pt, &mfx );
608             if( !result )
609                 fputs(  "     okay",stdout);
610             else
611                 printf( "     %s", g10_errstr(result));
612             putchar('\n');
613             free_packet(pkt);
614             last_was_pubkey_enc = 0;
615         }
616         else if( pkt->pkttype == PKT_COMPR_DATA ) {
617             PKT_compressed *zd = pkt->pkt.compressed;
618             printf("zip: compressed data packet\n");
619             result = handle_compressed( zd );
620             if( !result )
621                 fputs(  "     okay",stdout);
622             else
623                 printf( "     %s", g10_errstr(result));
624             putchar('\n');
625             free_packet(pkt);
626             last_was_pubkey_enc = 0;
627         }
628         else
629             free_packet(pkt);
630     }
631
632     if( last_user_id )
633         free_user_id( last_user_id );
634     if( last_seckey )
635         free_seckey_cert( last_seckey );
636     if( last_pubkey )
637         free_pubkey_cert( last_pubkey );
638     m_free(dek);
639     free_packet( pkt );
640     m_free( pkt );
641     free_md_filter_context( &mfx );
642     return 0;
643 }
644 #endif
645