See ChangeLog: Mon Apr 26 17:48:15 CEST 1999 Werner Koch
[gnupg.git] / g10 / encode.c
1 /* encode.c - encode data
2  *      Copyright (C) 1998 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG 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  * GnuPG 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 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27
28 #include "options.h"
29 #include "packet.h"
30 #include "errors.h"
31 #include "iobuf.h"
32 #include "keydb.h"
33 #include "memory.h"
34 #include "util.h"
35 #include "main.h"
36 #include "filter.h"
37 #include "trustdb.h"
38 #include "i18n.h"
39
40
41 static int encode_simple( const char *filename, int mode );
42 static int encode_crypt_mdc( const char* fname, STRLIST remusr );
43 static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out );
44
45
46
47 /****************
48  * Encode FILENAME with only the symmetric cipher.  Take input from
49  * stdin if FILENAME is NULL.
50  */
51 int
52 encode_symmetric( const char *filename )
53 {
54     return encode_simple( filename, 1 );
55 }
56
57 /****************
58  * Encode FILENAME as a literal data packet only. Take input from
59  * stdin if FILENAME is NULL.
60  */
61 int
62 encode_store( const char *filename )
63 {
64     return encode_simple( filename, 0 );
65 }
66
67
68 static int
69 encode_simple( const char *filename, int mode )
70 {
71     IOBUF inp, out;
72     PACKET pkt;
73     PKT_plaintext *pt;
74     STRING2KEY *s2k = NULL;
75     int rc = 0;
76     u32 filesize;
77     cipher_filter_context_t cfx;
78     armor_filter_context_t afx;
79     compress_filter_context_t zfx;
80     text_filter_context_t tfx;
81     int do_compress = opt.compress && !opt.rfc1991;
82
83     memset( &cfx, 0, sizeof cfx);
84     memset( &afx, 0, sizeof afx);
85     memset( &zfx, 0, sizeof zfx);
86     memset( &tfx, 0, sizeof tfx);
87     init_packet(&pkt);
88
89     /* prepare iobufs */
90     if( !(inp = iobuf_open(filename)) ) {
91         log_error(_("%s: can't open: %s\n"), filename? filename: "[stdin]",
92                                         strerror(errno) );
93         return G10ERR_OPEN_FILE;
94     }
95
96     if( opt.textmode )
97         iobuf_push_filter( inp, text_filter, &tfx );
98
99     cfx.dek = NULL;
100     if( mode ) {
101         s2k = m_alloc_clear( sizeof *s2k );
102         s2k->mode = opt.rfc1991? 0:opt.s2k_mode;
103         s2k->hash_algo = opt.def_digest_algo ? opt.def_digest_algo
104                                              : opt.s2k_digest_algo;
105         cfx.dek = passphrase_to_dek( NULL,
106                        opt.def_cipher_algo ? opt.def_cipher_algo
107                                            : opt.s2k_cipher_algo , s2k, 2 );
108         if( !cfx.dek || !cfx.dek->keylen ) {
109             rc = G10ERR_PASSPHRASE;
110             m_free(cfx.dek);
111             m_free(s2k);
112             iobuf_close(inp);
113             log_error(_("error creating passphrase: %s\n"), g10_errstr(rc) );
114             return rc;
115         }
116     }
117
118     if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) {
119         iobuf_close(inp);
120         m_free(cfx.dek);
121         m_free(s2k);
122         return rc;
123     }
124
125     if( opt.armor )
126         iobuf_push_filter( out, armor_filter, &afx );
127   #ifdef ENABLE_COMMENT_PACKETS
128     else {
129         write_comment( out, "#created by GNUPG v" VERSION " ("
130                                             PRINTABLE_OS_NAME ")");
131         if( opt.comment_string )
132             write_comment( out, opt.comment_string );
133     }
134   #endif
135     if( s2k && !opt.rfc1991 ) {
136         PKT_symkey_enc *enc = m_alloc_clear( sizeof *enc );
137         enc->version = 4;
138         enc->cipher_algo = cfx.dek->algo;
139         enc->s2k = *s2k;
140         pkt.pkttype = PKT_SYMKEY_ENC;
141         pkt.pkt.symkey_enc = enc;
142         if( (rc = build_packet( out, &pkt )) )
143             log_error("build symkey packet failed: %s\n", g10_errstr(rc) );
144         m_free(enc);
145     }
146
147     /* setup the inner packet */
148     if( filename || opt.set_filename ) {
149         char *s = make_basename( opt.set_filename ? opt.set_filename : filename );
150         pt = m_alloc( sizeof *pt + strlen(s) - 1 );
151         pt->namelen = strlen(s);
152         memcpy(pt->name, s, pt->namelen );
153         m_free(s);
154     }
155     else { /* no filename */
156         pt = m_alloc( sizeof *pt - 1 );
157         pt->namelen = 0;
158     }
159     /* pgp5 has problems to decrypt symmetrically encrypted data from
160      * GnuPG if the filelength is in the inner packet.  It works
161      * when only partial length headers are use.  Until we have
162      * tracked this problem down. We use this temporary fix
163      * (fixme: remove the && !mode )
164      */
165     if( filename && !opt.textmode && !mode ) {
166         if( !(filesize = iobuf_get_filelength(inp)) )
167             log_info(_("%s: WARNING: empty file\n"), filename );
168     }
169     else
170         filesize = 0; /* stdin */
171     pt->timestamp = make_timestamp();
172     pt->mode = opt.textmode? 't' : 'b';
173     pt->len = filesize;
174     pt->buf = inp;
175     pkt.pkttype = PKT_PLAINTEXT;
176     pkt.pkt.plaintext = pt;
177     cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0;
178
179     /* register the cipher filter */
180     if( mode )
181         iobuf_push_filter( out, cipher_filter, &cfx );
182     /* register the compress filter */
183     if( do_compress )
184         iobuf_push_filter( out, compress_filter, &zfx );
185
186     /* do the work */
187     if( (rc = build_packet( out, &pkt )) )
188         log_error("build_packet failed: %s\n", g10_errstr(rc) );
189
190     /* finish the stuff */
191     iobuf_close(inp);
192     iobuf_close(out); /* fixme: check returncode */
193     pt->buf = NULL;
194     free_packet(&pkt);
195     m_free(cfx.dek);
196     m_free(s2k);
197     return rc;
198 }
199
200 /****************
201  * Encrypt the file with the given userids (or ask if none
202  * is supplied).
203  */
204 int
205 encode_crypt( const char *filename, STRLIST remusr )
206 {
207     IOBUF inp = NULL, out = NULL;
208     PACKET pkt;
209     PKT_plaintext *pt = NULL;
210     int rc = 0;
211     u32 filesize;
212     cipher_filter_context_t cfx;
213     armor_filter_context_t afx;
214     compress_filter_context_t zfx;
215     text_filter_context_t tfx;
216     PK_LIST pk_list;
217     int do_compress = opt.compress && !opt.rfc1991;
218
219     if( opt.force_mdc )
220         return encode_crypt_mdc( filename, remusr );
221
222
223     memset( &cfx, 0, sizeof cfx);
224     memset( &afx, 0, sizeof afx);
225     memset( &zfx, 0, sizeof zfx);
226     memset( &tfx, 0, sizeof tfx);
227     init_packet(&pkt);
228
229     if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) )
230         return rc;
231
232     /* prepare iobufs */
233     if( !(inp = iobuf_open(filename)) ) {
234         log_error(_("can't open %s: %s\n"), filename? filename: "[stdin]",
235                                         strerror(errno) );
236         rc = G10ERR_OPEN_FILE;
237         goto leave;
238     }
239     else if( opt.verbose )
240         log_info(_("reading from `%s'\n"), filename? filename: "[stdin]");
241
242     if( opt.textmode )
243         iobuf_push_filter( inp, text_filter, &tfx );
244
245     if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) )
246         goto leave;
247
248
249     if( opt.armor )
250         iobuf_push_filter( out, armor_filter, &afx );
251   #ifdef ENABLE_COMMENT_PACKETS
252     else {
253         write_comment( out, "#created by GNUPG v" VERSION " ("
254                                             PRINTABLE_OS_NAME ")");
255         if( opt.comment_string )
256             write_comment( out, opt.comment_string );
257     }
258   #endif
259     /* create a session key */
260     cfx.dek = m_alloc_secure( sizeof *cfx.dek );
261     if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
262         cfx.dek->algo = select_algo_from_prefs( pk_list, PREFTYPE_SYM );
263         if( cfx.dek->algo == -1 )
264             cfx.dek->algo = DEFAULT_CIPHER_ALGO;
265     }
266     else
267         cfx.dek->algo = opt.def_cipher_algo;
268     make_session_key( cfx.dek );
269     if( DBG_CIPHER )
270         log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );
271
272     rc = write_pubkey_enc_from_list( pk_list, cfx.dek, out );
273     if( rc  )
274         goto leave;
275
276     /* setup the inner packet */
277     if( filename || opt.set_filename ) {
278         char *s = make_basename( opt.set_filename ? opt.set_filename : filename );
279         pt = m_alloc( sizeof *pt + strlen(s) - 1 );
280         pt->namelen = strlen(s);
281         memcpy(pt->name, s, pt->namelen );
282         m_free(s);
283     }
284     else { /* no filename */
285         pt = m_alloc( sizeof *pt - 1 );
286         pt->namelen = 0;
287     }
288     if( filename && !opt.textmode ) {
289         if( !(filesize = iobuf_get_filelength(inp)) )
290             log_info(_("%s: WARNING: empty file\n"), filename );
291     }
292     else
293         filesize = 0; /* stdin */
294     pt->timestamp = make_timestamp();
295     pt->mode = opt.textmode ? 't' : 'b';
296     pt->len = filesize;
297     pt->new_ctb = !pt->len && !opt.rfc1991;
298     pt->buf = inp;
299     pkt.pkttype = PKT_PLAINTEXT;
300     pkt.pkt.plaintext = pt;
301     cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
302
303     /* register the cipher filter */
304     iobuf_push_filter( out, cipher_filter, &cfx );
305     /* register the compress filter */
306     if( do_compress ) {
307         int compr_algo = select_algo_from_prefs( pk_list, PREFTYPE_COMPR );
308         if( !compr_algo )
309             ; /* don't use compression */
310         else {
311             if( compr_algo == 1 )
312                 zfx.algo = 1; /* default is 2 */
313             iobuf_push_filter( out, compress_filter, &zfx );
314         }
315     }
316
317     /* do the work */
318     if( (rc = build_packet( out, &pkt )) )
319         log_error("build_packet failed: %s\n", g10_errstr(rc) );
320
321     /* finish the stuff */
322   leave:
323     iobuf_close(inp);
324     if( rc )
325         iobuf_cancel(out);
326     else
327         iobuf_close(out); /* fixme: check returncode */
328     if( pt )
329         pt->buf = NULL;
330     free_packet(&pkt);
331     m_free(cfx.dek);
332     release_pk_list( pk_list );
333     return rc;
334 }
335
336
337
338 static int
339 encode_crypt_mdc( const char* fname, STRLIST remusr )
340 {
341     armor_filter_context_t afx;
342     compress_filter_context_t zfx;
343     md_filter_context_t mfx;
344     text_filter_context_t tfx;
345     encrypt_filter_context_t efx;
346     IOBUF inp = NULL, out = NULL;
347     PACKET pkt;
348     PKT_plaintext *pt = NULL;
349     u32 filesize;
350     int rc = 0;
351     PK_LIST pk_list = NULL;
352     int compr_algo = -1; /* unknown */
353
354
355     memset( &afx, 0, sizeof afx);
356     memset( &zfx, 0, sizeof zfx);
357     memset( &mfx, 0, sizeof mfx);
358     memset( &tfx, 0, sizeof tfx);
359     memset( &efx, 0, sizeof efx);
360     init_packet( &pkt );
361
362     if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )) )
363         goto leave;
364     compr_algo = select_algo_from_prefs( pk_list, PREFTYPE_COMPR );
365
366     /* prepare iobufs */
367     if( !(inp = iobuf_open(fname)) ) {
368         log_error("can't open %s: %s\n", fname? fname: "[stdin]",
369                                         strerror(errno) );
370         rc = G10ERR_OPEN_FILE;
371         goto leave;
372     }
373
374     if( (rc = open_outfile( fname, opt.armor? 1: 0, &out )))
375         goto leave;
376
377     /* prepare to calculate the MD over the input */
378     mfx.md = md_open( DIGEST_ALGO_SHA1, 0 );
379     iobuf_push_filter( inp, md_filter, &mfx );
380
381     if( opt.armor )
382         iobuf_push_filter( out, armor_filter, &afx );
383     efx.pk_list = pk_list;
384     /* fixme: set efx.cfx.datalen if known */
385     iobuf_push_filter( out, encrypt_filter, &efx );
386
387     if( opt.compress ) {
388         if( !compr_algo )
389             ; /* don't use compression */
390         else {
391             if( compr_algo == 1 )
392                 zfx.algo = 1;
393             iobuf_push_filter( out, compress_filter, &zfx );
394         }
395     }
396
397     /* build a one pass packet */
398     {
399         PKT_onepass_sig *ops;
400
401         ops = m_alloc_clear( sizeof *ops );
402         ops->sig_class = 0x00;
403         ops->digest_algo = DIGEST_ALGO_SHA1;
404         ops->pubkey_algo = 0;
405         ops->keyid[0] = 0;
406         ops->keyid[1] = 0;
407         ops->last = 1;
408
409         init_packet(&pkt);
410         pkt.pkttype = PKT_ONEPASS_SIG;
411         pkt.pkt.onepass_sig = ops;
412         rc = build_packet( out, &pkt );
413         free_packet( &pkt );
414         if( rc ) {
415             log_error("build onepass_sig packet failed: %s\n",
416                                                         g10_errstr(rc));
417             goto leave;
418         }
419     }
420
421     /* setup the inner packet */
422     if( fname || opt.set_filename ) {
423         char *s = make_basename( opt.set_filename ? opt.set_filename : fname );
424         pt = m_alloc( sizeof *pt + strlen(s) - 1 );
425         pt->namelen = strlen(s);
426         memcpy(pt->name, s, pt->namelen );
427         m_free(s);
428     }
429     else { /* no filename */
430         pt = m_alloc( sizeof *pt - 1 );
431         pt->namelen = 0;
432     }
433     if( fname ) {
434         if( !(filesize = iobuf_get_filelength(inp)) )
435             log_info(_("WARNING: `%s' is an empty file\n"), fname );
436
437         /* because the text_filter modifies the length of the
438          * data, it is not possible to know the used length
439          * without a double read of the file - to avoid that
440          * we simple use partial length packets.
441          */
442         if( opt.textmode )
443             filesize = 0;
444     }
445     else
446         filesize = 0; /* stdin */
447     pt->timestamp = make_timestamp();
448     pt->mode = opt.textmode ? 't':'b';
449     pt->len = filesize;
450     pt->new_ctb = !pt->len;
451     pt->buf = inp;
452     pkt.pkttype = PKT_PLAINTEXT;
453     pkt.pkt.plaintext = pt;
454     /*cfx.datalen = filesize? calc_packet_length( &pkt ) : 0;*/
455     if( (rc = build_packet( out, &pkt )) )
456         log_error("build_packet(PLAINTEXT) failed: %s\n", g10_errstr(rc) );
457     pt->buf = NULL;
458
459     /* build the MDC faked signature packet */
460     {
461         PKT_signature *sig;
462         MD_HANDLE md;
463         byte buf[6];
464         size_t n;
465
466         sig = m_alloc_clear( sizeof *sig );
467         sig->version = 4;
468         sig->digest_algo = DIGEST_ALGO_SHA1;
469         md = md_copy( mfx.md );
470
471         md_putc( md, sig->version );
472         md_putc( md, sig->sig_class );
473         md_putc( md, sig->pubkey_algo );
474         md_putc( md, sig->digest_algo );
475         n = 6;
476         /* add some magic */
477         buf[0] = sig->version;
478         buf[1] = 0xff; buf[2] = 0; buf[3] = 0; buf[4] = 0; buf[5] = 6;
479         md_write( md, buf, 6 );
480         md_final( md );
481
482         /* pack the hash into data[0] */
483         memcpy( sig->digest_start, md_read( md, DIGEST_ALGO_SHA1), 2 );
484         sig->data[0] = mpi_alloc( (20+BYTES_PER_MPI_LIMB-1)
485                                   /BYTES_PER_MPI_LIMB );
486         mpi_set_buffer( sig->data[0], md_read(md, DIGEST_ALGO_SHA1),
487                                  md_digest_length(DIGEST_ALGO_SHA1), 0 );
488
489         md_close( md );
490
491         if( !rc ) { /* and write it */
492             init_packet(&pkt);
493             pkt.pkttype = PKT_SIGNATURE;
494             pkt.pkt.signature = sig;
495             rc = build_packet( out, &pkt );
496             free_packet( &pkt );
497             if( rc )
498                 log_error("build MDC packet failed: %s\n", g10_errstr(rc) );
499         }
500         if( rc )
501             goto leave;
502     }
503
504
505   leave:
506     if( rc )
507         iobuf_cancel(out);
508     else
509         iobuf_close(out);
510     iobuf_close(inp);
511     md_close( mfx.md );
512     release_pk_list( pk_list );
513     return rc;
514 }
515
516
517
518
519
520
521
522
523
524 /****************
525  * Filter to do a complete public key encryption.
526  */
527 int
528 encrypt_filter( void *opaque, int control,
529                IOBUF a, byte *buf, size_t *ret_len)
530 {
531     size_t size = *ret_len;
532     encrypt_filter_context_t *efx = opaque;
533     int rc=0;
534
535     if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */
536         BUG(); /* not used */
537     }
538     else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
539         if( !efx->header_okay ) {
540             efx->cfx.dek = m_alloc_secure( sizeof *efx->cfx.dek );
541
542             if( !opt.def_cipher_algo  ) { /* try to get it from the prefs */
543                 efx->cfx.dek->algo =
544                           select_algo_from_prefs( efx->pk_list, PREFTYPE_SYM );
545                 if( efx->cfx.dek->algo == -1 )
546                     efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
547             }
548             else
549                 efx->cfx.dek->algo = opt.def_cipher_algo;
550             make_session_key( efx->cfx.dek );
551             if( DBG_CIPHER )
552                 log_hexdump("DEK is: ",
553                              efx->cfx.dek->key, efx->cfx.dek->keylen );
554
555             rc = write_pubkey_enc_from_list( efx->pk_list, efx->cfx.dek, a );
556             if( rc )
557                 return rc;
558
559             iobuf_push_filter( a, cipher_filter, &efx->cfx );
560
561             efx->header_okay = 1;
562         }
563         rc = iobuf_write( a, buf, size );
564
565     }
566     else if( control == IOBUFCTRL_FREE ) {
567     }
568     else if( control == IOBUFCTRL_DESC ) {
569         *(char**)buf = "encrypt_filter";
570     }
571     return rc;
572 }
573
574
575 /****************
576  * Write pubkey-enc packets from the list of PKs to OUT.
577  */
578 static int
579 write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
580 {
581     PACKET pkt;
582     PKT_public_key *pk;
583     PKT_pubkey_enc  *enc;
584     int rc;
585
586     for( ; pk_list; pk_list = pk_list->next ) {
587         MPI frame;
588
589         pk = pk_list->pk;
590
591         print_pubkey_algo_note( pk->pubkey_algo );
592         enc = m_alloc_clear( sizeof *enc );
593         enc->pubkey_algo = pk->pubkey_algo;
594         keyid_from_pk( pk, enc->keyid );
595         enc->throw_keyid = opt.throw_keyid;
596         frame = encode_session_key( dek, pubkey_nbits( pk->pubkey_algo,
597                                                           pk->pkey ) );
598         rc = pubkey_encrypt( pk->pubkey_algo, enc->data, frame, pk->pkey );
599         mpi_free( frame );
600         if( rc )
601             log_error("pubkey_encrypt failed: %s\n", g10_errstr(rc) );
602         else {
603             if( opt.verbose ) {
604                 char *ustr = get_user_id_string( enc->keyid );
605                 log_info(_("%s/%s encrypted for: %s\n"),
606                     pubkey_algo_to_string(enc->pubkey_algo),
607                     cipher_algo_to_string(dek->algo), ustr );
608                 m_free(ustr);
609             }
610             /* and write it */
611             init_packet(&pkt);
612             pkt.pkttype = PKT_PUBKEY_ENC;
613             pkt.pkt.pubkey_enc = enc;
614             rc = build_packet( out, &pkt );
615             if( rc )
616                log_error("build_packet(pubkey_enc) failed: %s\n", g10_errstr(rc));
617         }
618         free_pubkey_enc(enc);
619         if( rc )
620             return rc;
621     }
622     return 0;
623 }
624