diff --git a/g10/ChangeLog b/g10/ChangeLog index c1642ff5f..294f91a81 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,20 @@ +2002-08-30 Werner Koch + + * pkclist.c (do_we_trust_pre): Changed the wording of a warning. + + * encode.c (encode_simple,encode_crypt): Use new style CTB for + compressssed packets when using MDC. We need to do this so that + concatenated messages are properly decrypted. Old style + compression assumes that it is the last packet; given that we + can't determine the length in advance, the uncompressor does not + know where to start. Actually we should use the new CTB always + but this would break PGP 2 compatibility. + * parse-packet.c (parse): Special treatment for new style CTB + compressed packets. + + * build-packet.c (do_mdc): Removed. Was not used. + (do_encrypted_mdc): Count the version number and the MDC packet. + 2002-08-28 David Shaw * sig-check.c (do_check_messages, do_check): Show keyid in error diff --git a/g10/build-packet.c b/g10/build-packet.c index e7bc3f638..c4508116c 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -44,7 +44,6 @@ static u32 calc_plaintext( PKT_plaintext *pt ); static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt ); static int do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed ); static int do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed ); -static int do_mdc( IOBUF out, PKT_mdc *mdc ); static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd ); static int do_signature( IOBUF out, int ctb, PKT_signature *sig ); static int do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops ); @@ -122,9 +121,6 @@ build_packet( IOBUF out, PACKET *pkt ) case PKT_ENCRYPTED_MDC: rc = do_encrypted_mdc( out, ctb, pkt->pkt.encrypted ); break; - case PKT_MDC: - rc = do_mdc( out, pkt->pkt.mdc ); - break; case PKT_COMPRESSED: rc = do_compressed( out, ctb, pkt->pkt.compressed ); break; @@ -136,6 +132,7 @@ build_packet( IOBUF out, PACKET *pkt ) break; case PKT_RING_TRUST: break; /* ignore it (keyring.c does write it directly)*/ + case PKT_MDC: /* we write it directly, so we should never see it here. */ default: log_bug("invalid packet type in build_packet()\n"); break; @@ -580,7 +577,8 @@ do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed ) assert( ed->mdc_method ); - n = ed->len ? (ed->len + ed->extralen) : 0; + /* Take version number and the following MDC packet in account. */ + n = ed->len ? (ed->len + ed->extralen + 1 + 22) : 0; write_header(out, ctb, n ); iobuf_put(out, 1 ); /* version */ @@ -590,23 +588,16 @@ do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed ) } -static int -do_mdc( IOBUF out, PKT_mdc *mdc ) -{ - /* This packet requires a fixed header encoding */ - iobuf_put( out, 0xd3 ); /* packet ID and 1 byte length */ - iobuf_put( out, 0x14 ); /* length = 20 */ - if( iobuf_write( out, mdc->hash, sizeof(mdc->hash) ) ) - return G10ERR_WRITE_FILE; - return 0; -} - static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd ) { int rc = 0; - /* we must use the old convention and don't use blockmode */ + /* We must use the old convention and don't use blockmode for tyhe + sake of PGP 2 compatibility. However if the new_ctb flag was + set, CTB is already formatted as new style and write_header2 + does create a partial length encoding using new the new + style. */ write_header2(out, ctb, 0, 0, 0 ); iobuf_put(out, cd->algorithm ); diff --git a/g10/compress.c b/g10/compress.c index 6d85e0181..6ea84f6cd 100644 --- a/g10/compress.c +++ b/g10/compress.c @@ -171,11 +171,11 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs, if( DBG_FILTER ) log_debug("enter inflate: avail_in=%u, avail_out=%u\n", (unsigned)zs->avail_in, (unsigned)zs->avail_out); - #ifdef Z_SYNC_FLUSH +#ifdef Z_SYNC_FLUSH zrc = inflate( zs, Z_SYNC_FLUSH ); - #else +#else zrc = inflate( zs, Z_PARTIAL_FLUSH ); - #endif +#endif if( DBG_FILTER ) log_debug("leave inflate: avail_in=%u, avail_out=%u, zrc=%d\n", (unsigned)zs->avail_in, (unsigned)zs->avail_out, zrc); diff --git a/g10/encode.c b/g10/encode.c index 4811e4e88..14192bd16 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -319,6 +319,8 @@ encode_simple( const char *filename, int mode, int compat ) /* register the compress filter */ if( do_compress ) { + if (cfx.dek && cfx.dek->use_mdc) + zfx.new_ctb = 1; zfx.algo=opt.def_compress_algo; if(zfx.algo==-1) zfx.algo=DEFAULT_COMPRESS_ALGO; @@ -554,6 +556,8 @@ encode_crypt( const char *filename, STRLIST remusr ) /* algo 0 means no compression */ if( compr_algo ) { + if (cfx.dek && cfx.dek->use_mdc) + zfx.new_ctb = 1; zfx.algo = compr_algo; iobuf_push_filter( out, compress_filter, &zfx ); } @@ -565,13 +569,15 @@ encode_crypt( const char *filename, STRLIST remusr ) log_error("build_packet failed: %s\n", g10_errstr(rc) ); } else { - /* user requested not to create a literal packet, so we copy the plain data */ + /* user requested not to create a literal packet, so we copy + the plain data */ byte copy_buffer[4096]; int bytes_copied; while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1) if (iobuf_write(out, copy_buffer, bytes_copied) == -1) { rc = G10ERR_WRITE_FILE; - log_error("copying input to output failed: %s\n", g10_errstr(rc) ); + log_error("copying input to output failed: %s\n", + g10_errstr(rc) ); break; } memset(copy_buffer, 0, 4096); /* burn buffer */ diff --git a/g10/filter.h b/g10/filter.h index b7a99e6bc..c933d2383 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -77,6 +77,7 @@ struct compress_filter_context_s { unsigned outbufsize; int algo; /* compress algo */ int algo1hack; + int new_ctb; void (*release)(struct compress_filter_context_s*); }; typedef struct compress_filter_context_s compress_filter_context_t; diff --git a/g10/parse-packet.c b/g10/parse-packet.c index f922a6551..760e25061 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -318,39 +318,47 @@ parse( IOBUF inp, PACKET *pkt, int onlykeypkts, off_t *retpos, pktlen = 0; new_ctb = !!(ctb & 0x40); if( new_ctb ) { - pkttype = ctb & 0x3f; + pkttype = ctb & 0x3f; if( (c = iobuf_get(inp)) == -1 ) { log_error("%s: 1st length byte missing\n", iobuf_where(inp) ); rc = G10ERR_INVALID_PACKET; goto leave; } - hdr[hdrlen++] = c; - if( c < 192 ) - pktlen = c; - else if( c < 224 ) { - pktlen = (c - 192) * 256; - if( (c = iobuf_get(inp)) == -1 ) { - log_error("%s: 2nd length byte missing\n", iobuf_where(inp) ); - rc = G10ERR_INVALID_PACKET; - goto leave; - } - hdr[hdrlen++] = c; - pktlen += c + 192; - } - else if( c == 255 ) { - pktlen = (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 24; - pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 16; - pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 8; - if( (c = iobuf_get(inp)) == -1 ) { - log_error("%s: 4 byte length invalid\n", iobuf_where(inp) ); - rc = G10ERR_INVALID_PACKET; - goto leave; - } - pktlen |= (hdr[hdrlen++] = c ); - } - else { /* partial body length */ - iobuf_set_partial_block_mode(inp, c & 0xff); - pktlen = 0;/* to indicate partial length */ + if (pkttype == PKT_COMPRESSED) { + iobuf_set_partial_block_mode(inp, c & 0xff); + pktlen = 0;/* to indicate partial length */ + } + else { + hdr[hdrlen++] = c; + if( c < 192 ) + pktlen = c; + else if( c < 224 ) { + pktlen = (c - 192) * 256; + if( (c = iobuf_get(inp)) == -1 ) { + log_error("%s: 2nd length byte missing\n", + iobuf_where(inp) ); + rc = G10ERR_INVALID_PACKET; + goto leave; + } + hdr[hdrlen++] = c; + pktlen += c + 192; + } + else if( c == 255 ) { + pktlen = (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 24; + pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 16; + pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 8; + if( (c = iobuf_get(inp)) == -1 ) { + log_error("%s: 4 byte length invalid\n", + iobuf_where(inp) ); + rc = G10ERR_INVALID_PACKET; + goto leave; + } + pktlen |= (hdr[hdrlen++] = c ); + } + else { /* partial body length */ + iobuf_set_partial_block_mode(inp, c & 0xff); + pktlen = 0;/* to indicate partial length */ + } } } else { @@ -400,14 +408,14 @@ parse( IOBUF inp, PACKET *pkt, int onlykeypkts, off_t *retpos, } if( DBG_PACKET ) { - #ifdef DEBUG_PARSE_PACKET +#ifdef DEBUG_PARSE_PACKET log_debug("parse_packet(iob=%d): type=%d length=%lu%s (%s.%s.%d)\n", iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"", dbg_w, dbg_f, dbg_l ); - #else +#else log_debug("parse_packet(iob=%d): type=%d length=%lu%s\n", iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"" ); - #endif +#endif } pkt->pkttype = pkttype; rc = G10ERR_UNKNOWN_PACKET; /* default error */ @@ -2014,8 +2022,8 @@ parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen, * the compress algorithm should know the length) */ zd = pkt->pkt.compressed = m_alloc(sizeof *pkt->pkt.compressed ); - zd->len = 0; /* not yet used */ zd->algorithm = iobuf_get_noeof(inp); + zd->len = 0; /* not used */ zd->new_ctb = new_ctb; zd->buf = inp; if( list_mode ) @@ -2036,8 +2044,8 @@ parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, ed->len = pktlen; /* we don't know the extralen which is (cipher_blocksize+2) because the algorithm ist not specified in this packet. - However, it is only important to know this for somesanity - checks on the pkacet length - it doesn't matter that we can't + However, it is only important to know this for some sanity + checks on the packet length - it doesn't matter that we can't do it */ ed->extralen = 0; ed->buf = NULL; diff --git a/g10/pkclist.c b/g10/pkclist.c index 3790e38bf..684145fe5 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -510,9 +510,9 @@ do_we_trust_pre( PKT_public_key *pk, unsigned int trustlevel ) tty_printf("\n"); tty_printf(_( -"It is NOT certain that the key belongs to its owner.\n" -"If you *really* know what you are doing, you may answer\n" -"the next question with yes\n\n") ); +"It is NOT certain that the key belongs to the person named\n" +"in the user ID. If you *really* know what you are doing,\n" +"you may answer the next question with yes\n\n")); if( cpr_get_answer_is_yes("untrusted_key.override", _("Use this key anyway? ")) )